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