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