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