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 "lldb/lldb-python.h" 11 12 #include "CommandObjectTarget.h" 13 14 // C Includes 15 #include <errno.h> 16 17 // C++ Includes 18 // Other libraries and framework includes 19 // Project includes 20 #include "lldb/Interpreter/Args.h" 21 #include "lldb/Core/Debugger.h" 22 #include "lldb/Core/InputReader.h" 23 #include "lldb/Core/Module.h" 24 #include "lldb/Core/ModuleSpec.h" 25 #include "lldb/Core/Section.h" 26 #include "lldb/Core/State.h" 27 #include "lldb/Core/Timer.h" 28 #include "lldb/Core/ValueObjectVariable.h" 29 #include "lldb/Host/Symbols.h" 30 #include "lldb/Interpreter/CommandInterpreter.h" 31 #include "lldb/Interpreter/CommandReturnObject.h" 32 #include "lldb/Interpreter/Options.h" 33 #include "lldb/Interpreter/OptionGroupArchitecture.h" 34 #include "lldb/Interpreter/OptionGroupBoolean.h" 35 #include "lldb/Interpreter/OptionGroupFile.h" 36 #include "lldb/Interpreter/OptionGroupFormat.h" 37 #include "lldb/Interpreter/OptionGroupVariable.h" 38 #include "lldb/Interpreter/OptionGroupPlatform.h" 39 #include "lldb/Interpreter/OptionGroupUInt64.h" 40 #include "lldb/Interpreter/OptionGroupUUID.h" 41 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h" 42 #include "lldb/Symbol/CompileUnit.h" 43 #include "lldb/Symbol/FuncUnwinders.h" 44 #include "lldb/Symbol/LineTable.h" 45 #include "lldb/Symbol/ObjectFile.h" 46 #include "lldb/Symbol/SymbolFile.h" 47 #include "lldb/Symbol/SymbolVendor.h" 48 #include "lldb/Symbol/UnwindPlan.h" 49 #include "lldb/Symbol/VariableList.h" 50 #include "lldb/Target/Process.h" 51 #include "lldb/Target/StackFrame.h" 52 #include "lldb/Target/Thread.h" 53 #include "lldb/Target/ThreadSpec.h" 54 55 using namespace lldb; 56 using namespace lldb_private; 57 58 59 60 static void 61 DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm) 62 { 63 const ArchSpec &target_arch = target->GetArchitecture(); 64 65 Module *exe_module = target->GetExecutableModulePointer(); 66 char exe_path[PATH_MAX]; 67 bool exe_valid = false; 68 if (exe_module) 69 exe_valid = exe_module->GetFileSpec().GetPath (exe_path, sizeof(exe_path)); 70 71 if (!exe_valid) 72 ::strcpy (exe_path, "<none>"); 73 74 strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path); 75 76 uint32_t properties = 0; 77 if (target_arch.IsValid()) 78 { 79 strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str()); 80 properties++; 81 } 82 PlatformSP platform_sp (target->GetPlatform()); 83 if (platform_sp) 84 strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName().GetCString()); 85 86 ProcessSP process_sp (target->GetProcessSP()); 87 bool show_process_status = false; 88 if (process_sp) 89 { 90 lldb::pid_t pid = process_sp->GetID(); 91 StateType state = process_sp->GetState(); 92 if (show_stopped_process_status) 93 show_process_status = StateIsStoppedState(state, true); 94 const char *state_cstr = StateAsCString (state); 95 if (pid != LLDB_INVALID_PROCESS_ID) 96 strm.Printf ("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid); 97 strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr); 98 } 99 if (properties > 0) 100 strm.PutCString (" )\n"); 101 else 102 strm.EOL(); 103 if (show_process_status) 104 { 105 const bool only_threads_with_stop_reason = true; 106 const uint32_t start_frame = 0; 107 const uint32_t num_frames = 1; 108 const uint32_t num_frames_with_source = 1; 109 process_sp->GetStatus (strm); 110 process_sp->GetThreadStatus (strm, 111 only_threads_with_stop_reason, 112 start_frame, 113 num_frames, 114 num_frames_with_source); 115 116 } 117 } 118 119 static uint32_t 120 DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm) 121 { 122 const uint32_t num_targets = target_list.GetNumTargets(); 123 if (num_targets) 124 { 125 TargetSP selected_target_sp (target_list.GetSelectedTarget()); 126 strm.PutCString ("Current targets:\n"); 127 for (uint32_t i=0; i<num_targets; ++i) 128 { 129 TargetSP target_sp (target_list.GetTargetAtIndex (i)); 130 if (target_sp) 131 { 132 bool is_selected = target_sp.get() == selected_target_sp.get(); 133 DumpTargetInfo (i, 134 target_sp.get(), 135 is_selected ? "* " : " ", 136 show_stopped_process_status, 137 strm); 138 } 139 } 140 } 141 return num_targets; 142 } 143 #pragma mark CommandObjectTargetCreate 144 145 //------------------------------------------------------------------------- 146 // "target create" 147 //------------------------------------------------------------------------- 148 149 class CommandObjectTargetCreate : public CommandObjectParsed 150 { 151 public: 152 CommandObjectTargetCreate(CommandInterpreter &interpreter) : 153 CommandObjectParsed (interpreter, 154 "target create", 155 "Create a target using the argument as the main executable.", 156 NULL), 157 m_option_group (interpreter), 158 m_arch_option (), 159 m_platform_options(true), // Do include the "--platform" option in the platform settings by passing true 160 m_core_file (LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename, "Fullpath to a core file to use for this target."), 161 m_symbol_file (LLDB_OPT_SET_1, false, "symfile", 's', 0, eArgTypeFilename, "Fullpath to a stand alone debug symbols file for when debug symbols are not in the executable."), 162 m_add_dependents (LLDB_OPT_SET_1, false, "no-dependents", 'd', "Don't load dependent files when creating the target, just add the specified executable.", true, true) 163 { 164 CommandArgumentEntry arg; 165 CommandArgumentData file_arg; 166 167 // Define the first (and only) variant of this arg. 168 file_arg.arg_type = eArgTypeFilename; 169 file_arg.arg_repetition = eArgRepeatPlain; 170 171 // There is only one variant this argument could be; put it into the argument entry. 172 arg.push_back (file_arg); 173 174 // Push the data for the first argument into the m_arguments vector. 175 m_arguments.push_back (arg); 176 177 m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 178 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 179 m_option_group.Append (&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 180 m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 181 m_option_group.Append (&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 182 m_option_group.Finalize(); 183 } 184 185 ~CommandObjectTargetCreate () 186 { 187 } 188 189 Options * 190 GetOptions () 191 { 192 return &m_option_group; 193 } 194 195 virtual int 196 HandleArgumentCompletion (Args &input, 197 int &cursor_index, 198 int &cursor_char_position, 199 OptionElementVector &opt_element_vector, 200 int match_start_point, 201 int max_return_elements, 202 bool &word_complete, 203 StringList &matches) 204 { 205 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 206 completion_str.erase (cursor_char_position); 207 208 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 209 CommandCompletions::eDiskFileCompletion, 210 completion_str.c_str(), 211 match_start_point, 212 max_return_elements, 213 NULL, 214 word_complete, 215 matches); 216 return matches.GetSize(); 217 } 218 219 protected: 220 bool 221 DoExecute (Args& command, CommandReturnObject &result) 222 { 223 const size_t argc = command.GetArgumentCount(); 224 FileSpec core_file (m_core_file.GetOptionValue().GetCurrentValue()); 225 226 if (argc == 1 || core_file) 227 { 228 FileSpec symfile (m_symbol_file.GetOptionValue().GetCurrentValue()); 229 if (symfile) 230 { 231 if (!symfile.Exists()) 232 { 233 char symfile_path[PATH_MAX]; 234 symfile.GetPath(symfile_path, sizeof(symfile_path)); 235 result.AppendErrorWithFormat("invalid symbol file path '%s'", symfile_path); 236 result.SetStatus (eReturnStatusFailed); 237 return false; 238 } 239 } 240 241 const char *file_path = command.GetArgumentAtIndex(0); 242 Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path); 243 TargetSP target_sp; 244 Debugger &debugger = m_interpreter.GetDebugger(); 245 const char *arch_cstr = m_arch_option.GetArchitectureName(); 246 const bool get_dependent_files = m_add_dependents.GetOptionValue().GetCurrentValue(); 247 Error error (debugger.GetTargetList().CreateTarget (debugger, 248 file_path, 249 arch_cstr, 250 get_dependent_files, 251 &m_platform_options, 252 target_sp)); 253 254 if (target_sp) 255 { 256 if (symfile) 257 { 258 ModuleSP module_sp (target_sp->GetExecutableModule()); 259 if (module_sp) 260 module_sp->SetSymbolFileFileSpec(symfile); 261 } 262 263 debugger.GetTargetList().SetSelectedTarget(target_sp.get()); 264 if (core_file) 265 { 266 char core_path[PATH_MAX]; 267 core_file.GetPath(core_path, sizeof(core_path)); 268 if (core_file.Exists()) 269 { 270 FileSpec core_file_dir; 271 core_file_dir.GetDirectory() = core_file.GetDirectory(); 272 target_sp->GetExecutableSearchPaths ().Append (core_file_dir); 273 274 ProcessSP process_sp (target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), NULL, &core_file)); 275 276 if (process_sp) 277 { 278 // Seems wierd that we Launch a core file, but that is 279 // what we do! 280 error = process_sp->LoadCore(); 281 282 if (error.Fail()) 283 { 284 result.AppendError(error.AsCString("can't find plug-in for core file")); 285 result.SetStatus (eReturnStatusFailed); 286 return false; 287 } 288 else 289 { 290 result.AppendMessageWithFormat ("Core file '%s' (%s) was loaded.\n", core_path, target_sp->GetArchitecture().GetArchitectureName()); 291 result.SetStatus (eReturnStatusSuccessFinishNoResult); 292 } 293 } 294 else 295 { 296 result.AppendErrorWithFormat ("Unable to find process plug-in for core file '%s'\n", core_path); 297 result.SetStatus (eReturnStatusFailed); 298 } 299 } 300 else 301 { 302 result.AppendErrorWithFormat ("Core file '%s' does not exist\n", core_path); 303 result.SetStatus (eReturnStatusFailed); 304 } 305 } 306 else 307 { 308 result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName()); 309 result.SetStatus (eReturnStatusSuccessFinishNoResult); 310 } 311 } 312 else 313 { 314 result.AppendError(error.AsCString()); 315 result.SetStatus (eReturnStatusFailed); 316 } 317 } 318 else 319 { 320 result.AppendErrorWithFormat("'%s' takes exactly one executable path argument, or use the --core-file option.\n", m_cmd_name.c_str()); 321 result.SetStatus (eReturnStatusFailed); 322 } 323 return result.Succeeded(); 324 325 } 326 327 private: 328 OptionGroupOptions m_option_group; 329 OptionGroupArchitecture m_arch_option; 330 OptionGroupPlatform m_platform_options; 331 OptionGroupFile m_core_file; 332 OptionGroupFile m_symbol_file; 333 OptionGroupBoolean m_add_dependents; 334 }; 335 336 #pragma mark CommandObjectTargetList 337 338 //---------------------------------------------------------------------- 339 // "target list" 340 //---------------------------------------------------------------------- 341 342 class CommandObjectTargetList : public CommandObjectParsed 343 { 344 public: 345 CommandObjectTargetList (CommandInterpreter &interpreter) : 346 CommandObjectParsed (interpreter, 347 "target list", 348 "List all current targets in the current debug session.", 349 NULL, 350 0) 351 { 352 } 353 354 virtual 355 ~CommandObjectTargetList () 356 { 357 } 358 359 protected: 360 virtual bool 361 DoExecute (Args& args, CommandReturnObject &result) 362 { 363 if (args.GetArgumentCount() == 0) 364 { 365 Stream &strm = result.GetOutputStream(); 366 367 bool show_stopped_process_status = false; 368 if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0) 369 { 370 strm.PutCString ("No targets.\n"); 371 } 372 result.SetStatus (eReturnStatusSuccessFinishResult); 373 } 374 else 375 { 376 result.AppendError ("the 'target list' command takes no arguments\n"); 377 result.SetStatus (eReturnStatusFailed); 378 } 379 return result.Succeeded(); 380 } 381 }; 382 383 384 #pragma mark CommandObjectTargetSelect 385 386 //---------------------------------------------------------------------- 387 // "target select" 388 //---------------------------------------------------------------------- 389 390 class CommandObjectTargetSelect : public CommandObjectParsed 391 { 392 public: 393 CommandObjectTargetSelect (CommandInterpreter &interpreter) : 394 CommandObjectParsed (interpreter, 395 "target select", 396 "Select a target as the current target by target index.", 397 NULL, 398 0) 399 { 400 } 401 402 virtual 403 ~CommandObjectTargetSelect () 404 { 405 } 406 407 protected: 408 virtual bool 409 DoExecute (Args& args, CommandReturnObject &result) 410 { 411 if (args.GetArgumentCount() == 1) 412 { 413 bool success = false; 414 const char *target_idx_arg = args.GetArgumentAtIndex(0); 415 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success); 416 if (success) 417 { 418 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList(); 419 const uint32_t num_targets = target_list.GetNumTargets(); 420 if (target_idx < num_targets) 421 { 422 TargetSP target_sp (target_list.GetTargetAtIndex (target_idx)); 423 if (target_sp) 424 { 425 Stream &strm = result.GetOutputStream(); 426 target_list.SetSelectedTarget (target_sp.get()); 427 bool show_stopped_process_status = false; 428 DumpTargetList (target_list, show_stopped_process_status, strm); 429 result.SetStatus (eReturnStatusSuccessFinishResult); 430 } 431 else 432 { 433 result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx); 434 result.SetStatus (eReturnStatusFailed); 435 } 436 } 437 else 438 { 439 result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n", 440 target_idx, 441 num_targets - 1); 442 result.SetStatus (eReturnStatusFailed); 443 } 444 } 445 else 446 { 447 result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg); 448 result.SetStatus (eReturnStatusFailed); 449 } 450 } 451 else 452 { 453 result.AppendError ("'target select' takes a single argument: a target index\n"); 454 result.SetStatus (eReturnStatusFailed); 455 } 456 return result.Succeeded(); 457 } 458 }; 459 460 #pragma mark CommandObjectTargetSelect 461 462 //---------------------------------------------------------------------- 463 // "target delete" 464 //---------------------------------------------------------------------- 465 466 class CommandObjectTargetDelete : public CommandObjectParsed 467 { 468 public: 469 CommandObjectTargetDelete (CommandInterpreter &interpreter) : 470 CommandObjectParsed (interpreter, 471 "target delete", 472 "Delete one or more targets by target index.", 473 NULL, 474 0), 475 m_option_group (interpreter), 476 m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', "Perform extra cleanup to minimize memory consumption after deleting the target.", false, false) 477 { 478 m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 479 m_option_group.Finalize(); 480 } 481 482 virtual 483 ~CommandObjectTargetDelete () 484 { 485 } 486 487 Options * 488 GetOptions () 489 { 490 return &m_option_group; 491 } 492 493 protected: 494 virtual bool 495 DoExecute (Args& args, CommandReturnObject &result) 496 { 497 const size_t argc = args.GetArgumentCount(); 498 std::vector<TargetSP> delete_target_list; 499 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList(); 500 bool success = true; 501 TargetSP target_sp; 502 if (argc > 0) 503 { 504 const uint32_t num_targets = target_list.GetNumTargets(); 505 // Bail out if don't have any targets. 506 if (num_targets == 0) { 507 result.AppendError("no targets to delete"); 508 result.SetStatus(eReturnStatusFailed); 509 success = false; 510 } 511 512 for (uint32_t arg_idx = 0; success && arg_idx < argc; ++arg_idx) 513 { 514 const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx); 515 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success); 516 if (success) 517 { 518 if (target_idx < num_targets) 519 { 520 target_sp = target_list.GetTargetAtIndex (target_idx); 521 if (target_sp) 522 { 523 delete_target_list.push_back (target_sp); 524 continue; 525 } 526 } 527 if (num_targets > 1) 528 result.AppendErrorWithFormat ("target index %u is out of range, valid target indexes are 0 - %u\n", 529 target_idx, 530 num_targets - 1); 531 else 532 result.AppendErrorWithFormat("target index %u is out of range, the only valid index is 0\n", 533 target_idx); 534 535 result.SetStatus (eReturnStatusFailed); 536 success = false; 537 } 538 else 539 { 540 result.AppendErrorWithFormat("invalid target index '%s'\n", target_idx_arg); 541 result.SetStatus (eReturnStatusFailed); 542 success = false; 543 } 544 } 545 546 } 547 else 548 { 549 target_sp = target_list.GetSelectedTarget(); 550 if (target_sp) 551 { 552 delete_target_list.push_back (target_sp); 553 } 554 else 555 { 556 result.AppendErrorWithFormat("no target is currently selected\n"); 557 result.SetStatus (eReturnStatusFailed); 558 success = false; 559 } 560 } 561 if (success) 562 { 563 const size_t num_targets_to_delete = delete_target_list.size(); 564 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) 565 { 566 target_sp = delete_target_list[idx]; 567 target_list.DeleteTarget(target_sp); 568 target_sp->Destroy(); 569 } 570 // If "--clean" was specified, prune any orphaned shared modules from 571 // the global shared module list 572 if (m_cleanup_option.GetOptionValue ()) 573 { 574 const bool mandatory = true; 575 ModuleList::RemoveOrphanSharedModules(mandatory); 576 } 577 result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete); 578 result.SetStatus(eReturnStatusSuccessFinishResult); 579 } 580 581 return result.Succeeded(); 582 } 583 584 OptionGroupOptions m_option_group; 585 OptionGroupBoolean m_cleanup_option; 586 }; 587 588 589 #pragma mark CommandObjectTargetVariable 590 591 //---------------------------------------------------------------------- 592 // "target variable" 593 //---------------------------------------------------------------------- 594 595 class CommandObjectTargetVariable : public CommandObjectParsed 596 { 597 public: 598 CommandObjectTargetVariable (CommandInterpreter &interpreter) : 599 CommandObjectParsed (interpreter, 600 "target variable", 601 "Read global variable(s) prior to, or while running your binary.", 602 NULL, 603 eFlagRequiresTarget), 604 m_option_group (interpreter), 605 m_option_variable (false), // Don't include frame options 606 m_option_format (eFormatDefault), 607 m_option_compile_units (LLDB_OPT_SET_1, false, "file", 'file', 0, eArgTypeFilename, "A basename or fullpath to a file that contains global variables. This option can be specified multiple times."), 608 m_option_shared_libraries (LLDB_OPT_SET_1, false, "shlib",'shlb', 0, eArgTypeFilename, "A basename or fullpath to a shared library to use in the search for global variables. This option can be specified multiple times."), 609 m_varobj_options() 610 { 611 CommandArgumentEntry arg; 612 CommandArgumentData var_name_arg; 613 614 // Define the first (and only) variant of this arg. 615 var_name_arg.arg_type = eArgTypeVarName; 616 var_name_arg.arg_repetition = eArgRepeatPlus; 617 618 // There is only one variant this argument could be; put it into the argument entry. 619 arg.push_back (var_name_arg); 620 621 // Push the data for the first argument into the m_arguments vector. 622 m_arguments.push_back (arg); 623 624 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 625 m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 626 m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1); 627 m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 628 m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 629 m_option_group.Finalize(); 630 } 631 632 virtual 633 ~CommandObjectTargetVariable () 634 { 635 } 636 637 void 638 DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name) 639 { 640 ValueObject::DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions()); 641 642 switch (var_sp->GetScope()) 643 { 644 case eValueTypeVariableGlobal: 645 if (m_option_variable.show_scope) 646 s.PutCString("GLOBAL: "); 647 break; 648 649 case eValueTypeVariableStatic: 650 if (m_option_variable.show_scope) 651 s.PutCString("STATIC: "); 652 break; 653 654 case eValueTypeVariableArgument: 655 if (m_option_variable.show_scope) 656 s.PutCString(" ARG: "); 657 break; 658 659 case eValueTypeVariableLocal: 660 if (m_option_variable.show_scope) 661 s.PutCString(" LOCAL: "); 662 break; 663 664 default: 665 break; 666 } 667 668 if (m_option_variable.show_decl) 669 { 670 bool show_fullpaths = false; 671 bool show_module = true; 672 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module)) 673 s.PutCString (": "); 674 } 675 676 const Format format = m_option_format.GetFormat(); 677 if (format != eFormatDefault) 678 options.SetFormat(format); 679 680 options.SetRootValueObjectName(root_name); 681 682 ValueObject::DumpValueObject (s, 683 valobj_sp.get(), 684 options); 685 686 } 687 688 689 static size_t GetVariableCallback (void *baton, 690 const char *name, 691 VariableList &variable_list) 692 { 693 Target *target = static_cast<Target *>(baton); 694 if (target) 695 { 696 return target->GetImages().FindGlobalVariables (ConstString(name), 697 true, 698 UINT32_MAX, 699 variable_list); 700 } 701 return 0; 702 } 703 704 705 706 Options * 707 GetOptions () 708 { 709 return &m_option_group; 710 } 711 712 protected: 713 714 void 715 DumpGlobalVariableList(const ExecutionContext &exe_ctx, const SymbolContext &sc, const VariableList &variable_list, Stream &s) 716 { 717 size_t count = variable_list.GetSize(); 718 if (count > 0) 719 { 720 if (sc.module_sp) 721 { 722 if (sc.comp_unit) 723 { 724 s.Printf ("Global variables for %s in %s:\n", 725 sc.comp_unit->GetPath().c_str(), 726 sc.module_sp->GetFileSpec().GetPath().c_str()); 727 } 728 else 729 { 730 s.Printf ("Global variables for %s\n", 731 sc.module_sp->GetFileSpec().GetPath().c_str()); 732 } 733 } 734 else if (sc.comp_unit) 735 { 736 s.Printf ("Global variables for %s\n", 737 sc.comp_unit->GetPath().c_str()); 738 } 739 740 for (uint32_t i=0; i<count; ++i) 741 { 742 VariableSP var_sp (variable_list.GetVariableAtIndex(i)); 743 if (var_sp) 744 { 745 ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp)); 746 747 if (valobj_sp) 748 DumpValueObject (s, var_sp, valobj_sp, var_sp->GetName().GetCString()); 749 } 750 } 751 } 752 753 } 754 virtual bool 755 DoExecute (Args& args, CommandReturnObject &result) 756 { 757 Target *target = m_exe_ctx.GetTargetPtr(); 758 const size_t argc = args.GetArgumentCount(); 759 Stream &s = result.GetOutputStream(); 760 761 if (argc > 0) 762 { 763 764 for (size_t idx = 0; idx < argc; ++idx) 765 { 766 VariableList variable_list; 767 ValueObjectList valobj_list; 768 769 const char *arg = args.GetArgumentAtIndex(idx); 770 size_t matches = 0; 771 bool use_var_name = false; 772 if (m_option_variable.use_regex) 773 { 774 RegularExpression regex(arg); 775 if (!regex.IsValid ()) 776 { 777 result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg); 778 result.SetStatus (eReturnStatusFailed); 779 return false; 780 } 781 use_var_name = true; 782 matches = target->GetImages().FindGlobalVariables (regex, 783 true, 784 UINT32_MAX, 785 variable_list); 786 } 787 else 788 { 789 Error error (Variable::GetValuesForVariableExpressionPath (arg, 790 m_exe_ctx.GetBestExecutionContextScope(), 791 GetVariableCallback, 792 target, 793 variable_list, 794 valobj_list)); 795 matches = variable_list.GetSize(); 796 } 797 798 if (matches == 0) 799 { 800 result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg); 801 result.SetStatus (eReturnStatusFailed); 802 return false; 803 } 804 else 805 { 806 for (uint32_t global_idx=0; global_idx<matches; ++global_idx) 807 { 808 VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx)); 809 if (var_sp) 810 { 811 ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx)); 812 if (!valobj_sp) 813 valobj_sp = ValueObjectVariable::Create (m_exe_ctx.GetBestExecutionContextScope(), var_sp); 814 815 if (valobj_sp) 816 DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg); 817 } 818 } 819 } 820 } 821 } 822 else 823 { 824 const FileSpecList &compile_units = m_option_compile_units.GetOptionValue().GetCurrentValue(); 825 const FileSpecList &shlibs = m_option_shared_libraries.GetOptionValue().GetCurrentValue(); 826 SymbolContextList sc_list; 827 const size_t num_compile_units = compile_units.GetSize(); 828 const size_t num_shlibs = shlibs.GetSize(); 829 if (num_compile_units == 0 && num_shlibs == 0) 830 { 831 bool success = false; 832 StackFrame *frame = m_exe_ctx.GetFramePtr(); 833 CompileUnit *comp_unit = NULL; 834 if (frame) 835 { 836 SymbolContext sc = frame->GetSymbolContext (eSymbolContextCompUnit); 837 if (sc.comp_unit) 838 { 839 const bool can_create = true; 840 VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create)); 841 if (comp_unit_varlist_sp) 842 { 843 size_t count = comp_unit_varlist_sp->GetSize(); 844 if (count > 0) 845 { 846 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s); 847 success = true; 848 } 849 } 850 } 851 } 852 if (!success) 853 { 854 if (frame) 855 { 856 if (comp_unit) 857 result.AppendErrorWithFormat ("no global variables in current compile unit: %s\n", 858 comp_unit->GetPath().c_str()); 859 else 860 result.AppendErrorWithFormat ("no debug information for frame %u\n", frame->GetFrameIndex()); 861 } 862 else 863 result.AppendError ("'target variable' takes one or more global variable names as arguments\n"); 864 result.SetStatus (eReturnStatusFailed); 865 } 866 } 867 else 868 { 869 SymbolContextList sc_list; 870 const bool append = true; 871 // We have one or more compile unit or shlib 872 if (num_shlibs > 0) 873 { 874 for (size_t shlib_idx=0; shlib_idx<num_shlibs; ++shlib_idx) 875 { 876 const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx)); 877 ModuleSpec module_spec (module_file); 878 879 ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec)); 880 if (module_sp) 881 { 882 if (num_compile_units > 0) 883 { 884 for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx) 885 module_sp->FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list); 886 } 887 else 888 { 889 SymbolContext sc; 890 sc.module_sp = module_sp; 891 sc_list.Append(sc); 892 } 893 } 894 else 895 { 896 // Didn't find matching shlib/module in target... 897 result.AppendErrorWithFormat ("target doesn't contain the specified shared library: %s\n", 898 module_file.GetPath().c_str()); 899 } 900 } 901 } 902 else 903 { 904 // No shared libraries, we just want to find globals for the compile units files that were specified 905 for (size_t cu_idx=0; cu_idx<num_compile_units; ++cu_idx) 906 target->GetImages().FindCompileUnits(compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list); 907 } 908 909 const uint32_t num_scs = sc_list.GetSize(); 910 if (num_scs > 0) 911 { 912 SymbolContext sc; 913 for (uint32_t sc_idx=0; sc_idx<num_scs; ++sc_idx) 914 { 915 if (sc_list.GetContextAtIndex(sc_idx, sc)) 916 { 917 if (sc.comp_unit) 918 { 919 const bool can_create = true; 920 VariableListSP comp_unit_varlist_sp (sc.comp_unit->GetVariableList(can_create)); 921 if (comp_unit_varlist_sp) 922 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s); 923 } 924 else if (sc.module_sp) 925 { 926 // Get all global variables for this module 927 lldb_private::RegularExpression all_globals_regex("."); // Any global with at least one character 928 VariableList variable_list; 929 sc.module_sp->FindGlobalVariables(all_globals_regex, append, UINT32_MAX, variable_list); 930 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s); 931 } 932 } 933 } 934 } 935 } 936 } 937 938 if (m_interpreter.TruncationWarningNecessary()) 939 { 940 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(), 941 m_cmd_name.c_str()); 942 m_interpreter.TruncationWarningGiven(); 943 } 944 945 return result.Succeeded(); 946 } 947 948 OptionGroupOptions m_option_group; 949 OptionGroupVariable m_option_variable; 950 OptionGroupFormat m_option_format; 951 OptionGroupFileList m_option_compile_units; 952 OptionGroupFileList m_option_shared_libraries; 953 OptionGroupValueObjectDisplay m_varobj_options; 954 955 }; 956 957 958 #pragma mark CommandObjectTargetModulesSearchPathsAdd 959 960 class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed 961 { 962 public: 963 964 CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) : 965 CommandObjectParsed (interpreter, 966 "target modules search-paths add", 967 "Add new image search paths substitution pairs to the current target.", 968 NULL) 969 { 970 CommandArgumentEntry arg; 971 CommandArgumentData old_prefix_arg; 972 CommandArgumentData new_prefix_arg; 973 974 // Define the first variant of this arg pair. 975 old_prefix_arg.arg_type = eArgTypeOldPathPrefix; 976 old_prefix_arg.arg_repetition = eArgRepeatPairPlus; 977 978 // Define the first variant of this arg pair. 979 new_prefix_arg.arg_type = eArgTypeNewPathPrefix; 980 new_prefix_arg.arg_repetition = eArgRepeatPairPlus; 981 982 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they 983 // must always occur together, they are treated as two variants of one argument rather than two independent 984 // arguments. Push them both into the first argument position for m_arguments... 985 986 arg.push_back (old_prefix_arg); 987 arg.push_back (new_prefix_arg); 988 989 m_arguments.push_back (arg); 990 } 991 992 ~CommandObjectTargetModulesSearchPathsAdd () 993 { 994 } 995 996 protected: 997 bool 998 DoExecute (Args& command, 999 CommandReturnObject &result) 1000 { 1001 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1002 if (target) 1003 { 1004 const size_t argc = command.GetArgumentCount(); 1005 if (argc & 1) 1006 { 1007 result.AppendError ("add requires an even number of arguments\n"); 1008 result.SetStatus (eReturnStatusFailed); 1009 } 1010 else 1011 { 1012 for (size_t i=0; i<argc; i+=2) 1013 { 1014 const char *from = command.GetArgumentAtIndex(i); 1015 const char *to = command.GetArgumentAtIndex(i+1); 1016 1017 if (from[0] && to[0]) 1018 { 1019 bool last_pair = ((argc - i) == 2); 1020 target->GetImageSearchPathList().Append (ConstString(from), 1021 ConstString(to), 1022 last_pair); // Notify if this is the last pair 1023 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1024 } 1025 else 1026 { 1027 if (from[0]) 1028 result.AppendError ("<path-prefix> can't be empty\n"); 1029 else 1030 result.AppendError ("<new-path-prefix> can't be empty\n"); 1031 result.SetStatus (eReturnStatusFailed); 1032 } 1033 } 1034 } 1035 } 1036 else 1037 { 1038 result.AppendError ("invalid target\n"); 1039 result.SetStatus (eReturnStatusFailed); 1040 } 1041 return result.Succeeded(); 1042 } 1043 }; 1044 1045 #pragma mark CommandObjectTargetModulesSearchPathsClear 1046 1047 class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed 1048 { 1049 public: 1050 1051 CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) : 1052 CommandObjectParsed (interpreter, 1053 "target modules search-paths clear", 1054 "Clear all current image search path substitution pairs from the current target.", 1055 "target modules search-paths clear") 1056 { 1057 } 1058 1059 ~CommandObjectTargetModulesSearchPathsClear () 1060 { 1061 } 1062 1063 protected: 1064 bool 1065 DoExecute (Args& command, 1066 CommandReturnObject &result) 1067 { 1068 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1069 if (target) 1070 { 1071 bool notify = true; 1072 target->GetImageSearchPathList().Clear(notify); 1073 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1074 } 1075 else 1076 { 1077 result.AppendError ("invalid target\n"); 1078 result.SetStatus (eReturnStatusFailed); 1079 } 1080 return result.Succeeded(); 1081 } 1082 }; 1083 1084 #pragma mark CommandObjectTargetModulesSearchPathsInsert 1085 1086 class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed 1087 { 1088 public: 1089 1090 CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) : 1091 CommandObjectParsed (interpreter, 1092 "target modules search-paths insert", 1093 "Insert a new image search path substitution pair into the current target at the specified index.", 1094 NULL) 1095 { 1096 CommandArgumentEntry arg1; 1097 CommandArgumentEntry arg2; 1098 CommandArgumentData index_arg; 1099 CommandArgumentData old_prefix_arg; 1100 CommandArgumentData new_prefix_arg; 1101 1102 // Define the first and only variant of this arg. 1103 index_arg.arg_type = eArgTypeIndex; 1104 index_arg.arg_repetition = eArgRepeatPlain; 1105 1106 // Put the one and only variant into the first arg for m_arguments: 1107 arg1.push_back (index_arg); 1108 1109 // Define the first variant of this arg pair. 1110 old_prefix_arg.arg_type = eArgTypeOldPathPrefix; 1111 old_prefix_arg.arg_repetition = eArgRepeatPairPlus; 1112 1113 // Define the first variant of this arg pair. 1114 new_prefix_arg.arg_type = eArgTypeNewPathPrefix; 1115 new_prefix_arg.arg_repetition = eArgRepeatPairPlus; 1116 1117 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they 1118 // must always occur together, they are treated as two variants of one argument rather than two independent 1119 // arguments. Push them both into the same argument position for m_arguments... 1120 1121 arg2.push_back (old_prefix_arg); 1122 arg2.push_back (new_prefix_arg); 1123 1124 // Add arguments to m_arguments. 1125 m_arguments.push_back (arg1); 1126 m_arguments.push_back (arg2); 1127 } 1128 1129 ~CommandObjectTargetModulesSearchPathsInsert () 1130 { 1131 } 1132 1133 protected: 1134 bool 1135 DoExecute (Args& command, 1136 CommandReturnObject &result) 1137 { 1138 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1139 if (target) 1140 { 1141 size_t argc = command.GetArgumentCount(); 1142 // check for at least 3 arguments and an odd nubmer of parameters 1143 if (argc >= 3 && argc & 1) 1144 { 1145 bool success = false; 1146 1147 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success); 1148 1149 if (!success) 1150 { 1151 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0)); 1152 result.SetStatus (eReturnStatusFailed); 1153 return result.Succeeded(); 1154 } 1155 1156 // shift off the index 1157 command.Shift(); 1158 argc = command.GetArgumentCount(); 1159 1160 for (uint32_t i=0; i<argc; i+=2, ++insert_idx) 1161 { 1162 const char *from = command.GetArgumentAtIndex(i); 1163 const char *to = command.GetArgumentAtIndex(i+1); 1164 1165 if (from[0] && to[0]) 1166 { 1167 bool last_pair = ((argc - i) == 2); 1168 target->GetImageSearchPathList().Insert (ConstString(from), 1169 ConstString(to), 1170 insert_idx, 1171 last_pair); 1172 result.SetStatus (eReturnStatusSuccessFinishNoResult); 1173 } 1174 else 1175 { 1176 if (from[0]) 1177 result.AppendError ("<path-prefix> can't be empty\n"); 1178 else 1179 result.AppendError ("<new-path-prefix> can't be empty\n"); 1180 result.SetStatus (eReturnStatusFailed); 1181 return false; 1182 } 1183 } 1184 } 1185 else 1186 { 1187 result.AppendError ("insert requires at least three arguments\n"); 1188 result.SetStatus (eReturnStatusFailed); 1189 return result.Succeeded(); 1190 } 1191 1192 } 1193 else 1194 { 1195 result.AppendError ("invalid target\n"); 1196 result.SetStatus (eReturnStatusFailed); 1197 } 1198 return result.Succeeded(); 1199 } 1200 }; 1201 1202 1203 #pragma mark CommandObjectTargetModulesSearchPathsList 1204 1205 1206 class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed 1207 { 1208 public: 1209 1210 CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) : 1211 CommandObjectParsed (interpreter, 1212 "target modules search-paths list", 1213 "List all current image search path substitution pairs in the current target.", 1214 "target modules search-paths list") 1215 { 1216 } 1217 1218 ~CommandObjectTargetModulesSearchPathsList () 1219 { 1220 } 1221 1222 protected: 1223 bool 1224 DoExecute (Args& command, 1225 CommandReturnObject &result) 1226 { 1227 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1228 if (target) 1229 { 1230 if (command.GetArgumentCount() != 0) 1231 { 1232 result.AppendError ("list takes no arguments\n"); 1233 result.SetStatus (eReturnStatusFailed); 1234 return result.Succeeded(); 1235 } 1236 1237 target->GetImageSearchPathList().Dump(&result.GetOutputStream()); 1238 result.SetStatus (eReturnStatusSuccessFinishResult); 1239 } 1240 else 1241 { 1242 result.AppendError ("invalid target\n"); 1243 result.SetStatus (eReturnStatusFailed); 1244 } 1245 return result.Succeeded(); 1246 } 1247 }; 1248 1249 #pragma mark CommandObjectTargetModulesSearchPathsQuery 1250 1251 class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed 1252 { 1253 public: 1254 1255 CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) : 1256 CommandObjectParsed (interpreter, 1257 "target modules search-paths query", 1258 "Transform a path using the first applicable image search path.", 1259 NULL) 1260 { 1261 CommandArgumentEntry arg; 1262 CommandArgumentData path_arg; 1263 1264 // Define the first (and only) variant of this arg. 1265 path_arg.arg_type = eArgTypeDirectoryName; 1266 path_arg.arg_repetition = eArgRepeatPlain; 1267 1268 // There is only one variant this argument could be; put it into the argument entry. 1269 arg.push_back (path_arg); 1270 1271 // Push the data for the first argument into the m_arguments vector. 1272 m_arguments.push_back (arg); 1273 } 1274 1275 ~CommandObjectTargetModulesSearchPathsQuery () 1276 { 1277 } 1278 1279 protected: 1280 bool 1281 DoExecute (Args& command, 1282 CommandReturnObject &result) 1283 { 1284 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 1285 if (target) 1286 { 1287 if (command.GetArgumentCount() != 1) 1288 { 1289 result.AppendError ("query requires one argument\n"); 1290 result.SetStatus (eReturnStatusFailed); 1291 return result.Succeeded(); 1292 } 1293 1294 ConstString orig(command.GetArgumentAtIndex(0)); 1295 ConstString transformed; 1296 if (target->GetImageSearchPathList().RemapPath(orig, transformed)) 1297 result.GetOutputStream().Printf("%s\n", transformed.GetCString()); 1298 else 1299 result.GetOutputStream().Printf("%s\n", orig.GetCString()); 1300 1301 result.SetStatus (eReturnStatusSuccessFinishResult); 1302 } 1303 else 1304 { 1305 result.AppendError ("invalid target\n"); 1306 result.SetStatus (eReturnStatusFailed); 1307 } 1308 return result.Succeeded(); 1309 } 1310 }; 1311 1312 //---------------------------------------------------------------------- 1313 // Static Helper functions 1314 //---------------------------------------------------------------------- 1315 static void 1316 DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width) 1317 { 1318 if (module) 1319 { 1320 const char *arch_cstr; 1321 if (full_triple) 1322 arch_cstr = module->GetArchitecture().GetTriple().str().c_str(); 1323 else 1324 arch_cstr = module->GetArchitecture().GetArchitectureName(); 1325 if (width) 1326 strm.Printf("%-*s", width, arch_cstr); 1327 else 1328 strm.PutCString(arch_cstr); 1329 } 1330 } 1331 1332 static void 1333 DumpModuleUUID (Stream &strm, Module *module) 1334 { 1335 if (module && module->GetUUID().IsValid()) 1336 module->GetUUID().Dump (&strm); 1337 else 1338 strm.PutCString(" "); 1339 } 1340 1341 static uint32_t 1342 DumpCompileUnitLineTable (CommandInterpreter &interpreter, 1343 Stream &strm, 1344 Module *module, 1345 const FileSpec &file_spec, 1346 bool load_addresses) 1347 { 1348 uint32_t num_matches = 0; 1349 if (module) 1350 { 1351 SymbolContextList sc_list; 1352 num_matches = module->ResolveSymbolContextsForFileSpec (file_spec, 1353 0, 1354 false, 1355 eSymbolContextCompUnit, 1356 sc_list); 1357 1358 for (uint32_t i=0; i<num_matches; ++i) 1359 { 1360 SymbolContext sc; 1361 if (sc_list.GetContextAtIndex(i, sc)) 1362 { 1363 if (i > 0) 1364 strm << "\n\n"; 1365 1366 strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `" 1367 << module->GetFileSpec().GetFilename() << "\n"; 1368 LineTable *line_table = sc.comp_unit->GetLineTable(); 1369 if (line_table) 1370 line_table->GetDescription (&strm, 1371 interpreter.GetExecutionContext().GetTargetPtr(), 1372 lldb::eDescriptionLevelBrief); 1373 else 1374 strm << "No line table"; 1375 } 1376 } 1377 } 1378 return num_matches; 1379 } 1380 1381 static void 1382 DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) 1383 { 1384 if (file_spec_ptr) 1385 { 1386 if (width > 0) 1387 { 1388 std::string fullpath = file_spec_ptr->GetPath(); 1389 strm.Printf("%-*s", width, fullpath.c_str()); 1390 return; 1391 } 1392 else 1393 { 1394 file_spec_ptr->Dump(&strm); 1395 return; 1396 } 1397 } 1398 // Keep the width spacing correct if things go wrong... 1399 if (width > 0) 1400 strm.Printf("%-*s", width, ""); 1401 } 1402 1403 static void 1404 DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) 1405 { 1406 if (file_spec_ptr) 1407 { 1408 if (width > 0) 1409 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString("")); 1410 else 1411 file_spec_ptr->GetDirectory().Dump(&strm); 1412 return; 1413 } 1414 // Keep the width spacing correct if things go wrong... 1415 if (width > 0) 1416 strm.Printf("%-*s", width, ""); 1417 } 1418 1419 static void 1420 DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width) 1421 { 1422 if (file_spec_ptr) 1423 { 1424 if (width > 0) 1425 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString("")); 1426 else 1427 file_spec_ptr->GetFilename().Dump(&strm); 1428 return; 1429 } 1430 // Keep the width spacing correct if things go wrong... 1431 if (width > 0) 1432 strm.Printf("%-*s", width, ""); 1433 } 1434 1435 1436 static void 1437 DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order) 1438 { 1439 if (module) 1440 { 1441 SymbolVendor *sym_vendor = module->GetSymbolVendor (); 1442 if (sym_vendor) 1443 { 1444 Symtab *symtab = sym_vendor->GetSymtab(); 1445 if (symtab) 1446 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), sort_order); 1447 } 1448 } 1449 } 1450 1451 static void 1452 DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module) 1453 { 1454 if (module) 1455 { 1456 SectionList *section_list = module->GetUnifiedSectionList(); 1457 if (section_list) 1458 { 1459 strm.Printf ("Sections for '%s' (%s):\n", 1460 module->GetSpecificationDescription().c_str(), 1461 module->GetArchitecture().GetArchitectureName()); 1462 strm.IndentMore(); 1463 section_list->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX); 1464 strm.IndentLess(); 1465 } 1466 } 1467 } 1468 1469 static bool 1470 DumpModuleSymbolVendor (Stream &strm, Module *module) 1471 { 1472 if (module) 1473 { 1474 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true); 1475 if (symbol_vendor) 1476 { 1477 symbol_vendor->Dump(&strm); 1478 return true; 1479 } 1480 } 1481 return false; 1482 } 1483 1484 static void 1485 DumpAddress (ExecutionContextScope *exe_scope, const Address &so_addr, bool verbose, Stream &strm) 1486 { 1487 strm.IndentMore(); 1488 strm.Indent (" Address: "); 1489 so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress); 1490 strm.PutCString (" ("); 1491 so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset); 1492 strm.PutCString (")\n"); 1493 strm.Indent (" Summary: "); 1494 const uint32_t save_indent = strm.GetIndentLevel (); 1495 strm.SetIndentLevel (save_indent + 13); 1496 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription); 1497 strm.SetIndentLevel (save_indent); 1498 // Print out detailed address information when verbose is enabled 1499 if (verbose) 1500 { 1501 strm.EOL(); 1502 so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext); 1503 } 1504 strm.IndentLess(); 1505 } 1506 1507 static bool 1508 LookupAddressInModule (CommandInterpreter &interpreter, 1509 Stream &strm, 1510 Module *module, 1511 uint32_t resolve_mask, 1512 lldb::addr_t raw_addr, 1513 lldb::addr_t offset, 1514 bool verbose) 1515 { 1516 if (module) 1517 { 1518 lldb::addr_t addr = raw_addr - offset; 1519 Address so_addr; 1520 SymbolContext sc; 1521 Target *target = interpreter.GetExecutionContext().GetTargetPtr(); 1522 if (target && !target->GetSectionLoadList().IsEmpty()) 1523 { 1524 if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr)) 1525 return false; 1526 else if (so_addr.GetModule().get() != module) 1527 return false; 1528 } 1529 else 1530 { 1531 if (!module->ResolveFileAddress (addr, so_addr)) 1532 return false; 1533 } 1534 1535 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope(); 1536 DumpAddress (exe_scope, so_addr, verbose, strm); 1537 // strm.IndentMore(); 1538 // strm.Indent (" Address: "); 1539 // so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress); 1540 // strm.PutCString (" ("); 1541 // so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset); 1542 // strm.PutCString (")\n"); 1543 // strm.Indent (" Summary: "); 1544 // const uint32_t save_indent = strm.GetIndentLevel (); 1545 // strm.SetIndentLevel (save_indent + 13); 1546 // so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription); 1547 // strm.SetIndentLevel (save_indent); 1548 // // Print out detailed address information when verbose is enabled 1549 // if (verbose) 1550 // { 1551 // strm.EOL(); 1552 // so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext); 1553 // } 1554 // strm.IndentLess(); 1555 return true; 1556 } 1557 1558 return false; 1559 } 1560 1561 static uint32_t 1562 LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose) 1563 { 1564 if (module) 1565 { 1566 SymbolContext sc; 1567 1568 SymbolVendor *sym_vendor = module->GetSymbolVendor (); 1569 if (sym_vendor) 1570 { 1571 Symtab *symtab = sym_vendor->GetSymtab(); 1572 if (symtab) 1573 { 1574 uint32_t i; 1575 std::vector<uint32_t> match_indexes; 1576 ConstString symbol_name (name); 1577 uint32_t num_matches = 0; 1578 if (name_is_regex) 1579 { 1580 RegularExpression name_regexp(name); 1581 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp, 1582 eSymbolTypeAny, 1583 match_indexes); 1584 } 1585 else 1586 { 1587 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes); 1588 } 1589 1590 1591 if (num_matches > 0) 1592 { 1593 strm.Indent (); 1594 strm.Printf("%u symbols match %s'%s' in ", num_matches, 1595 name_is_regex ? "the regular expression " : "", name); 1596 DumpFullpath (strm, &module->GetFileSpec(), 0); 1597 strm.PutCString(":\n"); 1598 strm.IndentMore (); 1599 //Symtab::DumpSymbolHeader (&strm); 1600 for (i=0; i < num_matches; ++i) 1601 { 1602 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]); 1603 DumpAddress (interpreter.GetExecutionContext().GetBestExecutionContextScope(), 1604 symbol->GetAddress(), 1605 verbose, 1606 strm); 1607 1608 // strm.Indent (); 1609 // symbol->Dump (&strm, interpreter.GetExecutionContext().GetTargetPtr(), i); 1610 } 1611 strm.IndentLess (); 1612 return num_matches; 1613 } 1614 } 1615 } 1616 } 1617 return 0; 1618 } 1619 1620 1621 static void 1622 DumpSymbolContextList (ExecutionContextScope *exe_scope, Stream &strm, SymbolContextList &sc_list, bool verbose) 1623 { 1624 strm.IndentMore (); 1625 uint32_t i; 1626 const uint32_t num_matches = sc_list.GetSize(); 1627 1628 for (i=0; i<num_matches; ++i) 1629 { 1630 SymbolContext sc; 1631 if (sc_list.GetContextAtIndex(i, sc)) 1632 { 1633 AddressRange range; 1634 1635 sc.GetAddressRange(eSymbolContextEverything, 1636 0, 1637 true, 1638 range); 1639 1640 DumpAddress (exe_scope, range.GetBaseAddress(), verbose, strm); 1641 } 1642 } 1643 strm.IndentLess (); 1644 } 1645 1646 static size_t 1647 LookupFunctionInModule (CommandInterpreter &interpreter, 1648 Stream &strm, 1649 Module *module, 1650 const char *name, 1651 bool name_is_regex, 1652 bool include_inlines, 1653 bool include_symbols, 1654 bool verbose) 1655 { 1656 if (module && name && name[0]) 1657 { 1658 SymbolContextList sc_list; 1659 const bool append = true; 1660 size_t num_matches = 0; 1661 if (name_is_regex) 1662 { 1663 RegularExpression function_name_regex (name); 1664 num_matches = module->FindFunctions (function_name_regex, 1665 include_symbols, 1666 include_inlines, 1667 append, 1668 sc_list); 1669 } 1670 else 1671 { 1672 ConstString function_name (name); 1673 num_matches = module->FindFunctions (function_name, 1674 NULL, 1675 eFunctionNameTypeAuto, 1676 include_symbols, 1677 include_inlines, 1678 append, 1679 sc_list); 1680 } 1681 1682 if (num_matches) 1683 { 1684 strm.Indent (); 1685 strm.Printf("%zu match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1686 DumpFullpath (strm, &module->GetFileSpec(), 0); 1687 strm.PutCString(":\n"); 1688 DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose); 1689 } 1690 return num_matches; 1691 } 1692 return 0; 1693 } 1694 1695 static size_t 1696 LookupTypeInModule (CommandInterpreter &interpreter, 1697 Stream &strm, 1698 Module *module, 1699 const char *name_cstr, 1700 bool name_is_regex) 1701 { 1702 if (module && name_cstr && name_cstr[0]) 1703 { 1704 TypeList type_list; 1705 const uint32_t max_num_matches = UINT32_MAX; 1706 size_t num_matches = 0; 1707 bool name_is_fully_qualified = false; 1708 SymbolContext sc; 1709 1710 ConstString name(name_cstr); 1711 num_matches = module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, type_list); 1712 1713 if (num_matches) 1714 { 1715 strm.Indent (); 1716 strm.Printf("%zu match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1717 DumpFullpath (strm, &module->GetFileSpec(), 0); 1718 strm.PutCString(":\n"); 1719 const uint32_t num_types = type_list.GetSize(); 1720 for (uint32_t i=0; i<num_types; ++i) 1721 { 1722 TypeSP type_sp (type_list.GetTypeAtIndex(i)); 1723 if (type_sp) 1724 { 1725 // Resolve the clang type so that any forward references 1726 // to types that haven't yet been parsed will get parsed. 1727 type_sp->GetClangFullType (); 1728 type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1729 // Print all typedef chains 1730 TypeSP typedef_type_sp (type_sp); 1731 TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType()); 1732 while (typedefed_type_sp) 1733 { 1734 strm.EOL(); 1735 strm.Printf(" typedef '%s': ", typedef_type_sp->GetName().GetCString()); 1736 typedefed_type_sp->GetClangFullType (); 1737 typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1738 typedef_type_sp = typedefed_type_sp; 1739 typedefed_type_sp = typedef_type_sp->GetTypedefType(); 1740 } 1741 } 1742 strm.EOL(); 1743 } 1744 } 1745 return num_matches; 1746 } 1747 return 0; 1748 } 1749 1750 static size_t 1751 LookupTypeHere (CommandInterpreter &interpreter, 1752 Stream &strm, 1753 const SymbolContext &sym_ctx, 1754 const char *name_cstr, 1755 bool name_is_regex) 1756 { 1757 if (!sym_ctx.module_sp) 1758 return 0; 1759 1760 TypeList type_list; 1761 const uint32_t max_num_matches = UINT32_MAX; 1762 size_t num_matches = 1; 1763 bool name_is_fully_qualified = false; 1764 1765 ConstString name(name_cstr); 1766 num_matches = sym_ctx.module_sp->FindTypes(sym_ctx, name, name_is_fully_qualified, max_num_matches, type_list); 1767 1768 if (num_matches) 1769 { 1770 strm.Indent (); 1771 strm.PutCString("Best match found in "); 1772 DumpFullpath (strm, &sym_ctx.module_sp->GetFileSpec(), 0); 1773 strm.PutCString(":\n"); 1774 1775 TypeSP type_sp (type_list.GetTypeAtIndex(0)); 1776 if (type_sp) 1777 { 1778 // Resolve the clang type so that any forward references 1779 // to types that haven't yet been parsed will get parsed. 1780 type_sp->GetClangFullType (); 1781 type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1782 // Print all typedef chains 1783 TypeSP typedef_type_sp (type_sp); 1784 TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType()); 1785 while (typedefed_type_sp) 1786 { 1787 strm.EOL(); 1788 strm.Printf(" typedef '%s': ", typedef_type_sp->GetName().GetCString()); 1789 typedefed_type_sp->GetClangFullType (); 1790 typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true); 1791 typedef_type_sp = typedefed_type_sp; 1792 typedefed_type_sp = typedef_type_sp->GetTypedefType(); 1793 } 1794 } 1795 strm.EOL(); 1796 } 1797 return num_matches; 1798 } 1799 1800 static uint32_t 1801 LookupFileAndLineInModule (CommandInterpreter &interpreter, 1802 Stream &strm, 1803 Module *module, 1804 const FileSpec &file_spec, 1805 uint32_t line, 1806 bool check_inlines, 1807 bool verbose) 1808 { 1809 if (module && file_spec) 1810 { 1811 SymbolContextList sc_list; 1812 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines, 1813 eSymbolContextEverything, sc_list); 1814 if (num_matches > 0) 1815 { 1816 strm.Indent (); 1817 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : ""); 1818 strm << file_spec; 1819 if (line > 0) 1820 strm.Printf (":%u", line); 1821 strm << " in "; 1822 DumpFullpath (strm, &module->GetFileSpec(), 0); 1823 strm.PutCString(":\n"); 1824 DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose); 1825 return num_matches; 1826 } 1827 } 1828 return 0; 1829 1830 } 1831 1832 1833 static size_t 1834 FindModulesByName (Target *target, 1835 const char *module_name, 1836 ModuleList &module_list, 1837 bool check_global_list) 1838 { 1839 // Dump specified images (by basename or fullpath) 1840 FileSpec module_file_spec(module_name, false); 1841 ModuleSpec module_spec (module_file_spec); 1842 1843 const size_t initial_size = module_list.GetSize (); 1844 1845 if (check_global_list) 1846 { 1847 // Check the global list 1848 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex()); 1849 const size_t num_modules = Module::GetNumberAllocatedModules(); 1850 ModuleSP module_sp; 1851 for (size_t image_idx = 0; image_idx<num_modules; ++image_idx) 1852 { 1853 Module *module = Module::GetAllocatedModuleAtIndex(image_idx); 1854 1855 if (module) 1856 { 1857 if (module->MatchesModuleSpec (module_spec)) 1858 { 1859 module_sp = module->shared_from_this(); 1860 module_list.AppendIfNeeded(module_sp); 1861 } 1862 } 1863 } 1864 } 1865 else 1866 { 1867 if (target) 1868 { 1869 const size_t num_matches = target->GetImages().FindModules (module_spec, module_list); 1870 1871 // Not found in our module list for our target, check the main 1872 // shared module list in case it is a extra file used somewhere 1873 // else 1874 if (num_matches == 0) 1875 { 1876 module_spec.GetArchitecture() = target->GetArchitecture(); 1877 ModuleList::FindSharedModules (module_spec, module_list); 1878 } 1879 } 1880 else 1881 { 1882 ModuleList::FindSharedModules (module_spec,module_list); 1883 } 1884 } 1885 1886 return module_list.GetSize () - initial_size; 1887 } 1888 1889 #pragma mark CommandObjectTargetModulesModuleAutoComplete 1890 1891 //---------------------------------------------------------------------- 1892 // A base command object class that can auto complete with module file 1893 // paths 1894 //---------------------------------------------------------------------- 1895 1896 class CommandObjectTargetModulesModuleAutoComplete : public CommandObjectParsed 1897 { 1898 public: 1899 1900 CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter, 1901 const char *name, 1902 const char *help, 1903 const char *syntax) : 1904 CommandObjectParsed (interpreter, name, help, syntax) 1905 { 1906 CommandArgumentEntry arg; 1907 CommandArgumentData file_arg; 1908 1909 // Define the first (and only) variant of this arg. 1910 file_arg.arg_type = eArgTypeFilename; 1911 file_arg.arg_repetition = eArgRepeatStar; 1912 1913 // There is only one variant this argument could be; put it into the argument entry. 1914 arg.push_back (file_arg); 1915 1916 // Push the data for the first argument into the m_arguments vector. 1917 m_arguments.push_back (arg); 1918 } 1919 1920 virtual 1921 ~CommandObjectTargetModulesModuleAutoComplete () 1922 { 1923 } 1924 1925 virtual int 1926 HandleArgumentCompletion (Args &input, 1927 int &cursor_index, 1928 int &cursor_char_position, 1929 OptionElementVector &opt_element_vector, 1930 int match_start_point, 1931 int max_return_elements, 1932 bool &word_complete, 1933 StringList &matches) 1934 { 1935 // Arguments are the standard module completer. 1936 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 1937 completion_str.erase (cursor_char_position); 1938 1939 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 1940 CommandCompletions::eModuleCompletion, 1941 completion_str.c_str(), 1942 match_start_point, 1943 max_return_elements, 1944 NULL, 1945 word_complete, 1946 matches); 1947 return matches.GetSize(); 1948 } 1949 }; 1950 1951 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete 1952 1953 //---------------------------------------------------------------------- 1954 // A base command object class that can auto complete with module source 1955 // file paths 1956 //---------------------------------------------------------------------- 1957 1958 class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectParsed 1959 { 1960 public: 1961 1962 CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter, 1963 const char *name, 1964 const char *help, 1965 const char *syntax, 1966 uint32_t flags) : 1967 CommandObjectParsed (interpreter, name, help, syntax, flags) 1968 { 1969 CommandArgumentEntry arg; 1970 CommandArgumentData source_file_arg; 1971 1972 // Define the first (and only) variant of this arg. 1973 source_file_arg.arg_type = eArgTypeSourceFile; 1974 source_file_arg.arg_repetition = eArgRepeatPlus; 1975 1976 // There is only one variant this argument could be; put it into the argument entry. 1977 arg.push_back (source_file_arg); 1978 1979 // Push the data for the first argument into the m_arguments vector. 1980 m_arguments.push_back (arg); 1981 } 1982 1983 virtual 1984 ~CommandObjectTargetModulesSourceFileAutoComplete () 1985 { 1986 } 1987 1988 virtual int 1989 HandleArgumentCompletion (Args &input, 1990 int &cursor_index, 1991 int &cursor_char_position, 1992 OptionElementVector &opt_element_vector, 1993 int match_start_point, 1994 int max_return_elements, 1995 bool &word_complete, 1996 StringList &matches) 1997 { 1998 // Arguments are the standard source file completer. 1999 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2000 completion_str.erase (cursor_char_position); 2001 2002 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2003 CommandCompletions::eSourceFileCompletion, 2004 completion_str.c_str(), 2005 match_start_point, 2006 max_return_elements, 2007 NULL, 2008 word_complete, 2009 matches); 2010 return matches.GetSize(); 2011 } 2012 }; 2013 2014 2015 #pragma mark CommandObjectTargetModulesDumpSymtab 2016 2017 2018 class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete 2019 { 2020 public: 2021 CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) : 2022 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2023 "target modules dump symtab", 2024 "Dump the symbol table from one or more target modules.", 2025 NULL), 2026 m_options (interpreter) 2027 { 2028 } 2029 2030 virtual 2031 ~CommandObjectTargetModulesDumpSymtab () 2032 { 2033 } 2034 2035 virtual Options * 2036 GetOptions () 2037 { 2038 return &m_options; 2039 } 2040 2041 class CommandOptions : public Options 2042 { 2043 public: 2044 2045 CommandOptions (CommandInterpreter &interpreter) : 2046 Options(interpreter), 2047 m_sort_order (eSortOrderNone) 2048 { 2049 } 2050 2051 virtual 2052 ~CommandOptions () 2053 { 2054 } 2055 2056 virtual Error 2057 SetOptionValue (uint32_t option_idx, const char *option_arg) 2058 { 2059 Error error; 2060 const int short_option = m_getopt_table[option_idx].val; 2061 2062 switch (short_option) 2063 { 2064 case 's': 2065 m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg, 2066 g_option_table[option_idx].enum_values, 2067 eSortOrderNone, 2068 error); 2069 break; 2070 2071 default: 2072 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 2073 break; 2074 2075 } 2076 return error; 2077 } 2078 2079 void 2080 OptionParsingStarting () 2081 { 2082 m_sort_order = eSortOrderNone; 2083 } 2084 2085 const OptionDefinition* 2086 GetDefinitions () 2087 { 2088 return g_option_table; 2089 } 2090 2091 // Options table: Required for subclasses of Options. 2092 static OptionDefinition g_option_table[]; 2093 2094 SortOrder m_sort_order; 2095 }; 2096 2097 protected: 2098 virtual bool 2099 DoExecute (Args& command, 2100 CommandReturnObject &result) 2101 { 2102 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2103 if (target == NULL) 2104 { 2105 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2106 result.SetStatus (eReturnStatusFailed); 2107 return false; 2108 } 2109 else 2110 { 2111 uint32_t num_dumped = 0; 2112 2113 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2114 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2115 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2116 2117 if (command.GetArgumentCount() == 0) 2118 { 2119 // Dump all sections for all modules images 2120 Mutex::Locker modules_locker(target->GetImages().GetMutex()); 2121 const size_t num_modules = target->GetImages().GetSize(); 2122 if (num_modules > 0) 2123 { 2124 result.GetOutputStream().Printf("Dumping symbol table for %zu modules.\n", num_modules); 2125 for (size_t image_idx = 0; image_idx<num_modules; ++image_idx) 2126 { 2127 if (num_dumped > 0) 2128 { 2129 result.GetOutputStream().EOL(); 2130 result.GetOutputStream().EOL(); 2131 } 2132 num_dumped++; 2133 DumpModuleSymtab (m_interpreter, 2134 result.GetOutputStream(), 2135 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx), 2136 m_options.m_sort_order); 2137 } 2138 } 2139 else 2140 { 2141 result.AppendError ("the target has no associated executable images"); 2142 result.SetStatus (eReturnStatusFailed); 2143 return false; 2144 } 2145 } 2146 else 2147 { 2148 // Dump specified images (by basename or fullpath) 2149 const char *arg_cstr; 2150 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2151 { 2152 ModuleList module_list; 2153 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2154 if (num_matches > 0) 2155 { 2156 for (size_t i=0; i<num_matches; ++i) 2157 { 2158 Module *module = module_list.GetModulePointerAtIndex(i); 2159 if (module) 2160 { 2161 if (num_dumped > 0) 2162 { 2163 result.GetOutputStream().EOL(); 2164 result.GetOutputStream().EOL(); 2165 } 2166 num_dumped++; 2167 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order); 2168 } 2169 } 2170 } 2171 else 2172 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2173 } 2174 } 2175 2176 if (num_dumped > 0) 2177 result.SetStatus (eReturnStatusSuccessFinishResult); 2178 else 2179 { 2180 result.AppendError ("no matching executable images found"); 2181 result.SetStatus (eReturnStatusFailed); 2182 } 2183 } 2184 return result.Succeeded(); 2185 } 2186 2187 2188 CommandOptions m_options; 2189 }; 2190 2191 static OptionEnumValueElement 2192 g_sort_option_enumeration[4] = 2193 { 2194 { eSortOrderNone, "none", "No sorting, use the original symbol table order."}, 2195 { eSortOrderByAddress, "address", "Sort output by symbol address."}, 2196 { eSortOrderByName, "name", "Sort output by symbol name."}, 2197 { 0, NULL, NULL } 2198 }; 2199 2200 2201 OptionDefinition 2202 CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] = 2203 { 2204 { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."}, 2205 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 2206 }; 2207 2208 #pragma mark CommandObjectTargetModulesDumpSections 2209 2210 //---------------------------------------------------------------------- 2211 // Image section dumping command 2212 //---------------------------------------------------------------------- 2213 2214 class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete 2215 { 2216 public: 2217 CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) : 2218 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2219 "target modules dump sections", 2220 "Dump the sections from one or more target modules.", 2221 //"target modules dump sections [<file1> ...]") 2222 NULL) 2223 { 2224 } 2225 2226 virtual 2227 ~CommandObjectTargetModulesDumpSections () 2228 { 2229 } 2230 2231 protected: 2232 virtual bool 2233 DoExecute (Args& command, 2234 CommandReturnObject &result) 2235 { 2236 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2237 if (target == NULL) 2238 { 2239 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2240 result.SetStatus (eReturnStatusFailed); 2241 return false; 2242 } 2243 else 2244 { 2245 uint32_t num_dumped = 0; 2246 2247 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2248 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2249 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2250 2251 if (command.GetArgumentCount() == 0) 2252 { 2253 // Dump all sections for all modules images 2254 const size_t num_modules = target->GetImages().GetSize(); 2255 if (num_modules > 0) 2256 { 2257 result.GetOutputStream().Printf("Dumping sections for %zu modules.\n", num_modules); 2258 for (size_t image_idx = 0; image_idx<num_modules; ++image_idx) 2259 { 2260 num_dumped++; 2261 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)); 2262 } 2263 } 2264 else 2265 { 2266 result.AppendError ("the target has no associated executable images"); 2267 result.SetStatus (eReturnStatusFailed); 2268 return false; 2269 } 2270 } 2271 else 2272 { 2273 // Dump specified images (by basename or fullpath) 2274 const char *arg_cstr; 2275 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2276 { 2277 ModuleList module_list; 2278 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2279 if (num_matches > 0) 2280 { 2281 for (size_t i=0; i<num_matches; ++i) 2282 { 2283 Module *module = module_list.GetModulePointerAtIndex(i); 2284 if (module) 2285 { 2286 num_dumped++; 2287 DumpModuleSections (m_interpreter, result.GetOutputStream(), module); 2288 } 2289 } 2290 } 2291 else 2292 { 2293 // Check the global list 2294 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex()); 2295 2296 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2297 } 2298 } 2299 } 2300 2301 if (num_dumped > 0) 2302 result.SetStatus (eReturnStatusSuccessFinishResult); 2303 else 2304 { 2305 result.AppendError ("no matching executable images found"); 2306 result.SetStatus (eReturnStatusFailed); 2307 } 2308 } 2309 return result.Succeeded(); 2310 } 2311 }; 2312 2313 2314 #pragma mark CommandObjectTargetModulesDumpSymfile 2315 2316 //---------------------------------------------------------------------- 2317 // Image debug symbol dumping command 2318 //---------------------------------------------------------------------- 2319 2320 class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete 2321 { 2322 public: 2323 CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) : 2324 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2325 "target modules dump symfile", 2326 "Dump the debug symbol file for one or more target modules.", 2327 //"target modules dump symfile [<file1> ...]") 2328 NULL) 2329 { 2330 } 2331 2332 virtual 2333 ~CommandObjectTargetModulesDumpSymfile () 2334 { 2335 } 2336 2337 protected: 2338 virtual bool 2339 DoExecute (Args& command, 2340 CommandReturnObject &result) 2341 { 2342 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2343 if (target == NULL) 2344 { 2345 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2346 result.SetStatus (eReturnStatusFailed); 2347 return false; 2348 } 2349 else 2350 { 2351 uint32_t num_dumped = 0; 2352 2353 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2354 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2355 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2356 2357 if (command.GetArgumentCount() == 0) 2358 { 2359 // Dump all sections for all modules images 2360 const ModuleList &target_modules = target->GetImages(); 2361 Mutex::Locker modules_locker (target_modules.GetMutex()); 2362 const size_t num_modules = target_modules.GetSize(); 2363 if (num_modules > 0) 2364 { 2365 result.GetOutputStream().Printf("Dumping debug symbols for %zu modules.\n", num_modules); 2366 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 2367 { 2368 if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx))) 2369 num_dumped++; 2370 } 2371 } 2372 else 2373 { 2374 result.AppendError ("the target has no associated executable images"); 2375 result.SetStatus (eReturnStatusFailed); 2376 return false; 2377 } 2378 } 2379 else 2380 { 2381 // Dump specified images (by basename or fullpath) 2382 const char *arg_cstr; 2383 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2384 { 2385 ModuleList module_list; 2386 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true); 2387 if (num_matches > 0) 2388 { 2389 for (size_t i=0; i<num_matches; ++i) 2390 { 2391 Module *module = module_list.GetModulePointerAtIndex(i); 2392 if (module) 2393 { 2394 if (DumpModuleSymbolVendor (result.GetOutputStream(), module)) 2395 num_dumped++; 2396 } 2397 } 2398 } 2399 else 2400 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 2401 } 2402 } 2403 2404 if (num_dumped > 0) 2405 result.SetStatus (eReturnStatusSuccessFinishResult); 2406 else 2407 { 2408 result.AppendError ("no matching executable images found"); 2409 result.SetStatus (eReturnStatusFailed); 2410 } 2411 } 2412 return result.Succeeded(); 2413 } 2414 }; 2415 2416 2417 #pragma mark CommandObjectTargetModulesDumpLineTable 2418 2419 //---------------------------------------------------------------------- 2420 // Image debug line table dumping command 2421 //---------------------------------------------------------------------- 2422 2423 class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete 2424 { 2425 public: 2426 CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) : 2427 CommandObjectTargetModulesSourceFileAutoComplete (interpreter, 2428 "target modules dump line-table", 2429 "Dump the line table for one or more compilation units.", 2430 NULL, 2431 eFlagRequiresTarget) 2432 { 2433 } 2434 2435 virtual 2436 ~CommandObjectTargetModulesDumpLineTable () 2437 { 2438 } 2439 2440 protected: 2441 virtual bool 2442 DoExecute (Args& command, 2443 CommandReturnObject &result) 2444 { 2445 Target *target = m_exe_ctx.GetTargetPtr(); 2446 uint32_t total_num_dumped = 0; 2447 2448 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2449 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2450 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2451 2452 if (command.GetArgumentCount() == 0) 2453 { 2454 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str()); 2455 result.SetStatus (eReturnStatusFailed); 2456 } 2457 else 2458 { 2459 // Dump specified images (by basename or fullpath) 2460 const char *arg_cstr; 2461 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2462 { 2463 FileSpec file_spec(arg_cstr, false); 2464 2465 const ModuleList &target_modules = target->GetImages(); 2466 Mutex::Locker modules_locker(target_modules.GetMutex()); 2467 const size_t num_modules = target_modules.GetSize(); 2468 if (num_modules > 0) 2469 { 2470 uint32_t num_dumped = 0; 2471 for (uint32_t i = 0; i<num_modules; ++i) 2472 { 2473 if (DumpCompileUnitLineTable (m_interpreter, 2474 result.GetOutputStream(), 2475 target_modules.GetModulePointerAtIndexUnlocked(i), 2476 file_spec, 2477 m_exe_ctx.GetProcessPtr() && m_exe_ctx.GetProcessRef().IsAlive())) 2478 num_dumped++; 2479 } 2480 if (num_dumped == 0) 2481 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr); 2482 else 2483 total_num_dumped += num_dumped; 2484 } 2485 } 2486 } 2487 2488 if (total_num_dumped > 0) 2489 result.SetStatus (eReturnStatusSuccessFinishResult); 2490 else 2491 { 2492 result.AppendError ("no source filenames matched any command arguments"); 2493 result.SetStatus (eReturnStatusFailed); 2494 } 2495 return result.Succeeded(); 2496 } 2497 }; 2498 2499 2500 #pragma mark CommandObjectTargetModulesDump 2501 2502 //---------------------------------------------------------------------- 2503 // Dump multi-word command for target modules 2504 //---------------------------------------------------------------------- 2505 2506 class CommandObjectTargetModulesDump : public CommandObjectMultiword 2507 { 2508 public: 2509 2510 //------------------------------------------------------------------ 2511 // Constructors and Destructors 2512 //------------------------------------------------------------------ 2513 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) : 2514 CommandObjectMultiword (interpreter, 2515 "target modules dump", 2516 "A set of commands for dumping information about one or more target modules.", 2517 "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]") 2518 { 2519 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter))); 2520 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter))); 2521 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter))); 2522 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter))); 2523 } 2524 2525 virtual 2526 ~CommandObjectTargetModulesDump() 2527 { 2528 } 2529 }; 2530 2531 class CommandObjectTargetModulesAdd : public CommandObjectParsed 2532 { 2533 public: 2534 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) : 2535 CommandObjectParsed (interpreter, 2536 "target modules add", 2537 "Add a new module to the current target's modules.", 2538 "target modules add [<module>]"), 2539 m_option_group (interpreter), 2540 m_symbol_file (LLDB_OPT_SET_1, false, "symfile", 's', 0, eArgTypeFilename, "Fullpath to a stand alone debug symbols file for when debug symbols are not in the executable.") 2541 { 2542 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2543 m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2544 m_option_group.Finalize(); 2545 } 2546 2547 virtual 2548 ~CommandObjectTargetModulesAdd () 2549 { 2550 } 2551 2552 virtual Options * 2553 GetOptions () 2554 { 2555 return &m_option_group; 2556 } 2557 2558 virtual int 2559 HandleArgumentCompletion (Args &input, 2560 int &cursor_index, 2561 int &cursor_char_position, 2562 OptionElementVector &opt_element_vector, 2563 int match_start_point, 2564 int max_return_elements, 2565 bool &word_complete, 2566 StringList &matches) 2567 { 2568 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2569 completion_str.erase (cursor_char_position); 2570 2571 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2572 CommandCompletions::eDiskFileCompletion, 2573 completion_str.c_str(), 2574 match_start_point, 2575 max_return_elements, 2576 NULL, 2577 word_complete, 2578 matches); 2579 return matches.GetSize(); 2580 } 2581 2582 protected: 2583 2584 OptionGroupOptions m_option_group; 2585 OptionGroupUUID m_uuid_option_group; 2586 OptionGroupFile m_symbol_file; 2587 2588 2589 virtual bool 2590 DoExecute (Args& args, 2591 CommandReturnObject &result) 2592 { 2593 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2594 if (target == NULL) 2595 { 2596 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2597 result.SetStatus (eReturnStatusFailed); 2598 return false; 2599 } 2600 else 2601 { 2602 bool flush = false; 2603 2604 const size_t argc = args.GetArgumentCount(); 2605 if (argc == 0) 2606 { 2607 if (m_uuid_option_group.GetOptionValue ().OptionWasSet()) 2608 { 2609 // We are given a UUID only, go locate the file 2610 ModuleSpec module_spec; 2611 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue(); 2612 if (m_symbol_file.GetOptionValue().OptionWasSet()) 2613 module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue(); 2614 if (Symbols::DownloadObjectAndSymbolFile (module_spec)) 2615 { 2616 ModuleSP module_sp (target->GetSharedModule (module_spec)); 2617 if (module_sp) 2618 { 2619 result.SetStatus (eReturnStatusSuccessFinishResult); 2620 return true; 2621 } 2622 else 2623 { 2624 flush = true; 2625 2626 StreamString strm; 2627 module_spec.GetUUID().Dump (&strm); 2628 if (module_spec.GetFileSpec()) 2629 { 2630 if (module_spec.GetSymbolFileSpec()) 2631 { 2632 result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s and symbol file %s", 2633 strm.GetString().c_str(), 2634 module_spec.GetFileSpec().GetPath().c_str(), 2635 module_spec.GetSymbolFileSpec().GetPath().c_str()); 2636 } 2637 else 2638 { 2639 result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s", 2640 strm.GetString().c_str(), 2641 module_spec.GetFileSpec().GetPath().c_str()); 2642 } 2643 } 2644 else 2645 { 2646 result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s", 2647 strm.GetString().c_str()); 2648 } 2649 result.SetStatus (eReturnStatusFailed); 2650 return false; 2651 } 2652 } 2653 else 2654 { 2655 StreamString strm; 2656 module_spec.GetUUID().Dump (&strm); 2657 result.AppendErrorWithFormat ("Unable to locate the executable or symbol file with UUID %s", strm.GetString().c_str()); 2658 result.SetStatus (eReturnStatusFailed); 2659 return false; 2660 } 2661 } 2662 else 2663 { 2664 result.AppendError ("one or more executable image paths must be specified"); 2665 result.SetStatus (eReturnStatusFailed); 2666 return false; 2667 } 2668 } 2669 else 2670 { 2671 for (size_t i=0; i<argc; ++i) 2672 { 2673 const char *path = args.GetArgumentAtIndex(i); 2674 if (path) 2675 { 2676 FileSpec file_spec(path, true); 2677 if (file_spec.Exists()) 2678 { 2679 ModuleSpec module_spec (file_spec); 2680 if (m_uuid_option_group.GetOptionValue ().OptionWasSet()) 2681 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue(); 2682 if (m_symbol_file.GetOptionValue().OptionWasSet()) 2683 module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue(); 2684 Error error; 2685 ModuleSP module_sp (target->GetSharedModule (module_spec, &error)); 2686 if (!module_sp) 2687 { 2688 const char *error_cstr = error.AsCString(); 2689 if (error_cstr) 2690 result.AppendError (error_cstr); 2691 else 2692 result.AppendErrorWithFormat ("unsupported module: %s", path); 2693 result.SetStatus (eReturnStatusFailed); 2694 return false; 2695 } 2696 else 2697 { 2698 flush = true; 2699 } 2700 result.SetStatus (eReturnStatusSuccessFinishResult); 2701 } 2702 else 2703 { 2704 char resolved_path[PATH_MAX]; 2705 result.SetStatus (eReturnStatusFailed); 2706 if (file_spec.GetPath (resolved_path, sizeof(resolved_path))) 2707 { 2708 if (strcmp (resolved_path, path) != 0) 2709 { 2710 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path); 2711 break; 2712 } 2713 } 2714 result.AppendErrorWithFormat ("invalid module path '%s'\n", path); 2715 break; 2716 } 2717 } 2718 } 2719 } 2720 2721 if (flush) 2722 { 2723 ProcessSP process = target->GetProcessSP(); 2724 if (process) 2725 process->Flush(); 2726 } 2727 } 2728 2729 return result.Succeeded(); 2730 } 2731 2732 }; 2733 2734 class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete 2735 { 2736 public: 2737 CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) : 2738 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2739 "target modules load", 2740 "Set the load addresses for one or more sections in a target module.", 2741 "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"), 2742 m_option_group (interpreter), 2743 m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeFilename, "Fullpath or basename for module to load."), 2744 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) 2745 { 2746 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2747 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2748 m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2749 m_option_group.Finalize(); 2750 } 2751 2752 virtual 2753 ~CommandObjectTargetModulesLoad () 2754 { 2755 } 2756 2757 virtual Options * 2758 GetOptions () 2759 { 2760 return &m_option_group; 2761 } 2762 2763 protected: 2764 virtual bool 2765 DoExecute (Args& args, 2766 CommandReturnObject &result) 2767 { 2768 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2769 if (target == NULL) 2770 { 2771 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2772 result.SetStatus (eReturnStatusFailed); 2773 return false; 2774 } 2775 else 2776 { 2777 const size_t argc = args.GetArgumentCount(); 2778 ModuleSpec module_spec; 2779 bool search_using_module_spec = false; 2780 if (m_file_option.GetOptionValue().OptionWasSet()) 2781 { 2782 search_using_module_spec = true; 2783 module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); 2784 } 2785 2786 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) 2787 { 2788 search_using_module_spec = true; 2789 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2790 } 2791 2792 if (search_using_module_spec) 2793 { 2794 2795 ModuleList matching_modules; 2796 const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules); 2797 2798 char path[PATH_MAX]; 2799 if (num_matches == 1) 2800 { 2801 Module *module = matching_modules.GetModulePointerAtIndex(0); 2802 if (module) 2803 { 2804 ObjectFile *objfile = module->GetObjectFile(); 2805 if (objfile) 2806 { 2807 SectionList *section_list = objfile->GetSectionList(); 2808 if (section_list) 2809 { 2810 bool changed = false; 2811 if (argc == 0) 2812 { 2813 if (m_slide_option.GetOptionValue().OptionWasSet()) 2814 { 2815 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue(); 2816 module->SetLoadAddress (*target, slide, changed); 2817 } 2818 else 2819 { 2820 result.AppendError ("one or more section name + load address pair must be specified"); 2821 result.SetStatus (eReturnStatusFailed); 2822 return false; 2823 } 2824 } 2825 else 2826 { 2827 if (m_slide_option.GetOptionValue().OptionWasSet()) 2828 { 2829 result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n"); 2830 result.SetStatus (eReturnStatusFailed); 2831 return false; 2832 } 2833 2834 for (size_t i=0; i<argc; i += 2) 2835 { 2836 const char *sect_name = args.GetArgumentAtIndex(i); 2837 const char *load_addr_cstr = args.GetArgumentAtIndex(i+1); 2838 if (sect_name && load_addr_cstr) 2839 { 2840 ConstString const_sect_name(sect_name); 2841 bool success = false; 2842 addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success); 2843 if (success) 2844 { 2845 SectionSP section_sp (section_list->FindSectionByName(const_sect_name)); 2846 if (section_sp) 2847 { 2848 if (section_sp->IsThreadSpecific()) 2849 { 2850 result.AppendErrorWithFormat ("thread specific sections are not yet supported (section '%s')\n", sect_name); 2851 result.SetStatus (eReturnStatusFailed); 2852 break; 2853 } 2854 else 2855 { 2856 if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr)) 2857 changed = true; 2858 result.AppendMessageWithFormat("section '%s' loaded at 0x%" PRIx64 "\n", sect_name, load_addr); 2859 } 2860 } 2861 else 2862 { 2863 result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name); 2864 result.SetStatus (eReturnStatusFailed); 2865 break; 2866 } 2867 } 2868 else 2869 { 2870 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr); 2871 result.SetStatus (eReturnStatusFailed); 2872 break; 2873 } 2874 } 2875 else 2876 { 2877 if (sect_name) 2878 result.AppendError ("section names must be followed by a load address.\n"); 2879 else 2880 result.AppendError ("one or more section name + load address pair must be specified.\n"); 2881 result.SetStatus (eReturnStatusFailed); 2882 break; 2883 } 2884 } 2885 } 2886 2887 if (changed) 2888 { 2889 target->ModulesDidLoad (matching_modules); 2890 Process *process = m_exe_ctx.GetProcessPtr(); 2891 if (process) 2892 process->Flush(); 2893 } 2894 } 2895 else 2896 { 2897 module->GetFileSpec().GetPath (path, sizeof(path)); 2898 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path); 2899 result.SetStatus (eReturnStatusFailed); 2900 } 2901 } 2902 else 2903 { 2904 module->GetFileSpec().GetPath (path, sizeof(path)); 2905 result.AppendErrorWithFormat ("no object file for module '%s'\n", path); 2906 result.SetStatus (eReturnStatusFailed); 2907 } 2908 } 2909 else 2910 { 2911 FileSpec *module_spec_file = module_spec.GetFileSpecPtr(); 2912 if (module_spec_file) 2913 { 2914 module_spec_file->GetPath (path, sizeof(path)); 2915 result.AppendErrorWithFormat ("invalid module '%s'.\n", path); 2916 } 2917 else 2918 result.AppendError ("no module spec"); 2919 result.SetStatus (eReturnStatusFailed); 2920 } 2921 } 2922 else 2923 { 2924 std::string uuid_str; 2925 2926 if (module_spec.GetFileSpec()) 2927 module_spec.GetFileSpec().GetPath (path, sizeof(path)); 2928 else 2929 path[0] = '\0'; 2930 2931 if (module_spec.GetUUIDPtr()) 2932 uuid_str = module_spec.GetUUID().GetAsString(); 2933 if (num_matches > 1) 2934 { 2935 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n", 2936 path[0] ? " file=" : "", 2937 path, 2938 !uuid_str.empty() ? " uuid=" : "", 2939 uuid_str.c_str()); 2940 for (size_t i=0; i<num_matches; ++i) 2941 { 2942 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path))) 2943 result.AppendMessageWithFormat("%s\n", path); 2944 } 2945 } 2946 else 2947 { 2948 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n", 2949 path[0] ? " file=" : "", 2950 path, 2951 !uuid_str.empty() ? " uuid=" : "", 2952 uuid_str.c_str()); 2953 } 2954 result.SetStatus (eReturnStatusFailed); 2955 } 2956 } 2957 else 2958 { 2959 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n"); 2960 result.SetStatus (eReturnStatusFailed); 2961 return false; 2962 } 2963 } 2964 return result.Succeeded(); 2965 } 2966 2967 OptionGroupOptions m_option_group; 2968 OptionGroupUUID m_uuid_option_group; 2969 OptionGroupFile m_file_option; 2970 OptionGroupUInt64 m_slide_option; 2971 }; 2972 2973 //---------------------------------------------------------------------- 2974 // List images with associated information 2975 //---------------------------------------------------------------------- 2976 class CommandObjectTargetModulesList : public CommandObjectParsed 2977 { 2978 public: 2979 2980 class CommandOptions : public Options 2981 { 2982 public: 2983 2984 CommandOptions (CommandInterpreter &interpreter) : 2985 Options(interpreter), 2986 m_format_array(), 2987 m_use_global_module_list (false), 2988 m_module_addr (LLDB_INVALID_ADDRESS) 2989 { 2990 } 2991 2992 virtual 2993 ~CommandOptions () 2994 { 2995 } 2996 2997 virtual Error 2998 SetOptionValue (uint32_t option_idx, const char *option_arg) 2999 { 3000 Error error; 3001 3002 const int short_option = m_getopt_table[option_idx].val; 3003 if (short_option == 'g') 3004 { 3005 m_use_global_module_list = true; 3006 } 3007 else if (short_option == 'a') 3008 { 3009 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 3010 m_module_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 3011 } 3012 else 3013 { 3014 unsigned long width = 0; 3015 if (option_arg) 3016 width = strtoul (option_arg, NULL, 0); 3017 m_format_array.push_back(std::make_pair(short_option, width)); 3018 } 3019 return error; 3020 } 3021 3022 void 3023 OptionParsingStarting () 3024 { 3025 m_format_array.clear(); 3026 m_use_global_module_list = false; 3027 m_module_addr = LLDB_INVALID_ADDRESS; 3028 } 3029 3030 const OptionDefinition* 3031 GetDefinitions () 3032 { 3033 return g_option_table; 3034 } 3035 3036 // Options table: Required for subclasses of Options. 3037 3038 static OptionDefinition g_option_table[]; 3039 3040 // Instance variables to hold the values for command options. 3041 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection; 3042 FormatWidthCollection m_format_array; 3043 bool m_use_global_module_list; 3044 lldb::addr_t m_module_addr; 3045 }; 3046 3047 CommandObjectTargetModulesList (CommandInterpreter &interpreter) : 3048 CommandObjectParsed (interpreter, 3049 "target modules list", 3050 "List current executable and dependent shared library images.", 3051 "target modules list [<cmd-options>]"), 3052 m_options (interpreter) 3053 { 3054 } 3055 3056 virtual 3057 ~CommandObjectTargetModulesList () 3058 { 3059 } 3060 3061 virtual 3062 Options * 3063 GetOptions () 3064 { 3065 return &m_options; 3066 } 3067 3068 protected: 3069 virtual bool 3070 DoExecute (Args& command, 3071 CommandReturnObject &result) 3072 { 3073 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3074 const bool use_global_module_list = m_options.m_use_global_module_list; 3075 // Define a local module list here to ensure it lives longer than any "locker" 3076 // object which might lock its contents below (through the "module_list_ptr" 3077 // variable). 3078 ModuleList module_list; 3079 if (target == NULL && use_global_module_list == false) 3080 { 3081 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 3082 result.SetStatus (eReturnStatusFailed); 3083 return false; 3084 } 3085 else 3086 { 3087 if (target) 3088 { 3089 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 3090 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 3091 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 3092 } 3093 // Dump all sections for all modules images 3094 Stream &strm = result.GetOutputStream(); 3095 3096 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) 3097 { 3098 if (target) 3099 { 3100 Address module_address; 3101 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) 3102 { 3103 ModuleSP module_sp (module_address.GetModule()); 3104 if (module_sp) 3105 { 3106 PrintModule (target, module_sp.get(), 0, strm); 3107 result.SetStatus (eReturnStatusSuccessFinishResult); 3108 } 3109 else 3110 { 3111 result.AppendErrorWithFormat ("Couldn't find module matching address: 0x%" PRIx64 ".", m_options.m_module_addr); 3112 result.SetStatus (eReturnStatusFailed); 3113 } 3114 } 3115 else 3116 { 3117 result.AppendErrorWithFormat ("Couldn't find module containing address: 0x%" PRIx64 ".", m_options.m_module_addr); 3118 result.SetStatus (eReturnStatusFailed); 3119 } 3120 } 3121 else 3122 { 3123 result.AppendError ("Can only look up modules by address with a valid target."); 3124 result.SetStatus (eReturnStatusFailed); 3125 } 3126 return result.Succeeded(); 3127 } 3128 3129 size_t num_modules = 0; 3130 Mutex::Locker locker; // This locker will be locked on the mutex in module_list_ptr if it is non-NULL. 3131 // Otherwise it will lock the AllocationModuleCollectionMutex when accessing 3132 // the global module list directly. 3133 const ModuleList *module_list_ptr = NULL; 3134 const size_t argc = command.GetArgumentCount(); 3135 if (argc == 0) 3136 { 3137 if (use_global_module_list) 3138 { 3139 locker.Lock (Module::GetAllocationModuleCollectionMutex()); 3140 num_modules = Module::GetNumberAllocatedModules(); 3141 } 3142 else 3143 { 3144 module_list_ptr = &target->GetImages(); 3145 } 3146 } 3147 else 3148 { 3149 for (size_t i=0; i<argc; ++i) 3150 { 3151 // Dump specified images (by basename or fullpath) 3152 const char *arg_cstr = command.GetArgumentAtIndex(i); 3153 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list); 3154 if (num_matches == 0) 3155 { 3156 if (argc == 1) 3157 { 3158 result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr); 3159 result.SetStatus (eReturnStatusFailed); 3160 return false; 3161 } 3162 } 3163 } 3164 3165 module_list_ptr = &module_list; 3166 } 3167 3168 if (module_list_ptr != NULL) 3169 { 3170 locker.Lock(module_list_ptr->GetMutex()); 3171 num_modules = module_list_ptr->GetSize(); 3172 } 3173 3174 if (num_modules > 0) 3175 { 3176 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 3177 { 3178 ModuleSP module_sp; 3179 Module *module; 3180 if (module_list_ptr) 3181 { 3182 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx); 3183 module = module_sp.get(); 3184 } 3185 else 3186 { 3187 module = Module::GetAllocatedModuleAtIndex(image_idx); 3188 module_sp = module->shared_from_this(); 3189 } 3190 3191 const size_t indent = strm.Printf("[%3u] ", image_idx); 3192 PrintModule (target, module, indent, strm); 3193 3194 } 3195 result.SetStatus (eReturnStatusSuccessFinishResult); 3196 } 3197 else 3198 { 3199 if (argc) 3200 { 3201 if (use_global_module_list) 3202 result.AppendError ("the global module list has no matching modules"); 3203 else 3204 result.AppendError ("the target has no matching modules"); 3205 } 3206 else 3207 { 3208 if (use_global_module_list) 3209 result.AppendError ("the global module list is empty"); 3210 else 3211 result.AppendError ("the target has no associated executable images"); 3212 } 3213 result.SetStatus (eReturnStatusFailed); 3214 return false; 3215 } 3216 } 3217 return result.Succeeded(); 3218 } 3219 3220 void 3221 PrintModule (Target *target, Module *module, int indent, Stream &strm) 3222 { 3223 3224 if (module == NULL) 3225 { 3226 strm.PutCString("Null module"); 3227 return; 3228 } 3229 3230 bool dump_object_name = false; 3231 if (m_options.m_format_array.empty()) 3232 { 3233 m_options.m_format_array.push_back(std::make_pair('u', 0)); 3234 m_options.m_format_array.push_back(std::make_pair('h', 0)); 3235 m_options.m_format_array.push_back(std::make_pair('f', 0)); 3236 m_options.m_format_array.push_back(std::make_pair('S', 0)); 3237 } 3238 const size_t num_entries = m_options.m_format_array.size(); 3239 bool print_space = false; 3240 for (size_t i=0; i<num_entries; ++i) 3241 { 3242 if (print_space) 3243 strm.PutChar(' '); 3244 print_space = true; 3245 const char format_char = m_options.m_format_array[i].first; 3246 uint32_t width = m_options.m_format_array[i].second; 3247 switch (format_char) 3248 { 3249 case 'A': 3250 DumpModuleArchitecture (strm, module, false, width); 3251 break; 3252 3253 case 't': 3254 DumpModuleArchitecture (strm, module, true, width); 3255 break; 3256 3257 case 'f': 3258 DumpFullpath (strm, &module->GetFileSpec(), width); 3259 dump_object_name = true; 3260 break; 3261 3262 case 'd': 3263 DumpDirectory (strm, &module->GetFileSpec(), width); 3264 break; 3265 3266 case 'b': 3267 DumpBasename (strm, &module->GetFileSpec(), width); 3268 dump_object_name = true; 3269 break; 3270 3271 case 'h': 3272 case 'o': 3273 // Image header address 3274 { 3275 uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16; 3276 3277 ObjectFile *objfile = module->GetObjectFile (); 3278 if (objfile) 3279 { 3280 Address header_addr(objfile->GetHeaderAddress()); 3281 if (header_addr.IsValid()) 3282 { 3283 if (target && !target->GetSectionLoadList().IsEmpty()) 3284 { 3285 lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target); 3286 if (header_load_addr == LLDB_INVALID_ADDRESS) 3287 { 3288 header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress); 3289 } 3290 else 3291 { 3292 if (format_char == 'o') 3293 { 3294 // Show the offset of slide for the image 3295 strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress()); 3296 } 3297 else 3298 { 3299 // Show the load address of the image 3300 strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr); 3301 } 3302 } 3303 break; 3304 } 3305 // The address was valid, but the image isn't loaded, output the address in an appropriate format 3306 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress); 3307 break; 3308 } 3309 } 3310 strm.Printf ("%*s", addr_nibble_width + 2, ""); 3311 } 3312 break; 3313 case 'r': 3314 { 3315 size_t ref_count = 0; 3316 ModuleSP module_sp (module->shared_from_this()); 3317 if (module_sp) 3318 { 3319 // Take one away to make sure we don't count our local "module_sp" 3320 ref_count = module_sp.use_count() - 1; 3321 } 3322 if (width) 3323 strm.Printf("{%*zu}", width, ref_count); 3324 else 3325 strm.Printf("{%zu}", ref_count); 3326 } 3327 break; 3328 3329 case 's': 3330 case 'S': 3331 { 3332 SymbolVendor *symbol_vendor = module->GetSymbolVendor(); 3333 if (symbol_vendor) 3334 { 3335 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 3336 if (symbol_file) 3337 { 3338 if (format_char == 'S') 3339 { 3340 FileSpec &symfile_spec = symbol_file->GetObjectFile()->GetFileSpec(); 3341 // Dump symbol file only if different from module file 3342 if (!symfile_spec || symfile_spec == module->GetFileSpec()) 3343 { 3344 print_space = false; 3345 break; 3346 } 3347 // Add a newline and indent past the index 3348 strm.Printf ("\n%*s", indent, ""); 3349 } 3350 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width); 3351 dump_object_name = true; 3352 break; 3353 } 3354 } 3355 strm.Printf("%.*s", width, "<NONE>"); 3356 } 3357 break; 3358 3359 case 'm': 3360 module->GetModificationTime().Dump(&strm, width); 3361 break; 3362 3363 case 'p': 3364 strm.Printf("%p", module); 3365 break; 3366 3367 case 'u': 3368 DumpModuleUUID(strm, module); 3369 break; 3370 3371 default: 3372 break; 3373 } 3374 3375 } 3376 if (dump_object_name) 3377 { 3378 const char *object_name = module->GetObjectName().GetCString(); 3379 if (object_name) 3380 strm.Printf ("(%s)", object_name); 3381 } 3382 strm.EOL(); 3383 } 3384 3385 CommandOptions m_options; 3386 }; 3387 3388 OptionDefinition 3389 CommandObjectTargetModulesList::CommandOptions::g_option_table[] = 3390 { 3391 { LLDB_OPT_SET_1, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddressOrExpression, "Display the image at this address."}, 3392 { LLDB_OPT_SET_1, false, "arch", 'A', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, 3393 { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, 3394 { LLDB_OPT_SET_1, false, "header", 'h', no_argument, NULL, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise."}, 3395 { LLDB_OPT_SET_1, false, "offset", 'o', no_argument, NULL, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)."}, 3396 { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, 3397 { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, 3398 { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, 3399 { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, 3400 { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, 3401 { LLDB_OPT_SET_1, false, "symfile-unique", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file."}, 3402 { LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."}, 3403 { 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."}, 3404 { LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."}, 3405 { 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."}, 3406 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3407 }; 3408 3409 #pragma mark CommandObjectTargetModulesShowUnwind 3410 3411 //---------------------------------------------------------------------- 3412 // Lookup unwind information in images 3413 //---------------------------------------------------------------------- 3414 3415 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed 3416 { 3417 public: 3418 3419 enum 3420 { 3421 eLookupTypeInvalid = -1, 3422 eLookupTypeAddress = 0, 3423 eLookupTypeSymbol, 3424 eLookupTypeFunction, 3425 eLookupTypeFunctionOrSymbol, 3426 kNumLookupTypes 3427 }; 3428 3429 class CommandOptions : public Options 3430 { 3431 public: 3432 3433 CommandOptions (CommandInterpreter &interpreter) : 3434 Options(interpreter), 3435 m_type(eLookupTypeInvalid), 3436 m_str(), 3437 m_addr(LLDB_INVALID_ADDRESS) 3438 { 3439 } 3440 3441 virtual 3442 ~CommandOptions () 3443 { 3444 } 3445 3446 virtual Error 3447 SetOptionValue (uint32_t option_idx, const char *option_arg) 3448 { 3449 Error error; 3450 3451 const int short_option = m_getopt_table[option_idx].val; 3452 3453 switch (short_option) 3454 { 3455 case 'a': 3456 { 3457 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 3458 m_type = eLookupTypeAddress; 3459 m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 3460 if (m_addr == LLDB_INVALID_ADDRESS) 3461 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg); 3462 break; 3463 } 3464 3465 case 'n': 3466 { 3467 m_str = option_arg; 3468 m_type = eLookupTypeFunctionOrSymbol; 3469 break; 3470 } 3471 } 3472 3473 return error; 3474 } 3475 3476 void 3477 OptionParsingStarting () 3478 { 3479 m_type = eLookupTypeInvalid; 3480 m_str.clear(); 3481 m_addr = LLDB_INVALID_ADDRESS; 3482 } 3483 3484 const OptionDefinition* 3485 GetDefinitions () 3486 { 3487 return g_option_table; 3488 } 3489 3490 // Options table: Required for subclasses of Options. 3491 3492 static OptionDefinition g_option_table[]; 3493 3494 // Instance variables to hold the values for command options. 3495 3496 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3497 std::string m_str; // Holds name lookup 3498 lldb::addr_t m_addr; // Holds the address to lookup 3499 }; 3500 3501 CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) : 3502 CommandObjectParsed (interpreter, 3503 "target modules show-unwind", 3504 "Show synthesized unwind instructions for a function.", 3505 NULL, 3506 eFlagRequiresTarget | 3507 eFlagRequiresProcess | 3508 eFlagProcessMustBeLaunched | 3509 eFlagProcessMustBePaused ), 3510 m_options (interpreter) 3511 { 3512 } 3513 3514 virtual 3515 ~CommandObjectTargetModulesShowUnwind () 3516 { 3517 } 3518 3519 virtual 3520 Options * 3521 GetOptions () 3522 { 3523 return &m_options; 3524 } 3525 3526 protected: 3527 bool 3528 DoExecute (Args& command, 3529 CommandReturnObject &result) 3530 { 3531 Target *target = m_exe_ctx.GetTargetPtr(); 3532 Process *process = m_exe_ctx.GetProcessPtr(); 3533 ABI *abi = NULL; 3534 if (process) 3535 abi = process->GetABI().get(); 3536 3537 if (process == NULL) 3538 { 3539 result.AppendError ("You must have a process running to use this command."); 3540 result.SetStatus (eReturnStatusFailed); 3541 return false; 3542 } 3543 3544 ThreadList threads(process->GetThreadList()); 3545 if (threads.GetSize() == 0) 3546 { 3547 result.AppendError ("The process must be paused to use this command."); 3548 result.SetStatus (eReturnStatusFailed); 3549 return false; 3550 } 3551 3552 ThreadSP thread(threads.GetThreadAtIndex(0)); 3553 if (thread.get() == NULL) 3554 { 3555 result.AppendError ("The process must be paused to use this command."); 3556 result.SetStatus (eReturnStatusFailed); 3557 return false; 3558 } 3559 3560 SymbolContextList sc_list; 3561 3562 if (m_options.m_type == eLookupTypeFunctionOrSymbol) 3563 { 3564 ConstString function_name (m_options.m_str.c_str()); 3565 target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list); 3566 } 3567 else if (m_options.m_type == eLookupTypeAddress && target) 3568 { 3569 Address addr; 3570 if (target->GetSectionLoadList().ResolveLoadAddress (m_options.m_addr, addr)) 3571 { 3572 SymbolContext sc; 3573 ModuleSP module_sp (addr.GetModule()); 3574 module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextEverything, sc); 3575 if (sc.function || sc.symbol) 3576 { 3577 sc_list.Append(sc); 3578 } 3579 } 3580 } 3581 3582 size_t num_matches = sc_list.GetSize(); 3583 for (uint32_t idx = 0; idx < num_matches; idx++) 3584 { 3585 SymbolContext sc; 3586 sc_list.GetContextAtIndex(idx, sc); 3587 if (sc.symbol == NULL && sc.function == NULL) 3588 continue; 3589 if (sc.module_sp.get() == NULL || sc.module_sp->GetObjectFile() == NULL) 3590 continue; 3591 AddressRange range; 3592 if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range)) 3593 continue; 3594 if (!range.GetBaseAddress().IsValid()) 3595 continue; 3596 ConstString funcname(sc.GetFunctionName()); 3597 if (funcname.IsEmpty()) 3598 continue; 3599 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target); 3600 if (abi) 3601 start_addr = abi->FixCodeAddress(start_addr); 3602 3603 FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc)); 3604 if (func_unwinders_sp.get() == NULL) 3605 continue; 3606 3607 Address first_non_prologue_insn (func_unwinders_sp->GetFirstNonPrologueInsn(*target)); 3608 if (first_non_prologue_insn.IsValid()) 3609 { 3610 result.GetOutputStream().Printf("First non-prologue instruction is at address 0x%" PRIx64 " or offset %" PRId64 " into the function.\n", first_non_prologue_insn.GetLoadAddress(target), first_non_prologue_insn.GetLoadAddress(target) - start_addr); 3611 result.GetOutputStream().Printf ("\n"); 3612 } 3613 3614 UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*thread.get()); 3615 if (non_callsite_unwind_plan.get()) 3616 { 3617 result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3618 non_callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3619 result.GetOutputStream().Printf ("\n"); 3620 } 3621 3622 UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(-1); 3623 if (callsite_unwind_plan.get()) 3624 { 3625 result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3626 callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3627 result.GetOutputStream().Printf ("\n"); 3628 } 3629 3630 UnwindPlanSP arch_default_unwind_plan = func_unwinders_sp->GetUnwindPlanArchitectureDefault(*thread.get()); 3631 if (arch_default_unwind_plan.get()) 3632 { 3633 result.GetOutputStream().Printf("Architecture default UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3634 arch_default_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3635 result.GetOutputStream().Printf ("\n"); 3636 } 3637 3638 UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get()); 3639 if (fast_unwind_plan.get()) 3640 { 3641 result.GetOutputStream().Printf("Fast UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3642 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3643 result.GetOutputStream().Printf ("\n"); 3644 } 3645 3646 3647 result.GetOutputStream().Printf ("\n"); 3648 } 3649 return result.Succeeded(); 3650 } 3651 3652 CommandOptions m_options; 3653 }; 3654 3655 OptionDefinition 3656 CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] = 3657 { 3658 { LLDB_OPT_SET_1, false, "name", 'n', required_argument, NULL, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."}, 3659 { LLDB_OPT_SET_2, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"}, 3660 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 3661 }; 3662 3663 //---------------------------------------------------------------------- 3664 // Lookup information in images 3665 //---------------------------------------------------------------------- 3666 class CommandObjectTargetModulesLookup : public CommandObjectParsed 3667 { 3668 public: 3669 3670 enum 3671 { 3672 eLookupTypeInvalid = -1, 3673 eLookupTypeAddress = 0, 3674 eLookupTypeSymbol, 3675 eLookupTypeFileLine, // Line is optional 3676 eLookupTypeFunction, 3677 eLookupTypeFunctionOrSymbol, 3678 eLookupTypeType, 3679 kNumLookupTypes 3680 }; 3681 3682 class CommandOptions : public Options 3683 { 3684 public: 3685 3686 CommandOptions (CommandInterpreter &interpreter) : 3687 Options(interpreter) 3688 { 3689 OptionParsingStarting(); 3690 } 3691 3692 virtual 3693 ~CommandOptions () 3694 { 3695 } 3696 3697 virtual Error 3698 SetOptionValue (uint32_t option_idx, const char *option_arg) 3699 { 3700 Error error; 3701 3702 const int short_option = m_getopt_table[option_idx].val; 3703 3704 switch (short_option) 3705 { 3706 case 'a': 3707 { 3708 m_type = eLookupTypeAddress; 3709 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 3710 m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 3711 } 3712 break; 3713 3714 case 'o': 3715 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 3716 if (m_offset == LLDB_INVALID_ADDRESS) 3717 error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg); 3718 break; 3719 3720 case 's': 3721 m_str = option_arg; 3722 m_type = eLookupTypeSymbol; 3723 break; 3724 3725 case 'f': 3726 m_file.SetFile (option_arg, false); 3727 m_type = eLookupTypeFileLine; 3728 break; 3729 3730 case 'i': 3731 m_include_inlines = false; 3732 break; 3733 3734 case 'l': 3735 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX); 3736 if (m_line_number == UINT32_MAX) 3737 error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg); 3738 else if (m_line_number == 0) 3739 error.SetErrorString ("zero is an invalid line number"); 3740 m_type = eLookupTypeFileLine; 3741 break; 3742 3743 case 'F': 3744 m_str = option_arg; 3745 m_type = eLookupTypeFunction; 3746 break; 3747 3748 case 'n': 3749 m_str = option_arg; 3750 m_type = eLookupTypeFunctionOrSymbol; 3751 break; 3752 3753 case 't': 3754 m_str = option_arg; 3755 m_type = eLookupTypeType; 3756 break; 3757 3758 case 'v': 3759 m_verbose = 1; 3760 break; 3761 3762 case 'A': 3763 m_print_all = true; 3764 break; 3765 3766 case 'r': 3767 m_use_regex = true; 3768 break; 3769 } 3770 3771 return error; 3772 } 3773 3774 void 3775 OptionParsingStarting () 3776 { 3777 m_type = eLookupTypeInvalid; 3778 m_str.clear(); 3779 m_file.Clear(); 3780 m_addr = LLDB_INVALID_ADDRESS; 3781 m_offset = 0; 3782 m_line_number = 0; 3783 m_use_regex = false; 3784 m_include_inlines = true; 3785 m_verbose = false; 3786 m_print_all = false; 3787 } 3788 3789 const OptionDefinition* 3790 GetDefinitions () 3791 { 3792 return g_option_table; 3793 } 3794 3795 // Options table: Required for subclasses of Options. 3796 3797 static OptionDefinition g_option_table[]; 3798 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3799 std::string m_str; // Holds name lookup 3800 FileSpec m_file; // Files for file lookups 3801 lldb::addr_t m_addr; // Holds the address to lookup 3802 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups. 3803 uint32_t m_line_number; // Line number for file+line lookups 3804 bool m_use_regex; // Name lookups in m_str are regular expressions. 3805 bool m_include_inlines;// Check for inline entries when looking up by file/line. 3806 bool m_verbose; // Enable verbose lookup info 3807 bool m_print_all; // Print all matches, even in cases where there's a best match. 3808 3809 }; 3810 3811 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) : 3812 CommandObjectParsed (interpreter, 3813 "target modules lookup", 3814 "Look up information within executable and dependent shared library images.", 3815 NULL, 3816 eFlagRequiresTarget), 3817 m_options (interpreter) 3818 { 3819 CommandArgumentEntry arg; 3820 CommandArgumentData file_arg; 3821 3822 // Define the first (and only) variant of this arg. 3823 file_arg.arg_type = eArgTypeFilename; 3824 file_arg.arg_repetition = eArgRepeatStar; 3825 3826 // There is only one variant this argument could be; put it into the argument entry. 3827 arg.push_back (file_arg); 3828 3829 // Push the data for the first argument into the m_arguments vector. 3830 m_arguments.push_back (arg); 3831 } 3832 3833 virtual 3834 ~CommandObjectTargetModulesLookup () 3835 { 3836 } 3837 3838 virtual Options * 3839 GetOptions () 3840 { 3841 return &m_options; 3842 } 3843 3844 bool 3845 LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error) 3846 { 3847 switch (m_options.m_type) 3848 { 3849 case eLookupTypeAddress: 3850 case eLookupTypeFileLine: 3851 case eLookupTypeFunction: 3852 case eLookupTypeFunctionOrSymbol: 3853 case eLookupTypeSymbol: 3854 default: 3855 return false; 3856 case eLookupTypeType: 3857 break; 3858 } 3859 3860 StackFrameSP frame = m_exe_ctx.GetFrameSP(); 3861 3862 if (!frame) 3863 return false; 3864 3865 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule)); 3866 3867 if (!sym_ctx.module_sp) 3868 return false; 3869 3870 switch (m_options.m_type) 3871 { 3872 default: 3873 return false; 3874 case eLookupTypeType: 3875 if (!m_options.m_str.empty()) 3876 { 3877 if (LookupTypeHere (m_interpreter, 3878 result.GetOutputStream(), 3879 sym_ctx, 3880 m_options.m_str.c_str(), 3881 m_options.m_use_regex)) 3882 { 3883 result.SetStatus(eReturnStatusSuccessFinishResult); 3884 return true; 3885 } 3886 } 3887 break; 3888 } 3889 3890 return true; 3891 } 3892 3893 bool 3894 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error) 3895 { 3896 switch (m_options.m_type) 3897 { 3898 case eLookupTypeAddress: 3899 if (m_options.m_addr != LLDB_INVALID_ADDRESS) 3900 { 3901 if (LookupAddressInModule (m_interpreter, 3902 result.GetOutputStream(), 3903 module, 3904 eSymbolContextEverything, 3905 m_options.m_addr, 3906 m_options.m_offset, 3907 m_options.m_verbose)) 3908 { 3909 result.SetStatus(eReturnStatusSuccessFinishResult); 3910 return true; 3911 } 3912 } 3913 break; 3914 3915 case eLookupTypeSymbol: 3916 if (!m_options.m_str.empty()) 3917 { 3918 if (LookupSymbolInModule (m_interpreter, 3919 result.GetOutputStream(), 3920 module, 3921 m_options.m_str.c_str(), 3922 m_options.m_use_regex, 3923 m_options.m_verbose)) 3924 { 3925 result.SetStatus(eReturnStatusSuccessFinishResult); 3926 return true; 3927 } 3928 } 3929 break; 3930 3931 case eLookupTypeFileLine: 3932 if (m_options.m_file) 3933 { 3934 3935 if (LookupFileAndLineInModule (m_interpreter, 3936 result.GetOutputStream(), 3937 module, 3938 m_options.m_file, 3939 m_options.m_line_number, 3940 m_options.m_include_inlines, 3941 m_options.m_verbose)) 3942 { 3943 result.SetStatus(eReturnStatusSuccessFinishResult); 3944 return true; 3945 } 3946 } 3947 break; 3948 3949 case eLookupTypeFunctionOrSymbol: 3950 case eLookupTypeFunction: 3951 if (!m_options.m_str.empty()) 3952 { 3953 if (LookupFunctionInModule (m_interpreter, 3954 result.GetOutputStream(), 3955 module, 3956 m_options.m_str.c_str(), 3957 m_options.m_use_regex, 3958 m_options.m_include_inlines, 3959 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols 3960 m_options.m_verbose)) 3961 { 3962 result.SetStatus(eReturnStatusSuccessFinishResult); 3963 return true; 3964 } 3965 } 3966 break; 3967 3968 3969 case eLookupTypeType: 3970 if (!m_options.m_str.empty()) 3971 { 3972 if (LookupTypeInModule (m_interpreter, 3973 result.GetOutputStream(), 3974 module, 3975 m_options.m_str.c_str(), 3976 m_options.m_use_regex)) 3977 { 3978 result.SetStatus(eReturnStatusSuccessFinishResult); 3979 return true; 3980 } 3981 } 3982 break; 3983 3984 default: 3985 m_options.GenerateOptionUsage (result.GetErrorStream(), this); 3986 syntax_error = true; 3987 break; 3988 } 3989 3990 result.SetStatus (eReturnStatusFailed); 3991 return false; 3992 } 3993 3994 protected: 3995 virtual bool 3996 DoExecute (Args& command, 3997 CommandReturnObject &result) 3998 { 3999 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4000 if (target == NULL) 4001 { 4002 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 4003 result.SetStatus (eReturnStatusFailed); 4004 return false; 4005 } 4006 else 4007 { 4008 bool syntax_error = false; 4009 uint32_t i; 4010 uint32_t num_successful_lookups = 0; 4011 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 4012 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 4013 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 4014 // Dump all sections for all modules images 4015 4016 if (command.GetArgumentCount() == 0) 4017 { 4018 ModuleSP current_module; 4019 4020 // Where it is possible to look in the current symbol context 4021 // first, try that. If this search was successful and --all 4022 // was not passed, don't print anything else. 4023 if (LookupHere (m_interpreter, result, syntax_error)) 4024 { 4025 result.GetOutputStream().EOL(); 4026 num_successful_lookups++; 4027 if (!m_options.m_print_all) 4028 { 4029 result.SetStatus (eReturnStatusSuccessFinishResult); 4030 return result.Succeeded(); 4031 } 4032 } 4033 4034 // Dump all sections for all other modules 4035 4036 const ModuleList &target_modules = target->GetImages(); 4037 Mutex::Locker modules_locker(target_modules.GetMutex()); 4038 const size_t num_modules = target_modules.GetSize(); 4039 if (num_modules > 0) 4040 { 4041 for (i = 0; i<num_modules && syntax_error == false; ++i) 4042 { 4043 Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i); 4044 4045 if (module_pointer != current_module.get() && 4046 LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error)) 4047 { 4048 result.GetOutputStream().EOL(); 4049 num_successful_lookups++; 4050 } 4051 } 4052 } 4053 else 4054 { 4055 result.AppendError ("the target has no associated executable images"); 4056 result.SetStatus (eReturnStatusFailed); 4057 return false; 4058 } 4059 } 4060 else 4061 { 4062 // Dump specified images (by basename or fullpath) 4063 const char *arg_cstr; 4064 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i) 4065 { 4066 ModuleList module_list; 4067 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false); 4068 if (num_matches > 0) 4069 { 4070 for (size_t j=0; j<num_matches; ++j) 4071 { 4072 Module *module = module_list.GetModulePointerAtIndex(j); 4073 if (module) 4074 { 4075 if (LookupInModule (m_interpreter, module, result, syntax_error)) 4076 { 4077 result.GetOutputStream().EOL(); 4078 num_successful_lookups++; 4079 } 4080 } 4081 } 4082 } 4083 else 4084 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 4085 } 4086 } 4087 4088 if (num_successful_lookups > 0) 4089 result.SetStatus (eReturnStatusSuccessFinishResult); 4090 else 4091 result.SetStatus (eReturnStatusFailed); 4092 } 4093 return result.Succeeded(); 4094 } 4095 4096 CommandOptions m_options; 4097 }; 4098 4099 OptionDefinition 4100 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] = 4101 { 4102 { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."}, 4103 { 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."}, 4104 { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5 4105 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ , 4106 false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."}, 4107 { 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."}, 4108 { 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."}, 4109 { 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)."}, 4110 { LLDB_OPT_SET_FROM_TO(3,5), 4111 false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."}, 4112 { LLDB_OPT_SET_4, true, "function", 'F', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules."}, 4113 { LLDB_OPT_SET_5, true, "name", 'n', required_argument, NULL, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules."}, 4114 { LLDB_OPT_SET_6, true, "type", 't', required_argument, NULL, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules."}, 4115 { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, 4116 { LLDB_OPT_SET_ALL, false, "all", 'A', no_argument, NULL, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available."}, 4117 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 4118 }; 4119 4120 4121 #pragma mark CommandObjectMultiwordImageSearchPaths 4122 4123 //------------------------------------------------------------------------- 4124 // CommandObjectMultiwordImageSearchPaths 4125 //------------------------------------------------------------------------- 4126 4127 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword 4128 { 4129 public: 4130 4131 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) : 4132 CommandObjectMultiword (interpreter, 4133 "target modules search-paths", 4134 "A set of commands for operating on debugger target image search paths.", 4135 "target modules search-paths <subcommand> [<subcommand-options>]") 4136 { 4137 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter))); 4138 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter))); 4139 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter))); 4140 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter))); 4141 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter))); 4142 } 4143 4144 ~CommandObjectTargetModulesImageSearchPaths() 4145 { 4146 } 4147 }; 4148 4149 4150 4151 #pragma mark CommandObjectTargetModules 4152 4153 //------------------------------------------------------------------------- 4154 // CommandObjectTargetModules 4155 //------------------------------------------------------------------------- 4156 4157 class CommandObjectTargetModules : public CommandObjectMultiword 4158 { 4159 public: 4160 //------------------------------------------------------------------ 4161 // Constructors and Destructors 4162 //------------------------------------------------------------------ 4163 CommandObjectTargetModules(CommandInterpreter &interpreter) : 4164 CommandObjectMultiword (interpreter, 4165 "target modules", 4166 "A set of commands for accessing information for one or more target modules.", 4167 "target modules <sub-command> ...") 4168 { 4169 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter))); 4170 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter))); 4171 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter))); 4172 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter))); 4173 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter))); 4174 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter))); 4175 LoadSubCommand ("show-unwind", CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter))); 4176 4177 } 4178 virtual 4179 ~CommandObjectTargetModules() 4180 { 4181 } 4182 4183 private: 4184 //------------------------------------------------------------------ 4185 // For CommandObjectTargetModules only 4186 //------------------------------------------------------------------ 4187 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules); 4188 }; 4189 4190 4191 4192 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed 4193 { 4194 public: 4195 CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) : 4196 CommandObjectParsed (interpreter, 4197 "target symbols add", 4198 "Add a debug symbol file to one of the target's current modules by specifying a path to a debug symbols file, or using the options to specify a module to download symbols for.", 4199 "target symbols add [<symfile>]", eFlagRequiresTarget), 4200 m_option_group (interpreter), 4201 m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."), 4202 m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true) 4203 4204 { 4205 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 4206 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 4207 m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2); 4208 m_option_group.Finalize(); 4209 } 4210 4211 virtual 4212 ~CommandObjectTargetSymbolsAdd () 4213 { 4214 } 4215 4216 virtual int 4217 HandleArgumentCompletion (Args &input, 4218 int &cursor_index, 4219 int &cursor_char_position, 4220 OptionElementVector &opt_element_vector, 4221 int match_start_point, 4222 int max_return_elements, 4223 bool &word_complete, 4224 StringList &matches) 4225 { 4226 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 4227 completion_str.erase (cursor_char_position); 4228 4229 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 4230 CommandCompletions::eDiskFileCompletion, 4231 completion_str.c_str(), 4232 match_start_point, 4233 max_return_elements, 4234 NULL, 4235 word_complete, 4236 matches); 4237 return matches.GetSize(); 4238 } 4239 4240 virtual Options * 4241 GetOptions () 4242 { 4243 return &m_option_group; 4244 } 4245 4246 4247 protected: 4248 4249 bool 4250 AddModuleSymbols (Target *target, 4251 ModuleSpec &module_spec, 4252 bool &flush, 4253 CommandReturnObject &result) 4254 { 4255 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec(); 4256 if (symbol_fspec) 4257 { 4258 char symfile_path[PATH_MAX]; 4259 symbol_fspec.GetPath (symfile_path, sizeof(symfile_path)); 4260 4261 if (!module_spec.GetUUID().IsValid()) 4262 { 4263 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec()) 4264 module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename(); 4265 } 4266 // We now have a module that represents a symbol file 4267 // that can be used for a module that might exist in the 4268 // current target, so we need to find that module in the 4269 // target 4270 ModuleList matching_module_list; 4271 4272 size_t num_matches = 0; 4273 // First extract all module specs from the symbol file 4274 lldb_private::ModuleSpecList symfile_module_specs; 4275 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), 0, symfile_module_specs)) 4276 { 4277 // Now extract the module spec that matches the target architecture 4278 ModuleSpec target_arch_module_spec; 4279 ModuleSpec symfile_module_spec; 4280 target_arch_module_spec.GetArchitecture() = target->GetArchitecture(); 4281 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, symfile_module_spec)) 4282 { 4283 // See if it has a UUID? 4284 if (symfile_module_spec.GetUUID().IsValid()) 4285 { 4286 // It has a UUID, look for this UUID in the target modules 4287 ModuleSpec symfile_uuid_module_spec; 4288 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); 4289 num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list); 4290 } 4291 } 4292 4293 if (num_matches == 0) 4294 { 4295 // No matches yet, iterate through the module specs to find a UUID value that 4296 // we can match up to an image in our target 4297 const size_t num_symfile_module_specs = symfile_module_specs.GetSize(); 4298 for (size_t i=0; i<num_symfile_module_specs && num_matches == 0; ++i) 4299 { 4300 if (symfile_module_specs.GetModuleSpecAtIndex(i, symfile_module_spec)) 4301 { 4302 if (symfile_module_spec.GetUUID().IsValid()) 4303 { 4304 // It has a UUID, look for this UUID in the target modules 4305 ModuleSpec symfile_uuid_module_spec; 4306 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); 4307 num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list); 4308 } 4309 } 4310 } 4311 } 4312 } 4313 4314 // Just try to match up the file by basename if we have no matches at this point 4315 if (num_matches == 0) 4316 num_matches = target->GetImages().FindModules (module_spec, matching_module_list); 4317 4318 while (num_matches == 0) 4319 { 4320 ConstString filename_no_extension(module_spec.GetFileSpec().GetFileNameStrippingExtension()); 4321 // Empty string returned, lets bail 4322 if (!filename_no_extension) 4323 break; 4324 4325 // Check if there was no extension to strip and the basename is the same 4326 if (filename_no_extension == module_spec.GetFileSpec().GetFilename()) 4327 break; 4328 4329 // Replace basename with one less extension 4330 module_spec.GetFileSpec().GetFilename() = filename_no_extension; 4331 4332 num_matches = target->GetImages().FindModules (module_spec, matching_module_list); 4333 4334 } 4335 4336 if (num_matches > 1) 4337 { 4338 result.AppendErrorWithFormat ("multiple modules match symbol file '%s', use the --uuid option to resolve the ambiguity.\n", symfile_path); 4339 } 4340 else if (num_matches == 1) 4341 { 4342 ModuleSP module_sp (matching_module_list.GetModuleAtIndex(0)); 4343 4344 // The module has not yet created its symbol vendor, we can just 4345 // give the existing target module the symfile path to use for 4346 // when it decides to create it! 4347 module_sp->SetSymbolFileFileSpec (symbol_fspec); 4348 4349 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(true, &result.GetErrorStream()); 4350 if (symbol_vendor) 4351 { 4352 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 4353 4354 if (symbol_file) 4355 { 4356 ObjectFile *object_file = symbol_file->GetObjectFile(); 4357 4358 if (object_file && object_file->GetFileSpec() == symbol_fspec) 4359 { 4360 // Provide feedback that the symfile has been successfully added. 4361 const FileSpec &module_fs = module_sp->GetFileSpec(); 4362 result.AppendMessageWithFormat("symbol file '%s' has been added to '%s'\n", 4363 symfile_path, 4364 module_fs.GetPath().c_str()); 4365 4366 // Let clients know something changed in the module 4367 // if it is currently loaded 4368 ModuleList module_list; 4369 module_list.Append (module_sp); 4370 target->SymbolsDidLoad (module_list); 4371 4372 // Make sure we load any scripting resources that may be embedded 4373 // in the debug info files in case the platform supports that. 4374 Error error; 4375 StreamString feedback_stream; 4376 module_sp->LoadScriptingResourceInTarget (target, error,&feedback_stream); 4377 if (error.Fail() && error.AsCString()) 4378 result.AppendWarningWithFormat("unable to load scripting data for module %s - error reported was %s", 4379 module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(), 4380 error.AsCString()); 4381 else if (feedback_stream.GetSize()) 4382 result.AppendWarningWithFormat("%s",feedback_stream.GetData()); 4383 4384 flush = true; 4385 result.SetStatus (eReturnStatusSuccessFinishResult); 4386 return true; 4387 } 4388 } 4389 } 4390 // Clear the symbol file spec if anything went wrong 4391 module_sp->SetSymbolFileFileSpec (FileSpec()); 4392 } 4393 4394 if (module_spec.GetUUID().IsValid()) 4395 { 4396 StreamString ss_symfile_uuid; 4397 module_spec.GetUUID().Dump(&ss_symfile_uuid); 4398 result.AppendErrorWithFormat ("symbol file '%s' (%s) does not match any existing module%s\n", 4399 symfile_path, 4400 ss_symfile_uuid.GetData(), 4401 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular) 4402 ? "\n please specify the full path to the symbol file" 4403 : ""); 4404 } 4405 else 4406 { 4407 result.AppendErrorWithFormat ("symbol file '%s' does not match any existing module%s\n", 4408 symfile_path, 4409 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular) 4410 ? "\n please specify the full path to the symbol file" 4411 : ""); 4412 } 4413 } 4414 else 4415 { 4416 result.AppendError ("one or more executable image paths must be specified"); 4417 } 4418 result.SetStatus (eReturnStatusFailed); 4419 return false; 4420 } 4421 4422 virtual bool 4423 DoExecute (Args& args, 4424 CommandReturnObject &result) 4425 { 4426 Target *target = m_exe_ctx.GetTargetPtr(); 4427 result.SetStatus (eReturnStatusFailed); 4428 bool flush = false; 4429 ModuleSpec module_spec; 4430 const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet(); 4431 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet(); 4432 const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet(); 4433 4434 const size_t argc = args.GetArgumentCount(); 4435 if (argc == 0) 4436 { 4437 if (uuid_option_set || file_option_set || frame_option_set) 4438 { 4439 bool success = false; 4440 bool error_set = false; 4441 if (frame_option_set) 4442 { 4443 Process *process = m_exe_ctx.GetProcessPtr(); 4444 if (process) 4445 { 4446 const StateType process_state = process->GetState(); 4447 if (StateIsStoppedState (process_state, true)) 4448 { 4449 StackFrame *frame = m_exe_ctx.GetFramePtr(); 4450 if (frame) 4451 { 4452 ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp); 4453 if (frame_module_sp) 4454 { 4455 if (frame_module_sp->GetPlatformFileSpec().Exists()) 4456 { 4457 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); 4458 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec(); 4459 } 4460 module_spec.GetUUID() = frame_module_sp->GetUUID(); 4461 success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec(); 4462 } 4463 else 4464 { 4465 result.AppendError ("frame has no module"); 4466 error_set = true; 4467 } 4468 } 4469 else 4470 { 4471 result.AppendError ("invalid current frame"); 4472 error_set = true; 4473 } 4474 } 4475 else 4476 { 4477 result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state)); 4478 error_set = true; 4479 } 4480 } 4481 else 4482 { 4483 result.AppendError ("a process must exist in order to use the --frame option"); 4484 error_set = true; 4485 } 4486 } 4487 else 4488 { 4489 if (uuid_option_set) 4490 { 4491 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); 4492 success |= module_spec.GetUUID().IsValid(); 4493 } 4494 else if (file_option_set) 4495 { 4496 module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); 4497 ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec)); 4498 if (module_sp) 4499 { 4500 module_spec.GetFileSpec() = module_sp->GetFileSpec(); 4501 module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec(); 4502 module_spec.GetUUID() = module_sp->GetUUID(); 4503 module_spec.GetArchitecture() = module_sp->GetArchitecture(); 4504 } 4505 else 4506 { 4507 module_spec.GetArchitecture() = target->GetArchitecture(); 4508 } 4509 success |= module_spec.GetFileSpec().Exists(); 4510 } 4511 } 4512 4513 if (success) 4514 { 4515 if (Symbols::DownloadObjectAndSymbolFile (module_spec)) 4516 { 4517 if (module_spec.GetSymbolFileSpec()) 4518 success = AddModuleSymbols (target, module_spec, flush, result); 4519 } 4520 } 4521 4522 if (!success && !error_set) 4523 { 4524 StreamString error_strm; 4525 if (uuid_option_set) 4526 { 4527 error_strm.PutCString("unable to find debug symbols for UUID "); 4528 module_spec.GetUUID().Dump (&error_strm); 4529 } 4530 else if (file_option_set) 4531 { 4532 error_strm.PutCString("unable to find debug symbols for the executable file "); 4533 error_strm << module_spec.GetFileSpec(); 4534 } 4535 else if (frame_option_set) 4536 { 4537 error_strm.PutCString("unable to find debug symbols for the current frame"); 4538 } 4539 result.AppendError (error_strm.GetData()); 4540 } 4541 } 4542 else 4543 { 4544 result.AppendError ("one or more symbol file paths must be specified, or options must be specified"); 4545 } 4546 } 4547 else 4548 { 4549 if (uuid_option_set) 4550 { 4551 result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments"); 4552 } 4553 else if (file_option_set) 4554 { 4555 result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments"); 4556 } 4557 else if (frame_option_set) 4558 { 4559 result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments"); 4560 } 4561 else 4562 { 4563 PlatformSP platform_sp (target->GetPlatform()); 4564 4565 for (size_t i=0; i<argc; ++i) 4566 { 4567 const char *symfile_path = args.GetArgumentAtIndex(i); 4568 if (symfile_path) 4569 { 4570 module_spec.GetSymbolFileSpec().SetFile(symfile_path, true); 4571 if (platform_sp) 4572 { 4573 FileSpec symfile_spec; 4574 if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success()) 4575 module_spec.GetSymbolFileSpec() = symfile_spec; 4576 } 4577 4578 ArchSpec arch; 4579 bool symfile_exists = module_spec.GetSymbolFileSpec().Exists(); 4580 4581 if (symfile_exists) 4582 { 4583 if (!AddModuleSymbols (target, module_spec, flush, result)) 4584 break; 4585 } 4586 else 4587 { 4588 char resolved_symfile_path[PATH_MAX]; 4589 if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path))) 4590 { 4591 if (strcmp (resolved_symfile_path, symfile_path) != 0) 4592 { 4593 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path); 4594 break; 4595 } 4596 } 4597 result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path); 4598 break; 4599 } 4600 } 4601 } 4602 } 4603 } 4604 4605 if (flush) 4606 { 4607 Process *process = m_exe_ctx.GetProcessPtr(); 4608 if (process) 4609 process->Flush(); 4610 } 4611 return result.Succeeded(); 4612 } 4613 4614 OptionGroupOptions m_option_group; 4615 OptionGroupUUID m_uuid_option_group; 4616 OptionGroupFile m_file_option; 4617 OptionGroupBoolean m_current_frame_option; 4618 4619 4620 }; 4621 4622 4623 #pragma mark CommandObjectTargetSymbols 4624 4625 //------------------------------------------------------------------------- 4626 // CommandObjectTargetSymbols 4627 //------------------------------------------------------------------------- 4628 4629 class CommandObjectTargetSymbols : public CommandObjectMultiword 4630 { 4631 public: 4632 //------------------------------------------------------------------ 4633 // Constructors and Destructors 4634 //------------------------------------------------------------------ 4635 CommandObjectTargetSymbols(CommandInterpreter &interpreter) : 4636 CommandObjectMultiword (interpreter, 4637 "target symbols", 4638 "A set of commands for adding and managing debug symbol files.", 4639 "target symbols <sub-command> ...") 4640 { 4641 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter))); 4642 4643 } 4644 virtual 4645 ~CommandObjectTargetSymbols() 4646 { 4647 } 4648 4649 private: 4650 //------------------------------------------------------------------ 4651 // For CommandObjectTargetModules only 4652 //------------------------------------------------------------------ 4653 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols); 4654 }; 4655 4656 4657 #pragma mark CommandObjectTargetStopHookAdd 4658 4659 //------------------------------------------------------------------------- 4660 // CommandObjectTargetStopHookAdd 4661 //------------------------------------------------------------------------- 4662 4663 class CommandObjectTargetStopHookAdd : public CommandObjectParsed 4664 { 4665 public: 4666 4667 class CommandOptions : public Options 4668 { 4669 public: 4670 CommandOptions (CommandInterpreter &interpreter) : 4671 Options(interpreter), 4672 m_line_start(0), 4673 m_line_end (UINT_MAX), 4674 m_func_name_type_mask (eFunctionNameTypeAuto), 4675 m_sym_ctx_specified (false), 4676 m_thread_specified (false), 4677 m_use_one_liner (false), 4678 m_one_liner() 4679 { 4680 } 4681 4682 ~CommandOptions () {} 4683 4684 const OptionDefinition* 4685 GetDefinitions () 4686 { 4687 return g_option_table; 4688 } 4689 4690 virtual Error 4691 SetOptionValue (uint32_t option_idx, const char *option_arg) 4692 { 4693 Error error; 4694 const int short_option = m_getopt_table[option_idx].val; 4695 bool success; 4696 4697 switch (short_option) 4698 { 4699 case 'c': 4700 m_class_name = option_arg; 4701 m_sym_ctx_specified = true; 4702 break; 4703 4704 case 'e': 4705 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success); 4706 if (!success) 4707 { 4708 error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg); 4709 break; 4710 } 4711 m_sym_ctx_specified = true; 4712 break; 4713 4714 case 'l': 4715 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success); 4716 if (!success) 4717 { 4718 error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg); 4719 break; 4720 } 4721 m_sym_ctx_specified = true; 4722 break; 4723 4724 case 'i': 4725 m_no_inlines = true; 4726 break; 4727 4728 case 'n': 4729 m_function_name = option_arg; 4730 m_func_name_type_mask |= eFunctionNameTypeAuto; 4731 m_sym_ctx_specified = true; 4732 break; 4733 4734 case 'f': 4735 m_file_name = option_arg; 4736 m_sym_ctx_specified = true; 4737 break; 4738 case 's': 4739 m_module_name = option_arg; 4740 m_sym_ctx_specified = true; 4741 break; 4742 case 't' : 4743 { 4744 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 4745 if (m_thread_id == LLDB_INVALID_THREAD_ID) 4746 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 4747 m_thread_specified = true; 4748 } 4749 break; 4750 case 'T': 4751 m_thread_name = option_arg; 4752 m_thread_specified = true; 4753 break; 4754 case 'q': 4755 m_queue_name = option_arg; 4756 m_thread_specified = true; 4757 break; 4758 case 'x': 4759 { 4760 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 4761 if (m_thread_id == UINT32_MAX) 4762 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 4763 m_thread_specified = true; 4764 } 4765 break; 4766 case 'o': 4767 m_use_one_liner = true; 4768 m_one_liner = option_arg; 4769 break; 4770 default: 4771 error.SetErrorStringWithFormat ("unrecognized option %c.", short_option); 4772 break; 4773 } 4774 return error; 4775 } 4776 4777 void 4778 OptionParsingStarting () 4779 { 4780 m_class_name.clear(); 4781 m_function_name.clear(); 4782 m_line_start = 0; 4783 m_line_end = UINT_MAX; 4784 m_file_name.clear(); 4785 m_module_name.clear(); 4786 m_func_name_type_mask = eFunctionNameTypeAuto; 4787 m_thread_id = LLDB_INVALID_THREAD_ID; 4788 m_thread_index = UINT32_MAX; 4789 m_thread_name.clear(); 4790 m_queue_name.clear(); 4791 4792 m_no_inlines = false; 4793 m_sym_ctx_specified = false; 4794 m_thread_specified = false; 4795 4796 m_use_one_liner = false; 4797 m_one_liner.clear(); 4798 } 4799 4800 4801 static OptionDefinition g_option_table[]; 4802 4803 std::string m_class_name; 4804 std::string m_function_name; 4805 uint32_t m_line_start; 4806 uint32_t m_line_end; 4807 std::string m_file_name; 4808 std::string m_module_name; 4809 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType. 4810 lldb::tid_t m_thread_id; 4811 uint32_t m_thread_index; 4812 std::string m_thread_name; 4813 std::string m_queue_name; 4814 bool m_sym_ctx_specified; 4815 bool m_no_inlines; 4816 bool m_thread_specified; 4817 // Instance variables to hold the values for one_liner options. 4818 bool m_use_one_liner; 4819 std::string m_one_liner; 4820 }; 4821 4822 Options * 4823 GetOptions () 4824 { 4825 return &m_options; 4826 } 4827 4828 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) : 4829 CommandObjectParsed (interpreter, 4830 "target stop-hook add ", 4831 "Add a hook to be executed when the target stops.", 4832 "target stop-hook add"), 4833 m_options (interpreter) 4834 { 4835 } 4836 4837 ~CommandObjectTargetStopHookAdd () 4838 { 4839 } 4840 4841 static size_t 4842 ReadCommandsCallbackFunction (void *baton, 4843 InputReader &reader, 4844 lldb::InputReaderAction notification, 4845 const char *bytes, 4846 size_t bytes_len) 4847 { 4848 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream(); 4849 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton); 4850 static bool got_interrupted; 4851 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode(); 4852 4853 switch (notification) 4854 { 4855 case eInputReaderActivate: 4856 if (!batch_mode) 4857 { 4858 out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end."); 4859 if (reader.GetPrompt()) 4860 out_stream->Printf ("%s", reader.GetPrompt()); 4861 out_stream->Flush(); 4862 } 4863 got_interrupted = false; 4864 break; 4865 4866 case eInputReaderDeactivate: 4867 break; 4868 4869 case eInputReaderReactivate: 4870 if (reader.GetPrompt() && !batch_mode) 4871 { 4872 out_stream->Printf ("%s", reader.GetPrompt()); 4873 out_stream->Flush(); 4874 } 4875 got_interrupted = false; 4876 break; 4877 4878 case eInputReaderAsynchronousOutputWritten: 4879 break; 4880 4881 case eInputReaderGotToken: 4882 if (bytes && bytes_len && baton) 4883 { 4884 StringList *commands = new_stop_hook->GetCommandPointer(); 4885 if (commands) 4886 { 4887 commands->AppendString (bytes, bytes_len); 4888 } 4889 } 4890 if (!reader.IsDone() && reader.GetPrompt() && !batch_mode) 4891 { 4892 out_stream->Printf ("%s", reader.GetPrompt()); 4893 out_stream->Flush(); 4894 } 4895 break; 4896 4897 case eInputReaderInterrupt: 4898 { 4899 // Finish, and cancel the stop hook. 4900 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID()); 4901 if (!batch_mode) 4902 { 4903 out_stream->Printf ("Stop hook cancelled.\n"); 4904 out_stream->Flush(); 4905 } 4906 4907 reader.SetIsDone (true); 4908 } 4909 got_interrupted = true; 4910 break; 4911 4912 case eInputReaderEndOfFile: 4913 reader.SetIsDone (true); 4914 break; 4915 4916 case eInputReaderDone: 4917 if (!got_interrupted && !batch_mode) 4918 { 4919 out_stream->Printf ("Stop hook #%" PRIu64 " added.\n", new_stop_hook->GetID()); 4920 out_stream->Flush(); 4921 } 4922 break; 4923 } 4924 4925 return bytes_len; 4926 } 4927 4928 protected: 4929 bool 4930 DoExecute (Args& command, CommandReturnObject &result) 4931 { 4932 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4933 if (target) 4934 { 4935 Target::StopHookSP new_hook_sp; 4936 target->AddStopHook (new_hook_sp); 4937 4938 // First step, make the specifier. 4939 std::unique_ptr<SymbolContextSpecifier> specifier_ap; 4940 if (m_options.m_sym_ctx_specified) 4941 { 4942 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget())); 4943 4944 if (!m_options.m_module_name.empty()) 4945 { 4946 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified); 4947 } 4948 4949 if (!m_options.m_class_name.empty()) 4950 { 4951 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified); 4952 } 4953 4954 if (!m_options.m_file_name.empty()) 4955 { 4956 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified); 4957 } 4958 4959 if (m_options.m_line_start != 0) 4960 { 4961 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified); 4962 } 4963 4964 if (m_options.m_line_end != UINT_MAX) 4965 { 4966 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); 4967 } 4968 4969 if (!m_options.m_function_name.empty()) 4970 { 4971 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified); 4972 } 4973 } 4974 4975 if (specifier_ap.get()) 4976 new_hook_sp->SetSpecifier (specifier_ap.release()); 4977 4978 // Next see if any of the thread options have been entered: 4979 4980 if (m_options.m_thread_specified) 4981 { 4982 ThreadSpec *thread_spec = new ThreadSpec(); 4983 4984 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 4985 { 4986 thread_spec->SetTID (m_options.m_thread_id); 4987 } 4988 4989 if (m_options.m_thread_index != UINT32_MAX) 4990 thread_spec->SetIndex (m_options.m_thread_index); 4991 4992 if (!m_options.m_thread_name.empty()) 4993 thread_spec->SetName (m_options.m_thread_name.c_str()); 4994 4995 if (!m_options.m_queue_name.empty()) 4996 thread_spec->SetQueueName (m_options.m_queue_name.c_str()); 4997 4998 new_hook_sp->SetThreadSpecifier (thread_spec); 4999 5000 } 5001 if (m_options.m_use_one_liner) 5002 { 5003 // Use one-liner. 5004 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str()); 5005 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID()); 5006 } 5007 else 5008 { 5009 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into 5010 // the new stop hook's command string. 5011 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger())); 5012 if (!reader_sp) 5013 { 5014 result.AppendError("out of memory\n"); 5015 result.SetStatus (eReturnStatusFailed); 5016 target->RemoveStopHookByID (new_hook_sp->GetID()); 5017 return false; 5018 } 5019 5020 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction, 5021 new_hook_sp.get(), // baton 5022 eInputReaderGranularityLine, // token size, to pass to callback function 5023 "DONE", // end token 5024 "> ", // prompt 5025 true)); // echo input 5026 if (!err.Success()) 5027 { 5028 result.AppendError (err.AsCString()); 5029 result.SetStatus (eReturnStatusFailed); 5030 target->RemoveStopHookByID (new_hook_sp->GetID()); 5031 return false; 5032 } 5033 m_interpreter.GetDebugger().PushInputReader (reader_sp); 5034 } 5035 result.SetStatus (eReturnStatusSuccessFinishNoResult); 5036 } 5037 else 5038 { 5039 result.AppendError ("invalid target\n"); 5040 result.SetStatus (eReturnStatusFailed); 5041 } 5042 5043 return result.Succeeded(); 5044 } 5045 private: 5046 CommandOptions m_options; 5047 }; 5048 5049 OptionDefinition 5050 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] = 5051 { 5052 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, 0, eArgTypeOneLiner, 5053 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, 5054 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 5055 "Set the module within which the stop-hook is to be run."}, 5056 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex, 5057 "The stop hook is run only for the thread whose index matches this argument."}, 5058 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, 0, eArgTypeThreadID, 5059 "The stop hook is run only for the thread whose TID matches this argument."}, 5060 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, 0, eArgTypeThreadName, 5061 "The stop hook is run only for the thread whose thread name matches this argument."}, 5062 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, 0, eArgTypeQueueName, 5063 "The stop hook is run only for threads in the queue whose name is given by this argument."}, 5064 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 5065 "Specify the source file within which the stop-hook is to be run." }, 5066 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum, 5067 "Set the start of the line range for which the stop-hook is to be run."}, 5068 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum, 5069 "Set the end of the line range for which the stop-hook is to be run."}, 5070 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, 0, eArgTypeClassName, 5071 "Specify the class within which the stop-hook is to be run." }, 5072 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 5073 "Set the function name within which the stop hook will be run." }, 5074 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 5075 }; 5076 5077 #pragma mark CommandObjectTargetStopHookDelete 5078 5079 //------------------------------------------------------------------------- 5080 // CommandObjectTargetStopHookDelete 5081 //------------------------------------------------------------------------- 5082 5083 class CommandObjectTargetStopHookDelete : public CommandObjectParsed 5084 { 5085 public: 5086 5087 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) : 5088 CommandObjectParsed (interpreter, 5089 "target stop-hook delete", 5090 "Delete a stop-hook.", 5091 "target stop-hook delete [<idx>]") 5092 { 5093 } 5094 5095 ~CommandObjectTargetStopHookDelete () 5096 { 5097 } 5098 5099 protected: 5100 bool 5101 DoExecute (Args& command, CommandReturnObject &result) 5102 { 5103 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 5104 if (target) 5105 { 5106 // FIXME: see if we can use the breakpoint id style parser? 5107 size_t num_args = command.GetArgumentCount(); 5108 if (num_args == 0) 5109 { 5110 if (!m_interpreter.Confirm ("Delete all stop hooks?", true)) 5111 { 5112 result.SetStatus (eReturnStatusFailed); 5113 return false; 5114 } 5115 else 5116 { 5117 target->RemoveAllStopHooks(); 5118 } 5119 } 5120 else 5121 { 5122 bool success; 5123 for (size_t i = 0; i < num_args; i++) 5124 { 5125 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 5126 if (!success) 5127 { 5128 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5129 result.SetStatus(eReturnStatusFailed); 5130 return false; 5131 } 5132 success = target->RemoveStopHookByID (user_id); 5133 if (!success) 5134 { 5135 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5136 result.SetStatus(eReturnStatusFailed); 5137 return false; 5138 } 5139 } 5140 } 5141 result.SetStatus (eReturnStatusSuccessFinishNoResult); 5142 } 5143 else 5144 { 5145 result.AppendError ("invalid target\n"); 5146 result.SetStatus (eReturnStatusFailed); 5147 } 5148 5149 return result.Succeeded(); 5150 } 5151 }; 5152 #pragma mark CommandObjectTargetStopHookEnableDisable 5153 5154 //------------------------------------------------------------------------- 5155 // CommandObjectTargetStopHookEnableDisable 5156 //------------------------------------------------------------------------- 5157 5158 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed 5159 { 5160 public: 5161 5162 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) : 5163 CommandObjectParsed (interpreter, 5164 name, 5165 help, 5166 syntax), 5167 m_enable (enable) 5168 { 5169 } 5170 5171 ~CommandObjectTargetStopHookEnableDisable () 5172 { 5173 } 5174 5175 protected: 5176 bool 5177 DoExecute (Args& command, CommandReturnObject &result) 5178 { 5179 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 5180 if (target) 5181 { 5182 // FIXME: see if we can use the breakpoint id style parser? 5183 size_t num_args = command.GetArgumentCount(); 5184 bool success; 5185 5186 if (num_args == 0) 5187 { 5188 target->SetAllStopHooksActiveState (m_enable); 5189 } 5190 else 5191 { 5192 for (size_t i = 0; i < num_args; i++) 5193 { 5194 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 5195 if (!success) 5196 { 5197 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5198 result.SetStatus(eReturnStatusFailed); 5199 return false; 5200 } 5201 success = target->SetStopHookActiveStateByID (user_id, m_enable); 5202 if (!success) 5203 { 5204 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5205 result.SetStatus(eReturnStatusFailed); 5206 return false; 5207 } 5208 } 5209 } 5210 result.SetStatus (eReturnStatusSuccessFinishNoResult); 5211 } 5212 else 5213 { 5214 result.AppendError ("invalid target\n"); 5215 result.SetStatus (eReturnStatusFailed); 5216 } 5217 return result.Succeeded(); 5218 } 5219 private: 5220 bool m_enable; 5221 }; 5222 5223 #pragma mark CommandObjectTargetStopHookList 5224 5225 //------------------------------------------------------------------------- 5226 // CommandObjectTargetStopHookList 5227 //------------------------------------------------------------------------- 5228 5229 class CommandObjectTargetStopHookList : public CommandObjectParsed 5230 { 5231 public: 5232 5233 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) : 5234 CommandObjectParsed (interpreter, 5235 "target stop-hook list", 5236 "List all stop-hooks.", 5237 "target stop-hook list [<type>]") 5238 { 5239 } 5240 5241 ~CommandObjectTargetStopHookList () 5242 { 5243 } 5244 5245 protected: 5246 bool 5247 DoExecute (Args& command, CommandReturnObject &result) 5248 { 5249 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 5250 if (!target) 5251 { 5252 result.AppendError ("invalid target\n"); 5253 result.SetStatus (eReturnStatusFailed); 5254 return result.Succeeded(); 5255 } 5256 5257 size_t num_hooks = target->GetNumStopHooks (); 5258 if (num_hooks == 0) 5259 { 5260 result.GetOutputStream().PutCString ("No stop hooks.\n"); 5261 } 5262 else 5263 { 5264 for (size_t i = 0; i < num_hooks; i++) 5265 { 5266 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i); 5267 if (i > 0) 5268 result.GetOutputStream().PutCString ("\n"); 5269 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull); 5270 } 5271 } 5272 result.SetStatus (eReturnStatusSuccessFinishResult); 5273 return result.Succeeded(); 5274 } 5275 }; 5276 5277 #pragma mark CommandObjectMultiwordTargetStopHooks 5278 //------------------------------------------------------------------------- 5279 // CommandObjectMultiwordTargetStopHooks 5280 //------------------------------------------------------------------------- 5281 5282 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword 5283 { 5284 public: 5285 5286 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) : 5287 CommandObjectMultiword (interpreter, 5288 "target stop-hook", 5289 "A set of commands for operating on debugger target stop-hooks.", 5290 "target stop-hook <subcommand> [<subcommand-options>]") 5291 { 5292 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter))); 5293 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter))); 5294 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 5295 false, 5296 "target stop-hook disable [<id>]", 5297 "Disable a stop-hook.", 5298 "target stop-hook disable"))); 5299 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 5300 true, 5301 "target stop-hook enable [<id>]", 5302 "Enable a stop-hook.", 5303 "target stop-hook enable"))); 5304 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter))); 5305 } 5306 5307 ~CommandObjectMultiwordTargetStopHooks() 5308 { 5309 } 5310 }; 5311 5312 5313 5314 #pragma mark CommandObjectMultiwordTarget 5315 5316 //------------------------------------------------------------------------- 5317 // CommandObjectMultiwordTarget 5318 //------------------------------------------------------------------------- 5319 5320 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) : 5321 CommandObjectMultiword (interpreter, 5322 "target", 5323 "A set of commands for operating on debugger targets.", 5324 "target <subcommand> [<subcommand-options>]") 5325 { 5326 5327 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter))); 5328 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter))); 5329 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter))); 5330 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter))); 5331 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter))); 5332 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter))); 5333 LoadSubCommand ("symbols", CommandObjectSP (new CommandObjectTargetSymbols (interpreter))); 5334 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter))); 5335 } 5336 5337 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () 5338 { 5339 } 5340 5341 5342