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