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