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