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