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