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