1 //===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "CommandObjectTarget.h" 11 12 // C Includes 13 #include <errno.h> 14 15 // C++ Includes 16 // Other libraries and framework includes 17 // Project includes 18 #include "lldb/Interpreter/Args.h" 19 #include "lldb/Core/Debugger.h" 20 #include "lldb/Core/InputReader.h" 21 #include "lldb/Core/Section.h" 22 #include "lldb/Core/State.h" 23 #include "lldb/Core/Timer.h" 24 #include "lldb/Core/ValueObjectVariable.h" 25 #include "lldb/Interpreter/CommandInterpreter.h" 26 #include "lldb/Interpreter/CommandReturnObject.h" 27 #include "lldb/Interpreter/Options.h" 28 #include "lldb/Interpreter/OptionGroupArchitecture.h" 29 #include "lldb/Interpreter/OptionGroupBoolean.h" 30 #include "lldb/Interpreter/OptionGroupFile.h" 31 #include "lldb/Interpreter/OptionGroupFormat.h" 32 #include "lldb/Interpreter/OptionGroupVariable.h" 33 #include "lldb/Interpreter/OptionGroupPlatform.h" 34 #include "lldb/Interpreter/OptionGroupUInt64.h" 35 #include "lldb/Interpreter/OptionGroupUUID.h" 36 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" 37 #include "lldb/Symbol/LineTable.h" 38 #include "lldb/Symbol/ObjectFile.h" 39 #include "lldb/Symbol/SymbolFile.h" 40 #include "lldb/Symbol/SymbolVendor.h" 41 #include "lldb/Symbol/VariableList.h" 42 #include "lldb/Target/Process.h" 43 #include "lldb/Target/StackFrame.h" 44 #include "lldb/Target/Thread.h" 45 #include "lldb/Target/ThreadSpec.h" 46 47 using namespace lldb; 48 using namespace lldb_private; 49 50 51 52 static void 53 DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm) 54 { 55 const ArchSpec &target_arch = target->GetArchitecture(); 56 57 Module *exe_module = target->GetExecutableModulePointer(); 58 char exe_path[PATH_MAX]; 59 bool exe_valid = false; 60 if (exe_module) 61 exe_valid = exe_module->GetFileSpec().GetPath (exe_path, sizeof(exe_path)); 62 63 if (!exe_valid) 64 ::strcpy (exe_path, "<none>"); 65 66 strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path); 67 68 uint32_t properties = 0; 69 if (target_arch.IsValid()) 70 { 71 strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str()); 72 properties++; 73 } 74 PlatformSP platform_sp (target->GetPlatform()); 75 if (platform_sp) 76 strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName()); 77 78 ProcessSP process_sp (target->GetProcessSP()); 79 bool show_process_status = false; 80 if (process_sp) 81 { 82 lldb::pid_t pid = process_sp->GetID(); 83 StateType state = process_sp->GetState(); 84 if (show_stopped_process_status) 85 show_process_status = StateIsStoppedState(state, true); 86 const char *state_cstr = StateAsCString (state); 87 if (pid != LLDB_INVALID_PROCESS_ID) 88 strm.Printf ("%spid=%llu", properties++ > 0 ? ", " : " ( ", pid); 89 strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr); 90 } 91 if (properties > 0) 92 strm.PutCString (" )\n"); 93 else 94 strm.EOL(); 95 if (show_process_status) 96 { 97 const bool only_threads_with_stop_reason = true; 98 const uint32_t start_frame = 0; 99 const uint32_t num_frames = 1; 100 const uint32_t num_frames_with_source = 1; 101 process_sp->GetStatus (strm); 102 process_sp->GetThreadStatus (strm, 103 only_threads_with_stop_reason, 104 start_frame, 105 num_frames, 106 num_frames_with_source); 107 108 } 109 } 110 111 static uint32_t 112 DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm) 113 { 114 const uint32_t num_targets = target_list.GetNumTargets(); 115 if (num_targets) 116 { 117 TargetSP selected_target_sp (target_list.GetSelectedTarget()); 118 strm.PutCString ("Current targets:\n"); 119 for (uint32_t i=0; i<num_targets; ++i) 120 { 121 TargetSP target_sp (target_list.GetTargetAtIndex (i)); 122 if (target_sp) 123 { 124 bool is_selected = target_sp.get() == selected_target_sp.get(); 125 DumpTargetInfo (i, 126 target_sp.get(), 127 is_selected ? "* " : " ", 128 show_stopped_process_status, 129 strm); 130 } 131 } 132 } 133 return num_targets; 134 } 135 #pragma mark CommandObjectTargetCreate 136 137 //------------------------------------------------------------------------- 138 // "target create" 139 //------------------------------------------------------------------------- 140 141 class CommandObjectTargetCreate : public CommandObject 142 { 143 public: 144 CommandObjectTargetCreate(CommandInterpreter &interpreter) : 145 CommandObject (interpreter, 146 "target create", 147 "Create a target using the argument as the main executable.", 148 NULL), 149 m_option_group (interpreter), 150 m_arch_option (), 151 m_platform_options(true) // Do include the "--platform" option in the platform settings by passing true 152 { 153 CommandArgumentEntry arg; 154 CommandArgumentData file_arg; 155 156 // Define the first (and only) variant of this arg. 157 file_arg.arg_type = eArgTypeFilename; 158 file_arg.arg_repetition = eArgRepeatPlain; 159 160 // There is only one variant this argument could be; put it into the argument entry. 161 arg.push_back (file_arg); 162 163 // Push the data for the first argument into the m_arguments vector. 164 m_arguments.push_back (arg); 165 166 m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 167 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 168 m_option_group.Finalize(); 169 } 170 171 ~CommandObjectTargetCreate () 172 { 173 } 174 175 Options * 176 GetOptions () 177 { 178 return &m_option_group; 179 } 180 181 bool 182 Execute (Args& command, CommandReturnObject &result) 183 { 184 const int argc = command.GetArgumentCount(); 185 if (argc == 1) 186 { 187 const char *file_path = command.GetArgumentAtIndex(0); 188 Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path); 189 FileSpec file_spec (file_path, true); 190 191 TargetSP target_sp; 192 Debugger &debugger = m_interpreter.GetDebugger(); 193 const char *arch_cstr = m_arch_option.GetArchitectureName(); 194 const bool get_dependent_files = true; 195 Error error (debugger.GetTargetList().CreateTarget (debugger, 196 file_spec, 197 arch_cstr, 198 get_dependent_files, 199 &m_platform_options, 200 target_sp)); 201 202 if (target_sp) 203 { 204 debugger.GetTargetList().SetSelectedTarget(target_sp.get()); 205 result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName()); 206 result.SetStatus (eReturnStatusSuccessFinishNoResult); 207 } 208 else 209 { 210 result.AppendError(error.AsCString()); 211 result.SetStatus (eReturnStatusFailed); 212 } 213 } 214 else 215 { 216 result.AppendErrorWithFormat("'%s' takes exactly one executable path argument.\n", m_cmd_name.c_str()); 217 result.SetStatus (eReturnStatusFailed); 218 } 219 return result.Succeeded(); 220 221 } 222 223 int 224 HandleArgumentCompletion (Args &input, 225 int &cursor_index, 226 int &cursor_char_position, 227 OptionElementVector &opt_element_vector, 228 int match_start_point, 229 int max_return_elements, 230 bool &word_complete, 231 StringList &matches) 232 { 233 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 234 completion_str.erase (cursor_char_position); 235 236 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 237 CommandCompletions::eDiskFileCompletion, 238 completion_str.c_str(), 239 match_start_point, 240 max_return_elements, 241 NULL, 242 word_complete, 243 matches); 244 return matches.GetSize(); 245 } 246 private: 247 OptionGroupOptions m_option_group; 248 OptionGroupArchitecture m_arch_option; 249 OptionGroupPlatform m_platform_options; 250 251 }; 252 253 #pragma mark CommandObjectTargetList 254 255 //---------------------------------------------------------------------- 256 // "target list" 257 //---------------------------------------------------------------------- 258 259 class CommandObjectTargetList : public CommandObject 260 { 261 public: 262 CommandObjectTargetList (CommandInterpreter &interpreter) : 263 CommandObject (interpreter, 264 "target list", 265 "List all current targets in the current debug session.", 266 NULL, 267 0) 268 { 269 } 270 271 virtual 272 ~CommandObjectTargetList () 273 { 274 } 275 276 virtual bool 277 Execute (Args& args, CommandReturnObject &result) 278 { 279 if (args.GetArgumentCount() == 0) 280 { 281 Stream &strm = result.GetOutputStream(); 282 283 bool show_stopped_process_status = false; 284 if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0) 285 { 286 strm.PutCString ("No targets.\n"); 287 } 288 result.SetStatus (eReturnStatusSuccessFinishResult); 289 } 290 else 291 { 292 result.AppendError ("the 'target list' command takes no arguments\n"); 293 result.SetStatus (eReturnStatusFailed); 294 } 295 return result.Succeeded(); 296 } 297 }; 298 299 300 #pragma mark CommandObjectTargetSelect 301 302 //---------------------------------------------------------------------- 303 // "target select" 304 //---------------------------------------------------------------------- 305 306 class CommandObjectTargetSelect : public CommandObject 307 { 308 public: 309 CommandObjectTargetSelect (CommandInterpreter &interpreter) : 310 CommandObject (interpreter, 311 "target select", 312 "Select a target as the current target by target index.", 313 NULL, 314 0) 315 { 316 } 317 318 virtual 319 ~CommandObjectTargetSelect () 320 { 321 } 322 323 virtual bool 324 Execute (Args& args, CommandReturnObject &result) 325 { 326 if (args.GetArgumentCount() == 1) 327 { 328 bool success = false; 329 const char *target_idx_arg = args.GetArgumentAtIndex(0); 330 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success); 331 if (success) 332 { 333 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList(); 334 const uint32_t num_targets = target_list.GetNumTargets(); 335 if (target_idx < num_targets) 336 { 337 TargetSP target_sp (target_list.GetTargetAtIndex (target_idx)); 338 if (target_sp) 339 { 340 Stream &strm = result.GetOutputStream(); 341 target_list.SetSelectedTarget (target_sp.get()); 342 bool show_stopped_process_status = false; 343 DumpTargetList (target_list, show_stopped_process_status, strm); 344 result.SetStatus (eReturnStatusSuccessFinishResult); 345 } 346 else 347 { 348 result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx); 349 result.SetStatus (eReturnStatusFailed); 350 } 351 } 352 else 353 { 354 result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n", 355 target_idx, 356 num_targets - 1); 357 result.SetStatus (eReturnStatusFailed); 358 } 359 } 360 else 361 { 362 result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg); 363 result.SetStatus (eReturnStatusFailed); 364 } 365 } 366 else 367 { 368 result.AppendError ("'target select' takes a single argument: a target index\n"); 369 result.SetStatus (eReturnStatusFailed); 370 } 371 return result.Succeeded(); 372 } 373 }; 374 375 #pragma mark CommandObjectTargetSelect 376 377 //---------------------------------------------------------------------- 378 // "target delete" 379 //---------------------------------------------------------------------- 380 381 class CommandObjectTargetDelete : public CommandObject 382 { 383 public: 384 CommandObjectTargetDelete (CommandInterpreter &interpreter) : 385 CommandObject (interpreter, 386 "target delete", 387 "Delete one or more targets by target index.", 388 NULL, 389 0), 390 m_option_group (interpreter), 391 m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', 0, eArgTypeNone, "Perform extra cleanup to minimize memory consumption after deleting the target.", false) 392 { 393 m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 394 m_option_group.Finalize(); 395 } 396 397 virtual 398 ~CommandObjectTargetDelete () 399 { 400 } 401 402 virtual bool 403 Execute (Args& args, CommandReturnObject &result) 404 { 405 const size_t argc = args.GetArgumentCount(); 406 std::vector<TargetSP> delete_target_list; 407 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList(); 408 bool success = true; 409 TargetSP target_sp; 410 if (argc > 0) 411 { 412 const uint32_t num_targets = target_list.GetNumTargets(); 413 for (uint32_t arg_idx = 0; success && arg_idx < argc; ++arg_idx) 414 { 415 const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx); 416 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success); 417 if (success) 418 { 419 if (target_idx < num_targets) 420 { 421 target_sp = target_list.GetTargetAtIndex (target_idx); 422 if (target_sp) 423 { 424 delete_target_list.push_back (target_sp); 425 continue; 426 } 427 } 428 result.AppendErrorWithFormat ("target index %u is out of range, valid target indexes are 0 - %u\n", 429 target_idx, 430 num_targets - 1); 431 result.SetStatus (eReturnStatusFailed); 432 success = false; 433 } 434 else 435 { 436 result.AppendErrorWithFormat("invalid target index '%s'\n", target_idx_arg); 437 result.SetStatus (eReturnStatusFailed); 438 success = false; 439 } 440 } 441 442 } 443 else 444 { 445 target_sp = target_list.GetSelectedTarget(); 446 if (target_sp) 447 { 448 delete_target_list.push_back (target_sp); 449 } 450 else 451 { 452 result.AppendErrorWithFormat("no target is currently selected\n"); 453 result.SetStatus (eReturnStatusFailed); 454 success = false; 455 } 456 } 457 if (success) 458 { 459 const size_t num_targets_to_delete = delete_target_list.size(); 460 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) 461 { 462 target_sp = delete_target_list[idx]; 463 target_list.DeleteTarget(target_sp); 464 target_sp->Destroy(); 465 } 466 // If "--clean" was specified, prune any orphaned shared modules from 467 // the global shared module list 468 if (m_cleanup_option.GetOptionValue ()) 469 { 470 ModuleList::RemoveOrphanSharedModules(); 471 } 472 result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete); 473 result.SetStatus(eReturnStatusSuccessFinishResult); 474 } 475 476 return result.Succeeded(); 477 } 478 479 Options * 480 GetOptions () 481 { 482 return &m_option_group; 483 } 484 485 protected: 486 OptionGroupOptions m_option_group; 487 OptionGroupBoolean m_cleanup_option; 488 }; 489 490 491 #pragma mark CommandObjectTargetVariable 492 493 //---------------------------------------------------------------------- 494 // "target variable" 495 //---------------------------------------------------------------------- 496 497 class CommandObjectTargetVariable : public CommandObject 498 { 499 public: 500 CommandObjectTargetVariable (CommandInterpreter &interpreter) : 501 CommandObject (interpreter, 502 "target variable", 503 "Read global variable(s) prior to running your binary.", 504 NULL, 505 0), 506 m_option_group (interpreter), 507 m_option_variable (false), // Don't include frame options 508 m_option_format (eFormatDefault), 509 m_option_compile_units (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "A basename or fullpath to a file that contains global variables. This option can be specified multiple times."), 510 m_option_shared_libraries (LLDB_OPT_SET_1, false, "shlib",'s', 0, eArgTypePath, "A basename or fullpath to a shared library to use in the search for global variables. This option can be specified multiple times."), 511 m_varobj_options() 512 { 513 CommandArgumentEntry arg; 514 CommandArgumentData var_name_arg; 515 516 // Define the first (and only) variant of this arg. 517 var_name_arg.arg_type = eArgTypeVarName; 518 var_name_arg.arg_repetition = eArgRepeatPlus; 519 520 // There is only one variant this argument could be; put it into the argument entry. 521 arg.push_back (var_name_arg); 522 523 // Push the data for the first argument into the m_arguments vector. 524 m_arguments.push_back (arg); 525 526 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 527 m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 528 m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1); 529 m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 530 m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 531 m_option_group.Finalize(); 532 } 533 534 virtual 535 ~CommandObjectTargetVariable () 536 { 537 } 538 539 void 540 DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name) 541 { 542 ValueObject::DumpValueObjectOptions options; 543 544 options.SetPointerDepth(m_varobj_options.ptr_depth) 545 .SetMaximumDepth(m_varobj_options.max_depth) 546 .SetShowTypes(m_varobj_options.show_types) 547 .SetShowLocation(m_varobj_options.show_location) 548 .SetUseObjectiveC(m_varobj_options.use_objc) 549 .SetUseDynamicType(m_varobj_options.use_dynamic) 550 .SetUseSyntheticValue((lldb::SyntheticValueType)m_varobj_options.use_synth) 551 .SetFlatOutput(m_varobj_options.flat_output) 552 .SetOmitSummaryDepth(m_varobj_options.no_summary_depth) 553 .SetIgnoreCap(m_varobj_options.ignore_cap); 554 555 switch (var_sp->GetScope()) 556 { 557 case eValueTypeVariableGlobal: 558 if (m_option_variable.show_scope) 559 s.PutCString("GLOBAL: "); 560 break; 561 562 case eValueTypeVariableStatic: 563 if (m_option_variable.show_scope) 564 s.PutCString("STATIC: "); 565 break; 566 567 case eValueTypeVariableArgument: 568 if (m_option_variable.show_scope) 569 s.PutCString(" ARG: "); 570 break; 571 572 case eValueTypeVariableLocal: 573 if (m_option_variable.show_scope) 574 s.PutCString(" LOCAL: "); 575 break; 576 577 default: 578 break; 579 } 580 581 if (m_option_variable.show_decl) 582 { 583 bool show_fullpaths = false; 584 bool show_module = true; 585 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module)) 586 s.PutCString (": "); 587 } 588 589 const Format format = m_option_format.GetFormat(); 590 if (format != eFormatDefault) 591 valobj_sp->SetFormat (format); 592 593 ValueObject::DumpValueObject (s, 594 valobj_sp.get(), 595 root_name, 596 options); 597 598 } 599 600 601 static uint32_t GetVariableCallback (void *baton, 602 const char *name, 603 VariableList &variable_list) 604 { 605 Target *target = static_cast<Target *>(baton); 606 if (target) 607 { 608 return target->GetImages().FindGlobalVariables (ConstString(name), 609 true, 610 UINT32_MAX, 611 variable_list); 612 } 613 return 0; 614 } 615 616 617 618 virtual bool 619 Execute (Args& args, CommandReturnObject &result) 620 { 621 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 622 Target *target = exe_ctx.GetTargetPtr(); 623 if (target) 624 { 625 const size_t argc = args.GetArgumentCount(); 626 Stream &s = result.GetOutputStream(); 627 if (argc > 0) 628 { 629 630 for (size_t idx = 0; idx < argc; ++idx) 631 { 632 VariableList variable_list; 633 ValueObjectList valobj_list; 634 635 const char *arg = args.GetArgumentAtIndex(idx); 636 uint32_t matches = 0; 637 bool use_var_name = false; 638 if (m_option_variable.use_regex) 639 { 640 RegularExpression regex(arg); 641 if (!regex.IsValid ()) 642 { 643 result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg); 644 result.SetStatus (eReturnStatusFailed); 645 return false; 646 } 647 use_var_name = true; 648 matches = target->GetImages().FindGlobalVariables (regex, 649 true, 650 UINT32_MAX, 651 variable_list); 652 } 653 else 654 { 655 Error error (Variable::GetValuesForVariableExpressionPath (arg, 656 exe_ctx.GetBestExecutionContextScope(), 657 GetVariableCallback, 658 target, 659 variable_list, 660 valobj_list)); 661 matches = variable_list.GetSize(); 662 } 663 664 if (matches == 0) 665 { 666 result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg); 667 result.SetStatus (eReturnStatusFailed); 668 return false; 669 } 670 else 671 { 672 for (uint32_t global_idx=0; global_idx<matches; ++global_idx) 673 { 674 VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx)); 675 if (var_sp) 676 { 677 ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx)); 678 if (!valobj_sp) 679 valobj_sp = ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp); 680 681 if (valobj_sp) 682 DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg); 683 } 684 } 685 } 686 } 687 } 688 else 689 { 690 bool success = false; 691 StackFrame *frame = exe_ctx.GetFramePtr(); 692 CompileUnit *comp_unit = NULL; 693 if (frame) 694 { 695 comp_unit = frame->GetSymbolContext (eSymbolContextCompUnit).comp_unit; 696 if (comp_unit) 697 { 698 const bool can_create = true; 699 VariableListSP comp_unit_varlist_sp (comp_unit->GetVariableList(can_create)); 700 if (comp_unit_varlist_sp) 701 { 702 size_t count = comp_unit_varlist_sp->GetSize(); 703 if (count > 0) 704 { 705 s.Printf ("Global variables for %s/%s:\n", 706 comp_unit->GetDirectory().GetCString(), 707 comp_unit->GetFilename().GetCString()); 708 709 success = true; 710 for (uint32_t i=0; i<count; ++i) 711 { 712 VariableSP var_sp (comp_unit_varlist_sp->GetVariableAtIndex(i)); 713 if (var_sp) 714 { 715 ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp)); 716 717 if (valobj_sp) 718 DumpValueObject (s, var_sp, valobj_sp, var_sp->GetName().GetCString()); 719 } 720 } 721 } 722 } 723 } 724 } 725 if (!success) 726 { 727 if (frame) 728 { 729 if (comp_unit) 730 result.AppendErrorWithFormat ("no global variables in current compile unit: %s/%s\n", 731 comp_unit->GetDirectory().GetCString(), 732 comp_unit->GetFilename().GetCString()); 733 else 734 result.AppendError ("no debug information for frame %u\n", frame->GetFrameIndex()); 735 } 736 else 737 result.AppendError ("'target variable' takes one or more global variable names as arguments\n"); 738 result.SetStatus (eReturnStatusFailed); 739 } 740 } 741 } 742 else 743 { 744 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 745 result.SetStatus (eReturnStatusFailed); 746 return false; 747 } 748 749 if (m_interpreter.TruncationWarningNecessary()) 750 { 751 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(), 752 m_cmd_name.c_str()); 753 m_interpreter.TruncationWarningGiven(); 754 } 755 756 return result.Succeeded(); 757 } 758 759 Options * 760 GetOptions () 761 { 762 return &m_option_group; 763 } 764 765 protected: 766 OptionGroupOptions m_option_group; 767 OptionGroupVariable m_option_variable; 768 OptionGroupFormat m_option_format; 769 OptionGroupFileList m_option_compile_units; 770 OptionGroupFileList m_option_shared_libraries; 771 OptionGroupValueObjectDisplay m_varobj_options; 772 773 }; 774 775 776 #pragma mark CommandObjectTargetModulesSearchPathsAdd 777 778 class CommandObjectTargetModulesSearchPathsAdd : public CommandObject 779 { 780 public: 781 782 CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) : 783 CommandObject (interpreter, 784 "target modules search-paths add", 785 "Add new image search paths substitution pairs to the current target.", 786 NULL) 787 { 788 CommandArgumentEntry arg; 789 CommandArgumentData old_prefix_arg; 790 CommandArgumentData new_prefix_arg; 791 792 // Define the first variant of this arg pair. 793 old_prefix_arg.arg_type = eArgTypeOldPathPrefix; 794 old_prefix_arg.arg_repetition = eArgRepeatPairPlus; 795 796 // Define the first variant of this arg pair. 797 new_prefix_arg.arg_type = eArgTypeNewPathPrefix; 798 new_prefix_arg.arg_repetition = eArgRepeatPairPlus; 799 800 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they 801 // must always occur together, they are treated as two variants of one argument rather than two independent 802 // arguments. Push them both into the first argument position for m_arguments... 803 804 arg.push_back (old_prefix_arg); 805 arg.push_back (new_prefix_arg); 806 807 m_arguments.push_back (arg); 808 } 809 810 ~CommandObjectTargetModulesSearchPathsAdd () 811 { 812 } 813 814 bool 815 Execute (Args& command, 816 CommandReturnObject &result) 817 { 818 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 819 if (target) 820 { 821 uint32_t argc = command.GetArgumentCount(); 822 if (argc & 1) 823 { 824 result.AppendError ("add requires an even number of arguments\n"); 825 result.SetStatus (eReturnStatusFailed); 826 } 827 else 828 { 829 for (uint32_t i=0; i<argc; i+=2) 830 { 831 const char *from = command.GetArgumentAtIndex(i); 832 const char *to = command.GetArgumentAtIndex(i+1); 833 834 if (from[0] && to[0]) 835 { 836 bool last_pair = ((argc - i) == 2); 837 target->GetImageSearchPathList().Append (ConstString(from), 838 ConstString(to), 839 last_pair); // Notify if this is the last pair 840 result.SetStatus (eReturnStatusSuccessFinishNoResult); 841 } 842 else 843 { 844 if (from[0]) 845 result.AppendError ("<path-prefix> can't be empty\n"); 846 else 847 result.AppendError ("<new-path-prefix> can't be empty\n"); 848 result.SetStatus (eReturnStatusFailed); 849 } 850 } 851 } 852 } 853 else 854 { 855 result.AppendError ("invalid target\n"); 856 result.SetStatus (eReturnStatusFailed); 857 } 858 return result.Succeeded(); 859 } 860 }; 861 862 #pragma mark CommandObjectTargetModulesSearchPathsClear 863 864 class CommandObjectTargetModulesSearchPathsClear : public CommandObject 865 { 866 public: 867 868 CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) : 869 CommandObject (interpreter, 870 "target modules search-paths clear", 871 "Clear all current image search path substitution pairs from the current target.", 872 "target modules search-paths clear") 873 { 874 } 875 876 ~CommandObjectTargetModulesSearchPathsClear () 877 { 878 } 879 880 bool 881 Execute (Args& command, 882 CommandReturnObject &result) 883 { 884 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 885 if (target) 886 { 887 bool notify = true; 888 target->GetImageSearchPathList().Clear(notify); 889 result.SetStatus (eReturnStatusSuccessFinishNoResult); 890 } 891 else 892 { 893 result.AppendError ("invalid target\n"); 894 result.SetStatus (eReturnStatusFailed); 895 } 896 return result.Succeeded(); 897 } 898 }; 899 900 #pragma mark CommandObjectTargetModulesSearchPathsInsert 901 902 class CommandObjectTargetModulesSearchPathsInsert : public CommandObject 903 { 904 public: 905 906 CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) : 907 CommandObject (interpreter, 908 "target modules search-paths insert", 909 "Insert a new image search path substitution pair into the current target at the specified index.", 910 NULL) 911 { 912 CommandArgumentEntry arg1; 913 CommandArgumentEntry arg2; 914 CommandArgumentData index_arg; 915 CommandArgumentData old_prefix_arg; 916 CommandArgumentData new_prefix_arg; 917 918 // Define the first and only variant of this arg. 919 index_arg.arg_type = eArgTypeIndex; 920 index_arg.arg_repetition = eArgRepeatPlain; 921 922 // Put the one and only variant into the first arg for m_arguments: 923 arg1.push_back (index_arg); 924 925 // Define the first variant of this arg pair. 926 old_prefix_arg.arg_type = eArgTypeOldPathPrefix; 927 old_prefix_arg.arg_repetition = eArgRepeatPairPlus; 928 929 // Define the first variant of this arg pair. 930 new_prefix_arg.arg_type = eArgTypeNewPathPrefix; 931 new_prefix_arg.arg_repetition = eArgRepeatPairPlus; 932 933 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they 934 // must always occur together, they are treated as two variants of one argument rather than two independent 935 // arguments. Push them both into the same argument position for m_arguments... 936 937 arg2.push_back (old_prefix_arg); 938 arg2.push_back (new_prefix_arg); 939 940 // Add arguments to m_arguments. 941 m_arguments.push_back (arg1); 942 m_arguments.push_back (arg2); 943 } 944 945 ~CommandObjectTargetModulesSearchPathsInsert () 946 { 947 } 948 949 bool 950 Execute (Args& command, 951 CommandReturnObject &result) 952 { 953 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 954 if (target) 955 { 956 uint32_t argc = command.GetArgumentCount(); 957 // check for at least 3 arguments and an odd nubmer of parameters 958 if (argc >= 3 && argc & 1) 959 { 960 bool success = false; 961 962 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success); 963 964 if (!success) 965 { 966 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0)); 967 result.SetStatus (eReturnStatusFailed); 968 return result.Succeeded(); 969 } 970 971 // shift off the index 972 command.Shift(); 973 argc = command.GetArgumentCount(); 974 975 for (uint32_t i=0; i<argc; i+=2, ++insert_idx) 976 { 977 const char *from = command.GetArgumentAtIndex(i); 978 const char *to = command.GetArgumentAtIndex(i+1); 979 980 if (from[0] && to[0]) 981 { 982 bool last_pair = ((argc - i) == 2); 983 target->GetImageSearchPathList().Insert (ConstString(from), 984 ConstString(to), 985 insert_idx, 986 last_pair); 987 result.SetStatus (eReturnStatusSuccessFinishNoResult); 988 } 989 else 990 { 991 if (from[0]) 992 result.AppendError ("<path-prefix> can't be empty\n"); 993 else 994 result.AppendError ("<new-path-prefix> can't be empty\n"); 995 result.SetStatus (eReturnStatusFailed); 996 return false; 997 } 998 } 999 } 1000 else 1001 { 1002 result.AppendError ("insert requires at least three arguments\n"); 1003 result.SetStatus (eReturnStatusFailed); 1004 return result.Succeeded(); 1005 } 1006 1007 } 1008 else 1009 { 1010 result.AppendError ("invalid target\n"); 1011 result.SetStatus (eReturnStatusFailed); 1012 } 1013 return result.Succeeded(); 1014 } 1015 }; 1016 1017 1018 #pragma mark CommandObjectTargetModulesSearchPathsList 1019 1020 1021 class CommandObjectTargetModulesSearchPathsList : public CommandObject 1022 { 1023 public: 1024 1025 CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) : 1026 CommandObject (interpreter, 1027 "target modules search-paths list", 1028 "List all current image search path substitution pairs in the current target.", 1029 "target modules search-paths list") 1030 { 1031 } 1032 1033 ~CommandObjectTargetModulesSearchPathsList () 1034 { 1035 } 1036 1037 bool 1038 Execute (Args& command, 1039 CommandReturnObject &result) 1040 { 1041 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1042 if (target) 1043 { 1044 if (command.GetArgumentCount() != 0) 1045 { 1046 result.AppendError ("list takes no arguments\n"); 1047 result.SetStatus (eReturnStatusFailed); 1048 return result.Succeeded(); 1049 } 1050 1051 target->GetImageSearchPathList().Dump(&result.GetOutputStream()); 1052 result.SetStatus (eReturnStatusSuccessFinishResult); 1053 } 1054 else 1055 { 1056 result.AppendError ("invalid target\n"); 1057 result.SetStatus (eReturnStatusFailed); 1058 } 1059 return result.Succeeded(); 1060 } 1061 }; 1062 1063 #pragma mark CommandObjectTargetModulesSearchPathsQuery 1064 1065 class CommandObjectTargetModulesSearchPathsQuery : public CommandObject 1066 { 1067 public: 1068 1069 CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) : 1070 CommandObject (interpreter, 1071 "target modules search-paths query", 1072 "Transform a path using the first applicable image search path.", 1073 NULL) 1074 { 1075 CommandArgumentEntry arg; 1076 CommandArgumentData path_arg; 1077 1078 // Define the first (and only) variant of this arg. 1079 path_arg.arg_type = eArgTypePath; 1080 path_arg.arg_repetition = eArgRepeatPlain; 1081 1082 // There is only one variant this argument could be; put it into the argument entry. 1083 arg.push_back (path_arg); 1084 1085 // Push the data for the first argument into the m_arguments vector. 1086 m_arguments.push_back (arg); 1087 } 1088 1089 ~CommandObjectTargetModulesSearchPathsQuery () 1090 { 1091 } 1092 1093 bool 1094 Execute (Args& command, 1095 CommandReturnObject &result) 1096 { 1097 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1098 if (target) 1099 { 1100 if (command.GetArgumentCount() != 1) 1101 { 1102 result.AppendError ("query requires one argument\n"); 1103 result.SetStatus (eReturnStatusFailed); 1104 return result.Succeeded(); 1105 } 1106 1107 ConstString orig(command.GetArgumentAtIndex(0)); 1108 ConstString transformed; 1109 if (target->GetImageSearchPathList().RemapPath(orig, transformed)) 1110 result.GetOutputStream().Printf("%s\n", transformed.GetCString()); 1111 else 1112 result.GetOutputStream().Printf("%s\n", orig.GetCString()); 1113 1114 result.SetStatus (eReturnStatusSuccessFinishResult); 1115 } 1116 else 1117 { 1118 result.AppendError ("invalid target\n"); 1119 result.SetStatus (eReturnStatusFailed); 1120 } 1121 return result.Succeeded(); 1122 } 1123 }; 1124 1125 //---------------------------------------------------------------------- 1126 // Static Helper functions 1127 //---------------------------------------------------------------------- 1128 static void 1129 DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width) 1130 { 1131 if (module) 1132 { 1133 const char *arch_cstr; 1134 if (full_triple) 1135 arch_cstr = module->GetArchitecture().GetTriple().str().c_str(); 1136 else 1137 arch_cstr = module->GetArchitecture().GetArchitectureName(); 1138 if (width) 1139 strm.Printf("%-*s", width, arch_cstr); 1140 else 1141 strm.PutCString(arch_cstr); 1142 } 1143 } 1144 1145 static void 1146 DumpModuleUUID (Stream &strm, Module *module) 1147 { 1148 if (module->GetUUID().IsValid()) 1149 module->GetUUID().Dump (&strm); 1150 else 1151 strm.PutCString(" "); 1152 } 1153 1154 static uint32_t 1155 DumpCompileUnitLineTable 1156 ( 1157 CommandInterpreter &interpreter, 1158 Stream &strm, 1159 Module *module, 1160 const FileSpec &file_spec, 1161 bool load_addresses 1162 ) 1163 { 1164 uint32_t num_matches = 0; 1165 if (module) 1166 { 1167 SymbolContextList sc_list; 1168 num_matches = module->ResolveSymbolContextsForFileSpec (file_spec, 1169 0, 1170 false, 1171 eSymbolContextCompUnit, 1172 sc_list); 1173 1174 for (uint32_t i=0; i<num_matches; ++i) 1175 { 1176 SymbolContext sc; 1177 if (sc_list.GetContextAtIndex(i, sc)) 1178 { 1179 if (i > 0) 1180 strm << "\n\n"; 1181 1182 strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `" 1183 << module->GetFileSpec().GetFilename() << "\n"; 1184 LineTable *line_table = sc.comp_unit->GetLineTable(); 1185 if (line_table) 1186 line_table->GetDescription (&strm, 1187 interpreter.GetExecutionContext().GetTargetPtr(), 1188 lldb::eDescriptionLevelBrief); 1189 else 1190 strm << "No line table"; 1191 } 1192 } 1193 } 1194 return num_matches; 1195 } 1196 1197 static void 1198 DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) 1199 { 1200 if (file_spec_ptr) 1201 { 1202 if (width > 0) 1203 { 1204 char fullpath[PATH_MAX]; 1205 if (file_spec_ptr->GetPath(fullpath, sizeof(fullpath))) 1206 { 1207 strm.Printf("%-*s", width, fullpath); 1208 return; 1209 } 1210 } 1211 else 1212 { 1213 file_spec_ptr->Dump(&strm); 1214 return; 1215 } 1216 } 1217 // Keep the width spacing correct if things go wrong... 1218 if (width > 0) 1219 strm.Printf("%-*s", width, ""); 1220 } 1221 1222 static void 1223 DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) 1224 { 1225 if (file_spec_ptr) 1226 { 1227 if (width > 0) 1228 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString("")); 1229 else 1230 file_spec_ptr->GetDirectory().Dump(&strm); 1231 return; 1232 } 1233 // Keep the width spacing correct if things go wrong... 1234 if (width > 0) 1235 strm.Printf("%-*s", width, ""); 1236 } 1237 1238 static void 1239 DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) 1240 { 1241 if (file_spec_ptr) 1242 { 1243 if (width > 0) 1244 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString("")); 1245 else 1246 file_spec_ptr->GetFilename().Dump(&strm); 1247 return; 1248 } 1249 // Keep the width spacing correct if things go wrong... 1250 if (width > 0) 1251 strm.Printf("%-*s", width, ""); 1252 } 1253 1254 1255 static void 1256 DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order) 1257 { 1258 if (module) 1259 { 1260 ObjectFile *objfile = module->GetObjectFile (); 1261 if (objfile) 1262 { 1263 Symtab *symtab = objfile->GetSymtab(); 1264 if (symtab) 1265 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), sort_order); 1266 } 1267 } 1268 } 1269 1270 static void 1271 DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module) 1272 { 1273 if (module) 1274 { 1275 ObjectFile *objfile = module->GetObjectFile (); 1276 if (objfile) 1277 { 1278 SectionList *section_list = objfile->GetSectionList(); 1279 if (section_list) 1280 { 1281 strm.PutCString ("Sections for '"); 1282 strm << module->GetFileSpec(); 1283 if (module->GetObjectName()) 1284 strm << '(' << module->GetObjectName() << ')'; 1285 strm.Printf ("' (%s):\n", module->GetArchitecture().GetArchitectureName()); 1286 strm.IndentMore(); 1287 section_list->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX); 1288 strm.IndentLess(); 1289 } 1290 } 1291 } 1292 } 1293 1294 static bool 1295 DumpModuleSymbolVendor (Stream &strm, Module *module) 1296 { 1297 if (module) 1298 { 1299 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true); 1300 if (symbol_vendor) 1301 { 1302 symbol_vendor->Dump(&strm); 1303 return true; 1304 } 1305 } 1306 return false; 1307 } 1308 1309 static bool 1310 LookupAddressInModule 1311 ( 1312 CommandInterpreter &interpreter, 1313 Stream &strm, 1314 Module *module, 1315 uint32_t resolve_mask, 1316 lldb::addr_t raw_addr, 1317 lldb::addr_t offset, 1318 bool verbose 1319 ) 1320 { 1321 if (module) 1322 { 1323 lldb::addr_t addr = raw_addr - offset; 1324 Address so_addr; 1325 SymbolContext sc; 1326 Target *target = interpreter.GetExecutionContext().GetTargetPtr(); 1327 if (target && !target->GetSectionLoadList().IsEmpty()) 1328 { 1329 if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr)) 1330 return false; 1331 else if (so_addr.GetModule() != module) 1332 return false; 1333 } 1334 else 1335 { 1336 if (!module->ResolveFileAddress (addr, so_addr)) 1337 return false; 1338 } 1339 1340 // If an offset was given, print out the address we ended up looking up 1341 if (offset) 1342 strm.Printf("File Address: 0x%llx\n", addr); 1343 1344 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope(); 1345 strm.IndentMore(); 1346 strm.Indent (" Address: "); 1347 so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset); 1348 strm.EOL(); 1349 strm.Indent (" Summary: "); 1350 const uint32_t save_indent = strm.GetIndentLevel (); 1351 strm.SetIndentLevel (save_indent + 13); 1352 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription); 1353 strm.SetIndentLevel (save_indent); 1354 // Print out detailed address information when verbose is enabled 1355 if (verbose) 1356 { 1357 strm.EOL(); 1358 so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext); 1359 } 1360 strm.IndentLess(); 1361 return true; 1362 } 1363 1364 return false; 1365 } 1366 1367 static uint32_t 1368 LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex) 1369 { 1370 if (module) 1371 { 1372 SymbolContext sc; 1373 1374 ObjectFile *objfile = module->GetObjectFile (); 1375 if (objfile) 1376 { 1377 Symtab *symtab = objfile->GetSymtab(); 1378 if (symtab) 1379 { 1380 uint32_t i; 1381 std::vector<uint32_t> match_indexes; 1382 ConstString symbol_name (name); 1383 uint32_t num_matches = 0; 1384 if (name_is_regex) 1385 { 1386 RegularExpression name_regexp(name); 1387 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp, 1388 eSymbolTypeAny, 1389 match_indexes); 1390 } 1391 else 1392 { 1393 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes); 1394 } 1395 1396 1397 if (num_matches > 0) 1398 { 1399 strm.Indent (); 1400 strm.Printf("%u symbols match %s'%s' in ", num_matches, 1401 name_is_regex ? "the regular expression " : "", name); 1402 DumpFullpath (strm, &module->GetFileSpec(), 0); 1403 strm.PutCString(":\n"); 1404 strm.IndentMore (); 1405 Symtab::DumpSymbolHeader (&strm); 1406 for (i=0; i < num_matches; ++i) 1407 { 1408 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]); 1409 strm.Indent (); 1410 symbol->Dump (&strm, interpreter.GetExecutionContext().GetTargetPtr(), i); 1411 } 1412 strm.IndentLess (); 1413 return num_matches; 1414 } 1415 } 1416 } 1417 } 1418 return 0; 1419 } 1420 1421 1422 static void 1423 DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr, bool verbose) 1424 { 1425 strm.IndentMore (); 1426 uint32_t i; 1427 const uint32_t num_matches = sc_list.GetSize(); 1428 1429 for (i=0; i<num_matches; ++i) 1430 { 1431 SymbolContext sc; 1432 if (sc_list.GetContextAtIndex(i, sc)) 1433 { 1434 strm.Indent(); 1435 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope (); 1436 1437 if (prepend_addr) 1438 { 1439 if (sc.line_entry.range.GetBaseAddress().IsValid()) 1440 { 1441 sc.line_entry.range.GetBaseAddress().Dump (&strm, 1442 exe_scope, 1443 Address::DumpStyleLoadAddress, 1444 Address::DumpStyleModuleWithFileAddress); 1445 strm.PutCString(" in "); 1446 } 1447 } 1448 sc.DumpStopContext(&strm, 1449 exe_scope, 1450 sc.line_entry.range.GetBaseAddress(), 1451 true, 1452 true, 1453 false); 1454 strm.EOL(); 1455 if (verbose) 1456 { 1457 if (sc.line_entry.range.GetBaseAddress().IsValid()) 1458 { 1459 if (sc.line_entry.range.GetBaseAddress().Dump (&strm, 1460 exe_scope, 1461 Address::DumpStyleDetailedSymbolContext)) 1462 strm.PutCString("\n\n"); 1463 } 1464 else if (sc.function->GetAddressRange().GetBaseAddress().IsValid()) 1465 { 1466 if (sc.function->GetAddressRange().GetBaseAddress().Dump (&strm, 1467 exe_scope, 1468 Address::DumpStyleDetailedSymbolContext)) 1469 strm.PutCString("\n\n"); 1470 } 1471 } 1472 } 1473 } 1474 strm.IndentLess (); 1475 } 1476 1477 static uint32_t 1478 LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose) 1479 { 1480 if (module && name && name[0]) 1481 { 1482 SymbolContextList sc_list; 1483 const bool include_symbols = false; 1484 const bool append = true; 1485 uint32_t num_matches = 0; 1486 if (name_is_regex) 1487 { 1488 RegularExpression function_name_regex (name); 1489 num_matches = module->FindFunctions (function_name_regex, 1490 include_symbols, 1491 append, 1492 sc_list); 1493 } 1494 else 1495 { 1496 ConstString function_name (name); 1497 num_matches = module->FindFunctions (function_name, 1498 NULL, 1499 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector, 1500 include_symbols, 1501 append, 1502 sc_list); 1503 } 1504 1505 if (num_matches) 1506 { 1507 strm.Indent (); 1508 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1509 DumpFullpath (strm, &module->GetFileSpec(), 0); 1510 strm.PutCString(":\n"); 1511 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose); 1512 } 1513 return num_matches; 1514 } 1515 return 0; 1516 } 1517 1518 static uint32_t 1519 LookupTypeInModule (CommandInterpreter &interpreter, 1520 Stream &strm, 1521 Module *module, 1522 const char *name_cstr, 1523 bool name_is_regex) 1524 { 1525 if (module && name_cstr && name_cstr[0]) 1526 { 1527 /*SymbolContextList sc_list; 1528 1529 SymbolVendor *symbol_vendor = module->GetSymbolVendor(); 1530 if (symbol_vendor) 1531 {*/ 1532 TypeList type_list; 1533 uint32_t num_matches = 0; 1534 SymbolContext sc; 1535 // if (name_is_regex) 1536 // { 1537 // RegularExpression name_regex (name_cstr); 1538 // num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list); 1539 // } 1540 // else 1541 // { 1542 ConstString name(name_cstr); 1543 num_matches = module->FindTypes(sc, name, NULL, true, UINT32_MAX, type_list); 1544 // } 1545 1546 if (num_matches) 1547 { 1548 strm.Indent (); 1549 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1550 DumpFullpath (strm, &module->GetFileSpec(), 0); 1551 strm.PutCString(":\n"); 1552 const uint32_t num_types = type_list.GetSize(); 1553 for (uint32_t i=0; i<num_types; ++i) 1554 { 1555 TypeSP type_sp (type_list.GetTypeAtIndex(i)); 1556 if (type_sp) 1557 { 1558 // Resolve the clang type so that any forward references 1559 // to types that haven't yet been parsed will get parsed. 1560 type_sp->GetClangFullType (); 1561 type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1562 } 1563 strm.EOL(); 1564 } 1565 } 1566 return num_matches; 1567 //} 1568 } 1569 return 0; 1570 } 1571 1572 static uint32_t 1573 LookupFileAndLineInModule (CommandInterpreter &interpreter, 1574 Stream &strm, 1575 Module *module, 1576 const FileSpec &file_spec, 1577 uint32_t line, 1578 bool check_inlines, 1579 bool verbose) 1580 { 1581 if (module && file_spec) 1582 { 1583 SymbolContextList sc_list; 1584 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, 1585 eSymbolContextEverything, sc_list); 1586 if (num_matches > 0) 1587 { 1588 strm.Indent (); 1589 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1590 strm << file_spec; 1591 if (line > 0) 1592 strm.Printf (":%u", line); 1593 strm << " in "; 1594 DumpFullpath (strm, &module->GetFileSpec(), 0); 1595 strm.PutCString(":\n"); 1596 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose); 1597 return num_matches; 1598 } 1599 } 1600 return 0; 1601 1602 } 1603 1604 1605 static size_t 1606 FindModulesByName (Target *target, 1607 const char *module_name, 1608 ModuleList &module_list, 1609 bool check_global_list) 1610 { 1611 // Dump specified images (by basename or fullpath) 1612 FileSpec module_file_spec(module_name, false); 1613 1614 const size_t initial_size = module_list.GetSize (); 1615 1616 size_t num_matches = 0; 1617 1618 if (target) 1619 { 1620 num_matches = target->GetImages().FindModules (&module_file_spec, 1621 NULL, 1622 NULL, 1623 NULL, 1624 module_list); 1625 1626 // Not found in our module list for our target, check the main 1627 // shared module list in case it is a extra file used somewhere 1628 // else 1629 if (num_matches == 0) 1630 num_matches = ModuleList::FindSharedModules (module_file_spec, 1631 target->GetArchitecture(), 1632 NULL, 1633 NULL, 1634 module_list); 1635 } 1636 else 1637 { 1638 num_matches = ModuleList::FindSharedModules (module_file_spec, 1639 ArchSpec(), 1640 NULL, 1641 NULL, 1642 module_list); 1643 } 1644 1645 if (check_global_list && num_matches == 0) 1646 { 1647 // Check the global list 1648 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex().GetMutex()); 1649 const uint32_t num_modules = Module::GetNumberAllocatedModules(); 1650 ModuleSP module_sp; 1651 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 1652 { 1653 Module *module = Module::GetAllocatedModuleAtIndex(image_idx); 1654 1655 if (module) 1656 { 1657 if (FileSpec::Equal(module->GetFileSpec(), module_file_spec, true)) 1658 { 1659 module_sp = module; 1660 module_list.AppendIfNeeded(module_sp); 1661 } 1662 } 1663 } 1664 } 1665 return module_list.GetSize () - initial_size; 1666 } 1667 1668 #pragma mark CommandObjectTargetModulesModuleAutoComplete 1669 1670 //---------------------------------------------------------------------- 1671 // A base command object class that can auto complete with module file 1672 // paths 1673 //---------------------------------------------------------------------- 1674 1675 class CommandObjectTargetModulesModuleAutoComplete : public CommandObject 1676 { 1677 public: 1678 1679 CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter, 1680 const char *name, 1681 const char *help, 1682 const char *syntax) : 1683 CommandObject (interpreter, name, help, syntax) 1684 { 1685 CommandArgumentEntry arg; 1686 CommandArgumentData file_arg; 1687 1688 // Define the first (and only) variant of this arg. 1689 file_arg.arg_type = eArgTypeFilename; 1690 file_arg.arg_repetition = eArgRepeatStar; 1691 1692 // There is only one variant this argument could be; put it into the argument entry. 1693 arg.push_back (file_arg); 1694 1695 // Push the data for the first argument into the m_arguments vector. 1696 m_arguments.push_back (arg); 1697 } 1698 1699 virtual 1700 ~CommandObjectTargetModulesModuleAutoComplete () 1701 { 1702 } 1703 1704 virtual int 1705 HandleArgumentCompletion (Args &input, 1706 int &cursor_index, 1707 int &cursor_char_position, 1708 OptionElementVector &opt_element_vector, 1709 int match_start_point, 1710 int max_return_elements, 1711 bool &word_complete, 1712 StringList &matches) 1713 { 1714 // Arguments are the standard module completer. 1715 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1716 completion_str.erase (cursor_char_position); 1717 1718 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1719 CommandCompletions::eModuleCompletion, 1720 completion_str.c_str(), 1721 match_start_point, 1722 max_return_elements, 1723 NULL, 1724 word_complete, 1725 matches); 1726 return matches.GetSize(); 1727 } 1728 }; 1729 1730 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete 1731 1732 //---------------------------------------------------------------------- 1733 // A base command object class that can auto complete with module source 1734 // file paths 1735 //---------------------------------------------------------------------- 1736 1737 class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObject 1738 { 1739 public: 1740 1741 CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter, 1742 const char *name, 1743 const char *help, 1744 const char *syntax) : 1745 CommandObject (interpreter, name, help, syntax) 1746 { 1747 CommandArgumentEntry arg; 1748 CommandArgumentData source_file_arg; 1749 1750 // Define the first (and only) variant of this arg. 1751 source_file_arg.arg_type = eArgTypeSourceFile; 1752 source_file_arg.arg_repetition = eArgRepeatPlus; 1753 1754 // There is only one variant this argument could be; put it into the argument entry. 1755 arg.push_back (source_file_arg); 1756 1757 // Push the data for the first argument into the m_arguments vector. 1758 m_arguments.push_back (arg); 1759 } 1760 1761 virtual 1762 ~CommandObjectTargetModulesSourceFileAutoComplete () 1763 { 1764 } 1765 1766 virtual int 1767 HandleArgumentCompletion (Args &input, 1768 int &cursor_index, 1769 int &cursor_char_position, 1770 OptionElementVector &opt_element_vector, 1771 int match_start_point, 1772 int max_return_elements, 1773 bool &word_complete, 1774 StringList &matches) 1775 { 1776 // Arguments are the standard source file completer. 1777 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1778 completion_str.erase (cursor_char_position); 1779 1780 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1781 CommandCompletions::eSourceFileCompletion, 1782 completion_str.c_str(), 1783 match_start_point, 1784 max_return_elements, 1785 NULL, 1786 word_complete, 1787 matches); 1788 return matches.GetSize(); 1789 } 1790 }; 1791 1792 1793 #pragma mark CommandObjectTargetModulesDumpSymtab 1794 1795 1796 class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete 1797 { 1798 public: 1799 CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) : 1800 CommandObjectTargetModulesModuleAutoComplete (interpreter, 1801 "target modules dump symtab", 1802 "Dump the symbol table from one or more target modules.", 1803 NULL), 1804 m_options (interpreter) 1805 { 1806 } 1807 1808 virtual 1809 ~CommandObjectTargetModulesDumpSymtab () 1810 { 1811 } 1812 1813 virtual bool 1814 Execute (Args& command, 1815 CommandReturnObject &result) 1816 { 1817 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1818 if (target == NULL) 1819 { 1820 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 1821 result.SetStatus (eReturnStatusFailed); 1822 return false; 1823 } 1824 else 1825 { 1826 uint32_t num_dumped = 0; 1827 1828 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 1829 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 1830 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 1831 1832 if (command.GetArgumentCount() == 0) 1833 { 1834 // Dump all sections for all modules images 1835 const uint32_t num_modules = target->GetImages().GetSize(); 1836 if (num_modules > 0) 1837 { 1838 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules); 1839 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 1840 { 1841 if (num_dumped > 0) 1842 { 1843 result.GetOutputStream().EOL(); 1844 result.GetOutputStream().EOL(); 1845 } 1846 num_dumped++; 1847 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order); 1848 } 1849 } 1850 else 1851 { 1852 result.AppendError ("the target has no associated executable images"); 1853 result.SetStatus (eReturnStatusFailed); 1854 return false; 1855 } 1856 } 1857 else 1858 { 1859 // Dump specified images (by basename or fullpath) 1860 const char *arg_cstr; 1861 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 1862 { 1863 ModuleList module_list; 1864 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 1865 if (num_matches > 0) 1866 { 1867 for (size_t i=0; i<num_matches; ++i) 1868 { 1869 Module *module = module_list.GetModulePointerAtIndex(i); 1870 if (module) 1871 { 1872 if (num_dumped > 0) 1873 { 1874 result.GetOutputStream().EOL(); 1875 result.GetOutputStream().EOL(); 1876 } 1877 num_dumped++; 1878 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order); 1879 } 1880 } 1881 } 1882 else 1883 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 1884 } 1885 } 1886 1887 if (num_dumped > 0) 1888 result.SetStatus (eReturnStatusSuccessFinishResult); 1889 else 1890 { 1891 result.AppendError ("no matching executable images found"); 1892 result.SetStatus (eReturnStatusFailed); 1893 } 1894 } 1895 return result.Succeeded(); 1896 } 1897 1898 virtual Options * 1899 GetOptions () 1900 { 1901 return &m_options; 1902 } 1903 1904 class CommandOptions : public Options 1905 { 1906 public: 1907 1908 CommandOptions (CommandInterpreter &interpreter) : 1909 Options(interpreter), 1910 m_sort_order (eSortOrderNone) 1911 { 1912 } 1913 1914 virtual 1915 ~CommandOptions () 1916 { 1917 } 1918 1919 virtual Error 1920 SetOptionValue (uint32_t option_idx, const char *option_arg) 1921 { 1922 Error error; 1923 char short_option = (char) m_getopt_table[option_idx].val; 1924 1925 switch (short_option) 1926 { 1927 case 's': 1928 m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg, 1929 g_option_table[option_idx].enum_values, 1930 eSortOrderNone, 1931 error); 1932 break; 1933 1934 default: 1935 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 1936 break; 1937 1938 } 1939 return error; 1940 } 1941 1942 void 1943 OptionParsingStarting () 1944 { 1945 m_sort_order = eSortOrderNone; 1946 } 1947 1948 const OptionDefinition* 1949 GetDefinitions () 1950 { 1951 return g_option_table; 1952 } 1953 1954 // Options table: Required for subclasses of Options. 1955 static OptionDefinition g_option_table[]; 1956 1957 SortOrder m_sort_order; 1958 }; 1959 1960 protected: 1961 1962 CommandOptions m_options; 1963 }; 1964 1965 static OptionEnumValueElement 1966 g_sort_option_enumeration[4] = 1967 { 1968 { eSortOrderNone, "none", "No sorting, use the original symbol table order."}, 1969 { eSortOrderByAddress, "address", "Sort output by symbol address."}, 1970 { eSortOrderByName, "name", "Sort output by symbol name."}, 1971 { 0, NULL, NULL } 1972 }; 1973 1974 1975 OptionDefinition 1976 CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] = 1977 { 1978 { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."}, 1979 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 1980 }; 1981 1982 #pragma mark CommandObjectTargetModulesDumpSections 1983 1984 //---------------------------------------------------------------------- 1985 // Image section dumping command 1986 //---------------------------------------------------------------------- 1987 1988 class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete 1989 { 1990 public: 1991 CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) : 1992 CommandObjectTargetModulesModuleAutoComplete (interpreter, 1993 "target modules dump sections", 1994 "Dump the sections from one or more target modules.", 1995 //"target modules dump sections [<file1> ...]") 1996 NULL) 1997 { 1998 } 1999 2000 virtual 2001 ~CommandObjectTargetModulesDumpSections () 2002 { 2003 } 2004 2005 virtual bool 2006 Execute (Args& command, 2007 CommandReturnObject &result) 2008 { 2009 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2010 if (target == NULL) 2011 { 2012 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2013 result.SetStatus (eReturnStatusFailed); 2014 return false; 2015 } 2016 else 2017 { 2018 uint32_t num_dumped = 0; 2019 2020 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2021 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2022 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2023 2024 if (command.GetArgumentCount() == 0) 2025 { 2026 // Dump all sections for all modules images 2027 const uint32_t num_modules = target->GetImages().GetSize(); 2028 if (num_modules > 0) 2029 { 2030 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules); 2031 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2032 { 2033 num_dumped++; 2034 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)); 2035 } 2036 } 2037 else 2038 { 2039 result.AppendError ("the target has no associated executable images"); 2040 result.SetStatus (eReturnStatusFailed); 2041 return false; 2042 } 2043 } 2044 else 2045 { 2046 // Dump specified images (by basename or fullpath) 2047 const char *arg_cstr; 2048 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2049 { 2050 ModuleList module_list; 2051 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2052 if (num_matches > 0) 2053 { 2054 for (size_t i=0; i<num_matches; ++i) 2055 { 2056 Module *module = module_list.GetModulePointerAtIndex(i); 2057 if (module) 2058 { 2059 num_dumped++; 2060 DumpModuleSections (m_interpreter, result.GetOutputStream(), module); 2061 } 2062 } 2063 } 2064 else 2065 { 2066 // Check the global list 2067 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex().GetMutex()); 2068 2069 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2070 } 2071 } 2072 } 2073 2074 if (num_dumped > 0) 2075 result.SetStatus (eReturnStatusSuccessFinishResult); 2076 else 2077 { 2078 result.AppendError ("no matching executable images found"); 2079 result.SetStatus (eReturnStatusFailed); 2080 } 2081 } 2082 return result.Succeeded(); 2083 } 2084 }; 2085 2086 2087 #pragma mark CommandObjectTargetModulesDumpSymfile 2088 2089 //---------------------------------------------------------------------- 2090 // Image debug symbol dumping command 2091 //---------------------------------------------------------------------- 2092 2093 class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete 2094 { 2095 public: 2096 CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) : 2097 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2098 "target modules dump symfile", 2099 "Dump the debug symbol file for one or more target modules.", 2100 //"target modules dump symfile [<file1> ...]") 2101 NULL) 2102 { 2103 } 2104 2105 virtual 2106 ~CommandObjectTargetModulesDumpSymfile () 2107 { 2108 } 2109 2110 virtual bool 2111 Execute (Args& command, 2112 CommandReturnObject &result) 2113 { 2114 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2115 if (target == NULL) 2116 { 2117 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2118 result.SetStatus (eReturnStatusFailed); 2119 return false; 2120 } 2121 else 2122 { 2123 uint32_t num_dumped = 0; 2124 2125 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2126 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2127 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2128 2129 if (command.GetArgumentCount() == 0) 2130 { 2131 // Dump all sections for all modules images 2132 const uint32_t num_modules = target->GetImages().GetSize(); 2133 if (num_modules > 0) 2134 { 2135 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules); 2136 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2137 { 2138 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx))) 2139 num_dumped++; 2140 } 2141 } 2142 else 2143 { 2144 result.AppendError ("the target has no associated executable images"); 2145 result.SetStatus (eReturnStatusFailed); 2146 return false; 2147 } 2148 } 2149 else 2150 { 2151 // Dump specified images (by basename or fullpath) 2152 const char *arg_cstr; 2153 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2154 { 2155 ModuleList module_list; 2156 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2157 if (num_matches > 0) 2158 { 2159 for (size_t i=0; i<num_matches; ++i) 2160 { 2161 Module *module = module_list.GetModulePointerAtIndex(i); 2162 if (module) 2163 { 2164 if (DumpModuleSymbolVendor (result.GetOutputStream(), module)) 2165 num_dumped++; 2166 } 2167 } 2168 } 2169 else 2170 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2171 } 2172 } 2173 2174 if (num_dumped > 0) 2175 result.SetStatus (eReturnStatusSuccessFinishResult); 2176 else 2177 { 2178 result.AppendError ("no matching executable images found"); 2179 result.SetStatus (eReturnStatusFailed); 2180 } 2181 } 2182 return result.Succeeded(); 2183 } 2184 }; 2185 2186 2187 #pragma mark CommandObjectTargetModulesDumpLineTable 2188 2189 //---------------------------------------------------------------------- 2190 // Image debug line table dumping command 2191 //---------------------------------------------------------------------- 2192 2193 class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete 2194 { 2195 public: 2196 CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) : 2197 CommandObjectTargetModulesSourceFileAutoComplete (interpreter, 2198 "target modules dump line-table", 2199 "Dump the debug symbol file for one or more target modules.", 2200 NULL) 2201 { 2202 } 2203 2204 virtual 2205 ~CommandObjectTargetModulesDumpLineTable () 2206 { 2207 } 2208 2209 virtual bool 2210 Execute (Args& command, 2211 CommandReturnObject &result) 2212 { 2213 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2214 if (target == NULL) 2215 { 2216 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2217 result.SetStatus (eReturnStatusFailed); 2218 return false; 2219 } 2220 else 2221 { 2222 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 2223 uint32_t total_num_dumped = 0; 2224 2225 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2226 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2227 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2228 2229 if (command.GetArgumentCount() == 0) 2230 { 2231 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str()); 2232 result.SetStatus (eReturnStatusFailed); 2233 } 2234 else 2235 { 2236 // Dump specified images (by basename or fullpath) 2237 const char *arg_cstr; 2238 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2239 { 2240 FileSpec file_spec(arg_cstr, false); 2241 const uint32_t num_modules = target->GetImages().GetSize(); 2242 if (num_modules > 0) 2243 { 2244 uint32_t num_dumped = 0; 2245 for (uint32_t i = 0; i<num_modules; ++i) 2246 { 2247 if (DumpCompileUnitLineTable (m_interpreter, 2248 result.GetOutputStream(), 2249 target->GetImages().GetModulePointerAtIndex(i), 2250 file_spec, 2251 exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive())) 2252 num_dumped++; 2253 } 2254 if (num_dumped == 0) 2255 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr); 2256 else 2257 total_num_dumped += num_dumped; 2258 } 2259 } 2260 } 2261 2262 if (total_num_dumped > 0) 2263 result.SetStatus (eReturnStatusSuccessFinishResult); 2264 else 2265 { 2266 result.AppendError ("no source filenames matched any command arguments"); 2267 result.SetStatus (eReturnStatusFailed); 2268 } 2269 } 2270 return result.Succeeded(); 2271 } 2272 }; 2273 2274 2275 #pragma mark CommandObjectTargetModulesDump 2276 2277 //---------------------------------------------------------------------- 2278 // Dump multi-word command for target modules 2279 //---------------------------------------------------------------------- 2280 2281 class CommandObjectTargetModulesDump : public CommandObjectMultiword 2282 { 2283 public: 2284 2285 //------------------------------------------------------------------ 2286 // Constructors and Destructors 2287 //------------------------------------------------------------------ 2288 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) : 2289 CommandObjectMultiword (interpreter, 2290 "target modules dump", 2291 "A set of commands for dumping information about one or more target modules.", 2292 "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]") 2293 { 2294 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter))); 2295 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter))); 2296 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter))); 2297 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter))); 2298 } 2299 2300 virtual 2301 ~CommandObjectTargetModulesDump() 2302 { 2303 } 2304 }; 2305 2306 class CommandObjectTargetModulesAdd : public CommandObject 2307 { 2308 public: 2309 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) : 2310 CommandObject (interpreter, 2311 "target modules add", 2312 "Add a new module to the current target's modules.", 2313 "target modules add [<module>]") 2314 { 2315 } 2316 2317 virtual 2318 ~CommandObjectTargetModulesAdd () 2319 { 2320 } 2321 2322 virtual bool 2323 Execute (Args& args, 2324 CommandReturnObject &result) 2325 { 2326 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2327 if (target == NULL) 2328 { 2329 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2330 result.SetStatus (eReturnStatusFailed); 2331 return false; 2332 } 2333 else 2334 { 2335 const size_t argc = args.GetArgumentCount(); 2336 if (argc == 0) 2337 { 2338 result.AppendError ("one or more executable image paths must be specified"); 2339 result.SetStatus (eReturnStatusFailed); 2340 return false; 2341 } 2342 else 2343 { 2344 for (size_t i=0; i<argc; ++i) 2345 { 2346 const char *path = args.GetArgumentAtIndex(i); 2347 if (path) 2348 { 2349 FileSpec file_spec(path, true); 2350 ArchSpec arch; 2351 if (file_spec.Exists()) 2352 { 2353 ModuleSP module_sp (target->GetSharedModule(file_spec, arch)); 2354 if (!module_sp) 2355 { 2356 result.AppendError ("one or more executable image paths must be specified"); 2357 result.SetStatus (eReturnStatusFailed); 2358 return false; 2359 } 2360 result.SetStatus (eReturnStatusSuccessFinishResult); 2361 } 2362 else 2363 { 2364 char resolved_path[PATH_MAX]; 2365 result.SetStatus (eReturnStatusFailed); 2366 if (file_spec.GetPath (resolved_path, sizeof(resolved_path))) 2367 { 2368 if (strcmp (resolved_path, path) != 0) 2369 { 2370 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path); 2371 break; 2372 } 2373 } 2374 result.AppendErrorWithFormat ("invalid module path '%s'\n", path); 2375 break; 2376 } 2377 } 2378 } 2379 } 2380 } 2381 return result.Succeeded(); 2382 } 2383 2384 int 2385 HandleArgumentCompletion (Args &input, 2386 int &cursor_index, 2387 int &cursor_char_position, 2388 OptionElementVector &opt_element_vector, 2389 int match_start_point, 2390 int max_return_elements, 2391 bool &word_complete, 2392 StringList &matches) 2393 { 2394 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2395 completion_str.erase (cursor_char_position); 2396 2397 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2398 CommandCompletions::eDiskFileCompletion, 2399 completion_str.c_str(), 2400 match_start_point, 2401 max_return_elements, 2402 NULL, 2403 word_complete, 2404 matches); 2405 return matches.GetSize(); 2406 } 2407 2408 }; 2409 2410 class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete 2411 { 2412 public: 2413 CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) : 2414 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2415 "target modules load", 2416 "Set the load addresses for one or more sections in a target module.", 2417 "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"), 2418 m_option_group (interpreter), 2419 m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "Fullpath or basename for module to load."), 2420 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset, "Set the load address for all sections to be the virtual address in the file plus the offset.", 0) 2421 { 2422 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2423 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2424 m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2425 m_option_group.Finalize(); 2426 } 2427 2428 virtual 2429 ~CommandObjectTargetModulesLoad () 2430 { 2431 } 2432 2433 virtual bool 2434 Execute (Args& args, 2435 CommandReturnObject &result) 2436 { 2437 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2438 if (target == NULL) 2439 { 2440 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2441 result.SetStatus (eReturnStatusFailed); 2442 return false; 2443 } 2444 else 2445 { 2446 const size_t argc = args.GetArgumentCount(); 2447 const FileSpec *file_ptr = NULL; 2448 const UUID *uuid_ptr = NULL; 2449 if (m_file_option.GetOptionValue().OptionWasSet()) 2450 file_ptr = &m_file_option.GetOptionValue().GetCurrentValue(); 2451 2452 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) 2453 uuid_ptr = &m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2454 2455 if (file_ptr || uuid_ptr) 2456 { 2457 2458 ModuleList matching_modules; 2459 const size_t num_matches = target->GetImages().FindModules (file_ptr, // File spec to match (can be NULL to match by UUID only) 2460 NULL, // Architecture 2461 uuid_ptr, // UUID to match (can be NULL to not match on UUID) 2462 NULL, // Object name 2463 matching_modules); 2464 2465 char path[PATH_MAX]; 2466 if (num_matches == 1) 2467 { 2468 Module *module = matching_modules.GetModulePointerAtIndex(0); 2469 if (module) 2470 { 2471 ObjectFile *objfile = module->GetObjectFile(); 2472 if (objfile) 2473 { 2474 SectionList *section_list = objfile->GetSectionList(); 2475 if (section_list) 2476 { 2477 if (argc == 0) 2478 { 2479 if (m_slide_option.GetOptionValue().OptionWasSet()) 2480 { 2481 Module *module = matching_modules.GetModulePointerAtIndex(0); 2482 if (module) 2483 { 2484 ObjectFile *objfile = module->GetObjectFile(); 2485 if (objfile) 2486 { 2487 SectionList *section_list = objfile->GetSectionList(); 2488 if (section_list) 2489 { 2490 const size_t num_sections = section_list->GetSize(); 2491 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue(); 2492 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx) 2493 { 2494 SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx)); 2495 if (section_sp) 2496 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), section_sp->GetFileAddress() + slide); 2497 } 2498 } 2499 } 2500 } 2501 } 2502 else 2503 { 2504 result.AppendError ("one or more section name + load address pair must be specified"); 2505 result.SetStatus (eReturnStatusFailed); 2506 return false; 2507 } 2508 } 2509 else 2510 { 2511 if (m_slide_option.GetOptionValue().OptionWasSet()) 2512 { 2513 result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n"); 2514 result.SetStatus (eReturnStatusFailed); 2515 return false; 2516 } 2517 2518 for (size_t i=0; i<argc; i += 2) 2519 { 2520 const char *sect_name = args.GetArgumentAtIndex(i); 2521 const char *load_addr_cstr = args.GetArgumentAtIndex(i+1); 2522 if (sect_name && load_addr_cstr) 2523 { 2524 ConstString const_sect_name(sect_name); 2525 bool success = false; 2526 addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success); 2527 if (success) 2528 { 2529 SectionSP section_sp (section_list->FindSectionByName(const_sect_name)); 2530 if (section_sp) 2531 { 2532 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), load_addr); 2533 result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr); 2534 } 2535 else 2536 { 2537 result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name); 2538 result.SetStatus (eReturnStatusFailed); 2539 break; 2540 } 2541 } 2542 else 2543 { 2544 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr); 2545 result.SetStatus (eReturnStatusFailed); 2546 break; 2547 } 2548 } 2549 else 2550 { 2551 if (sect_name) 2552 result.AppendError ("section names must be followed by a load address.\n"); 2553 else 2554 result.AppendError ("one or more section name + load address pair must be specified.\n"); 2555 result.SetStatus (eReturnStatusFailed); 2556 break; 2557 } 2558 } 2559 } 2560 } 2561 else 2562 { 2563 module->GetFileSpec().GetPath (path, sizeof(path)); 2564 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path); 2565 result.SetStatus (eReturnStatusFailed); 2566 } 2567 } 2568 else 2569 { 2570 module->GetFileSpec().GetPath (path, sizeof(path)); 2571 result.AppendErrorWithFormat ("no object file for module '%s'\n", path); 2572 result.SetStatus (eReturnStatusFailed); 2573 } 2574 } 2575 else 2576 { 2577 module->GetFileSpec().GetPath (path, sizeof(path)); 2578 result.AppendErrorWithFormat ("invalid module '%s'.\n", path); 2579 result.SetStatus (eReturnStatusFailed); 2580 } 2581 } 2582 else 2583 { 2584 char uuid_cstr[64]; 2585 if (file_ptr) 2586 file_ptr->GetPath (path, sizeof(path)); 2587 else 2588 path[0] = '\0'; 2589 2590 if (uuid_ptr) 2591 uuid_ptr->GetAsCString(uuid_cstr, sizeof(uuid_cstr)); 2592 else 2593 uuid_cstr[0] = '\0'; 2594 if (num_matches > 1) 2595 { 2596 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n", 2597 path[0] ? " file=" : "", 2598 path, 2599 uuid_cstr[0] ? " uuid=" : "", 2600 uuid_cstr); 2601 for (size_t i=0; i<num_matches; ++i) 2602 { 2603 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path))) 2604 result.AppendMessageWithFormat("%s\n", path); 2605 } 2606 } 2607 else 2608 { 2609 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n", 2610 path[0] ? " file=" : "", 2611 path, 2612 uuid_cstr[0] ? " uuid=" : "", 2613 uuid_cstr); 2614 } 2615 result.SetStatus (eReturnStatusFailed); 2616 } 2617 } 2618 else 2619 { 2620 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n"); 2621 result.SetStatus (eReturnStatusFailed); 2622 return false; 2623 } 2624 } 2625 return result.Succeeded(); 2626 } 2627 2628 virtual Options * 2629 GetOptions () 2630 { 2631 return &m_option_group; 2632 } 2633 2634 protected: 2635 OptionGroupOptions m_option_group; 2636 OptionGroupUUID m_uuid_option_group; 2637 OptionGroupFile m_file_option; 2638 OptionGroupUInt64 m_slide_option; 2639 }; 2640 2641 //---------------------------------------------------------------------- 2642 // List images with associated information 2643 //---------------------------------------------------------------------- 2644 class CommandObjectTargetModulesList : public CommandObject 2645 { 2646 public: 2647 2648 class CommandOptions : public Options 2649 { 2650 public: 2651 2652 CommandOptions (CommandInterpreter &interpreter) : 2653 Options(interpreter), 2654 m_format_array(), 2655 m_use_global_module_list (false), 2656 m_module_addr (LLDB_INVALID_ADDRESS) 2657 { 2658 } 2659 2660 virtual 2661 ~CommandOptions () 2662 { 2663 } 2664 2665 virtual Error 2666 SetOptionValue (uint32_t option_idx, const char *option_arg) 2667 { 2668 char short_option = (char) m_getopt_table[option_idx].val; 2669 if (short_option == 'g') 2670 { 2671 m_use_global_module_list = true; 2672 } 2673 else if (short_option == 'a') 2674 { 2675 bool success; 2676 m_module_addr = Args::StringToAddress(option_arg, LLDB_INVALID_ADDRESS, &success); 2677 if (!success) 2678 { 2679 Error error; 2680 error.SetErrorStringWithFormat("invalid address: \"%s\"", option_arg); 2681 } 2682 } 2683 else 2684 { 2685 uint32_t width = 0; 2686 if (option_arg) 2687 width = strtoul (option_arg, NULL, 0); 2688 m_format_array.push_back(std::make_pair(short_option, width)); 2689 } 2690 Error error; 2691 return error; 2692 } 2693 2694 void 2695 OptionParsingStarting () 2696 { 2697 m_format_array.clear(); 2698 m_use_global_module_list = false; 2699 m_module_addr = LLDB_INVALID_ADDRESS; 2700 } 2701 2702 const OptionDefinition* 2703 GetDefinitions () 2704 { 2705 return g_option_table; 2706 } 2707 2708 // Options table: Required for subclasses of Options. 2709 2710 static OptionDefinition g_option_table[]; 2711 2712 // Instance variables to hold the values for command options. 2713 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection; 2714 FormatWidthCollection m_format_array; 2715 bool m_use_global_module_list; 2716 lldb::addr_t m_module_addr; 2717 }; 2718 2719 CommandObjectTargetModulesList (CommandInterpreter &interpreter) : 2720 CommandObject (interpreter, 2721 "target modules list", 2722 "List current executable and dependent shared library images.", 2723 "target modules list [<cmd-options>]"), 2724 m_options (interpreter) 2725 { 2726 } 2727 2728 virtual 2729 ~CommandObjectTargetModulesList () 2730 { 2731 } 2732 2733 virtual 2734 Options * 2735 GetOptions () 2736 { 2737 return &m_options; 2738 } 2739 2740 virtual bool 2741 Execute (Args& command, 2742 CommandReturnObject &result) 2743 { 2744 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2745 const bool use_global_module_list = m_options.m_use_global_module_list; 2746 if (target == NULL && use_global_module_list == false) 2747 { 2748 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2749 result.SetStatus (eReturnStatusFailed); 2750 return false; 2751 } 2752 else 2753 { 2754 if (target) 2755 { 2756 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2757 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2758 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2759 } 2760 // Dump all sections for all modules images 2761 uint32_t num_modules = 0; 2762 Mutex::Locker locker; 2763 2764 Stream &strm = result.GetOutputStream(); 2765 2766 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) 2767 { 2768 if (target) 2769 { 2770 Address module_address; 2771 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) 2772 { 2773 Module *module = module_address.GetModule(); 2774 if (module) 2775 { 2776 PrintModule (strm, module); 2777 result.SetStatus (eReturnStatusSuccessFinishResult); 2778 } 2779 else 2780 { 2781 result.AppendError ("Couldn't find module matching address: 0x%llx.", m_options.m_module_addr); 2782 result.SetStatus (eReturnStatusFailed); 2783 } 2784 } 2785 else 2786 { 2787 result.AppendError ("Couldn't find module containing address: 0x%llx.", m_options.m_module_addr); 2788 result.SetStatus (eReturnStatusFailed); 2789 } 2790 } 2791 else 2792 { 2793 result.AppendError ("Can only look up modules by address with a valid target."); 2794 result.SetStatus (eReturnStatusFailed); 2795 } 2796 return result.Succeeded(); 2797 } 2798 2799 if (use_global_module_list) 2800 { 2801 locker.Reset (Module::GetAllocationModuleCollectionMutex().GetMutex()); 2802 num_modules = Module::GetNumberAllocatedModules(); 2803 } 2804 else 2805 num_modules = target->GetImages().GetSize(); 2806 2807 if (num_modules > 0) 2808 { 2809 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2810 { 2811 ModuleSP module_sp; 2812 Module *module; 2813 if (use_global_module_list) 2814 { 2815 module = Module::GetAllocatedModuleAtIndex(image_idx); 2816 module_sp = module; 2817 } 2818 else 2819 { 2820 module_sp = target->GetImages().GetModuleAtIndex(image_idx); 2821 module = module_sp.get(); 2822 } 2823 2824 strm.Printf("[%3u] ", image_idx); 2825 PrintModule (strm, module); 2826 2827 } 2828 result.SetStatus (eReturnStatusSuccessFinishResult); 2829 } 2830 else 2831 { 2832 if (use_global_module_list) 2833 result.AppendError ("the global module list is empty"); 2834 else 2835 result.AppendError ("the target has no associated executable images"); 2836 result.SetStatus (eReturnStatusFailed); 2837 return false; 2838 } 2839 } 2840 return result.Succeeded(); 2841 } 2842 protected: 2843 2844 void 2845 PrintModule (Stream &strm, Module *module) 2846 { 2847 2848 bool dump_object_name = false; 2849 if (m_options.m_format_array.empty()) 2850 { 2851 DumpFullpath(strm, &module->GetFileSpec(), 0); 2852 dump_object_name = true; 2853 } 2854 else 2855 { 2856 const size_t num_entries = m_options.m_format_array.size(); 2857 for (size_t i=0; i<num_entries; ++i) 2858 { 2859 if (i > 0) 2860 strm.PutChar(' '); 2861 char format_char = m_options.m_format_array[i].first; 2862 uint32_t width = m_options.m_format_array[i].second; 2863 switch (format_char) 2864 { 2865 case 'A': 2866 DumpModuleArchitecture (strm, module, false, width); 2867 break; 2868 2869 case 't': 2870 DumpModuleArchitecture (strm, module, true, width); 2871 break; 2872 2873 case 'f': 2874 DumpFullpath (strm, &module->GetFileSpec(), width); 2875 dump_object_name = true; 2876 break; 2877 2878 case 'd': 2879 DumpDirectory (strm, &module->GetFileSpec(), width); 2880 break; 2881 2882 case 'b': 2883 DumpBasename (strm, &module->GetFileSpec(), width); 2884 dump_object_name = true; 2885 break; 2886 2887 case 'r': 2888 { 2889 uint32_t ref_count = 0; 2890 ModuleSP module_sp (module); 2891 if (module_sp) 2892 { 2893 // Take one away to make sure we don't count our local "module_sp" 2894 ref_count = module_sp.use_count() - 1; 2895 } 2896 if (width) 2897 strm.Printf("{%*u}", width, ref_count); 2898 else 2899 strm.Printf("{%u}", ref_count); 2900 } 2901 break; 2902 2903 case 's': 2904 case 'S': 2905 { 2906 SymbolVendor *symbol_vendor = module->GetSymbolVendor(); 2907 if (symbol_vendor) 2908 { 2909 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 2910 if (symbol_file) 2911 { 2912 if (format_char == 'S') 2913 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); 2914 else 2915 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); 2916 dump_object_name = true; 2917 break; 2918 } 2919 } 2920 strm.Printf("%.*s", width, "<NONE>"); 2921 } 2922 break; 2923 2924 case 'm': 2925 module->GetModificationTime().Dump(&strm, width); 2926 break; 2927 2928 case 'p': 2929 strm.Printf("%p", module); 2930 break; 2931 2932 case 'u': 2933 DumpModuleUUID(strm, module); 2934 break; 2935 2936 default: 2937 break; 2938 } 2939 2940 } 2941 if (dump_object_name) 2942 { 2943 const char *object_name = module->GetObjectName().GetCString(); 2944 if (object_name) 2945 strm.Printf ("(%s)", object_name); 2946 } 2947 } 2948 strm.EOL(); 2949 } 2950 2951 CommandOptions m_options; 2952 }; 2953 2954 OptionDefinition 2955 CommandObjectTargetModulesList::CommandOptions::g_option_table[] = 2956 { 2957 { LLDB_OPT_SET_1, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Display the image at this address."}, 2958 { LLDB_OPT_SET_1, false, "arch", 'A', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, 2959 { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, 2960 { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, 2961 { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, 2962 { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, 2963 { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, 2964 { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, 2965 { LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."}, 2966 { LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."}, 2967 { LLDB_OPT_SET_1, false, "ref-count", 'r', optional_argument, NULL, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache."}, 2968 { LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."}, 2969 { LLDB_OPT_SET_1, false, "global", 'g', no_argument, NULL, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target."}, 2970 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 2971 }; 2972 2973 2974 2975 //---------------------------------------------------------------------- 2976 // Lookup information in images 2977 //---------------------------------------------------------------------- 2978 class CommandObjectTargetModulesLookup : public CommandObject 2979 { 2980 public: 2981 2982 enum 2983 { 2984 eLookupTypeInvalid = -1, 2985 eLookupTypeAddress = 0, 2986 eLookupTypeSymbol, 2987 eLookupTypeFileLine, // Line is optional 2988 eLookupTypeFunction, 2989 eLookupTypeType, 2990 kNumLookupTypes 2991 }; 2992 2993 class CommandOptions : public Options 2994 { 2995 public: 2996 2997 CommandOptions (CommandInterpreter &interpreter) : 2998 Options(interpreter) 2999 { 3000 OptionParsingStarting(); 3001 } 3002 3003 virtual 3004 ~CommandOptions () 3005 { 3006 } 3007 3008 virtual Error 3009 SetOptionValue (uint32_t option_idx, const char *option_arg) 3010 { 3011 Error error; 3012 3013 char short_option = (char) m_getopt_table[option_idx].val; 3014 3015 switch (short_option) 3016 { 3017 case 'a': 3018 m_type = eLookupTypeAddress; 3019 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 3020 if (m_addr == LLDB_INVALID_ADDRESS) 3021 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg); 3022 break; 3023 3024 case 'o': 3025 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 3026 if (m_offset == LLDB_INVALID_ADDRESS) 3027 error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg); 3028 break; 3029 3030 case 's': 3031 m_str = option_arg; 3032 m_type = eLookupTypeSymbol; 3033 break; 3034 3035 case 'f': 3036 m_file.SetFile (option_arg, false); 3037 m_type = eLookupTypeFileLine; 3038 break; 3039 3040 case 'i': 3041 m_check_inlines = false; 3042 break; 3043 3044 case 'l': 3045 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX); 3046 if (m_line_number == UINT32_MAX) 3047 error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg); 3048 else if (m_line_number == 0) 3049 error.SetErrorString ("zero is an invalid line number"); 3050 m_type = eLookupTypeFileLine; 3051 break; 3052 3053 case 'n': 3054 m_str = option_arg; 3055 m_type = eLookupTypeFunction; 3056 break; 3057 3058 case 't': 3059 m_str = option_arg; 3060 m_type = eLookupTypeType; 3061 break; 3062 3063 case 'v': 3064 m_verbose = 1; 3065 break; 3066 3067 case 'r': 3068 m_use_regex = true; 3069 break; 3070 } 3071 3072 return error; 3073 } 3074 3075 void 3076 OptionParsingStarting () 3077 { 3078 m_type = eLookupTypeInvalid; 3079 m_str.clear(); 3080 m_file.Clear(); 3081 m_addr = LLDB_INVALID_ADDRESS; 3082 m_offset = 0; 3083 m_line_number = 0; 3084 m_use_regex = false; 3085 m_check_inlines = true; 3086 m_verbose = false; 3087 } 3088 3089 const OptionDefinition* 3090 GetDefinitions () 3091 { 3092 return g_option_table; 3093 } 3094 3095 // Options table: Required for subclasses of Options. 3096 3097 static OptionDefinition g_option_table[]; 3098 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3099 std::string m_str; // Holds name lookup 3100 FileSpec m_file; // Files for file lookups 3101 lldb::addr_t m_addr; // Holds the address to lookup 3102 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups. 3103 uint32_t m_line_number; // Line number for file+line lookups 3104 bool m_use_regex; // Name lookups in m_str are regular expressions. 3105 bool m_check_inlines;// Check for inline entries when looking up by file/line. 3106 bool m_verbose; // Enable verbose lookup info 3107 3108 }; 3109 3110 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) : 3111 CommandObject (interpreter, 3112 "target modules lookup", 3113 "Look up information within executable and dependent shared library images.", 3114 NULL), 3115 m_options (interpreter) 3116 { 3117 CommandArgumentEntry arg; 3118 CommandArgumentData file_arg; 3119 3120 // Define the first (and only) variant of this arg. 3121 file_arg.arg_type = eArgTypeFilename; 3122 file_arg.arg_repetition = eArgRepeatStar; 3123 3124 // There is only one variant this argument could be; put it into the argument entry. 3125 arg.push_back (file_arg); 3126 3127 // Push the data for the first argument into the m_arguments vector. 3128 m_arguments.push_back (arg); 3129 } 3130 3131 virtual 3132 ~CommandObjectTargetModulesLookup () 3133 { 3134 } 3135 3136 virtual Options * 3137 GetOptions () 3138 { 3139 return &m_options; 3140 } 3141 3142 3143 bool 3144 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error) 3145 { 3146 switch (m_options.m_type) 3147 { 3148 case eLookupTypeAddress: 3149 if (m_options.m_addr != LLDB_INVALID_ADDRESS) 3150 { 3151 if (LookupAddressInModule (m_interpreter, 3152 result.GetOutputStream(), 3153 module, 3154 eSymbolContextEverything, 3155 m_options.m_addr, 3156 m_options.m_offset, 3157 m_options.m_verbose)) 3158 { 3159 result.SetStatus(eReturnStatusSuccessFinishResult); 3160 return true; 3161 } 3162 } 3163 break; 3164 3165 case eLookupTypeSymbol: 3166 if (!m_options.m_str.empty()) 3167 { 3168 if (LookupSymbolInModule (m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex)) 3169 { 3170 result.SetStatus(eReturnStatusSuccessFinishResult); 3171 return true; 3172 } 3173 } 3174 break; 3175 3176 case eLookupTypeFileLine: 3177 if (m_options.m_file) 3178 { 3179 3180 if (LookupFileAndLineInModule (m_interpreter, 3181 result.GetOutputStream(), 3182 module, 3183 m_options.m_file, 3184 m_options.m_line_number, 3185 m_options.m_check_inlines, 3186 m_options.m_verbose)) 3187 { 3188 result.SetStatus(eReturnStatusSuccessFinishResult); 3189 return true; 3190 } 3191 } 3192 break; 3193 3194 case eLookupTypeFunction: 3195 if (!m_options.m_str.empty()) 3196 { 3197 if (LookupFunctionInModule (m_interpreter, 3198 result.GetOutputStream(), 3199 module, 3200 m_options.m_str.c_str(), 3201 m_options.m_use_regex, 3202 m_options.m_verbose)) 3203 { 3204 result.SetStatus(eReturnStatusSuccessFinishResult); 3205 return true; 3206 } 3207 } 3208 break; 3209 3210 case eLookupTypeType: 3211 if (!m_options.m_str.empty()) 3212 { 3213 if (LookupTypeInModule (m_interpreter, 3214 result.GetOutputStream(), 3215 module, 3216 m_options.m_str.c_str(), 3217 m_options.m_use_regex)) 3218 { 3219 result.SetStatus(eReturnStatusSuccessFinishResult); 3220 return true; 3221 } 3222 } 3223 break; 3224 3225 default: 3226 m_options.GenerateOptionUsage (result.GetErrorStream(), this); 3227 syntax_error = true; 3228 break; 3229 } 3230 3231 result.SetStatus (eReturnStatusFailed); 3232 return false; 3233 } 3234 3235 virtual bool 3236 Execute (Args& command, 3237 CommandReturnObject &result) 3238 { 3239 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3240 if (target == NULL) 3241 { 3242 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 3243 result.SetStatus (eReturnStatusFailed); 3244 return false; 3245 } 3246 else 3247 { 3248 bool syntax_error = false; 3249 uint32_t i; 3250 uint32_t num_successful_lookups = 0; 3251 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 3252 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 3253 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 3254 // Dump all sections for all modules images 3255 3256 if (command.GetArgumentCount() == 0) 3257 { 3258 // Dump all sections for all modules images 3259 const uint32_t num_modules = target->GetImages().GetSize(); 3260 if (num_modules > 0) 3261 { 3262 for (i = 0; i<num_modules && syntax_error == false; ++i) 3263 { 3264 if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error)) 3265 { 3266 result.GetOutputStream().EOL(); 3267 num_successful_lookups++; 3268 } 3269 } 3270 } 3271 else 3272 { 3273 result.AppendError ("the target has no associated executable images"); 3274 result.SetStatus (eReturnStatusFailed); 3275 return false; 3276 } 3277 } 3278 else 3279 { 3280 // Dump specified images (by basename or fullpath) 3281 const char *arg_cstr; 3282 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i) 3283 { 3284 ModuleList module_list; 3285 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false); 3286 if (num_matches > 0) 3287 { 3288 for (size_t i=0; i<num_matches; ++i) 3289 { 3290 Module *module = module_list.GetModulePointerAtIndex(i); 3291 if (module) 3292 { 3293 if (LookupInModule (m_interpreter, module, result, syntax_error)) 3294 { 3295 result.GetOutputStream().EOL(); 3296 num_successful_lookups++; 3297 } 3298 } 3299 } 3300 } 3301 else 3302 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 3303 } 3304 } 3305 3306 if (num_successful_lookups > 0) 3307 result.SetStatus (eReturnStatusSuccessFinishResult); 3308 else 3309 result.SetStatus (eReturnStatusFailed); 3310 } 3311 return result.Succeeded(); 3312 } 3313 protected: 3314 3315 CommandOptions m_options; 3316 }; 3317 3318 OptionDefinition 3319 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] = 3320 { 3321 { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more target modules."}, 3322 { LLDB_OPT_SET_1, false, "offset", 'o', required_argument, NULL, 0, eArgTypeOffset, "When looking up an address subtract <offset> from any addresses before doing the lookup."}, 3323 { LLDB_OPT_SET_2| LLDB_OPT_SET_4 3324 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_5 */ , 3325 false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."}, 3326 { LLDB_OPT_SET_2, true, "symbol", 's', required_argument, NULL, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules."}, 3327 { LLDB_OPT_SET_3, true, "file", 'f', required_argument, NULL, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules."}, 3328 { LLDB_OPT_SET_3, false, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)."}, 3329 { LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Check inline line entries (must be used in conjunction with --file)."}, 3330 { LLDB_OPT_SET_4, true, "function", 'n', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules."}, 3331 { LLDB_OPT_SET_5, true, "type", 't', required_argument, NULL, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules."}, 3332 { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, 3333 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3334 }; 3335 3336 3337 #pragma mark CommandObjectMultiwordImageSearchPaths 3338 3339 //------------------------------------------------------------------------- 3340 // CommandObjectMultiwordImageSearchPaths 3341 //------------------------------------------------------------------------- 3342 3343 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword 3344 { 3345 public: 3346 3347 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) : 3348 CommandObjectMultiword (interpreter, 3349 "target modules search-paths", 3350 "A set of commands for operating on debugger target image search paths.", 3351 "target modules search-paths <subcommand> [<subcommand-options>]") 3352 { 3353 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter))); 3354 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter))); 3355 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter))); 3356 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter))); 3357 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter))); 3358 } 3359 3360 ~CommandObjectTargetModulesImageSearchPaths() 3361 { 3362 } 3363 }; 3364 3365 3366 3367 #pragma mark CommandObjectTargetModules 3368 3369 //------------------------------------------------------------------------- 3370 // CommandObjectTargetModules 3371 //------------------------------------------------------------------------- 3372 3373 class CommandObjectTargetModules : public CommandObjectMultiword 3374 { 3375 public: 3376 //------------------------------------------------------------------ 3377 // Constructors and Destructors 3378 //------------------------------------------------------------------ 3379 CommandObjectTargetModules(CommandInterpreter &interpreter) : 3380 CommandObjectMultiword (interpreter, 3381 "target modules", 3382 "A set of commands for accessing information for one or more target modules.", 3383 "target modules <sub-command> ...") 3384 { 3385 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter))); 3386 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter))); 3387 //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter))); 3388 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter))); 3389 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter))); 3390 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter))); 3391 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter))); 3392 3393 } 3394 virtual 3395 ~CommandObjectTargetModules() 3396 { 3397 } 3398 3399 private: 3400 //------------------------------------------------------------------ 3401 // For CommandObjectTargetModules only 3402 //------------------------------------------------------------------ 3403 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules); 3404 }; 3405 3406 3407 #pragma mark CommandObjectTargetStopHookAdd 3408 3409 //------------------------------------------------------------------------- 3410 // CommandObjectTargetStopHookAdd 3411 //------------------------------------------------------------------------- 3412 3413 class CommandObjectTargetStopHookAdd : public CommandObject 3414 { 3415 public: 3416 3417 class CommandOptions : public Options 3418 { 3419 public: 3420 CommandOptions (CommandInterpreter &interpreter) : 3421 Options(interpreter), 3422 m_line_start(0), 3423 m_line_end (UINT_MAX), 3424 m_func_name_type_mask (eFunctionNameTypeAuto), 3425 m_sym_ctx_specified (false), 3426 m_thread_specified (false), 3427 m_use_one_liner (false), 3428 m_one_liner() 3429 { 3430 } 3431 3432 ~CommandOptions () {} 3433 3434 const OptionDefinition* 3435 GetDefinitions () 3436 { 3437 return g_option_table; 3438 } 3439 3440 virtual Error 3441 SetOptionValue (uint32_t option_idx, const char *option_arg) 3442 { 3443 Error error; 3444 char short_option = (char) m_getopt_table[option_idx].val; 3445 bool success; 3446 3447 switch (short_option) 3448 { 3449 case 'c': 3450 m_class_name = option_arg; 3451 m_sym_ctx_specified = true; 3452 break; 3453 3454 case 'e': 3455 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success); 3456 if (!success) 3457 { 3458 error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg); 3459 break; 3460 } 3461 m_sym_ctx_specified = true; 3462 break; 3463 3464 case 'l': 3465 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success); 3466 if (!success) 3467 { 3468 error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg); 3469 break; 3470 } 3471 m_sym_ctx_specified = true; 3472 break; 3473 3474 case 'n': 3475 m_function_name = option_arg; 3476 m_func_name_type_mask |= eFunctionNameTypeAuto; 3477 m_sym_ctx_specified = true; 3478 break; 3479 3480 case 'f': 3481 m_file_name = option_arg; 3482 m_sym_ctx_specified = true; 3483 break; 3484 case 's': 3485 m_module_name = option_arg; 3486 m_sym_ctx_specified = true; 3487 break; 3488 case 't' : 3489 { 3490 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 3491 if (m_thread_id == LLDB_INVALID_THREAD_ID) 3492 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 3493 m_thread_specified = true; 3494 } 3495 break; 3496 case 'T': 3497 m_thread_name = option_arg; 3498 m_thread_specified = true; 3499 break; 3500 case 'q': 3501 m_queue_name = option_arg; 3502 m_thread_specified = true; 3503 break; 3504 case 'x': 3505 { 3506 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 3507 if (m_thread_id == UINT32_MAX) 3508 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 3509 m_thread_specified = true; 3510 } 3511 break; 3512 case 'o': 3513 m_use_one_liner = true; 3514 m_one_liner = option_arg; 3515 break; 3516 default: 3517 error.SetErrorStringWithFormat ("unrecognized option %c.", short_option); 3518 break; 3519 } 3520 return error; 3521 } 3522 3523 void 3524 OptionParsingStarting () 3525 { 3526 m_class_name.clear(); 3527 m_function_name.clear(); 3528 m_line_start = 0; 3529 m_line_end = UINT_MAX; 3530 m_file_name.clear(); 3531 m_module_name.clear(); 3532 m_func_name_type_mask = eFunctionNameTypeAuto; 3533 m_thread_id = LLDB_INVALID_THREAD_ID; 3534 m_thread_index = UINT32_MAX; 3535 m_thread_name.clear(); 3536 m_queue_name.clear(); 3537 3538 m_sym_ctx_specified = false; 3539 m_thread_specified = false; 3540 3541 m_use_one_liner = false; 3542 m_one_liner.clear(); 3543 } 3544 3545 3546 static OptionDefinition g_option_table[]; 3547 3548 std::string m_class_name; 3549 std::string m_function_name; 3550 uint32_t m_line_start; 3551 uint32_t m_line_end; 3552 std::string m_file_name; 3553 std::string m_module_name; 3554 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType. 3555 lldb::tid_t m_thread_id; 3556 uint32_t m_thread_index; 3557 std::string m_thread_name; 3558 std::string m_queue_name; 3559 bool m_sym_ctx_specified; 3560 bool m_thread_specified; 3561 // Instance variables to hold the values for one_liner options. 3562 bool m_use_one_liner; 3563 std::string m_one_liner; 3564 }; 3565 3566 Options * 3567 GetOptions () 3568 { 3569 return &m_options; 3570 } 3571 3572 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) : 3573 CommandObject (interpreter, 3574 "target stop-hook add ", 3575 "Add a hook to be executed when the target stops.", 3576 "target stop-hook add"), 3577 m_options (interpreter) 3578 { 3579 } 3580 3581 ~CommandObjectTargetStopHookAdd () 3582 { 3583 } 3584 3585 static size_t 3586 ReadCommandsCallbackFunction (void *baton, 3587 InputReader &reader, 3588 lldb::InputReaderAction notification, 3589 const char *bytes, 3590 size_t bytes_len) 3591 { 3592 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 3593 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton); 3594 static bool got_interrupted; 3595 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 3596 3597 switch (notification) 3598 { 3599 case eInputReaderActivate: 3600 if (!batch_mode) 3601 { 3602 out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end."); 3603 if (reader.GetPrompt()) 3604 out_stream->Printf ("%s", reader.GetPrompt()); 3605 out_stream->Flush(); 3606 } 3607 got_interrupted = false; 3608 break; 3609 3610 case eInputReaderDeactivate: 3611 break; 3612 3613 case eInputReaderReactivate: 3614 if (reader.GetPrompt() && !batch_mode) 3615 { 3616 out_stream->Printf ("%s", reader.GetPrompt()); 3617 out_stream->Flush(); 3618 } 3619 got_interrupted = false; 3620 break; 3621 3622 case eInputReaderAsynchronousOutputWritten: 3623 break; 3624 3625 case eInputReaderGotToken: 3626 if (bytes && bytes_len && baton) 3627 { 3628 StringList *commands = new_stop_hook->GetCommandPointer(); 3629 if (commands) 3630 { 3631 commands->AppendString (bytes, bytes_len); 3632 } 3633 } 3634 if (!reader.IsDone() && reader.GetPrompt() && !batch_mode) 3635 { 3636 out_stream->Printf ("%s", reader.GetPrompt()); 3637 out_stream->Flush(); 3638 } 3639 break; 3640 3641 case eInputReaderInterrupt: 3642 { 3643 // Finish, and cancel the stop hook. 3644 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID()); 3645 if (!batch_mode) 3646 { 3647 out_stream->Printf ("Stop hook cancelled.\n"); 3648 out_stream->Flush(); 3649 } 3650 3651 reader.SetIsDone (true); 3652 } 3653 got_interrupted = true; 3654 break; 3655 3656 case eInputReaderEndOfFile: 3657 reader.SetIsDone (true); 3658 break; 3659 3660 case eInputReaderDone: 3661 if (!got_interrupted && !batch_mode) 3662 { 3663 out_stream->Printf ("Stop hook #%llu added.\n", new_stop_hook->GetID()); 3664 out_stream->Flush(); 3665 } 3666 break; 3667 } 3668 3669 return bytes_len; 3670 } 3671 3672 bool 3673 Execute (Args& command, 3674 CommandReturnObject &result) 3675 { 3676 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3677 if (target) 3678 { 3679 Target::StopHookSP new_hook_sp; 3680 target->AddStopHook (new_hook_sp); 3681 3682 // First step, make the specifier. 3683 std::auto_ptr<SymbolContextSpecifier> specifier_ap; 3684 if (m_options.m_sym_ctx_specified) 3685 { 3686 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget())); 3687 3688 if (!m_options.m_module_name.empty()) 3689 { 3690 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified); 3691 } 3692 3693 if (!m_options.m_class_name.empty()) 3694 { 3695 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified); 3696 } 3697 3698 if (!m_options.m_file_name.empty()) 3699 { 3700 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified); 3701 } 3702 3703 if (m_options.m_line_start != 0) 3704 { 3705 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified); 3706 } 3707 3708 if (m_options.m_line_end != UINT_MAX) 3709 { 3710 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); 3711 } 3712 3713 if (!m_options.m_function_name.empty()) 3714 { 3715 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified); 3716 } 3717 } 3718 3719 if (specifier_ap.get()) 3720 new_hook_sp->SetSpecifier (specifier_ap.release()); 3721 3722 // Next see if any of the thread options have been entered: 3723 3724 if (m_options.m_thread_specified) 3725 { 3726 ThreadSpec *thread_spec = new ThreadSpec(); 3727 3728 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 3729 { 3730 thread_spec->SetTID (m_options.m_thread_id); 3731 } 3732 3733 if (m_options.m_thread_index != UINT32_MAX) 3734 thread_spec->SetIndex (m_options.m_thread_index); 3735 3736 if (!m_options.m_thread_name.empty()) 3737 thread_spec->SetName (m_options.m_thread_name.c_str()); 3738 3739 if (!m_options.m_queue_name.empty()) 3740 thread_spec->SetQueueName (m_options.m_queue_name.c_str()); 3741 3742 new_hook_sp->SetThreadSpecifier (thread_spec); 3743 3744 } 3745 if (m_options.m_use_one_liner) 3746 { 3747 // Use one-liner. 3748 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str()); 3749 result.AppendMessageWithFormat("Stop hook #%llu added.\n", new_hook_sp->GetID()); 3750 } 3751 else 3752 { 3753 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into 3754 // the new stop hook's command string. 3755 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); 3756 if (!reader_sp) 3757 { 3758 result.AppendError("out of memory\n"); 3759 result.SetStatus (eReturnStatusFailed); 3760 target->RemoveStopHookByID (new_hook_sp->GetID()); 3761 return false; 3762 } 3763 3764 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction, 3765 new_hook_sp.get(), // baton 3766 eInputReaderGranularityLine, // token size, to pass to callback function 3767 "DONE", // end token 3768 "> ", // prompt 3769 true)); // echo input 3770 if (!err.Success()) 3771 { 3772 result.AppendError (err.AsCString()); 3773 result.SetStatus (eReturnStatusFailed); 3774 target->RemoveStopHookByID (new_hook_sp->GetID()); 3775 return false; 3776 } 3777 m_interpreter.GetDebugger().PushInputReader (reader_sp); 3778 } 3779 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3780 } 3781 else 3782 { 3783 result.AppendError ("invalid target\n"); 3784 result.SetStatus (eReturnStatusFailed); 3785 } 3786 3787 return result.Succeeded(); 3788 } 3789 private: 3790 CommandOptions m_options; 3791 }; 3792 3793 OptionDefinition 3794 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] = 3795 { 3796 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, NULL, eArgTypeOneLiner, 3797 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, 3798 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 3799 "Set the module within which the stop-hook is to be run."}, 3800 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex, 3801 "The stop hook is run only for the thread whose index matches this argument."}, 3802 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID, 3803 "The stop hook is run only for the thread whose TID matches this argument."}, 3804 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName, 3805 "The stop hook is run only for the thread whose thread name matches this argument."}, 3806 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName, 3807 "The stop hook is run only for threads in the queue whose name is given by this argument."}, 3808 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 3809 "Specify the source file within which the stop-hook is to be run." }, 3810 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum, 3811 "Set the start of the line range for which the stop-hook is to be run."}, 3812 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum, 3813 "Set the end of the line range for which the stop-hook is to be run."}, 3814 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName, 3815 "Specify the class within which the stop-hook is to be run." }, 3816 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 3817 "Set the function name within which the stop hook will be run." }, 3818 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3819 }; 3820 3821 #pragma mark CommandObjectTargetStopHookDelete 3822 3823 //------------------------------------------------------------------------- 3824 // CommandObjectTargetStopHookDelete 3825 //------------------------------------------------------------------------- 3826 3827 class CommandObjectTargetStopHookDelete : public CommandObject 3828 { 3829 public: 3830 3831 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) : 3832 CommandObject (interpreter, 3833 "target stop-hook delete", 3834 "Delete a stop-hook.", 3835 "target stop-hook delete [<idx>]") 3836 { 3837 } 3838 3839 ~CommandObjectTargetStopHookDelete () 3840 { 3841 } 3842 3843 bool 3844 Execute (Args& command, 3845 CommandReturnObject &result) 3846 { 3847 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3848 if (target) 3849 { 3850 // FIXME: see if we can use the breakpoint id style parser? 3851 size_t num_args = command.GetArgumentCount(); 3852 if (num_args == 0) 3853 { 3854 if (!m_interpreter.Confirm ("Delete all stop hooks?", true)) 3855 { 3856 result.SetStatus (eReturnStatusFailed); 3857 return false; 3858 } 3859 else 3860 { 3861 target->RemoveAllStopHooks(); 3862 } 3863 } 3864 else 3865 { 3866 bool success; 3867 for (size_t i = 0; i < num_args; i++) 3868 { 3869 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 3870 if (!success) 3871 { 3872 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3873 result.SetStatus(eReturnStatusFailed); 3874 return false; 3875 } 3876 success = target->RemoveStopHookByID (user_id); 3877 if (!success) 3878 { 3879 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3880 result.SetStatus(eReturnStatusFailed); 3881 return false; 3882 } 3883 } 3884 } 3885 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3886 } 3887 else 3888 { 3889 result.AppendError ("invalid target\n"); 3890 result.SetStatus (eReturnStatusFailed); 3891 } 3892 3893 return result.Succeeded(); 3894 } 3895 }; 3896 #pragma mark CommandObjectTargetStopHookEnableDisable 3897 3898 //------------------------------------------------------------------------- 3899 // CommandObjectTargetStopHookEnableDisable 3900 //------------------------------------------------------------------------- 3901 3902 class CommandObjectTargetStopHookEnableDisable : public CommandObject 3903 { 3904 public: 3905 3906 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) : 3907 CommandObject (interpreter, 3908 name, 3909 help, 3910 syntax), 3911 m_enable (enable) 3912 { 3913 } 3914 3915 ~CommandObjectTargetStopHookEnableDisable () 3916 { 3917 } 3918 3919 bool 3920 Execute (Args& command, 3921 CommandReturnObject &result) 3922 { 3923 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3924 if (target) 3925 { 3926 // FIXME: see if we can use the breakpoint id style parser? 3927 size_t num_args = command.GetArgumentCount(); 3928 bool success; 3929 3930 if (num_args == 0) 3931 { 3932 target->SetAllStopHooksActiveState (m_enable); 3933 } 3934 else 3935 { 3936 for (size_t i = 0; i < num_args; i++) 3937 { 3938 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 3939 if (!success) 3940 { 3941 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3942 result.SetStatus(eReturnStatusFailed); 3943 return false; 3944 } 3945 success = target->SetStopHookActiveStateByID (user_id, m_enable); 3946 if (!success) 3947 { 3948 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 3949 result.SetStatus(eReturnStatusFailed); 3950 return false; 3951 } 3952 } 3953 } 3954 result.SetStatus (eReturnStatusSuccessFinishNoResult); 3955 } 3956 else 3957 { 3958 result.AppendError ("invalid target\n"); 3959 result.SetStatus (eReturnStatusFailed); 3960 } 3961 return result.Succeeded(); 3962 } 3963 private: 3964 bool m_enable; 3965 }; 3966 3967 #pragma mark CommandObjectTargetStopHookList 3968 3969 //------------------------------------------------------------------------- 3970 // CommandObjectTargetStopHookList 3971 //------------------------------------------------------------------------- 3972 3973 class CommandObjectTargetStopHookList : public CommandObject 3974 { 3975 public: 3976 3977 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) : 3978 CommandObject (interpreter, 3979 "target stop-hook list", 3980 "List all stop-hooks.", 3981 "target stop-hook list [<type>]") 3982 { 3983 } 3984 3985 ~CommandObjectTargetStopHookList () 3986 { 3987 } 3988 3989 bool 3990 Execute (Args& command, 3991 CommandReturnObject &result) 3992 { 3993 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3994 if (!target) 3995 { 3996 result.AppendError ("invalid target\n"); 3997 result.SetStatus (eReturnStatusFailed); 3998 return result.Succeeded(); 3999 } 4000 4001 size_t num_hooks = target->GetNumStopHooks (); 4002 if (num_hooks == 0) 4003 { 4004 result.GetOutputStream().PutCString ("No stop hooks.\n"); 4005 } 4006 else 4007 { 4008 for (size_t i = 0; i < num_hooks; i++) 4009 { 4010 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i); 4011 if (i > 0) 4012 result.GetOutputStream().PutCString ("\n"); 4013 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull); 4014 } 4015 } 4016 result.SetStatus (eReturnStatusSuccessFinishResult); 4017 return result.Succeeded(); 4018 } 4019 }; 4020 4021 #pragma mark CommandObjectMultiwordTargetStopHooks 4022 //------------------------------------------------------------------------- 4023 // CommandObjectMultiwordTargetStopHooks 4024 //------------------------------------------------------------------------- 4025 4026 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword 4027 { 4028 public: 4029 4030 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) : 4031 CommandObjectMultiword (interpreter, 4032 "target stop-hook", 4033 "A set of commands for operating on debugger target stop-hooks.", 4034 "target stop-hook <subcommand> [<subcommand-options>]") 4035 { 4036 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter))); 4037 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter))); 4038 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 4039 false, 4040 "target stop-hook disable [<id>]", 4041 "Disable a stop-hook.", 4042 "target stop-hook disable"))); 4043 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 4044 true, 4045 "target stop-hook enable [<id>]", 4046 "Enable a stop-hook.", 4047 "target stop-hook enable"))); 4048 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter))); 4049 } 4050 4051 ~CommandObjectMultiwordTargetStopHooks() 4052 { 4053 } 4054 }; 4055 4056 4057 4058 #pragma mark CommandObjectMultiwordTarget 4059 4060 //------------------------------------------------------------------------- 4061 // CommandObjectMultiwordTarget 4062 //------------------------------------------------------------------------- 4063 4064 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) : 4065 CommandObjectMultiword (interpreter, 4066 "target", 4067 "A set of commands for operating on debugger targets.", 4068 "target <subcommand> [<subcommand-options>]") 4069 { 4070 4071 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter))); 4072 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter))); 4073 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter))); 4074 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter))); 4075 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter))); 4076 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter))); 4077 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter))); 4078 } 4079 4080 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () 4081 { 4082 } 4083 4084 4085