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