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