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