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