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