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