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