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