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 Address first_non_prologue_insn (func_unwinders_sp->GetFirstNonPrologueInsn(*target)); 3748 if (first_non_prologue_insn.IsValid()) 3749 { 3750 result.GetOutputStream().Printf("First non-prologue instruction is at address 0x%" PRIx64 " or offset %" PRId64 " into the function.\n", first_non_prologue_insn.GetLoadAddress(target), first_non_prologue_insn.GetLoadAddress(target) - start_addr); 3751 result.GetOutputStream().Printf ("\n"); 3752 } 3753 3754 UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread.get(), -1); 3755 if (non_callsite_unwind_plan.get()) 3756 { 3757 result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3758 non_callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3759 result.GetOutputStream().Printf ("\n"); 3760 } 3761 3762 UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1); 3763 if (callsite_unwind_plan.get()) 3764 { 3765 result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3766 callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3767 result.GetOutputStream().Printf ("\n"); 3768 } 3769 3770 UnwindPlanSP arch_default_unwind_plan = func_unwinders_sp->GetUnwindPlanArchitectureDefault(*thread.get()); 3771 if (arch_default_unwind_plan.get()) 3772 { 3773 result.GetOutputStream().Printf("Architecture default UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3774 arch_default_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3775 result.GetOutputStream().Printf ("\n"); 3776 } 3777 3778 UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get()); 3779 if (fast_unwind_plan.get()) 3780 { 3781 result.GetOutputStream().Printf("Fast UnwindPlan for %s`%s (start addr 0x%" PRIx64 "):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3782 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3783 result.GetOutputStream().Printf ("\n"); 3784 } 3785 3786 3787 result.GetOutputStream().Printf ("\n"); 3788 } 3789 return result.Succeeded(); 3790 } 3791 3792 CommandOptions m_options; 3793 }; 3794 3795 OptionDefinition 3796 CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] = 3797 { 3798 { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."}, 3799 { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"}, 3800 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3801 }; 3802 3803 //---------------------------------------------------------------------- 3804 // Lookup information in images 3805 //---------------------------------------------------------------------- 3806 class CommandObjectTargetModulesLookup : public CommandObjectParsed 3807 { 3808 public: 3809 enum 3810 { 3811 eLookupTypeInvalid = -1, 3812 eLookupTypeAddress = 0, 3813 eLookupTypeSymbol, 3814 eLookupTypeFileLine, // Line is optional 3815 eLookupTypeFunction, 3816 eLookupTypeFunctionOrSymbol, 3817 eLookupTypeType, 3818 kNumLookupTypes 3819 }; 3820 3821 class CommandOptions : public Options 3822 { 3823 public: 3824 CommandOptions (CommandInterpreter &interpreter) : 3825 Options(interpreter) 3826 { 3827 OptionParsingStarting(); 3828 } 3829 3830 virtual 3831 ~CommandOptions () 3832 { 3833 } 3834 3835 virtual Error 3836 SetOptionValue (uint32_t option_idx, const char *option_arg) 3837 { 3838 Error error; 3839 3840 const int short_option = m_getopt_table[option_idx].val; 3841 3842 switch (short_option) 3843 { 3844 case 'a': 3845 { 3846 m_type = eLookupTypeAddress; 3847 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 3848 m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 3849 } 3850 break; 3851 3852 case 'o': 3853 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS); 3854 if (m_offset == LLDB_INVALID_ADDRESS) 3855 error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg); 3856 break; 3857 3858 case 's': 3859 m_str = option_arg; 3860 m_type = eLookupTypeSymbol; 3861 break; 3862 3863 case 'f': 3864 m_file.SetFile (option_arg, false); 3865 m_type = eLookupTypeFileLine; 3866 break; 3867 3868 case 'i': 3869 m_include_inlines = false; 3870 break; 3871 3872 case 'l': 3873 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX); 3874 if (m_line_number == UINT32_MAX) 3875 error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg); 3876 else if (m_line_number == 0) 3877 error.SetErrorString ("zero is an invalid line number"); 3878 m_type = eLookupTypeFileLine; 3879 break; 3880 3881 case 'F': 3882 m_str = option_arg; 3883 m_type = eLookupTypeFunction; 3884 break; 3885 3886 case 'n': 3887 m_str = option_arg; 3888 m_type = eLookupTypeFunctionOrSymbol; 3889 break; 3890 3891 case 't': 3892 m_str = option_arg; 3893 m_type = eLookupTypeType; 3894 break; 3895 3896 case 'v': 3897 m_verbose = 1; 3898 break; 3899 3900 case 'A': 3901 m_print_all = true; 3902 break; 3903 3904 case 'r': 3905 m_use_regex = true; 3906 break; 3907 } 3908 3909 return error; 3910 } 3911 3912 void 3913 OptionParsingStarting () 3914 { 3915 m_type = eLookupTypeInvalid; 3916 m_str.clear(); 3917 m_file.Clear(); 3918 m_addr = LLDB_INVALID_ADDRESS; 3919 m_offset = 0; 3920 m_line_number = 0; 3921 m_use_regex = false; 3922 m_include_inlines = true; 3923 m_verbose = false; 3924 m_print_all = false; 3925 } 3926 3927 const OptionDefinition* 3928 GetDefinitions () 3929 { 3930 return g_option_table; 3931 } 3932 3933 // Options table: Required for subclasses of Options. 3934 3935 static OptionDefinition g_option_table[]; 3936 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3937 std::string m_str; // Holds name lookup 3938 FileSpec m_file; // Files for file lookups 3939 lldb::addr_t m_addr; // Holds the address to lookup 3940 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups. 3941 uint32_t m_line_number; // Line number for file+line lookups 3942 bool m_use_regex; // Name lookups in m_str are regular expressions. 3943 bool m_include_inlines;// Check for inline entries when looking up by file/line. 3944 bool m_verbose; // Enable verbose lookup info 3945 bool m_print_all; // Print all matches, even in cases where there's a best match. 3946 }; 3947 3948 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) : 3949 CommandObjectParsed (interpreter, 3950 "target modules lookup", 3951 "Look up information within executable and dependent shared library images.", 3952 NULL, 3953 eFlagRequiresTarget), 3954 m_options (interpreter) 3955 { 3956 CommandArgumentEntry arg; 3957 CommandArgumentData file_arg; 3958 3959 // Define the first (and only) variant of this arg. 3960 file_arg.arg_type = eArgTypeFilename; 3961 file_arg.arg_repetition = eArgRepeatStar; 3962 3963 // There is only one variant this argument could be; put it into the argument entry. 3964 arg.push_back (file_arg); 3965 3966 // Push the data for the first argument into the m_arguments vector. 3967 m_arguments.push_back (arg); 3968 } 3969 3970 virtual 3971 ~CommandObjectTargetModulesLookup () 3972 { 3973 } 3974 3975 virtual Options * 3976 GetOptions () 3977 { 3978 return &m_options; 3979 } 3980 3981 bool 3982 LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error) 3983 { 3984 switch (m_options.m_type) 3985 { 3986 case eLookupTypeAddress: 3987 case eLookupTypeFileLine: 3988 case eLookupTypeFunction: 3989 case eLookupTypeFunctionOrSymbol: 3990 case eLookupTypeSymbol: 3991 default: 3992 return false; 3993 case eLookupTypeType: 3994 break; 3995 } 3996 3997 StackFrameSP frame = m_exe_ctx.GetFrameSP(); 3998 3999 if (!frame) 4000 return false; 4001 4002 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule)); 4003 4004 if (!sym_ctx.module_sp) 4005 return false; 4006 4007 switch (m_options.m_type) 4008 { 4009 default: 4010 return false; 4011 case eLookupTypeType: 4012 if (!m_options.m_str.empty()) 4013 { 4014 if (LookupTypeHere (m_interpreter, 4015 result.GetOutputStream(), 4016 sym_ctx, 4017 m_options.m_str.c_str(), 4018 m_options.m_use_regex)) 4019 { 4020 result.SetStatus(eReturnStatusSuccessFinishResult); 4021 return true; 4022 } 4023 } 4024 break; 4025 } 4026 4027 return true; 4028 } 4029 4030 bool 4031 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error) 4032 { 4033 switch (m_options.m_type) 4034 { 4035 case eLookupTypeAddress: 4036 if (m_options.m_addr != LLDB_INVALID_ADDRESS) 4037 { 4038 if (LookupAddressInModule (m_interpreter, 4039 result.GetOutputStream(), 4040 module, 4041 eSymbolContextEverything, 4042 m_options.m_addr, 4043 m_options.m_offset, 4044 m_options.m_verbose)) 4045 { 4046 result.SetStatus(eReturnStatusSuccessFinishResult); 4047 return true; 4048 } 4049 } 4050 break; 4051 4052 case eLookupTypeSymbol: 4053 if (!m_options.m_str.empty()) 4054 { 4055 if (LookupSymbolInModule (m_interpreter, 4056 result.GetOutputStream(), 4057 module, 4058 m_options.m_str.c_str(), 4059 m_options.m_use_regex, 4060 m_options.m_verbose)) 4061 { 4062 result.SetStatus(eReturnStatusSuccessFinishResult); 4063 return true; 4064 } 4065 } 4066 break; 4067 4068 case eLookupTypeFileLine: 4069 if (m_options.m_file) 4070 { 4071 if (LookupFileAndLineInModule (m_interpreter, 4072 result.GetOutputStream(), 4073 module, 4074 m_options.m_file, 4075 m_options.m_line_number, 4076 m_options.m_include_inlines, 4077 m_options.m_verbose)) 4078 { 4079 result.SetStatus(eReturnStatusSuccessFinishResult); 4080 return true; 4081 } 4082 } 4083 break; 4084 4085 case eLookupTypeFunctionOrSymbol: 4086 case eLookupTypeFunction: 4087 if (!m_options.m_str.empty()) 4088 { 4089 if (LookupFunctionInModule (m_interpreter, 4090 result.GetOutputStream(), 4091 module, 4092 m_options.m_str.c_str(), 4093 m_options.m_use_regex, 4094 m_options.m_include_inlines, 4095 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols 4096 m_options.m_verbose)) 4097 { 4098 result.SetStatus(eReturnStatusSuccessFinishResult); 4099 return true; 4100 } 4101 } 4102 break; 4103 4104 case eLookupTypeType: 4105 if (!m_options.m_str.empty()) 4106 { 4107 if (LookupTypeInModule (m_interpreter, 4108 result.GetOutputStream(), 4109 module, 4110 m_options.m_str.c_str(), 4111 m_options.m_use_regex)) 4112 { 4113 result.SetStatus(eReturnStatusSuccessFinishResult); 4114 return true; 4115 } 4116 } 4117 break; 4118 4119 default: 4120 m_options.GenerateOptionUsage (result.GetErrorStream(), this); 4121 syntax_error = true; 4122 break; 4123 } 4124 4125 result.SetStatus (eReturnStatusFailed); 4126 return false; 4127 } 4128 4129 protected: 4130 virtual bool 4131 DoExecute (Args& command, 4132 CommandReturnObject &result) 4133 { 4134 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4135 if (target == NULL) 4136 { 4137 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 4138 result.SetStatus (eReturnStatusFailed); 4139 return false; 4140 } 4141 else 4142 { 4143 bool syntax_error = false; 4144 uint32_t i; 4145 uint32_t num_successful_lookups = 0; 4146 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 4147 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 4148 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 4149 // Dump all sections for all modules images 4150 4151 if (command.GetArgumentCount() == 0) 4152 { 4153 ModuleSP current_module; 4154 4155 // Where it is possible to look in the current symbol context 4156 // first, try that. If this search was successful and --all 4157 // was not passed, don't print anything else. 4158 if (LookupHere (m_interpreter, result, syntax_error)) 4159 { 4160 result.GetOutputStream().EOL(); 4161 num_successful_lookups++; 4162 if (!m_options.m_print_all) 4163 { 4164 result.SetStatus (eReturnStatusSuccessFinishResult); 4165 return result.Succeeded(); 4166 } 4167 } 4168 4169 // Dump all sections for all other modules 4170 4171 const ModuleList &target_modules = target->GetImages(); 4172 Mutex::Locker modules_locker(target_modules.GetMutex()); 4173 const size_t num_modules = target_modules.GetSize(); 4174 if (num_modules > 0) 4175 { 4176 for (i = 0; i<num_modules && syntax_error == false; ++i) 4177 { 4178 Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i); 4179 4180 if (module_pointer != current_module.get() && 4181 LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error)) 4182 { 4183 result.GetOutputStream().EOL(); 4184 num_successful_lookups++; 4185 } 4186 } 4187 } 4188 else 4189 { 4190 result.AppendError ("the target has no associated executable images"); 4191 result.SetStatus (eReturnStatusFailed); 4192 return false; 4193 } 4194 } 4195 else 4196 { 4197 // Dump specified images (by basename or fullpath) 4198 const char *arg_cstr; 4199 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i) 4200 { 4201 ModuleList module_list; 4202 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false); 4203 if (num_matches > 0) 4204 { 4205 for (size_t j=0; j<num_matches; ++j) 4206 { 4207 Module *module = module_list.GetModulePointerAtIndex(j); 4208 if (module) 4209 { 4210 if (LookupInModule (m_interpreter, module, result, syntax_error)) 4211 { 4212 result.GetOutputStream().EOL(); 4213 num_successful_lookups++; 4214 } 4215 } 4216 } 4217 } 4218 else 4219 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 4220 } 4221 } 4222 4223 if (num_successful_lookups > 0) 4224 result.SetStatus (eReturnStatusSuccessFinishResult); 4225 else 4226 result.SetStatus (eReturnStatusFailed); 4227 } 4228 return result.Succeeded(); 4229 } 4230 4231 CommandOptions m_options; 4232 }; 4233 4234 OptionDefinition 4235 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] = 4236 { 4237 { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."}, 4238 { 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."}, 4239 { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5 4240 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ , 4241 false, "regex", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."}, 4242 { 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."}, 4243 { 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."}, 4244 { 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)."}, 4245 { LLDB_OPT_SET_FROM_TO(3,5), 4246 false, "no-inlines", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."}, 4247 { 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."}, 4248 { 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."}, 4249 { 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."}, 4250 { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, 4251 { 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."}, 4252 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 4253 }; 4254 4255 4256 #pragma mark CommandObjectMultiwordImageSearchPaths 4257 4258 //------------------------------------------------------------------------- 4259 // CommandObjectMultiwordImageSearchPaths 4260 //------------------------------------------------------------------------- 4261 4262 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword 4263 { 4264 public: 4265 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) : 4266 CommandObjectMultiword (interpreter, 4267 "target modules search-paths", 4268 "A set of commands for operating on debugger target image search paths.", 4269 "target modules search-paths <subcommand> [<subcommand-options>]") 4270 { 4271 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter))); 4272 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter))); 4273 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter))); 4274 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter))); 4275 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter))); 4276 } 4277 4278 ~CommandObjectTargetModulesImageSearchPaths() 4279 { 4280 } 4281 }; 4282 4283 4284 4285 #pragma mark CommandObjectTargetModules 4286 4287 //------------------------------------------------------------------------- 4288 // CommandObjectTargetModules 4289 //------------------------------------------------------------------------- 4290 4291 class CommandObjectTargetModules : public CommandObjectMultiword 4292 { 4293 public: 4294 //------------------------------------------------------------------ 4295 // Constructors and Destructors 4296 //------------------------------------------------------------------ 4297 CommandObjectTargetModules(CommandInterpreter &interpreter) : 4298 CommandObjectMultiword (interpreter, 4299 "target modules", 4300 "A set of commands for accessing information for one or more target modules.", 4301 "target modules <sub-command> ...") 4302 { 4303 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter))); 4304 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter))); 4305 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter))); 4306 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter))); 4307 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter))); 4308 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter))); 4309 LoadSubCommand ("show-unwind", CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter))); 4310 4311 } 4312 virtual 4313 ~CommandObjectTargetModules() 4314 { 4315 } 4316 4317 private: 4318 //------------------------------------------------------------------ 4319 // For CommandObjectTargetModules only 4320 //------------------------------------------------------------------ 4321 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules); 4322 }; 4323 4324 4325 4326 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed 4327 { 4328 public: 4329 CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) : 4330 CommandObjectParsed (interpreter, 4331 "target symbols add", 4332 "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.", 4333 "target symbols add [<symfile>]", eFlagRequiresTarget), 4334 m_option_group (interpreter), 4335 m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."), 4336 m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true) 4337 4338 { 4339 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 4340 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 4341 m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2); 4342 m_option_group.Finalize(); 4343 } 4344 4345 virtual 4346 ~CommandObjectTargetSymbolsAdd () 4347 { 4348 } 4349 4350 virtual int 4351 HandleArgumentCompletion (Args &input, 4352 int &cursor_index, 4353 int &cursor_char_position, 4354 OptionElementVector &opt_element_vector, 4355 int match_start_point, 4356 int max_return_elements, 4357 bool &word_complete, 4358 StringList &matches) 4359 { 4360 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 4361 completion_str.erase (cursor_char_position); 4362 4363 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 4364 CommandCompletions::eDiskFileCompletion, 4365 completion_str.c_str(), 4366 match_start_point, 4367 max_return_elements, 4368 NULL, 4369 word_complete, 4370 matches); 4371 return matches.GetSize(); 4372 } 4373 4374 virtual Options * 4375 GetOptions () 4376 { 4377 return &m_option_group; 4378 } 4379 4380 protected: 4381 bool 4382 AddModuleSymbols (Target *target, 4383 ModuleSpec &module_spec, 4384 bool &flush, 4385 CommandReturnObject &result) 4386 { 4387 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec(); 4388 if (symbol_fspec) 4389 { 4390 char symfile_path[PATH_MAX]; 4391 symbol_fspec.GetPath (symfile_path, sizeof(symfile_path)); 4392 4393 if (!module_spec.GetUUID().IsValid()) 4394 { 4395 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec()) 4396 module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename(); 4397 } 4398 // We now have a module that represents a symbol file 4399 // that can be used for a module that might exist in the 4400 // current target, so we need to find that module in the 4401 // target 4402 ModuleList matching_module_list; 4403 4404 size_t num_matches = 0; 4405 // First extract all module specs from the symbol file 4406 lldb_private::ModuleSpecList symfile_module_specs; 4407 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), 0, 0, symfile_module_specs)) 4408 { 4409 // Now extract the module spec that matches the target architecture 4410 ModuleSpec target_arch_module_spec; 4411 ModuleSpec symfile_module_spec; 4412 target_arch_module_spec.GetArchitecture() = target->GetArchitecture(); 4413 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, symfile_module_spec)) 4414 { 4415 // See if it has a UUID? 4416 if (symfile_module_spec.GetUUID().IsValid()) 4417 { 4418 // It has a UUID, look for this UUID in the target modules 4419 ModuleSpec symfile_uuid_module_spec; 4420 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); 4421 num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list); 4422 } 4423 } 4424 4425 if (num_matches == 0) 4426 { 4427 // No matches yet, iterate through the module specs to find a UUID value that 4428 // we can match up to an image in our target 4429 const size_t num_symfile_module_specs = symfile_module_specs.GetSize(); 4430 for (size_t i=0; i<num_symfile_module_specs && num_matches == 0; ++i) 4431 { 4432 if (symfile_module_specs.GetModuleSpecAtIndex(i, symfile_module_spec)) 4433 { 4434 if (symfile_module_spec.GetUUID().IsValid()) 4435 { 4436 // It has a UUID, look for this UUID in the target modules 4437 ModuleSpec symfile_uuid_module_spec; 4438 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); 4439 num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list); 4440 } 4441 } 4442 } 4443 } 4444 } 4445 4446 // Just try to match up the file by basename if we have no matches at this point 4447 if (num_matches == 0) 4448 num_matches = target->GetImages().FindModules (module_spec, matching_module_list); 4449 4450 while (num_matches == 0) 4451 { 4452 ConstString filename_no_extension(module_spec.GetFileSpec().GetFileNameStrippingExtension()); 4453 // Empty string returned, lets bail 4454 if (!filename_no_extension) 4455 break; 4456 4457 // Check if there was no extension to strip and the basename is the same 4458 if (filename_no_extension == module_spec.GetFileSpec().GetFilename()) 4459 break; 4460 4461 // Replace basename with one less extension 4462 module_spec.GetFileSpec().GetFilename() = filename_no_extension; 4463 4464 num_matches = target->GetImages().FindModules (module_spec, matching_module_list); 4465 } 4466 4467 if (num_matches > 1) 4468 { 4469 result.AppendErrorWithFormat ("multiple modules match symbol file '%s', use the --uuid option to resolve the ambiguity.\n", symfile_path); 4470 } 4471 else if (num_matches == 1) 4472 { 4473 ModuleSP module_sp (matching_module_list.GetModuleAtIndex(0)); 4474 4475 // The module has not yet created its symbol vendor, we can just 4476 // give the existing target module the symfile path to use for 4477 // when it decides to create it! 4478 module_sp->SetSymbolFileFileSpec (symbol_fspec); 4479 4480 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(true, &result.GetErrorStream()); 4481 if (symbol_vendor) 4482 { 4483 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 4484 4485 if (symbol_file) 4486 { 4487 ObjectFile *object_file = symbol_file->GetObjectFile(); 4488 4489 if (object_file && object_file->GetFileSpec() == symbol_fspec) 4490 { 4491 // Provide feedback that the symfile has been successfully added. 4492 const FileSpec &module_fs = module_sp->GetFileSpec(); 4493 result.AppendMessageWithFormat("symbol file '%s' has been added to '%s'\n", 4494 symfile_path, 4495 module_fs.GetPath().c_str()); 4496 4497 // Let clients know something changed in the module 4498 // if it is currently loaded 4499 ModuleList module_list; 4500 module_list.Append (module_sp); 4501 target->SymbolsDidLoad (module_list); 4502 4503 // Make sure we load any scripting resources that may be embedded 4504 // in the debug info files in case the platform supports that. 4505 Error error; 4506 StreamString feedback_stream; 4507 module_sp->LoadScriptingResourceInTarget (target, error,&feedback_stream); 4508 if (error.Fail() && error.AsCString()) 4509 result.AppendWarningWithFormat("unable to load scripting data for module %s - error reported was %s", 4510 module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(), 4511 error.AsCString()); 4512 else if (feedback_stream.GetSize()) 4513 result.AppendWarningWithFormat("%s",feedback_stream.GetData()); 4514 4515 flush = true; 4516 result.SetStatus (eReturnStatusSuccessFinishResult); 4517 return true; 4518 } 4519 } 4520 } 4521 // Clear the symbol file spec if anything went wrong 4522 module_sp->SetSymbolFileFileSpec (FileSpec()); 4523 } 4524 4525 if (module_spec.GetUUID().IsValid()) 4526 { 4527 StreamString ss_symfile_uuid; 4528 module_spec.GetUUID().Dump(&ss_symfile_uuid); 4529 result.AppendErrorWithFormat ("symbol file '%s' (%s) does not match any existing module%s\n", 4530 symfile_path, 4531 ss_symfile_uuid.GetData(), 4532 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular) 4533 ? "\n please specify the full path to the symbol file" 4534 : ""); 4535 } 4536 else 4537 { 4538 result.AppendErrorWithFormat ("symbol file '%s' does not match any existing module%s\n", 4539 symfile_path, 4540 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular) 4541 ? "\n please specify the full path to the symbol file" 4542 : ""); 4543 } 4544 } 4545 else 4546 { 4547 result.AppendError ("one or more executable image paths must be specified"); 4548 } 4549 result.SetStatus (eReturnStatusFailed); 4550 return false; 4551 } 4552 4553 virtual bool 4554 DoExecute (Args& args, 4555 CommandReturnObject &result) 4556 { 4557 Target *target = m_exe_ctx.GetTargetPtr(); 4558 result.SetStatus (eReturnStatusFailed); 4559 bool flush = false; 4560 ModuleSpec module_spec; 4561 const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet(); 4562 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet(); 4563 const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet(); 4564 4565 const size_t argc = args.GetArgumentCount(); 4566 if (argc == 0) 4567 { 4568 if (uuid_option_set || file_option_set || frame_option_set) 4569 { 4570 bool success = false; 4571 bool error_set = false; 4572 if (frame_option_set) 4573 { 4574 Process *process = m_exe_ctx.GetProcessPtr(); 4575 if (process) 4576 { 4577 const StateType process_state = process->GetState(); 4578 if (StateIsStoppedState (process_state, true)) 4579 { 4580 StackFrame *frame = m_exe_ctx.GetFramePtr(); 4581 if (frame) 4582 { 4583 ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp); 4584 if (frame_module_sp) 4585 { 4586 if (frame_module_sp->GetPlatformFileSpec().Exists()) 4587 { 4588 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); 4589 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec(); 4590 } 4591 module_spec.GetUUID() = frame_module_sp->GetUUID(); 4592 success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec(); 4593 } 4594 else 4595 { 4596 result.AppendError ("frame has no module"); 4597 error_set = true; 4598 } 4599 } 4600 else 4601 { 4602 result.AppendError ("invalid current frame"); 4603 error_set = true; 4604 } 4605 } 4606 else 4607 { 4608 result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state)); 4609 error_set = true; 4610 } 4611 } 4612 else 4613 { 4614 result.AppendError ("a process must exist in order to use the --frame option"); 4615 error_set = true; 4616 } 4617 } 4618 else 4619 { 4620 if (uuid_option_set) 4621 { 4622 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); 4623 success |= module_spec.GetUUID().IsValid(); 4624 } 4625 else if (file_option_set) 4626 { 4627 module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); 4628 ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec)); 4629 if (module_sp) 4630 { 4631 module_spec.GetFileSpec() = module_sp->GetFileSpec(); 4632 module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec(); 4633 module_spec.GetUUID() = module_sp->GetUUID(); 4634 module_spec.GetArchitecture() = module_sp->GetArchitecture(); 4635 } 4636 else 4637 { 4638 module_spec.GetArchitecture() = target->GetArchitecture(); 4639 } 4640 success |= module_spec.GetFileSpec().Exists(); 4641 } 4642 } 4643 4644 if (success) 4645 { 4646 if (Symbols::DownloadObjectAndSymbolFile (module_spec)) 4647 { 4648 if (module_spec.GetSymbolFileSpec()) 4649 success = AddModuleSymbols (target, module_spec, flush, result); 4650 } 4651 } 4652 4653 if (!success && !error_set) 4654 { 4655 StreamString error_strm; 4656 if (uuid_option_set) 4657 { 4658 error_strm.PutCString("unable to find debug symbols for UUID "); 4659 module_spec.GetUUID().Dump (&error_strm); 4660 } 4661 else if (file_option_set) 4662 { 4663 error_strm.PutCString("unable to find debug symbols for the executable file "); 4664 error_strm << module_spec.GetFileSpec(); 4665 } 4666 else if (frame_option_set) 4667 { 4668 error_strm.PutCString("unable to find debug symbols for the current frame"); 4669 } 4670 result.AppendError (error_strm.GetData()); 4671 } 4672 } 4673 else 4674 { 4675 result.AppendError ("one or more symbol file paths must be specified, or options must be specified"); 4676 } 4677 } 4678 else 4679 { 4680 if (uuid_option_set) 4681 { 4682 result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments"); 4683 } 4684 else if (file_option_set) 4685 { 4686 result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments"); 4687 } 4688 else if (frame_option_set) 4689 { 4690 result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments"); 4691 } 4692 else 4693 { 4694 PlatformSP platform_sp (target->GetPlatform()); 4695 4696 for (size_t i=0; i<argc; ++i) 4697 { 4698 const char *symfile_path = args.GetArgumentAtIndex(i); 4699 if (symfile_path) 4700 { 4701 module_spec.GetSymbolFileSpec().SetFile(symfile_path, true); 4702 if (platform_sp) 4703 { 4704 FileSpec symfile_spec; 4705 if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success()) 4706 module_spec.GetSymbolFileSpec() = symfile_spec; 4707 } 4708 4709 ArchSpec arch; 4710 bool symfile_exists = module_spec.GetSymbolFileSpec().Exists(); 4711 4712 if (symfile_exists) 4713 { 4714 if (!AddModuleSymbols (target, module_spec, flush, result)) 4715 break; 4716 } 4717 else 4718 { 4719 char resolved_symfile_path[PATH_MAX]; 4720 if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path))) 4721 { 4722 if (strcmp (resolved_symfile_path, symfile_path) != 0) 4723 { 4724 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path); 4725 break; 4726 } 4727 } 4728 result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path); 4729 break; 4730 } 4731 } 4732 } 4733 } 4734 } 4735 4736 if (flush) 4737 { 4738 Process *process = m_exe_ctx.GetProcessPtr(); 4739 if (process) 4740 process->Flush(); 4741 } 4742 return result.Succeeded(); 4743 } 4744 4745 OptionGroupOptions m_option_group; 4746 OptionGroupUUID m_uuid_option_group; 4747 OptionGroupFile m_file_option; 4748 OptionGroupBoolean m_current_frame_option; 4749 }; 4750 4751 4752 #pragma mark CommandObjectTargetSymbols 4753 4754 //------------------------------------------------------------------------- 4755 // CommandObjectTargetSymbols 4756 //------------------------------------------------------------------------- 4757 4758 class CommandObjectTargetSymbols : public CommandObjectMultiword 4759 { 4760 public: 4761 //------------------------------------------------------------------ 4762 // Constructors and Destructors 4763 //------------------------------------------------------------------ 4764 CommandObjectTargetSymbols(CommandInterpreter &interpreter) : 4765 CommandObjectMultiword (interpreter, 4766 "target symbols", 4767 "A set of commands for adding and managing debug symbol files.", 4768 "target symbols <sub-command> ...") 4769 { 4770 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter))); 4771 4772 } 4773 virtual 4774 ~CommandObjectTargetSymbols() 4775 { 4776 } 4777 4778 private: 4779 //------------------------------------------------------------------ 4780 // For CommandObjectTargetModules only 4781 //------------------------------------------------------------------ 4782 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols); 4783 }; 4784 4785 4786 #pragma mark CommandObjectTargetStopHookAdd 4787 4788 //------------------------------------------------------------------------- 4789 // CommandObjectTargetStopHookAdd 4790 //------------------------------------------------------------------------- 4791 4792 class CommandObjectTargetStopHookAdd : 4793 public CommandObjectParsed, 4794 public IOHandlerDelegateMultiline 4795 { 4796 public: 4797 4798 class CommandOptions : public Options 4799 { 4800 public: 4801 CommandOptions (CommandInterpreter &interpreter) : 4802 Options(interpreter), 4803 m_line_start(0), 4804 m_line_end (UINT_MAX), 4805 m_func_name_type_mask (eFunctionNameTypeAuto), 4806 m_sym_ctx_specified (false), 4807 m_thread_specified (false), 4808 m_use_one_liner (false), 4809 m_one_liner() 4810 { 4811 } 4812 4813 ~CommandOptions () {} 4814 4815 const OptionDefinition* 4816 GetDefinitions () 4817 { 4818 return g_option_table; 4819 } 4820 4821 virtual Error 4822 SetOptionValue (uint32_t option_idx, const char *option_arg) 4823 { 4824 Error error; 4825 const int short_option = m_getopt_table[option_idx].val; 4826 bool success; 4827 4828 switch (short_option) 4829 { 4830 case 'c': 4831 m_class_name = option_arg; 4832 m_sym_ctx_specified = true; 4833 break; 4834 4835 case 'e': 4836 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success); 4837 if (!success) 4838 { 4839 error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg); 4840 break; 4841 } 4842 m_sym_ctx_specified = true; 4843 break; 4844 4845 case 'l': 4846 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success); 4847 if (!success) 4848 { 4849 error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg); 4850 break; 4851 } 4852 m_sym_ctx_specified = true; 4853 break; 4854 4855 case 'i': 4856 m_no_inlines = true; 4857 break; 4858 4859 case 'n': 4860 m_function_name = option_arg; 4861 m_func_name_type_mask |= eFunctionNameTypeAuto; 4862 m_sym_ctx_specified = true; 4863 break; 4864 4865 case 'f': 4866 m_file_name = option_arg; 4867 m_sym_ctx_specified = true; 4868 break; 4869 case 's': 4870 m_module_name = option_arg; 4871 m_sym_ctx_specified = true; 4872 break; 4873 case 't' : 4874 { 4875 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 4876 if (m_thread_id == LLDB_INVALID_THREAD_ID) 4877 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 4878 m_thread_specified = true; 4879 } 4880 break; 4881 case 'T': 4882 m_thread_name = option_arg; 4883 m_thread_specified = true; 4884 break; 4885 case 'q': 4886 m_queue_name = option_arg; 4887 m_thread_specified = true; 4888 break; 4889 case 'x': 4890 { 4891 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0); 4892 if (m_thread_id == UINT32_MAX) 4893 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 4894 m_thread_specified = true; 4895 } 4896 break; 4897 case 'o': 4898 m_use_one_liner = true; 4899 m_one_liner = option_arg; 4900 break; 4901 default: 4902 error.SetErrorStringWithFormat ("unrecognized option %c.", short_option); 4903 break; 4904 } 4905 return error; 4906 } 4907 4908 void 4909 OptionParsingStarting () 4910 { 4911 m_class_name.clear(); 4912 m_function_name.clear(); 4913 m_line_start = 0; 4914 m_line_end = UINT_MAX; 4915 m_file_name.clear(); 4916 m_module_name.clear(); 4917 m_func_name_type_mask = eFunctionNameTypeAuto; 4918 m_thread_id = LLDB_INVALID_THREAD_ID; 4919 m_thread_index = UINT32_MAX; 4920 m_thread_name.clear(); 4921 m_queue_name.clear(); 4922 4923 m_no_inlines = false; 4924 m_sym_ctx_specified = false; 4925 m_thread_specified = false; 4926 4927 m_use_one_liner = false; 4928 m_one_liner.clear(); 4929 } 4930 4931 4932 static OptionDefinition g_option_table[]; 4933 4934 std::string m_class_name; 4935 std::string m_function_name; 4936 uint32_t m_line_start; 4937 uint32_t m_line_end; 4938 std::string m_file_name; 4939 std::string m_module_name; 4940 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType. 4941 lldb::tid_t m_thread_id; 4942 uint32_t m_thread_index; 4943 std::string m_thread_name; 4944 std::string m_queue_name; 4945 bool m_sym_ctx_specified; 4946 bool m_no_inlines; 4947 bool m_thread_specified; 4948 // Instance variables to hold the values for one_liner options. 4949 bool m_use_one_liner; 4950 std::string m_one_liner; 4951 }; 4952 4953 Options * 4954 GetOptions () 4955 { 4956 return &m_options; 4957 } 4958 4959 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) : 4960 CommandObjectParsed (interpreter, 4961 "target stop-hook add", 4962 "Add a hook to be executed when the target stops.", 4963 "target stop-hook add"), 4964 IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand), 4965 m_options (interpreter) 4966 { 4967 } 4968 4969 ~CommandObjectTargetStopHookAdd () 4970 { 4971 } 4972 4973 protected: 4974 virtual void 4975 IOHandlerActivated (IOHandler &io_handler) 4976 { 4977 StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 4978 if (output_sp) 4979 { 4980 output_sp->PutCString("Enter your stop hook command(s). Type 'DONE' to end.\n"); 4981 output_sp->Flush(); 4982 } 4983 } 4984 4985 virtual void 4986 IOHandlerInputComplete (IOHandler &io_handler, std::string &line) 4987 { 4988 if (m_stop_hook_sp) 4989 { 4990 if (line.empty()) 4991 { 4992 StreamFileSP error_sp(io_handler.GetErrorStreamFile()); 4993 if (error_sp) 4994 { 4995 error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", m_stop_hook_sp->GetID()); 4996 error_sp->Flush(); 4997 } 4998 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4999 if (target) 5000 target->RemoveStopHookByID(m_stop_hook_sp->GetID()); 5001 } 5002 else 5003 { 5004 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line); 5005 StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 5006 if (output_sp) 5007 { 5008 output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID()); 5009 output_sp->Flush(); 5010 } 5011 } 5012 m_stop_hook_sp.reset(); 5013 } 5014 io_handler.SetIsDone(true); 5015 } 5016 5017 bool 5018 DoExecute (Args& command, CommandReturnObject &result) 5019 { 5020 m_stop_hook_sp.reset(); 5021 5022 Target *target = GetSelectedOrDummyTarget(); 5023 if (target) 5024 { 5025 Target::StopHookSP new_hook_sp = target->CreateStopHook(); 5026 5027 // First step, make the specifier. 5028 std::unique_ptr<SymbolContextSpecifier> specifier_ap; 5029 if (m_options.m_sym_ctx_specified) 5030 { 5031 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget())); 5032 5033 if (!m_options.m_module_name.empty()) 5034 { 5035 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified); 5036 } 5037 5038 if (!m_options.m_class_name.empty()) 5039 { 5040 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified); 5041 } 5042 5043 if (!m_options.m_file_name.empty()) 5044 { 5045 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified); 5046 } 5047 5048 if (m_options.m_line_start != 0) 5049 { 5050 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified); 5051 } 5052 5053 if (m_options.m_line_end != UINT_MAX) 5054 { 5055 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); 5056 } 5057 5058 if (!m_options.m_function_name.empty()) 5059 { 5060 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified); 5061 } 5062 } 5063 5064 if (specifier_ap.get()) 5065 new_hook_sp->SetSpecifier (specifier_ap.release()); 5066 5067 // Next see if any of the thread options have been entered: 5068 5069 if (m_options.m_thread_specified) 5070 { 5071 ThreadSpec *thread_spec = new ThreadSpec(); 5072 5073 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 5074 { 5075 thread_spec->SetTID (m_options.m_thread_id); 5076 } 5077 5078 if (m_options.m_thread_index != UINT32_MAX) 5079 thread_spec->SetIndex (m_options.m_thread_index); 5080 5081 if (!m_options.m_thread_name.empty()) 5082 thread_spec->SetName (m_options.m_thread_name.c_str()); 5083 5084 if (!m_options.m_queue_name.empty()) 5085 thread_spec->SetQueueName (m_options.m_queue_name.c_str()); 5086 5087 new_hook_sp->SetThreadSpecifier (thread_spec); 5088 5089 } 5090 if (m_options.m_use_one_liner) 5091 { 5092 // Use one-liner. 5093 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str()); 5094 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID()); 5095 } 5096 else 5097 { 5098 m_stop_hook_sp = new_hook_sp; 5099 m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt 5100 *this, // IOHandlerDelegate 5101 true, // Run IOHandler in async mode 5102 NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 5103 5104 } 5105 result.SetStatus (eReturnStatusSuccessFinishNoResult); 5106 } 5107 else 5108 { 5109 result.AppendError ("invalid target\n"); 5110 result.SetStatus (eReturnStatusFailed); 5111 } 5112 5113 return result.Succeeded(); 5114 } 5115 private: 5116 CommandOptions m_options; 5117 Target::StopHookSP m_stop_hook_sp; 5118 }; 5119 5120 OptionDefinition 5121 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] = 5122 { 5123 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner, 5124 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, 5125 { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 5126 "Set the module within which the stop-hook is to be run."}, 5127 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, 5128 "The stop hook is run only for the thread whose index matches this argument."}, 5129 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, 5130 "The stop hook is run only for the thread whose TID matches this argument."}, 5131 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, 5132 "The stop hook is run only for the thread whose thread name matches this argument."}, 5133 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, 5134 "The stop hook is run only for threads in the queue whose name is given by this argument."}, 5135 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 5136 "Specify the source file within which the stop-hook is to be run." }, 5137 { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, 5138 "Set the start of the line range for which the stop-hook is to be run."}, 5139 { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, 5140 "Set the end of the line range for which the stop-hook is to be run."}, 5141 { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeClassName, 5142 "Specify the class within which the stop-hook is to be run." }, 5143 { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 5144 "Set the function name within which the stop hook will be run." }, 5145 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 5146 }; 5147 5148 #pragma mark CommandObjectTargetStopHookDelete 5149 5150 //------------------------------------------------------------------------- 5151 // CommandObjectTargetStopHookDelete 5152 //------------------------------------------------------------------------- 5153 5154 class CommandObjectTargetStopHookDelete : public CommandObjectParsed 5155 { 5156 public: 5157 5158 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) : 5159 CommandObjectParsed (interpreter, 5160 "target stop-hook delete", 5161 "Delete a stop-hook.", 5162 "target stop-hook delete [<idx>]") 5163 { 5164 } 5165 5166 ~CommandObjectTargetStopHookDelete () 5167 { 5168 } 5169 5170 protected: 5171 bool 5172 DoExecute (Args& command, CommandReturnObject &result) 5173 { 5174 Target *target = GetSelectedOrDummyTarget(); 5175 if (target) 5176 { 5177 // FIXME: see if we can use the breakpoint id style parser? 5178 size_t num_args = command.GetArgumentCount(); 5179 if (num_args == 0) 5180 { 5181 if (!m_interpreter.Confirm ("Delete all stop hooks?", true)) 5182 { 5183 result.SetStatus (eReturnStatusFailed); 5184 return false; 5185 } 5186 else 5187 { 5188 target->RemoveAllStopHooks(); 5189 } 5190 } 5191 else 5192 { 5193 bool success; 5194 for (size_t i = 0; i < num_args; i++) 5195 { 5196 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 5197 if (!success) 5198 { 5199 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5200 result.SetStatus(eReturnStatusFailed); 5201 return false; 5202 } 5203 success = target->RemoveStopHookByID (user_id); 5204 if (!success) 5205 { 5206 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5207 result.SetStatus(eReturnStatusFailed); 5208 return false; 5209 } 5210 } 5211 } 5212 result.SetStatus (eReturnStatusSuccessFinishNoResult); 5213 } 5214 else 5215 { 5216 result.AppendError ("invalid target\n"); 5217 result.SetStatus (eReturnStatusFailed); 5218 } 5219 5220 return result.Succeeded(); 5221 } 5222 }; 5223 #pragma mark CommandObjectTargetStopHookEnableDisable 5224 5225 //------------------------------------------------------------------------- 5226 // CommandObjectTargetStopHookEnableDisable 5227 //------------------------------------------------------------------------- 5228 5229 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed 5230 { 5231 public: 5232 5233 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) : 5234 CommandObjectParsed (interpreter, 5235 name, 5236 help, 5237 syntax), 5238 m_enable (enable) 5239 { 5240 } 5241 5242 ~CommandObjectTargetStopHookEnableDisable () 5243 { 5244 } 5245 5246 protected: 5247 bool 5248 DoExecute (Args& command, CommandReturnObject &result) 5249 { 5250 Target *target = GetSelectedOrDummyTarget(); 5251 if (target) 5252 { 5253 // FIXME: see if we can use the breakpoint id style parser? 5254 size_t num_args = command.GetArgumentCount(); 5255 bool success; 5256 5257 if (num_args == 0) 5258 { 5259 target->SetAllStopHooksActiveState (m_enable); 5260 } 5261 else 5262 { 5263 for (size_t i = 0; i < num_args; i++) 5264 { 5265 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 5266 if (!success) 5267 { 5268 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5269 result.SetStatus(eReturnStatusFailed); 5270 return false; 5271 } 5272 success = target->SetStopHookActiveStateByID (user_id, m_enable); 5273 if (!success) 5274 { 5275 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5276 result.SetStatus(eReturnStatusFailed); 5277 return false; 5278 } 5279 } 5280 } 5281 result.SetStatus (eReturnStatusSuccessFinishNoResult); 5282 } 5283 else 5284 { 5285 result.AppendError ("invalid target\n"); 5286 result.SetStatus (eReturnStatusFailed); 5287 } 5288 return result.Succeeded(); 5289 } 5290 private: 5291 bool m_enable; 5292 }; 5293 5294 #pragma mark CommandObjectTargetStopHookList 5295 5296 //------------------------------------------------------------------------- 5297 // CommandObjectTargetStopHookList 5298 //------------------------------------------------------------------------- 5299 5300 class CommandObjectTargetStopHookList : public CommandObjectParsed 5301 { 5302 public: 5303 5304 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) : 5305 CommandObjectParsed (interpreter, 5306 "target stop-hook list", 5307 "List all stop-hooks.", 5308 "target stop-hook list [<type>]") 5309 { 5310 } 5311 5312 ~CommandObjectTargetStopHookList () 5313 { 5314 } 5315 5316 protected: 5317 bool 5318 DoExecute (Args& command, CommandReturnObject &result) 5319 { 5320 Target *target = GetSelectedOrDummyTarget(); 5321 if (!target) 5322 { 5323 result.AppendError ("invalid target\n"); 5324 result.SetStatus (eReturnStatusFailed); 5325 return result.Succeeded(); 5326 } 5327 5328 size_t num_hooks = target->GetNumStopHooks (); 5329 if (num_hooks == 0) 5330 { 5331 result.GetOutputStream().PutCString ("No stop hooks.\n"); 5332 } 5333 else 5334 { 5335 for (size_t i = 0; i < num_hooks; i++) 5336 { 5337 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i); 5338 if (i > 0) 5339 result.GetOutputStream().PutCString ("\n"); 5340 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull); 5341 } 5342 } 5343 result.SetStatus (eReturnStatusSuccessFinishResult); 5344 return result.Succeeded(); 5345 } 5346 }; 5347 5348 #pragma mark CommandObjectMultiwordTargetStopHooks 5349 //------------------------------------------------------------------------- 5350 // CommandObjectMultiwordTargetStopHooks 5351 //------------------------------------------------------------------------- 5352 5353 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword 5354 { 5355 public: 5356 5357 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) : 5358 CommandObjectMultiword (interpreter, 5359 "target stop-hook", 5360 "A set of commands for operating on debugger target stop-hooks.", 5361 "target stop-hook <subcommand> [<subcommand-options>]") 5362 { 5363 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter))); 5364 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter))); 5365 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 5366 false, 5367 "target stop-hook disable [<id>]", 5368 "Disable a stop-hook.", 5369 "target stop-hook disable"))); 5370 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 5371 true, 5372 "target stop-hook enable [<id>]", 5373 "Enable a stop-hook.", 5374 "target stop-hook enable"))); 5375 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter))); 5376 } 5377 5378 ~CommandObjectMultiwordTargetStopHooks() 5379 { 5380 } 5381 }; 5382 5383 5384 5385 #pragma mark CommandObjectMultiwordTarget 5386 5387 //------------------------------------------------------------------------- 5388 // CommandObjectMultiwordTarget 5389 //------------------------------------------------------------------------- 5390 5391 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) : 5392 CommandObjectMultiword (interpreter, 5393 "target", 5394 "A set of commands for operating on debugger targets.", 5395 "target <subcommand> [<subcommand-options>]") 5396 { 5397 5398 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter))); 5399 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter))); 5400 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter))); 5401 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter))); 5402 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter))); 5403 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter))); 5404 LoadSubCommand ("symbols", CommandObjectSP (new CommandObjectTargetSymbols (interpreter))); 5405 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter))); 5406 } 5407 5408 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () 5409 { 5410 } 5411 5412 5413