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