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