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