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