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