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