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/Frontend/CompilerInstance.h" 63 #include "clang/Frontend/CompilerInvocation.h" 64 #include "clang/Frontend/FrontendActions.h" 65 #include "clang/Serialization/ObjectFilePCHContainerReader.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(" ( arch="); 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 = Status::FromErrorStringWithFormat( 190 "unrecognized short option '%c'", 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 = GetTarget(); 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 = GetTarget(); 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 = GetTarget(); 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 = GetTarget(); 1207 target.GetImageSearchPathList().Dump(&result.GetOutputStream()); 1208 result.SetStatus(eReturnStatusSuccessFinishResult); 1209 } 1210 }; 1211 1212 #pragma mark CommandObjectTargetModulesSearchPathsQuery 1213 1214 class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed { 1215 public: 1216 CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter) 1217 : CommandObjectParsed( 1218 interpreter, "target modules search-paths query", 1219 "Transform a path using the first applicable image search path.", 1220 nullptr, eCommandRequiresTarget) { 1221 AddSimpleArgumentList(eArgTypeDirectoryName); 1222 } 1223 1224 ~CommandObjectTargetModulesSearchPathsQuery() override = default; 1225 1226 protected: 1227 void DoExecute(Args &command, CommandReturnObject &result) override { 1228 Target &target = GetTarget(); 1229 if (command.GetArgumentCount() != 1) { 1230 result.AppendError("query requires one argument\n"); 1231 return; 1232 } 1233 1234 ConstString orig(command.GetArgumentAtIndex(0)); 1235 ConstString transformed; 1236 if (target.GetImageSearchPathList().RemapPath(orig, transformed)) 1237 result.GetOutputStream().Printf("%s\n", transformed.GetCString()); 1238 else 1239 result.GetOutputStream().Printf("%s\n", orig.GetCString()); 1240 1241 result.SetStatus(eReturnStatusSuccessFinishResult); 1242 } 1243 }; 1244 1245 // Static Helper functions 1246 static void DumpModuleArchitecture(Stream &strm, Module *module, 1247 bool full_triple, uint32_t width) { 1248 if (module) { 1249 StreamString arch_strm; 1250 1251 if (full_triple) 1252 module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream()); 1253 else 1254 arch_strm.PutCString(module->GetArchitecture().GetArchitectureName()); 1255 std::string arch_str = std::string(arch_strm.GetString()); 1256 1257 if (width) 1258 strm.Printf("%-*s", width, arch_str.c_str()); 1259 else 1260 strm.PutCString(arch_str); 1261 } 1262 } 1263 1264 static void DumpModuleUUID(Stream &strm, Module *module) { 1265 if (module && module->GetUUID().IsValid()) 1266 module->GetUUID().Dump(strm); 1267 else 1268 strm.PutCString(" "); 1269 } 1270 1271 static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter, 1272 Stream &strm, Module *module, 1273 const FileSpec &file_spec, 1274 lldb::DescriptionLevel desc_level) { 1275 uint32_t num_matches = 0; 1276 if (module) { 1277 SymbolContextList sc_list; 1278 num_matches = module->ResolveSymbolContextsForFileSpec( 1279 file_spec, 0, false, eSymbolContextCompUnit, sc_list); 1280 1281 bool first_module = true; 1282 for (const SymbolContext &sc : sc_list) { 1283 if (!first_module) 1284 strm << "\n\n"; 1285 1286 strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `" 1287 << module->GetFileSpec().GetFilename() << "\n"; 1288 LineTable *line_table = sc.comp_unit->GetLineTable(); 1289 if (line_table) 1290 line_table->GetDescription( 1291 &strm, interpreter.GetExecutionContext().GetTargetPtr(), 1292 desc_level); 1293 else 1294 strm << "No line table"; 1295 1296 first_module = false; 1297 } 1298 } 1299 return num_matches; 1300 } 1301 1302 static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr, 1303 uint32_t width) { 1304 if (file_spec_ptr) { 1305 if (width > 0) { 1306 std::string fullpath = file_spec_ptr->GetPath(); 1307 strm.Printf("%-*s", width, fullpath.c_str()); 1308 return; 1309 } else { 1310 file_spec_ptr->Dump(strm.AsRawOstream()); 1311 return; 1312 } 1313 } 1314 // Keep the width spacing correct if things go wrong... 1315 if (width > 0) 1316 strm.Printf("%-*s", width, ""); 1317 } 1318 1319 static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr, 1320 uint32_t width) { 1321 if (file_spec_ptr) { 1322 if (width > 0) 1323 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString("")); 1324 else 1325 file_spec_ptr->GetDirectory().Dump(&strm); 1326 return; 1327 } 1328 // Keep the width spacing correct if things go wrong... 1329 if (width > 0) 1330 strm.Printf("%-*s", width, ""); 1331 } 1332 1333 static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr, 1334 uint32_t width) { 1335 if (file_spec_ptr) { 1336 if (width > 0) 1337 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString("")); 1338 else 1339 file_spec_ptr->GetFilename().Dump(&strm); 1340 return; 1341 } 1342 // Keep the width spacing correct if things go wrong... 1343 if (width > 0) 1344 strm.Printf("%-*s", width, ""); 1345 } 1346 1347 static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) { 1348 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex()); 1349 const size_t num_modules = module_list.GetSize(); 1350 if (num_modules == 0) 1351 return 0; 1352 1353 size_t num_dumped = 0; 1354 strm.Format("Dumping headers for {0} module(s).\n", num_modules); 1355 strm.IndentMore(); 1356 for (ModuleSP module_sp : module_list.ModulesNoLocking()) { 1357 if (module_sp) { 1358 if (num_dumped++ > 0) { 1359 strm.EOL(); 1360 strm.EOL(); 1361 } 1362 ObjectFile *objfile = module_sp->GetObjectFile(); 1363 if (objfile) 1364 objfile->Dump(&strm); 1365 else { 1366 strm.Format("No object file for module: {0:F}\n", 1367 module_sp->GetFileSpec()); 1368 } 1369 } 1370 } 1371 strm.IndentLess(); 1372 return num_dumped; 1373 } 1374 1375 static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm, 1376 Module *module, SortOrder sort_order, 1377 Mangled::NamePreference name_preference) { 1378 if (!module) 1379 return; 1380 if (Symtab *symtab = module->GetSymtab()) 1381 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), 1382 sort_order, name_preference); 1383 } 1384 1385 static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm, 1386 Module *module) { 1387 if (module) { 1388 SectionList *section_list = module->GetSectionList(); 1389 if (section_list) { 1390 strm.Printf("Sections for '%s' (%s):\n", 1391 module->GetSpecificationDescription().c_str(), 1392 module->GetArchitecture().GetArchitectureName()); 1393 section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2, 1394 interpreter.GetExecutionContext().GetTargetPtr(), true, 1395 UINT32_MAX); 1396 } 1397 } 1398 } 1399 1400 static bool DumpModuleSymbolFile(Stream &strm, Module *module) { 1401 if (module) { 1402 if (SymbolFile *symbol_file = module->GetSymbolFile(true)) { 1403 symbol_file->Dump(strm); 1404 return true; 1405 } 1406 } 1407 return false; 1408 } 1409 1410 static bool GetSeparateDebugInfoList(StructuredData::Array &list, 1411 Module *module, bool errors_only) { 1412 if (module) { 1413 if (SymbolFile *symbol_file = module->GetSymbolFile(/*can_create=*/true)) { 1414 StructuredData::Dictionary d; 1415 if (symbol_file->GetSeparateDebugInfo(d, errors_only)) { 1416 list.AddItem( 1417 std::make_shared<StructuredData::Dictionary>(std::move(d))); 1418 return true; 1419 } 1420 } 1421 } 1422 return false; 1423 } 1424 1425 static void DumpDwoFilesTable(Stream &strm, 1426 StructuredData::Array &dwo_listings) { 1427 strm.PutCString("Dwo ID Err Dwo Path"); 1428 strm.EOL(); 1429 strm.PutCString( 1430 "------------------ --- -----------------------------------------"); 1431 strm.EOL(); 1432 dwo_listings.ForEach([&strm](StructuredData::Object *dwo) { 1433 StructuredData::Dictionary *dict = dwo->GetAsDictionary(); 1434 if (!dict) 1435 return false; 1436 1437 uint64_t dwo_id; 1438 if (dict->GetValueForKeyAsInteger("dwo_id", dwo_id)) 1439 strm.Printf("0x%16.16" PRIx64 " ", dwo_id); 1440 else 1441 strm.Printf("0x???????????????? "); 1442 1443 llvm::StringRef error; 1444 if (dict->GetValueForKeyAsString("error", error)) 1445 strm << "E " << error; 1446 else { 1447 llvm::StringRef resolved_dwo_path; 1448 if (dict->GetValueForKeyAsString("resolved_dwo_path", 1449 resolved_dwo_path)) { 1450 strm << " " << resolved_dwo_path; 1451 if (resolved_dwo_path.ends_with(".dwp")) { 1452 llvm::StringRef dwo_name; 1453 if (dict->GetValueForKeyAsString("dwo_name", dwo_name)) 1454 strm << "(" << dwo_name << ")"; 1455 } 1456 } 1457 } 1458 strm.EOL(); 1459 return true; 1460 }); 1461 } 1462 1463 static void DumpOsoFilesTable(Stream &strm, 1464 StructuredData::Array &oso_listings) { 1465 strm.PutCString("Mod Time Err Oso Path"); 1466 strm.EOL(); 1467 strm.PutCString("------------------ --- ---------------------"); 1468 strm.EOL(); 1469 oso_listings.ForEach([&strm](StructuredData::Object *oso) { 1470 StructuredData::Dictionary *dict = oso->GetAsDictionary(); 1471 if (!dict) 1472 return false; 1473 1474 uint32_t oso_mod_time; 1475 if (dict->GetValueForKeyAsInteger("oso_mod_time", oso_mod_time)) 1476 strm.Printf("0x%16.16" PRIx32 " ", oso_mod_time); 1477 1478 llvm::StringRef error; 1479 if (dict->GetValueForKeyAsString("error", error)) 1480 strm << "E " << error; 1481 else { 1482 llvm::StringRef oso_path; 1483 if (dict->GetValueForKeyAsString("oso_path", oso_path)) 1484 strm << " " << oso_path; 1485 } 1486 strm.EOL(); 1487 return true; 1488 }); 1489 } 1490 1491 static void 1492 DumpAddress(ExecutionContextScope *exe_scope, const Address &so_addr, 1493 bool verbose, bool all_ranges, Stream &strm, 1494 std::optional<Stream::HighlightSettings> settings = std::nullopt) { 1495 strm.IndentMore(); 1496 strm.Indent(" Address: "); 1497 so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress); 1498 strm.PutCString(" ("); 1499 so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset); 1500 strm.PutCString(")\n"); 1501 strm.Indent(" Summary: "); 1502 const uint32_t save_indent = strm.GetIndentLevel(); 1503 strm.SetIndentLevel(save_indent + 13); 1504 so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription, 1505 Address::DumpStyleInvalid, UINT32_MAX, false, settings); 1506 strm.SetIndentLevel(save_indent); 1507 // Print out detailed address information when verbose is enabled 1508 if (verbose) { 1509 strm.EOL(); 1510 so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext, 1511 Address::DumpStyleInvalid, UINT32_MAX, all_ranges, settings); 1512 } 1513 strm.IndentLess(); 1514 } 1515 1516 static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm, 1517 Module *module, uint32_t resolve_mask, 1518 lldb::addr_t raw_addr, lldb::addr_t offset, 1519 bool verbose, bool all_ranges) { 1520 if (module) { 1521 lldb::addr_t addr = raw_addr - offset; 1522 Address so_addr; 1523 SymbolContext sc; 1524 Target *target = interpreter.GetExecutionContext().GetTargetPtr(); 1525 if (target && !target->GetSectionLoadList().IsEmpty()) { 1526 if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr)) 1527 return false; 1528 else if (so_addr.GetModule().get() != module) 1529 return false; 1530 } else { 1531 if (!module->ResolveFileAddress(addr, so_addr)) 1532 return false; 1533 } 1534 1535 ExecutionContextScope *exe_scope = 1536 interpreter.GetExecutionContext().GetBestExecutionContextScope(); 1537 DumpAddress(exe_scope, so_addr, verbose, all_ranges, strm); 1538 return true; 1539 } 1540 1541 return false; 1542 } 1543 1544 static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter, 1545 Stream &strm, Module *module, 1546 const char *name, bool name_is_regex, 1547 bool verbose, bool all_ranges) { 1548 if (!module) 1549 return 0; 1550 1551 Symtab *symtab = module->GetSymtab(); 1552 if (!symtab) 1553 return 0; 1554 1555 SymbolContext sc; 1556 const bool use_color = interpreter.GetDebugger().GetUseColor(); 1557 std::vector<uint32_t> match_indexes; 1558 ConstString symbol_name(name); 1559 uint32_t num_matches = 0; 1560 if (name_is_regex) { 1561 RegularExpression name_regexp(symbol_name.GetStringRef()); 1562 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType( 1563 name_regexp, eSymbolTypeAny, match_indexes); 1564 } else { 1565 num_matches = 1566 symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes); 1567 } 1568 1569 if (num_matches > 0) { 1570 strm.Indent(); 1571 strm.Printf("%u symbols match %s'%s' in ", num_matches, 1572 name_is_regex ? "the regular expression " : "", name); 1573 DumpFullpath(strm, &module->GetFileSpec(), 0); 1574 strm.PutCString(":\n"); 1575 strm.IndentMore(); 1576 Stream::HighlightSettings settings( 1577 name, interpreter.GetDebugger().GetRegexMatchAnsiPrefix(), 1578 interpreter.GetDebugger().GetRegexMatchAnsiSuffix()); 1579 for (uint32_t i = 0; i < num_matches; ++i) { 1580 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]); 1581 if (symbol) { 1582 if (symbol->ValueIsAddress()) { 1583 DumpAddress( 1584 interpreter.GetExecutionContext().GetBestExecutionContextScope(), 1585 symbol->GetAddressRef(), verbose, all_ranges, strm, 1586 use_color && name_is_regex 1587 ? std::optional<Stream::HighlightSettings>{settings} 1588 : std::nullopt); 1589 strm.EOL(); 1590 } else { 1591 strm.IndentMore(); 1592 strm.Indent(" Name: "); 1593 strm.PutCStringColorHighlighted( 1594 symbol->GetDisplayName().GetStringRef(), 1595 use_color && name_is_regex 1596 ? std::optional<Stream::HighlightSettings>{settings} 1597 : std::nullopt); 1598 strm.EOL(); 1599 strm.Indent(" Value: "); 1600 strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetRawValue()); 1601 if (symbol->GetByteSizeIsValid()) { 1602 strm.Indent(" Size: "); 1603 strm.Printf("0x%16.16" PRIx64 "\n", symbol->GetByteSize()); 1604 } 1605 strm.IndentLess(); 1606 } 1607 } 1608 } 1609 strm.IndentLess(); 1610 } 1611 return num_matches; 1612 } 1613 1614 static void DumpSymbolContextList( 1615 ExecutionContextScope *exe_scope, Stream &strm, 1616 const SymbolContextList &sc_list, bool verbose, bool all_ranges, 1617 std::optional<Stream::HighlightSettings> settings = std::nullopt) { 1618 strm.IndentMore(); 1619 bool first_module = true; 1620 for (const SymbolContext &sc : sc_list) { 1621 if (!first_module) 1622 strm.EOL(); 1623 1624 AddressRange range; 1625 1626 sc.GetAddressRange(eSymbolContextEverything, 0, true, range); 1627 1628 DumpAddress(exe_scope, range.GetBaseAddress(), verbose, all_ranges, strm, 1629 settings); 1630 first_module = false; 1631 } 1632 strm.IndentLess(); 1633 } 1634 1635 static size_t LookupFunctionInModule(CommandInterpreter &interpreter, 1636 Stream &strm, Module *module, 1637 const char *name, bool name_is_regex, 1638 const ModuleFunctionSearchOptions &options, 1639 bool verbose, bool all_ranges) { 1640 if (module && name && name[0]) { 1641 SymbolContextList sc_list; 1642 size_t num_matches = 0; 1643 if (name_is_regex) { 1644 RegularExpression function_name_regex((llvm::StringRef(name))); 1645 module->FindFunctions(function_name_regex, options, sc_list); 1646 } else { 1647 ConstString function_name(name); 1648 module->FindFunctions(function_name, CompilerDeclContext(), 1649 eFunctionNameTypeAuto, options, sc_list); 1650 } 1651 num_matches = sc_list.GetSize(); 1652 if (num_matches) { 1653 strm.Indent(); 1654 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches, 1655 num_matches > 1 ? "es" : ""); 1656 DumpFullpath(strm, &module->GetFileSpec(), 0); 1657 strm.PutCString(":\n"); 1658 DumpSymbolContextList( 1659 interpreter.GetExecutionContext().GetBestExecutionContextScope(), 1660 strm, sc_list, verbose, all_ranges); 1661 } 1662 return num_matches; 1663 } 1664 return 0; 1665 } 1666 1667 static size_t LookupTypeInModule(Target *target, 1668 CommandInterpreter &interpreter, Stream &strm, 1669 Module *module, const char *name_cstr, 1670 bool name_is_regex) { 1671 if (module && name_cstr && name_cstr[0]) { 1672 TypeQuery query(name_cstr); 1673 TypeResults results; 1674 module->FindTypes(query, results); 1675 1676 TypeList type_list; 1677 SymbolContext sc; 1678 if (module) 1679 sc.module_sp = module->shared_from_this(); 1680 // Sort the type results and put the results that matched in \a module 1681 // first if \a module was specified. 1682 sc.SortTypeList(results.GetTypeMap(), type_list); 1683 if (type_list.Empty()) 1684 return 0; 1685 1686 const uint64_t num_matches = type_list.GetSize(); 1687 1688 strm.Indent(); 1689 strm.Printf("%" PRIu64 " match%s found in ", num_matches, 1690 num_matches > 1 ? "es" : ""); 1691 DumpFullpath(strm, &module->GetFileSpec(), 0); 1692 strm.PutCString(":\n"); 1693 for (TypeSP type_sp : type_list.Types()) { 1694 if (!type_sp) 1695 continue; 1696 // Resolve the clang type so that any forward references to types 1697 // that haven't yet been parsed will get parsed. 1698 type_sp->GetFullCompilerType(); 1699 type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target); 1700 // Print all typedef chains 1701 TypeSP typedef_type_sp(type_sp); 1702 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType()); 1703 while (typedefed_type_sp) { 1704 strm.EOL(); 1705 strm.Printf(" typedef '%s': ", 1706 typedef_type_sp->GetName().GetCString()); 1707 typedefed_type_sp->GetFullCompilerType(); 1708 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true, 1709 target); 1710 typedef_type_sp = typedefed_type_sp; 1711 typedefed_type_sp = typedef_type_sp->GetTypedefType(); 1712 } 1713 strm.EOL(); 1714 } 1715 return type_list.GetSize(); 1716 } 1717 return 0; 1718 } 1719 1720 static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter, 1721 Stream &strm, Module &module, 1722 const char *name_cstr, bool name_is_regex) { 1723 TypeQuery query(name_cstr); 1724 TypeResults results; 1725 module.FindTypes(query, results); 1726 TypeList type_list; 1727 SymbolContext sc; 1728 sc.module_sp = module.shared_from_this(); 1729 sc.SortTypeList(results.GetTypeMap(), type_list); 1730 if (type_list.Empty()) 1731 return 0; 1732 1733 strm.Indent(); 1734 strm.PutCString("Best match found in "); 1735 DumpFullpath(strm, &module.GetFileSpec(), 0); 1736 strm.PutCString(":\n"); 1737 1738 TypeSP type_sp(type_list.GetTypeAtIndex(0)); 1739 if (type_sp) { 1740 // Resolve the clang type so that any forward references to types that 1741 // haven't yet been parsed will get parsed. 1742 type_sp->GetFullCompilerType(); 1743 type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target); 1744 // Print all typedef chains. 1745 TypeSP typedef_type_sp(type_sp); 1746 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType()); 1747 while (typedefed_type_sp) { 1748 strm.EOL(); 1749 strm.Printf(" typedef '%s': ", 1750 typedef_type_sp->GetName().GetCString()); 1751 typedefed_type_sp->GetFullCompilerType(); 1752 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true, 1753 target); 1754 typedef_type_sp = typedefed_type_sp; 1755 typedefed_type_sp = typedef_type_sp->GetTypedefType(); 1756 } 1757 } 1758 strm.EOL(); 1759 return type_list.GetSize(); 1760 } 1761 1762 static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter, 1763 Stream &strm, Module *module, 1764 const FileSpec &file_spec, 1765 uint32_t line, bool check_inlines, 1766 bool verbose, bool all_ranges) { 1767 if (module && file_spec) { 1768 SymbolContextList sc_list; 1769 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec( 1770 file_spec, line, check_inlines, eSymbolContextEverything, sc_list); 1771 if (num_matches > 0) { 1772 strm.Indent(); 1773 strm.Printf("%u match%s found in ", num_matches, 1774 num_matches > 1 ? "es" : ""); 1775 strm << file_spec; 1776 if (line > 0) 1777 strm.Printf(":%u", line); 1778 strm << " in "; 1779 DumpFullpath(strm, &module->GetFileSpec(), 0); 1780 strm.PutCString(":\n"); 1781 DumpSymbolContextList( 1782 interpreter.GetExecutionContext().GetBestExecutionContextScope(), 1783 strm, sc_list, verbose, all_ranges); 1784 return num_matches; 1785 } 1786 } 1787 return 0; 1788 } 1789 1790 static size_t FindModulesByName(Target *target, const char *module_name, 1791 ModuleList &module_list, 1792 bool check_global_list) { 1793 FileSpec module_file_spec(module_name); 1794 ModuleSpec module_spec(module_file_spec); 1795 1796 const size_t initial_size = module_list.GetSize(); 1797 1798 if (check_global_list) { 1799 // Check the global list 1800 std::lock_guard<std::recursive_mutex> guard( 1801 Module::GetAllocationModuleCollectionMutex()); 1802 const size_t num_modules = Module::GetNumberAllocatedModules(); 1803 ModuleSP module_sp; 1804 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { 1805 Module *module = Module::GetAllocatedModuleAtIndex(image_idx); 1806 1807 if (module) { 1808 if (module->MatchesModuleSpec(module_spec)) { 1809 module_sp = module->shared_from_this(); 1810 module_list.AppendIfNeeded(module_sp); 1811 } 1812 } 1813 } 1814 } else { 1815 if (target) { 1816 target->GetImages().FindModules(module_spec, module_list); 1817 const size_t num_matches = module_list.GetSize(); 1818 1819 // Not found in our module list for our target, check the main shared 1820 // module list in case it is a extra file used somewhere else 1821 if (num_matches == 0) { 1822 module_spec.GetArchitecture() = target->GetArchitecture(); 1823 ModuleList::FindSharedModules(module_spec, module_list); 1824 } 1825 } else { 1826 ModuleList::FindSharedModules(module_spec, module_list); 1827 } 1828 } 1829 1830 return module_list.GetSize() - initial_size; 1831 } 1832 1833 #pragma mark CommandObjectTargetModulesModuleAutoComplete 1834 1835 // A base command object class that can auto complete with module file 1836 // paths 1837 1838 class CommandObjectTargetModulesModuleAutoComplete 1839 : public CommandObjectParsed { 1840 public: 1841 CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter, 1842 const char *name, 1843 const char *help, 1844 const char *syntax, 1845 uint32_t flags = 0) 1846 : CommandObjectParsed(interpreter, name, help, syntax, flags) { 1847 AddSimpleArgumentList(eArgTypeFilename, eArgRepeatStar); 1848 } 1849 1850 ~CommandObjectTargetModulesModuleAutoComplete() override = default; 1851 1852 void 1853 HandleArgumentCompletion(CompletionRequest &request, 1854 OptionElementVector &opt_element_vector) override { 1855 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( 1856 GetCommandInterpreter(), lldb::eModuleCompletion, request, nullptr); 1857 } 1858 }; 1859 1860 #pragma mark CommandObjectTargetModulesSourceFileAutoComplete 1861 1862 // A base command object class that can auto complete with module source 1863 // file paths 1864 1865 class CommandObjectTargetModulesSourceFileAutoComplete 1866 : public CommandObjectParsed { 1867 public: 1868 CommandObjectTargetModulesSourceFileAutoComplete( 1869 CommandInterpreter &interpreter, const char *name, const char *help, 1870 const char *syntax, uint32_t flags) 1871 : CommandObjectParsed(interpreter, name, help, syntax, flags) { 1872 AddSimpleArgumentList(eArgTypeSourceFile, eArgRepeatPlus); 1873 } 1874 1875 ~CommandObjectTargetModulesSourceFileAutoComplete() override = default; 1876 1877 void 1878 HandleArgumentCompletion(CompletionRequest &request, 1879 OptionElementVector &opt_element_vector) override { 1880 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks( 1881 GetCommandInterpreter(), lldb::eSourceFileCompletion, request, nullptr); 1882 } 1883 }; 1884 1885 #pragma mark CommandObjectTargetModulesDumpObjfile 1886 1887 class CommandObjectTargetModulesDumpObjfile 1888 : public CommandObjectTargetModulesModuleAutoComplete { 1889 public: 1890 CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter) 1891 : CommandObjectTargetModulesModuleAutoComplete( 1892 interpreter, "target modules dump objfile", 1893 "Dump the object file headers from one or more target modules.", 1894 nullptr, eCommandRequiresTarget) {} 1895 1896 ~CommandObjectTargetModulesDumpObjfile() override = default; 1897 1898 protected: 1899 void DoExecute(Args &command, CommandReturnObject &result) override { 1900 Target &target = GetTarget(); 1901 1902 uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize(); 1903 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 1904 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 1905 1906 size_t num_dumped = 0; 1907 if (command.GetArgumentCount() == 0) { 1908 // Dump all headers for all modules images 1909 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(), 1910 target.GetImages()); 1911 if (num_dumped == 0) { 1912 result.AppendError("the target has no associated executable images"); 1913 } 1914 } else { 1915 // Find the modules that match the basename or full path. 1916 ModuleList module_list; 1917 const char *arg_cstr; 1918 for (int arg_idx = 0; 1919 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; 1920 ++arg_idx) { 1921 size_t num_matched = 1922 FindModulesByName(&target, arg_cstr, module_list, true); 1923 if (num_matched == 0) { 1924 result.AppendWarningWithFormat( 1925 "Unable to find an image that matches '%s'.\n", arg_cstr); 1926 } 1927 } 1928 // Dump all the modules we found. 1929 num_dumped = 1930 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list); 1931 } 1932 1933 if (num_dumped > 0) { 1934 result.SetStatus(eReturnStatusSuccessFinishResult); 1935 } else { 1936 result.AppendError("no matching executable images found"); 1937 } 1938 } 1939 }; 1940 1941 #define LLDB_OPTIONS_target_modules_dump_symtab 1942 #include "CommandOptions.inc" 1943 1944 class CommandObjectTargetModulesDumpSymtab 1945 : public CommandObjectTargetModulesModuleAutoComplete { 1946 public: 1947 CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter) 1948 : CommandObjectTargetModulesModuleAutoComplete( 1949 interpreter, "target modules dump symtab", 1950 "Dump the symbol table from one or more target modules.", nullptr, 1951 eCommandRequiresTarget) {} 1952 1953 ~CommandObjectTargetModulesDumpSymtab() override = default; 1954 1955 Options *GetOptions() override { return &m_options; } 1956 1957 class CommandOptions : public Options { 1958 public: 1959 CommandOptions() = default; 1960 1961 ~CommandOptions() override = default; 1962 1963 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 1964 ExecutionContext *execution_context) override { 1965 Status error; 1966 const int short_option = m_getopt_table[option_idx].val; 1967 1968 switch (short_option) { 1969 case 'm': 1970 m_prefer_mangled.SetCurrentValue(true); 1971 m_prefer_mangled.SetOptionWasSet(); 1972 break; 1973 1974 case 's': 1975 m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum( 1976 option_arg, GetDefinitions()[option_idx].enum_values, 1977 eSortOrderNone, error); 1978 break; 1979 1980 default: 1981 llvm_unreachable("Unimplemented option"); 1982 } 1983 return error; 1984 } 1985 1986 void OptionParsingStarting(ExecutionContext *execution_context) override { 1987 m_sort_order = eSortOrderNone; 1988 m_prefer_mangled.Clear(); 1989 } 1990 1991 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 1992 return llvm::ArrayRef(g_target_modules_dump_symtab_options); 1993 } 1994 1995 SortOrder m_sort_order = eSortOrderNone; 1996 OptionValueBoolean m_prefer_mangled = {false, false}; 1997 }; 1998 1999 protected: 2000 void DoExecute(Args &command, CommandReturnObject &result) override { 2001 Target &target = GetTarget(); 2002 uint32_t num_dumped = 0; 2003 Mangled::NamePreference name_preference = 2004 (m_options.m_prefer_mangled ? Mangled::ePreferMangled 2005 : Mangled::ePreferDemangled); 2006 2007 uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize(); 2008 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2009 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2010 2011 if (command.GetArgumentCount() == 0) { 2012 // Dump all sections for all modules images 2013 const ModuleList &module_list = target.GetImages(); 2014 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex()); 2015 const size_t num_modules = module_list.GetSize(); 2016 if (num_modules > 0) { 2017 result.GetOutputStream().Format( 2018 "Dumping symbol table for {0} modules.\n", num_modules); 2019 for (ModuleSP module_sp : module_list.ModulesNoLocking()) { 2020 if (num_dumped > 0) { 2021 result.GetOutputStream().EOL(); 2022 result.GetOutputStream().EOL(); 2023 } 2024 if (INTERRUPT_REQUESTED(GetDebugger(), 2025 "Interrupted in dump all symtabs with {0} " 2026 "of {1} dumped.", num_dumped, num_modules)) 2027 break; 2028 2029 num_dumped++; 2030 DumpModuleSymtab(m_interpreter, result.GetOutputStream(), 2031 module_sp.get(), m_options.m_sort_order, 2032 name_preference); 2033 } 2034 } else { 2035 result.AppendError("the target has no associated executable images"); 2036 return; 2037 } 2038 } else { 2039 // Dump specified images (by basename or fullpath) 2040 const char *arg_cstr; 2041 for (int arg_idx = 0; 2042 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; 2043 ++arg_idx) { 2044 ModuleList module_list; 2045 const size_t num_matches = 2046 FindModulesByName(&target, arg_cstr, module_list, true); 2047 if (num_matches > 0) { 2048 for (ModuleSP module_sp : module_list.Modules()) { 2049 if (module_sp) { 2050 if (num_dumped > 0) { 2051 result.GetOutputStream().EOL(); 2052 result.GetOutputStream().EOL(); 2053 } 2054 if (INTERRUPT_REQUESTED(GetDebugger(), 2055 "Interrupted in dump symtab list with {0} of {1} dumped.", 2056 num_dumped, num_matches)) 2057 break; 2058 2059 num_dumped++; 2060 DumpModuleSymtab(m_interpreter, result.GetOutputStream(), 2061 module_sp.get(), m_options.m_sort_order, 2062 name_preference); 2063 } 2064 } 2065 } else 2066 result.AppendWarningWithFormat( 2067 "Unable to find an image that matches '%s'.\n", arg_cstr); 2068 } 2069 } 2070 2071 if (num_dumped > 0) 2072 result.SetStatus(eReturnStatusSuccessFinishResult); 2073 else { 2074 result.AppendError("no matching executable images found"); 2075 } 2076 } 2077 2078 CommandOptions m_options; 2079 }; 2080 2081 #pragma mark CommandObjectTargetModulesDumpSections 2082 2083 // Image section dumping command 2084 2085 class CommandObjectTargetModulesDumpSections 2086 : public CommandObjectTargetModulesModuleAutoComplete { 2087 public: 2088 CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter) 2089 : CommandObjectTargetModulesModuleAutoComplete( 2090 interpreter, "target modules dump sections", 2091 "Dump the sections from one or more target modules.", 2092 //"target modules dump sections [<file1> ...]") 2093 nullptr, eCommandRequiresTarget) {} 2094 2095 ~CommandObjectTargetModulesDumpSections() override = default; 2096 2097 protected: 2098 void DoExecute(Args &command, CommandReturnObject &result) override { 2099 Target &target = GetTarget(); 2100 uint32_t num_dumped = 0; 2101 2102 uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize(); 2103 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2104 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2105 2106 if (command.GetArgumentCount() == 0) { 2107 // Dump all sections for all modules images 2108 const size_t num_modules = target.GetImages().GetSize(); 2109 if (num_modules == 0) { 2110 result.AppendError("the target has no associated executable images"); 2111 return; 2112 } 2113 2114 result.GetOutputStream().Format("Dumping sections for {0} modules.\n", 2115 num_modules); 2116 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) { 2117 if (INTERRUPT_REQUESTED(GetDebugger(), 2118 "Interrupted in dump all sections with {0} of {1} dumped", 2119 image_idx, num_modules)) 2120 break; 2121 2122 num_dumped++; 2123 DumpModuleSections( 2124 m_interpreter, result.GetOutputStream(), 2125 target.GetImages().GetModulePointerAtIndex(image_idx)); 2126 } 2127 } else { 2128 // Dump specified images (by basename or fullpath) 2129 const char *arg_cstr; 2130 for (int arg_idx = 0; 2131 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; 2132 ++arg_idx) { 2133 ModuleList module_list; 2134 const size_t num_matches = 2135 FindModulesByName(&target, arg_cstr, module_list, true); 2136 if (num_matches > 0) { 2137 for (size_t i = 0; i < num_matches; ++i) { 2138 if (INTERRUPT_REQUESTED(GetDebugger(), 2139 "Interrupted in dump section list with {0} of {1} dumped.", 2140 i, num_matches)) 2141 break; 2142 2143 Module *module = module_list.GetModulePointerAtIndex(i); 2144 if (module) { 2145 num_dumped++; 2146 DumpModuleSections(m_interpreter, result.GetOutputStream(), 2147 module); 2148 } 2149 } 2150 } else { 2151 // Check the global list 2152 std::lock_guard<std::recursive_mutex> guard( 2153 Module::GetAllocationModuleCollectionMutex()); 2154 2155 result.AppendWarningWithFormat( 2156 "Unable to find an image that matches '%s'.\n", arg_cstr); 2157 } 2158 } 2159 } 2160 2161 if (num_dumped > 0) 2162 result.SetStatus(eReturnStatusSuccessFinishResult); 2163 else { 2164 result.AppendError("no matching executable images found"); 2165 } 2166 } 2167 }; 2168 2169 class CommandObjectTargetModulesDumpClangPCMInfo : public CommandObjectParsed { 2170 public: 2171 CommandObjectTargetModulesDumpClangPCMInfo(CommandInterpreter &interpreter) 2172 : CommandObjectParsed( 2173 interpreter, "target modules dump pcm-info", 2174 "Dump information about the given clang module (pcm).") { 2175 // Take a single file argument. 2176 AddSimpleArgumentList(eArgTypeFilename); 2177 } 2178 2179 ~CommandObjectTargetModulesDumpClangPCMInfo() override = default; 2180 2181 protected: 2182 void DoExecute(Args &command, CommandReturnObject &result) override { 2183 if (command.GetArgumentCount() != 1) { 2184 result.AppendErrorWithFormat("'%s' takes exactly one pcm path argument.", 2185 m_cmd_name.c_str()); 2186 return; 2187 } 2188 2189 const char *pcm_path = command.GetArgumentAtIndex(0); 2190 const FileSpec pcm_file{pcm_path}; 2191 2192 if (pcm_file.GetFileNameExtension() != ".pcm") { 2193 result.AppendError("file must have a .pcm extension"); 2194 return; 2195 } 2196 2197 if (!FileSystem::Instance().Exists(pcm_file)) { 2198 result.AppendError("pcm file does not exist"); 2199 return; 2200 } 2201 2202 clang::CompilerInstance compiler; 2203 compiler.createDiagnostics(); 2204 2205 const char *clang_args[] = {"clang", pcm_path}; 2206 compiler.setInvocation(clang::createInvocation(clang_args)); 2207 2208 // Pass empty deleter to not attempt to free memory that was allocated 2209 // outside of the current scope, possibly statically. 2210 std::shared_ptr<llvm::raw_ostream> Out( 2211 &result.GetOutputStream().AsRawOstream(), [](llvm::raw_ostream *) {}); 2212 clang::DumpModuleInfoAction dump_module_info(Out); 2213 // DumpModuleInfoAction requires ObjectFilePCHContainerReader. 2214 compiler.getPCHContainerOperations()->registerReader( 2215 std::make_unique<clang::ObjectFilePCHContainerReader>()); 2216 2217 if (compiler.ExecuteAction(dump_module_info)) 2218 result.SetStatus(eReturnStatusSuccessFinishResult); 2219 } 2220 }; 2221 2222 #pragma mark CommandObjectTargetModulesDumpClangAST 2223 2224 // Clang AST dumping command 2225 2226 class CommandObjectTargetModulesDumpClangAST 2227 : public CommandObjectTargetModulesModuleAutoComplete { 2228 public: 2229 CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter) 2230 : CommandObjectTargetModulesModuleAutoComplete( 2231 interpreter, "target modules dump ast", 2232 "Dump the clang ast for a given module's symbol file.", 2233 //"target modules dump ast [<file1> ...]") 2234 nullptr, eCommandRequiresTarget) {} 2235 2236 ~CommandObjectTargetModulesDumpClangAST() override = default; 2237 2238 protected: 2239 void DoExecute(Args &command, CommandReturnObject &result) override { 2240 Target &target = GetTarget(); 2241 2242 const ModuleList &module_list = target.GetImages(); 2243 const size_t num_modules = module_list.GetSize(); 2244 if (num_modules == 0) { 2245 result.AppendError("the target has no associated executable images"); 2246 return; 2247 } 2248 2249 if (command.GetArgumentCount() == 0) { 2250 // Dump all ASTs for all modules images 2251 result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n", 2252 num_modules); 2253 for (ModuleSP module_sp : module_list.ModulesNoLocking()) { 2254 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping clang ast")) 2255 break; 2256 if (SymbolFile *sf = module_sp->GetSymbolFile()) 2257 sf->DumpClangAST(result.GetOutputStream()); 2258 } 2259 result.SetStatus(eReturnStatusSuccessFinishResult); 2260 return; 2261 } 2262 2263 // Dump specified ASTs (by basename or fullpath) 2264 for (const Args::ArgEntry &arg : command.entries()) { 2265 ModuleList module_list; 2266 const size_t num_matches = 2267 FindModulesByName(&target, arg.c_str(), module_list, true); 2268 if (num_matches == 0) { 2269 // Check the global list 2270 std::lock_guard<std::recursive_mutex> guard( 2271 Module::GetAllocationModuleCollectionMutex()); 2272 2273 result.AppendWarningWithFormat( 2274 "Unable to find an image that matches '%s'.\n", arg.c_str()); 2275 continue; 2276 } 2277 2278 for (size_t i = 0; i < num_matches; ++i) { 2279 if (INTERRUPT_REQUESTED(GetDebugger(), 2280 "Interrupted in dump clang ast list with {0} of {1} dumped.", 2281 i, num_matches)) 2282 break; 2283 2284 Module *m = module_list.GetModulePointerAtIndex(i); 2285 if (SymbolFile *sf = m->GetSymbolFile()) 2286 sf->DumpClangAST(result.GetOutputStream()); 2287 } 2288 } 2289 result.SetStatus(eReturnStatusSuccessFinishResult); 2290 } 2291 }; 2292 2293 #pragma mark CommandObjectTargetModulesDumpSymfile 2294 2295 // Image debug symbol dumping command 2296 2297 class CommandObjectTargetModulesDumpSymfile 2298 : public CommandObjectTargetModulesModuleAutoComplete { 2299 public: 2300 CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter) 2301 : CommandObjectTargetModulesModuleAutoComplete( 2302 interpreter, "target modules dump symfile", 2303 "Dump the debug symbol file for one or more target modules.", 2304 //"target modules dump symfile [<file1> ...]") 2305 nullptr, eCommandRequiresTarget) {} 2306 2307 ~CommandObjectTargetModulesDumpSymfile() override = default; 2308 2309 protected: 2310 void DoExecute(Args &command, CommandReturnObject &result) override { 2311 Target &target = GetTarget(); 2312 uint32_t num_dumped = 0; 2313 2314 uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize(); 2315 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2316 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2317 2318 if (command.GetArgumentCount() == 0) { 2319 // Dump all sections for all modules images 2320 const ModuleList &target_modules = target.GetImages(); 2321 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); 2322 const size_t num_modules = target_modules.GetSize(); 2323 if (num_modules == 0) { 2324 result.AppendError("the target has no associated executable images"); 2325 return; 2326 } 2327 result.GetOutputStream().Format( 2328 "Dumping debug symbols for {0} modules.\n", num_modules); 2329 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) { 2330 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted in dumping all " 2331 "debug symbols with {0} of {1} modules dumped", 2332 num_dumped, num_modules)) 2333 break; 2334 2335 if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get())) 2336 num_dumped++; 2337 } 2338 } else { 2339 // Dump specified images (by basename or fullpath) 2340 const char *arg_cstr; 2341 for (int arg_idx = 0; 2342 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; 2343 ++arg_idx) { 2344 ModuleList module_list; 2345 const size_t num_matches = 2346 FindModulesByName(&target, arg_cstr, module_list, true); 2347 if (num_matches > 0) { 2348 for (size_t i = 0; i < num_matches; ++i) { 2349 if (INTERRUPT_REQUESTED(GetDebugger(), "Interrupted dumping {0} " 2350 "of {1} requested modules", 2351 i, num_matches)) 2352 break; 2353 Module *module = module_list.GetModulePointerAtIndex(i); 2354 if (module) { 2355 if (DumpModuleSymbolFile(result.GetOutputStream(), module)) 2356 num_dumped++; 2357 } 2358 } 2359 } else 2360 result.AppendWarningWithFormat( 2361 "Unable to find an image that matches '%s'.\n", arg_cstr); 2362 } 2363 } 2364 2365 if (num_dumped > 0) 2366 result.SetStatus(eReturnStatusSuccessFinishResult); 2367 else { 2368 result.AppendError("no matching executable images found"); 2369 } 2370 } 2371 }; 2372 2373 #pragma mark CommandObjectTargetModulesDumpLineTable 2374 #define LLDB_OPTIONS_target_modules_dump 2375 #include "CommandOptions.inc" 2376 2377 // Image debug line table dumping command 2378 2379 class CommandObjectTargetModulesDumpLineTable 2380 : public CommandObjectTargetModulesSourceFileAutoComplete { 2381 public: 2382 CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter) 2383 : CommandObjectTargetModulesSourceFileAutoComplete( 2384 interpreter, "target modules dump line-table", 2385 "Dump the line table for one or more compilation units.", nullptr, 2386 eCommandRequiresTarget) {} 2387 2388 ~CommandObjectTargetModulesDumpLineTable() override = default; 2389 2390 Options *GetOptions() override { return &m_options; } 2391 2392 protected: 2393 void DoExecute(Args &command, CommandReturnObject &result) override { 2394 Target *target = m_exe_ctx.GetTargetPtr(); 2395 uint32_t total_num_dumped = 0; 2396 2397 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize(); 2398 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2399 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2400 2401 if (command.GetArgumentCount() == 0) { 2402 result.AppendError("file option must be specified."); 2403 return; 2404 } else { 2405 // Dump specified images (by basename or fullpath) 2406 const char *arg_cstr; 2407 for (int arg_idx = 0; 2408 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; 2409 ++arg_idx) { 2410 FileSpec file_spec(arg_cstr); 2411 2412 const ModuleList &target_modules = target->GetImages(); 2413 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); 2414 size_t num_modules = target_modules.GetSize(); 2415 if (num_modules > 0) { 2416 uint32_t num_dumped = 0; 2417 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) { 2418 if (INTERRUPT_REQUESTED(GetDebugger(), 2419 "Interrupted in dump all line tables with " 2420 "{0} of {1} dumped", num_dumped, 2421 num_modules)) 2422 break; 2423 2424 if (DumpCompileUnitLineTable( 2425 m_interpreter, result.GetOutputStream(), module_sp.get(), 2426 file_spec, 2427 m_options.m_verbose ? eDescriptionLevelFull 2428 : eDescriptionLevelBrief)) 2429 num_dumped++; 2430 } 2431 if (num_dumped == 0) 2432 result.AppendWarningWithFormat( 2433 "No source filenames matched '%s'.\n", arg_cstr); 2434 else 2435 total_num_dumped += num_dumped; 2436 } 2437 } 2438 } 2439 2440 if (total_num_dumped > 0) 2441 result.SetStatus(eReturnStatusSuccessFinishResult); 2442 else { 2443 result.AppendError("no source filenames matched any command arguments"); 2444 } 2445 } 2446 2447 class CommandOptions : public Options { 2448 public: 2449 CommandOptions() { OptionParsingStarting(nullptr); } 2450 2451 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 2452 ExecutionContext *execution_context) override { 2453 assert(option_idx == 0 && "We only have one option."); 2454 m_verbose = true; 2455 2456 return Status(); 2457 } 2458 2459 void OptionParsingStarting(ExecutionContext *execution_context) override { 2460 m_verbose = false; 2461 } 2462 2463 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 2464 return llvm::ArrayRef(g_target_modules_dump_options); 2465 } 2466 2467 bool m_verbose; 2468 }; 2469 2470 CommandOptions m_options; 2471 }; 2472 2473 #pragma mark CommandObjectTargetModulesDumpSeparateDebugInfoFiles 2474 #define LLDB_OPTIONS_target_modules_dump_separate_debug_info 2475 #include "CommandOptions.inc" 2476 2477 // Image debug separate debug info dumping command 2478 2479 class CommandObjectTargetModulesDumpSeparateDebugInfoFiles 2480 : public CommandObjectTargetModulesModuleAutoComplete { 2481 public: 2482 CommandObjectTargetModulesDumpSeparateDebugInfoFiles( 2483 CommandInterpreter &interpreter) 2484 : CommandObjectTargetModulesModuleAutoComplete( 2485 interpreter, "target modules dump separate-debug-info", 2486 "List the separate debug info symbol files for one or more target " 2487 "modules.", 2488 nullptr, eCommandRequiresTarget) {} 2489 2490 ~CommandObjectTargetModulesDumpSeparateDebugInfoFiles() override = default; 2491 2492 Options *GetOptions() override { return &m_options; } 2493 2494 class CommandOptions : public Options { 2495 public: 2496 CommandOptions() = default; 2497 2498 ~CommandOptions() override = default; 2499 2500 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 2501 ExecutionContext *execution_context) override { 2502 Status error; 2503 const int short_option = m_getopt_table[option_idx].val; 2504 2505 switch (short_option) { 2506 case 'j': 2507 m_json.SetCurrentValue(true); 2508 m_json.SetOptionWasSet(); 2509 break; 2510 case 'e': 2511 m_errors_only.SetCurrentValue(true); 2512 m_errors_only.SetOptionWasSet(); 2513 break; 2514 default: 2515 llvm_unreachable("Unimplemented option"); 2516 } 2517 return error; 2518 } 2519 2520 void OptionParsingStarting(ExecutionContext *execution_context) override { 2521 m_json.Clear(); 2522 m_errors_only.Clear(); 2523 } 2524 2525 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 2526 return llvm::ArrayRef(g_target_modules_dump_separate_debug_info_options); 2527 } 2528 2529 OptionValueBoolean m_json = false; 2530 OptionValueBoolean m_errors_only = false; 2531 }; 2532 2533 protected: 2534 void DoExecute(Args &command, CommandReturnObject &result) override { 2535 Target &target = GetTarget(); 2536 uint32_t num_dumped = 0; 2537 2538 uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize(); 2539 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 2540 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 2541 2542 StructuredData::Array separate_debug_info_lists_by_module; 2543 if (command.GetArgumentCount() == 0) { 2544 // Dump all sections for all modules images 2545 const ModuleList &target_modules = target.GetImages(); 2546 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); 2547 const size_t num_modules = target_modules.GetSize(); 2548 if (num_modules == 0) { 2549 result.AppendError("the target has no associated executable images"); 2550 return; 2551 } 2552 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) { 2553 if (INTERRUPT_REQUESTED( 2554 GetDebugger(), 2555 "Interrupted in dumping all " 2556 "separate debug info with {0} of {1} modules dumped", 2557 num_dumped, num_modules)) 2558 break; 2559 2560 if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module, 2561 module_sp.get(), 2562 bool(m_options.m_errors_only))) 2563 num_dumped++; 2564 } 2565 } else { 2566 // Dump specified images (by basename or fullpath) 2567 const char *arg_cstr; 2568 for (int arg_idx = 0; 2569 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr; 2570 ++arg_idx) { 2571 ModuleList module_list; 2572 const size_t num_matches = 2573 FindModulesByName(&target, arg_cstr, module_list, true); 2574 if (num_matches > 0) { 2575 for (size_t i = 0; i < num_matches; ++i) { 2576 if (INTERRUPT_REQUESTED(GetDebugger(), 2577 "Interrupted dumping {0} " 2578 "of {1} requested modules", 2579 i, num_matches)) 2580 break; 2581 Module *module = module_list.GetModulePointerAtIndex(i); 2582 if (GetSeparateDebugInfoList(separate_debug_info_lists_by_module, 2583 module, bool(m_options.m_errors_only))) 2584 num_dumped++; 2585 } 2586 } else 2587 result.AppendWarningWithFormat( 2588 "Unable to find an image that matches '%s'.\n", arg_cstr); 2589 } 2590 } 2591 2592 if (num_dumped > 0) { 2593 Stream &strm = result.GetOutputStream(); 2594 // Display the debug info files in some format. 2595 if (m_options.m_json) { 2596 // JSON format 2597 separate_debug_info_lists_by_module.Dump(strm, 2598 /*pretty_print=*/true); 2599 } else { 2600 // Human-readable table format 2601 separate_debug_info_lists_by_module.ForEach( 2602 [&result, &strm](StructuredData::Object *obj) { 2603 if (!obj) { 2604 return false; 2605 } 2606 2607 // Each item in `separate_debug_info_lists_by_module` should be a 2608 // valid structured data dictionary. 2609 StructuredData::Dictionary *separate_debug_info_list = 2610 obj->GetAsDictionary(); 2611 if (!separate_debug_info_list) { 2612 return false; 2613 } 2614 2615 llvm::StringRef type; 2616 llvm::StringRef symfile; 2617 StructuredData::Array *files; 2618 if (!(separate_debug_info_list->GetValueForKeyAsString("type", 2619 type) && 2620 separate_debug_info_list->GetValueForKeyAsString("symfile", 2621 symfile) && 2622 separate_debug_info_list->GetValueForKeyAsArray( 2623 "separate-debug-info-files", files))) { 2624 assert(false); 2625 } 2626 2627 strm << "Symbol file: " << symfile; 2628 strm.EOL(); 2629 strm << "Type: \"" << type << "\""; 2630 strm.EOL(); 2631 if (type == "dwo") { 2632 DumpDwoFilesTable(strm, *files); 2633 } else if (type == "oso") { 2634 DumpOsoFilesTable(strm, *files); 2635 } else { 2636 result.AppendWarningWithFormat( 2637 "Found unsupported debug info type '%s'.\n", 2638 type.str().c_str()); 2639 } 2640 return true; 2641 }); 2642 } 2643 result.SetStatus(eReturnStatusSuccessFinishResult); 2644 } else { 2645 result.AppendError("no matching executable images found"); 2646 } 2647 } 2648 2649 CommandOptions m_options; 2650 }; 2651 2652 #pragma mark CommandObjectTargetModulesDump 2653 2654 // Dump multi-word command for target modules 2655 2656 class CommandObjectTargetModulesDump : public CommandObjectMultiword { 2657 public: 2658 // Constructors and Destructors 2659 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) 2660 : CommandObjectMultiword( 2661 interpreter, "target modules dump", 2662 "Commands for dumping information about one or more target " 2663 "modules.", 2664 "target modules dump " 2665 "[objfile|symtab|sections|ast|symfile|line-table|pcm-info|separate-" 2666 "debug-info] " 2667 "[<file1> <file2> ...]") { 2668 LoadSubCommand("objfile", 2669 CommandObjectSP( 2670 new CommandObjectTargetModulesDumpObjfile(interpreter))); 2671 LoadSubCommand( 2672 "symtab", 2673 CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter))); 2674 LoadSubCommand("sections", 2675 CommandObjectSP(new CommandObjectTargetModulesDumpSections( 2676 interpreter))); 2677 LoadSubCommand("symfile", 2678 CommandObjectSP( 2679 new CommandObjectTargetModulesDumpSymfile(interpreter))); 2680 LoadSubCommand( 2681 "ast", CommandObjectSP( 2682 new CommandObjectTargetModulesDumpClangAST(interpreter))); 2683 LoadSubCommand("line-table", 2684 CommandObjectSP(new CommandObjectTargetModulesDumpLineTable( 2685 interpreter))); 2686 LoadSubCommand( 2687 "pcm-info", 2688 CommandObjectSP( 2689 new CommandObjectTargetModulesDumpClangPCMInfo(interpreter))); 2690 LoadSubCommand("separate-debug-info", 2691 CommandObjectSP( 2692 new CommandObjectTargetModulesDumpSeparateDebugInfoFiles( 2693 interpreter))); 2694 } 2695 2696 ~CommandObjectTargetModulesDump() override = default; 2697 }; 2698 2699 class CommandObjectTargetModulesAdd : public CommandObjectParsed { 2700 public: 2701 CommandObjectTargetModulesAdd(CommandInterpreter &interpreter) 2702 : CommandObjectParsed(interpreter, "target modules add", 2703 "Add a new module to the current target's modules.", 2704 "target modules add [<module>]", 2705 eCommandRequiresTarget), 2706 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0, 2707 eArgTypeFilename, 2708 "Fullpath to a stand alone debug " 2709 "symbols file for when debug symbols " 2710 "are not in the executable.") { 2711 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL, 2712 LLDB_OPT_SET_1); 2713 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2714 m_option_group.Finalize(); 2715 AddSimpleArgumentList(eArgTypePath, eArgRepeatStar); 2716 } 2717 2718 ~CommandObjectTargetModulesAdd() override = default; 2719 2720 Options *GetOptions() override { return &m_option_group; } 2721 2722 protected: 2723 OptionGroupOptions m_option_group; 2724 OptionGroupUUID m_uuid_option_group; 2725 OptionGroupFile m_symbol_file; 2726 2727 void DoExecute(Args &args, CommandReturnObject &result) override { 2728 Target &target = GetTarget(); 2729 bool flush = false; 2730 2731 const size_t argc = args.GetArgumentCount(); 2732 if (argc == 0) { 2733 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) { 2734 // We are given a UUID only, go locate the file 2735 ModuleSpec module_spec; 2736 module_spec.GetUUID() = 2737 m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2738 if (m_symbol_file.GetOptionValue().OptionWasSet()) 2739 module_spec.GetSymbolFileSpec() = 2740 m_symbol_file.GetOptionValue().GetCurrentValue(); 2741 Status error; 2742 if (PluginManager::DownloadObjectAndSymbolFile(module_spec, error)) { 2743 ModuleSP module_sp( 2744 target.GetOrCreateModule(module_spec, true /* notify */)); 2745 if (module_sp) { 2746 result.SetStatus(eReturnStatusSuccessFinishResult); 2747 return; 2748 } else { 2749 StreamString strm; 2750 module_spec.GetUUID().Dump(strm); 2751 if (module_spec.GetFileSpec()) { 2752 if (module_spec.GetSymbolFileSpec()) { 2753 result.AppendErrorWithFormat( 2754 "Unable to create the executable or symbol file with " 2755 "UUID %s with path %s and symbol file %s", 2756 strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(), 2757 module_spec.GetSymbolFileSpec().GetPath().c_str()); 2758 } else { 2759 result.AppendErrorWithFormat( 2760 "Unable to create the executable or symbol file with " 2761 "UUID %s with path %s", 2762 strm.GetData(), 2763 module_spec.GetFileSpec().GetPath().c_str()); 2764 } 2765 } else { 2766 result.AppendErrorWithFormat("Unable to create the executable " 2767 "or symbol file with UUID %s", 2768 strm.GetData()); 2769 } 2770 return; 2771 } 2772 } else { 2773 StreamString strm; 2774 module_spec.GetUUID().Dump(strm); 2775 result.AppendErrorWithFormat( 2776 "Unable to locate the executable or symbol file with UUID %s", 2777 strm.GetData()); 2778 result.SetError(std::move(error)); 2779 return; 2780 } 2781 } else { 2782 result.AppendError( 2783 "one or more executable image paths must be specified"); 2784 return; 2785 } 2786 } else { 2787 for (auto &entry : args.entries()) { 2788 if (entry.ref().empty()) 2789 continue; 2790 2791 FileSpec file_spec(entry.ref()); 2792 if (FileSystem::Instance().Exists(file_spec)) { 2793 ModuleSpec module_spec(file_spec); 2794 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) 2795 module_spec.GetUUID() = 2796 m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2797 if (m_symbol_file.GetOptionValue().OptionWasSet()) 2798 module_spec.GetSymbolFileSpec() = 2799 m_symbol_file.GetOptionValue().GetCurrentValue(); 2800 if (!module_spec.GetArchitecture().IsValid()) 2801 module_spec.GetArchitecture() = target.GetArchitecture(); 2802 Status error; 2803 ModuleSP module_sp( 2804 target.GetOrCreateModule(module_spec, true /* notify */, &error)); 2805 if (!module_sp) { 2806 const char *error_cstr = error.AsCString(); 2807 if (error_cstr) 2808 result.AppendError(error_cstr); 2809 else 2810 result.AppendErrorWithFormat("unsupported module: %s", 2811 entry.c_str()); 2812 return; 2813 } else { 2814 flush = true; 2815 } 2816 result.SetStatus(eReturnStatusSuccessFinishResult); 2817 } else { 2818 std::string resolved_path = file_spec.GetPath(); 2819 if (resolved_path != entry.ref()) { 2820 result.AppendErrorWithFormat( 2821 "invalid module path '%s' with resolved path '%s'\n", 2822 entry.ref().str().c_str(), resolved_path.c_str()); 2823 break; 2824 } 2825 result.AppendErrorWithFormat("invalid module path '%s'\n", 2826 entry.c_str()); 2827 break; 2828 } 2829 } 2830 } 2831 2832 if (flush) { 2833 ProcessSP process = target.GetProcessSP(); 2834 if (process) 2835 process->Flush(); 2836 } 2837 } 2838 }; 2839 2840 class CommandObjectTargetModulesLoad 2841 : public CommandObjectTargetModulesModuleAutoComplete { 2842 public: 2843 CommandObjectTargetModulesLoad(CommandInterpreter &interpreter) 2844 : CommandObjectTargetModulesModuleAutoComplete( 2845 interpreter, "target modules load", 2846 "Set the load addresses for one or more sections in a target " 2847 "module.", 2848 "target modules load [--file <module> --uuid <uuid>] <sect-name> " 2849 "<address> [<sect-name> <address> ....]", 2850 eCommandRequiresTarget), 2851 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName, 2852 "Fullpath or basename for module to load.", ""), 2853 m_load_option(LLDB_OPT_SET_1, false, "load", 'l', 2854 "Write file contents to the memory.", false, true), 2855 m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p', 2856 "Set PC to the entry point." 2857 " Only applicable with '--load' option.", 2858 false, true), 2859 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset, 2860 "Set the load address for all sections to be the " 2861 "virtual address in the file plus the offset.", 2862 0) { 2863 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL, 2864 LLDB_OPT_SET_1); 2865 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2866 m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2867 m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2868 m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 2869 m_option_group.Finalize(); 2870 } 2871 2872 ~CommandObjectTargetModulesLoad() override = default; 2873 2874 Options *GetOptions() override { return &m_option_group; } 2875 2876 protected: 2877 void DoExecute(Args &args, CommandReturnObject &result) override { 2878 Target &target = GetTarget(); 2879 const bool load = m_load_option.GetOptionValue().GetCurrentValue(); 2880 const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue(); 2881 2882 const size_t argc = args.GetArgumentCount(); 2883 ModuleSpec module_spec; 2884 bool search_using_module_spec = false; 2885 2886 // Allow "load" option to work without --file or --uuid option. 2887 if (load) { 2888 if (!m_file_option.GetOptionValue().OptionWasSet() && 2889 !m_uuid_option_group.GetOptionValue().OptionWasSet()) { 2890 ModuleList &module_list = target.GetImages(); 2891 if (module_list.GetSize() == 1) { 2892 search_using_module_spec = true; 2893 module_spec.GetFileSpec() = 2894 module_list.GetModuleAtIndex(0)->GetFileSpec(); 2895 } 2896 } 2897 } 2898 2899 if (m_file_option.GetOptionValue().OptionWasSet()) { 2900 search_using_module_spec = true; 2901 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue(); 2902 const bool use_global_module_list = true; 2903 ModuleList module_list; 2904 const size_t num_matches = FindModulesByName( 2905 &target, arg_cstr, module_list, use_global_module_list); 2906 if (num_matches == 1) { 2907 module_spec.GetFileSpec() = 2908 module_list.GetModuleAtIndex(0)->GetFileSpec(); 2909 } else if (num_matches > 1) { 2910 search_using_module_spec = false; 2911 result.AppendErrorWithFormat( 2912 "more than 1 module matched by name '%s'\n", arg_cstr); 2913 } else { 2914 search_using_module_spec = false; 2915 result.AppendErrorWithFormat("no object file for module '%s'\n", 2916 arg_cstr); 2917 } 2918 } 2919 2920 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) { 2921 search_using_module_spec = true; 2922 module_spec.GetUUID() = 2923 m_uuid_option_group.GetOptionValue().GetCurrentValue(); 2924 } 2925 2926 if (search_using_module_spec) { 2927 ModuleList matching_modules; 2928 target.GetImages().FindModules(module_spec, matching_modules); 2929 const size_t num_matches = matching_modules.GetSize(); 2930 2931 char path[PATH_MAX]; 2932 if (num_matches == 1) { 2933 Module *module = matching_modules.GetModulePointerAtIndex(0); 2934 if (module) { 2935 ObjectFile *objfile = module->GetObjectFile(); 2936 if (objfile) { 2937 SectionList *section_list = module->GetSectionList(); 2938 if (section_list) { 2939 bool changed = false; 2940 if (argc == 0) { 2941 if (m_slide_option.GetOptionValue().OptionWasSet()) { 2942 const addr_t slide = 2943 m_slide_option.GetOptionValue().GetCurrentValue(); 2944 const bool slide_is_offset = true; 2945 module->SetLoadAddress(target, slide, slide_is_offset, 2946 changed); 2947 } else { 2948 result.AppendError("one or more section name + load " 2949 "address pair must be specified"); 2950 return; 2951 } 2952 } else { 2953 if (m_slide_option.GetOptionValue().OptionWasSet()) { 2954 result.AppendError("The \"--slide <offset>\" option can't " 2955 "be used in conjunction with setting " 2956 "section load addresses.\n"); 2957 return; 2958 } 2959 2960 for (size_t i = 0; i < argc; i += 2) { 2961 const char *sect_name = args.GetArgumentAtIndex(i); 2962 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1); 2963 if (sect_name && load_addr_cstr) { 2964 ConstString const_sect_name(sect_name); 2965 addr_t load_addr; 2966 if (llvm::to_integer(load_addr_cstr, load_addr)) { 2967 SectionSP section_sp( 2968 section_list->FindSectionByName(const_sect_name)); 2969 if (section_sp) { 2970 if (section_sp->IsThreadSpecific()) { 2971 result.AppendErrorWithFormat( 2972 "thread specific sections are not yet " 2973 "supported (section '%s')\n", 2974 sect_name); 2975 break; 2976 } else { 2977 if (target.GetSectionLoadList().SetSectionLoadAddress( 2978 section_sp, load_addr)) 2979 changed = true; 2980 result.AppendMessageWithFormat( 2981 "section '%s' loaded at 0x%" PRIx64 "\n", 2982 sect_name, load_addr); 2983 } 2984 } else { 2985 result.AppendErrorWithFormat("no section found that " 2986 "matches the section " 2987 "name '%s'\n", 2988 sect_name); 2989 break; 2990 } 2991 } else { 2992 result.AppendErrorWithFormat( 2993 "invalid load address string '%s'\n", load_addr_cstr); 2994 break; 2995 } 2996 } else { 2997 if (sect_name) 2998 result.AppendError("section names must be followed by " 2999 "a load address.\n"); 3000 else 3001 result.AppendError("one or more section name + load " 3002 "address pair must be specified.\n"); 3003 break; 3004 } 3005 } 3006 } 3007 3008 if (changed) { 3009 target.ModulesDidLoad(matching_modules); 3010 Process *process = m_exe_ctx.GetProcessPtr(); 3011 if (process) 3012 process->Flush(); 3013 } 3014 if (load) { 3015 ProcessSP process = target.CalculateProcess(); 3016 Address file_entry = objfile->GetEntryPointAddress(); 3017 if (!process) { 3018 result.AppendError("No process"); 3019 return; 3020 } 3021 if (set_pc && !file_entry.IsValid()) { 3022 result.AppendError("No entry address in object file"); 3023 return; 3024 } 3025 std::vector<ObjectFile::LoadableData> loadables( 3026 objfile->GetLoadableData(target)); 3027 if (loadables.size() == 0) { 3028 result.AppendError("No loadable sections"); 3029 return; 3030 } 3031 Status error = process->WriteObjectFile(std::move(loadables)); 3032 if (error.Fail()) { 3033 result.AppendError(error.AsCString()); 3034 return; 3035 } 3036 if (set_pc) { 3037 ThreadList &thread_list = process->GetThreadList(); 3038 RegisterContextSP reg_context( 3039 thread_list.GetSelectedThread()->GetRegisterContext()); 3040 addr_t file_entry_addr = file_entry.GetLoadAddress(&target); 3041 if (!reg_context->SetPC(file_entry_addr)) { 3042 result.AppendErrorWithFormat("failed to set PC value to " 3043 "0x%" PRIx64 "\n", 3044 file_entry_addr); 3045 } 3046 } 3047 } 3048 } else { 3049 module->GetFileSpec().GetPath(path, sizeof(path)); 3050 result.AppendErrorWithFormat("no sections in object file '%s'\n", 3051 path); 3052 } 3053 } else { 3054 module->GetFileSpec().GetPath(path, sizeof(path)); 3055 result.AppendErrorWithFormat("no object file for module '%s'\n", 3056 path); 3057 } 3058 } else { 3059 FileSpec *module_spec_file = module_spec.GetFileSpecPtr(); 3060 if (module_spec_file) { 3061 module_spec_file->GetPath(path, sizeof(path)); 3062 result.AppendErrorWithFormat("invalid module '%s'.\n", path); 3063 } else 3064 result.AppendError("no module spec"); 3065 } 3066 } else { 3067 std::string uuid_str; 3068 3069 if (module_spec.GetFileSpec()) 3070 module_spec.GetFileSpec().GetPath(path, sizeof(path)); 3071 else 3072 path[0] = '\0'; 3073 3074 if (module_spec.GetUUIDPtr()) 3075 uuid_str = module_spec.GetUUID().GetAsString(); 3076 if (num_matches > 1) { 3077 result.AppendErrorWithFormat( 3078 "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "", 3079 path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str()); 3080 for (size_t i = 0; i < num_matches; ++i) { 3081 if (matching_modules.GetModulePointerAtIndex(i) 3082 ->GetFileSpec() 3083 .GetPath(path, sizeof(path))) 3084 result.AppendMessageWithFormat("%s\n", path); 3085 } 3086 } else { 3087 result.AppendErrorWithFormat( 3088 "no modules were found that match%s%s%s%s.\n", 3089 path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "", 3090 uuid_str.c_str()); 3091 } 3092 } 3093 } else { 3094 result.AppendError("either the \"--file <module>\" or the \"--uuid " 3095 "<uuid>\" option must be specified.\n"); 3096 } 3097 } 3098 3099 OptionGroupOptions m_option_group; 3100 OptionGroupUUID m_uuid_option_group; 3101 OptionGroupString m_file_option; 3102 OptionGroupBoolean m_load_option; 3103 OptionGroupBoolean m_pc_option; 3104 OptionGroupUInt64 m_slide_option; 3105 }; 3106 3107 #pragma mark CommandObjectTargetModulesList 3108 // List images with associated information 3109 #define LLDB_OPTIONS_target_modules_list 3110 #include "CommandOptions.inc" 3111 3112 class CommandObjectTargetModulesList : public CommandObjectParsed { 3113 public: 3114 class CommandOptions : public Options { 3115 public: 3116 CommandOptions() = default; 3117 3118 ~CommandOptions() override = default; 3119 3120 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 3121 ExecutionContext *execution_context) override { 3122 Status error; 3123 3124 const int short_option = m_getopt_table[option_idx].val; 3125 if (short_option == 'g') { 3126 m_use_global_module_list = true; 3127 } else if (short_option == 'a') { 3128 m_module_addr = OptionArgParser::ToAddress( 3129 execution_context, option_arg, LLDB_INVALID_ADDRESS, &error); 3130 } else { 3131 unsigned long width = 0; 3132 option_arg.getAsInteger(0, width); 3133 m_format_array.push_back(std::make_pair(short_option, width)); 3134 } 3135 return error; 3136 } 3137 3138 void OptionParsingStarting(ExecutionContext *execution_context) override { 3139 m_format_array.clear(); 3140 m_use_global_module_list = false; 3141 m_module_addr = LLDB_INVALID_ADDRESS; 3142 } 3143 3144 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 3145 return llvm::ArrayRef(g_target_modules_list_options); 3146 } 3147 3148 // Instance variables to hold the values for command options. 3149 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection; 3150 FormatWidthCollection m_format_array; 3151 bool m_use_global_module_list = false; 3152 lldb::addr_t m_module_addr = LLDB_INVALID_ADDRESS; 3153 }; 3154 3155 CommandObjectTargetModulesList(CommandInterpreter &interpreter) 3156 : CommandObjectParsed( 3157 interpreter, "target modules list", 3158 "List current executable and dependent shared library images.") { 3159 AddSimpleArgumentList(eArgTypeModule, eArgRepeatStar); 3160 } 3161 3162 ~CommandObjectTargetModulesList() override = default; 3163 3164 Options *GetOptions() override { return &m_options; } 3165 3166 protected: 3167 void DoExecute(Args &command, CommandReturnObject &result) override { 3168 Target &target = GetTarget(); 3169 const bool use_global_module_list = m_options.m_use_global_module_list; 3170 // Define a local module list here to ensure it lives longer than any 3171 // "locker" object which might lock its contents below (through the 3172 // "module_list_ptr" variable). 3173 ModuleList module_list; 3174 uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize(); 3175 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 3176 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 3177 // Dump all sections for all modules images 3178 Stream &strm = result.GetOutputStream(); 3179 3180 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) { 3181 Address module_address; 3182 if (module_address.SetLoadAddress(m_options.m_module_addr, &target)) { 3183 ModuleSP module_sp(module_address.GetModule()); 3184 if (module_sp) { 3185 PrintModule(target, module_sp.get(), 0, strm); 3186 result.SetStatus(eReturnStatusSuccessFinishResult); 3187 } else { 3188 result.AppendErrorWithFormat( 3189 "Couldn't find module matching address: 0x%" PRIx64 ".", 3190 m_options.m_module_addr); 3191 } 3192 } else { 3193 result.AppendErrorWithFormat( 3194 "Couldn't find module containing address: 0x%" PRIx64 ".", 3195 m_options.m_module_addr); 3196 } 3197 return; 3198 } 3199 3200 size_t num_modules = 0; 3201 3202 // This locker will be locked on the mutex in module_list_ptr if it is 3203 // non-nullptr. Otherwise it will lock the 3204 // AllocationModuleCollectionMutex when accessing the global module list 3205 // directly. 3206 std::unique_lock<std::recursive_mutex> guard( 3207 Module::GetAllocationModuleCollectionMutex(), std::defer_lock); 3208 3209 const ModuleList *module_list_ptr = nullptr; 3210 const size_t argc = command.GetArgumentCount(); 3211 if (argc == 0) { 3212 if (use_global_module_list) { 3213 guard.lock(); 3214 num_modules = Module::GetNumberAllocatedModules(); 3215 } else { 3216 module_list_ptr = &target.GetImages(); 3217 } 3218 } else { 3219 for (const Args::ArgEntry &arg : command) { 3220 // Dump specified images (by basename or fullpath) 3221 const size_t num_matches = FindModulesByName( 3222 &target, arg.c_str(), module_list, use_global_module_list); 3223 if (num_matches == 0) { 3224 if (argc == 1) { 3225 result.AppendErrorWithFormat("no modules found that match '%s'", 3226 arg.c_str()); 3227 return; 3228 } 3229 } 3230 } 3231 3232 module_list_ptr = &module_list; 3233 } 3234 3235 std::unique_lock<std::recursive_mutex> lock; 3236 if (module_list_ptr != nullptr) { 3237 lock = 3238 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex()); 3239 3240 num_modules = module_list_ptr->GetSize(); 3241 } 3242 3243 if (num_modules > 0) { 3244 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) { 3245 ModuleSP module_sp; 3246 Module *module; 3247 if (module_list_ptr) { 3248 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx); 3249 module = module_sp.get(); 3250 } else { 3251 module = Module::GetAllocatedModuleAtIndex(image_idx); 3252 module_sp = module->shared_from_this(); 3253 } 3254 3255 const size_t indent = strm.Printf("[%3u] ", image_idx); 3256 PrintModule(target, module, indent, strm); 3257 } 3258 result.SetStatus(eReturnStatusSuccessFinishResult); 3259 } else { 3260 if (argc) { 3261 if (use_global_module_list) 3262 result.AppendError( 3263 "the global module list has no matching modules"); 3264 else 3265 result.AppendError("the target has no matching modules"); 3266 } else { 3267 if (use_global_module_list) 3268 result.AppendError("the global module list is empty"); 3269 else 3270 result.AppendError( 3271 "the target has no associated executable images"); 3272 } 3273 return; 3274 } 3275 } 3276 3277 void PrintModule(Target &target, Module *module, int indent, Stream &strm) { 3278 if (module == nullptr) { 3279 strm.PutCString("Null module"); 3280 return; 3281 } 3282 3283 bool dump_object_name = false; 3284 if (m_options.m_format_array.empty()) { 3285 m_options.m_format_array.push_back(std::make_pair('u', 0)); 3286 m_options.m_format_array.push_back(std::make_pair('h', 0)); 3287 m_options.m_format_array.push_back(std::make_pair('f', 0)); 3288 m_options.m_format_array.push_back(std::make_pair('S', 0)); 3289 } 3290 const size_t num_entries = m_options.m_format_array.size(); 3291 bool print_space = false; 3292 for (size_t i = 0; i < num_entries; ++i) { 3293 if (print_space) 3294 strm.PutChar(' '); 3295 print_space = true; 3296 const char format_char = m_options.m_format_array[i].first; 3297 uint32_t width = m_options.m_format_array[i].second; 3298 switch (format_char) { 3299 case 'A': 3300 DumpModuleArchitecture(strm, module, false, width); 3301 break; 3302 3303 case 't': 3304 DumpModuleArchitecture(strm, module, true, width); 3305 break; 3306 3307 case 'f': 3308 DumpFullpath(strm, &module->GetFileSpec(), width); 3309 dump_object_name = true; 3310 break; 3311 3312 case 'd': 3313 DumpDirectory(strm, &module->GetFileSpec(), width); 3314 break; 3315 3316 case 'b': 3317 DumpBasename(strm, &module->GetFileSpec(), width); 3318 dump_object_name = true; 3319 break; 3320 3321 case 'h': 3322 case 'o': 3323 // Image header address 3324 { 3325 uint32_t addr_nibble_width = 3326 target.GetArchitecture().GetAddressByteSize() * 2; 3327 3328 ObjectFile *objfile = module->GetObjectFile(); 3329 if (objfile) { 3330 Address base_addr(objfile->GetBaseAddress()); 3331 if (base_addr.IsValid()) { 3332 if (!target.GetSectionLoadList().IsEmpty()) { 3333 lldb::addr_t load_addr = base_addr.GetLoadAddress(&target); 3334 if (load_addr == LLDB_INVALID_ADDRESS) { 3335 base_addr.Dump(&strm, &target, 3336 Address::DumpStyleModuleWithFileAddress, 3337 Address::DumpStyleFileAddress); 3338 } else { 3339 if (format_char == 'o') { 3340 // Show the offset of slide for the image 3341 strm.Printf("0x%*.*" PRIx64, addr_nibble_width, 3342 addr_nibble_width, 3343 load_addr - base_addr.GetFileAddress()); 3344 } else { 3345 // Show the load address of the image 3346 strm.Printf("0x%*.*" PRIx64, addr_nibble_width, 3347 addr_nibble_width, load_addr); 3348 } 3349 } 3350 break; 3351 } 3352 // The address was valid, but the image isn't loaded, output the 3353 // address in an appropriate format 3354 base_addr.Dump(&strm, &target, Address::DumpStyleFileAddress); 3355 break; 3356 } 3357 } 3358 strm.Printf("%*s", addr_nibble_width + 2, ""); 3359 } 3360 break; 3361 3362 case 'r': { 3363 size_t ref_count = 0; 3364 char in_shared_cache = 'Y'; 3365 3366 ModuleSP module_sp(module->shared_from_this()); 3367 if (!ModuleList::ModuleIsInCache(module)) 3368 in_shared_cache = 'N'; 3369 if (module_sp) { 3370 // Take one away to make sure we don't count our local "module_sp" 3371 ref_count = module_sp.use_count() - 1; 3372 } 3373 if (width) 3374 strm.Printf("{%c %*" PRIu64 "}", in_shared_cache, width, (uint64_t)ref_count); 3375 else 3376 strm.Printf("{%c %" PRIu64 "}", in_shared_cache, (uint64_t)ref_count); 3377 } break; 3378 3379 case 's': 3380 case 'S': { 3381 if (const SymbolFile *symbol_file = module->GetSymbolFile()) { 3382 const FileSpec symfile_spec = 3383 symbol_file->GetObjectFile()->GetFileSpec(); 3384 if (format_char == 'S') { 3385 // Dump symbol file only if different from module file 3386 if (!symfile_spec || symfile_spec == module->GetFileSpec()) { 3387 print_space = false; 3388 break; 3389 } 3390 // Add a newline and indent past the index 3391 strm.Printf("\n%*s", indent, ""); 3392 } 3393 DumpFullpath(strm, &symfile_spec, width); 3394 dump_object_name = true; 3395 break; 3396 } 3397 strm.Printf("%.*s", width, "<NONE>"); 3398 } break; 3399 3400 case 'm': 3401 strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(), 3402 llvm::AlignStyle::Left, width)); 3403 break; 3404 3405 case 'p': 3406 strm.Printf("%p", static_cast<void *>(module)); 3407 break; 3408 3409 case 'u': 3410 DumpModuleUUID(strm, module); 3411 break; 3412 3413 default: 3414 break; 3415 } 3416 } 3417 if (dump_object_name) { 3418 const char *object_name = module->GetObjectName().GetCString(); 3419 if (object_name) 3420 strm.Printf("(%s)", object_name); 3421 } 3422 strm.EOL(); 3423 } 3424 3425 CommandOptions m_options; 3426 }; 3427 3428 #pragma mark CommandObjectTargetModulesShowUnwind 3429 3430 // Lookup unwind information in images 3431 #define LLDB_OPTIONS_target_modules_show_unwind 3432 #include "CommandOptions.inc" 3433 3434 class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed { 3435 public: 3436 enum { 3437 eLookupTypeInvalid = -1, 3438 eLookupTypeAddress = 0, 3439 eLookupTypeSymbol, 3440 eLookupTypeFunction, 3441 eLookupTypeFunctionOrSymbol, 3442 kNumLookupTypes 3443 }; 3444 3445 class CommandOptions : public Options { 3446 public: 3447 CommandOptions() = default; 3448 3449 ~CommandOptions() override = default; 3450 3451 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 3452 ExecutionContext *execution_context) override { 3453 Status error; 3454 3455 const int short_option = m_getopt_table[option_idx].val; 3456 3457 switch (short_option) { 3458 case 'a': { 3459 m_str = std::string(option_arg); 3460 m_type = eLookupTypeAddress; 3461 m_addr = OptionArgParser::ToAddress(execution_context, option_arg, 3462 LLDB_INVALID_ADDRESS, &error); 3463 if (m_addr == LLDB_INVALID_ADDRESS) 3464 error = Status::FromErrorStringWithFormat( 3465 "invalid address string '%s'", option_arg.str().c_str()); 3466 break; 3467 } 3468 3469 case 'n': 3470 m_str = std::string(option_arg); 3471 m_type = eLookupTypeFunctionOrSymbol; 3472 break; 3473 3474 default: 3475 llvm_unreachable("Unimplemented option"); 3476 } 3477 3478 return error; 3479 } 3480 3481 void OptionParsingStarting(ExecutionContext *execution_context) override { 3482 m_type = eLookupTypeInvalid; 3483 m_str.clear(); 3484 m_addr = LLDB_INVALID_ADDRESS; 3485 } 3486 3487 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 3488 return llvm::ArrayRef(g_target_modules_show_unwind_options); 3489 } 3490 3491 // Instance variables to hold the values for command options. 3492 3493 int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after 3494 // parsing options 3495 std::string m_str; // Holds name lookup 3496 lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup 3497 }; 3498 3499 CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter) 3500 : CommandObjectParsed( 3501 interpreter, "target modules show-unwind", 3502 "Show synthesized unwind instructions for a function.", nullptr, 3503 eCommandRequiresTarget | eCommandRequiresProcess | 3504 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused) {} 3505 3506 ~CommandObjectTargetModulesShowUnwind() override = default; 3507 3508 Options *GetOptions() override { return &m_options; } 3509 3510 protected: 3511 void DoExecute(Args &command, CommandReturnObject &result) override { 3512 Target *target = m_exe_ctx.GetTargetPtr(); 3513 Process *process = m_exe_ctx.GetProcessPtr(); 3514 ABI *abi = nullptr; 3515 if (process) 3516 abi = process->GetABI().get(); 3517 3518 if (process == nullptr) { 3519 result.AppendError( 3520 "You must have a process running to use this command."); 3521 return; 3522 } 3523 3524 ThreadList threads(process->GetThreadList()); 3525 if (threads.GetSize() == 0) { 3526 result.AppendError("The process must be paused to use this command."); 3527 return; 3528 } 3529 3530 ThreadSP thread(threads.GetThreadAtIndex(0)); 3531 if (!thread) { 3532 result.AppendError("The process must be paused to use this command."); 3533 return; 3534 } 3535 3536 SymbolContextList sc_list; 3537 3538 if (m_options.m_type == eLookupTypeFunctionOrSymbol) { 3539 ConstString function_name(m_options.m_str.c_str()); 3540 ModuleFunctionSearchOptions function_options; 3541 function_options.include_symbols = true; 3542 function_options.include_inlines = false; 3543 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto, 3544 function_options, sc_list); 3545 } else if (m_options.m_type == eLookupTypeAddress && target) { 3546 Address addr; 3547 if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr, 3548 addr)) { 3549 SymbolContext sc; 3550 ModuleSP module_sp(addr.GetModule()); 3551 module_sp->ResolveSymbolContextForAddress(addr, 3552 eSymbolContextEverything, sc); 3553 if (sc.function || sc.symbol) { 3554 sc_list.Append(sc); 3555 } 3556 } 3557 } else { 3558 result.AppendError( 3559 "address-expression or function name option must be specified."); 3560 return; 3561 } 3562 3563 if (sc_list.GetSize() == 0) { 3564 result.AppendErrorWithFormat("no unwind data found that matches '%s'.", 3565 m_options.m_str.c_str()); 3566 return; 3567 } 3568 3569 for (const SymbolContext &sc : sc_list) { 3570 if (sc.symbol == nullptr && sc.function == nullptr) 3571 continue; 3572 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr) 3573 continue; 3574 AddressRange range; 3575 if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, 3576 false, range)) 3577 continue; 3578 if (!range.GetBaseAddress().IsValid()) 3579 continue; 3580 ConstString funcname(sc.GetFunctionName()); 3581 if (funcname.IsEmpty()) 3582 continue; 3583 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target); 3584 if (abi) 3585 start_addr = abi->FixCodeAddress(start_addr); 3586 range.GetBaseAddress().SetLoadAddress(start_addr, target); 3587 3588 FuncUnwindersSP func_unwinders_sp( 3589 sc.module_sp->GetUnwindTable() 3590 .GetUncachedFuncUnwindersContainingAddress(range.GetBaseAddress(), 3591 sc)); 3592 if (!func_unwinders_sp) 3593 continue; 3594 3595 result.GetOutputStream().Printf( 3596 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n", 3597 sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), 3598 funcname.AsCString(), start_addr); 3599 3600 Args args; 3601 target->GetUserSpecifiedTrapHandlerNames(args); 3602 size_t count = args.GetArgumentCount(); 3603 for (size_t i = 0; i < count; i++) { 3604 const char *trap_func_name = args.GetArgumentAtIndex(i); 3605 if (strcmp(funcname.GetCString(), trap_func_name) == 0) 3606 result.GetOutputStream().Printf( 3607 "This function is " 3608 "treated as a trap handler function via user setting.\n"); 3609 } 3610 PlatformSP platform_sp(target->GetPlatform()); 3611 if (platform_sp) { 3612 const std::vector<ConstString> trap_handler_names( 3613 platform_sp->GetTrapHandlerSymbolNames()); 3614 for (ConstString trap_name : trap_handler_names) { 3615 if (trap_name == funcname) { 3616 result.GetOutputStream().Printf( 3617 "This function's " 3618 "name is listed by the platform as a trap handler.\n"); 3619 } 3620 } 3621 } 3622 3623 result.GetOutputStream().Printf("\n"); 3624 3625 UnwindPlanSP non_callsite_unwind_plan = 3626 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread); 3627 if (non_callsite_unwind_plan) { 3628 result.GetOutputStream().Printf( 3629 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n", 3630 non_callsite_unwind_plan->GetSourceName().AsCString()); 3631 } 3632 UnwindPlanSP callsite_unwind_plan = 3633 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread); 3634 if (callsite_unwind_plan) { 3635 result.GetOutputStream().Printf( 3636 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n", 3637 callsite_unwind_plan->GetSourceName().AsCString()); 3638 } 3639 UnwindPlanSP fast_unwind_plan = 3640 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread); 3641 if (fast_unwind_plan) { 3642 result.GetOutputStream().Printf( 3643 "Fast UnwindPlan is '%s'\n", 3644 fast_unwind_plan->GetSourceName().AsCString()); 3645 } 3646 3647 result.GetOutputStream().Printf("\n"); 3648 3649 UnwindPlanSP assembly_sp = 3650 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread); 3651 if (assembly_sp) { 3652 result.GetOutputStream().Printf( 3653 "Assembly language inspection UnwindPlan:\n"); 3654 assembly_sp->Dump(result.GetOutputStream(), thread.get(), 3655 LLDB_INVALID_ADDRESS); 3656 result.GetOutputStream().Printf("\n"); 3657 } 3658 3659 UnwindPlanSP of_unwind_sp = 3660 func_unwinders_sp->GetObjectFileUnwindPlan(*target); 3661 if (of_unwind_sp) { 3662 result.GetOutputStream().Printf("object file UnwindPlan:\n"); 3663 of_unwind_sp->Dump(result.GetOutputStream(), thread.get(), 3664 LLDB_INVALID_ADDRESS); 3665 result.GetOutputStream().Printf("\n"); 3666 } 3667 3668 UnwindPlanSP of_unwind_augmented_sp = 3669 func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, *thread); 3670 if (of_unwind_augmented_sp) { 3671 result.GetOutputStream().Printf("object file augmented UnwindPlan:\n"); 3672 of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(), 3673 LLDB_INVALID_ADDRESS); 3674 result.GetOutputStream().Printf("\n"); 3675 } 3676 3677 UnwindPlanSP ehframe_sp = 3678 func_unwinders_sp->GetEHFrameUnwindPlan(*target); 3679 if (ehframe_sp) { 3680 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n"); 3681 ehframe_sp->Dump(result.GetOutputStream(), thread.get(), 3682 LLDB_INVALID_ADDRESS); 3683 result.GetOutputStream().Printf("\n"); 3684 } 3685 3686 UnwindPlanSP ehframe_augmented_sp = 3687 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread); 3688 if (ehframe_augmented_sp) { 3689 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n"); 3690 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(), 3691 LLDB_INVALID_ADDRESS); 3692 result.GetOutputStream().Printf("\n"); 3693 } 3694 3695 if (UnwindPlanSP plan_sp = 3696 func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) { 3697 result.GetOutputStream().Printf("debug_frame UnwindPlan:\n"); 3698 plan_sp->Dump(result.GetOutputStream(), thread.get(), 3699 LLDB_INVALID_ADDRESS); 3700 result.GetOutputStream().Printf("\n"); 3701 } 3702 3703 if (UnwindPlanSP plan_sp = 3704 func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target, 3705 *thread)) { 3706 result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n"); 3707 plan_sp->Dump(result.GetOutputStream(), thread.get(), 3708 LLDB_INVALID_ADDRESS); 3709 result.GetOutputStream().Printf("\n"); 3710 } 3711 3712 UnwindPlanSP arm_unwind_sp = 3713 func_unwinders_sp->GetArmUnwindUnwindPlan(*target); 3714 if (arm_unwind_sp) { 3715 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n"); 3716 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(), 3717 LLDB_INVALID_ADDRESS); 3718 result.GetOutputStream().Printf("\n"); 3719 } 3720 3721 if (UnwindPlanSP symfile_plan_sp = 3722 func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) { 3723 result.GetOutputStream().Printf("Symbol file UnwindPlan:\n"); 3724 symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(), 3725 LLDB_INVALID_ADDRESS); 3726 result.GetOutputStream().Printf("\n"); 3727 } 3728 3729 UnwindPlanSP compact_unwind_sp = 3730 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target); 3731 if (compact_unwind_sp) { 3732 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n"); 3733 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(), 3734 LLDB_INVALID_ADDRESS); 3735 result.GetOutputStream().Printf("\n"); 3736 } 3737 3738 if (fast_unwind_plan) { 3739 result.GetOutputStream().Printf("Fast UnwindPlan:\n"); 3740 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), 3741 LLDB_INVALID_ADDRESS); 3742 result.GetOutputStream().Printf("\n"); 3743 } 3744 3745 ABISP abi_sp = process->GetABI(); 3746 if (abi_sp) { 3747 UnwindPlan arch_default(lldb::eRegisterKindGeneric); 3748 if (abi_sp->CreateDefaultUnwindPlan(arch_default)) { 3749 result.GetOutputStream().Printf("Arch default UnwindPlan:\n"); 3750 arch_default.Dump(result.GetOutputStream(), thread.get(), 3751 LLDB_INVALID_ADDRESS); 3752 result.GetOutputStream().Printf("\n"); 3753 } 3754 3755 UnwindPlan arch_entry(lldb::eRegisterKindGeneric); 3756 if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) { 3757 result.GetOutputStream().Printf( 3758 "Arch default at entry point UnwindPlan:\n"); 3759 arch_entry.Dump(result.GetOutputStream(), thread.get(), 3760 LLDB_INVALID_ADDRESS); 3761 result.GetOutputStream().Printf("\n"); 3762 } 3763 } 3764 3765 result.GetOutputStream().Printf("\n"); 3766 } 3767 } 3768 3769 CommandOptions m_options; 3770 }; 3771 3772 // Lookup information in images 3773 #define LLDB_OPTIONS_target_modules_lookup 3774 #include "CommandOptions.inc" 3775 3776 class CommandObjectTargetModulesLookup : public CommandObjectParsed { 3777 public: 3778 enum { 3779 eLookupTypeInvalid = -1, 3780 eLookupTypeAddress = 0, 3781 eLookupTypeSymbol, 3782 eLookupTypeFileLine, // Line is optional 3783 eLookupTypeFunction, 3784 eLookupTypeFunctionOrSymbol, 3785 eLookupTypeType, 3786 kNumLookupTypes 3787 }; 3788 3789 class CommandOptions : public Options { 3790 public: 3791 CommandOptions() { OptionParsingStarting(nullptr); } 3792 3793 ~CommandOptions() override = default; 3794 3795 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 3796 ExecutionContext *execution_context) override { 3797 Status error; 3798 3799 const int short_option = m_getopt_table[option_idx].val; 3800 3801 switch (short_option) { 3802 case 'a': { 3803 m_type = eLookupTypeAddress; 3804 m_addr = OptionArgParser::ToAddress(execution_context, option_arg, 3805 LLDB_INVALID_ADDRESS, &error); 3806 } break; 3807 3808 case 'o': 3809 if (option_arg.getAsInteger(0, m_offset)) 3810 error = Status::FromErrorStringWithFormat( 3811 "invalid offset string '%s'", option_arg.str().c_str()); 3812 break; 3813 3814 case 's': 3815 m_str = std::string(option_arg); 3816 m_type = eLookupTypeSymbol; 3817 break; 3818 3819 case 'f': 3820 m_file.SetFile(option_arg, FileSpec::Style::native); 3821 m_type = eLookupTypeFileLine; 3822 break; 3823 3824 case 'i': 3825 m_include_inlines = false; 3826 break; 3827 3828 case 'l': 3829 if (option_arg.getAsInteger(0, m_line_number)) 3830 error = Status::FromErrorStringWithFormat( 3831 "invalid line number string '%s'", option_arg.str().c_str()); 3832 else if (m_line_number == 0) 3833 error = Status::FromErrorString("zero is an invalid line number"); 3834 m_type = eLookupTypeFileLine; 3835 break; 3836 3837 case 'F': 3838 m_str = std::string(option_arg); 3839 m_type = eLookupTypeFunction; 3840 break; 3841 3842 case 'n': 3843 m_str = std::string(option_arg); 3844 m_type = eLookupTypeFunctionOrSymbol; 3845 break; 3846 3847 case 't': 3848 m_str = std::string(option_arg); 3849 m_type = eLookupTypeType; 3850 break; 3851 3852 case 'v': 3853 m_verbose = true; 3854 break; 3855 3856 case 'A': 3857 m_print_all = true; 3858 break; 3859 3860 case 'r': 3861 m_use_regex = true; 3862 break; 3863 3864 case '\x01': 3865 m_all_ranges = true; 3866 break; 3867 default: 3868 llvm_unreachable("Unimplemented option"); 3869 } 3870 3871 return error; 3872 } 3873 3874 void OptionParsingStarting(ExecutionContext *execution_context) override { 3875 m_type = eLookupTypeInvalid; 3876 m_str.clear(); 3877 m_file.Clear(); 3878 m_addr = LLDB_INVALID_ADDRESS; 3879 m_offset = 0; 3880 m_line_number = 0; 3881 m_use_regex = false; 3882 m_include_inlines = true; 3883 m_all_ranges = false; 3884 m_verbose = false; 3885 m_print_all = false; 3886 } 3887 3888 Status OptionParsingFinished(ExecutionContext *execution_context) override { 3889 Status status; 3890 if (m_all_ranges && !m_verbose) { 3891 status = 3892 Status::FromErrorString("--show-variable-ranges must be used in " 3893 "conjunction with --verbose."); 3894 } 3895 return status; 3896 } 3897 3898 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 3899 return llvm::ArrayRef(g_target_modules_lookup_options); 3900 } 3901 3902 int m_type; // Should be a eLookupTypeXXX enum after parsing options 3903 std::string m_str; // Holds name lookup 3904 FileSpec m_file; // Files for file lookups 3905 lldb::addr_t m_addr; // Holds the address to lookup 3906 lldb::addr_t 3907 m_offset; // Subtract this offset from m_addr before doing lookups. 3908 uint32_t m_line_number; // Line number for file+line lookups 3909 bool m_use_regex; // Name lookups in m_str are regular expressions. 3910 bool m_include_inlines; // Check for inline entries when looking up by 3911 // file/line. 3912 bool m_all_ranges; // Print all ranges or single range. 3913 bool m_verbose; // Enable verbose lookup info 3914 bool m_print_all; // Print all matches, even in cases where there's a best 3915 // match. 3916 }; 3917 3918 CommandObjectTargetModulesLookup(CommandInterpreter &interpreter) 3919 : CommandObjectParsed(interpreter, "target modules lookup", 3920 "Look up information within executable and " 3921 "dependent shared library images.", 3922 nullptr, eCommandRequiresTarget) { 3923 AddSimpleArgumentList(eArgTypeFilename, eArgRepeatStar); 3924 } 3925 3926 ~CommandObjectTargetModulesLookup() override = default; 3927 3928 Options *GetOptions() override { return &m_options; } 3929 3930 bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result, 3931 bool &syntax_error) { 3932 switch (m_options.m_type) { 3933 case eLookupTypeAddress: 3934 case eLookupTypeFileLine: 3935 case eLookupTypeFunction: 3936 case eLookupTypeFunctionOrSymbol: 3937 case eLookupTypeSymbol: 3938 default: 3939 return false; 3940 case eLookupTypeType: 3941 break; 3942 } 3943 3944 StackFrameSP frame = m_exe_ctx.GetFrameSP(); 3945 3946 if (!frame) 3947 return false; 3948 3949 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule)); 3950 3951 if (!sym_ctx.module_sp) 3952 return false; 3953 3954 switch (m_options.m_type) { 3955 default: 3956 return false; 3957 case eLookupTypeType: 3958 if (!m_options.m_str.empty()) { 3959 if (LookupTypeHere(&GetTarget(), m_interpreter, 3960 result.GetOutputStream(), *sym_ctx.module_sp, 3961 m_options.m_str.c_str(), m_options.m_use_regex)) { 3962 result.SetStatus(eReturnStatusSuccessFinishResult); 3963 return true; 3964 } 3965 } 3966 break; 3967 } 3968 3969 return false; 3970 } 3971 3972 bool LookupInModule(CommandInterpreter &interpreter, Module *module, 3973 CommandReturnObject &result, bool &syntax_error) { 3974 switch (m_options.m_type) { 3975 case eLookupTypeAddress: 3976 if (m_options.m_addr != LLDB_INVALID_ADDRESS) { 3977 if (LookupAddressInModule( 3978 m_interpreter, result.GetOutputStream(), module, 3979 eSymbolContextEverything | 3980 (m_options.m_verbose 3981 ? static_cast<int>(eSymbolContextVariable) 3982 : 0), 3983 m_options.m_addr, m_options.m_offset, m_options.m_verbose, 3984 m_options.m_all_ranges)) { 3985 result.SetStatus(eReturnStatusSuccessFinishResult); 3986 return true; 3987 } 3988 } 3989 break; 3990 3991 case eLookupTypeSymbol: 3992 if (!m_options.m_str.empty()) { 3993 if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(), 3994 module, m_options.m_str.c_str(), 3995 m_options.m_use_regex, m_options.m_verbose, 3996 m_options.m_all_ranges)) { 3997 result.SetStatus(eReturnStatusSuccessFinishResult); 3998 return true; 3999 } 4000 } 4001 break; 4002 4003 case eLookupTypeFileLine: 4004 if (m_options.m_file) { 4005 if (LookupFileAndLineInModule( 4006 m_interpreter, result.GetOutputStream(), module, 4007 m_options.m_file, m_options.m_line_number, 4008 m_options.m_include_inlines, m_options.m_verbose, 4009 m_options.m_all_ranges)) { 4010 result.SetStatus(eReturnStatusSuccessFinishResult); 4011 return true; 4012 } 4013 } 4014 break; 4015 4016 case eLookupTypeFunctionOrSymbol: 4017 case eLookupTypeFunction: 4018 if (!m_options.m_str.empty()) { 4019 ModuleFunctionSearchOptions function_options; 4020 function_options.include_symbols = 4021 m_options.m_type == eLookupTypeFunctionOrSymbol; 4022 function_options.include_inlines = m_options.m_include_inlines; 4023 4024 if (LookupFunctionInModule(m_interpreter, result.GetOutputStream(), 4025 module, m_options.m_str.c_str(), 4026 m_options.m_use_regex, function_options, 4027 m_options.m_verbose, 4028 m_options.m_all_ranges)) { 4029 result.SetStatus(eReturnStatusSuccessFinishResult); 4030 return true; 4031 } 4032 } 4033 break; 4034 4035 case eLookupTypeType: 4036 if (!m_options.m_str.empty()) { 4037 if (LookupTypeInModule( 4038 &GetTarget(), m_interpreter, result.GetOutputStream(), module, 4039 m_options.m_str.c_str(), m_options.m_use_regex)) { 4040 result.SetStatus(eReturnStatusSuccessFinishResult); 4041 return true; 4042 } 4043 } 4044 break; 4045 4046 default: 4047 m_options.GenerateOptionUsage( 4048 result.GetErrorStream(), *this, 4049 GetCommandInterpreter().GetDebugger().GetTerminalWidth()); 4050 syntax_error = true; 4051 break; 4052 } 4053 4054 result.SetStatus(eReturnStatusFailed); 4055 return false; 4056 } 4057 4058 protected: 4059 void DoExecute(Args &command, CommandReturnObject &result) override { 4060 Target &target = GetTarget(); 4061 bool syntax_error = false; 4062 uint32_t i; 4063 uint32_t num_successful_lookups = 0; 4064 uint32_t addr_byte_size = target.GetArchitecture().GetAddressByteSize(); 4065 result.GetOutputStream().SetAddressByteSize(addr_byte_size); 4066 result.GetErrorStream().SetAddressByteSize(addr_byte_size); 4067 // Dump all sections for all modules images 4068 4069 if (command.GetArgumentCount() == 0) { 4070 ModuleSP current_module; 4071 4072 // Where it is possible to look in the current symbol context first, 4073 // try that. If this search was successful and --all was not passed, 4074 // don't print anything else. 4075 if (LookupHere(m_interpreter, result, syntax_error)) { 4076 result.GetOutputStream().EOL(); 4077 num_successful_lookups++; 4078 if (!m_options.m_print_all) { 4079 result.SetStatus(eReturnStatusSuccessFinishResult); 4080 return; 4081 } 4082 } 4083 4084 // Dump all sections for all other modules 4085 4086 const ModuleList &target_modules = target.GetImages(); 4087 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex()); 4088 if (target_modules.GetSize() == 0) { 4089 result.AppendError("the target has no associated executable images"); 4090 return; 4091 } 4092 4093 for (ModuleSP module_sp : target_modules.ModulesNoLocking()) { 4094 if (module_sp != current_module && 4095 LookupInModule(m_interpreter, module_sp.get(), result, 4096 syntax_error)) { 4097 result.GetOutputStream().EOL(); 4098 num_successful_lookups++; 4099 } 4100 } 4101 } else { 4102 // Dump specified images (by basename or fullpath) 4103 const char *arg_cstr; 4104 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr && 4105 !syntax_error; 4106 ++i) { 4107 ModuleList module_list; 4108 const size_t num_matches = 4109 FindModulesByName(&target, arg_cstr, module_list, false); 4110 if (num_matches > 0) { 4111 for (size_t j = 0; j < num_matches; ++j) { 4112 Module *module = module_list.GetModulePointerAtIndex(j); 4113 if (module) { 4114 if (LookupInModule(m_interpreter, module, result, syntax_error)) { 4115 result.GetOutputStream().EOL(); 4116 num_successful_lookups++; 4117 } 4118 } 4119 } 4120 } else 4121 result.AppendWarningWithFormat( 4122 "Unable to find an image that matches '%s'.\n", arg_cstr); 4123 } 4124 } 4125 4126 if (num_successful_lookups > 0) 4127 result.SetStatus(eReturnStatusSuccessFinishResult); 4128 else 4129 result.SetStatus(eReturnStatusFailed); 4130 } 4131 4132 CommandOptions m_options; 4133 }; 4134 4135 #pragma mark CommandObjectMultiwordImageSearchPaths 4136 4137 // CommandObjectMultiwordImageSearchPaths 4138 4139 class CommandObjectTargetModulesImageSearchPaths 4140 : public CommandObjectMultiword { 4141 public: 4142 CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter) 4143 : CommandObjectMultiword( 4144 interpreter, "target modules search-paths", 4145 "Commands for managing module search paths for a target.", 4146 "target modules search-paths <subcommand> [<subcommand-options>]") { 4147 LoadSubCommand( 4148 "add", CommandObjectSP( 4149 new CommandObjectTargetModulesSearchPathsAdd(interpreter))); 4150 LoadSubCommand( 4151 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear( 4152 interpreter))); 4153 LoadSubCommand( 4154 "insert", 4155 CommandObjectSP( 4156 new CommandObjectTargetModulesSearchPathsInsert(interpreter))); 4157 LoadSubCommand( 4158 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList( 4159 interpreter))); 4160 LoadSubCommand( 4161 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery( 4162 interpreter))); 4163 } 4164 4165 ~CommandObjectTargetModulesImageSearchPaths() override = default; 4166 }; 4167 4168 #pragma mark CommandObjectTargetModules 4169 4170 // CommandObjectTargetModules 4171 4172 class CommandObjectTargetModules : public CommandObjectMultiword { 4173 public: 4174 // Constructors and Destructors 4175 CommandObjectTargetModules(CommandInterpreter &interpreter) 4176 : CommandObjectMultiword(interpreter, "target modules", 4177 "Commands for accessing information for one or " 4178 "more target modules.", 4179 "target modules <sub-command> ...") { 4180 LoadSubCommand( 4181 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter))); 4182 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad( 4183 interpreter))); 4184 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump( 4185 interpreter))); 4186 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList( 4187 interpreter))); 4188 LoadSubCommand( 4189 "lookup", 4190 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter))); 4191 LoadSubCommand( 4192 "search-paths", 4193 CommandObjectSP( 4194 new CommandObjectTargetModulesImageSearchPaths(interpreter))); 4195 LoadSubCommand( 4196 "show-unwind", 4197 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter))); 4198 } 4199 4200 ~CommandObjectTargetModules() override = default; 4201 4202 private: 4203 // For CommandObjectTargetModules only 4204 CommandObjectTargetModules(const CommandObjectTargetModules &) = delete; 4205 const CommandObjectTargetModules & 4206 operator=(const CommandObjectTargetModules &) = delete; 4207 }; 4208 4209 class CommandObjectTargetSymbolsAdd : public CommandObjectParsed { 4210 public: 4211 CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter) 4212 : CommandObjectParsed( 4213 interpreter, "target symbols add", 4214 "Add a debug symbol file to one of the target's current modules by " 4215 "specifying a path to a debug symbols file or by using the options " 4216 "to specify a module.", 4217 "target symbols add <cmd-options> [<symfile>]", 4218 eCommandRequiresTarget), 4219 m_file_option( 4220 LLDB_OPT_SET_1, false, "shlib", 's', lldb::eModuleCompletion, 4221 eArgTypeShlibName, 4222 "Locate the debug symbols for the shared library specified by " 4223 "name."), 4224 m_current_frame_option( 4225 LLDB_OPT_SET_2, false, "frame", 'F', 4226 "Locate the debug symbols for the currently selected frame.", false, 4227 true), 4228 m_current_stack_option(LLDB_OPT_SET_2, false, "stack", 'S', 4229 "Locate the debug symbols for every frame in " 4230 "the current call stack.", 4231 false, true) 4232 4233 { 4234 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL, 4235 LLDB_OPT_SET_1); 4236 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1); 4237 m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2, 4238 LLDB_OPT_SET_2); 4239 m_option_group.Append(&m_current_stack_option, LLDB_OPT_SET_2, 4240 LLDB_OPT_SET_2); 4241 m_option_group.Finalize(); 4242 AddSimpleArgumentList(eArgTypeFilename); 4243 } 4244 4245 ~CommandObjectTargetSymbolsAdd() override = default; 4246 4247 Options *GetOptions() override { return &m_option_group; } 4248 4249 protected: 4250 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush, 4251 CommandReturnObject &result) { 4252 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec(); 4253 if (!symbol_fspec) { 4254 result.AppendError( 4255 "one or more executable image paths must be specified"); 4256 return false; 4257 } 4258 4259 char symfile_path[PATH_MAX]; 4260 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path)); 4261 4262 if (!module_spec.GetUUID().IsValid()) { 4263 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec()) 4264 module_spec.GetFileSpec().SetFilename(symbol_fspec.GetFilename()); 4265 } 4266 4267 // Now module_spec represents a symbol file for a module that might exist 4268 // in the current target. Let's find possible matches. 4269 ModuleList matching_modules; 4270 4271 // First extract all module specs from the symbol file 4272 lldb_private::ModuleSpecList symfile_module_specs; 4273 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(), 4274 0, 0, symfile_module_specs)) { 4275 // Now extract the module spec that matches the target architecture 4276 ModuleSpec target_arch_module_spec; 4277 ModuleSpec symfile_module_spec; 4278 target_arch_module_spec.GetArchitecture() = target->GetArchitecture(); 4279 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec, 4280 symfile_module_spec)) { 4281 if (symfile_module_spec.GetUUID().IsValid()) { 4282 // It has a UUID, look for this UUID in the target modules 4283 ModuleSpec symfile_uuid_module_spec; 4284 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID(); 4285 target->GetImages().FindModules(symfile_uuid_module_spec, 4286 matching_modules); 4287 } 4288 } 4289 4290 if (matching_modules.IsEmpty()) { 4291 // No matches yet. Iterate through the module specs to find a UUID 4292 // value that we can match up to an image in our target. 4293 const size_t num_symfile_module_specs = symfile_module_specs.GetSize(); 4294 for (size_t i = 0; 4295 i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) { 4296 if (symfile_module_specs.GetModuleSpecAtIndex( 4297 i, symfile_module_spec)) { 4298 if (symfile_module_spec.GetUUID().IsValid()) { 4299 // It has a UUID. Look for this UUID in the target modules. 4300 ModuleSpec symfile_uuid_module_spec; 4301 symfile_uuid_module_spec.GetUUID() = 4302 symfile_module_spec.GetUUID(); 4303 target->GetImages().FindModules(symfile_uuid_module_spec, 4304 matching_modules); 4305 } 4306 } 4307 } 4308 } 4309 } 4310 4311 // Just try to match up the file by basename if we have no matches at 4312 // this point. For example, module foo might have symbols in foo.debug. 4313 if (matching_modules.IsEmpty()) 4314 target->GetImages().FindModules(module_spec, matching_modules); 4315 4316 while (matching_modules.IsEmpty()) { 4317 ConstString filename_no_extension( 4318 module_spec.GetFileSpec().GetFileNameStrippingExtension()); 4319 // Empty string returned, let's bail 4320 if (!filename_no_extension) 4321 break; 4322 4323 // Check if there was no extension to strip and the basename is the same 4324 if (filename_no_extension == module_spec.GetFileSpec().GetFilename()) 4325 break; 4326 4327 // Replace basename with one fewer extension 4328 module_spec.GetFileSpec().SetFilename(filename_no_extension); 4329 target->GetImages().FindModules(module_spec, matching_modules); 4330 } 4331 4332 if (matching_modules.GetSize() > 1) { 4333 result.AppendErrorWithFormat("multiple modules match symbol file '%s', " 4334 "use the --uuid option to resolve the " 4335 "ambiguity.\n", 4336 symfile_path); 4337 return false; 4338 } 4339 4340 if (matching_modules.GetSize() == 1) { 4341 ModuleSP module_sp(matching_modules.GetModuleAtIndex(0)); 4342 4343 // The module has not yet created its symbol vendor, we can just give 4344 // the existing target module the symfile path to use for when it 4345 // decides to create it! 4346 module_sp->SetSymbolFileFileSpec(symbol_fspec); 4347 4348 SymbolFile *symbol_file = 4349 module_sp->GetSymbolFile(true, &result.GetErrorStream()); 4350 if (symbol_file) { 4351 ObjectFile *object_file = symbol_file->GetObjectFile(); 4352 if (object_file && object_file->GetFileSpec() == symbol_fspec) { 4353 // Provide feedback that the symfile has been successfully added. 4354 const FileSpec &module_fs = module_sp->GetFileSpec(); 4355 result.AppendMessageWithFormat( 4356 "symbol file '%s' has been added to '%s'\n", symfile_path, 4357 module_fs.GetPath().c_str()); 4358 4359 // Let clients know something changed in the module if it is 4360 // currently loaded 4361 ModuleList module_list; 4362 module_list.Append(module_sp); 4363 target->SymbolsDidLoad(module_list); 4364 4365 // Make sure we load any scripting resources that may be embedded 4366 // in the debug info files in case the platform supports that. 4367 Status error; 4368 StreamString feedback_stream; 4369 module_sp->LoadScriptingResourceInTarget(target, error, 4370 feedback_stream); 4371 if (error.Fail() && error.AsCString()) 4372 result.AppendWarningWithFormat( 4373 "unable to load scripting data for module %s - error " 4374 "reported was %s", 4375 module_sp->GetFileSpec() 4376 .GetFileNameStrippingExtension() 4377 .GetCString(), 4378 error.AsCString()); 4379 else if (feedback_stream.GetSize()) 4380 result.AppendWarning(feedback_stream.GetData()); 4381 4382 flush = true; 4383 result.SetStatus(eReturnStatusSuccessFinishResult); 4384 return true; 4385 } 4386 } 4387 // Clear the symbol file spec if anything went wrong 4388 module_sp->SetSymbolFileFileSpec(FileSpec()); 4389 } 4390 4391 StreamString ss_symfile_uuid; 4392 if (module_spec.GetUUID().IsValid()) { 4393 ss_symfile_uuid << " ("; 4394 module_spec.GetUUID().Dump(ss_symfile_uuid); 4395 ss_symfile_uuid << ')'; 4396 } 4397 result.AppendErrorWithFormat( 4398 "symbol file '%s'%s does not match any existing module%s\n", 4399 symfile_path, ss_symfile_uuid.GetData(), 4400 !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath()) 4401 ? "\n please specify the full path to the symbol file" 4402 : ""); 4403 return false; 4404 } 4405 4406 bool DownloadObjectAndSymbolFile(ModuleSpec &module_spec, 4407 CommandReturnObject &result, bool &flush) { 4408 Status error; 4409 if (PluginManager::DownloadObjectAndSymbolFile(module_spec, error)) { 4410 if (module_spec.GetSymbolFileSpec()) 4411 return AddModuleSymbols(m_exe_ctx.GetTargetPtr(), module_spec, flush, 4412 result); 4413 } else { 4414 result.SetError(std::move(error)); 4415 } 4416 return false; 4417 } 4418 4419 bool AddSymbolsForUUID(CommandReturnObject &result, bool &flush) { 4420 assert(m_uuid_option_group.GetOptionValue().OptionWasSet()); 4421 4422 ModuleSpec module_spec; 4423 module_spec.GetUUID() = 4424 m_uuid_option_group.GetOptionValue().GetCurrentValue(); 4425 4426 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) { 4427 StreamString error_strm; 4428 error_strm.PutCString("unable to find debug symbols for UUID "); 4429 module_spec.GetUUID().Dump(error_strm); 4430 result.AppendError(error_strm.GetString()); 4431 return false; 4432 } 4433 4434 return true; 4435 } 4436 4437 bool AddSymbolsForFile(CommandReturnObject &result, bool &flush) { 4438 assert(m_file_option.GetOptionValue().OptionWasSet()); 4439 4440 ModuleSpec module_spec; 4441 module_spec.GetFileSpec() = 4442 m_file_option.GetOptionValue().GetCurrentValue(); 4443 4444 Target *target = m_exe_ctx.GetTargetPtr(); 4445 ModuleSP module_sp(target->GetImages().FindFirstModule(module_spec)); 4446 if (module_sp) { 4447 module_spec.GetFileSpec() = module_sp->GetFileSpec(); 4448 module_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec(); 4449 module_spec.GetUUID() = module_sp->GetUUID(); 4450 module_spec.GetArchitecture() = module_sp->GetArchitecture(); 4451 } else { 4452 module_spec.GetArchitecture() = target->GetArchitecture(); 4453 } 4454 4455 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) { 4456 StreamString error_strm; 4457 error_strm.PutCString( 4458 "unable to find debug symbols for the executable file "); 4459 error_strm << module_spec.GetFileSpec(); 4460 result.AppendError(error_strm.GetString()); 4461 return false; 4462 } 4463 4464 return true; 4465 } 4466 4467 bool AddSymbolsForFrame(CommandReturnObject &result, bool &flush) { 4468 assert(m_current_frame_option.GetOptionValue().OptionWasSet()); 4469 4470 Process *process = m_exe_ctx.GetProcessPtr(); 4471 if (!process) { 4472 result.AppendError( 4473 "a process must exist in order to use the --frame option"); 4474 return false; 4475 } 4476 4477 const StateType process_state = process->GetState(); 4478 if (!StateIsStoppedState(process_state, true)) { 4479 result.AppendErrorWithFormat("process is not stopped: %s", 4480 StateAsCString(process_state)); 4481 return false; 4482 } 4483 4484 StackFrame *frame = m_exe_ctx.GetFramePtr(); 4485 if (!frame) { 4486 result.AppendError("invalid current frame"); 4487 return false; 4488 } 4489 4490 ModuleSP frame_module_sp( 4491 frame->GetSymbolContext(eSymbolContextModule).module_sp); 4492 if (!frame_module_sp) { 4493 result.AppendError("frame has no module"); 4494 return false; 4495 } 4496 4497 ModuleSpec module_spec; 4498 module_spec.GetUUID() = frame_module_sp->GetUUID(); 4499 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); 4500 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec(); 4501 4502 if (!DownloadObjectAndSymbolFile(module_spec, result, flush)) { 4503 result.AppendError("unable to find debug symbols for the current frame"); 4504 return false; 4505 } 4506 4507 return true; 4508 } 4509 4510 bool AddSymbolsForStack(CommandReturnObject &result, bool &flush) { 4511 assert(m_current_stack_option.GetOptionValue().OptionWasSet()); 4512 4513 Process *process = m_exe_ctx.GetProcessPtr(); 4514 if (!process) { 4515 result.AppendError( 4516 "a process must exist in order to use the --stack option"); 4517 return false; 4518 } 4519 4520 const StateType process_state = process->GetState(); 4521 if (!StateIsStoppedState(process_state, true)) { 4522 result.AppendErrorWithFormat("process is not stopped: %s", 4523 StateAsCString(process_state)); 4524 return false; 4525 } 4526 4527 Thread *thread = m_exe_ctx.GetThreadPtr(); 4528 if (!thread) { 4529 result.AppendError("invalid current thread"); 4530 return false; 4531 } 4532 4533 bool symbols_found = false; 4534 uint32_t frame_count = thread->GetStackFrameCount(); 4535 for (uint32_t i = 0; i < frame_count; ++i) { 4536 lldb::StackFrameSP frame_sp = thread->GetStackFrameAtIndex(i); 4537 4538 ModuleSP frame_module_sp( 4539 frame_sp->GetSymbolContext(eSymbolContextModule).module_sp); 4540 if (!frame_module_sp) 4541 continue; 4542 4543 ModuleSpec module_spec; 4544 module_spec.GetUUID() = frame_module_sp->GetUUID(); 4545 module_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec(); 4546 module_spec.GetArchitecture() = frame_module_sp->GetArchitecture(); 4547 4548 bool current_frame_flush = false; 4549 if (DownloadObjectAndSymbolFile(module_spec, result, current_frame_flush)) 4550 symbols_found = true; 4551 flush |= current_frame_flush; 4552 } 4553 4554 if (!symbols_found) { 4555 result.AppendError( 4556 "unable to find debug symbols in the current call stack"); 4557 return false; 4558 } 4559 4560 return true; 4561 } 4562 4563 void DoExecute(Args &args, CommandReturnObject &result) override { 4564 Target *target = m_exe_ctx.GetTargetPtr(); 4565 result.SetStatus(eReturnStatusFailed); 4566 bool flush = false; 4567 ModuleSpec module_spec; 4568 const bool uuid_option_set = 4569 m_uuid_option_group.GetOptionValue().OptionWasSet(); 4570 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet(); 4571 const bool frame_option_set = 4572 m_current_frame_option.GetOptionValue().OptionWasSet(); 4573 const bool stack_option_set = 4574 m_current_stack_option.GetOptionValue().OptionWasSet(); 4575 const size_t argc = args.GetArgumentCount(); 4576 4577 if (argc == 0) { 4578 if (uuid_option_set) 4579 AddSymbolsForUUID(result, flush); 4580 else if (file_option_set) 4581 AddSymbolsForFile(result, flush); 4582 else if (frame_option_set) 4583 AddSymbolsForFrame(result, flush); 4584 else if (stack_option_set) 4585 AddSymbolsForStack(result, flush); 4586 else 4587 result.AppendError("one or more symbol file paths must be specified, " 4588 "or options must be specified"); 4589 } else { 4590 if (uuid_option_set) { 4591 result.AppendError("specify either one or more paths to symbol files " 4592 "or use the --uuid option without arguments"); 4593 } else if (frame_option_set) { 4594 result.AppendError("specify either one or more paths to symbol files " 4595 "or use the --frame option without arguments"); 4596 } else if (file_option_set && argc > 1) { 4597 result.AppendError("specify at most one symbol file path when " 4598 "--shlib option is set"); 4599 } else { 4600 PlatformSP platform_sp(target->GetPlatform()); 4601 4602 for (auto &entry : args.entries()) { 4603 if (!entry.ref().empty()) { 4604 auto &symbol_file_spec = module_spec.GetSymbolFileSpec(); 4605 symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native); 4606 FileSystem::Instance().Resolve(symbol_file_spec); 4607 if (file_option_set) { 4608 module_spec.GetFileSpec() = 4609 m_file_option.GetOptionValue().GetCurrentValue(); 4610 } 4611 if (platform_sp) { 4612 FileSpec symfile_spec; 4613 if (platform_sp 4614 ->ResolveSymbolFile(*target, module_spec, symfile_spec) 4615 .Success()) 4616 module_spec.GetSymbolFileSpec() = symfile_spec; 4617 } 4618 4619 bool symfile_exists = 4620 FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec()); 4621 4622 if (symfile_exists) { 4623 if (!AddModuleSymbols(target, module_spec, flush, result)) 4624 break; 4625 } else { 4626 std::string resolved_symfile_path = 4627 module_spec.GetSymbolFileSpec().GetPath(); 4628 if (resolved_symfile_path != entry.ref()) { 4629 result.AppendErrorWithFormat( 4630 "invalid module path '%s' with resolved path '%s'\n", 4631 entry.c_str(), resolved_symfile_path.c_str()); 4632 break; 4633 } 4634 result.AppendErrorWithFormat("invalid module path '%s'\n", 4635 entry.c_str()); 4636 break; 4637 } 4638 } 4639 } 4640 } 4641 } 4642 4643 if (flush) { 4644 Process *process = m_exe_ctx.GetProcessPtr(); 4645 if (process) 4646 process->Flush(); 4647 } 4648 } 4649 4650 OptionGroupOptions m_option_group; 4651 OptionGroupUUID m_uuid_option_group; 4652 OptionGroupFile m_file_option; 4653 OptionGroupBoolean m_current_frame_option; 4654 OptionGroupBoolean m_current_stack_option; 4655 }; 4656 4657 #pragma mark CommandObjectTargetSymbols 4658 4659 // CommandObjectTargetSymbols 4660 4661 class CommandObjectTargetSymbols : public CommandObjectMultiword { 4662 public: 4663 // Constructors and Destructors 4664 CommandObjectTargetSymbols(CommandInterpreter &interpreter) 4665 : CommandObjectMultiword( 4666 interpreter, "target symbols", 4667 "Commands for adding and managing debug symbol files.", 4668 "target symbols <sub-command> ...") { 4669 LoadSubCommand( 4670 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter))); 4671 } 4672 4673 ~CommandObjectTargetSymbols() override = default; 4674 4675 private: 4676 // For CommandObjectTargetModules only 4677 CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete; 4678 const CommandObjectTargetSymbols & 4679 operator=(const CommandObjectTargetSymbols &) = delete; 4680 }; 4681 4682 #pragma mark CommandObjectTargetStopHookAdd 4683 4684 // CommandObjectTargetStopHookAdd 4685 #define LLDB_OPTIONS_target_stop_hook_add 4686 #include "CommandOptions.inc" 4687 4688 class CommandObjectTargetStopHookAdd : public CommandObjectParsed, 4689 public IOHandlerDelegateMultiline { 4690 public: 4691 class CommandOptions : public OptionGroup { 4692 public: 4693 CommandOptions() : m_line_end(UINT_MAX) {} 4694 4695 ~CommandOptions() override = default; 4696 4697 llvm::ArrayRef<OptionDefinition> GetDefinitions() override { 4698 return llvm::ArrayRef(g_target_stop_hook_add_options); 4699 } 4700 4701 Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg, 4702 ExecutionContext *execution_context) override { 4703 Status error; 4704 const int short_option = 4705 g_target_stop_hook_add_options[option_idx].short_option; 4706 4707 switch (short_option) { 4708 case 'c': 4709 m_class_name = std::string(option_arg); 4710 m_sym_ctx_specified = true; 4711 break; 4712 4713 case 'e': 4714 if (option_arg.getAsInteger(0, m_line_end)) { 4715 error = Status::FromErrorStringWithFormat( 4716 "invalid end line number: \"%s\"", option_arg.str().c_str()); 4717 break; 4718 } 4719 m_sym_ctx_specified = true; 4720 break; 4721 4722 case 'G': { 4723 bool value, success; 4724 value = OptionArgParser::ToBoolean(option_arg, false, &success); 4725 if (success) { 4726 m_auto_continue = value; 4727 } else 4728 error = Status::FromErrorStringWithFormat( 4729 "invalid boolean value '%s' passed for -G option", 4730 option_arg.str().c_str()); 4731 } break; 4732 case 'l': 4733 if (option_arg.getAsInteger(0, m_line_start)) { 4734 error = Status::FromErrorStringWithFormat( 4735 "invalid start line number: \"%s\"", option_arg.str().c_str()); 4736 break; 4737 } 4738 m_sym_ctx_specified = true; 4739 break; 4740 4741 case 'i': 4742 m_no_inlines = true; 4743 break; 4744 4745 case 'n': 4746 m_function_name = std::string(option_arg); 4747 m_func_name_type_mask |= eFunctionNameTypeAuto; 4748 m_sym_ctx_specified = true; 4749 break; 4750 4751 case 'f': 4752 m_file_name = std::string(option_arg); 4753 m_sym_ctx_specified = true; 4754 break; 4755 4756 case 's': 4757 m_module_name = std::string(option_arg); 4758 m_sym_ctx_specified = true; 4759 break; 4760 4761 case 't': 4762 if (option_arg.getAsInteger(0, m_thread_id)) 4763 error = Status::FromErrorStringWithFormat( 4764 "invalid thread id string '%s'", option_arg.str().c_str()); 4765 m_thread_specified = true; 4766 break; 4767 4768 case 'T': 4769 m_thread_name = std::string(option_arg); 4770 m_thread_specified = true; 4771 break; 4772 4773 case 'q': 4774 m_queue_name = std::string(option_arg); 4775 m_thread_specified = true; 4776 break; 4777 4778 case 'x': 4779 if (option_arg.getAsInteger(0, m_thread_index)) 4780 error = Status::FromErrorStringWithFormat( 4781 "invalid thread index string '%s'", option_arg.str().c_str()); 4782 m_thread_specified = true; 4783 break; 4784 4785 case 'o': 4786 m_use_one_liner = true; 4787 m_one_liner.push_back(std::string(option_arg)); 4788 break; 4789 4790 default: 4791 llvm_unreachable("Unimplemented option"); 4792 } 4793 return error; 4794 } 4795 4796 void OptionParsingStarting(ExecutionContext *execution_context) override { 4797 m_class_name.clear(); 4798 m_function_name.clear(); 4799 m_line_start = 0; 4800 m_line_end = LLDB_INVALID_LINE_NUMBER; 4801 m_file_name.clear(); 4802 m_module_name.clear(); 4803 m_func_name_type_mask = eFunctionNameTypeAuto; 4804 m_thread_id = LLDB_INVALID_THREAD_ID; 4805 m_thread_index = UINT32_MAX; 4806 m_thread_name.clear(); 4807 m_queue_name.clear(); 4808 4809 m_no_inlines = false; 4810 m_sym_ctx_specified = false; 4811 m_thread_specified = false; 4812 4813 m_use_one_liner = false; 4814 m_one_liner.clear(); 4815 m_auto_continue = false; 4816 } 4817 4818 std::string m_class_name; 4819 std::string m_function_name; 4820 uint32_t m_line_start = 0; 4821 uint32_t m_line_end = LLDB_INVALID_LINE_NUMBER; 4822 std::string m_file_name; 4823 std::string m_module_name; 4824 uint32_t m_func_name_type_mask = 4825 eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType. 4826 lldb::tid_t m_thread_id = LLDB_INVALID_THREAD_ID; 4827 uint32_t m_thread_index = UINT32_MAX; 4828 std::string m_thread_name; 4829 std::string m_queue_name; 4830 bool m_sym_ctx_specified = false; 4831 bool m_no_inlines = false; 4832 bool m_thread_specified = false; 4833 // Instance variables to hold the values for one_liner options. 4834 bool m_use_one_liner = false; 4835 std::vector<std::string> m_one_liner; 4836 4837 bool m_auto_continue = false; 4838 }; 4839 4840 CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter) 4841 : CommandObjectParsed(interpreter, "target stop-hook add", 4842 "Add a hook to be executed when the target stops." 4843 "The hook can either be a list of commands or an " 4844 "appropriately defined Python class. You can also " 4845 "add filters so the hook only runs a certain stop " 4846 "points.", 4847 "target stop-hook add"), 4848 IOHandlerDelegateMultiline("DONE", 4849 IOHandlerDelegate::Completion::LLDBCommand), 4850 m_python_class_options("scripted stop-hook", true, 'P') { 4851 SetHelpLong( 4852 R"( 4853 Command Based stop-hooks: 4854 ------------------------- 4855 Stop hooks can run a list of lldb commands by providing one or more 4856 --one-line-command options. The commands will get run in the order they are 4857 added. Or you can provide no commands, in which case you will enter a 4858 command editor where you can enter the commands to be run. 4859 4860 Python Based Stop Hooks: 4861 ------------------------ 4862 Stop hooks can be implemented with a suitably defined Python class, whose name 4863 is passed in the --python-class option. 4864 4865 When the stop hook is added, the class is initialized by calling: 4866 4867 def __init__(self, target, extra_args, internal_dict): 4868 4869 target: The target that the stop hook is being added to. 4870 extra_args: An SBStructuredData Dictionary filled with the -key -value 4871 option pairs passed to the command. 4872 dict: An implementation detail provided by lldb. 4873 4874 Then when the stop-hook triggers, lldb will run the 'handle_stop' method. 4875 The method has the signature: 4876 4877 def handle_stop(self, exe_ctx, stream): 4878 4879 exe_ctx: An SBExecutionContext for the thread that has stopped. 4880 stream: An SBStream, anything written to this stream will be printed in the 4881 the stop message when the process stops. 4882 4883 Return Value: The method returns "should_stop". If should_stop is false 4884 from all the stop hook executions on threads that stopped 4885 with a reason, then the process will continue. Note that this 4886 will happen only after all the stop hooks are run. 4887 4888 Filter Options: 4889 --------------- 4890 Stop hooks can be set to always run, or to only run when the stopped thread 4891 matches the filter options passed on the command line. The available filter 4892 options include a shared library or a thread or queue specification, 4893 a line range in a source file, a function name or a class name. 4894 )"); 4895 m_all_options.Append(&m_python_class_options, 4896 LLDB_OPT_SET_1 | LLDB_OPT_SET_2, 4897 LLDB_OPT_SET_FROM_TO(4, 6)); 4898 m_all_options.Append(&m_options); 4899 m_all_options.Finalize(); 4900 } 4901 4902 ~CommandObjectTargetStopHookAdd() override = default; 4903 4904 Options *GetOptions() override { return &m_all_options; } 4905 4906 protected: 4907 void IOHandlerActivated(IOHandler &io_handler, bool interactive) override { 4908 StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); 4909 if (output_sp && interactive) { 4910 output_sp->PutCString( 4911 "Enter your stop hook command(s). Type 'DONE' to end.\n"); 4912 output_sp->Flush(); 4913 } 4914 } 4915 4916 void IOHandlerInputComplete(IOHandler &io_handler, 4917 std::string &line) override { 4918 if (m_stop_hook_sp) { 4919 if (line.empty()) { 4920 StreamFileSP error_sp(io_handler.GetErrorStreamFileSP()); 4921 if (error_sp) { 4922 error_sp->Printf("error: stop hook #%" PRIu64 4923 " aborted, no commands.\n", 4924 m_stop_hook_sp->GetID()); 4925 error_sp->Flush(); 4926 } 4927 GetTarget().UndoCreateStopHook(m_stop_hook_sp->GetID()); 4928 } else { 4929 // The IOHandler editor is only for command lines stop hooks: 4930 Target::StopHookCommandLine *hook_ptr = 4931 static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get()); 4932 4933 hook_ptr->SetActionFromString(line); 4934 StreamFileSP output_sp(io_handler.GetOutputStreamFileSP()); 4935 if (output_sp) { 4936 output_sp->Printf("Stop hook #%" PRIu64 " added.\n", 4937 m_stop_hook_sp->GetID()); 4938 output_sp->Flush(); 4939 } 4940 } 4941 m_stop_hook_sp.reset(); 4942 } 4943 io_handler.SetIsDone(true); 4944 } 4945 4946 void DoExecute(Args &command, CommandReturnObject &result) override { 4947 m_stop_hook_sp.reset(); 4948 4949 Target &target = GetTarget(); 4950 Target::StopHookSP new_hook_sp = 4951 target.CreateStopHook(m_python_class_options.GetName().empty() ? 4952 Target::StopHook::StopHookKind::CommandBased 4953 : Target::StopHook::StopHookKind::ScriptBased); 4954 4955 // First step, make the specifier. 4956 std::unique_ptr<SymbolContextSpecifier> specifier_up; 4957 if (m_options.m_sym_ctx_specified) { 4958 specifier_up = std::make_unique<SymbolContextSpecifier>( 4959 GetDebugger().GetSelectedTarget()); 4960 4961 if (!m_options.m_module_name.empty()) { 4962 specifier_up->AddSpecification( 4963 m_options.m_module_name.c_str(), 4964 SymbolContextSpecifier::eModuleSpecified); 4965 } 4966 4967 if (!m_options.m_class_name.empty()) { 4968 specifier_up->AddSpecification( 4969 m_options.m_class_name.c_str(), 4970 SymbolContextSpecifier::eClassOrNamespaceSpecified); 4971 } 4972 4973 if (!m_options.m_file_name.empty()) { 4974 specifier_up->AddSpecification(m_options.m_file_name.c_str(), 4975 SymbolContextSpecifier::eFileSpecified); 4976 } 4977 4978 if (m_options.m_line_start != 0) { 4979 specifier_up->AddLineSpecification( 4980 m_options.m_line_start, 4981 SymbolContextSpecifier::eLineStartSpecified); 4982 } 4983 4984 if (m_options.m_line_end != UINT_MAX) { 4985 specifier_up->AddLineSpecification( 4986 m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified); 4987 } 4988 4989 if (!m_options.m_function_name.empty()) { 4990 specifier_up->AddSpecification( 4991 m_options.m_function_name.c_str(), 4992 SymbolContextSpecifier::eFunctionSpecified); 4993 } 4994 } 4995 4996 if (specifier_up) 4997 new_hook_sp->SetSpecifier(specifier_up.release()); 4998 4999 // Next see if any of the thread options have been entered: 5000 5001 if (m_options.m_thread_specified) { 5002 ThreadSpec *thread_spec = new ThreadSpec(); 5003 5004 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) { 5005 thread_spec->SetTID(m_options.m_thread_id); 5006 } 5007 5008 if (m_options.m_thread_index != UINT32_MAX) 5009 thread_spec->SetIndex(m_options.m_thread_index); 5010 5011 if (!m_options.m_thread_name.empty()) 5012 thread_spec->SetName(m_options.m_thread_name.c_str()); 5013 5014 if (!m_options.m_queue_name.empty()) 5015 thread_spec->SetQueueName(m_options.m_queue_name.c_str()); 5016 5017 new_hook_sp->SetThreadSpecifier(thread_spec); 5018 } 5019 5020 new_hook_sp->SetAutoContinue(m_options.m_auto_continue); 5021 if (m_options.m_use_one_liner) { 5022 // This is a command line stop hook: 5023 Target::StopHookCommandLine *hook_ptr = 5024 static_cast<Target::StopHookCommandLine *>(new_hook_sp.get()); 5025 hook_ptr->SetActionFromStrings(m_options.m_one_liner); 5026 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", 5027 new_hook_sp->GetID()); 5028 } else if (!m_python_class_options.GetName().empty()) { 5029 // This is a scripted stop hook: 5030 Target::StopHookScripted *hook_ptr = 5031 static_cast<Target::StopHookScripted *>(new_hook_sp.get()); 5032 Status error = hook_ptr->SetScriptCallback( 5033 m_python_class_options.GetName(), 5034 m_python_class_options.GetStructuredData()); 5035 if (error.Success()) 5036 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n", 5037 new_hook_sp->GetID()); 5038 else { 5039 // FIXME: Set the stop hook ID counter back. 5040 result.AppendErrorWithFormat("Couldn't add stop hook: %s", 5041 error.AsCString()); 5042 target.UndoCreateStopHook(new_hook_sp->GetID()); 5043 return; 5044 } 5045 } else { 5046 m_stop_hook_sp = new_hook_sp; 5047 m_interpreter.GetLLDBCommandsFromIOHandler("> ", // Prompt 5048 *this); // IOHandlerDelegate 5049 } 5050 result.SetStatus(eReturnStatusSuccessFinishNoResult); 5051 } 5052 5053 private: 5054 CommandOptions m_options; 5055 OptionGroupPythonClassWithDict m_python_class_options; 5056 OptionGroupOptions m_all_options; 5057 5058 Target::StopHookSP m_stop_hook_sp; 5059 }; 5060 5061 #pragma mark CommandObjectTargetStopHookDelete 5062 5063 // CommandObjectTargetStopHookDelete 5064 5065 class CommandObjectTargetStopHookDelete : public CommandObjectParsed { 5066 public: 5067 CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter) 5068 : CommandObjectParsed(interpreter, "target stop-hook delete", 5069 "Delete a stop-hook.", 5070 "target stop-hook delete [<idx>]") { 5071 AddSimpleArgumentList(eArgTypeStopHookID, eArgRepeatStar); 5072 } 5073 5074 ~CommandObjectTargetStopHookDelete() override = default; 5075 5076 void 5077 HandleArgumentCompletion(CompletionRequest &request, 5078 OptionElementVector &opt_element_vector) override { 5079 if (request.GetCursorIndex()) 5080 return; 5081 CommandObject::HandleArgumentCompletion(request, opt_element_vector); 5082 } 5083 5084 protected: 5085 void DoExecute(Args &command, CommandReturnObject &result) override { 5086 Target &target = GetTarget(); 5087 // FIXME: see if we can use the breakpoint id style parser? 5088 size_t num_args = command.GetArgumentCount(); 5089 if (num_args == 0) { 5090 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) { 5091 result.SetStatus(eReturnStatusFailed); 5092 return; 5093 } else { 5094 target.RemoveAllStopHooks(); 5095 } 5096 } else { 5097 for (size_t i = 0; i < num_args; i++) { 5098 lldb::user_id_t user_id; 5099 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) { 5100 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", 5101 command.GetArgumentAtIndex(i)); 5102 return; 5103 } 5104 if (!target.RemoveStopHookByID(user_id)) { 5105 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n", 5106 command.GetArgumentAtIndex(i)); 5107 return; 5108 } 5109 } 5110 } 5111 result.SetStatus(eReturnStatusSuccessFinishNoResult); 5112 } 5113 }; 5114 5115 #pragma mark CommandObjectTargetStopHookEnableDisable 5116 5117 // CommandObjectTargetStopHookEnableDisable 5118 5119 class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed { 5120 public: 5121 CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter, 5122 bool enable, const char *name, 5123 const char *help, const char *syntax) 5124 : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) { 5125 AddSimpleArgumentList(eArgTypeStopHookID, eArgRepeatStar); 5126 } 5127 5128 ~CommandObjectTargetStopHookEnableDisable() override = default; 5129 5130 void 5131 HandleArgumentCompletion(CompletionRequest &request, 5132 OptionElementVector &opt_element_vector) override { 5133 if (request.GetCursorIndex()) 5134 return; 5135 CommandObject::HandleArgumentCompletion(request, opt_element_vector); 5136 } 5137 5138 protected: 5139 void DoExecute(Args &command, CommandReturnObject &result) override { 5140 Target &target = GetTarget(); 5141 // FIXME: see if we can use the breakpoint id style parser? 5142 size_t num_args = command.GetArgumentCount(); 5143 bool success; 5144 5145 if (num_args == 0) { 5146 target.SetAllStopHooksActiveState(m_enable); 5147 } else { 5148 for (size_t i = 0; i < num_args; i++) { 5149 lldb::user_id_t user_id; 5150 if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) { 5151 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n", 5152 command.GetArgumentAtIndex(i)); 5153 return; 5154 } 5155 success = target.SetStopHookActiveStateByID(user_id, m_enable); 5156 if (!success) { 5157 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n", 5158 command.GetArgumentAtIndex(i)); 5159 return; 5160 } 5161 } 5162 } 5163 result.SetStatus(eReturnStatusSuccessFinishNoResult); 5164 } 5165 5166 private: 5167 bool m_enable; 5168 }; 5169 5170 #pragma mark CommandObjectTargetStopHookList 5171 5172 // CommandObjectTargetStopHookList 5173 5174 class CommandObjectTargetStopHookList : public CommandObjectParsed { 5175 public: 5176 CommandObjectTargetStopHookList(CommandInterpreter &interpreter) 5177 : CommandObjectParsed(interpreter, "target stop-hook list", 5178 "List all stop-hooks.", "target stop-hook list") {} 5179 5180 ~CommandObjectTargetStopHookList() override = default; 5181 5182 protected: 5183 void DoExecute(Args &command, CommandReturnObject &result) override { 5184 Target &target = GetTarget(); 5185 5186 size_t num_hooks = target.GetNumStopHooks(); 5187 if (num_hooks == 0) { 5188 result.GetOutputStream().PutCString("No stop hooks.\n"); 5189 } else { 5190 for (size_t i = 0; i < num_hooks; i++) { 5191 Target::StopHookSP this_hook = target.GetStopHookAtIndex(i); 5192 if (i > 0) 5193 result.GetOutputStream().PutCString("\n"); 5194 this_hook->GetDescription(result.GetOutputStream(), 5195 eDescriptionLevelFull); 5196 } 5197 } 5198 result.SetStatus(eReturnStatusSuccessFinishResult); 5199 } 5200 }; 5201 5202 #pragma mark CommandObjectMultiwordTargetStopHooks 5203 5204 // CommandObjectMultiwordTargetStopHooks 5205 5206 class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword { 5207 public: 5208 CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter) 5209 : CommandObjectMultiword( 5210 interpreter, "target stop-hook", 5211 "Commands for operating on debugger target stop-hooks.", 5212 "target stop-hook <subcommand> [<subcommand-options>]") { 5213 LoadSubCommand("add", CommandObjectSP( 5214 new CommandObjectTargetStopHookAdd(interpreter))); 5215 LoadSubCommand( 5216 "delete", 5217 CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter))); 5218 LoadSubCommand("disable", 5219 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable( 5220 interpreter, false, "target stop-hook disable [<id>]", 5221 "Disable a stop-hook.", "target stop-hook disable"))); 5222 LoadSubCommand("enable", 5223 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable( 5224 interpreter, true, "target stop-hook enable [<id>]", 5225 "Enable a stop-hook.", "target stop-hook enable"))); 5226 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList( 5227 interpreter))); 5228 } 5229 5230 ~CommandObjectMultiwordTargetStopHooks() override = default; 5231 }; 5232 5233 #pragma mark CommandObjectTargetDumpTypesystem 5234 5235 /// Dumps the TypeSystem of the selected Target. 5236 class CommandObjectTargetDumpTypesystem : public CommandObjectParsed { 5237 public: 5238 CommandObjectTargetDumpTypesystem(CommandInterpreter &interpreter) 5239 : CommandObjectParsed( 5240 interpreter, "target dump typesystem", 5241 "Dump the state of the target's internal type system. Intended to " 5242 "be used for debugging LLDB itself.", 5243 nullptr, eCommandRequiresTarget) {} 5244 5245 ~CommandObjectTargetDumpTypesystem() override = default; 5246 5247 protected: 5248 void DoExecute(Args &command, CommandReturnObject &result) override { 5249 // Go over every scratch TypeSystem and dump to the command output. 5250 for (lldb::TypeSystemSP ts : GetTarget().GetScratchTypeSystems()) 5251 if (ts) 5252 ts->Dump(result.GetOutputStream().AsRawOstream()); 5253 5254 result.SetStatus(eReturnStatusSuccessFinishResult); 5255 } 5256 }; 5257 5258 #pragma mark CommandObjectTargetDumpSectionLoadList 5259 5260 /// Dumps the SectionLoadList of the selected Target. 5261 class CommandObjectTargetDumpSectionLoadList : public CommandObjectParsed { 5262 public: 5263 CommandObjectTargetDumpSectionLoadList(CommandInterpreter &interpreter) 5264 : CommandObjectParsed( 5265 interpreter, "target dump section-load-list", 5266 "Dump the state of the target's internal section load list. " 5267 "Intended to be used for debugging LLDB itself.", 5268 nullptr, eCommandRequiresTarget) {} 5269 5270 ~CommandObjectTargetDumpSectionLoadList() override = default; 5271 5272 protected: 5273 void DoExecute(Args &command, CommandReturnObject &result) override { 5274 Target &target = GetTarget(); 5275 target.GetSectionLoadList().Dump(result.GetOutputStream(), &target); 5276 result.SetStatus(eReturnStatusSuccessFinishResult); 5277 } 5278 }; 5279 5280 #pragma mark CommandObjectTargetDump 5281 5282 /// Multi-word command for 'target dump'. 5283 class CommandObjectTargetDump : public CommandObjectMultiword { 5284 public: 5285 // Constructors and Destructors 5286 CommandObjectTargetDump(CommandInterpreter &interpreter) 5287 : CommandObjectMultiword( 5288 interpreter, "target dump", 5289 "Commands for dumping information about the target.", 5290 "target dump [typesystem|section-load-list]") { 5291 LoadSubCommand( 5292 "typesystem", 5293 CommandObjectSP(new CommandObjectTargetDumpTypesystem(interpreter))); 5294 LoadSubCommand("section-load-list", 5295 CommandObjectSP(new CommandObjectTargetDumpSectionLoadList( 5296 interpreter))); 5297 } 5298 5299 ~CommandObjectTargetDump() override = default; 5300 }; 5301 5302 #pragma mark CommandObjectMultiwordTarget 5303 5304 // CommandObjectMultiwordTarget 5305 5306 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget( 5307 CommandInterpreter &interpreter) 5308 : CommandObjectMultiword(interpreter, "target", 5309 "Commands for operating on debugger targets.", 5310 "target <subcommand> [<subcommand-options>]") { 5311 LoadSubCommand("create", 5312 CommandObjectSP(new CommandObjectTargetCreate(interpreter))); 5313 LoadSubCommand("delete", 5314 CommandObjectSP(new CommandObjectTargetDelete(interpreter))); 5315 LoadSubCommand("dump", 5316 CommandObjectSP(new CommandObjectTargetDump(interpreter))); 5317 LoadSubCommand("list", 5318 CommandObjectSP(new CommandObjectTargetList(interpreter))); 5319 LoadSubCommand("select", 5320 CommandObjectSP(new CommandObjectTargetSelect(interpreter))); 5321 LoadSubCommand("show-launch-environment", 5322 CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment( 5323 interpreter))); 5324 LoadSubCommand( 5325 "stop-hook", 5326 CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter))); 5327 LoadSubCommand("modules", 5328 CommandObjectSP(new CommandObjectTargetModules(interpreter))); 5329 LoadSubCommand("symbols", 5330 CommandObjectSP(new CommandObjectTargetSymbols(interpreter))); 5331 LoadSubCommand("variable", 5332 CommandObjectSP(new CommandObjectTargetVariable(interpreter))); 5333 } 5334 5335 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default; 5336