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