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