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