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.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str()); 2581 result.SetStatus (eReturnStatusFailed); 2582 } 2583 else 2584 { 2585 // Dump specified images (by basename or fullpath) 2586 const char *arg_cstr; 2587 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 2588 { 2589 FileSpec file_spec(arg_cstr, false); 2590 2591 const ModuleList &target_modules = target->GetImages(); 2592 Mutex::Locker modules_locker(target_modules.GetMutex()); 2593 const size_t num_modules = target_modules.GetSize(); 2594 if (num_modules > 0) 2595 { 2596 uint32_t num_dumped = 0; 2597 for (uint32_t i = 0; i<num_modules; ++i) 2598 { 2599 if (DumpCompileUnitLineTable (m_interpreter, 2600 result.GetOutputStream(), 2601 target_modules.GetModulePointerAtIndexUnlocked(i), 2602 file_spec, 2603 m_exe_ctx.GetProcessPtr() && m_exe_ctx.GetProcessRef().IsAlive())) 2604 num_dumped++; 2605 } 2606 if (num_dumped == 0) 2607 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr); 2608 else 2609 total_num_dumped += num_dumped; 2610 } 2611 } 2612 } 2613 2614 if (total_num_dumped > 0) 2615 result.SetStatus (eReturnStatusSuccessFinishResult); 2616 else 2617 { 2618 result.AppendError ("no source filenames matched any command arguments"); 2619 result.SetStatus (eReturnStatusFailed); 2620 } 2621 return result.Succeeded(); 2622 } 2623 }; 2624 2625 2626 #pragma mark CommandObjectTargetModulesDump 2627 2628 //---------------------------------------------------------------------- 2629 // Dump multi-word command for target modules 2630 //---------------------------------------------------------------------- 2631 2632 class CommandObjectTargetModulesDump : public CommandObjectMultiword 2633 { 2634 public: 2635 //------------------------------------------------------------------ 2636 // Constructors and Destructors 2637 //------------------------------------------------------------------ 2638 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) : 2639 CommandObjectMultiword (interpreter, 2640 "target modules dump", 2641 "A set of commands for dumping information about one or more target modules.", 2642 "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]") 2643 { 2644 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter))); 2645 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter))); 2646 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter))); 2647 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter))); 2648 } 2649 2650 ~CommandObjectTargetModulesDump() override 2651 { 2652 } 2653 }; 2654 2655 class CommandObjectTargetModulesAdd : public CommandObjectParsed 2656 { 2657 public: 2658 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) : 2659 CommandObjectParsed (interpreter, 2660 "target modules add", 2661 "Add a new module to the current target's modules.", 2662 "target modules add [<module>]"), 2663 m_option_group (interpreter), 2664 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.") 2665 { 2666 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2667 m_option_group.Append (&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2668 m_option_group.Finalize(); 2669 } 2670 2671 ~CommandObjectTargetModulesAdd () override 2672 { 2673 } 2674 2675 Options * 2676 GetOptions () override 2677 { 2678 return &m_option_group; 2679 } 2680 2681 int 2682 HandleArgumentCompletion (Args &input, 2683 int &cursor_index, 2684 int &cursor_char_position, 2685 OptionElementVector &opt_element_vector, 2686 int match_start_point, 2687 int max_return_elements, 2688 bool &word_complete, 2689 StringList &matches) override 2690 { 2691 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 2692 completion_str.erase (cursor_char_position); 2693 2694 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 2695 CommandCompletions::eDiskFileCompletion, 2696 completion_str.c_str(), 2697 match_start_point, 2698 max_return_elements, 2699 NULL, 2700 word_complete, 2701 matches); 2702 return matches.GetSize(); 2703 } 2704 2705 protected: 2706 OptionGroupOptions m_option_group; 2707 OptionGroupUUID m_uuid_option_group; 2708 OptionGroupFile m_symbol_file; 2709 2710 bool 2711 DoExecute (Args& args, CommandReturnObject &result) override 2712 { 2713 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2714 if (target == NULL) 2715 { 2716 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2717 result.SetStatus (eReturnStatusFailed); 2718 return false; 2719 } 2720 else 2721 { 2722 bool flush = false; 2723 2724 const size_t argc = args.GetArgumentCount(); 2725 if (argc == 0) 2726 { 2727 if (m_uuid_option_group.GetOptionValue ().OptionWasSet()) 2728 { 2729 // We are given a UUID only, go locate the file 2730 ModuleSpec module_spec; 2731 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue(); 2732 if (m_symbol_file.GetOptionValue().OptionWasSet()) 2733 module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue(); 2734 if (Symbols::DownloadObjectAndSymbolFile (module_spec)) 2735 { 2736 ModuleSP module_sp (target->GetSharedModule (module_spec)); 2737 if (module_sp) 2738 { 2739 result.SetStatus (eReturnStatusSuccessFinishResult); 2740 return true; 2741 } 2742 else 2743 { 2744 StreamString strm; 2745 module_spec.GetUUID().Dump (&strm); 2746 if (module_spec.GetFileSpec()) 2747 { 2748 if (module_spec.GetSymbolFileSpec()) 2749 { 2750 result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s and symbol file %s", 2751 strm.GetString().c_str(), 2752 module_spec.GetFileSpec().GetPath().c_str(), 2753 module_spec.GetSymbolFileSpec().GetPath().c_str()); 2754 } 2755 else 2756 { 2757 result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s with path %s", 2758 strm.GetString().c_str(), 2759 module_spec.GetFileSpec().GetPath().c_str()); 2760 } 2761 } 2762 else 2763 { 2764 result.AppendErrorWithFormat ("Unable to create the executable or symbol file with UUID %s", 2765 strm.GetString().c_str()); 2766 } 2767 result.SetStatus (eReturnStatusFailed); 2768 return false; 2769 } 2770 } 2771 else 2772 { 2773 StreamString strm; 2774 module_spec.GetUUID().Dump (&strm); 2775 result.AppendErrorWithFormat ("Unable to locate the executable or symbol file with UUID %s", strm.GetString().c_str()); 2776 result.SetStatus (eReturnStatusFailed); 2777 return false; 2778 } 2779 } 2780 else 2781 { 2782 result.AppendError ("one or more executable image paths must be specified"); 2783 result.SetStatus (eReturnStatusFailed); 2784 return false; 2785 } 2786 } 2787 else 2788 { 2789 for (size_t i=0; i<argc; ++i) 2790 { 2791 const char *path = args.GetArgumentAtIndex(i); 2792 if (path) 2793 { 2794 FileSpec file_spec(path, true); 2795 if (file_spec.Exists()) 2796 { 2797 ModuleSpec module_spec (file_spec); 2798 if (m_uuid_option_group.GetOptionValue ().OptionWasSet()) 2799 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue ().GetCurrentValue(); 2800 if (m_symbol_file.GetOptionValue().OptionWasSet()) 2801 module_spec.GetSymbolFileSpec() = m_symbol_file.GetOptionValue().GetCurrentValue(); 2802 if (!module_spec.GetArchitecture().IsValid()) 2803 module_spec.GetArchitecture() = target->GetArchitecture(); 2804 Error error; 2805 ModuleSP module_sp (target->GetSharedModule (module_spec, &error)); 2806 if (!module_sp) 2807 { 2808 const char *error_cstr = error.AsCString(); 2809 if (error_cstr) 2810 result.AppendError (error_cstr); 2811 else 2812 result.AppendErrorWithFormat ("unsupported module: %s", path); 2813 result.SetStatus (eReturnStatusFailed); 2814 return false; 2815 } 2816 else 2817 { 2818 flush = true; 2819 } 2820 result.SetStatus (eReturnStatusSuccessFinishResult); 2821 } 2822 else 2823 { 2824 char resolved_path[PATH_MAX]; 2825 result.SetStatus (eReturnStatusFailed); 2826 if (file_spec.GetPath (resolved_path, sizeof(resolved_path))) 2827 { 2828 if (strcmp (resolved_path, path) != 0) 2829 { 2830 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path); 2831 break; 2832 } 2833 } 2834 result.AppendErrorWithFormat ("invalid module path '%s'\n", path); 2835 break; 2836 } 2837 } 2838 } 2839 } 2840 2841 if (flush) 2842 { 2843 ProcessSP process = target->GetProcessSP(); 2844 if (process) 2845 process->Flush(); 2846 } 2847 } 2848 2849 return result.Succeeded(); 2850 } 2851 2852 }; 2853 2854 class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete 2855 { 2856 public: 2857 CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) : 2858 CommandObjectTargetModulesModuleAutoComplete (interpreter, 2859 "target modules load", 2860 "Set the load addresses for one or more sections in a target module.", 2861 "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"), 2862 m_option_group (interpreter), 2863 m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName, "Fullpath or basename for module to load.", ""), 2864 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset, "Set the load address for all sections to be the virtual address in the file plus the offset.", 0) 2865 { 2866 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2867 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2868 m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2869 m_option_group.Finalize(); 2870 } 2871 2872 ~CommandObjectTargetModulesLoad () override 2873 { 2874 } 2875 2876 Options * 2877 GetOptions () override 2878 { 2879 return &m_option_group; 2880 } 2881 2882 protected: 2883 bool 2884 DoExecute (Args& args, CommandReturnObject &result) override 2885 { 2886 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 2887 if (target == NULL) 2888 { 2889 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 2890 result.SetStatus (eReturnStatusFailed); 2891 return false; 2892 } 2893 else 2894 { 2895 const size_t argc = args.GetArgumentCount(); 2896 ModuleSpec module_spec; 2897 bool search_using_module_spec = false; 2898 if (m_file_option.GetOptionValue().OptionWasSet()) 2899 { 2900 search_using_module_spec = true; 2901 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue(); 2902 const bool use_global_module_list = true; 2903 ModuleList module_list; 2904 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list); 2905 if (num_matches == 1) 2906 { 2907 module_spec.GetFileSpec() = module_list.GetModuleAtIndex(0)->GetFileSpec(); 2908 } 2909 else if (num_matches > 1 ) 2910 { 2911 search_using_module_spec = false; 2912 result.AppendErrorWithFormat ("more than 1 module matched by name '%s'\n", arg_cstr); 2913 result.SetStatus (eReturnStatusFailed); 2914 } 2915 else 2916 { 2917 search_using_module_spec = false; 2918 result.AppendErrorWithFormat ("no object file for module '%s'\n", arg_cstr); 2919 result.SetStatus (eReturnStatusFailed); 2920 } 2921 } 2922 2923 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) 2924 { 2925 search_using_module_spec = true; 2926 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2927 } 2928 2929 if (search_using_module_spec) 2930 { 2931 ModuleList matching_modules; 2932 const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules); 2933 2934 char path[PATH_MAX]; 2935 if (num_matches == 1) 2936 { 2937 Module *module = matching_modules.GetModulePointerAtIndex(0); 2938 if (module) 2939 { 2940 ObjectFile *objfile = module->GetObjectFile(); 2941 if (objfile) 2942 { 2943 SectionList *section_list = module->GetSectionList(); 2944 if (section_list) 2945 { 2946 bool changed = false; 2947 if (argc == 0) 2948 { 2949 if (m_slide_option.GetOptionValue().OptionWasSet()) 2950 { 2951 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue(); 2952 const bool slide_is_offset = true; 2953 module->SetLoadAddress (*target, slide, slide_is_offset, changed); 2954 } 2955 else 2956 { 2957 result.AppendError ("one or more section name + load address pair must be specified"); 2958 result.SetStatus (eReturnStatusFailed); 2959 return false; 2960 } 2961 } 2962 else 2963 { 2964 if (m_slide_option.GetOptionValue().OptionWasSet()) 2965 { 2966 result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n"); 2967 result.SetStatus (eReturnStatusFailed); 2968 return false; 2969 } 2970 2971 for (size_t i=0; i<argc; i += 2) 2972 { 2973 const char *sect_name = args.GetArgumentAtIndex(i); 2974 const char *load_addr_cstr = args.GetArgumentAtIndex(i+1); 2975 if (sect_name && load_addr_cstr) 2976 { 2977 ConstString const_sect_name(sect_name); 2978 bool success = false; 2979 addr_t load_addr = StringConvert::ToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success); 2980 if (success) 2981 { 2982 SectionSP section_sp (section_list->FindSectionByName(const_sect_name)); 2983 if (section_sp) 2984 { 2985 if (section_sp->IsThreadSpecific()) 2986 { 2987 result.AppendErrorWithFormat ("thread specific sections are not yet supported (section '%s')\n", sect_name); 2988 result.SetStatus (eReturnStatusFailed); 2989 break; 2990 } 2991 else 2992 { 2993 if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr)) 2994 changed = true; 2995 result.AppendMessageWithFormat("section '%s' loaded at 0x%" PRIx64 "\n", sect_name, load_addr); 2996 } 2997 } 2998 else 2999 { 3000 result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name); 3001 result.SetStatus (eReturnStatusFailed); 3002 break; 3003 } 3004 } 3005 else 3006 { 3007 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr); 3008 result.SetStatus (eReturnStatusFailed); 3009 break; 3010 } 3011 } 3012 else 3013 { 3014 if (sect_name) 3015 result.AppendError ("section names must be followed by a load address.\n"); 3016 else 3017 result.AppendError ("one or more section name + load address pair must be specified.\n"); 3018 result.SetStatus (eReturnStatusFailed); 3019 break; 3020 } 3021 } 3022 } 3023 3024 if (changed) 3025 { 3026 target->ModulesDidLoad (matching_modules); 3027 Process *process = m_exe_ctx.GetProcessPtr(); 3028 if (process) 3029 process->Flush(); 3030 } 3031 } 3032 else 3033 { 3034 module->GetFileSpec().GetPath (path, sizeof(path)); 3035 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path); 3036 result.SetStatus (eReturnStatusFailed); 3037 } 3038 } 3039 else 3040 { 3041 module->GetFileSpec().GetPath (path, sizeof(path)); 3042 result.AppendErrorWithFormat ("no object file for module '%s'\n", path); 3043 result.SetStatus (eReturnStatusFailed); 3044 } 3045 } 3046 else 3047 { 3048 FileSpec *module_spec_file = module_spec.GetFileSpecPtr(); 3049 if (module_spec_file) 3050 { 3051 module_spec_file->GetPath (path, sizeof(path)); 3052 result.AppendErrorWithFormat ("invalid module '%s'.\n", path); 3053 } 3054 else 3055 result.AppendError ("no module spec"); 3056 result.SetStatus (eReturnStatusFailed); 3057 } 3058 } 3059 else 3060 { 3061 std::string uuid_str; 3062 3063 if (module_spec.GetFileSpec()) 3064 module_spec.GetFileSpec().GetPath (path, sizeof(path)); 3065 else 3066 path[0] = '\0'; 3067 3068 if (module_spec.GetUUIDPtr()) 3069 uuid_str = module_spec.GetUUID().GetAsString(); 3070 if (num_matches > 1) 3071 { 3072 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n", 3073 path[0] ? " file=" : "", 3074 path, 3075 !uuid_str.empty() ? " uuid=" : "", 3076 uuid_str.c_str()); 3077 for (size_t i=0; i<num_matches; ++i) 3078 { 3079 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path))) 3080 result.AppendMessageWithFormat("%s\n", path); 3081 } 3082 } 3083 else 3084 { 3085 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n", 3086 path[0] ? " file=" : "", 3087 path, 3088 !uuid_str.empty() ? " uuid=" : "", 3089 uuid_str.c_str()); 3090 } 3091 result.SetStatus (eReturnStatusFailed); 3092 } 3093 } 3094 else 3095 { 3096 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n"); 3097 result.SetStatus (eReturnStatusFailed); 3098 return false; 3099 } 3100 } 3101 return result.Succeeded(); 3102 } 3103 3104 OptionGroupOptions m_option_group; 3105 OptionGroupUUID m_uuid_option_group; 3106 OptionGroupString m_file_option; 3107 OptionGroupUInt64 m_slide_option; 3108 }; 3109 3110 //---------------------------------------------------------------------- 3111 // List images with associated information 3112 //---------------------------------------------------------------------- 3113 class CommandObjectTargetModulesList : public CommandObjectParsed 3114 { 3115 public: 3116 class CommandOptions : public Options 3117 { 3118 public: 3119 CommandOptions (CommandInterpreter &interpreter) : 3120 Options(interpreter), 3121 m_format_array(), 3122 m_use_global_module_list (false), 3123 m_module_addr (LLDB_INVALID_ADDRESS) 3124 { 3125 } 3126 3127 ~CommandOptions () override 3128 { 3129 } 3130 3131 Error 3132 SetOptionValue (uint32_t option_idx, const char *option_arg) override 3133 { 3134 Error error; 3135 3136 const int short_option = m_getopt_table[option_idx].val; 3137 if (short_option == 'g') 3138 { 3139 m_use_global_module_list = true; 3140 } 3141 else if (short_option == 'a') 3142 { 3143 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 3144 m_module_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 3145 } 3146 else 3147 { 3148 unsigned long width = 0; 3149 if (option_arg) 3150 width = strtoul (option_arg, NULL, 0); 3151 m_format_array.push_back(std::make_pair(short_option, width)); 3152 } 3153 return error; 3154 } 3155 3156 void 3157 OptionParsingStarting () override 3158 { 3159 m_format_array.clear(); 3160 m_use_global_module_list = false; 3161 m_module_addr = LLDB_INVALID_ADDRESS; 3162 } 3163 3164 const OptionDefinition* 3165 GetDefinitions () override 3166 { 3167 return g_option_table; 3168 } 3169 3170 // Options table: Required for subclasses of Options. 3171 3172 static OptionDefinition g_option_table[]; 3173 3174 // Instance variables to hold the values for command options. 3175 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection; 3176 FormatWidthCollection m_format_array; 3177 bool m_use_global_module_list; 3178 lldb::addr_t m_module_addr; 3179 }; 3180 3181 CommandObjectTargetModulesList (CommandInterpreter &interpreter) : 3182 CommandObjectParsed (interpreter, 3183 "target modules list", 3184 "List current executable and dependent shared library images.", 3185 "target modules list [<cmd-options>]"), 3186 m_options (interpreter) 3187 { 3188 } 3189 3190 ~CommandObjectTargetModulesList () override 3191 { 3192 } 3193 3194 Options * 3195 GetOptions () override 3196 { 3197 return &m_options; 3198 } 3199 3200 protected: 3201 bool 3202 DoExecute (Args& command, CommandReturnObject &result) override 3203 { 3204 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 3205 const bool use_global_module_list = m_options.m_use_global_module_list; 3206 // Define a local module list here to ensure it lives longer than any "locker" 3207 // object which might lock its contents below (through the "module_list_ptr" 3208 // variable). 3209 ModuleList module_list; 3210 if (target == NULL && use_global_module_list == false) 3211 { 3212 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 3213 result.SetStatus (eReturnStatusFailed); 3214 return false; 3215 } 3216 else 3217 { 3218 if (target) 3219 { 3220 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 3221 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 3222 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 3223 } 3224 // Dump all sections for all modules images 3225 Stream &strm = result.GetOutputStream(); 3226 3227 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) 3228 { 3229 if (target) 3230 { 3231 Address module_address; 3232 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) 3233 { 3234 ModuleSP module_sp (module_address.GetModule()); 3235 if (module_sp) 3236 { 3237 PrintModule (target, module_sp.get(), 0, strm); 3238 result.SetStatus (eReturnStatusSuccessFinishResult); 3239 } 3240 else 3241 { 3242 result.AppendErrorWithFormat ("Couldn't find module matching address: 0x%" PRIx64 ".", m_options.m_module_addr); 3243 result.SetStatus (eReturnStatusFailed); 3244 } 3245 } 3246 else 3247 { 3248 result.AppendErrorWithFormat ("Couldn't find module containing address: 0x%" PRIx64 ".", m_options.m_module_addr); 3249 result.SetStatus (eReturnStatusFailed); 3250 } 3251 } 3252 else 3253 { 3254 result.AppendError ("Can only look up modules by address with a valid target."); 3255 result.SetStatus (eReturnStatusFailed); 3256 } 3257 return result.Succeeded(); 3258 } 3259 3260 size_t num_modules = 0; 3261 Mutex::Locker locker; // This locker will be locked on the mutex in module_list_ptr if it is non-NULL. 3262 // Otherwise it will lock the AllocationModuleCollectionMutex when accessing 3263 // the global module list directly. 3264 const ModuleList *module_list_ptr = NULL; 3265 const size_t argc = command.GetArgumentCount(); 3266 if (argc == 0) 3267 { 3268 if (use_global_module_list) 3269 { 3270 locker.Lock (Module::GetAllocationModuleCollectionMutex()); 3271 num_modules = Module::GetNumberAllocatedModules(); 3272 } 3273 else 3274 { 3275 module_list_ptr = &target->GetImages(); 3276 } 3277 } 3278 else 3279 { 3280 for (size_t i=0; i<argc; ++i) 3281 { 3282 // Dump specified images (by basename or fullpath) 3283 const char *arg_cstr = command.GetArgumentAtIndex(i); 3284 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list); 3285 if (num_matches == 0) 3286 { 3287 if (argc == 1) 3288 { 3289 result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr); 3290 result.SetStatus (eReturnStatusFailed); 3291 return false; 3292 } 3293 } 3294 } 3295 3296 module_list_ptr = &module_list; 3297 } 3298 3299 if (module_list_ptr != NULL) 3300 { 3301 locker.Lock(module_list_ptr->GetMutex()); 3302 num_modules = module_list_ptr->GetSize(); 3303 } 3304 3305 if (num_modules > 0) 3306 { 3307 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx) 3308 { 3309 ModuleSP module_sp; 3310 Module *module; 3311 if (module_list_ptr) 3312 { 3313 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx); 3314 module = module_sp.get(); 3315 } 3316 else 3317 { 3318 module = Module::GetAllocatedModuleAtIndex(image_idx); 3319 module_sp = module->shared_from_this(); 3320 } 3321 3322 const size_t indent = strm.Printf("[%3u] ", image_idx); 3323 PrintModule (target, module, indent, strm); 3324 3325 } 3326 result.SetStatus (eReturnStatusSuccessFinishResult); 3327 } 3328 else 3329 { 3330 if (argc) 3331 { 3332 if (use_global_module_list) 3333 result.AppendError ("the global module list has no matching modules"); 3334 else 3335 result.AppendError ("the target has no matching modules"); 3336 } 3337 else 3338 { 3339 if (use_global_module_list) 3340 result.AppendError ("the global module list is empty"); 3341 else 3342 result.AppendError ("the target has no associated executable images"); 3343 } 3344 result.SetStatus (eReturnStatusFailed); 3345 return false; 3346 } 3347 } 3348 return result.Succeeded(); 3349 } 3350 3351 void 3352 PrintModule (Target *target, Module *module, int indent, Stream &strm) 3353 { 3354 3355 if (module == NULL) 3356 { 3357 strm.PutCString("Null module"); 3358 return; 3359 } 3360 3361 bool dump_object_name = false; 3362 if (m_options.m_format_array.empty()) 3363 { 3364 m_options.m_format_array.push_back(std::make_pair('u', 0)); 3365 m_options.m_format_array.push_back(std::make_pair('h', 0)); 3366 m_options.m_format_array.push_back(std::make_pair('f', 0)); 3367 m_options.m_format_array.push_back(std::make_pair('S', 0)); 3368 } 3369 const size_t num_entries = m_options.m_format_array.size(); 3370 bool print_space = false; 3371 for (size_t i=0; i<num_entries; ++i) 3372 { 3373 if (print_space) 3374 strm.PutChar(' '); 3375 print_space = true; 3376 const char format_char = m_options.m_format_array[i].first; 3377 uint32_t width = m_options.m_format_array[i].second; 3378 switch (format_char) 3379 { 3380 case 'A': 3381 DumpModuleArchitecture (strm, module, false, width); 3382 break; 3383 3384 case 't': 3385 DumpModuleArchitecture (strm, module, true, width); 3386 break; 3387 3388 case 'f': 3389 DumpFullpath (strm, &module->GetFileSpec(), width); 3390 dump_object_name = true; 3391 break; 3392 3393 case 'd': 3394 DumpDirectory (strm, &module->GetFileSpec(), width); 3395 break; 3396 3397 case 'b': 3398 DumpBasename (strm, &module->GetFileSpec(), width); 3399 dump_object_name = true; 3400 break; 3401 3402 case 'h': 3403 case 'o': 3404 // Image header address 3405 { 3406 uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16; 3407 3408 ObjectFile *objfile = module->GetObjectFile (); 3409 if (objfile) 3410 { 3411 Address header_addr(objfile->GetHeaderAddress()); 3412 if (header_addr.IsValid()) 3413 { 3414 if (target && !target->GetSectionLoadList().IsEmpty()) 3415 { 3416 lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target); 3417 if (header_load_addr == LLDB_INVALID_ADDRESS) 3418 { 3419 header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress); 3420 } 3421 else 3422 { 3423 if (format_char == 'o') 3424 { 3425 // Show the offset of slide for the image 3426 strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress()); 3427 } 3428 else 3429 { 3430 // Show the load address of the image 3431 strm.Printf ("0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width, header_load_addr); 3432 } 3433 } 3434 break; 3435 } 3436 // The address was valid, but the image isn't loaded, output the address in an appropriate format 3437 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress); 3438 break; 3439 } 3440 } 3441 strm.Printf ("%*s", addr_nibble_width + 2, ""); 3442 } 3443 break; 3444 case 'r': 3445 { 3446 size_t ref_count = 0; 3447 ModuleSP module_sp (module->shared_from_this()); 3448 if (module_sp) 3449 { 3450 // Take one away to make sure we don't count our local "module_sp" 3451 ref_count = module_sp.use_count() - 1; 3452 } 3453 if (width) 3454 strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count); 3455 else 3456 strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count); 3457 } 3458 break; 3459 3460 case 's': 3461 case 'S': 3462 { 3463 const SymbolVendor *symbol_vendor = module->GetSymbolVendor(); 3464 if (symbol_vendor) 3465 { 3466 const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec(); 3467 if (format_char == 'S') 3468 { 3469 // Dump symbol file only if different from module file 3470 if (!symfile_spec || symfile_spec == module->GetFileSpec()) 3471 { 3472 print_space = false; 3473 break; 3474 } 3475 // Add a newline and indent past the index 3476 strm.Printf ("\n%*s", indent, ""); 3477 } 3478 DumpFullpath (strm, &symfile_spec, width); 3479 dump_object_name = true; 3480 break; 3481 } 3482 strm.Printf("%.*s", width, "<NONE>"); 3483 } 3484 break; 3485 3486 case 'm': 3487 module->GetModificationTime().Dump(&strm, width); 3488 break; 3489 3490 case 'p': 3491 strm.Printf("%p", static_cast<void*>(module)); 3492 break; 3493 3494 case 'u': 3495 DumpModuleUUID(strm, module); 3496 break; 3497 3498 default: 3499 break; 3500 } 3501 3502 } 3503 if (dump_object_name) 3504 { 3505 const char *object_name = module->GetObjectName().GetCString(); 3506 if (object_name) 3507 strm.Printf ("(%s)", object_name); 3508 } 3509 strm.EOL(); 3510 } 3511 3512 CommandOptions m_options; 3513 }; 3514 3515 OptionDefinition 3516 CommandObjectTargetModulesList::CommandOptions::g_option_table[] = 3517 { 3518 { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Display the image at this address."}, 3519 { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."}, 3520 { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the triple when listing images."}, 3521 { 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."}, 3522 { 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)."}, 3523 { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Display the UUID when listing images."}, 3524 { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."}, 3525 { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."}, 3526 { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."}, 3527 { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."}, 3528 { 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."}, 3529 { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."}, 3530 { 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."}, 3531 { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, NULL, NULL, 0, eArgTypeNone, "Display the module pointer."}, 3532 { 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."}, 3533 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3534 }; 3535 3536 #pragma mark CommandObjectTargetModulesShowUnwind 3537 3538 //---------------------------------------------------------------------- 3539 // Lookup unwind information in images 3540 //---------------------------------------------------------------------- 3541 3542 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed 3543 { 3544 public: 3545 3546 enum 3547 { 3548 eLookupTypeInvalid = -1, 3549 eLookupTypeAddress = 0, 3550 eLookupTypeSymbol, 3551 eLookupTypeFunction, 3552 eLookupTypeFunctionOrSymbol, 3553 kNumLookupTypes 3554 }; 3555 3556 class CommandOptions : public Options 3557 { 3558 public: 3559 3560 CommandOptions (CommandInterpreter &interpreter) : 3561 Options(interpreter), 3562 m_type(eLookupTypeInvalid), 3563 m_str(), 3564 m_addr(LLDB_INVALID_ADDRESS) 3565 { 3566 } 3567 3568 ~CommandOptions () override 3569 { 3570 } 3571 3572 Error 3573 SetOptionValue (uint32_t option_idx, const char *option_arg) override 3574 { 3575 Error error; 3576 3577 const int short_option = m_getopt_table[option_idx].val; 3578 3579 switch (short_option) 3580 { 3581 case 'a': 3582 { 3583 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 3584 m_str = option_arg; 3585 m_type = eLookupTypeAddress; 3586 m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 3587 if (m_addr == LLDB_INVALID_ADDRESS) 3588 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg); 3589 break; 3590 } 3591 3592 case 'n': 3593 { 3594 m_str = option_arg; 3595 m_type = eLookupTypeFunctionOrSymbol; 3596 break; 3597 } 3598 3599 default: 3600 error.SetErrorStringWithFormat ("unrecognized option %c.", short_option); 3601 break; 3602 } 3603 3604 return error; 3605 } 3606 3607 void 3608 OptionParsingStarting () override 3609 { 3610 m_type = eLookupTypeInvalid; 3611 m_str.clear(); 3612 m_addr = LLDB_INVALID_ADDRESS; 3613 } 3614 3615 const OptionDefinition* 3616 GetDefinitions () override 3617 { 3618 return g_option_table; 3619 } 3620 3621 // Options table: Required for subclasses of Options. 3622 3623 static OptionDefinition g_option_table[]; 3624 3625 // Instance variables to hold the values for command options. 3626 3627 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3628 std::string m_str; // Holds name lookup 3629 lldb::addr_t m_addr; // Holds the address to lookup 3630 }; 3631 3632 CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) : 3633 CommandObjectParsed (interpreter, 3634 "target modules show-unwind", 3635 "Show synthesized unwind instructions for a function.", 3636 NULL, 3637 eCommandRequiresTarget | 3638 eCommandRequiresProcess | 3639 eCommandProcessMustBeLaunched | 3640 eCommandProcessMustBePaused ), 3641 m_options (interpreter) 3642 { 3643 } 3644 3645 ~CommandObjectTargetModulesShowUnwind () override 3646 { 3647 } 3648 3649 Options * 3650 GetOptions () override 3651 { 3652 return &m_options; 3653 } 3654 3655 protected: 3656 bool 3657 DoExecute (Args& command, CommandReturnObject &result) override 3658 { 3659 Target *target = m_exe_ctx.GetTargetPtr(); 3660 Process *process = m_exe_ctx.GetProcessPtr(); 3661 ABI *abi = NULL; 3662 if (process) 3663 abi = process->GetABI().get(); 3664 3665 if (process == NULL) 3666 { 3667 result.AppendError ("You must have a process running to use this command."); 3668 result.SetStatus (eReturnStatusFailed); 3669 return false; 3670 } 3671 3672 ThreadList threads(process->GetThreadList()); 3673 if (threads.GetSize() == 0) 3674 { 3675 result.AppendError ("The process must be paused to use this command."); 3676 result.SetStatus (eReturnStatusFailed); 3677 return false; 3678 } 3679 3680 ThreadSP thread(threads.GetThreadAtIndex(0)); 3681 if (thread.get() == NULL) 3682 { 3683 result.AppendError ("The process must be paused to use this command."); 3684 result.SetStatus (eReturnStatusFailed); 3685 return false; 3686 } 3687 3688 SymbolContextList sc_list; 3689 3690 if (m_options.m_type == eLookupTypeFunctionOrSymbol) 3691 { 3692 ConstString function_name (m_options.m_str.c_str()); 3693 target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list); 3694 } 3695 else if (m_options.m_type == eLookupTypeAddress && target) 3696 { 3697 Address addr; 3698 if (target->GetSectionLoadList().ResolveLoadAddress (m_options.m_addr, addr)) 3699 { 3700 SymbolContext sc; 3701 ModuleSP module_sp (addr.GetModule()); 3702 module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextEverything, sc); 3703 if (sc.function || sc.symbol) 3704 { 3705 sc_list.Append(sc); 3706 } 3707 } 3708 } 3709 else 3710 { 3711 result.AppendError ("address-expression or function name option must be specified."); 3712 result.SetStatus (eReturnStatusFailed); 3713 return false; 3714 } 3715 3716 size_t num_matches = sc_list.GetSize(); 3717 if (num_matches == 0) 3718 { 3719 result.AppendErrorWithFormat ("no unwind data found that matches '%s'.", m_options.m_str.c_str()); 3720 result.SetStatus (eReturnStatusFailed); 3721 return false; 3722 } 3723 3724 for (uint32_t idx = 0; idx < num_matches; idx++) 3725 { 3726 SymbolContext sc; 3727 sc_list.GetContextAtIndex(idx, sc); 3728 if (sc.symbol == NULL && sc.function == NULL) 3729 continue; 3730 if (sc.module_sp.get() == NULL || sc.module_sp->GetObjectFile() == NULL) 3731 continue; 3732 AddressRange range; 3733 if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range)) 3734 continue; 3735 if (!range.GetBaseAddress().IsValid()) 3736 continue; 3737 ConstString funcname(sc.GetFunctionName()); 3738 if (funcname.IsEmpty()) 3739 continue; 3740 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target); 3741 if (abi) 3742 start_addr = abi->FixCodeAddress(start_addr); 3743 3744 FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc)); 3745 if (func_unwinders_sp.get() == NULL) 3746 continue; 3747 3748 result.GetOutputStream().Printf("UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr); 3749 3750 UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread.get(), -1); 3751 if (non_callsite_unwind_plan.get()) 3752 { 3753 result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n", non_callsite_unwind_plan->GetSourceName().AsCString()); 3754 } 3755 UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1); 3756 if (callsite_unwind_plan.get()) 3757 { 3758 result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", callsite_unwind_plan->GetSourceName().AsCString()); 3759 } 3760 UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread.get()); 3761 if (fast_unwind_plan.get()) 3762 { 3763 result.GetOutputStream().Printf("Fast UnwindPlan is '%s'\n", fast_unwind_plan->GetSourceName().AsCString()); 3764 } 3765 3766 result.GetOutputStream().Printf("\n"); 3767 3768 UnwindPlanSP assembly_sp = func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread.get(), 0); 3769 if (assembly_sp) 3770 { 3771 result.GetOutputStream().Printf("Assembly language inspection UnwindPlan:\n"); 3772 assembly_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3773 result.GetOutputStream().Printf("\n"); 3774 } 3775 3776 3777 UnwindPlanSP ehframe_sp = func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0); 3778 if (ehframe_sp) 3779 { 3780 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n"); 3781 ehframe_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3782 result.GetOutputStream().Printf("\n"); 3783 } 3784 3785 UnwindPlanSP ehframe_augmented_sp = func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread.get(), 0); 3786 if (ehframe_augmented_sp) 3787 { 3788 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n"); 3789 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3790 result.GetOutputStream().Printf("\n"); 3791 } 3792 3793 UnwindPlanSP arm_unwind_sp = func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0); 3794 if (arm_unwind_sp) 3795 { 3796 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n"); 3797 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3798 result.GetOutputStream().Printf("\n"); 3799 } 3800 3801 UnwindPlanSP compact_unwind_sp = func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0); 3802 if (compact_unwind_sp) 3803 { 3804 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n"); 3805 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3806 result.GetOutputStream().Printf("\n"); 3807 } 3808 3809 if (fast_unwind_plan) 3810 { 3811 result.GetOutputStream().Printf("Fast UnwindPlan:\n"); 3812 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3813 result.GetOutputStream().Printf("\n"); 3814 } 3815 3816 ABISP abi_sp = process->GetABI(); 3817 if (abi_sp) 3818 { 3819 UnwindPlan arch_default(lldb::eRegisterKindGeneric); 3820 if (abi_sp->CreateDefaultUnwindPlan (arch_default)) 3821 { 3822 result.GetOutputStream().Printf("Arch default UnwindPlan:\n"); 3823 arch_default.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3824 result.GetOutputStream().Printf("\n"); 3825 } 3826 3827 UnwindPlan arch_entry(lldb::eRegisterKindGeneric); 3828 if (abi_sp->CreateFunctionEntryUnwindPlan (arch_entry)) 3829 { 3830 result.GetOutputStream().Printf("Arch default at entry point UnwindPlan:\n"); 3831 arch_entry.Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS); 3832 result.GetOutputStream().Printf("\n"); 3833 } 3834 } 3835 3836 result.GetOutputStream().Printf ("\n"); 3837 } 3838 return result.Succeeded(); 3839 } 3840 3841 CommandOptions m_options; 3842 }; 3843 3844 OptionDefinition 3845 CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] = 3846 { 3847 { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."}, 3848 { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"}, 3849 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 3850 }; 3851 3852 //---------------------------------------------------------------------- 3853 // Lookup information in images 3854 //---------------------------------------------------------------------- 3855 class CommandObjectTargetModulesLookup : public CommandObjectParsed 3856 { 3857 public: 3858 enum 3859 { 3860 eLookupTypeInvalid = -1, 3861 eLookupTypeAddress = 0, 3862 eLookupTypeSymbol, 3863 eLookupTypeFileLine, // Line is optional 3864 eLookupTypeFunction, 3865 eLookupTypeFunctionOrSymbol, 3866 eLookupTypeType, 3867 kNumLookupTypes 3868 }; 3869 3870 class CommandOptions : public Options 3871 { 3872 public: 3873 CommandOptions (CommandInterpreter &interpreter) : 3874 Options(interpreter) 3875 { 3876 OptionParsingStarting(); 3877 } 3878 3879 ~CommandOptions () override 3880 { 3881 } 3882 3883 Error 3884 SetOptionValue (uint32_t option_idx, const char *option_arg) override 3885 { 3886 Error error; 3887 3888 const int short_option = m_getopt_table[option_idx].val; 3889 3890 switch (short_option) 3891 { 3892 case 'a': 3893 { 3894 m_type = eLookupTypeAddress; 3895 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext()); 3896 m_addr = Args::StringToAddress(&exe_ctx, option_arg, LLDB_INVALID_ADDRESS, &error); 3897 } 3898 break; 3899 3900 case 'o': 3901 m_offset = StringConvert::ToUInt64(option_arg, LLDB_INVALID_ADDRESS); 3902 if (m_offset == LLDB_INVALID_ADDRESS) 3903 error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg); 3904 break; 3905 3906 case 's': 3907 m_str = option_arg; 3908 m_type = eLookupTypeSymbol; 3909 break; 3910 3911 case 'f': 3912 m_file.SetFile (option_arg, false); 3913 m_type = eLookupTypeFileLine; 3914 break; 3915 3916 case 'i': 3917 m_include_inlines = false; 3918 break; 3919 3920 case 'l': 3921 m_line_number = StringConvert::ToUInt32(option_arg, UINT32_MAX); 3922 if (m_line_number == UINT32_MAX) 3923 error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg); 3924 else if (m_line_number == 0) 3925 error.SetErrorString ("zero is an invalid line number"); 3926 m_type = eLookupTypeFileLine; 3927 break; 3928 3929 case 'F': 3930 m_str = option_arg; 3931 m_type = eLookupTypeFunction; 3932 break; 3933 3934 case 'n': 3935 m_str = option_arg; 3936 m_type = eLookupTypeFunctionOrSymbol; 3937 break; 3938 3939 case 't': 3940 m_str = option_arg; 3941 m_type = eLookupTypeType; 3942 break; 3943 3944 case 'v': 3945 m_verbose = 1; 3946 break; 3947 3948 case 'A': 3949 m_print_all = true; 3950 break; 3951 3952 case 'r': 3953 m_use_regex = true; 3954 break; 3955 } 3956 3957 return error; 3958 } 3959 3960 void 3961 OptionParsingStarting () override 3962 { 3963 m_type = eLookupTypeInvalid; 3964 m_str.clear(); 3965 m_file.Clear(); 3966 m_addr = LLDB_INVALID_ADDRESS; 3967 m_offset = 0; 3968 m_line_number = 0; 3969 m_use_regex = false; 3970 m_include_inlines = true; 3971 m_verbose = false; 3972 m_print_all = false; 3973 } 3974 3975 const OptionDefinition* 3976 GetDefinitions () override 3977 { 3978 return g_option_table; 3979 } 3980 3981 // Options table: Required for subclasses of Options. 3982 3983 static OptionDefinition g_option_table[]; 3984 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3985 std::string m_str; // Holds name lookup 3986 FileSpec m_file; // Files for file lookups 3987 lldb::addr_t m_addr; // Holds the address to lookup 3988 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups. 3989 uint32_t m_line_number; // Line number for file+line lookups 3990 bool m_use_regex; // Name lookups in m_str are regular expressions. 3991 bool m_include_inlines;// Check for inline entries when looking up by file/line. 3992 bool m_verbose; // Enable verbose lookup info 3993 bool m_print_all; // Print all matches, even in cases where there's a best match. 3994 }; 3995 3996 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) : 3997 CommandObjectParsed (interpreter, 3998 "target modules lookup", 3999 "Look up information within executable and dependent shared library images.", 4000 NULL, 4001 eCommandRequiresTarget), 4002 m_options (interpreter) 4003 { 4004 CommandArgumentEntry arg; 4005 CommandArgumentData file_arg; 4006 4007 // Define the first (and only) variant of this arg. 4008 file_arg.arg_type = eArgTypeFilename; 4009 file_arg.arg_repetition = eArgRepeatStar; 4010 4011 // There is only one variant this argument could be; put it into the argument entry. 4012 arg.push_back (file_arg); 4013 4014 // Push the data for the first argument into the m_arguments vector. 4015 m_arguments.push_back (arg); 4016 } 4017 4018 ~CommandObjectTargetModulesLookup () override 4019 { 4020 } 4021 4022 Options * 4023 GetOptions () override 4024 { 4025 return &m_options; 4026 } 4027 4028 bool 4029 LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error) 4030 { 4031 switch (m_options.m_type) 4032 { 4033 case eLookupTypeAddress: 4034 case eLookupTypeFileLine: 4035 case eLookupTypeFunction: 4036 case eLookupTypeFunctionOrSymbol: 4037 case eLookupTypeSymbol: 4038 default: 4039 return false; 4040 case eLookupTypeType: 4041 break; 4042 } 4043 4044 StackFrameSP frame = m_exe_ctx.GetFrameSP(); 4045 4046 if (!frame) 4047 return false; 4048 4049 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule)); 4050 4051 if (!sym_ctx.module_sp) 4052 return false; 4053 4054 switch (m_options.m_type) 4055 { 4056 default: 4057 return false; 4058 case eLookupTypeType: 4059 if (!m_options.m_str.empty()) 4060 { 4061 if (LookupTypeHere (m_interpreter, 4062 result.GetOutputStream(), 4063 sym_ctx, 4064 m_options.m_str.c_str(), 4065 m_options.m_use_regex)) 4066 { 4067 result.SetStatus(eReturnStatusSuccessFinishResult); 4068 return true; 4069 } 4070 } 4071 break; 4072 } 4073 4074 return true; 4075 } 4076 4077 bool 4078 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error) 4079 { 4080 switch (m_options.m_type) 4081 { 4082 case eLookupTypeAddress: 4083 if (m_options.m_addr != LLDB_INVALID_ADDRESS) 4084 { 4085 if (LookupAddressInModule (m_interpreter, 4086 result.GetOutputStream(), 4087 module, 4088 eSymbolContextEverything | (m_options.m_verbose ? eSymbolContextVariable : 0), 4089 m_options.m_addr, 4090 m_options.m_offset, 4091 m_options.m_verbose)) 4092 { 4093 result.SetStatus(eReturnStatusSuccessFinishResult); 4094 return true; 4095 } 4096 } 4097 break; 4098 4099 case eLookupTypeSymbol: 4100 if (!m_options.m_str.empty()) 4101 { 4102 if (LookupSymbolInModule (m_interpreter, 4103 result.GetOutputStream(), 4104 module, 4105 m_options.m_str.c_str(), 4106 m_options.m_use_regex, 4107 m_options.m_verbose)) 4108 { 4109 result.SetStatus(eReturnStatusSuccessFinishResult); 4110 return true; 4111 } 4112 } 4113 break; 4114 4115 case eLookupTypeFileLine: 4116 if (m_options.m_file) 4117 { 4118 if (LookupFileAndLineInModule (m_interpreter, 4119 result.GetOutputStream(), 4120 module, 4121 m_options.m_file, 4122 m_options.m_line_number, 4123 m_options.m_include_inlines, 4124 m_options.m_verbose)) 4125 { 4126 result.SetStatus(eReturnStatusSuccessFinishResult); 4127 return true; 4128 } 4129 } 4130 break; 4131 4132 case eLookupTypeFunctionOrSymbol: 4133 case eLookupTypeFunction: 4134 if (!m_options.m_str.empty()) 4135 { 4136 if (LookupFunctionInModule (m_interpreter, 4137 result.GetOutputStream(), 4138 module, 4139 m_options.m_str.c_str(), 4140 m_options.m_use_regex, 4141 m_options.m_include_inlines, 4142 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols 4143 m_options.m_verbose)) 4144 { 4145 result.SetStatus(eReturnStatusSuccessFinishResult); 4146 return true; 4147 } 4148 } 4149 break; 4150 4151 case eLookupTypeType: 4152 if (!m_options.m_str.empty()) 4153 { 4154 if (LookupTypeInModule (m_interpreter, 4155 result.GetOutputStream(), 4156 module, 4157 m_options.m_str.c_str(), 4158 m_options.m_use_regex)) 4159 { 4160 result.SetStatus(eReturnStatusSuccessFinishResult); 4161 return true; 4162 } 4163 } 4164 break; 4165 4166 default: 4167 m_options.GenerateOptionUsage (result.GetErrorStream(), this); 4168 syntax_error = true; 4169 break; 4170 } 4171 4172 result.SetStatus (eReturnStatusFailed); 4173 return false; 4174 } 4175 4176 protected: 4177 bool 4178 DoExecute (Args& command, CommandReturnObject &result) override 4179 { 4180 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 4181 if (target == NULL) 4182 { 4183 result.AppendError ("invalid target, create a debug target using the 'target create' command"); 4184 result.SetStatus (eReturnStatusFailed); 4185 return false; 4186 } 4187 else 4188 { 4189 bool syntax_error = false; 4190 uint32_t i; 4191 uint32_t num_successful_lookups = 0; 4192 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 4193 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 4194 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 4195 // Dump all sections for all modules images 4196 4197 if (command.GetArgumentCount() == 0) 4198 { 4199 ModuleSP current_module; 4200 4201 // Where it is possible to look in the current symbol context 4202 // first, try that. If this search was successful and --all 4203 // was not passed, don't print anything else. 4204 if (LookupHere (m_interpreter, result, syntax_error)) 4205 { 4206 result.GetOutputStream().EOL(); 4207 num_successful_lookups++; 4208 if (!m_options.m_print_all) 4209 { 4210 result.SetStatus (eReturnStatusSuccessFinishResult); 4211 return result.Succeeded(); 4212 } 4213 } 4214 4215 // Dump all sections for all other modules 4216 4217 const ModuleList &target_modules = target->GetImages(); 4218 Mutex::Locker modules_locker(target_modules.GetMutex()); 4219 const size_t num_modules = target_modules.GetSize(); 4220 if (num_modules > 0) 4221 { 4222 for (i = 0; i<num_modules && syntax_error == false; ++i) 4223 { 4224 Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i); 4225 4226 if (module_pointer != current_module.get() && 4227 LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error)) 4228 { 4229 result.GetOutputStream().EOL(); 4230 num_successful_lookups++; 4231 } 4232 } 4233 } 4234 else 4235 { 4236 result.AppendError ("the target has no associated executable images"); 4237 result.SetStatus (eReturnStatusFailed); 4238 return false; 4239 } 4240 } 4241 else 4242 { 4243 // Dump specified images (by basename or fullpath) 4244 const char *arg_cstr; 4245 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i) 4246 { 4247 ModuleList module_list; 4248 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false); 4249 if (num_matches > 0) 4250 { 4251 for (size_t j=0; j<num_matches; ++j) 4252 { 4253 Module *module = module_list.GetModulePointerAtIndex(j); 4254 if (module) 4255 { 4256 if (LookupInModule (m_interpreter, module, result, syntax_error)) 4257 { 4258 result.GetOutputStream().EOL(); 4259 num_successful_lookups++; 4260 } 4261 } 4262 } 4263 } 4264 else 4265 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr); 4266 } 4267 } 4268 4269 if (num_successful_lookups > 0) 4270 result.SetStatus (eReturnStatusSuccessFinishResult); 4271 else 4272 result.SetStatus (eReturnStatusFailed); 4273 } 4274 return result.Succeeded(); 4275 } 4276 4277 CommandOptions m_options; 4278 }; 4279 4280 OptionDefinition 4281 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] = 4282 { 4283 { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."}, 4284 { 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."}, 4285 { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5 4286 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ , 4287 false, "regex", 'r', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."}, 4288 { 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."}, 4289 { 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."}, 4290 { 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)."}, 4291 { LLDB_OPT_SET_FROM_TO(3,5), 4292 false, "no-inlines", 'i', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."}, 4293 { 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."}, 4294 { 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."}, 4295 { 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."}, 4296 { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable verbose lookup information."}, 4297 { 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."}, 4298 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 4299 }; 4300 4301 4302 #pragma mark CommandObjectMultiwordImageSearchPaths 4303 4304 //------------------------------------------------------------------------- 4305 // CommandObjectMultiwordImageSearchPaths 4306 //------------------------------------------------------------------------- 4307 4308 class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword 4309 { 4310 public: 4311 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) : 4312 CommandObjectMultiword (interpreter, 4313 "target modules search-paths", 4314 "A set of commands for operating on debugger target image search paths.", 4315 "target modules search-paths <subcommand> [<subcommand-options>]") 4316 { 4317 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter))); 4318 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter))); 4319 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter))); 4320 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter))); 4321 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter))); 4322 } 4323 4324 ~CommandObjectTargetModulesImageSearchPaths() override 4325 { 4326 } 4327 }; 4328 4329 4330 4331 #pragma mark CommandObjectTargetModules 4332 4333 //------------------------------------------------------------------------- 4334 // CommandObjectTargetModules 4335 //------------------------------------------------------------------------- 4336 4337 class CommandObjectTargetModules : public CommandObjectMultiword 4338 { 4339 public: 4340 //------------------------------------------------------------------ 4341 // Constructors and Destructors 4342 //------------------------------------------------------------------ 4343 CommandObjectTargetModules(CommandInterpreter &interpreter) : 4344 CommandObjectMultiword (interpreter, 4345 "target modules", 4346 "A set of commands for accessing information for one or more target modules.", 4347 "target modules <sub-command> ...") 4348 { 4349 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter))); 4350 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter))); 4351 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter))); 4352 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter))); 4353 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter))); 4354 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter))); 4355 LoadSubCommand ("show-unwind", CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter))); 4356 4357 } 4358 4359 ~CommandObjectTargetModules() override 4360 { 4361 } 4362 4363 private: 4364 //------------------------------------------------------------------ 4365 // For CommandObjectTargetModules only 4366 //------------------------------------------------------------------ 4367 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules); 4368 }; 4369 4370 4371 4372 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed 4373 { 4374 public: 4375 CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) : 4376 CommandObjectParsed (interpreter, 4377 "target symbols add", 4378 "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.", 4379 "target symbols add [<symfile>]", eCommandRequiresTarget), 4380 m_option_group (interpreter), 4381 m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."), 4382 m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true) 4383 4384 { 4385 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 4386 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 4387 m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2); 4388 m_option_group.Finalize(); 4389 } 4390 4391 ~CommandObjectTargetSymbolsAdd () override 4392 { 4393 } 4394 4395 int 4396 HandleArgumentCompletion (Args &input, 4397 int &cursor_index, 4398 int &cursor_char_position, 4399 OptionElementVector &opt_element_vector, 4400 int match_start_point, 4401 int max_return_elements, 4402 bool &word_complete, 4403 StringList &matches) override 4404 { 4405 std::string completion_str (input.GetArgumentAtIndex(cursor_index)); 4406 completion_str.erase (cursor_char_position); 4407 4408 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter, 4409 CommandCompletions::eDiskFileCompletion, 4410 completion_str.c_str(), 4411 match_start_point, 4412 max_return_elements, 4413 NULL, 4414 word_complete, 4415 matches); 4416 return matches.GetSize(); 4417 } 4418 4419 Options * 4420 GetOptions () override 4421 { 4422 return &m_option_group; 4423 } 4424 4425 protected: 4426 bool 4427 AddModuleSymbols (Target *target, 4428 ModuleSpec &module_spec, 4429 bool &flush, 4430 CommandReturnObject &result) 4431 { 4432 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec(); 4433 if (symbol_fspec) 4434 { 4435 char symfile_path[PATH_MAX]; 4436 symbol_fspec.GetPath (symfile_path, sizeof(symfile_path)); 4437 4438 if (!module_spec.GetUUID().IsValid()) 4439 { 4440 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec()) 4441 module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename(); 4442 } 4443 // We now have a module that represents a symbol file 4444 // that can be used for a module that might exist in the 4445 // current target, so we need to find that module in the 4446 // target 4447 ModuleList matching_module_list; 4448 4449 size_t num_matches = 0; 4450 // First extract all module specs from the symbol file 4451 lldb_private::ModuleSpecList symfile_module_specs; 4452 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), 0, 0, symfile_module_specs)) 4453 { 4454 // Now extract the module spec that matches the target architecture 4455 ModuleSpec target_arch_module_spec; 4456 ModuleSpec symfile_module_spec; 4457 target_arch_module_spec.GetArchitecture() = target->GetArchitecture(); 4458 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, symfile_module_spec)) 4459 { 4460 // See if it has a UUID? 4461 if (symfile_module_spec.GetUUID().IsValid()) 4462 { 4463 // It has a UUID, look for this UUID in the target modules 4464 ModuleSpec symfile_uuid_module_spec; 4465 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); 4466 num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list); 4467 } 4468 } 4469 4470 if (num_matches == 0) 4471 { 4472 // No matches yet, iterate through the module specs to find a UUID value that 4473 // we can match up to an image in our target 4474 const size_t num_symfile_module_specs = symfile_module_specs.GetSize(); 4475 for (size_t i=0; i<num_symfile_module_specs && num_matches == 0; ++i) 4476 { 4477 if (symfile_module_specs.GetModuleSpecAtIndex(i, symfile_module_spec)) 4478 { 4479 if (symfile_module_spec.GetUUID().IsValid()) 4480 { 4481 // It has a UUID, look for this UUID in the target modules 4482 ModuleSpec symfile_uuid_module_spec; 4483 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); 4484 num_matches = target->GetImages().FindModules (symfile_uuid_module_spec, matching_module_list); 4485 } 4486 } 4487 } 4488 } 4489 } 4490 4491 // Just try to match up the file by basename if we have no matches at this point 4492 if (num_matches == 0) 4493 num_matches = target->GetImages().FindModules (module_spec, matching_module_list); 4494 4495 while (num_matches == 0) 4496 { 4497 ConstString filename_no_extension(module_spec.GetFileSpec().GetFileNameStrippingExtension()); 4498 // Empty string returned, lets bail 4499 if (!filename_no_extension) 4500 break; 4501 4502 // Check if there was no extension to strip and the basename is the same 4503 if (filename_no_extension == module_spec.GetFileSpec().GetFilename()) 4504 break; 4505 4506 // Replace basename with one less extension 4507 module_spec.GetFileSpec().GetFilename() = filename_no_extension; 4508 4509 num_matches = target->GetImages().FindModules (module_spec, matching_module_list); 4510 } 4511 4512 if (num_matches > 1) 4513 { 4514 result.AppendErrorWithFormat ("multiple modules match symbol file '%s', use the --uuid option to resolve the ambiguity.\n", symfile_path); 4515 } 4516 else if (num_matches == 1) 4517 { 4518 ModuleSP module_sp (matching_module_list.GetModuleAtIndex(0)); 4519 4520 // The module has not yet created its symbol vendor, we can just 4521 // give the existing target module the symfile path to use for 4522 // when it decides to create it! 4523 module_sp->SetSymbolFileFileSpec (symbol_fspec); 4524 4525 SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor(true, &result.GetErrorStream()); 4526 if (symbol_vendor) 4527 { 4528 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile(); 4529 4530 if (symbol_file) 4531 { 4532 ObjectFile *object_file = symbol_file->GetObjectFile(); 4533 4534 if (object_file && object_file->GetFileSpec() == symbol_fspec) 4535 { 4536 // Provide feedback that the symfile has been successfully added. 4537 const FileSpec &module_fs = module_sp->GetFileSpec(); 4538 result.AppendMessageWithFormat("symbol file '%s' has been added to '%s'\n", 4539 symfile_path, 4540 module_fs.GetPath().c_str()); 4541 4542 // Let clients know something changed in the module 4543 // if it is currently loaded 4544 ModuleList module_list; 4545 module_list.Append (module_sp); 4546 target->SymbolsDidLoad (module_list); 4547 4548 // Make sure we load any scripting resources that may be embedded 4549 // in the debug info files in case the platform supports that. 4550 Error error; 4551 StreamString feedback_stream; 4552 module_sp->LoadScriptingResourceInTarget (target, error,&feedback_stream); 4553 if (error.Fail() && error.AsCString()) 4554 result.AppendWarningWithFormat("unable to load scripting data for module %s - error reported was %s", 4555 module_sp->GetFileSpec().GetFileNameStrippingExtension().GetCString(), 4556 error.AsCString()); 4557 else if (feedback_stream.GetSize()) 4558 result.AppendWarningWithFormat("%s",feedback_stream.GetData()); 4559 4560 flush = true; 4561 result.SetStatus (eReturnStatusSuccessFinishResult); 4562 return true; 4563 } 4564 } 4565 } 4566 // Clear the symbol file spec if anything went wrong 4567 module_sp->SetSymbolFileFileSpec (FileSpec()); 4568 } 4569 4570 if (module_spec.GetUUID().IsValid()) 4571 { 4572 StreamString ss_symfile_uuid; 4573 module_spec.GetUUID().Dump(&ss_symfile_uuid); 4574 result.AppendErrorWithFormat ("symbol file '%s' (%s) does not match any existing module%s\n", 4575 symfile_path, 4576 ss_symfile_uuid.GetData(), 4577 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular) 4578 ? "\n please specify the full path to the symbol file" 4579 : ""); 4580 } 4581 else 4582 { 4583 result.AppendErrorWithFormat ("symbol file '%s' does not match any existing module%s\n", 4584 symfile_path, 4585 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular) 4586 ? "\n please specify the full path to the symbol file" 4587 : ""); 4588 } 4589 } 4590 else 4591 { 4592 result.AppendError ("one or more executable image paths must be specified"); 4593 } 4594 result.SetStatus (eReturnStatusFailed); 4595 return false; 4596 } 4597 4598 bool 4599 DoExecute (Args& args, CommandReturnObject &result) override 4600 { 4601 Target *target = m_exe_ctx.GetTargetPtr(); 4602 result.SetStatus (eReturnStatusFailed); 4603 bool flush = false; 4604 ModuleSpec module_spec; 4605 const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet(); 4606 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet(); 4607 const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet(); 4608 4609 const size_t argc = args.GetArgumentCount(); 4610 if (argc == 0) 4611 { 4612 if (uuid_option_set || file_option_set || frame_option_set) 4613 { 4614 bool success = false; 4615 bool error_set = false; 4616 if (frame_option_set) 4617 { 4618 Process *process = m_exe_ctx.GetProcessPtr(); 4619 if (process) 4620 { 4621 const StateType process_state = process->GetState(); 4622 if (StateIsStoppedState (process_state, true)) 4623 { 4624 StackFrame *frame = m_exe_ctx.GetFramePtr(); 4625 if (frame) 4626 { 4627 ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp); 4628 if (frame_module_sp) 4629 { 4630 if (frame_module_sp->GetPlatformFileSpec().Exists()) 4631 { 4632 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); 4633 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec(); 4634 } 4635 module_spec.GetUUID() = frame_module_sp->GetUUID(); 4636 success = module_spec.GetUUID().IsValid() || module_spec.GetFileSpec(); 4637 } 4638 else 4639 { 4640 result.AppendError ("frame has no module"); 4641 error_set = true; 4642 } 4643 } 4644 else 4645 { 4646 result.AppendError ("invalid current frame"); 4647 error_set = true; 4648 } 4649 } 4650 else 4651 { 4652 result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state)); 4653 error_set = true; 4654 } 4655 } 4656 else 4657 { 4658 result.AppendError ("a process must exist in order to use the --frame option"); 4659 error_set = true; 4660 } 4661 } 4662 else 4663 { 4664 if (uuid_option_set) 4665 { 4666 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue(); 4667 success |= module_spec.GetUUID().IsValid(); 4668 } 4669 else if (file_option_set) 4670 { 4671 module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue(); 4672 ModuleSP module_sp (target->GetImages().FindFirstModule(module_spec)); 4673 if (module_sp) 4674 { 4675 module_spec.GetFileSpec() = module_sp->GetFileSpec(); 4676 module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec(); 4677 module_spec.GetUUID() = module_sp->GetUUID(); 4678 module_spec.GetArchitecture() = module_sp->GetArchitecture(); 4679 } 4680 else 4681 { 4682 module_spec.GetArchitecture() = target->GetArchitecture(); 4683 } 4684 success |= module_spec.GetFileSpec().Exists(); 4685 } 4686 } 4687 4688 if (success) 4689 { 4690 if (Symbols::DownloadObjectAndSymbolFile (module_spec)) 4691 { 4692 if (module_spec.GetSymbolFileSpec()) 4693 success = AddModuleSymbols (target, module_spec, flush, result); 4694 } 4695 } 4696 4697 if (!success && !error_set) 4698 { 4699 StreamString error_strm; 4700 if (uuid_option_set) 4701 { 4702 error_strm.PutCString("unable to find debug symbols for UUID "); 4703 module_spec.GetUUID().Dump (&error_strm); 4704 } 4705 else if (file_option_set) 4706 { 4707 error_strm.PutCString("unable to find debug symbols for the executable file "); 4708 error_strm << module_spec.GetFileSpec(); 4709 } 4710 else if (frame_option_set) 4711 { 4712 error_strm.PutCString("unable to find debug symbols for the current frame"); 4713 } 4714 result.AppendError (error_strm.GetData()); 4715 } 4716 } 4717 else 4718 { 4719 result.AppendError ("one or more symbol file paths must be specified, or options must be specified"); 4720 } 4721 } 4722 else 4723 { 4724 if (uuid_option_set) 4725 { 4726 result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments"); 4727 } 4728 else if (file_option_set) 4729 { 4730 result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments"); 4731 } 4732 else if (frame_option_set) 4733 { 4734 result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments"); 4735 } 4736 else 4737 { 4738 PlatformSP platform_sp (target->GetPlatform()); 4739 4740 for (size_t i=0; i<argc; ++i) 4741 { 4742 const char *symfile_path = args.GetArgumentAtIndex(i); 4743 if (symfile_path) 4744 { 4745 module_spec.GetSymbolFileSpec().SetFile(symfile_path, true); 4746 if (platform_sp) 4747 { 4748 FileSpec symfile_spec; 4749 if (platform_sp->ResolveSymbolFile(*target, module_spec, symfile_spec).Success()) 4750 module_spec.GetSymbolFileSpec() = symfile_spec; 4751 } 4752 4753 ArchSpec arch; 4754 bool symfile_exists = module_spec.GetSymbolFileSpec().Exists(); 4755 4756 if (symfile_exists) 4757 { 4758 if (!AddModuleSymbols (target, module_spec, flush, result)) 4759 break; 4760 } 4761 else 4762 { 4763 char resolved_symfile_path[PATH_MAX]; 4764 if (module_spec.GetSymbolFileSpec().GetPath (resolved_symfile_path, sizeof(resolved_symfile_path))) 4765 { 4766 if (strcmp (resolved_symfile_path, symfile_path) != 0) 4767 { 4768 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path); 4769 break; 4770 } 4771 } 4772 result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path); 4773 break; 4774 } 4775 } 4776 } 4777 } 4778 } 4779 4780 if (flush) 4781 { 4782 Process *process = m_exe_ctx.GetProcessPtr(); 4783 if (process) 4784 process->Flush(); 4785 } 4786 return result.Succeeded(); 4787 } 4788 4789 OptionGroupOptions m_option_group; 4790 OptionGroupUUID m_uuid_option_group; 4791 OptionGroupFile m_file_option; 4792 OptionGroupBoolean m_current_frame_option; 4793 }; 4794 4795 4796 #pragma mark CommandObjectTargetSymbols 4797 4798 //------------------------------------------------------------------------- 4799 // CommandObjectTargetSymbols 4800 //------------------------------------------------------------------------- 4801 4802 class CommandObjectTargetSymbols : public CommandObjectMultiword 4803 { 4804 public: 4805 //------------------------------------------------------------------ 4806 // Constructors and Destructors 4807 //------------------------------------------------------------------ 4808 CommandObjectTargetSymbols(CommandInterpreter &interpreter) : 4809 CommandObjectMultiword (interpreter, 4810 "target symbols", 4811 "A set of commands for adding and managing debug symbol files.", 4812 "target symbols <sub-command> ...") 4813 { 4814 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter))); 4815 4816 } 4817 4818 ~CommandObjectTargetSymbols() override 4819 { 4820 } 4821 4822 private: 4823 //------------------------------------------------------------------ 4824 // For CommandObjectTargetModules only 4825 //------------------------------------------------------------------ 4826 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols); 4827 }; 4828 4829 4830 #pragma mark CommandObjectTargetStopHookAdd 4831 4832 //------------------------------------------------------------------------- 4833 // CommandObjectTargetStopHookAdd 4834 //------------------------------------------------------------------------- 4835 4836 class CommandObjectTargetStopHookAdd : 4837 public CommandObjectParsed, 4838 public IOHandlerDelegateMultiline 4839 { 4840 public: 4841 4842 class CommandOptions : public Options 4843 { 4844 public: 4845 CommandOptions (CommandInterpreter &interpreter) : 4846 Options(interpreter), 4847 m_line_start(0), 4848 m_line_end (UINT_MAX), 4849 m_func_name_type_mask (eFunctionNameTypeAuto), 4850 m_sym_ctx_specified (false), 4851 m_thread_specified (false), 4852 m_use_one_liner (false), 4853 m_one_liner() 4854 { 4855 } 4856 4857 ~CommandOptions () override {} 4858 4859 const OptionDefinition* 4860 GetDefinitions () override 4861 { 4862 return g_option_table; 4863 } 4864 4865 Error 4866 SetOptionValue (uint32_t option_idx, const char *option_arg) override 4867 { 4868 Error error; 4869 const int short_option = m_getopt_table[option_idx].val; 4870 bool success; 4871 4872 switch (short_option) 4873 { 4874 case 'c': 4875 m_class_name = option_arg; 4876 m_sym_ctx_specified = true; 4877 break; 4878 4879 case 'e': 4880 m_line_end = StringConvert::ToUInt32 (option_arg, UINT_MAX, 0, &success); 4881 if (!success) 4882 { 4883 error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg); 4884 break; 4885 } 4886 m_sym_ctx_specified = true; 4887 break; 4888 4889 case 'l': 4890 m_line_start = StringConvert::ToUInt32 (option_arg, 0, 0, &success); 4891 if (!success) 4892 { 4893 error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg); 4894 break; 4895 } 4896 m_sym_ctx_specified = true; 4897 break; 4898 4899 case 'i': 4900 m_no_inlines = true; 4901 break; 4902 4903 case 'n': 4904 m_function_name = option_arg; 4905 m_func_name_type_mask |= eFunctionNameTypeAuto; 4906 m_sym_ctx_specified = true; 4907 break; 4908 4909 case 'f': 4910 m_file_name = option_arg; 4911 m_sym_ctx_specified = true; 4912 break; 4913 case 's': 4914 m_module_name = option_arg; 4915 m_sym_ctx_specified = true; 4916 break; 4917 case 't' : 4918 { 4919 m_thread_id = StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0); 4920 if (m_thread_id == LLDB_INVALID_THREAD_ID) 4921 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg); 4922 m_thread_specified = true; 4923 } 4924 break; 4925 case 'T': 4926 m_thread_name = option_arg; 4927 m_thread_specified = true; 4928 break; 4929 case 'q': 4930 m_queue_name = option_arg; 4931 m_thread_specified = true; 4932 break; 4933 case 'x': 4934 { 4935 m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0); 4936 if (m_thread_id == UINT32_MAX) 4937 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg); 4938 m_thread_specified = true; 4939 } 4940 break; 4941 case 'o': 4942 m_use_one_liner = true; 4943 m_one_liner = option_arg; 4944 break; 4945 default: 4946 error.SetErrorStringWithFormat ("unrecognized option %c.", short_option); 4947 break; 4948 } 4949 return error; 4950 } 4951 4952 void 4953 OptionParsingStarting () override 4954 { 4955 m_class_name.clear(); 4956 m_function_name.clear(); 4957 m_line_start = 0; 4958 m_line_end = UINT_MAX; 4959 m_file_name.clear(); 4960 m_module_name.clear(); 4961 m_func_name_type_mask = eFunctionNameTypeAuto; 4962 m_thread_id = LLDB_INVALID_THREAD_ID; 4963 m_thread_index = UINT32_MAX; 4964 m_thread_name.clear(); 4965 m_queue_name.clear(); 4966 4967 m_no_inlines = false; 4968 m_sym_ctx_specified = false; 4969 m_thread_specified = false; 4970 4971 m_use_one_liner = false; 4972 m_one_liner.clear(); 4973 } 4974 4975 4976 static OptionDefinition g_option_table[]; 4977 4978 std::string m_class_name; 4979 std::string m_function_name; 4980 uint32_t m_line_start; 4981 uint32_t m_line_end; 4982 std::string m_file_name; 4983 std::string m_module_name; 4984 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType. 4985 lldb::tid_t m_thread_id; 4986 uint32_t m_thread_index; 4987 std::string m_thread_name; 4988 std::string m_queue_name; 4989 bool m_sym_ctx_specified; 4990 bool m_no_inlines; 4991 bool m_thread_specified; 4992 // Instance variables to hold the values for one_liner options. 4993 bool m_use_one_liner; 4994 std::string m_one_liner; 4995 }; 4996 4997 Options * 4998 GetOptions () override 4999 { 5000 return &m_options; 5001 } 5002 5003 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) : 5004 CommandObjectParsed (interpreter, 5005 "target stop-hook add", 5006 "Add a hook to be executed when the target stops.", 5007 "target stop-hook add"), 5008 IOHandlerDelegateMultiline ("DONE", IOHandlerDelegate::Completion::LLDBCommand), 5009 m_options (interpreter) 5010 { 5011 } 5012 5013 ~CommandObjectTargetStopHookAdd () override 5014 { 5015 } 5016 5017 protected: 5018 void 5019 IOHandlerActivated (IOHandler &io_handler) override 5020 { 5021 StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 5022 if (output_sp) 5023 { 5024 output_sp->PutCString("Enter your stop hook command(s). Type 'DONE' to end.\n"); 5025 output_sp->Flush(); 5026 } 5027 } 5028 5029 void 5030 IOHandlerInputComplete (IOHandler &io_handler, std::string &line) override 5031 { 5032 if (m_stop_hook_sp) 5033 { 5034 if (line.empty()) 5035 { 5036 StreamFileSP error_sp(io_handler.GetErrorStreamFile()); 5037 if (error_sp) 5038 { 5039 error_sp->Printf("error: stop hook #%" PRIu64 " aborted, no commands.\n", m_stop_hook_sp->GetID()); 5040 error_sp->Flush(); 5041 } 5042 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get(); 5043 if (target) 5044 target->RemoveStopHookByID(m_stop_hook_sp->GetID()); 5045 } 5046 else 5047 { 5048 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line); 5049 StreamFileSP output_sp(io_handler.GetOutputStreamFile()); 5050 if (output_sp) 5051 { 5052 output_sp->Printf("Stop hook #%" PRIu64 " added.\n", m_stop_hook_sp->GetID()); 5053 output_sp->Flush(); 5054 } 5055 } 5056 m_stop_hook_sp.reset(); 5057 } 5058 io_handler.SetIsDone(true); 5059 } 5060 5061 bool 5062 DoExecute (Args& command, CommandReturnObject &result) override 5063 { 5064 m_stop_hook_sp.reset(); 5065 5066 Target *target = GetSelectedOrDummyTarget(); 5067 if (target) 5068 { 5069 Target::StopHookSP new_hook_sp = target->CreateStopHook(); 5070 5071 // First step, make the specifier. 5072 std::unique_ptr<SymbolContextSpecifier> specifier_ap; 5073 if (m_options.m_sym_ctx_specified) 5074 { 5075 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget())); 5076 5077 if (!m_options.m_module_name.empty()) 5078 { 5079 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified); 5080 } 5081 5082 if (!m_options.m_class_name.empty()) 5083 { 5084 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified); 5085 } 5086 5087 if (!m_options.m_file_name.empty()) 5088 { 5089 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified); 5090 } 5091 5092 if (m_options.m_line_start != 0) 5093 { 5094 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified); 5095 } 5096 5097 if (m_options.m_line_end != UINT_MAX) 5098 { 5099 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); 5100 } 5101 5102 if (!m_options.m_function_name.empty()) 5103 { 5104 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified); 5105 } 5106 } 5107 5108 if (specifier_ap.get()) 5109 new_hook_sp->SetSpecifier (specifier_ap.release()); 5110 5111 // Next see if any of the thread options have been entered: 5112 5113 if (m_options.m_thread_specified) 5114 { 5115 ThreadSpec *thread_spec = new ThreadSpec(); 5116 5117 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) 5118 { 5119 thread_spec->SetTID (m_options.m_thread_id); 5120 } 5121 5122 if (m_options.m_thread_index != UINT32_MAX) 5123 thread_spec->SetIndex (m_options.m_thread_index); 5124 5125 if (!m_options.m_thread_name.empty()) 5126 thread_spec->SetName (m_options.m_thread_name.c_str()); 5127 5128 if (!m_options.m_queue_name.empty()) 5129 thread_spec->SetQueueName (m_options.m_queue_name.c_str()); 5130 5131 new_hook_sp->SetThreadSpecifier (thread_spec); 5132 5133 } 5134 if (m_options.m_use_one_liner) 5135 { 5136 // Use one-liner. 5137 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str()); 5138 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", new_hook_sp->GetID()); 5139 } 5140 else 5141 { 5142 m_stop_hook_sp = new_hook_sp; 5143 m_interpreter.GetLLDBCommandsFromIOHandler ("> ", // Prompt 5144 *this, // IOHandlerDelegate 5145 true, // Run IOHandler in async mode 5146 NULL); // Baton for the "io_handler" that will be passed back into our IOHandlerDelegate functions 5147 5148 } 5149 result.SetStatus (eReturnStatusSuccessFinishNoResult); 5150 } 5151 else 5152 { 5153 result.AppendError ("invalid target\n"); 5154 result.SetStatus (eReturnStatusFailed); 5155 } 5156 5157 return result.Succeeded(); 5158 } 5159 private: 5160 CommandOptions m_options; 5161 Target::StopHookSP m_stop_hook_sp; 5162 }; 5163 5164 OptionDefinition 5165 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] = 5166 { 5167 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeOneLiner, 5168 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." }, 5169 { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName, 5170 "Set the module within which the stop-hook is to be run."}, 5171 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadIndex, 5172 "The stop hook is run only for the thread whose index matches this argument."}, 5173 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadID, 5174 "The stop hook is run only for the thread whose TID matches this argument."}, 5175 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeThreadName, 5176 "The stop hook is run only for the thread whose thread name matches this argument."}, 5177 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeQueueName, 5178 "The stop hook is run only for threads in the queue whose name is given by this argument."}, 5179 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, 5180 "Specify the source file within which the stop-hook is to be run." }, 5181 { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, 5182 "Set the start of the line range for which the stop-hook is to be run."}, 5183 { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeLineNum, 5184 "Set the end of the line range for which the stop-hook is to be run."}, 5185 { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeClassName, 5186 "Specify the class within which the stop-hook is to be run." }, 5187 { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, NULL, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, 5188 "Set the function name within which the stop hook will be run." }, 5189 { 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL } 5190 }; 5191 5192 #pragma mark CommandObjectTargetStopHookDelete 5193 5194 //------------------------------------------------------------------------- 5195 // CommandObjectTargetStopHookDelete 5196 //------------------------------------------------------------------------- 5197 5198 class CommandObjectTargetStopHookDelete : public CommandObjectParsed 5199 { 5200 public: 5201 5202 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) : 5203 CommandObjectParsed (interpreter, 5204 "target stop-hook delete", 5205 "Delete a stop-hook.", 5206 "target stop-hook delete [<idx>]") 5207 { 5208 } 5209 5210 ~CommandObjectTargetStopHookDelete () override 5211 { 5212 } 5213 5214 protected: 5215 bool 5216 DoExecute (Args& command, CommandReturnObject &result) override 5217 { 5218 Target *target = GetSelectedOrDummyTarget(); 5219 if (target) 5220 { 5221 // FIXME: see if we can use the breakpoint id style parser? 5222 size_t num_args = command.GetArgumentCount(); 5223 if (num_args == 0) 5224 { 5225 if (!m_interpreter.Confirm ("Delete all stop hooks?", true)) 5226 { 5227 result.SetStatus (eReturnStatusFailed); 5228 return false; 5229 } 5230 else 5231 { 5232 target->RemoveAllStopHooks(); 5233 } 5234 } 5235 else 5236 { 5237 bool success; 5238 for (size_t i = 0; i < num_args; i++) 5239 { 5240 lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 5241 if (!success) 5242 { 5243 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5244 result.SetStatus(eReturnStatusFailed); 5245 return false; 5246 } 5247 success = target->RemoveStopHookByID (user_id); 5248 if (!success) 5249 { 5250 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5251 result.SetStatus(eReturnStatusFailed); 5252 return false; 5253 } 5254 } 5255 } 5256 result.SetStatus (eReturnStatusSuccessFinishNoResult); 5257 } 5258 else 5259 { 5260 result.AppendError ("invalid target\n"); 5261 result.SetStatus (eReturnStatusFailed); 5262 } 5263 5264 return result.Succeeded(); 5265 } 5266 }; 5267 #pragma mark CommandObjectTargetStopHookEnableDisable 5268 5269 //------------------------------------------------------------------------- 5270 // CommandObjectTargetStopHookEnableDisable 5271 //------------------------------------------------------------------------- 5272 5273 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed 5274 { 5275 public: 5276 5277 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) : 5278 CommandObjectParsed (interpreter, 5279 name, 5280 help, 5281 syntax), 5282 m_enable (enable) 5283 { 5284 } 5285 5286 ~CommandObjectTargetStopHookEnableDisable () override 5287 { 5288 } 5289 5290 protected: 5291 bool 5292 DoExecute (Args& command, CommandReturnObject &result) override 5293 { 5294 Target *target = GetSelectedOrDummyTarget(); 5295 if (target) 5296 { 5297 // FIXME: see if we can use the breakpoint id style parser? 5298 size_t num_args = command.GetArgumentCount(); 5299 bool success; 5300 5301 if (num_args == 0) 5302 { 5303 target->SetAllStopHooksActiveState (m_enable); 5304 } 5305 else 5306 { 5307 for (size_t i = 0; i < num_args; i++) 5308 { 5309 lldb::user_id_t user_id = StringConvert::ToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success); 5310 if (!success) 5311 { 5312 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5313 result.SetStatus(eReturnStatusFailed); 5314 return false; 5315 } 5316 success = target->SetStopHookActiveStateByID (user_id, m_enable); 5317 if (!success) 5318 { 5319 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i)); 5320 result.SetStatus(eReturnStatusFailed); 5321 return false; 5322 } 5323 } 5324 } 5325 result.SetStatus (eReturnStatusSuccessFinishNoResult); 5326 } 5327 else 5328 { 5329 result.AppendError ("invalid target\n"); 5330 result.SetStatus (eReturnStatusFailed); 5331 } 5332 return result.Succeeded(); 5333 } 5334 private: 5335 bool m_enable; 5336 }; 5337 5338 #pragma mark CommandObjectTargetStopHookList 5339 5340 //------------------------------------------------------------------------- 5341 // CommandObjectTargetStopHookList 5342 //------------------------------------------------------------------------- 5343 5344 class CommandObjectTargetStopHookList : public CommandObjectParsed 5345 { 5346 public: 5347 5348 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) : 5349 CommandObjectParsed (interpreter, 5350 "target stop-hook list", 5351 "List all stop-hooks.", 5352 "target stop-hook list [<type>]") 5353 { 5354 } 5355 5356 ~CommandObjectTargetStopHookList () override 5357 { 5358 } 5359 5360 protected: 5361 bool 5362 DoExecute (Args& command, CommandReturnObject &result) override 5363 { 5364 Target *target = GetSelectedOrDummyTarget(); 5365 if (!target) 5366 { 5367 result.AppendError ("invalid target\n"); 5368 result.SetStatus (eReturnStatusFailed); 5369 return result.Succeeded(); 5370 } 5371 5372 size_t num_hooks = target->GetNumStopHooks (); 5373 if (num_hooks == 0) 5374 { 5375 result.GetOutputStream().PutCString ("No stop hooks.\n"); 5376 } 5377 else 5378 { 5379 for (size_t i = 0; i < num_hooks; i++) 5380 { 5381 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i); 5382 if (i > 0) 5383 result.GetOutputStream().PutCString ("\n"); 5384 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull); 5385 } 5386 } 5387 result.SetStatus (eReturnStatusSuccessFinishResult); 5388 return result.Succeeded(); 5389 } 5390 }; 5391 5392 #pragma mark CommandObjectMultiwordTargetStopHooks 5393 //------------------------------------------------------------------------- 5394 // CommandObjectMultiwordTargetStopHooks 5395 //------------------------------------------------------------------------- 5396 5397 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword 5398 { 5399 public: 5400 5401 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) : 5402 CommandObjectMultiword (interpreter, 5403 "target stop-hook", 5404 "A set of commands for operating on debugger target stop-hooks.", 5405 "target stop-hook <subcommand> [<subcommand-options>]") 5406 { 5407 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter))); 5408 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter))); 5409 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 5410 false, 5411 "target stop-hook disable [<id>]", 5412 "Disable a stop-hook.", 5413 "target stop-hook disable"))); 5414 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter, 5415 true, 5416 "target stop-hook enable [<id>]", 5417 "Enable a stop-hook.", 5418 "target stop-hook enable"))); 5419 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter))); 5420 } 5421 5422 ~CommandObjectMultiwordTargetStopHooks() override 5423 { 5424 } 5425 }; 5426 5427 5428 5429 #pragma mark CommandObjectMultiwordTarget 5430 5431 //------------------------------------------------------------------------- 5432 // CommandObjectMultiwordTarget 5433 //------------------------------------------------------------------------- 5434 5435 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) : 5436 CommandObjectMultiword (interpreter, 5437 "target", 5438 "A set of commands for operating on debugger targets.", 5439 "target <subcommand> [<subcommand-options>]") 5440 { 5441 5442 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter))); 5443 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter))); 5444 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter))); 5445 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter))); 5446 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter))); 5447 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter))); 5448 LoadSubCommand ("symbols", CommandObjectSP (new CommandObjectTargetSymbols (interpreter))); 5449 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter))); 5450 } 5451 5452 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget () 5453 { 5454 } 5455 5456 5457