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