15ffd83dbSDimitry Andric //===-- CommandObjectTarget.cpp -------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #include "CommandObjectTarget.h"
100b57cec5SDimitry Andric
110b57cec5SDimitry Andric #include "lldb/Core/Debugger.h"
120b57cec5SDimitry Andric #include "lldb/Core/IOHandler.h"
130b57cec5SDimitry Andric #include "lldb/Core/Module.h"
140b57cec5SDimitry Andric #include "lldb/Core/ModuleSpec.h"
150b57cec5SDimitry Andric #include "lldb/Core/Section.h"
160b57cec5SDimitry Andric #include "lldb/Core/ValueObjectVariable.h"
170b57cec5SDimitry Andric #include "lldb/DataFormatters/ValueObjectPrinter.h"
180b57cec5SDimitry Andric #include "lldb/Host/OptionParser.h"
190b57cec5SDimitry Andric #include "lldb/Interpreter/CommandInterpreter.h"
200b57cec5SDimitry Andric #include "lldb/Interpreter/CommandReturnObject.h"
210b57cec5SDimitry Andric #include "lldb/Interpreter/OptionArgParser.h"
220b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupArchitecture.h"
230b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupBoolean.h"
240b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupFile.h"
250b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupFormat.h"
26af732203SDimitry Andric #include "lldb/Interpreter/OptionGroupPlatform.h"
27af732203SDimitry Andric #include "lldb/Interpreter/OptionGroupPythonClassWithDict.h"
280b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupString.h"
290b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupUInt64.h"
300b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupUUID.h"
310b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
320b57cec5SDimitry Andric #include "lldb/Interpreter/OptionGroupVariable.h"
330b57cec5SDimitry Andric #include "lldb/Interpreter/Options.h"
340b57cec5SDimitry Andric #include "lldb/Symbol/CompileUnit.h"
350b57cec5SDimitry Andric #include "lldb/Symbol/FuncUnwinders.h"
360b57cec5SDimitry Andric #include "lldb/Symbol/LineTable.h"
370b57cec5SDimitry Andric #include "lldb/Symbol/LocateSymbolFile.h"
380b57cec5SDimitry Andric #include "lldb/Symbol/ObjectFile.h"
390b57cec5SDimitry Andric #include "lldb/Symbol/SymbolFile.h"
400b57cec5SDimitry Andric #include "lldb/Symbol/UnwindPlan.h"
410b57cec5SDimitry Andric #include "lldb/Symbol/VariableList.h"
420b57cec5SDimitry Andric #include "lldb/Target/ABI.h"
430b57cec5SDimitry Andric #include "lldb/Target/Process.h"
440b57cec5SDimitry Andric #include "lldb/Target/RegisterContext.h"
450b57cec5SDimitry Andric #include "lldb/Target/SectionLoadList.h"
460b57cec5SDimitry Andric #include "lldb/Target/StackFrame.h"
470b57cec5SDimitry Andric #include "lldb/Target/Thread.h"
480b57cec5SDimitry Andric #include "lldb/Target/ThreadSpec.h"
490b57cec5SDimitry Andric #include "lldb/Utility/Args.h"
500b57cec5SDimitry Andric #include "lldb/Utility/State.h"
510b57cec5SDimitry Andric #include "lldb/Utility/Timer.h"
520b57cec5SDimitry Andric
53af732203SDimitry Andric #include "llvm/ADT/ScopeExit.h"
540b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
550b57cec5SDimitry Andric #include "llvm/Support/FormatAdapters.h"
560b57cec5SDimitry Andric
570b57cec5SDimitry Andric
580b57cec5SDimitry Andric using namespace lldb;
590b57cec5SDimitry Andric using namespace lldb_private;
600b57cec5SDimitry Andric
DumpTargetInfo(uint32_t target_idx,Target * target,const char * prefix_cstr,bool show_stopped_process_status,Stream & strm)610b57cec5SDimitry Andric static void DumpTargetInfo(uint32_t target_idx, Target *target,
620b57cec5SDimitry Andric const char *prefix_cstr,
630b57cec5SDimitry Andric bool show_stopped_process_status, Stream &strm) {
640b57cec5SDimitry Andric const ArchSpec &target_arch = target->GetArchitecture();
650b57cec5SDimitry Andric
660b57cec5SDimitry Andric Module *exe_module = target->GetExecutableModulePointer();
670b57cec5SDimitry Andric char exe_path[PATH_MAX];
680b57cec5SDimitry Andric bool exe_valid = false;
690b57cec5SDimitry Andric if (exe_module)
700b57cec5SDimitry Andric exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
710b57cec5SDimitry Andric
720b57cec5SDimitry Andric if (!exe_valid)
730b57cec5SDimitry Andric ::strcpy(exe_path, "<none>");
740b57cec5SDimitry Andric
750b57cec5SDimitry Andric strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
760b57cec5SDimitry Andric exe_path);
770b57cec5SDimitry Andric
780b57cec5SDimitry Andric uint32_t properties = 0;
790b57cec5SDimitry Andric if (target_arch.IsValid()) {
800b57cec5SDimitry Andric strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
81480093f4SDimitry Andric target_arch.DumpTriple(strm.AsRawOstream());
820b57cec5SDimitry Andric properties++;
830b57cec5SDimitry Andric }
840b57cec5SDimitry Andric PlatformSP platform_sp(target->GetPlatform());
850b57cec5SDimitry Andric if (platform_sp)
860b57cec5SDimitry Andric strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ",
870b57cec5SDimitry Andric platform_sp->GetName().GetCString());
880b57cec5SDimitry Andric
890b57cec5SDimitry Andric ProcessSP process_sp(target->GetProcessSP());
900b57cec5SDimitry Andric bool show_process_status = false;
910b57cec5SDimitry Andric if (process_sp) {
920b57cec5SDimitry Andric lldb::pid_t pid = process_sp->GetID();
930b57cec5SDimitry Andric StateType state = process_sp->GetState();
940b57cec5SDimitry Andric if (show_stopped_process_status)
950b57cec5SDimitry Andric show_process_status = StateIsStoppedState(state, true);
960b57cec5SDimitry Andric const char *state_cstr = StateAsCString(state);
970b57cec5SDimitry Andric if (pid != LLDB_INVALID_PROCESS_ID)
980b57cec5SDimitry Andric strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
990b57cec5SDimitry Andric strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric if (properties > 0)
1020b57cec5SDimitry Andric strm.PutCString(" )\n");
1030b57cec5SDimitry Andric else
1040b57cec5SDimitry Andric strm.EOL();
1050b57cec5SDimitry Andric if (show_process_status) {
1060b57cec5SDimitry Andric const bool only_threads_with_stop_reason = true;
1070b57cec5SDimitry Andric const uint32_t start_frame = 0;
1080b57cec5SDimitry Andric const uint32_t num_frames = 1;
1090b57cec5SDimitry Andric const uint32_t num_frames_with_source = 1;
1100b57cec5SDimitry Andric const bool stop_format = false;
1110b57cec5SDimitry Andric process_sp->GetStatus(strm);
1120b57cec5SDimitry Andric process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
113480093f4SDimitry Andric start_frame, num_frames, num_frames_with_source,
114480093f4SDimitry Andric stop_format);
1150b57cec5SDimitry Andric }
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric
DumpTargetList(TargetList & target_list,bool show_stopped_process_status,Stream & strm)1180b57cec5SDimitry Andric static uint32_t DumpTargetList(TargetList &target_list,
1190b57cec5SDimitry Andric bool show_stopped_process_status, Stream &strm) {
1200b57cec5SDimitry Andric const uint32_t num_targets = target_list.GetNumTargets();
1210b57cec5SDimitry Andric if (num_targets) {
1220b57cec5SDimitry Andric TargetSP selected_target_sp(target_list.GetSelectedTarget());
1230b57cec5SDimitry Andric strm.PutCString("Current targets:\n");
1240b57cec5SDimitry Andric for (uint32_t i = 0; i < num_targets; ++i) {
1250b57cec5SDimitry Andric TargetSP target_sp(target_list.GetTargetAtIndex(i));
1260b57cec5SDimitry Andric if (target_sp) {
1270b57cec5SDimitry Andric bool is_selected = target_sp.get() == selected_target_sp.get();
1280b57cec5SDimitry Andric DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
1290b57cec5SDimitry Andric show_stopped_process_status, strm);
1300b57cec5SDimitry Andric }
1310b57cec5SDimitry Andric }
1320b57cec5SDimitry Andric }
1330b57cec5SDimitry Andric return num_targets;
1340b57cec5SDimitry Andric }
1350b57cec5SDimitry Andric
1360b57cec5SDimitry Andric // Note that the negation in the argument name causes a slightly confusing
1379dba64beSDimitry Andric // mapping of the enum values.
1380b57cec5SDimitry Andric static constexpr OptionEnumValueElement g_dependents_enumaration[] = {
1399dba64beSDimitry Andric {
1409dba64beSDimitry Andric eLoadDependentsDefault,
1419dba64beSDimitry Andric "default",
1429dba64beSDimitry Andric "Only load dependents when the target is an executable.",
1439dba64beSDimitry Andric },
1449dba64beSDimitry Andric {
1459dba64beSDimitry Andric eLoadDependentsNo,
1469dba64beSDimitry Andric "true",
1479dba64beSDimitry Andric "Don't load dependents, even if the target is an executable.",
1489dba64beSDimitry Andric },
1499dba64beSDimitry Andric {
1509dba64beSDimitry Andric eLoadDependentsYes,
1519dba64beSDimitry Andric "false",
1529dba64beSDimitry Andric "Load dependents, even if the target is not an executable.",
1539dba64beSDimitry Andric },
1549dba64beSDimitry Andric };
1550b57cec5SDimitry Andric
1569dba64beSDimitry Andric #define LLDB_OPTIONS_target_dependents
1579dba64beSDimitry Andric #include "CommandOptions.inc"
1580b57cec5SDimitry Andric
1590b57cec5SDimitry Andric class OptionGroupDependents : public OptionGroup {
1600b57cec5SDimitry Andric public:
161*5f7ddb14SDimitry Andric OptionGroupDependents() = default;
1620b57cec5SDimitry Andric
163*5f7ddb14SDimitry Andric ~OptionGroupDependents() override = default;
1640b57cec5SDimitry Andric
GetDefinitions()1650b57cec5SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1669dba64beSDimitry Andric return llvm::makeArrayRef(g_target_dependents_options);
1670b57cec5SDimitry Andric }
1680b57cec5SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_value,ExecutionContext * execution_context)1690b57cec5SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
1700b57cec5SDimitry Andric ExecutionContext *execution_context) override {
1710b57cec5SDimitry Andric Status error;
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andric // For compatibility no value means don't load dependents.
1740b57cec5SDimitry Andric if (option_value.empty()) {
1750b57cec5SDimitry Andric m_load_dependent_files = eLoadDependentsNo;
1760b57cec5SDimitry Andric return error;
1770b57cec5SDimitry Andric }
1780b57cec5SDimitry Andric
1799dba64beSDimitry Andric const char short_option =
1809dba64beSDimitry Andric g_target_dependents_options[option_idx].short_option;
1810b57cec5SDimitry Andric if (short_option == 'd') {
1820b57cec5SDimitry Andric LoadDependentFiles tmp_load_dependents;
1830b57cec5SDimitry Andric tmp_load_dependents = (LoadDependentFiles)OptionArgParser::ToOptionEnum(
1849dba64beSDimitry Andric option_value, g_target_dependents_options[option_idx].enum_values, 0,
1859dba64beSDimitry Andric error);
1860b57cec5SDimitry Andric if (error.Success())
1870b57cec5SDimitry Andric m_load_dependent_files = tmp_load_dependents;
1880b57cec5SDimitry Andric } else {
1890b57cec5SDimitry Andric error.SetErrorStringWithFormat("unrecognized short option '%c'",
1900b57cec5SDimitry Andric short_option);
1910b57cec5SDimitry Andric }
1920b57cec5SDimitry Andric
1930b57cec5SDimitry Andric return error;
1940b57cec5SDimitry Andric }
1950b57cec5SDimitry Andric
1960b57cec5SDimitry Andric Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
1970b57cec5SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)1980b57cec5SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
1990b57cec5SDimitry Andric m_load_dependent_files = eLoadDependentsDefault;
2000b57cec5SDimitry Andric }
2010b57cec5SDimitry Andric
2020b57cec5SDimitry Andric LoadDependentFiles m_load_dependent_files;
2030b57cec5SDimitry Andric
2040b57cec5SDimitry Andric private:
2055ffd83dbSDimitry Andric OptionGroupDependents(const OptionGroupDependents &) = delete;
2065ffd83dbSDimitry Andric const OptionGroupDependents &
2075ffd83dbSDimitry Andric operator=(const OptionGroupDependents &) = delete;
2080b57cec5SDimitry Andric };
2090b57cec5SDimitry Andric
2100b57cec5SDimitry Andric #pragma mark CommandObjectTargetCreate
2110b57cec5SDimitry Andric
2120b57cec5SDimitry Andric class CommandObjectTargetCreate : public CommandObjectParsed {
2130b57cec5SDimitry Andric public:
CommandObjectTargetCreate(CommandInterpreter & interpreter)2140b57cec5SDimitry Andric CommandObjectTargetCreate(CommandInterpreter &interpreter)
2150b57cec5SDimitry Andric : CommandObjectParsed(
2160b57cec5SDimitry Andric interpreter, "target create",
2170b57cec5SDimitry Andric "Create a target using the argument as the main executable.",
2180b57cec5SDimitry Andric nullptr),
2190b57cec5SDimitry Andric m_option_group(), m_arch_option(),
220af732203SDimitry Andric m_platform_options(true), // Include the --platform option.
2210b57cec5SDimitry Andric m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
2220b57cec5SDimitry Andric "Fullpath to a core file to use for this target."),
2230b57cec5SDimitry Andric m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2240b57cec5SDimitry Andric eArgTypeFilename,
2250b57cec5SDimitry Andric "Fullpath to a stand alone debug "
2260b57cec5SDimitry Andric "symbols file for when debug symbols "
2270b57cec5SDimitry Andric "are not in the executable."),
2280b57cec5SDimitry Andric m_remote_file(
2290b57cec5SDimitry Andric LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
2300b57cec5SDimitry Andric "Fullpath to the file on the remote host if debugging remotely."),
2310b57cec5SDimitry Andric m_add_dependents() {
2320b57cec5SDimitry Andric CommandArgumentEntry arg;
2330b57cec5SDimitry Andric CommandArgumentData file_arg;
2340b57cec5SDimitry Andric
2350b57cec5SDimitry Andric // Define the first (and only) variant of this arg.
2360b57cec5SDimitry Andric file_arg.arg_type = eArgTypeFilename;
2370b57cec5SDimitry Andric file_arg.arg_repetition = eArgRepeatPlain;
2380b57cec5SDimitry Andric
2390b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the
2400b57cec5SDimitry Andric // argument entry.
2410b57cec5SDimitry Andric arg.push_back(file_arg);
2420b57cec5SDimitry Andric
2430b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector.
2440b57cec5SDimitry Andric m_arguments.push_back(arg);
2450b57cec5SDimitry Andric
2460b57cec5SDimitry Andric m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
247af732203SDimitry Andric m_option_group.Append(&m_platform_options, LLDB_OPT_SET_ALL, 1);
2480b57cec5SDimitry Andric m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2490b57cec5SDimitry Andric m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2500b57cec5SDimitry Andric m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2510b57cec5SDimitry Andric m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2520b57cec5SDimitry Andric m_option_group.Finalize();
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric
2550b57cec5SDimitry Andric ~CommandObjectTargetCreate() override = default;
2560b57cec5SDimitry Andric
GetOptions()2570b57cec5SDimitry Andric Options *GetOptions() override { return &m_option_group; }
2580b57cec5SDimitry Andric
2599dba64beSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)2609dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
2610b57cec5SDimitry Andric OptionElementVector &opt_element_vector) override {
2620b57cec5SDimitry Andric CommandCompletions::InvokeCommonCompletionCallbacks(
2630b57cec5SDimitry Andric GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2640b57cec5SDimitry Andric request, nullptr);
2650b57cec5SDimitry Andric }
2660b57cec5SDimitry Andric
2670b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)2680b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
2690b57cec5SDimitry Andric const size_t argc = command.GetArgumentCount();
2700b57cec5SDimitry Andric FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
2710b57cec5SDimitry Andric FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
2720b57cec5SDimitry Andric
2730b57cec5SDimitry Andric if (core_file) {
2745ffd83dbSDimitry Andric auto file = FileSystem::Instance().Open(
2755ffd83dbSDimitry Andric core_file, lldb_private::File::eOpenOptionRead);
2765ffd83dbSDimitry Andric
2775ffd83dbSDimitry Andric if (!file) {
2785ffd83dbSDimitry Andric result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
2795ffd83dbSDimitry Andric core_file.GetPath(),
2805ffd83dbSDimitry Andric llvm::toString(file.takeError()));
2810b57cec5SDimitry Andric return false;
2820b57cec5SDimitry Andric }
2830b57cec5SDimitry Andric }
2840b57cec5SDimitry Andric
2850b57cec5SDimitry Andric if (argc == 1 || core_file || remote_file) {
2860b57cec5SDimitry Andric FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
2870b57cec5SDimitry Andric if (symfile) {
2885ffd83dbSDimitry Andric auto file = FileSystem::Instance().Open(
2895ffd83dbSDimitry Andric symfile, lldb_private::File::eOpenOptionRead);
2905ffd83dbSDimitry Andric
2915ffd83dbSDimitry Andric if (!file) {
2925ffd83dbSDimitry Andric result.AppendErrorWithFormatv("Cannot open '{0}': {1}.",
2935ffd83dbSDimitry Andric symfile.GetPath(),
2945ffd83dbSDimitry Andric llvm::toString(file.takeError()));
2950b57cec5SDimitry Andric return false;
2960b57cec5SDimitry Andric }
2970b57cec5SDimitry Andric }
2980b57cec5SDimitry Andric
2990b57cec5SDimitry Andric const char *file_path = command.GetArgumentAtIndex(0);
300af732203SDimitry Andric LLDB_SCOPED_TIMERF("(lldb) target create '%s'", file_path);
3010b57cec5SDimitry Andric FileSpec file_spec;
3020b57cec5SDimitry Andric
3030b57cec5SDimitry Andric if (file_path) {
3040b57cec5SDimitry Andric file_spec.SetFile(file_path, FileSpec::Style::native);
3050b57cec5SDimitry Andric FileSystem::Instance().Resolve(file_spec);
3060b57cec5SDimitry Andric }
3070b57cec5SDimitry Andric
3080b57cec5SDimitry Andric bool must_set_platform_path = false;
3090b57cec5SDimitry Andric
3100b57cec5SDimitry Andric Debugger &debugger = GetDebugger();
3110b57cec5SDimitry Andric
3120b57cec5SDimitry Andric TargetSP target_sp;
3130b57cec5SDimitry Andric llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
3140b57cec5SDimitry Andric Status error(debugger.GetTargetList().CreateTarget(
3150b57cec5SDimitry Andric debugger, file_path, arch_cstr,
316af732203SDimitry Andric m_add_dependents.m_load_dependent_files, &m_platform_options,
317af732203SDimitry Andric target_sp));
3180b57cec5SDimitry Andric
319af732203SDimitry Andric if (!target_sp) {
320af732203SDimitry Andric result.AppendError(error.AsCString());
321af732203SDimitry Andric return false;
322af732203SDimitry Andric }
323af732203SDimitry Andric
324af732203SDimitry Andric auto on_error = llvm::make_scope_exit(
325af732203SDimitry Andric [&target_list = debugger.GetTargetList(), &target_sp]() {
326af732203SDimitry Andric target_list.DeleteTarget(target_sp);
327af732203SDimitry Andric });
328af732203SDimitry Andric
3290b57cec5SDimitry Andric // Only get the platform after we create the target because we might
3300b57cec5SDimitry Andric // have switched platforms depending on what the arguments were to
3310b57cec5SDimitry Andric // CreateTarget() we can't rely on the selected platform.
3320b57cec5SDimitry Andric
3330b57cec5SDimitry Andric PlatformSP platform_sp = target_sp->GetPlatform();
3340b57cec5SDimitry Andric
3350b57cec5SDimitry Andric if (remote_file) {
3360b57cec5SDimitry Andric if (platform_sp) {
3370b57cec5SDimitry Andric // I have a remote file.. two possible cases
3380b57cec5SDimitry Andric if (file_spec && FileSystem::Instance().Exists(file_spec)) {
3390b57cec5SDimitry Andric // if the remote file does not exist, push it there
3400b57cec5SDimitry Andric if (!platform_sp->GetFileExists(remote_file)) {
3410b57cec5SDimitry Andric Status err = platform_sp->PutFile(file_spec, remote_file);
3420b57cec5SDimitry Andric if (err.Fail()) {
3430b57cec5SDimitry Andric result.AppendError(err.AsCString());
3440b57cec5SDimitry Andric return false;
3450b57cec5SDimitry Andric }
3460b57cec5SDimitry Andric }
3470b57cec5SDimitry Andric } else {
3480b57cec5SDimitry Andric // there is no local file and we need one
3490b57cec5SDimitry Andric // in order to make the remote ---> local transfer we need a
3500b57cec5SDimitry Andric // platform
3510b57cec5SDimitry Andric // TODO: if the user has passed in a --platform argument, use it
3520b57cec5SDimitry Andric // to fetch the right platform
3530b57cec5SDimitry Andric if (file_path) {
3540b57cec5SDimitry Andric // copy the remote file to the local file
3550b57cec5SDimitry Andric Status err = platform_sp->GetFile(remote_file, file_spec);
3560b57cec5SDimitry Andric if (err.Fail()) {
3570b57cec5SDimitry Andric result.AppendError(err.AsCString());
3580b57cec5SDimitry Andric return false;
3590b57cec5SDimitry Andric }
3600b57cec5SDimitry Andric } else {
3610b57cec5SDimitry Andric // make up a local file
3620b57cec5SDimitry Andric result.AppendError("remote --> local transfer without local "
3630b57cec5SDimitry Andric "path is not implemented yet");
3640b57cec5SDimitry Andric return false;
3650b57cec5SDimitry Andric }
3660b57cec5SDimitry Andric }
3670b57cec5SDimitry Andric } else {
3680b57cec5SDimitry Andric result.AppendError("no platform found for target");
3690b57cec5SDimitry Andric return false;
3700b57cec5SDimitry Andric }
3710b57cec5SDimitry Andric }
3720b57cec5SDimitry Andric
3730b57cec5SDimitry Andric if (symfile || remote_file) {
3740b57cec5SDimitry Andric ModuleSP module_sp(target_sp->GetExecutableModule());
3750b57cec5SDimitry Andric if (module_sp) {
3760b57cec5SDimitry Andric if (symfile)
3770b57cec5SDimitry Andric module_sp->SetSymbolFileFileSpec(symfile);
3780b57cec5SDimitry Andric if (remote_file) {
3790b57cec5SDimitry Andric std::string remote_path = remote_file.GetPath();
3800b57cec5SDimitry Andric target_sp->SetArg0(remote_path.c_str());
3810b57cec5SDimitry Andric module_sp->SetPlatformFileSpec(remote_file);
3820b57cec5SDimitry Andric }
3830b57cec5SDimitry Andric }
3840b57cec5SDimitry Andric }
3850b57cec5SDimitry Andric
3860b57cec5SDimitry Andric if (must_set_platform_path) {
3870b57cec5SDimitry Andric ModuleSpec main_module_spec(file_spec);
388480093f4SDimitry Andric ModuleSP module_sp =
389480093f4SDimitry Andric target_sp->GetOrCreateModule(main_module_spec, true /* notify */);
3900b57cec5SDimitry Andric if (module_sp)
3910b57cec5SDimitry Andric module_sp->SetPlatformFileSpec(remote_file);
3920b57cec5SDimitry Andric }
3935ffd83dbSDimitry Andric
3940b57cec5SDimitry Andric if (core_file) {
3950b57cec5SDimitry Andric FileSpec core_file_dir;
3960b57cec5SDimitry Andric core_file_dir.GetDirectory() = core_file.GetDirectory();
3970b57cec5SDimitry Andric target_sp->AppendExecutableSearchPaths(core_file_dir);
3980b57cec5SDimitry Andric
3990b57cec5SDimitry Andric ProcessSP process_sp(target_sp->CreateProcess(
400af732203SDimitry Andric GetDebugger().GetListener(), llvm::StringRef(), &core_file, false));
4010b57cec5SDimitry Andric
4020b57cec5SDimitry Andric if (process_sp) {
4030b57cec5SDimitry Andric // Seems weird that we Launch a core file, but that is what we
4040b57cec5SDimitry Andric // do!
4050b57cec5SDimitry Andric error = process_sp->LoadCore();
4060b57cec5SDimitry Andric
4070b57cec5SDimitry Andric if (error.Fail()) {
4080b57cec5SDimitry Andric result.AppendError(
4090b57cec5SDimitry Andric error.AsCString("can't find plug-in for core file"));
4100b57cec5SDimitry Andric return false;
4110b57cec5SDimitry Andric } else {
412af732203SDimitry Andric result.AppendMessageWithFormatv(
413af732203SDimitry Andric "Core file '{0}' ({1}) was loaded.\n", core_file.GetPath(),
4140b57cec5SDimitry Andric target_sp->GetArchitecture().GetArchitectureName());
4150b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult);
416af732203SDimitry Andric on_error.release();
4170b57cec5SDimitry Andric }
4180b57cec5SDimitry Andric } else {
4195ffd83dbSDimitry Andric result.AppendErrorWithFormatv(
4205ffd83dbSDimitry Andric "Unable to find process plug-in for core file '{0}'\n",
4215ffd83dbSDimitry Andric core_file.GetPath());
4220b57cec5SDimitry Andric }
4230b57cec5SDimitry Andric } else {
4240b57cec5SDimitry Andric result.AppendMessageWithFormat(
4259dba64beSDimitry Andric "Current executable set to '%s' (%s).\n",
4269dba64beSDimitry Andric file_spec.GetPath().c_str(),
4270b57cec5SDimitry Andric target_sp->GetArchitecture().GetArchitectureName());
4280b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult);
429af732203SDimitry Andric on_error.release();
4300b57cec5SDimitry Andric }
4310b57cec5SDimitry Andric } else {
4320b57cec5SDimitry Andric result.AppendErrorWithFormat("'%s' takes exactly one executable path "
4330b57cec5SDimitry Andric "argument, or use the --core option.\n",
4340b57cec5SDimitry Andric m_cmd_name.c_str());
4350b57cec5SDimitry Andric }
436af732203SDimitry Andric
4370b57cec5SDimitry Andric return result.Succeeded();
4380b57cec5SDimitry Andric }
4390b57cec5SDimitry Andric
4400b57cec5SDimitry Andric private:
4410b57cec5SDimitry Andric OptionGroupOptions m_option_group;
4420b57cec5SDimitry Andric OptionGroupArchitecture m_arch_option;
443af732203SDimitry Andric OptionGroupPlatform m_platform_options;
4440b57cec5SDimitry Andric OptionGroupFile m_core_file;
4450b57cec5SDimitry Andric OptionGroupFile m_symbol_file;
4460b57cec5SDimitry Andric OptionGroupFile m_remote_file;
4470b57cec5SDimitry Andric OptionGroupDependents m_add_dependents;
4480b57cec5SDimitry Andric };
4490b57cec5SDimitry Andric
4500b57cec5SDimitry Andric #pragma mark CommandObjectTargetList
4510b57cec5SDimitry Andric
4520b57cec5SDimitry Andric class CommandObjectTargetList : public CommandObjectParsed {
4530b57cec5SDimitry Andric public:
CommandObjectTargetList(CommandInterpreter & interpreter)4540b57cec5SDimitry Andric CommandObjectTargetList(CommandInterpreter &interpreter)
4550b57cec5SDimitry Andric : CommandObjectParsed(
4560b57cec5SDimitry Andric interpreter, "target list",
4570b57cec5SDimitry Andric "List all current targets in the current debug session.", nullptr) {
4580b57cec5SDimitry Andric }
4590b57cec5SDimitry Andric
4600b57cec5SDimitry Andric ~CommandObjectTargetList() override = default;
4610b57cec5SDimitry Andric
4620b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)4630b57cec5SDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
4640b57cec5SDimitry Andric if (args.GetArgumentCount() == 0) {
4650b57cec5SDimitry Andric Stream &strm = result.GetOutputStream();
4660b57cec5SDimitry Andric
4670b57cec5SDimitry Andric bool show_stopped_process_status = false;
4680b57cec5SDimitry Andric if (DumpTargetList(GetDebugger().GetTargetList(),
4690b57cec5SDimitry Andric show_stopped_process_status, strm) == 0) {
4700b57cec5SDimitry Andric strm.PutCString("No targets.\n");
4710b57cec5SDimitry Andric }
4720b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
4730b57cec5SDimitry Andric } else {
4740b57cec5SDimitry Andric result.AppendError("the 'target list' command takes no arguments\n");
4750b57cec5SDimitry Andric }
4760b57cec5SDimitry Andric return result.Succeeded();
4770b57cec5SDimitry Andric }
4780b57cec5SDimitry Andric };
4790b57cec5SDimitry Andric
4800b57cec5SDimitry Andric #pragma mark CommandObjectTargetSelect
4810b57cec5SDimitry Andric
4820b57cec5SDimitry Andric class CommandObjectTargetSelect : public CommandObjectParsed {
4830b57cec5SDimitry Andric public:
CommandObjectTargetSelect(CommandInterpreter & interpreter)4840b57cec5SDimitry Andric CommandObjectTargetSelect(CommandInterpreter &interpreter)
4850b57cec5SDimitry Andric : CommandObjectParsed(
4860b57cec5SDimitry Andric interpreter, "target select",
4870b57cec5SDimitry Andric "Select a target as the current target by target index.", nullptr) {
4880b57cec5SDimitry Andric }
4890b57cec5SDimitry Andric
4900b57cec5SDimitry Andric ~CommandObjectTargetSelect() override = default;
4910b57cec5SDimitry Andric
4920b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)4930b57cec5SDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
4940b57cec5SDimitry Andric if (args.GetArgumentCount() == 1) {
4950b57cec5SDimitry Andric const char *target_idx_arg = args.GetArgumentAtIndex(0);
4965ffd83dbSDimitry Andric uint32_t target_idx;
4975ffd83dbSDimitry Andric if (llvm::to_integer(target_idx_arg, target_idx)) {
4980b57cec5SDimitry Andric TargetList &target_list = GetDebugger().GetTargetList();
4990b57cec5SDimitry Andric const uint32_t num_targets = target_list.GetNumTargets();
5000b57cec5SDimitry Andric if (target_idx < num_targets) {
501af732203SDimitry Andric target_list.SetSelectedTarget(target_idx);
5020b57cec5SDimitry Andric Stream &strm = result.GetOutputStream();
5030b57cec5SDimitry Andric bool show_stopped_process_status = false;
5040b57cec5SDimitry Andric DumpTargetList(target_list, show_stopped_process_status, strm);
5050b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
5060b57cec5SDimitry Andric } else {
5070b57cec5SDimitry Andric if (num_targets > 0) {
5080b57cec5SDimitry Andric result.AppendErrorWithFormat(
5090b57cec5SDimitry Andric "index %u is out of range, valid target indexes are 0 - %u\n",
5100b57cec5SDimitry Andric target_idx, num_targets - 1);
5110b57cec5SDimitry Andric } else {
5120b57cec5SDimitry Andric result.AppendErrorWithFormat(
5130b57cec5SDimitry Andric "index %u is out of range since there are no active targets\n",
5140b57cec5SDimitry Andric target_idx);
5150b57cec5SDimitry Andric }
5160b57cec5SDimitry Andric }
5170b57cec5SDimitry Andric } else {
5180b57cec5SDimitry Andric result.AppendErrorWithFormat("invalid index string value '%s'\n",
5190b57cec5SDimitry Andric target_idx_arg);
5200b57cec5SDimitry Andric }
5210b57cec5SDimitry Andric } else {
5220b57cec5SDimitry Andric result.AppendError(
5230b57cec5SDimitry Andric "'target select' takes a single argument: a target index\n");
5240b57cec5SDimitry Andric }
5250b57cec5SDimitry Andric return result.Succeeded();
5260b57cec5SDimitry Andric }
5270b57cec5SDimitry Andric };
5280b57cec5SDimitry Andric
5295ffd83dbSDimitry Andric #pragma mark CommandObjectTargetDelete
5300b57cec5SDimitry Andric
5310b57cec5SDimitry Andric class CommandObjectTargetDelete : public CommandObjectParsed {
5320b57cec5SDimitry Andric public:
CommandObjectTargetDelete(CommandInterpreter & interpreter)5330b57cec5SDimitry Andric CommandObjectTargetDelete(CommandInterpreter &interpreter)
5340b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "target delete",
5350b57cec5SDimitry Andric "Delete one or more targets by target index.",
5360b57cec5SDimitry Andric nullptr),
5370b57cec5SDimitry Andric m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
5380b57cec5SDimitry Andric "Delete all targets.", false, true),
5390b57cec5SDimitry Andric m_cleanup_option(
5400b57cec5SDimitry Andric LLDB_OPT_SET_1, false, "clean", 'c',
5410b57cec5SDimitry Andric "Perform extra cleanup to minimize memory consumption after "
5420b57cec5SDimitry Andric "deleting the target. "
5430b57cec5SDimitry Andric "By default, LLDB will keep in memory any modules previously "
5440b57cec5SDimitry Andric "loaded by the target as well "
5450b57cec5SDimitry Andric "as all of its debug info. Specifying --clean will unload all of "
5460b57cec5SDimitry Andric "these shared modules and "
5470b57cec5SDimitry Andric "cause them to be reparsed again the next time the target is run",
5480b57cec5SDimitry Andric false, true) {
5490b57cec5SDimitry Andric m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
5500b57cec5SDimitry Andric m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
5510b57cec5SDimitry Andric m_option_group.Finalize();
5520b57cec5SDimitry Andric }
5530b57cec5SDimitry Andric
5540b57cec5SDimitry Andric ~CommandObjectTargetDelete() override = default;
5550b57cec5SDimitry Andric
GetOptions()5560b57cec5SDimitry Andric Options *GetOptions() override { return &m_option_group; }
5570b57cec5SDimitry Andric
5580b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)5590b57cec5SDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
5600b57cec5SDimitry Andric const size_t argc = args.GetArgumentCount();
5610b57cec5SDimitry Andric std::vector<TargetSP> delete_target_list;
5620b57cec5SDimitry Andric TargetList &target_list = GetDebugger().GetTargetList();
5630b57cec5SDimitry Andric TargetSP target_sp;
5640b57cec5SDimitry Andric
5650b57cec5SDimitry Andric if (m_all_option.GetOptionValue()) {
5660b57cec5SDimitry Andric for (int i = 0; i < target_list.GetNumTargets(); ++i)
5670b57cec5SDimitry Andric delete_target_list.push_back(target_list.GetTargetAtIndex(i));
5680b57cec5SDimitry Andric } else if (argc > 0) {
5690b57cec5SDimitry Andric const uint32_t num_targets = target_list.GetNumTargets();
5700b57cec5SDimitry Andric // Bail out if don't have any targets.
5710b57cec5SDimitry Andric if (num_targets == 0) {
5720b57cec5SDimitry Andric result.AppendError("no targets to delete");
5730b57cec5SDimitry Andric return false;
5740b57cec5SDimitry Andric }
5750b57cec5SDimitry Andric
5760b57cec5SDimitry Andric for (auto &entry : args.entries()) {
5770b57cec5SDimitry Andric uint32_t target_idx;
5789dba64beSDimitry Andric if (entry.ref().getAsInteger(0, target_idx)) {
5790b57cec5SDimitry Andric result.AppendErrorWithFormat("invalid target index '%s'\n",
5800b57cec5SDimitry Andric entry.c_str());
5810b57cec5SDimitry Andric return false;
5820b57cec5SDimitry Andric }
5830b57cec5SDimitry Andric if (target_idx < num_targets) {
5840b57cec5SDimitry Andric target_sp = target_list.GetTargetAtIndex(target_idx);
5850b57cec5SDimitry Andric if (target_sp) {
5860b57cec5SDimitry Andric delete_target_list.push_back(target_sp);
5870b57cec5SDimitry Andric continue;
5880b57cec5SDimitry Andric }
5890b57cec5SDimitry Andric }
5900b57cec5SDimitry Andric if (num_targets > 1)
5910b57cec5SDimitry Andric result.AppendErrorWithFormat("target index %u is out of range, valid "
5920b57cec5SDimitry Andric "target indexes are 0 - %u\n",
5930b57cec5SDimitry Andric target_idx, num_targets - 1);
5940b57cec5SDimitry Andric else
5950b57cec5SDimitry Andric result.AppendErrorWithFormat(
5960b57cec5SDimitry Andric "target index %u is out of range, the only valid index is 0\n",
5970b57cec5SDimitry Andric target_idx);
5980b57cec5SDimitry Andric
5990b57cec5SDimitry Andric return false;
6000b57cec5SDimitry Andric }
6010b57cec5SDimitry Andric } else {
6020b57cec5SDimitry Andric target_sp = target_list.GetSelectedTarget();
6030b57cec5SDimitry Andric if (!target_sp) {
6040b57cec5SDimitry Andric result.AppendErrorWithFormat("no target is currently selected\n");
6050b57cec5SDimitry Andric return false;
6060b57cec5SDimitry Andric }
6070b57cec5SDimitry Andric delete_target_list.push_back(target_sp);
6080b57cec5SDimitry Andric }
6090b57cec5SDimitry Andric
6100b57cec5SDimitry Andric const size_t num_targets_to_delete = delete_target_list.size();
6110b57cec5SDimitry Andric for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
6120b57cec5SDimitry Andric target_sp = delete_target_list[idx];
6130b57cec5SDimitry Andric target_list.DeleteTarget(target_sp);
6140b57cec5SDimitry Andric target_sp->Destroy();
6150b57cec5SDimitry Andric }
6160b57cec5SDimitry Andric // If "--clean" was specified, prune any orphaned shared modules from the
6170b57cec5SDimitry Andric // global shared module list
6180b57cec5SDimitry Andric if (m_cleanup_option.GetOptionValue()) {
6190b57cec5SDimitry Andric const bool mandatory = true;
6200b57cec5SDimitry Andric ModuleList::RemoveOrphanSharedModules(mandatory);
6210b57cec5SDimitry Andric }
6220b57cec5SDimitry Andric result.GetOutputStream().Printf("%u targets deleted.\n",
6230b57cec5SDimitry Andric (uint32_t)num_targets_to_delete);
6240b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
6250b57cec5SDimitry Andric
6260b57cec5SDimitry Andric return true;
6270b57cec5SDimitry Andric }
6280b57cec5SDimitry Andric
6290b57cec5SDimitry Andric OptionGroupOptions m_option_group;
6300b57cec5SDimitry Andric OptionGroupBoolean m_all_option;
6310b57cec5SDimitry Andric OptionGroupBoolean m_cleanup_option;
6320b57cec5SDimitry Andric };
6330b57cec5SDimitry Andric
6345ffd83dbSDimitry Andric class CommandObjectTargetShowLaunchEnvironment : public CommandObjectParsed {
6355ffd83dbSDimitry Andric public:
CommandObjectTargetShowLaunchEnvironment(CommandInterpreter & interpreter)6365ffd83dbSDimitry Andric CommandObjectTargetShowLaunchEnvironment(CommandInterpreter &interpreter)
6375ffd83dbSDimitry Andric : CommandObjectParsed(
6385ffd83dbSDimitry Andric interpreter, "target show-launch-environment",
6395ffd83dbSDimitry Andric "Shows the environment being passed to the process when launched, "
6405ffd83dbSDimitry Andric "taking info account 3 settings: target.env-vars, "
6415ffd83dbSDimitry Andric "target.inherit-env and target.unset-env-vars.",
6425ffd83dbSDimitry Andric nullptr, eCommandRequiresTarget) {}
6435ffd83dbSDimitry Andric
6445ffd83dbSDimitry Andric ~CommandObjectTargetShowLaunchEnvironment() override = default;
6455ffd83dbSDimitry Andric
6465ffd83dbSDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)6475ffd83dbSDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
6485ffd83dbSDimitry Andric Target *target = m_exe_ctx.GetTargetPtr();
6495ffd83dbSDimitry Andric Environment env = target->GetEnvironment();
6505ffd83dbSDimitry Andric
6515ffd83dbSDimitry Andric std::vector<Environment::value_type *> env_vector;
6525ffd83dbSDimitry Andric env_vector.reserve(env.size());
6535ffd83dbSDimitry Andric for (auto &KV : env)
6545ffd83dbSDimitry Andric env_vector.push_back(&KV);
6555ffd83dbSDimitry Andric std::sort(env_vector.begin(), env_vector.end(),
6565ffd83dbSDimitry Andric [](Environment::value_type *a, Environment::value_type *b) {
6575ffd83dbSDimitry Andric return a->first() < b->first();
6585ffd83dbSDimitry Andric });
6595ffd83dbSDimitry Andric
6605ffd83dbSDimitry Andric auto &strm = result.GetOutputStream();
6615ffd83dbSDimitry Andric for (auto &KV : env_vector)
6625ffd83dbSDimitry Andric strm.Format("{0}={1}\n", KV->first(), KV->second);
6635ffd83dbSDimitry Andric
6645ffd83dbSDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
6655ffd83dbSDimitry Andric return result.Succeeded();
6665ffd83dbSDimitry Andric }
6675ffd83dbSDimitry Andric };
6685ffd83dbSDimitry Andric
6690b57cec5SDimitry Andric #pragma mark CommandObjectTargetVariable
6700b57cec5SDimitry Andric
6710b57cec5SDimitry Andric class CommandObjectTargetVariable : public CommandObjectParsed {
6720b57cec5SDimitry Andric static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
6730b57cec5SDimitry Andric static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
6740b57cec5SDimitry Andric
6750b57cec5SDimitry Andric public:
CommandObjectTargetVariable(CommandInterpreter & interpreter)6760b57cec5SDimitry Andric CommandObjectTargetVariable(CommandInterpreter &interpreter)
6770b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "target variable",
6780b57cec5SDimitry Andric "Read global variables for the current target, "
6790b57cec5SDimitry Andric "before or while running a process.",
6800b57cec5SDimitry Andric nullptr, eCommandRequiresTarget),
6810b57cec5SDimitry Andric m_option_group(),
6820b57cec5SDimitry Andric m_option_variable(false), // Don't include frame options
6830b57cec5SDimitry Andric m_option_format(eFormatDefault),
6840b57cec5SDimitry Andric m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
6850b57cec5SDimitry Andric 0, eArgTypeFilename,
6860b57cec5SDimitry Andric "A basename or fullpath to a file that contains "
6870b57cec5SDimitry Andric "global variables. This option can be "
6880b57cec5SDimitry Andric "specified multiple times."),
6890b57cec5SDimitry Andric m_option_shared_libraries(
6900b57cec5SDimitry Andric LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
6910b57cec5SDimitry Andric eArgTypeFilename,
6920b57cec5SDimitry Andric "A basename or fullpath to a shared library to use in the search "
6930b57cec5SDimitry Andric "for global "
6940b57cec5SDimitry Andric "variables. This option can be specified multiple times."),
6950b57cec5SDimitry Andric m_varobj_options() {
6960b57cec5SDimitry Andric CommandArgumentEntry arg;
6970b57cec5SDimitry Andric CommandArgumentData var_name_arg;
6980b57cec5SDimitry Andric
6990b57cec5SDimitry Andric // Define the first (and only) variant of this arg.
7000b57cec5SDimitry Andric var_name_arg.arg_type = eArgTypeVarName;
7010b57cec5SDimitry Andric var_name_arg.arg_repetition = eArgRepeatPlus;
7020b57cec5SDimitry Andric
7030b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the
7040b57cec5SDimitry Andric // argument entry.
7050b57cec5SDimitry Andric arg.push_back(var_name_arg);
7060b57cec5SDimitry Andric
7070b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector.
7080b57cec5SDimitry Andric m_arguments.push_back(arg);
7090b57cec5SDimitry Andric
7100b57cec5SDimitry Andric m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
7110b57cec5SDimitry Andric m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
7120b57cec5SDimitry Andric m_option_group.Append(&m_option_format,
7130b57cec5SDimitry Andric OptionGroupFormat::OPTION_GROUP_FORMAT |
7140b57cec5SDimitry Andric OptionGroupFormat::OPTION_GROUP_GDB_FMT,
7150b57cec5SDimitry Andric LLDB_OPT_SET_1);
7160b57cec5SDimitry Andric m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
7170b57cec5SDimitry Andric LLDB_OPT_SET_1);
7180b57cec5SDimitry Andric m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
7190b57cec5SDimitry Andric LLDB_OPT_SET_1);
7200b57cec5SDimitry Andric m_option_group.Finalize();
7210b57cec5SDimitry Andric }
7220b57cec5SDimitry Andric
7230b57cec5SDimitry Andric ~CommandObjectTargetVariable() override = default;
7240b57cec5SDimitry Andric
DumpValueObject(Stream & s,VariableSP & var_sp,ValueObjectSP & valobj_sp,const char * root_name)7250b57cec5SDimitry Andric void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
7260b57cec5SDimitry Andric const char *root_name) {
7270b57cec5SDimitry Andric DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
7280b57cec5SDimitry Andric
7290b57cec5SDimitry Andric if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
7300b57cec5SDimitry Andric valobj_sp->IsRuntimeSupportValue())
7310b57cec5SDimitry Andric return;
7320b57cec5SDimitry Andric
7330b57cec5SDimitry Andric switch (var_sp->GetScope()) {
7340b57cec5SDimitry Andric case eValueTypeVariableGlobal:
7350b57cec5SDimitry Andric if (m_option_variable.show_scope)
7360b57cec5SDimitry Andric s.PutCString("GLOBAL: ");
7370b57cec5SDimitry Andric break;
7380b57cec5SDimitry Andric
7390b57cec5SDimitry Andric case eValueTypeVariableStatic:
7400b57cec5SDimitry Andric if (m_option_variable.show_scope)
7410b57cec5SDimitry Andric s.PutCString("STATIC: ");
7420b57cec5SDimitry Andric break;
7430b57cec5SDimitry Andric
7440b57cec5SDimitry Andric case eValueTypeVariableArgument:
7450b57cec5SDimitry Andric if (m_option_variable.show_scope)
7460b57cec5SDimitry Andric s.PutCString(" ARG: ");
7470b57cec5SDimitry Andric break;
7480b57cec5SDimitry Andric
7490b57cec5SDimitry Andric case eValueTypeVariableLocal:
7500b57cec5SDimitry Andric if (m_option_variable.show_scope)
7510b57cec5SDimitry Andric s.PutCString(" LOCAL: ");
7520b57cec5SDimitry Andric break;
7530b57cec5SDimitry Andric
7540b57cec5SDimitry Andric case eValueTypeVariableThreadLocal:
7550b57cec5SDimitry Andric if (m_option_variable.show_scope)
7560b57cec5SDimitry Andric s.PutCString("THREAD: ");
7570b57cec5SDimitry Andric break;
7580b57cec5SDimitry Andric
7590b57cec5SDimitry Andric default:
7600b57cec5SDimitry Andric break;
7610b57cec5SDimitry Andric }
7620b57cec5SDimitry Andric
7630b57cec5SDimitry Andric if (m_option_variable.show_decl) {
7640b57cec5SDimitry Andric bool show_fullpaths = false;
7650b57cec5SDimitry Andric bool show_module = true;
7660b57cec5SDimitry Andric if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
7670b57cec5SDimitry Andric s.PutCString(": ");
7680b57cec5SDimitry Andric }
7690b57cec5SDimitry Andric
7700b57cec5SDimitry Andric const Format format = m_option_format.GetFormat();
7710b57cec5SDimitry Andric if (format != eFormatDefault)
7720b57cec5SDimitry Andric options.SetFormat(format);
7730b57cec5SDimitry Andric
7740b57cec5SDimitry Andric options.SetRootValueObjectName(root_name);
7750b57cec5SDimitry Andric
7760b57cec5SDimitry Andric valobj_sp->Dump(s, options);
7770b57cec5SDimitry Andric }
7780b57cec5SDimitry Andric
GetVariableCallback(void * baton,const char * name,VariableList & variable_list)7790b57cec5SDimitry Andric static size_t GetVariableCallback(void *baton, const char *name,
7800b57cec5SDimitry Andric VariableList &variable_list) {
7819dba64beSDimitry Andric size_t old_size = variable_list.GetSize();
7820b57cec5SDimitry Andric Target *target = static_cast<Target *>(baton);
7839dba64beSDimitry Andric if (target)
7849dba64beSDimitry Andric target->GetImages().FindGlobalVariables(ConstString(name), UINT32_MAX,
7859dba64beSDimitry Andric variable_list);
7869dba64beSDimitry Andric return variable_list.GetSize() - old_size;
7870b57cec5SDimitry Andric }
7880b57cec5SDimitry Andric
GetOptions()7890b57cec5SDimitry Andric Options *GetOptions() override { return &m_option_group; }
7900b57cec5SDimitry Andric
7910b57cec5SDimitry Andric protected:
DumpGlobalVariableList(const ExecutionContext & exe_ctx,const SymbolContext & sc,const VariableList & variable_list,Stream & s)7920b57cec5SDimitry Andric void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
7930b57cec5SDimitry Andric const SymbolContext &sc,
7940b57cec5SDimitry Andric const VariableList &variable_list, Stream &s) {
795480093f4SDimitry Andric if (variable_list.Empty())
796480093f4SDimitry Andric return;
7970b57cec5SDimitry Andric if (sc.module_sp) {
7980b57cec5SDimitry Andric if (sc.comp_unit) {
799480093f4SDimitry Andric s.Format("Global variables for {0} in {1}:\n",
800480093f4SDimitry Andric sc.comp_unit->GetPrimaryFile(), sc.module_sp->GetFileSpec());
8010b57cec5SDimitry Andric } else {
8020b57cec5SDimitry Andric s.Printf("Global variables for %s\n",
8030b57cec5SDimitry Andric sc.module_sp->GetFileSpec().GetPath().c_str());
8040b57cec5SDimitry Andric }
8050b57cec5SDimitry Andric } else if (sc.comp_unit) {
806480093f4SDimitry Andric s.Format("Global variables for {0}\n", sc.comp_unit->GetPrimaryFile());
8070b57cec5SDimitry Andric }
8080b57cec5SDimitry Andric
809480093f4SDimitry Andric for (VariableSP var_sp : variable_list) {
810480093f4SDimitry Andric if (!var_sp)
811480093f4SDimitry Andric continue;
8120b57cec5SDimitry Andric ValueObjectSP valobj_sp(ValueObjectVariable::Create(
8130b57cec5SDimitry Andric exe_ctx.GetBestExecutionContextScope(), var_sp));
8140b57cec5SDimitry Andric
8150b57cec5SDimitry Andric if (valobj_sp)
816480093f4SDimitry Andric DumpValueObject(s, var_sp, valobj_sp, var_sp->GetName().GetCString());
8170b57cec5SDimitry Andric }
8180b57cec5SDimitry Andric }
8190b57cec5SDimitry Andric
DoExecute(Args & args,CommandReturnObject & result)8200b57cec5SDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
8210b57cec5SDimitry Andric Target *target = m_exe_ctx.GetTargetPtr();
8220b57cec5SDimitry Andric const size_t argc = args.GetArgumentCount();
8230b57cec5SDimitry Andric Stream &s = result.GetOutputStream();
8240b57cec5SDimitry Andric
8250b57cec5SDimitry Andric if (argc > 0) {
8265ffd83dbSDimitry Andric for (const Args::ArgEntry &arg : args) {
8270b57cec5SDimitry Andric VariableList variable_list;
8280b57cec5SDimitry Andric ValueObjectList valobj_list;
8290b57cec5SDimitry Andric
8300b57cec5SDimitry Andric size_t matches = 0;
8310b57cec5SDimitry Andric bool use_var_name = false;
8320b57cec5SDimitry Andric if (m_option_variable.use_regex) {
833*5f7ddb14SDimitry Andric RegularExpression regex(arg.ref());
8340b57cec5SDimitry Andric if (!regex.IsValid()) {
8350b57cec5SDimitry Andric result.GetErrorStream().Printf(
8365ffd83dbSDimitry Andric "error: invalid regular expression: '%s'\n", arg.c_str());
8370b57cec5SDimitry Andric return false;
8380b57cec5SDimitry Andric }
8390b57cec5SDimitry Andric use_var_name = true;
8409dba64beSDimitry Andric target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
8410b57cec5SDimitry Andric variable_list);
8429dba64beSDimitry Andric matches = variable_list.GetSize();
8430b57cec5SDimitry Andric } else {
8440b57cec5SDimitry Andric Status error(Variable::GetValuesForVariableExpressionPath(
8455ffd83dbSDimitry Andric arg.c_str(), m_exe_ctx.GetBestExecutionContextScope(),
8460b57cec5SDimitry Andric GetVariableCallback, target, variable_list, valobj_list));
8470b57cec5SDimitry Andric matches = variable_list.GetSize();
8480b57cec5SDimitry Andric }
8490b57cec5SDimitry Andric
8500b57cec5SDimitry Andric if (matches == 0) {
851*5f7ddb14SDimitry Andric result.AppendErrorWithFormat("can't find global variable '%s'",
852*5f7ddb14SDimitry Andric arg.c_str());
8530b57cec5SDimitry Andric return false;
8540b57cec5SDimitry Andric } else {
8550b57cec5SDimitry Andric for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
8560b57cec5SDimitry Andric VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
8570b57cec5SDimitry Andric if (var_sp) {
8580b57cec5SDimitry Andric ValueObjectSP valobj_sp(
8590b57cec5SDimitry Andric valobj_list.GetValueObjectAtIndex(global_idx));
8600b57cec5SDimitry Andric if (!valobj_sp)
8610b57cec5SDimitry Andric valobj_sp = ValueObjectVariable::Create(
8620b57cec5SDimitry Andric m_exe_ctx.GetBestExecutionContextScope(), var_sp);
8630b57cec5SDimitry Andric
8640b57cec5SDimitry Andric if (valobj_sp)
8650b57cec5SDimitry Andric DumpValueObject(s, var_sp, valobj_sp,
8660b57cec5SDimitry Andric use_var_name ? var_sp->GetName().GetCString()
8675ffd83dbSDimitry Andric : arg.c_str());
8680b57cec5SDimitry Andric }
8690b57cec5SDimitry Andric }
8700b57cec5SDimitry Andric }
8710b57cec5SDimitry Andric }
8720b57cec5SDimitry Andric } else {
8730b57cec5SDimitry Andric const FileSpecList &compile_units =
8740b57cec5SDimitry Andric m_option_compile_units.GetOptionValue().GetCurrentValue();
8750b57cec5SDimitry Andric const FileSpecList &shlibs =
8760b57cec5SDimitry Andric m_option_shared_libraries.GetOptionValue().GetCurrentValue();
8770b57cec5SDimitry Andric SymbolContextList sc_list;
8780b57cec5SDimitry Andric const size_t num_compile_units = compile_units.GetSize();
8790b57cec5SDimitry Andric const size_t num_shlibs = shlibs.GetSize();
8800b57cec5SDimitry Andric if (num_compile_units == 0 && num_shlibs == 0) {
8810b57cec5SDimitry Andric bool success = false;
8820b57cec5SDimitry Andric StackFrame *frame = m_exe_ctx.GetFramePtr();
8830b57cec5SDimitry Andric CompileUnit *comp_unit = nullptr;
8840b57cec5SDimitry Andric if (frame) {
8850b57cec5SDimitry Andric SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
886af732203SDimitry Andric comp_unit = sc.comp_unit;
8870b57cec5SDimitry Andric if (sc.comp_unit) {
8880b57cec5SDimitry Andric const bool can_create = true;
8890b57cec5SDimitry Andric VariableListSP comp_unit_varlist_sp(
8900b57cec5SDimitry Andric sc.comp_unit->GetVariableList(can_create));
8910b57cec5SDimitry Andric if (comp_unit_varlist_sp) {
8920b57cec5SDimitry Andric size_t count = comp_unit_varlist_sp->GetSize();
8930b57cec5SDimitry Andric if (count > 0) {
8940b57cec5SDimitry Andric DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
8950b57cec5SDimitry Andric success = true;
8960b57cec5SDimitry Andric }
8970b57cec5SDimitry Andric }
8980b57cec5SDimitry Andric }
8990b57cec5SDimitry Andric }
9000b57cec5SDimitry Andric if (!success) {
9010b57cec5SDimitry Andric if (frame) {
9020b57cec5SDimitry Andric if (comp_unit)
903480093f4SDimitry Andric result.AppendErrorWithFormatv(
904480093f4SDimitry Andric "no global variables in current compile unit: {0}\n",
905480093f4SDimitry Andric comp_unit->GetPrimaryFile());
9060b57cec5SDimitry Andric else
9070b57cec5SDimitry Andric result.AppendErrorWithFormat(
9080b57cec5SDimitry Andric "no debug information for frame %u\n",
9090b57cec5SDimitry Andric frame->GetFrameIndex());
9100b57cec5SDimitry Andric } else
9110b57cec5SDimitry Andric result.AppendError("'target variable' takes one or more global "
9120b57cec5SDimitry Andric "variable names as arguments\n");
9130b57cec5SDimitry Andric }
9140b57cec5SDimitry Andric } else {
9150b57cec5SDimitry Andric SymbolContextList sc_list;
9160b57cec5SDimitry Andric // We have one or more compile unit or shlib
9170b57cec5SDimitry Andric if (num_shlibs > 0) {
9180b57cec5SDimitry Andric for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
9190b57cec5SDimitry Andric const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
9200b57cec5SDimitry Andric ModuleSpec module_spec(module_file);
9210b57cec5SDimitry Andric
9220b57cec5SDimitry Andric ModuleSP module_sp(
9230b57cec5SDimitry Andric target->GetImages().FindFirstModule(module_spec));
9240b57cec5SDimitry Andric if (module_sp) {
9250b57cec5SDimitry Andric if (num_compile_units > 0) {
9260b57cec5SDimitry Andric for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
9270b57cec5SDimitry Andric module_sp->FindCompileUnits(
9289dba64beSDimitry Andric compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
9290b57cec5SDimitry Andric } else {
9300b57cec5SDimitry Andric SymbolContext sc;
9310b57cec5SDimitry Andric sc.module_sp = module_sp;
9320b57cec5SDimitry Andric sc_list.Append(sc);
9330b57cec5SDimitry Andric }
9340b57cec5SDimitry Andric } else {
9350b57cec5SDimitry Andric // Didn't find matching shlib/module in target...
9360b57cec5SDimitry Andric result.AppendErrorWithFormat(
9370b57cec5SDimitry Andric "target doesn't contain the specified shared library: %s\n",
9380b57cec5SDimitry Andric module_file.GetPath().c_str());
9390b57cec5SDimitry Andric }
9400b57cec5SDimitry Andric }
9410b57cec5SDimitry Andric } else {
9420b57cec5SDimitry Andric // No shared libraries, we just want to find globals for the compile
9430b57cec5SDimitry Andric // units files that were specified
9440b57cec5SDimitry Andric for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
9450b57cec5SDimitry Andric target->GetImages().FindCompileUnits(
9469dba64beSDimitry Andric compile_units.GetFileSpecAtIndex(cu_idx), sc_list);
9470b57cec5SDimitry Andric }
9480b57cec5SDimitry Andric
9490b57cec5SDimitry Andric const uint32_t num_scs = sc_list.GetSize();
9500b57cec5SDimitry Andric if (num_scs > 0) {
9510b57cec5SDimitry Andric SymbolContext sc;
9520b57cec5SDimitry Andric for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
9530b57cec5SDimitry Andric if (sc_list.GetContextAtIndex(sc_idx, sc)) {
9540b57cec5SDimitry Andric if (sc.comp_unit) {
9550b57cec5SDimitry Andric const bool can_create = true;
9560b57cec5SDimitry Andric VariableListSP comp_unit_varlist_sp(
9570b57cec5SDimitry Andric sc.comp_unit->GetVariableList(can_create));
9580b57cec5SDimitry Andric if (comp_unit_varlist_sp)
9590b57cec5SDimitry Andric DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
9600b57cec5SDimitry Andric s);
9610b57cec5SDimitry Andric } else if (sc.module_sp) {
9620b57cec5SDimitry Andric // Get all global variables for this module
9630b57cec5SDimitry Andric lldb_private::RegularExpression all_globals_regex(
9640b57cec5SDimitry Andric llvm::StringRef(
9650b57cec5SDimitry Andric ".")); // Any global with at least one character
9660b57cec5SDimitry Andric VariableList variable_list;
9670b57cec5SDimitry Andric sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
9680b57cec5SDimitry Andric variable_list);
9690b57cec5SDimitry Andric DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
9700b57cec5SDimitry Andric }
9710b57cec5SDimitry Andric }
9720b57cec5SDimitry Andric }
9730b57cec5SDimitry Andric }
9740b57cec5SDimitry Andric }
9750b57cec5SDimitry Andric }
9760b57cec5SDimitry Andric
9770b57cec5SDimitry Andric if (m_interpreter.TruncationWarningNecessary()) {
9780b57cec5SDimitry Andric result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
9790b57cec5SDimitry Andric m_cmd_name.c_str());
9800b57cec5SDimitry Andric m_interpreter.TruncationWarningGiven();
9810b57cec5SDimitry Andric }
9820b57cec5SDimitry Andric
9830b57cec5SDimitry Andric return result.Succeeded();
9840b57cec5SDimitry Andric }
9850b57cec5SDimitry Andric
9860b57cec5SDimitry Andric OptionGroupOptions m_option_group;
9870b57cec5SDimitry Andric OptionGroupVariable m_option_variable;
9880b57cec5SDimitry Andric OptionGroupFormat m_option_format;
9890b57cec5SDimitry Andric OptionGroupFileList m_option_compile_units;
9900b57cec5SDimitry Andric OptionGroupFileList m_option_shared_libraries;
9910b57cec5SDimitry Andric OptionGroupValueObjectDisplay m_varobj_options;
9920b57cec5SDimitry Andric };
9930b57cec5SDimitry Andric
9940b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsAdd
9950b57cec5SDimitry Andric
9960b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
9970b57cec5SDimitry Andric public:
CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter & interpreter)9980b57cec5SDimitry Andric CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
9990b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "target modules search-paths add",
10000b57cec5SDimitry Andric "Add new image search paths substitution pairs to "
10010b57cec5SDimitry Andric "the current target.",
10029dba64beSDimitry Andric nullptr, eCommandRequiresTarget) {
10030b57cec5SDimitry Andric CommandArgumentEntry arg;
10040b57cec5SDimitry Andric CommandArgumentData old_prefix_arg;
10050b57cec5SDimitry Andric CommandArgumentData new_prefix_arg;
10060b57cec5SDimitry Andric
10070b57cec5SDimitry Andric // Define the first variant of this arg pair.
10080b57cec5SDimitry Andric old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
10090b57cec5SDimitry Andric old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
10100b57cec5SDimitry Andric
10110b57cec5SDimitry Andric // Define the first variant of this arg pair.
10120b57cec5SDimitry Andric new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
10130b57cec5SDimitry Andric new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
10140b57cec5SDimitry Andric
10150b57cec5SDimitry Andric // There are two required arguments that must always occur together, i.e.
10160b57cec5SDimitry Andric // an argument "pair". Because they must always occur together, they are
10170b57cec5SDimitry Andric // treated as two variants of one argument rather than two independent
10180b57cec5SDimitry Andric // arguments. Push them both into the first argument position for
10190b57cec5SDimitry Andric // m_arguments...
10200b57cec5SDimitry Andric
10210b57cec5SDimitry Andric arg.push_back(old_prefix_arg);
10220b57cec5SDimitry Andric arg.push_back(new_prefix_arg);
10230b57cec5SDimitry Andric
10240b57cec5SDimitry Andric m_arguments.push_back(arg);
10250b57cec5SDimitry Andric }
10260b57cec5SDimitry Andric
10270b57cec5SDimitry Andric ~CommandObjectTargetModulesSearchPathsAdd() override = default;
10280b57cec5SDimitry Andric
10290b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)10300b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
10319dba64beSDimitry Andric Target *target = &GetSelectedTarget();
10320b57cec5SDimitry Andric const size_t argc = command.GetArgumentCount();
10330b57cec5SDimitry Andric if (argc & 1) {
10340b57cec5SDimitry Andric result.AppendError("add requires an even number of arguments\n");
10350b57cec5SDimitry Andric } else {
10360b57cec5SDimitry Andric for (size_t i = 0; i < argc; i += 2) {
10370b57cec5SDimitry Andric const char *from = command.GetArgumentAtIndex(i);
10380b57cec5SDimitry Andric const char *to = command.GetArgumentAtIndex(i + 1);
10390b57cec5SDimitry Andric
10400b57cec5SDimitry Andric if (from[0] && to[0]) {
10410b57cec5SDimitry Andric Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
10420b57cec5SDimitry Andric if (log) {
10439dba64beSDimitry Andric LLDB_LOGF(log,
10449dba64beSDimitry Andric "target modules search path adding ImageSearchPath "
10450b57cec5SDimitry Andric "pair: '%s' -> '%s'",
10460b57cec5SDimitry Andric from, to);
10470b57cec5SDimitry Andric }
10480b57cec5SDimitry Andric bool last_pair = ((argc - i) == 2);
10490b57cec5SDimitry Andric target->GetImageSearchPathList().Append(
10500b57cec5SDimitry Andric ConstString(from), ConstString(to),
10510b57cec5SDimitry Andric last_pair); // Notify if this is the last pair
10520b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult);
10530b57cec5SDimitry Andric } else {
10540b57cec5SDimitry Andric if (from[0])
10550b57cec5SDimitry Andric result.AppendError("<path-prefix> can't be empty\n");
10560b57cec5SDimitry Andric else
10570b57cec5SDimitry Andric result.AppendError("<new-path-prefix> can't be empty\n");
10580b57cec5SDimitry Andric }
10590b57cec5SDimitry Andric }
10600b57cec5SDimitry Andric }
10610b57cec5SDimitry Andric return result.Succeeded();
10620b57cec5SDimitry Andric }
10630b57cec5SDimitry Andric };
10640b57cec5SDimitry Andric
10650b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsClear
10660b57cec5SDimitry Andric
10670b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
10680b57cec5SDimitry Andric public:
CommandObjectTargetModulesSearchPathsClear(CommandInterpreter & interpreter)10690b57cec5SDimitry Andric CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
10700b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "target modules search-paths clear",
10710b57cec5SDimitry Andric "Clear all current image search path substitution "
10720b57cec5SDimitry Andric "pairs from the current target.",
10739dba64beSDimitry Andric "target modules search-paths clear",
10749dba64beSDimitry Andric eCommandRequiresTarget) {}
10750b57cec5SDimitry Andric
10760b57cec5SDimitry Andric ~CommandObjectTargetModulesSearchPathsClear() override = default;
10770b57cec5SDimitry Andric
10780b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)10790b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
10809dba64beSDimitry Andric Target *target = &GetSelectedTarget();
10810b57cec5SDimitry Andric bool notify = true;
10820b57cec5SDimitry Andric target->GetImageSearchPathList().Clear(notify);
10830b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult);
10840b57cec5SDimitry Andric return result.Succeeded();
10850b57cec5SDimitry Andric }
10860b57cec5SDimitry Andric };
10870b57cec5SDimitry Andric
10880b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsInsert
10890b57cec5SDimitry Andric
10900b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
10910b57cec5SDimitry Andric public:
CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter & interpreter)10920b57cec5SDimitry Andric CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
10930b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "target modules search-paths insert",
10940b57cec5SDimitry Andric "Insert a new image search path substitution pair "
10950b57cec5SDimitry Andric "into the current target at the specified index.",
10969dba64beSDimitry Andric nullptr, eCommandRequiresTarget) {
10970b57cec5SDimitry Andric CommandArgumentEntry arg1;
10980b57cec5SDimitry Andric CommandArgumentEntry arg2;
10990b57cec5SDimitry Andric CommandArgumentData index_arg;
11000b57cec5SDimitry Andric CommandArgumentData old_prefix_arg;
11010b57cec5SDimitry Andric CommandArgumentData new_prefix_arg;
11020b57cec5SDimitry Andric
11030b57cec5SDimitry Andric // Define the first and only variant of this arg.
11040b57cec5SDimitry Andric index_arg.arg_type = eArgTypeIndex;
11050b57cec5SDimitry Andric index_arg.arg_repetition = eArgRepeatPlain;
11060b57cec5SDimitry Andric
11070b57cec5SDimitry Andric // Put the one and only variant into the first arg for m_arguments:
11080b57cec5SDimitry Andric arg1.push_back(index_arg);
11090b57cec5SDimitry Andric
11100b57cec5SDimitry Andric // Define the first variant of this arg pair.
11110b57cec5SDimitry Andric old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
11120b57cec5SDimitry Andric old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
11130b57cec5SDimitry Andric
11140b57cec5SDimitry Andric // Define the first variant of this arg pair.
11150b57cec5SDimitry Andric new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
11160b57cec5SDimitry Andric new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
11170b57cec5SDimitry Andric
11180b57cec5SDimitry Andric // There are two required arguments that must always occur together, i.e.
11190b57cec5SDimitry Andric // an argument "pair". Because they must always occur together, they are
11200b57cec5SDimitry Andric // treated as two variants of one argument rather than two independent
11210b57cec5SDimitry Andric // arguments. Push them both into the same argument position for
11220b57cec5SDimitry Andric // m_arguments...
11230b57cec5SDimitry Andric
11240b57cec5SDimitry Andric arg2.push_back(old_prefix_arg);
11250b57cec5SDimitry Andric arg2.push_back(new_prefix_arg);
11260b57cec5SDimitry Andric
11270b57cec5SDimitry Andric // Add arguments to m_arguments.
11280b57cec5SDimitry Andric m_arguments.push_back(arg1);
11290b57cec5SDimitry Andric m_arguments.push_back(arg2);
11300b57cec5SDimitry Andric }
11310b57cec5SDimitry Andric
11320b57cec5SDimitry Andric ~CommandObjectTargetModulesSearchPathsInsert() override = default;
11330b57cec5SDimitry Andric
1134af732203SDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)1135af732203SDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
1136af732203SDimitry Andric OptionElementVector &opt_element_vector) override {
1137af732203SDimitry Andric if (!m_exe_ctx.HasTargetScope() || request.GetCursorIndex() != 0)
1138af732203SDimitry Andric return;
1139af732203SDimitry Andric
1140af732203SDimitry Andric Target *target = m_exe_ctx.GetTargetPtr();
1141af732203SDimitry Andric const PathMappingList &list = target->GetImageSearchPathList();
1142af732203SDimitry Andric const size_t num = list.GetSize();
1143af732203SDimitry Andric ConstString old_path, new_path;
1144af732203SDimitry Andric for (size_t i = 0; i < num; ++i) {
1145af732203SDimitry Andric if (!list.GetPathsAtIndex(i, old_path, new_path))
1146af732203SDimitry Andric break;
1147af732203SDimitry Andric StreamString strm;
1148af732203SDimitry Andric strm << old_path << " -> " << new_path;
1149af732203SDimitry Andric request.TryCompleteCurrentArg(std::to_string(i), strm.GetString());
1150af732203SDimitry Andric }
1151af732203SDimitry Andric }
1152af732203SDimitry Andric
11530b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)11540b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
11559dba64beSDimitry Andric Target *target = &GetSelectedTarget();
11560b57cec5SDimitry Andric size_t argc = command.GetArgumentCount();
11570b57cec5SDimitry Andric // check for at least 3 arguments and an odd number of parameters
11580b57cec5SDimitry Andric if (argc >= 3 && argc & 1) {
11595ffd83dbSDimitry Andric uint32_t insert_idx;
11600b57cec5SDimitry Andric
11615ffd83dbSDimitry Andric if (!llvm::to_integer(command.GetArgumentAtIndex(0), insert_idx)) {
11620b57cec5SDimitry Andric result.AppendErrorWithFormat(
11630b57cec5SDimitry Andric "<index> parameter is not an integer: '%s'.\n",
11640b57cec5SDimitry Andric command.GetArgumentAtIndex(0));
11650b57cec5SDimitry Andric return result.Succeeded();
11660b57cec5SDimitry Andric }
11670b57cec5SDimitry Andric
11680b57cec5SDimitry Andric // shift off the index
11690b57cec5SDimitry Andric command.Shift();
11700b57cec5SDimitry Andric argc = command.GetArgumentCount();
11710b57cec5SDimitry Andric
11720b57cec5SDimitry Andric for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
11730b57cec5SDimitry Andric const char *from = command.GetArgumentAtIndex(i);
11740b57cec5SDimitry Andric const char *to = command.GetArgumentAtIndex(i + 1);
11750b57cec5SDimitry Andric
11760b57cec5SDimitry Andric if (from[0] && to[0]) {
11770b57cec5SDimitry Andric bool last_pair = ((argc - i) == 2);
11780b57cec5SDimitry Andric target->GetImageSearchPathList().Insert(
11790b57cec5SDimitry Andric ConstString(from), ConstString(to), insert_idx, last_pair);
11800b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult);
11810b57cec5SDimitry Andric } else {
11820b57cec5SDimitry Andric if (from[0])
11830b57cec5SDimitry Andric result.AppendError("<path-prefix> can't be empty\n");
11840b57cec5SDimitry Andric else
11850b57cec5SDimitry Andric result.AppendError("<new-path-prefix> can't be empty\n");
11860b57cec5SDimitry Andric return false;
11870b57cec5SDimitry Andric }
11880b57cec5SDimitry Andric }
11890b57cec5SDimitry Andric } else {
11900b57cec5SDimitry Andric result.AppendError("insert requires at least three arguments\n");
11910b57cec5SDimitry Andric return result.Succeeded();
11920b57cec5SDimitry Andric }
11930b57cec5SDimitry Andric return result.Succeeded();
11940b57cec5SDimitry Andric }
11950b57cec5SDimitry Andric };
11960b57cec5SDimitry Andric
11970b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsList
11980b57cec5SDimitry Andric
11990b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
12000b57cec5SDimitry Andric public:
CommandObjectTargetModulesSearchPathsList(CommandInterpreter & interpreter)12010b57cec5SDimitry Andric CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
12020b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "target modules search-paths list",
12030b57cec5SDimitry Andric "List all current image search path substitution "
12040b57cec5SDimitry Andric "pairs in the current target.",
12059dba64beSDimitry Andric "target modules search-paths list",
12069dba64beSDimitry Andric eCommandRequiresTarget) {}
12070b57cec5SDimitry Andric
12080b57cec5SDimitry Andric ~CommandObjectTargetModulesSearchPathsList() override = default;
12090b57cec5SDimitry Andric
12100b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)12110b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
12129dba64beSDimitry Andric Target *target = &GetSelectedTarget();
12130b57cec5SDimitry Andric if (command.GetArgumentCount() != 0) {
12140b57cec5SDimitry Andric result.AppendError("list takes no arguments\n");
12150b57cec5SDimitry Andric return result.Succeeded();
12160b57cec5SDimitry Andric }
12170b57cec5SDimitry Andric
12180b57cec5SDimitry Andric target->GetImageSearchPathList().Dump(&result.GetOutputStream());
12190b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
12200b57cec5SDimitry Andric return result.Succeeded();
12210b57cec5SDimitry Andric }
12220b57cec5SDimitry Andric };
12230b57cec5SDimitry Andric
12240b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSearchPathsQuery
12250b57cec5SDimitry Andric
12260b57cec5SDimitry Andric class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
12270b57cec5SDimitry Andric public:
CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter & interpreter)12280b57cec5SDimitry Andric CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
12290b57cec5SDimitry Andric : CommandObjectParsed(
12300b57cec5SDimitry Andric interpreter, "target modules search-paths query",
12310b57cec5SDimitry Andric "Transform a path using the first applicable image search path.",
12329dba64beSDimitry Andric nullptr, eCommandRequiresTarget) {
12330b57cec5SDimitry Andric CommandArgumentEntry arg;
12340b57cec5SDimitry Andric CommandArgumentData path_arg;
12350b57cec5SDimitry Andric
12360b57cec5SDimitry Andric // Define the first (and only) variant of this arg.
12370b57cec5SDimitry Andric path_arg.arg_type = eArgTypeDirectoryName;
12380b57cec5SDimitry Andric path_arg.arg_repetition = eArgRepeatPlain;
12390b57cec5SDimitry Andric
12400b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the
12410b57cec5SDimitry Andric // argument entry.
12420b57cec5SDimitry Andric arg.push_back(path_arg);
12430b57cec5SDimitry Andric
12440b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector.
12450b57cec5SDimitry Andric m_arguments.push_back(arg);
12460b57cec5SDimitry Andric }
12470b57cec5SDimitry Andric
12480b57cec5SDimitry Andric ~CommandObjectTargetModulesSearchPathsQuery() override = default;
12490b57cec5SDimitry Andric
12500b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)12510b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
12529dba64beSDimitry Andric Target *target = &GetSelectedTarget();
12530b57cec5SDimitry Andric if (command.GetArgumentCount() != 1) {
12540b57cec5SDimitry Andric result.AppendError("query requires one argument\n");
12550b57cec5SDimitry Andric return result.Succeeded();
12560b57cec5SDimitry Andric }
12570b57cec5SDimitry Andric
12580b57cec5SDimitry Andric ConstString orig(command.GetArgumentAtIndex(0));
12590b57cec5SDimitry Andric ConstString transformed;
12600b57cec5SDimitry Andric if (target->GetImageSearchPathList().RemapPath(orig, transformed))
12610b57cec5SDimitry Andric result.GetOutputStream().Printf("%s\n", transformed.GetCString());
12620b57cec5SDimitry Andric else
12630b57cec5SDimitry Andric result.GetOutputStream().Printf("%s\n", orig.GetCString());
12640b57cec5SDimitry Andric
12650b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
12660b57cec5SDimitry Andric return result.Succeeded();
12670b57cec5SDimitry Andric }
12680b57cec5SDimitry Andric };
12690b57cec5SDimitry Andric
12700b57cec5SDimitry Andric // Static Helper functions
DumpModuleArchitecture(Stream & strm,Module * module,bool full_triple,uint32_t width)12710b57cec5SDimitry Andric static void DumpModuleArchitecture(Stream &strm, Module *module,
12720b57cec5SDimitry Andric bool full_triple, uint32_t width) {
12730b57cec5SDimitry Andric if (module) {
12740b57cec5SDimitry Andric StreamString arch_strm;
12750b57cec5SDimitry Andric
12760b57cec5SDimitry Andric if (full_triple)
1277480093f4SDimitry Andric module->GetArchitecture().DumpTriple(arch_strm.AsRawOstream());
12780b57cec5SDimitry Andric else
12790b57cec5SDimitry Andric arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
12805ffd83dbSDimitry Andric std::string arch_str = std::string(arch_strm.GetString());
12810b57cec5SDimitry Andric
12820b57cec5SDimitry Andric if (width)
12830b57cec5SDimitry Andric strm.Printf("%-*s", width, arch_str.c_str());
12840b57cec5SDimitry Andric else
12850b57cec5SDimitry Andric strm.PutCString(arch_str);
12860b57cec5SDimitry Andric }
12870b57cec5SDimitry Andric }
12880b57cec5SDimitry Andric
DumpModuleUUID(Stream & strm,Module * module)12890b57cec5SDimitry Andric static void DumpModuleUUID(Stream &strm, Module *module) {
12900b57cec5SDimitry Andric if (module && module->GetUUID().IsValid())
12910b57cec5SDimitry Andric module->GetUUID().Dump(&strm);
12920b57cec5SDimitry Andric else
12930b57cec5SDimitry Andric strm.PutCString(" ");
12940b57cec5SDimitry Andric }
12950b57cec5SDimitry Andric
DumpCompileUnitLineTable(CommandInterpreter & interpreter,Stream & strm,Module * module,const FileSpec & file_spec,lldb::DescriptionLevel desc_level)12960b57cec5SDimitry Andric static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
12970b57cec5SDimitry Andric Stream &strm, Module *module,
12980b57cec5SDimitry Andric const FileSpec &file_spec,
12990b57cec5SDimitry Andric lldb::DescriptionLevel desc_level) {
13000b57cec5SDimitry Andric uint32_t num_matches = 0;
13010b57cec5SDimitry Andric if (module) {
13020b57cec5SDimitry Andric SymbolContextList sc_list;
13030b57cec5SDimitry Andric num_matches = module->ResolveSymbolContextsForFileSpec(
13040b57cec5SDimitry Andric file_spec, 0, false, eSymbolContextCompUnit, sc_list);
13050b57cec5SDimitry Andric
13060b57cec5SDimitry Andric for (uint32_t i = 0; i < num_matches; ++i) {
13070b57cec5SDimitry Andric SymbolContext sc;
13080b57cec5SDimitry Andric if (sc_list.GetContextAtIndex(i, sc)) {
13090b57cec5SDimitry Andric if (i > 0)
13100b57cec5SDimitry Andric strm << "\n\n";
13110b57cec5SDimitry Andric
1312480093f4SDimitry Andric strm << "Line table for " << sc.comp_unit->GetPrimaryFile() << " in `"
1313480093f4SDimitry Andric << module->GetFileSpec().GetFilename() << "\n";
13140b57cec5SDimitry Andric LineTable *line_table = sc.comp_unit->GetLineTable();
13150b57cec5SDimitry Andric if (line_table)
13160b57cec5SDimitry Andric line_table->GetDescription(
13170b57cec5SDimitry Andric &strm, interpreter.GetExecutionContext().GetTargetPtr(),
13180b57cec5SDimitry Andric desc_level);
13190b57cec5SDimitry Andric else
13200b57cec5SDimitry Andric strm << "No line table";
13210b57cec5SDimitry Andric }
13220b57cec5SDimitry Andric }
13230b57cec5SDimitry Andric }
13240b57cec5SDimitry Andric return num_matches;
13250b57cec5SDimitry Andric }
13260b57cec5SDimitry Andric
DumpFullpath(Stream & strm,const FileSpec * file_spec_ptr,uint32_t width)13270b57cec5SDimitry Andric static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
13280b57cec5SDimitry Andric uint32_t width) {
13290b57cec5SDimitry Andric if (file_spec_ptr) {
13300b57cec5SDimitry Andric if (width > 0) {
13310b57cec5SDimitry Andric std::string fullpath = file_spec_ptr->GetPath();
13320b57cec5SDimitry Andric strm.Printf("%-*s", width, fullpath.c_str());
13330b57cec5SDimitry Andric return;
13340b57cec5SDimitry Andric } else {
1335480093f4SDimitry Andric file_spec_ptr->Dump(strm.AsRawOstream());
13360b57cec5SDimitry Andric return;
13370b57cec5SDimitry Andric }
13380b57cec5SDimitry Andric }
13390b57cec5SDimitry Andric // Keep the width spacing correct if things go wrong...
13400b57cec5SDimitry Andric if (width > 0)
13410b57cec5SDimitry Andric strm.Printf("%-*s", width, "");
13420b57cec5SDimitry Andric }
13430b57cec5SDimitry Andric
DumpDirectory(Stream & strm,const FileSpec * file_spec_ptr,uint32_t width)13440b57cec5SDimitry Andric static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
13450b57cec5SDimitry Andric uint32_t width) {
13460b57cec5SDimitry Andric if (file_spec_ptr) {
13470b57cec5SDimitry Andric if (width > 0)
13480b57cec5SDimitry Andric strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
13490b57cec5SDimitry Andric else
13500b57cec5SDimitry Andric file_spec_ptr->GetDirectory().Dump(&strm);
13510b57cec5SDimitry Andric return;
13520b57cec5SDimitry Andric }
13530b57cec5SDimitry Andric // Keep the width spacing correct if things go wrong...
13540b57cec5SDimitry Andric if (width > 0)
13550b57cec5SDimitry Andric strm.Printf("%-*s", width, "");
13560b57cec5SDimitry Andric }
13570b57cec5SDimitry Andric
DumpBasename(Stream & strm,const FileSpec * file_spec_ptr,uint32_t width)13580b57cec5SDimitry Andric static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
13590b57cec5SDimitry Andric uint32_t width) {
13600b57cec5SDimitry Andric if (file_spec_ptr) {
13610b57cec5SDimitry Andric if (width > 0)
13620b57cec5SDimitry Andric strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
13630b57cec5SDimitry Andric else
13640b57cec5SDimitry Andric file_spec_ptr->GetFilename().Dump(&strm);
13650b57cec5SDimitry Andric return;
13660b57cec5SDimitry Andric }
13670b57cec5SDimitry Andric // Keep the width spacing correct if things go wrong...
13680b57cec5SDimitry Andric if (width > 0)
13690b57cec5SDimitry Andric strm.Printf("%-*s", width, "");
13700b57cec5SDimitry Andric }
13710b57cec5SDimitry Andric
DumpModuleObjfileHeaders(Stream & strm,ModuleList & module_list)13720b57cec5SDimitry Andric static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
13730b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
13740b57cec5SDimitry Andric const size_t num_modules = module_list.GetSize();
1375af732203SDimitry Andric if (num_modules == 0)
1376af732203SDimitry Andric return 0;
1377af732203SDimitry Andric
1378af732203SDimitry Andric size_t num_dumped = 0;
1379af732203SDimitry Andric strm.Format("Dumping headers for {0} module(s).\n", num_modules);
13800b57cec5SDimitry Andric strm.IndentMore();
1381af732203SDimitry Andric for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
1382af732203SDimitry Andric if (module_sp) {
13830b57cec5SDimitry Andric if (num_dumped++ > 0) {
13840b57cec5SDimitry Andric strm.EOL();
13850b57cec5SDimitry Andric strm.EOL();
13860b57cec5SDimitry Andric }
1387af732203SDimitry Andric ObjectFile *objfile = module_sp->GetObjectFile();
13880b57cec5SDimitry Andric if (objfile)
13890b57cec5SDimitry Andric objfile->Dump(&strm);
13900b57cec5SDimitry Andric else {
13910b57cec5SDimitry Andric strm.Format("No object file for module: {0:F}\n",
1392af732203SDimitry Andric module_sp->GetFileSpec());
13930b57cec5SDimitry Andric }
13940b57cec5SDimitry Andric }
13950b57cec5SDimitry Andric }
13960b57cec5SDimitry Andric strm.IndentLess();
13970b57cec5SDimitry Andric return num_dumped;
13980b57cec5SDimitry Andric }
13990b57cec5SDimitry Andric
DumpModuleSymtab(CommandInterpreter & interpreter,Stream & strm,Module * module,SortOrder sort_order,Mangled::NamePreference name_preference)14000b57cec5SDimitry Andric static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1401480093f4SDimitry Andric Module *module, SortOrder sort_order,
1402480093f4SDimitry Andric Mangled::NamePreference name_preference) {
14039dba64beSDimitry Andric if (!module)
14049dba64beSDimitry Andric return;
14059dba64beSDimitry Andric if (Symtab *symtab = module->GetSymtab())
14060b57cec5SDimitry Andric symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1407480093f4SDimitry Andric sort_order, name_preference);
14080b57cec5SDimitry Andric }
14090b57cec5SDimitry Andric
DumpModuleSections(CommandInterpreter & interpreter,Stream & strm,Module * module)14100b57cec5SDimitry Andric static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
14110b57cec5SDimitry Andric Module *module) {
14120b57cec5SDimitry Andric if (module) {
14130b57cec5SDimitry Andric SectionList *section_list = module->GetSectionList();
14140b57cec5SDimitry Andric if (section_list) {
14150b57cec5SDimitry Andric strm.Printf("Sections for '%s' (%s):\n",
14160b57cec5SDimitry Andric module->GetSpecificationDescription().c_str(),
14170b57cec5SDimitry Andric module->GetArchitecture().GetArchitectureName());
14185ffd83dbSDimitry Andric section_list->Dump(strm.AsRawOstream(), strm.GetIndentLevel() + 2,
14190b57cec5SDimitry Andric interpreter.GetExecutionContext().GetTargetPtr(), true,
14200b57cec5SDimitry Andric UINT32_MAX);
14210b57cec5SDimitry Andric }
14220b57cec5SDimitry Andric }
14230b57cec5SDimitry Andric }
14240b57cec5SDimitry Andric
DumpModuleSymbolFile(Stream & strm,Module * module)14259dba64beSDimitry Andric static bool DumpModuleSymbolFile(Stream &strm, Module *module) {
14260b57cec5SDimitry Andric if (module) {
14279dba64beSDimitry Andric if (SymbolFile *symbol_file = module->GetSymbolFile(true)) {
14289dba64beSDimitry Andric symbol_file->Dump(strm);
14290b57cec5SDimitry Andric return true;
14300b57cec5SDimitry Andric }
14310b57cec5SDimitry Andric }
14320b57cec5SDimitry Andric return false;
14330b57cec5SDimitry Andric }
14340b57cec5SDimitry Andric
DumpAddress(ExecutionContextScope * exe_scope,const Address & so_addr,bool verbose,Stream & strm)14350b57cec5SDimitry Andric static void DumpAddress(ExecutionContextScope *exe_scope,
14360b57cec5SDimitry Andric const Address &so_addr, bool verbose, Stream &strm) {
14370b57cec5SDimitry Andric strm.IndentMore();
14380b57cec5SDimitry Andric strm.Indent(" Address: ");
14390b57cec5SDimitry Andric so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
14400b57cec5SDimitry Andric strm.PutCString(" (");
14410b57cec5SDimitry Andric so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
14420b57cec5SDimitry Andric strm.PutCString(")\n");
14430b57cec5SDimitry Andric strm.Indent(" Summary: ");
14440b57cec5SDimitry Andric const uint32_t save_indent = strm.GetIndentLevel();
14450b57cec5SDimitry Andric strm.SetIndentLevel(save_indent + 13);
14460b57cec5SDimitry Andric so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
14470b57cec5SDimitry Andric strm.SetIndentLevel(save_indent);
14480b57cec5SDimitry Andric // Print out detailed address information when verbose is enabled
14490b57cec5SDimitry Andric if (verbose) {
14500b57cec5SDimitry Andric strm.EOL();
14510b57cec5SDimitry Andric so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
14520b57cec5SDimitry Andric }
14530b57cec5SDimitry Andric strm.IndentLess();
14540b57cec5SDimitry Andric }
14550b57cec5SDimitry Andric
LookupAddressInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,uint32_t resolve_mask,lldb::addr_t raw_addr,lldb::addr_t offset,bool verbose)14560b57cec5SDimitry Andric static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
14570b57cec5SDimitry Andric Module *module, uint32_t resolve_mask,
14580b57cec5SDimitry Andric lldb::addr_t raw_addr, lldb::addr_t offset,
14590b57cec5SDimitry Andric bool verbose) {
14600b57cec5SDimitry Andric if (module) {
14610b57cec5SDimitry Andric lldb::addr_t addr = raw_addr - offset;
14620b57cec5SDimitry Andric Address so_addr;
14630b57cec5SDimitry Andric SymbolContext sc;
14640b57cec5SDimitry Andric Target *target = interpreter.GetExecutionContext().GetTargetPtr();
14650b57cec5SDimitry Andric if (target && !target->GetSectionLoadList().IsEmpty()) {
14660b57cec5SDimitry Andric if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
14670b57cec5SDimitry Andric return false;
14680b57cec5SDimitry Andric else if (so_addr.GetModule().get() != module)
14690b57cec5SDimitry Andric return false;
14700b57cec5SDimitry Andric } else {
14710b57cec5SDimitry Andric if (!module->ResolveFileAddress(addr, so_addr))
14720b57cec5SDimitry Andric return false;
14730b57cec5SDimitry Andric }
14740b57cec5SDimitry Andric
14750b57cec5SDimitry Andric ExecutionContextScope *exe_scope =
14760b57cec5SDimitry Andric interpreter.GetExecutionContext().GetBestExecutionContextScope();
14770b57cec5SDimitry Andric DumpAddress(exe_scope, so_addr, verbose, strm);
14780b57cec5SDimitry Andric // strm.IndentMore();
14790b57cec5SDimitry Andric // strm.Indent (" Address: ");
14800b57cec5SDimitry Andric // so_addr.Dump (&strm, exe_scope,
14810b57cec5SDimitry Andric // Address::DumpStyleModuleWithFileAddress);
14820b57cec5SDimitry Andric // strm.PutCString (" (");
14830b57cec5SDimitry Andric // so_addr.Dump (&strm, exe_scope,
14840b57cec5SDimitry Andric // Address::DumpStyleSectionNameOffset);
14850b57cec5SDimitry Andric // strm.PutCString (")\n");
14860b57cec5SDimitry Andric // strm.Indent (" Summary: ");
14870b57cec5SDimitry Andric // const uint32_t save_indent = strm.GetIndentLevel ();
14880b57cec5SDimitry Andric // strm.SetIndentLevel (save_indent + 13);
14890b57cec5SDimitry Andric // so_addr.Dump (&strm, exe_scope,
14900b57cec5SDimitry Andric // Address::DumpStyleResolvedDescription);
14910b57cec5SDimitry Andric // strm.SetIndentLevel (save_indent);
14920b57cec5SDimitry Andric // // Print out detailed address information when verbose is enabled
14930b57cec5SDimitry Andric // if (verbose)
14940b57cec5SDimitry Andric // {
14950b57cec5SDimitry Andric // strm.EOL();
14960b57cec5SDimitry Andric // so_addr.Dump (&strm, exe_scope,
14970b57cec5SDimitry Andric // Address::DumpStyleDetailedSymbolContext);
14980b57cec5SDimitry Andric // }
14990b57cec5SDimitry Andric // strm.IndentLess();
15000b57cec5SDimitry Andric return true;
15010b57cec5SDimitry Andric }
15020b57cec5SDimitry Andric
15030b57cec5SDimitry Andric return false;
15040b57cec5SDimitry Andric }
15050b57cec5SDimitry Andric
LookupSymbolInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const char * name,bool name_is_regex,bool verbose)15060b57cec5SDimitry Andric static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
15070b57cec5SDimitry Andric Stream &strm, Module *module,
15080b57cec5SDimitry Andric const char *name, bool name_is_regex,
15090b57cec5SDimitry Andric bool verbose) {
15109dba64beSDimitry Andric if (!module)
15119dba64beSDimitry Andric return 0;
15120b57cec5SDimitry Andric
15139dba64beSDimitry Andric Symtab *symtab = module->GetSymtab();
15149dba64beSDimitry Andric if (!symtab)
15159dba64beSDimitry Andric return 0;
15169dba64beSDimitry Andric
15179dba64beSDimitry Andric SymbolContext sc;
15180b57cec5SDimitry Andric std::vector<uint32_t> match_indexes;
15190b57cec5SDimitry Andric ConstString symbol_name(name);
15200b57cec5SDimitry Andric uint32_t num_matches = 0;
15210b57cec5SDimitry Andric if (name_is_regex) {
15220b57cec5SDimitry Andric RegularExpression name_regexp(symbol_name.GetStringRef());
15230b57cec5SDimitry Andric num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
15240b57cec5SDimitry Andric name_regexp, eSymbolTypeAny, match_indexes);
15250b57cec5SDimitry Andric } else {
15260b57cec5SDimitry Andric num_matches =
15270b57cec5SDimitry Andric symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
15280b57cec5SDimitry Andric }
15290b57cec5SDimitry Andric
15300b57cec5SDimitry Andric if (num_matches > 0) {
15310b57cec5SDimitry Andric strm.Indent();
15320b57cec5SDimitry Andric strm.Printf("%u symbols match %s'%s' in ", num_matches,
15330b57cec5SDimitry Andric name_is_regex ? "the regular expression " : "", name);
15340b57cec5SDimitry Andric DumpFullpath(strm, &module->GetFileSpec(), 0);
15350b57cec5SDimitry Andric strm.PutCString(":\n");
15360b57cec5SDimitry Andric strm.IndentMore();
15370b57cec5SDimitry Andric for (uint32_t i = 0; i < num_matches; ++i) {
15380b57cec5SDimitry Andric Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
15390b57cec5SDimitry Andric if (symbol && symbol->ValueIsAddress()) {
15409dba64beSDimitry Andric DumpAddress(
15419dba64beSDimitry Andric interpreter.GetExecutionContext().GetBestExecutionContextScope(),
15420b57cec5SDimitry Andric symbol->GetAddressRef(), verbose, strm);
15430b57cec5SDimitry Andric }
15440b57cec5SDimitry Andric }
15450b57cec5SDimitry Andric strm.IndentLess();
15469dba64beSDimitry Andric }
15470b57cec5SDimitry Andric return num_matches;
15480b57cec5SDimitry Andric }
15490b57cec5SDimitry Andric
DumpSymbolContextList(ExecutionContextScope * exe_scope,Stream & strm,SymbolContextList & sc_list,bool verbose)15500b57cec5SDimitry Andric static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
15510b57cec5SDimitry Andric Stream &strm, SymbolContextList &sc_list,
15520b57cec5SDimitry Andric bool verbose) {
15530b57cec5SDimitry Andric strm.IndentMore();
15540b57cec5SDimitry Andric
15550b57cec5SDimitry Andric const uint32_t num_matches = sc_list.GetSize();
15560b57cec5SDimitry Andric
15570b57cec5SDimitry Andric for (uint32_t i = 0; i < num_matches; ++i) {
15580b57cec5SDimitry Andric SymbolContext sc;
15590b57cec5SDimitry Andric if (sc_list.GetContextAtIndex(i, sc)) {
15600b57cec5SDimitry Andric AddressRange range;
15610b57cec5SDimitry Andric
15620b57cec5SDimitry Andric sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
15630b57cec5SDimitry Andric
15640b57cec5SDimitry Andric DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
15650b57cec5SDimitry Andric }
15660b57cec5SDimitry Andric }
15670b57cec5SDimitry Andric strm.IndentLess();
15680b57cec5SDimitry Andric }
15690b57cec5SDimitry Andric
LookupFunctionInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const char * name,bool name_is_regex,bool include_inlines,bool include_symbols,bool verbose)15700b57cec5SDimitry Andric static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
15710b57cec5SDimitry Andric Stream &strm, Module *module,
15720b57cec5SDimitry Andric const char *name, bool name_is_regex,
15730b57cec5SDimitry Andric bool include_inlines, bool include_symbols,
15740b57cec5SDimitry Andric bool verbose) {
15750b57cec5SDimitry Andric if (module && name && name[0]) {
15760b57cec5SDimitry Andric SymbolContextList sc_list;
15770b57cec5SDimitry Andric size_t num_matches = 0;
15780b57cec5SDimitry Andric if (name_is_regex) {
15790b57cec5SDimitry Andric RegularExpression function_name_regex((llvm::StringRef(name)));
15809dba64beSDimitry Andric module->FindFunctions(function_name_regex, include_symbols,
15819dba64beSDimitry Andric include_inlines, sc_list);
15820b57cec5SDimitry Andric } else {
15830b57cec5SDimitry Andric ConstString function_name(name);
15845ffd83dbSDimitry Andric module->FindFunctions(function_name, CompilerDeclContext(),
15855ffd83dbSDimitry Andric eFunctionNameTypeAuto, include_symbols,
15865ffd83dbSDimitry Andric include_inlines, sc_list);
15870b57cec5SDimitry Andric }
15889dba64beSDimitry Andric num_matches = sc_list.GetSize();
15890b57cec5SDimitry Andric if (num_matches) {
15900b57cec5SDimitry Andric strm.Indent();
15910b57cec5SDimitry Andric strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
15920b57cec5SDimitry Andric num_matches > 1 ? "es" : "");
15930b57cec5SDimitry Andric DumpFullpath(strm, &module->GetFileSpec(), 0);
15940b57cec5SDimitry Andric strm.PutCString(":\n");
15950b57cec5SDimitry Andric DumpSymbolContextList(
15960b57cec5SDimitry Andric interpreter.GetExecutionContext().GetBestExecutionContextScope(),
15970b57cec5SDimitry Andric strm, sc_list, verbose);
15980b57cec5SDimitry Andric }
15990b57cec5SDimitry Andric return num_matches;
16000b57cec5SDimitry Andric }
16010b57cec5SDimitry Andric return 0;
16020b57cec5SDimitry Andric }
16030b57cec5SDimitry Andric
LookupTypeInModule(Target * target,CommandInterpreter & interpreter,Stream & strm,Module * module,const char * name_cstr,bool name_is_regex)1604af732203SDimitry Andric static size_t LookupTypeInModule(Target *target,
1605af732203SDimitry Andric CommandInterpreter &interpreter, Stream &strm,
16060b57cec5SDimitry Andric Module *module, const char *name_cstr,
16070b57cec5SDimitry Andric bool name_is_regex) {
16080b57cec5SDimitry Andric TypeList type_list;
16099dba64beSDimitry Andric if (module && name_cstr && name_cstr[0]) {
16100b57cec5SDimitry Andric const uint32_t max_num_matches = UINT32_MAX;
16110b57cec5SDimitry Andric size_t num_matches = 0;
16120b57cec5SDimitry Andric bool name_is_fully_qualified = false;
16130b57cec5SDimitry Andric
16140b57cec5SDimitry Andric ConstString name(name_cstr);
16150b57cec5SDimitry Andric llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
16160b57cec5SDimitry Andric module->FindTypes(name, name_is_fully_qualified, max_num_matches,
16170b57cec5SDimitry Andric searched_symbol_files, type_list);
16180b57cec5SDimitry Andric
16199dba64beSDimitry Andric if (type_list.Empty())
16209dba64beSDimitry Andric return 0;
16219dba64beSDimitry Andric
16220b57cec5SDimitry Andric strm.Indent();
16230b57cec5SDimitry Andric strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
16240b57cec5SDimitry Andric num_matches > 1 ? "es" : "");
16250b57cec5SDimitry Andric DumpFullpath(strm, &module->GetFileSpec(), 0);
16260b57cec5SDimitry Andric strm.PutCString(":\n");
16270b57cec5SDimitry Andric for (TypeSP type_sp : type_list.Types()) {
16289dba64beSDimitry Andric if (!type_sp)
16299dba64beSDimitry Andric continue;
16300b57cec5SDimitry Andric // Resolve the clang type so that any forward references to types
16310b57cec5SDimitry Andric // that haven't yet been parsed will get parsed.
16320b57cec5SDimitry Andric type_sp->GetFullCompilerType();
1633af732203SDimitry Andric type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
16340b57cec5SDimitry Andric // Print all typedef chains
16350b57cec5SDimitry Andric TypeSP typedef_type_sp(type_sp);
16360b57cec5SDimitry Andric TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
16370b57cec5SDimitry Andric while (typedefed_type_sp) {
16380b57cec5SDimitry Andric strm.EOL();
16390b57cec5SDimitry Andric strm.Printf(" typedef '%s': ",
16400b57cec5SDimitry Andric typedef_type_sp->GetName().GetCString());
16410b57cec5SDimitry Andric typedefed_type_sp->GetFullCompilerType();
1642af732203SDimitry Andric typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1643af732203SDimitry Andric target);
16440b57cec5SDimitry Andric typedef_type_sp = typedefed_type_sp;
16450b57cec5SDimitry Andric typedefed_type_sp = typedef_type_sp->GetTypedefType();
16460b57cec5SDimitry Andric }
16470b57cec5SDimitry Andric }
16480b57cec5SDimitry Andric strm.EOL();
16490b57cec5SDimitry Andric }
16509dba64beSDimitry Andric return type_list.GetSize();
16510b57cec5SDimitry Andric }
16520b57cec5SDimitry Andric
LookupTypeHere(Target * target,CommandInterpreter & interpreter,Stream & strm,Module & module,const char * name_cstr,bool name_is_regex)1653af732203SDimitry Andric static size_t LookupTypeHere(Target *target, CommandInterpreter &interpreter,
1654af732203SDimitry Andric Stream &strm, Module &module,
1655af732203SDimitry Andric const char *name_cstr, bool name_is_regex) {
16560b57cec5SDimitry Andric TypeList type_list;
16570b57cec5SDimitry Andric const uint32_t max_num_matches = UINT32_MAX;
16580b57cec5SDimitry Andric bool name_is_fully_qualified = false;
16590b57cec5SDimitry Andric
16600b57cec5SDimitry Andric ConstString name(name_cstr);
16610b57cec5SDimitry Andric llvm::DenseSet<SymbolFile *> searched_symbol_files;
16629dba64beSDimitry Andric module.FindTypes(name, name_is_fully_qualified, max_num_matches,
16630b57cec5SDimitry Andric searched_symbol_files, type_list);
16640b57cec5SDimitry Andric
16659dba64beSDimitry Andric if (type_list.Empty())
16669dba64beSDimitry Andric return 0;
16679dba64beSDimitry Andric
16680b57cec5SDimitry Andric strm.Indent();
16690b57cec5SDimitry Andric strm.PutCString("Best match found in ");
16700b57cec5SDimitry Andric DumpFullpath(strm, &module.GetFileSpec(), 0);
16710b57cec5SDimitry Andric strm.PutCString(":\n");
16720b57cec5SDimitry Andric
16730b57cec5SDimitry Andric TypeSP type_sp(type_list.GetTypeAtIndex(0));
16740b57cec5SDimitry Andric if (type_sp) {
16750b57cec5SDimitry Andric // Resolve the clang type so that any forward references to types that
16760b57cec5SDimitry Andric // haven't yet been parsed will get parsed.
16770b57cec5SDimitry Andric type_sp->GetFullCompilerType();
1678af732203SDimitry Andric type_sp->GetDescription(&strm, eDescriptionLevelFull, true, target);
1679af732203SDimitry Andric // Print all typedef chains.
16800b57cec5SDimitry Andric TypeSP typedef_type_sp(type_sp);
16810b57cec5SDimitry Andric TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
16820b57cec5SDimitry Andric while (typedefed_type_sp) {
16830b57cec5SDimitry Andric strm.EOL();
16840b57cec5SDimitry Andric strm.Printf(" typedef '%s': ",
16850b57cec5SDimitry Andric typedef_type_sp->GetName().GetCString());
16860b57cec5SDimitry Andric typedefed_type_sp->GetFullCompilerType();
1687af732203SDimitry Andric typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true,
1688af732203SDimitry Andric target);
16890b57cec5SDimitry Andric typedef_type_sp = typedefed_type_sp;
16900b57cec5SDimitry Andric typedefed_type_sp = typedef_type_sp->GetTypedefType();
16910b57cec5SDimitry Andric }
16920b57cec5SDimitry Andric }
16930b57cec5SDimitry Andric strm.EOL();
16949dba64beSDimitry Andric return type_list.GetSize();
16950b57cec5SDimitry Andric }
16960b57cec5SDimitry Andric
LookupFileAndLineInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const FileSpec & file_spec,uint32_t line,bool check_inlines,bool verbose)16970b57cec5SDimitry Andric static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
16980b57cec5SDimitry Andric Stream &strm, Module *module,
16990b57cec5SDimitry Andric const FileSpec &file_spec,
17000b57cec5SDimitry Andric uint32_t line, bool check_inlines,
17010b57cec5SDimitry Andric bool verbose) {
17020b57cec5SDimitry Andric if (module && file_spec) {
17030b57cec5SDimitry Andric SymbolContextList sc_list;
17040b57cec5SDimitry Andric const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
17050b57cec5SDimitry Andric file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
17060b57cec5SDimitry Andric if (num_matches > 0) {
17070b57cec5SDimitry Andric strm.Indent();
17080b57cec5SDimitry Andric strm.Printf("%u match%s found in ", num_matches,
17090b57cec5SDimitry Andric num_matches > 1 ? "es" : "");
17100b57cec5SDimitry Andric strm << file_spec;
17110b57cec5SDimitry Andric if (line > 0)
17120b57cec5SDimitry Andric strm.Printf(":%u", line);
17130b57cec5SDimitry Andric strm << " in ";
17140b57cec5SDimitry Andric DumpFullpath(strm, &module->GetFileSpec(), 0);
17150b57cec5SDimitry Andric strm.PutCString(":\n");
17160b57cec5SDimitry Andric DumpSymbolContextList(
17170b57cec5SDimitry Andric interpreter.GetExecutionContext().GetBestExecutionContextScope(),
17180b57cec5SDimitry Andric strm, sc_list, verbose);
17190b57cec5SDimitry Andric return num_matches;
17200b57cec5SDimitry Andric }
17210b57cec5SDimitry Andric }
17220b57cec5SDimitry Andric return 0;
17230b57cec5SDimitry Andric }
17240b57cec5SDimitry Andric
FindModulesByName(Target * target,const char * module_name,ModuleList & module_list,bool check_global_list)17250b57cec5SDimitry Andric static size_t FindModulesByName(Target *target, const char *module_name,
17260b57cec5SDimitry Andric ModuleList &module_list,
17270b57cec5SDimitry Andric bool check_global_list) {
17280b57cec5SDimitry Andric FileSpec module_file_spec(module_name);
17290b57cec5SDimitry Andric ModuleSpec module_spec(module_file_spec);
17300b57cec5SDimitry Andric
17310b57cec5SDimitry Andric const size_t initial_size = module_list.GetSize();
17320b57cec5SDimitry Andric
17330b57cec5SDimitry Andric if (check_global_list) {
17340b57cec5SDimitry Andric // Check the global list
17350b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
17360b57cec5SDimitry Andric Module::GetAllocationModuleCollectionMutex());
17370b57cec5SDimitry Andric const size_t num_modules = Module::GetNumberAllocatedModules();
17380b57cec5SDimitry Andric ModuleSP module_sp;
17390b57cec5SDimitry Andric for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
17400b57cec5SDimitry Andric Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
17410b57cec5SDimitry Andric
17420b57cec5SDimitry Andric if (module) {
17430b57cec5SDimitry Andric if (module->MatchesModuleSpec(module_spec)) {
17440b57cec5SDimitry Andric module_sp = module->shared_from_this();
17450b57cec5SDimitry Andric module_list.AppendIfNeeded(module_sp);
17460b57cec5SDimitry Andric }
17470b57cec5SDimitry Andric }
17480b57cec5SDimitry Andric }
17490b57cec5SDimitry Andric } else {
17500b57cec5SDimitry Andric if (target) {
17510b57cec5SDimitry Andric target->GetImages().FindModules(module_spec, module_list);
17529dba64beSDimitry Andric const size_t num_matches = module_list.GetSize();
17530b57cec5SDimitry Andric
17540b57cec5SDimitry Andric // Not found in our module list for our target, check the main shared
17550b57cec5SDimitry Andric // module list in case it is a extra file used somewhere else
17560b57cec5SDimitry Andric if (num_matches == 0) {
17570b57cec5SDimitry Andric module_spec.GetArchitecture() = target->GetArchitecture();
17580b57cec5SDimitry Andric ModuleList::FindSharedModules(module_spec, module_list);
17590b57cec5SDimitry Andric }
17600b57cec5SDimitry Andric } else {
17610b57cec5SDimitry Andric ModuleList::FindSharedModules(module_spec, module_list);
17620b57cec5SDimitry Andric }
17630b57cec5SDimitry Andric }
17640b57cec5SDimitry Andric
17650b57cec5SDimitry Andric return module_list.GetSize() - initial_size;
17660b57cec5SDimitry Andric }
17670b57cec5SDimitry Andric
17680b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesModuleAutoComplete
17690b57cec5SDimitry Andric
17700b57cec5SDimitry Andric // A base command object class that can auto complete with module file
17710b57cec5SDimitry Andric // paths
17720b57cec5SDimitry Andric
17730b57cec5SDimitry Andric class CommandObjectTargetModulesModuleAutoComplete
17740b57cec5SDimitry Andric : public CommandObjectParsed {
17750b57cec5SDimitry Andric public:
CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags=0)17760b57cec5SDimitry Andric CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
17770b57cec5SDimitry Andric const char *name,
17780b57cec5SDimitry Andric const char *help,
17799dba64beSDimitry Andric const char *syntax,
17809dba64beSDimitry Andric uint32_t flags = 0)
17819dba64beSDimitry Andric : CommandObjectParsed(interpreter, name, help, syntax, flags) {
17820b57cec5SDimitry Andric CommandArgumentEntry arg;
17830b57cec5SDimitry Andric CommandArgumentData file_arg;
17840b57cec5SDimitry Andric
17850b57cec5SDimitry Andric // Define the first (and only) variant of this arg.
17860b57cec5SDimitry Andric file_arg.arg_type = eArgTypeFilename;
17870b57cec5SDimitry Andric file_arg.arg_repetition = eArgRepeatStar;
17880b57cec5SDimitry Andric
17890b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the
17900b57cec5SDimitry Andric // argument entry.
17910b57cec5SDimitry Andric arg.push_back(file_arg);
17920b57cec5SDimitry Andric
17930b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector.
17940b57cec5SDimitry Andric m_arguments.push_back(arg);
17950b57cec5SDimitry Andric }
17960b57cec5SDimitry Andric
17970b57cec5SDimitry Andric ~CommandObjectTargetModulesModuleAutoComplete() override = default;
17980b57cec5SDimitry Andric
17999dba64beSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)18009dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
18010b57cec5SDimitry Andric OptionElementVector &opt_element_vector) override {
18020b57cec5SDimitry Andric CommandCompletions::InvokeCommonCompletionCallbacks(
18030b57cec5SDimitry Andric GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
18040b57cec5SDimitry Andric nullptr);
18050b57cec5SDimitry Andric }
18060b57cec5SDimitry Andric };
18070b57cec5SDimitry Andric
18080b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
18090b57cec5SDimitry Andric
18100b57cec5SDimitry Andric // A base command object class that can auto complete with module source
18110b57cec5SDimitry Andric // file paths
18120b57cec5SDimitry Andric
18130b57cec5SDimitry Andric class CommandObjectTargetModulesSourceFileAutoComplete
18140b57cec5SDimitry Andric : public CommandObjectParsed {
18150b57cec5SDimitry Andric public:
CommandObjectTargetModulesSourceFileAutoComplete(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags)18160b57cec5SDimitry Andric CommandObjectTargetModulesSourceFileAutoComplete(
18170b57cec5SDimitry Andric CommandInterpreter &interpreter, const char *name, const char *help,
18180b57cec5SDimitry Andric const char *syntax, uint32_t flags)
18190b57cec5SDimitry Andric : CommandObjectParsed(interpreter, name, help, syntax, flags) {
18200b57cec5SDimitry Andric CommandArgumentEntry arg;
18210b57cec5SDimitry Andric CommandArgumentData source_file_arg;
18220b57cec5SDimitry Andric
18230b57cec5SDimitry Andric // Define the first (and only) variant of this arg.
18240b57cec5SDimitry Andric source_file_arg.arg_type = eArgTypeSourceFile;
18250b57cec5SDimitry Andric source_file_arg.arg_repetition = eArgRepeatPlus;
18260b57cec5SDimitry Andric
18270b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the
18280b57cec5SDimitry Andric // argument entry.
18290b57cec5SDimitry Andric arg.push_back(source_file_arg);
18300b57cec5SDimitry Andric
18310b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector.
18320b57cec5SDimitry Andric m_arguments.push_back(arg);
18330b57cec5SDimitry Andric }
18340b57cec5SDimitry Andric
18350b57cec5SDimitry Andric ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
18360b57cec5SDimitry Andric
18379dba64beSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)18389dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
18390b57cec5SDimitry Andric OptionElementVector &opt_element_vector) override {
18400b57cec5SDimitry Andric CommandCompletions::InvokeCommonCompletionCallbacks(
18410b57cec5SDimitry Andric GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
18420b57cec5SDimitry Andric request, nullptr);
18430b57cec5SDimitry Andric }
18440b57cec5SDimitry Andric };
18450b57cec5SDimitry Andric
18460b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpObjfile
18470b57cec5SDimitry Andric
18480b57cec5SDimitry Andric class CommandObjectTargetModulesDumpObjfile
18490b57cec5SDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
18500b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpObjfile(CommandInterpreter & interpreter)18510b57cec5SDimitry Andric CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
18520b57cec5SDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
18530b57cec5SDimitry Andric interpreter, "target modules dump objfile",
18540b57cec5SDimitry Andric "Dump the object file headers from one or more target modules.",
18559dba64beSDimitry Andric nullptr, eCommandRequiresTarget) {}
18560b57cec5SDimitry Andric
18570b57cec5SDimitry Andric ~CommandObjectTargetModulesDumpObjfile() override = default;
18580b57cec5SDimitry Andric
18590b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)18600b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
18619dba64beSDimitry Andric Target *target = &GetSelectedTarget();
18620b57cec5SDimitry Andric
18630b57cec5SDimitry Andric uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
18640b57cec5SDimitry Andric result.GetOutputStream().SetAddressByteSize(addr_byte_size);
18650b57cec5SDimitry Andric result.GetErrorStream().SetAddressByteSize(addr_byte_size);
18660b57cec5SDimitry Andric
18670b57cec5SDimitry Andric size_t num_dumped = 0;
18680b57cec5SDimitry Andric if (command.GetArgumentCount() == 0) {
18690b57cec5SDimitry Andric // Dump all headers for all modules images
18700b57cec5SDimitry Andric num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
18710b57cec5SDimitry Andric target->GetImages());
18720b57cec5SDimitry Andric if (num_dumped == 0) {
18730b57cec5SDimitry Andric result.AppendError("the target has no associated executable images");
18740b57cec5SDimitry Andric }
18750b57cec5SDimitry Andric } else {
18760b57cec5SDimitry Andric // Find the modules that match the basename or full path.
18770b57cec5SDimitry Andric ModuleList module_list;
18780b57cec5SDimitry Andric const char *arg_cstr;
18790b57cec5SDimitry Andric for (int arg_idx = 0;
18800b57cec5SDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
18810b57cec5SDimitry Andric ++arg_idx) {
18820b57cec5SDimitry Andric size_t num_matched =
18830b57cec5SDimitry Andric FindModulesByName(target, arg_cstr, module_list, true);
18840b57cec5SDimitry Andric if (num_matched == 0) {
18850b57cec5SDimitry Andric result.AppendWarningWithFormat(
18860b57cec5SDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
18870b57cec5SDimitry Andric }
18880b57cec5SDimitry Andric }
18890b57cec5SDimitry Andric // Dump all the modules we found.
18900b57cec5SDimitry Andric num_dumped =
18910b57cec5SDimitry Andric DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
18920b57cec5SDimitry Andric }
18930b57cec5SDimitry Andric
18940b57cec5SDimitry Andric if (num_dumped > 0) {
18950b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
18960b57cec5SDimitry Andric } else {
18970b57cec5SDimitry Andric result.AppendError("no matching executable images found");
18980b57cec5SDimitry Andric }
18990b57cec5SDimitry Andric return result.Succeeded();
19000b57cec5SDimitry Andric }
19010b57cec5SDimitry Andric };
19020b57cec5SDimitry Andric
19030b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpSymtab
19040b57cec5SDimitry Andric
19050b57cec5SDimitry Andric static constexpr OptionEnumValueElement g_sort_option_enumeration[] = {
19069dba64beSDimitry Andric {
19079dba64beSDimitry Andric eSortOrderNone,
19089dba64beSDimitry Andric "none",
19099dba64beSDimitry Andric "No sorting, use the original symbol table order.",
19109dba64beSDimitry Andric },
19119dba64beSDimitry Andric {
19129dba64beSDimitry Andric eSortOrderByAddress,
19139dba64beSDimitry Andric "address",
19149dba64beSDimitry Andric "Sort output by symbol address.",
19159dba64beSDimitry Andric },
19169dba64beSDimitry Andric {
19179dba64beSDimitry Andric eSortOrderByName,
19189dba64beSDimitry Andric "name",
19199dba64beSDimitry Andric "Sort output by symbol name.",
19209dba64beSDimitry Andric },
19219dba64beSDimitry Andric };
19220b57cec5SDimitry Andric
19230b57cec5SDimitry Andric #define LLDB_OPTIONS_target_modules_dump_symtab
19240b57cec5SDimitry Andric #include "CommandOptions.inc"
19250b57cec5SDimitry Andric
19260b57cec5SDimitry Andric class CommandObjectTargetModulesDumpSymtab
19270b57cec5SDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
19280b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpSymtab(CommandInterpreter & interpreter)19290b57cec5SDimitry Andric CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
19300b57cec5SDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
19310b57cec5SDimitry Andric interpreter, "target modules dump symtab",
19329dba64beSDimitry Andric "Dump the symbol table from one or more target modules.", nullptr,
19339dba64beSDimitry Andric eCommandRequiresTarget),
19340b57cec5SDimitry Andric m_options() {}
19350b57cec5SDimitry Andric
19360b57cec5SDimitry Andric ~CommandObjectTargetModulesDumpSymtab() override = default;
19370b57cec5SDimitry Andric
GetOptions()19380b57cec5SDimitry Andric Options *GetOptions() override { return &m_options; }
19390b57cec5SDimitry Andric
19400b57cec5SDimitry Andric class CommandOptions : public Options {
19410b57cec5SDimitry Andric public:
CommandOptions()1942*5f7ddb14SDimitry Andric CommandOptions() : Options() {}
19430b57cec5SDimitry Andric
19440b57cec5SDimitry Andric ~CommandOptions() override = default;
19450b57cec5SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)19460b57cec5SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
19470b57cec5SDimitry Andric ExecutionContext *execution_context) override {
19480b57cec5SDimitry Andric Status error;
19490b57cec5SDimitry Andric const int short_option = m_getopt_table[option_idx].val;
19500b57cec5SDimitry Andric
19510b57cec5SDimitry Andric switch (short_option) {
1952480093f4SDimitry Andric case 'm':
1953480093f4SDimitry Andric m_prefer_mangled.SetCurrentValue(true);
1954480093f4SDimitry Andric m_prefer_mangled.SetOptionWasSet();
1955480093f4SDimitry Andric break;
1956480093f4SDimitry Andric
19570b57cec5SDimitry Andric case 's':
19580b57cec5SDimitry Andric m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(
19590b57cec5SDimitry Andric option_arg, GetDefinitions()[option_idx].enum_values,
19600b57cec5SDimitry Andric eSortOrderNone, error);
19610b57cec5SDimitry Andric break;
19620b57cec5SDimitry Andric
19630b57cec5SDimitry Andric default:
19649dba64beSDimitry Andric llvm_unreachable("Unimplemented option");
19650b57cec5SDimitry Andric }
19660b57cec5SDimitry Andric return error;
19670b57cec5SDimitry Andric }
19680b57cec5SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)19690b57cec5SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
19700b57cec5SDimitry Andric m_sort_order = eSortOrderNone;
1971480093f4SDimitry Andric m_prefer_mangled.Clear();
19720b57cec5SDimitry Andric }
19730b57cec5SDimitry Andric
GetDefinitions()19740b57cec5SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
19750b57cec5SDimitry Andric return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
19760b57cec5SDimitry Andric }
19770b57cec5SDimitry Andric
1978*5f7ddb14SDimitry Andric SortOrder m_sort_order = eSortOrderNone;
1979480093f4SDimitry Andric OptionValueBoolean m_prefer_mangled = {false, false};
19800b57cec5SDimitry Andric };
19810b57cec5SDimitry Andric
19820b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)19830b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
19849dba64beSDimitry Andric Target *target = &GetSelectedTarget();
19850b57cec5SDimitry Andric uint32_t num_dumped = 0;
1986480093f4SDimitry Andric Mangled::NamePreference name_preference =
1987480093f4SDimitry Andric (m_options.m_prefer_mangled ? Mangled::ePreferMangled
1988480093f4SDimitry Andric : Mangled::ePreferDemangled);
19890b57cec5SDimitry Andric
19900b57cec5SDimitry Andric uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
19910b57cec5SDimitry Andric result.GetOutputStream().SetAddressByteSize(addr_byte_size);
19920b57cec5SDimitry Andric result.GetErrorStream().SetAddressByteSize(addr_byte_size);
19930b57cec5SDimitry Andric
19940b57cec5SDimitry Andric if (command.GetArgumentCount() == 0) {
19950b57cec5SDimitry Andric // Dump all sections for all modules images
1996af732203SDimitry Andric const ModuleList &module_list = target->GetImages();
1997af732203SDimitry Andric std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1998af732203SDimitry Andric const size_t num_modules = module_list.GetSize();
19990b57cec5SDimitry Andric if (num_modules > 0) {
2000af732203SDimitry Andric result.GetOutputStream().Format(
2001af732203SDimitry Andric "Dumping symbol table for {0} modules.\n", num_modules);
2002af732203SDimitry Andric for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
20030b57cec5SDimitry Andric if (num_dumped > 0) {
20040b57cec5SDimitry Andric result.GetOutputStream().EOL();
20050b57cec5SDimitry Andric result.GetOutputStream().EOL();
20060b57cec5SDimitry Andric }
20070b57cec5SDimitry Andric if (m_interpreter.WasInterrupted())
20080b57cec5SDimitry Andric break;
20090b57cec5SDimitry Andric num_dumped++;
2010af732203SDimitry Andric DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2011af732203SDimitry Andric module_sp.get(), m_options.m_sort_order,
2012af732203SDimitry Andric name_preference);
20130b57cec5SDimitry Andric }
20140b57cec5SDimitry Andric } else {
20150b57cec5SDimitry Andric result.AppendError("the target has no associated executable images");
20160b57cec5SDimitry Andric return false;
20170b57cec5SDimitry Andric }
20180b57cec5SDimitry Andric } else {
20190b57cec5SDimitry Andric // Dump specified images (by basename or fullpath)
20200b57cec5SDimitry Andric const char *arg_cstr;
20210b57cec5SDimitry Andric for (int arg_idx = 0;
20220b57cec5SDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
20230b57cec5SDimitry Andric ++arg_idx) {
20240b57cec5SDimitry Andric ModuleList module_list;
20250b57cec5SDimitry Andric const size_t num_matches =
20260b57cec5SDimitry Andric FindModulesByName(target, arg_cstr, module_list, true);
20270b57cec5SDimitry Andric if (num_matches > 0) {
2028af732203SDimitry Andric for (ModuleSP module_sp : module_list.Modules()) {
2029af732203SDimitry Andric if (module_sp) {
20300b57cec5SDimitry Andric if (num_dumped > 0) {
20310b57cec5SDimitry Andric result.GetOutputStream().EOL();
20320b57cec5SDimitry Andric result.GetOutputStream().EOL();
20330b57cec5SDimitry Andric }
20340b57cec5SDimitry Andric if (m_interpreter.WasInterrupted())
20350b57cec5SDimitry Andric break;
20360b57cec5SDimitry Andric num_dumped++;
2037af732203SDimitry Andric DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2038af732203SDimitry Andric module_sp.get(), m_options.m_sort_order,
2039af732203SDimitry Andric name_preference);
20400b57cec5SDimitry Andric }
20410b57cec5SDimitry Andric }
20420b57cec5SDimitry Andric } else
20430b57cec5SDimitry Andric result.AppendWarningWithFormat(
20440b57cec5SDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
20450b57cec5SDimitry Andric }
20460b57cec5SDimitry Andric }
20470b57cec5SDimitry Andric
20480b57cec5SDimitry Andric if (num_dumped > 0)
20490b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
20500b57cec5SDimitry Andric else {
20510b57cec5SDimitry Andric result.AppendError("no matching executable images found");
20520b57cec5SDimitry Andric }
20530b57cec5SDimitry Andric return result.Succeeded();
20540b57cec5SDimitry Andric }
20550b57cec5SDimitry Andric
20560b57cec5SDimitry Andric CommandOptions m_options;
20570b57cec5SDimitry Andric };
20580b57cec5SDimitry Andric
20590b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpSections
20600b57cec5SDimitry Andric
20610b57cec5SDimitry Andric // Image section dumping command
20620b57cec5SDimitry Andric
20630b57cec5SDimitry Andric class CommandObjectTargetModulesDumpSections
20640b57cec5SDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
20650b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpSections(CommandInterpreter & interpreter)20660b57cec5SDimitry Andric CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
20670b57cec5SDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
20680b57cec5SDimitry Andric interpreter, "target modules dump sections",
20690b57cec5SDimitry Andric "Dump the sections from one or more target modules.",
20700b57cec5SDimitry Andric //"target modules dump sections [<file1> ...]")
20719dba64beSDimitry Andric nullptr, eCommandRequiresTarget) {}
20720b57cec5SDimitry Andric
20730b57cec5SDimitry Andric ~CommandObjectTargetModulesDumpSections() override = default;
20740b57cec5SDimitry Andric
20750b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)20760b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
20779dba64beSDimitry Andric Target *target = &GetSelectedTarget();
20780b57cec5SDimitry Andric uint32_t num_dumped = 0;
20790b57cec5SDimitry Andric
20800b57cec5SDimitry Andric uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
20810b57cec5SDimitry Andric result.GetOutputStream().SetAddressByteSize(addr_byte_size);
20820b57cec5SDimitry Andric result.GetErrorStream().SetAddressByteSize(addr_byte_size);
20830b57cec5SDimitry Andric
20840b57cec5SDimitry Andric if (command.GetArgumentCount() == 0) {
20850b57cec5SDimitry Andric // Dump all sections for all modules images
20860b57cec5SDimitry Andric const size_t num_modules = target->GetImages().GetSize();
2087af732203SDimitry Andric if (num_modules == 0) {
2088af732203SDimitry Andric result.AppendError("the target has no associated executable images");
2089af732203SDimitry Andric return false;
2090af732203SDimitry Andric }
2091af732203SDimitry Andric
2092af732203SDimitry Andric result.GetOutputStream().Format("Dumping sections for {0} modules.\n",
2093af732203SDimitry Andric num_modules);
20940b57cec5SDimitry Andric for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
20950b57cec5SDimitry Andric if (m_interpreter.WasInterrupted())
20960b57cec5SDimitry Andric break;
20970b57cec5SDimitry Andric num_dumped++;
20980b57cec5SDimitry Andric DumpModuleSections(
20990b57cec5SDimitry Andric m_interpreter, result.GetOutputStream(),
21000b57cec5SDimitry Andric target->GetImages().GetModulePointerAtIndex(image_idx));
21010b57cec5SDimitry Andric }
21020b57cec5SDimitry Andric } else {
21030b57cec5SDimitry Andric // Dump specified images (by basename or fullpath)
21040b57cec5SDimitry Andric const char *arg_cstr;
21050b57cec5SDimitry Andric for (int arg_idx = 0;
21060b57cec5SDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
21070b57cec5SDimitry Andric ++arg_idx) {
21080b57cec5SDimitry Andric ModuleList module_list;
21090b57cec5SDimitry Andric const size_t num_matches =
21100b57cec5SDimitry Andric FindModulesByName(target, arg_cstr, module_list, true);
21110b57cec5SDimitry Andric if (num_matches > 0) {
21120b57cec5SDimitry Andric for (size_t i = 0; i < num_matches; ++i) {
21130b57cec5SDimitry Andric if (m_interpreter.WasInterrupted())
21140b57cec5SDimitry Andric break;
21150b57cec5SDimitry Andric Module *module = module_list.GetModulePointerAtIndex(i);
21160b57cec5SDimitry Andric if (module) {
21170b57cec5SDimitry Andric num_dumped++;
21180b57cec5SDimitry Andric DumpModuleSections(m_interpreter, result.GetOutputStream(),
21190b57cec5SDimitry Andric module);
21200b57cec5SDimitry Andric }
21210b57cec5SDimitry Andric }
21220b57cec5SDimitry Andric } else {
21230b57cec5SDimitry Andric // Check the global list
21240b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
21250b57cec5SDimitry Andric Module::GetAllocationModuleCollectionMutex());
21260b57cec5SDimitry Andric
21270b57cec5SDimitry Andric result.AppendWarningWithFormat(
21280b57cec5SDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
21290b57cec5SDimitry Andric }
21300b57cec5SDimitry Andric }
21310b57cec5SDimitry Andric }
21320b57cec5SDimitry Andric
21330b57cec5SDimitry Andric if (num_dumped > 0)
21340b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
21350b57cec5SDimitry Andric else {
21360b57cec5SDimitry Andric result.AppendError("no matching executable images found");
21370b57cec5SDimitry Andric }
21380b57cec5SDimitry Andric return result.Succeeded();
21390b57cec5SDimitry Andric }
21400b57cec5SDimitry Andric };
21410b57cec5SDimitry Andric
21425ffd83dbSDimitry Andric #pragma mark CommandObjectTargetModulesDumpClangAST
21430b57cec5SDimitry Andric
21440b57cec5SDimitry Andric // Clang AST dumping command
21450b57cec5SDimitry Andric
21460b57cec5SDimitry Andric class CommandObjectTargetModulesDumpClangAST
21470b57cec5SDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
21480b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpClangAST(CommandInterpreter & interpreter)21490b57cec5SDimitry Andric CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
21500b57cec5SDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
21510b57cec5SDimitry Andric interpreter, "target modules dump ast",
21520b57cec5SDimitry Andric "Dump the clang ast for a given module's symbol file.",
21530b57cec5SDimitry Andric //"target modules dump ast [<file1> ...]")
21549dba64beSDimitry Andric nullptr, eCommandRequiresTarget) {}
21550b57cec5SDimitry Andric
21560b57cec5SDimitry Andric ~CommandObjectTargetModulesDumpClangAST() override = default;
21570b57cec5SDimitry Andric
21580b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)21590b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
21609dba64beSDimitry Andric Target *target = &GetSelectedTarget();
21610b57cec5SDimitry Andric
2162af732203SDimitry Andric const ModuleList &module_list = target->GetImages();
2163af732203SDimitry Andric const size_t num_modules = module_list.GetSize();
21640b57cec5SDimitry Andric if (num_modules == 0) {
21650b57cec5SDimitry Andric result.AppendError("the target has no associated executable images");
21660b57cec5SDimitry Andric return false;
21670b57cec5SDimitry Andric }
21680b57cec5SDimitry Andric
21690b57cec5SDimitry Andric if (command.GetArgumentCount() == 0) {
21700b57cec5SDimitry Andric // Dump all ASTs for all modules images
2171af732203SDimitry Andric result.GetOutputStream().Format("Dumping clang ast for {0} modules.\n",
2172af732203SDimitry Andric num_modules);
2173af732203SDimitry Andric for (ModuleSP module_sp : module_list.ModulesNoLocking()) {
21740b57cec5SDimitry Andric if (m_interpreter.WasInterrupted())
21750b57cec5SDimitry Andric break;
2176af732203SDimitry Andric if (SymbolFile *sf = module_sp->GetSymbolFile())
21770b57cec5SDimitry Andric sf->DumpClangAST(result.GetOutputStream());
21780b57cec5SDimitry Andric }
21790b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
21800b57cec5SDimitry Andric return true;
21810b57cec5SDimitry Andric }
21820b57cec5SDimitry Andric
21830b57cec5SDimitry Andric // Dump specified ASTs (by basename or fullpath)
21840b57cec5SDimitry Andric for (const Args::ArgEntry &arg : command.entries()) {
21850b57cec5SDimitry Andric ModuleList module_list;
21860b57cec5SDimitry Andric const size_t num_matches =
21870b57cec5SDimitry Andric FindModulesByName(target, arg.c_str(), module_list, true);
21880b57cec5SDimitry Andric if (num_matches == 0) {
21890b57cec5SDimitry Andric // Check the global list
21900b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
21910b57cec5SDimitry Andric Module::GetAllocationModuleCollectionMutex());
21920b57cec5SDimitry Andric
21930b57cec5SDimitry Andric result.AppendWarningWithFormat(
21940b57cec5SDimitry Andric "Unable to find an image that matches '%s'.\n", arg.c_str());
21950b57cec5SDimitry Andric continue;
21960b57cec5SDimitry Andric }
21970b57cec5SDimitry Andric
21980b57cec5SDimitry Andric for (size_t i = 0; i < num_matches; ++i) {
21990b57cec5SDimitry Andric if (m_interpreter.WasInterrupted())
22000b57cec5SDimitry Andric break;
22010b57cec5SDimitry Andric Module *m = module_list.GetModulePointerAtIndex(i);
22029dba64beSDimitry Andric if (SymbolFile *sf = m->GetSymbolFile())
22030b57cec5SDimitry Andric sf->DumpClangAST(result.GetOutputStream());
22040b57cec5SDimitry Andric }
22050b57cec5SDimitry Andric }
22060b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
22070b57cec5SDimitry Andric return true;
22080b57cec5SDimitry Andric }
22090b57cec5SDimitry Andric };
22100b57cec5SDimitry Andric
22110b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpSymfile
22120b57cec5SDimitry Andric
22130b57cec5SDimitry Andric // Image debug symbol dumping command
22140b57cec5SDimitry Andric
22150b57cec5SDimitry Andric class CommandObjectTargetModulesDumpSymfile
22160b57cec5SDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
22170b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpSymfile(CommandInterpreter & interpreter)22180b57cec5SDimitry Andric CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
22190b57cec5SDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
22200b57cec5SDimitry Andric interpreter, "target modules dump symfile",
22210b57cec5SDimitry Andric "Dump the debug symbol file for one or more target modules.",
22220b57cec5SDimitry Andric //"target modules dump symfile [<file1> ...]")
22239dba64beSDimitry Andric nullptr, eCommandRequiresTarget) {}
22240b57cec5SDimitry Andric
22250b57cec5SDimitry Andric ~CommandObjectTargetModulesDumpSymfile() override = default;
22260b57cec5SDimitry Andric
22270b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)22280b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
22299dba64beSDimitry Andric Target *target = &GetSelectedTarget();
22300b57cec5SDimitry Andric uint32_t num_dumped = 0;
22310b57cec5SDimitry Andric
22320b57cec5SDimitry Andric uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
22330b57cec5SDimitry Andric result.GetOutputStream().SetAddressByteSize(addr_byte_size);
22340b57cec5SDimitry Andric result.GetErrorStream().SetAddressByteSize(addr_byte_size);
22350b57cec5SDimitry Andric
22360b57cec5SDimitry Andric if (command.GetArgumentCount() == 0) {
22370b57cec5SDimitry Andric // Dump all sections for all modules images
22380b57cec5SDimitry Andric const ModuleList &target_modules = target->GetImages();
22390b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
22400b57cec5SDimitry Andric const size_t num_modules = target_modules.GetSize();
2241af732203SDimitry Andric if (num_modules == 0) {
22420b57cec5SDimitry Andric result.AppendError("the target has no associated executable images");
22430b57cec5SDimitry Andric return false;
22440b57cec5SDimitry Andric }
2245af732203SDimitry Andric result.GetOutputStream().Format(
2246af732203SDimitry Andric "Dumping debug symbols for {0} modules.\n", num_modules);
2247af732203SDimitry Andric for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
2248af732203SDimitry Andric if (m_interpreter.WasInterrupted())
2249af732203SDimitry Andric break;
2250af732203SDimitry Andric if (DumpModuleSymbolFile(result.GetOutputStream(), module_sp.get()))
2251af732203SDimitry Andric num_dumped++;
2252af732203SDimitry Andric }
22530b57cec5SDimitry Andric } else {
22540b57cec5SDimitry Andric // Dump specified images (by basename or fullpath)
22550b57cec5SDimitry Andric const char *arg_cstr;
22560b57cec5SDimitry Andric for (int arg_idx = 0;
22570b57cec5SDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
22580b57cec5SDimitry Andric ++arg_idx) {
22590b57cec5SDimitry Andric ModuleList module_list;
22600b57cec5SDimitry Andric const size_t num_matches =
22610b57cec5SDimitry Andric FindModulesByName(target, arg_cstr, module_list, true);
22620b57cec5SDimitry Andric if (num_matches > 0) {
22630b57cec5SDimitry Andric for (size_t i = 0; i < num_matches; ++i) {
22640b57cec5SDimitry Andric if (m_interpreter.WasInterrupted())
22650b57cec5SDimitry Andric break;
22660b57cec5SDimitry Andric Module *module = module_list.GetModulePointerAtIndex(i);
22670b57cec5SDimitry Andric if (module) {
22689dba64beSDimitry Andric if (DumpModuleSymbolFile(result.GetOutputStream(), module))
22690b57cec5SDimitry Andric num_dumped++;
22700b57cec5SDimitry Andric }
22710b57cec5SDimitry Andric }
22720b57cec5SDimitry Andric } else
22730b57cec5SDimitry Andric result.AppendWarningWithFormat(
22740b57cec5SDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
22750b57cec5SDimitry Andric }
22760b57cec5SDimitry Andric }
22770b57cec5SDimitry Andric
22780b57cec5SDimitry Andric if (num_dumped > 0)
22790b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
22800b57cec5SDimitry Andric else {
22810b57cec5SDimitry Andric result.AppendError("no matching executable images found");
22820b57cec5SDimitry Andric }
22830b57cec5SDimitry Andric return result.Succeeded();
22840b57cec5SDimitry Andric }
22850b57cec5SDimitry Andric };
22860b57cec5SDimitry Andric
22870b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDumpLineTable
22889dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_dump
22899dba64beSDimitry Andric #include "CommandOptions.inc"
22900b57cec5SDimitry Andric
22910b57cec5SDimitry Andric // Image debug line table dumping command
22920b57cec5SDimitry Andric
22930b57cec5SDimitry Andric class CommandObjectTargetModulesDumpLineTable
22940b57cec5SDimitry Andric : public CommandObjectTargetModulesSourceFileAutoComplete {
22950b57cec5SDimitry Andric public:
CommandObjectTargetModulesDumpLineTable(CommandInterpreter & interpreter)22960b57cec5SDimitry Andric CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
22970b57cec5SDimitry Andric : CommandObjectTargetModulesSourceFileAutoComplete(
22980b57cec5SDimitry Andric interpreter, "target modules dump line-table",
22990b57cec5SDimitry Andric "Dump the line table for one or more compilation units.", nullptr,
23000b57cec5SDimitry Andric eCommandRequiresTarget) {}
23010b57cec5SDimitry Andric
23020b57cec5SDimitry Andric ~CommandObjectTargetModulesDumpLineTable() override = default;
23030b57cec5SDimitry Andric
GetOptions()23040b57cec5SDimitry Andric Options *GetOptions() override { return &m_options; }
23050b57cec5SDimitry Andric
23060b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)23070b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
23080b57cec5SDimitry Andric Target *target = m_exe_ctx.GetTargetPtr();
23090b57cec5SDimitry Andric uint32_t total_num_dumped = 0;
23100b57cec5SDimitry Andric
23110b57cec5SDimitry Andric uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
23120b57cec5SDimitry Andric result.GetOutputStream().SetAddressByteSize(addr_byte_size);
23130b57cec5SDimitry Andric result.GetErrorStream().SetAddressByteSize(addr_byte_size);
23140b57cec5SDimitry Andric
23150b57cec5SDimitry Andric if (command.GetArgumentCount() == 0) {
23160b57cec5SDimitry Andric result.AppendError("file option must be specified.");
23170b57cec5SDimitry Andric return result.Succeeded();
23180b57cec5SDimitry Andric } else {
23190b57cec5SDimitry Andric // Dump specified images (by basename or fullpath)
23200b57cec5SDimitry Andric const char *arg_cstr;
23210b57cec5SDimitry Andric for (int arg_idx = 0;
23220b57cec5SDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
23230b57cec5SDimitry Andric ++arg_idx) {
23240b57cec5SDimitry Andric FileSpec file_spec(arg_cstr);
23250b57cec5SDimitry Andric
23260b57cec5SDimitry Andric const ModuleList &target_modules = target->GetImages();
23270b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2328af732203SDimitry Andric if (target_modules.GetSize() > 0) {
23290b57cec5SDimitry Andric uint32_t num_dumped = 0;
2330af732203SDimitry Andric for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
23310b57cec5SDimitry Andric if (m_interpreter.WasInterrupted())
23320b57cec5SDimitry Andric break;
23330b57cec5SDimitry Andric if (DumpCompileUnitLineTable(
2334af732203SDimitry Andric m_interpreter, result.GetOutputStream(), module_sp.get(),
23350b57cec5SDimitry Andric file_spec,
23360b57cec5SDimitry Andric m_options.m_verbose ? eDescriptionLevelFull
23370b57cec5SDimitry Andric : eDescriptionLevelBrief))
23380b57cec5SDimitry Andric num_dumped++;
23390b57cec5SDimitry Andric }
23400b57cec5SDimitry Andric if (num_dumped == 0)
23410b57cec5SDimitry Andric result.AppendWarningWithFormat(
23420b57cec5SDimitry Andric "No source filenames matched '%s'.\n", arg_cstr);
23430b57cec5SDimitry Andric else
23440b57cec5SDimitry Andric total_num_dumped += num_dumped;
23450b57cec5SDimitry Andric }
23460b57cec5SDimitry Andric }
23470b57cec5SDimitry Andric }
23480b57cec5SDimitry Andric
23490b57cec5SDimitry Andric if (total_num_dumped > 0)
23500b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
23510b57cec5SDimitry Andric else {
23520b57cec5SDimitry Andric result.AppendError("no source filenames matched any command arguments");
23530b57cec5SDimitry Andric }
23540b57cec5SDimitry Andric return result.Succeeded();
23550b57cec5SDimitry Andric }
23560b57cec5SDimitry Andric
23570b57cec5SDimitry Andric class CommandOptions : public Options {
23580b57cec5SDimitry Andric public:
CommandOptions()23590b57cec5SDimitry Andric CommandOptions() : Options() { OptionParsingStarting(nullptr); }
23600b57cec5SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)23610b57cec5SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
23620b57cec5SDimitry Andric ExecutionContext *execution_context) override {
23630b57cec5SDimitry Andric assert(option_idx == 0 && "We only have one option.");
23640b57cec5SDimitry Andric m_verbose = true;
23650b57cec5SDimitry Andric
23660b57cec5SDimitry Andric return Status();
23670b57cec5SDimitry Andric }
23680b57cec5SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)23690b57cec5SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
23700b57cec5SDimitry Andric m_verbose = false;
23710b57cec5SDimitry Andric }
23720b57cec5SDimitry Andric
GetDefinitions()23730b57cec5SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
23749dba64beSDimitry Andric return llvm::makeArrayRef(g_target_modules_dump_options);
23750b57cec5SDimitry Andric }
23760b57cec5SDimitry Andric
23770b57cec5SDimitry Andric bool m_verbose;
23780b57cec5SDimitry Andric };
23790b57cec5SDimitry Andric
23800b57cec5SDimitry Andric CommandOptions m_options;
23810b57cec5SDimitry Andric };
23820b57cec5SDimitry Andric
23830b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesDump
23840b57cec5SDimitry Andric
23850b57cec5SDimitry Andric // Dump multi-word command for target modules
23860b57cec5SDimitry Andric
23870b57cec5SDimitry Andric class CommandObjectTargetModulesDump : public CommandObjectMultiword {
23880b57cec5SDimitry Andric public:
23890b57cec5SDimitry Andric // Constructors and Destructors
CommandObjectTargetModulesDump(CommandInterpreter & interpreter)23900b57cec5SDimitry Andric CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
23910b57cec5SDimitry Andric : CommandObjectMultiword(
23920b57cec5SDimitry Andric interpreter, "target modules dump",
23930b57cec5SDimitry Andric "Commands for dumping information about one or "
23940b57cec5SDimitry Andric "more target modules.",
23950b57cec5SDimitry Andric "target modules dump "
23960b57cec5SDimitry Andric "[headers|symtab|sections|ast|symfile|line-table] "
23970b57cec5SDimitry Andric "[<file1> <file2> ...]") {
23980b57cec5SDimitry Andric LoadSubCommand("objfile",
23990b57cec5SDimitry Andric CommandObjectSP(
24000b57cec5SDimitry Andric new CommandObjectTargetModulesDumpObjfile(interpreter)));
24010b57cec5SDimitry Andric LoadSubCommand(
24020b57cec5SDimitry Andric "symtab",
24030b57cec5SDimitry Andric CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
24040b57cec5SDimitry Andric LoadSubCommand("sections",
24050b57cec5SDimitry Andric CommandObjectSP(new CommandObjectTargetModulesDumpSections(
24060b57cec5SDimitry Andric interpreter)));
24070b57cec5SDimitry Andric LoadSubCommand("symfile",
24080b57cec5SDimitry Andric CommandObjectSP(
24090b57cec5SDimitry Andric new CommandObjectTargetModulesDumpSymfile(interpreter)));
24100b57cec5SDimitry Andric LoadSubCommand(
24110b57cec5SDimitry Andric "ast", CommandObjectSP(
24120b57cec5SDimitry Andric new CommandObjectTargetModulesDumpClangAST(interpreter)));
24130b57cec5SDimitry Andric LoadSubCommand("line-table",
24140b57cec5SDimitry Andric CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
24150b57cec5SDimitry Andric interpreter)));
24160b57cec5SDimitry Andric }
24170b57cec5SDimitry Andric
24180b57cec5SDimitry Andric ~CommandObjectTargetModulesDump() override = default;
24190b57cec5SDimitry Andric };
24200b57cec5SDimitry Andric
24210b57cec5SDimitry Andric class CommandObjectTargetModulesAdd : public CommandObjectParsed {
24220b57cec5SDimitry Andric public:
CommandObjectTargetModulesAdd(CommandInterpreter & interpreter)24230b57cec5SDimitry Andric CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
24240b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "target modules add",
24250b57cec5SDimitry Andric "Add a new module to the current target's modules.",
24269dba64beSDimitry Andric "target modules add [<module>]",
24279dba64beSDimitry Andric eCommandRequiresTarget),
24289dba64beSDimitry Andric m_option_group(), m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's',
24299dba64beSDimitry Andric 0, eArgTypeFilename,
24309dba64beSDimitry Andric "Fullpath to a stand alone debug "
24310b57cec5SDimitry Andric "symbols file for when debug symbols "
24320b57cec5SDimitry Andric "are not in the executable.") {
24330b57cec5SDimitry Andric m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
24340b57cec5SDimitry Andric LLDB_OPT_SET_1);
24350b57cec5SDimitry Andric m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
24360b57cec5SDimitry Andric m_option_group.Finalize();
24370b57cec5SDimitry Andric }
24380b57cec5SDimitry Andric
24390b57cec5SDimitry Andric ~CommandObjectTargetModulesAdd() override = default;
24400b57cec5SDimitry Andric
GetOptions()24410b57cec5SDimitry Andric Options *GetOptions() override { return &m_option_group; }
24420b57cec5SDimitry Andric
24439dba64beSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)24449dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
24450b57cec5SDimitry Andric OptionElementVector &opt_element_vector) override {
24460b57cec5SDimitry Andric CommandCompletions::InvokeCommonCompletionCallbacks(
24470b57cec5SDimitry Andric GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
24480b57cec5SDimitry Andric request, nullptr);
24490b57cec5SDimitry Andric }
24500b57cec5SDimitry Andric
24510b57cec5SDimitry Andric protected:
24520b57cec5SDimitry Andric OptionGroupOptions m_option_group;
24530b57cec5SDimitry Andric OptionGroupUUID m_uuid_option_group;
24540b57cec5SDimitry Andric OptionGroupFile m_symbol_file;
24550b57cec5SDimitry Andric
DoExecute(Args & args,CommandReturnObject & result)24560b57cec5SDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
24579dba64beSDimitry Andric Target *target = &GetSelectedTarget();
24580b57cec5SDimitry Andric bool flush = false;
24590b57cec5SDimitry Andric
24600b57cec5SDimitry Andric const size_t argc = args.GetArgumentCount();
24610b57cec5SDimitry Andric if (argc == 0) {
24620b57cec5SDimitry Andric if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
24630b57cec5SDimitry Andric // We are given a UUID only, go locate the file
24640b57cec5SDimitry Andric ModuleSpec module_spec;
24650b57cec5SDimitry Andric module_spec.GetUUID() =
24660b57cec5SDimitry Andric m_uuid_option_group.GetOptionValue().GetCurrentValue();
24670b57cec5SDimitry Andric if (m_symbol_file.GetOptionValue().OptionWasSet())
24680b57cec5SDimitry Andric module_spec.GetSymbolFileSpec() =
24690b57cec5SDimitry Andric m_symbol_file.GetOptionValue().GetCurrentValue();
24700b57cec5SDimitry Andric if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
24719dba64beSDimitry Andric ModuleSP module_sp(
24729dba64beSDimitry Andric target->GetOrCreateModule(module_spec, true /* notify */));
24730b57cec5SDimitry Andric if (module_sp) {
24740b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
24750b57cec5SDimitry Andric return true;
24760b57cec5SDimitry Andric } else {
24770b57cec5SDimitry Andric StreamString strm;
24780b57cec5SDimitry Andric module_spec.GetUUID().Dump(&strm);
24790b57cec5SDimitry Andric if (module_spec.GetFileSpec()) {
24800b57cec5SDimitry Andric if (module_spec.GetSymbolFileSpec()) {
24810b57cec5SDimitry Andric result.AppendErrorWithFormat(
24820b57cec5SDimitry Andric "Unable to create the executable or symbol file with "
24830b57cec5SDimitry Andric "UUID %s with path %s and symbol file %s",
24849dba64beSDimitry Andric strm.GetData(), module_spec.GetFileSpec().GetPath().c_str(),
24850b57cec5SDimitry Andric module_spec.GetSymbolFileSpec().GetPath().c_str());
24860b57cec5SDimitry Andric } else {
24870b57cec5SDimitry Andric result.AppendErrorWithFormat(
24880b57cec5SDimitry Andric "Unable to create the executable or symbol file with "
24890b57cec5SDimitry Andric "UUID %s with path %s",
24900b57cec5SDimitry Andric strm.GetData(),
24910b57cec5SDimitry Andric module_spec.GetFileSpec().GetPath().c_str());
24920b57cec5SDimitry Andric }
24930b57cec5SDimitry Andric } else {
24940b57cec5SDimitry Andric result.AppendErrorWithFormat("Unable to create the executable "
24950b57cec5SDimitry Andric "or symbol file with UUID %s",
24960b57cec5SDimitry Andric strm.GetData());
24970b57cec5SDimitry Andric }
24980b57cec5SDimitry Andric return false;
24990b57cec5SDimitry Andric }
25000b57cec5SDimitry Andric } else {
25010b57cec5SDimitry Andric StreamString strm;
25020b57cec5SDimitry Andric module_spec.GetUUID().Dump(&strm);
25030b57cec5SDimitry Andric result.AppendErrorWithFormat(
25040b57cec5SDimitry Andric "Unable to locate the executable or symbol file with UUID %s",
25050b57cec5SDimitry Andric strm.GetData());
25060b57cec5SDimitry Andric return false;
25070b57cec5SDimitry Andric }
25080b57cec5SDimitry Andric } else {
25090b57cec5SDimitry Andric result.AppendError(
25100b57cec5SDimitry Andric "one or more executable image paths must be specified");
25110b57cec5SDimitry Andric return false;
25120b57cec5SDimitry Andric }
25130b57cec5SDimitry Andric } else {
25140b57cec5SDimitry Andric for (auto &entry : args.entries()) {
25159dba64beSDimitry Andric if (entry.ref().empty())
25160b57cec5SDimitry Andric continue;
25170b57cec5SDimitry Andric
25189dba64beSDimitry Andric FileSpec file_spec(entry.ref());
25190b57cec5SDimitry Andric if (FileSystem::Instance().Exists(file_spec)) {
25200b57cec5SDimitry Andric ModuleSpec module_spec(file_spec);
25210b57cec5SDimitry Andric if (m_uuid_option_group.GetOptionValue().OptionWasSet())
25220b57cec5SDimitry Andric module_spec.GetUUID() =
25230b57cec5SDimitry Andric m_uuid_option_group.GetOptionValue().GetCurrentValue();
25240b57cec5SDimitry Andric if (m_symbol_file.GetOptionValue().OptionWasSet())
25250b57cec5SDimitry Andric module_spec.GetSymbolFileSpec() =
25260b57cec5SDimitry Andric m_symbol_file.GetOptionValue().GetCurrentValue();
25270b57cec5SDimitry Andric if (!module_spec.GetArchitecture().IsValid())
25280b57cec5SDimitry Andric module_spec.GetArchitecture() = target->GetArchitecture();
25290b57cec5SDimitry Andric Status error;
25309dba64beSDimitry Andric ModuleSP module_sp(target->GetOrCreateModule(
25319dba64beSDimitry Andric module_spec, true /* notify */, &error));
25320b57cec5SDimitry Andric if (!module_sp) {
25330b57cec5SDimitry Andric const char *error_cstr = error.AsCString();
25340b57cec5SDimitry Andric if (error_cstr)
25350b57cec5SDimitry Andric result.AppendError(error_cstr);
25360b57cec5SDimitry Andric else
25370b57cec5SDimitry Andric result.AppendErrorWithFormat("unsupported module: %s",
25380b57cec5SDimitry Andric entry.c_str());
25390b57cec5SDimitry Andric return false;
25400b57cec5SDimitry Andric } else {
25410b57cec5SDimitry Andric flush = true;
25420b57cec5SDimitry Andric }
25430b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
25440b57cec5SDimitry Andric } else {
25450b57cec5SDimitry Andric std::string resolved_path = file_spec.GetPath();
25469dba64beSDimitry Andric if (resolved_path != entry.ref()) {
25470b57cec5SDimitry Andric result.AppendErrorWithFormat(
25480b57cec5SDimitry Andric "invalid module path '%s' with resolved path '%s'\n",
25499dba64beSDimitry Andric entry.ref().str().c_str(), resolved_path.c_str());
25500b57cec5SDimitry Andric break;
25510b57cec5SDimitry Andric }
25520b57cec5SDimitry Andric result.AppendErrorWithFormat("invalid module path '%s'\n",
25530b57cec5SDimitry Andric entry.c_str());
25540b57cec5SDimitry Andric break;
25550b57cec5SDimitry Andric }
25560b57cec5SDimitry Andric }
25570b57cec5SDimitry Andric }
25580b57cec5SDimitry Andric
25590b57cec5SDimitry Andric if (flush) {
25600b57cec5SDimitry Andric ProcessSP process = target->GetProcessSP();
25610b57cec5SDimitry Andric if (process)
25620b57cec5SDimitry Andric process->Flush();
25630b57cec5SDimitry Andric }
25640b57cec5SDimitry Andric
25650b57cec5SDimitry Andric return result.Succeeded();
25660b57cec5SDimitry Andric }
25670b57cec5SDimitry Andric };
25680b57cec5SDimitry Andric
25690b57cec5SDimitry Andric class CommandObjectTargetModulesLoad
25700b57cec5SDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
25710b57cec5SDimitry Andric public:
CommandObjectTargetModulesLoad(CommandInterpreter & interpreter)25720b57cec5SDimitry Andric CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
25730b57cec5SDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
25749dba64beSDimitry Andric interpreter, "target modules load",
25759dba64beSDimitry Andric "Set the load addresses for one or more sections in a target "
25769dba64beSDimitry Andric "module.",
25770b57cec5SDimitry Andric "target modules load [--file <module> --uuid <uuid>] <sect-name> "
25789dba64beSDimitry Andric "<address> [<sect-name> <address> ....]",
25799dba64beSDimitry Andric eCommandRequiresTarget),
25800b57cec5SDimitry Andric m_option_group(),
25810b57cec5SDimitry Andric m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
25820b57cec5SDimitry Andric "Fullpath or basename for module to load.", ""),
25830b57cec5SDimitry Andric m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
25840b57cec5SDimitry Andric "Write file contents to the memory.", false, true),
25850b57cec5SDimitry Andric m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
25860b57cec5SDimitry Andric "Set PC to the entry point."
25870b57cec5SDimitry Andric " Only applicable with '--load' option.",
25880b57cec5SDimitry Andric false, true),
25890b57cec5SDimitry Andric m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
25900b57cec5SDimitry Andric "Set the load address for all sections to be the "
25910b57cec5SDimitry Andric "virtual address in the file plus the offset.",
25920b57cec5SDimitry Andric 0) {
25930b57cec5SDimitry Andric m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
25940b57cec5SDimitry Andric LLDB_OPT_SET_1);
25950b57cec5SDimitry Andric m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
25960b57cec5SDimitry Andric m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
25970b57cec5SDimitry Andric m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
25980b57cec5SDimitry Andric m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
25990b57cec5SDimitry Andric m_option_group.Finalize();
26000b57cec5SDimitry Andric }
26010b57cec5SDimitry Andric
26020b57cec5SDimitry Andric ~CommandObjectTargetModulesLoad() override = default;
26030b57cec5SDimitry Andric
GetOptions()26040b57cec5SDimitry Andric Options *GetOptions() override { return &m_option_group; }
26050b57cec5SDimitry Andric
26060b57cec5SDimitry Andric protected:
DoExecute(Args & args,CommandReturnObject & result)26070b57cec5SDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
26089dba64beSDimitry Andric Target *target = &GetSelectedTarget();
26090b57cec5SDimitry Andric const bool load = m_load_option.GetOptionValue().GetCurrentValue();
26100b57cec5SDimitry Andric const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
26119dba64beSDimitry Andric
26120b57cec5SDimitry Andric const size_t argc = args.GetArgumentCount();
26130b57cec5SDimitry Andric ModuleSpec module_spec;
26140b57cec5SDimitry Andric bool search_using_module_spec = false;
26150b57cec5SDimitry Andric
26160b57cec5SDimitry Andric // Allow "load" option to work without --file or --uuid option.
26170b57cec5SDimitry Andric if (load) {
26180b57cec5SDimitry Andric if (!m_file_option.GetOptionValue().OptionWasSet() &&
26190b57cec5SDimitry Andric !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
26200b57cec5SDimitry Andric ModuleList &module_list = target->GetImages();
26210b57cec5SDimitry Andric if (module_list.GetSize() == 1) {
26220b57cec5SDimitry Andric search_using_module_spec = true;
26230b57cec5SDimitry Andric module_spec.GetFileSpec() =
26240b57cec5SDimitry Andric module_list.GetModuleAtIndex(0)->GetFileSpec();
26250b57cec5SDimitry Andric }
26260b57cec5SDimitry Andric }
26270b57cec5SDimitry Andric }
26280b57cec5SDimitry Andric
26290b57cec5SDimitry Andric if (m_file_option.GetOptionValue().OptionWasSet()) {
26300b57cec5SDimitry Andric search_using_module_spec = true;
26310b57cec5SDimitry Andric const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
26320b57cec5SDimitry Andric const bool use_global_module_list = true;
26330b57cec5SDimitry Andric ModuleList module_list;
26340b57cec5SDimitry Andric const size_t num_matches = FindModulesByName(
26350b57cec5SDimitry Andric target, arg_cstr, module_list, use_global_module_list);
26360b57cec5SDimitry Andric if (num_matches == 1) {
26370b57cec5SDimitry Andric module_spec.GetFileSpec() =
26380b57cec5SDimitry Andric module_list.GetModuleAtIndex(0)->GetFileSpec();
26390b57cec5SDimitry Andric } else if (num_matches > 1) {
26400b57cec5SDimitry Andric search_using_module_spec = false;
26410b57cec5SDimitry Andric result.AppendErrorWithFormat(
26420b57cec5SDimitry Andric "more than 1 module matched by name '%s'\n", arg_cstr);
26430b57cec5SDimitry Andric } else {
26440b57cec5SDimitry Andric search_using_module_spec = false;
26450b57cec5SDimitry Andric result.AppendErrorWithFormat("no object file for module '%s'\n",
26460b57cec5SDimitry Andric arg_cstr);
26470b57cec5SDimitry Andric }
26480b57cec5SDimitry Andric }
26490b57cec5SDimitry Andric
26500b57cec5SDimitry Andric if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
26510b57cec5SDimitry Andric search_using_module_spec = true;
26520b57cec5SDimitry Andric module_spec.GetUUID() =
26530b57cec5SDimitry Andric m_uuid_option_group.GetOptionValue().GetCurrentValue();
26540b57cec5SDimitry Andric }
26550b57cec5SDimitry Andric
26560b57cec5SDimitry Andric if (search_using_module_spec) {
26570b57cec5SDimitry Andric ModuleList matching_modules;
26580b57cec5SDimitry Andric target->GetImages().FindModules(module_spec, matching_modules);
26599dba64beSDimitry Andric const size_t num_matches = matching_modules.GetSize();
26600b57cec5SDimitry Andric
26610b57cec5SDimitry Andric char path[PATH_MAX];
26620b57cec5SDimitry Andric if (num_matches == 1) {
26630b57cec5SDimitry Andric Module *module = matching_modules.GetModulePointerAtIndex(0);
26640b57cec5SDimitry Andric if (module) {
26650b57cec5SDimitry Andric ObjectFile *objfile = module->GetObjectFile();
26660b57cec5SDimitry Andric if (objfile) {
26670b57cec5SDimitry Andric SectionList *section_list = module->GetSectionList();
26680b57cec5SDimitry Andric if (section_list) {
26690b57cec5SDimitry Andric bool changed = false;
26700b57cec5SDimitry Andric if (argc == 0) {
26710b57cec5SDimitry Andric if (m_slide_option.GetOptionValue().OptionWasSet()) {
26720b57cec5SDimitry Andric const addr_t slide =
26730b57cec5SDimitry Andric m_slide_option.GetOptionValue().GetCurrentValue();
26740b57cec5SDimitry Andric const bool slide_is_offset = true;
26750b57cec5SDimitry Andric module->SetLoadAddress(*target, slide, slide_is_offset,
26760b57cec5SDimitry Andric changed);
26770b57cec5SDimitry Andric } else {
26780b57cec5SDimitry Andric result.AppendError("one or more section name + load "
26790b57cec5SDimitry Andric "address pair must be specified");
26800b57cec5SDimitry Andric return false;
26810b57cec5SDimitry Andric }
26820b57cec5SDimitry Andric } else {
26830b57cec5SDimitry Andric if (m_slide_option.GetOptionValue().OptionWasSet()) {
26840b57cec5SDimitry Andric result.AppendError("The \"--slide <offset>\" option can't "
26850b57cec5SDimitry Andric "be used in conjunction with setting "
26860b57cec5SDimitry Andric "section load addresses.\n");
26870b57cec5SDimitry Andric return false;
26880b57cec5SDimitry Andric }
26890b57cec5SDimitry Andric
26900b57cec5SDimitry Andric for (size_t i = 0; i < argc; i += 2) {
26910b57cec5SDimitry Andric const char *sect_name = args.GetArgumentAtIndex(i);
26920b57cec5SDimitry Andric const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
26930b57cec5SDimitry Andric if (sect_name && load_addr_cstr) {
26940b57cec5SDimitry Andric ConstString const_sect_name(sect_name);
26955ffd83dbSDimitry Andric addr_t load_addr;
26965ffd83dbSDimitry Andric if (llvm::to_integer(load_addr_cstr, load_addr)) {
26970b57cec5SDimitry Andric SectionSP section_sp(
26980b57cec5SDimitry Andric section_list->FindSectionByName(const_sect_name));
26990b57cec5SDimitry Andric if (section_sp) {
27000b57cec5SDimitry Andric if (section_sp->IsThreadSpecific()) {
27010b57cec5SDimitry Andric result.AppendErrorWithFormat(
27020b57cec5SDimitry Andric "thread specific sections are not yet "
27030b57cec5SDimitry Andric "supported (section '%s')\n",
27040b57cec5SDimitry Andric sect_name);
27050b57cec5SDimitry Andric break;
27060b57cec5SDimitry Andric } else {
27070b57cec5SDimitry Andric if (target->GetSectionLoadList()
27089dba64beSDimitry Andric .SetSectionLoadAddress(section_sp, load_addr))
27090b57cec5SDimitry Andric changed = true;
27100b57cec5SDimitry Andric result.AppendMessageWithFormat(
27110b57cec5SDimitry Andric "section '%s' loaded at 0x%" PRIx64 "\n",
27120b57cec5SDimitry Andric sect_name, load_addr);
27130b57cec5SDimitry Andric }
27140b57cec5SDimitry Andric } else {
27150b57cec5SDimitry Andric result.AppendErrorWithFormat("no section found that "
27160b57cec5SDimitry Andric "matches the section "
27170b57cec5SDimitry Andric "name '%s'\n",
27180b57cec5SDimitry Andric sect_name);
27190b57cec5SDimitry Andric break;
27200b57cec5SDimitry Andric }
27210b57cec5SDimitry Andric } else {
27220b57cec5SDimitry Andric result.AppendErrorWithFormat(
27239dba64beSDimitry Andric "invalid load address string '%s'\n", load_addr_cstr);
27240b57cec5SDimitry Andric break;
27250b57cec5SDimitry Andric }
27260b57cec5SDimitry Andric } else {
27270b57cec5SDimitry Andric if (sect_name)
27280b57cec5SDimitry Andric result.AppendError("section names must be followed by "
27290b57cec5SDimitry Andric "a load address.\n");
27300b57cec5SDimitry Andric else
27310b57cec5SDimitry Andric result.AppendError("one or more section name + load "
27320b57cec5SDimitry Andric "address pair must be specified.\n");
27330b57cec5SDimitry Andric break;
27340b57cec5SDimitry Andric }
27350b57cec5SDimitry Andric }
27360b57cec5SDimitry Andric }
27370b57cec5SDimitry Andric
27380b57cec5SDimitry Andric if (changed) {
27390b57cec5SDimitry Andric target->ModulesDidLoad(matching_modules);
27400b57cec5SDimitry Andric Process *process = m_exe_ctx.GetProcessPtr();
27410b57cec5SDimitry Andric if (process)
27420b57cec5SDimitry Andric process->Flush();
27430b57cec5SDimitry Andric }
27440b57cec5SDimitry Andric if (load) {
27450b57cec5SDimitry Andric ProcessSP process = target->CalculateProcess();
27460b57cec5SDimitry Andric Address file_entry = objfile->GetEntryPointAddress();
27470b57cec5SDimitry Andric if (!process) {
27480b57cec5SDimitry Andric result.AppendError("No process");
27490b57cec5SDimitry Andric return false;
27500b57cec5SDimitry Andric }
27510b57cec5SDimitry Andric if (set_pc && !file_entry.IsValid()) {
27520b57cec5SDimitry Andric result.AppendError("No entry address in object file");
27530b57cec5SDimitry Andric return false;
27540b57cec5SDimitry Andric }
27550b57cec5SDimitry Andric std::vector<ObjectFile::LoadableData> loadables(
27560b57cec5SDimitry Andric objfile->GetLoadableData(*target));
27570b57cec5SDimitry Andric if (loadables.size() == 0) {
27580b57cec5SDimitry Andric result.AppendError("No loadable sections");
27590b57cec5SDimitry Andric return false;
27600b57cec5SDimitry Andric }
27610b57cec5SDimitry Andric Status error = process->WriteObjectFile(std::move(loadables));
27620b57cec5SDimitry Andric if (error.Fail()) {
27630b57cec5SDimitry Andric result.AppendError(error.AsCString());
27640b57cec5SDimitry Andric return false;
27650b57cec5SDimitry Andric }
27660b57cec5SDimitry Andric if (set_pc) {
27670b57cec5SDimitry Andric ThreadList &thread_list = process->GetThreadList();
27680b57cec5SDimitry Andric RegisterContextSP reg_context(
27690b57cec5SDimitry Andric thread_list.GetSelectedThread()->GetRegisterContext());
27700b57cec5SDimitry Andric addr_t file_entry_addr = file_entry.GetLoadAddress(target);
27710b57cec5SDimitry Andric if (!reg_context->SetPC(file_entry_addr)) {
27720b57cec5SDimitry Andric result.AppendErrorWithFormat("failed to set PC value to "
27730b57cec5SDimitry Andric "0x%" PRIx64 "\n",
27740b57cec5SDimitry Andric file_entry_addr);
27750b57cec5SDimitry Andric }
27760b57cec5SDimitry Andric }
27770b57cec5SDimitry Andric }
27780b57cec5SDimitry Andric } else {
27790b57cec5SDimitry Andric module->GetFileSpec().GetPath(path, sizeof(path));
27809dba64beSDimitry Andric result.AppendErrorWithFormat("no sections in object file '%s'\n",
27819dba64beSDimitry Andric path);
27820b57cec5SDimitry Andric }
27830b57cec5SDimitry Andric } else {
27840b57cec5SDimitry Andric module->GetFileSpec().GetPath(path, sizeof(path));
27850b57cec5SDimitry Andric result.AppendErrorWithFormat("no object file for module '%s'\n",
27860b57cec5SDimitry Andric path);
27870b57cec5SDimitry Andric }
27880b57cec5SDimitry Andric } else {
27890b57cec5SDimitry Andric FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
27900b57cec5SDimitry Andric if (module_spec_file) {
27910b57cec5SDimitry Andric module_spec_file->GetPath(path, sizeof(path));
27920b57cec5SDimitry Andric result.AppendErrorWithFormat("invalid module '%s'.\n", path);
27930b57cec5SDimitry Andric } else
27940b57cec5SDimitry Andric result.AppendError("no module spec");
27950b57cec5SDimitry Andric }
27960b57cec5SDimitry Andric } else {
27970b57cec5SDimitry Andric std::string uuid_str;
27980b57cec5SDimitry Andric
27990b57cec5SDimitry Andric if (module_spec.GetFileSpec())
28000b57cec5SDimitry Andric module_spec.GetFileSpec().GetPath(path, sizeof(path));
28010b57cec5SDimitry Andric else
28020b57cec5SDimitry Andric path[0] = '\0';
28030b57cec5SDimitry Andric
28040b57cec5SDimitry Andric if (module_spec.GetUUIDPtr())
28050b57cec5SDimitry Andric uuid_str = module_spec.GetUUID().GetAsString();
28060b57cec5SDimitry Andric if (num_matches > 1) {
28070b57cec5SDimitry Andric result.AppendErrorWithFormat(
28080b57cec5SDimitry Andric "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
28090b57cec5SDimitry Andric path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
28100b57cec5SDimitry Andric for (size_t i = 0; i < num_matches; ++i) {
28110b57cec5SDimitry Andric if (matching_modules.GetModulePointerAtIndex(i)
28120b57cec5SDimitry Andric ->GetFileSpec()
28130b57cec5SDimitry Andric .GetPath(path, sizeof(path)))
28140b57cec5SDimitry Andric result.AppendMessageWithFormat("%s\n", path);
28150b57cec5SDimitry Andric }
28160b57cec5SDimitry Andric } else {
28170b57cec5SDimitry Andric result.AppendErrorWithFormat(
28180b57cec5SDimitry Andric "no modules were found that match%s%s%s%s.\n",
28199dba64beSDimitry Andric path[0] ? " file=" : "", path, !uuid_str.empty() ? " uuid=" : "",
28209dba64beSDimitry Andric uuid_str.c_str());
28210b57cec5SDimitry Andric }
28220b57cec5SDimitry Andric }
28230b57cec5SDimitry Andric } else {
28240b57cec5SDimitry Andric result.AppendError("either the \"--file <module>\" or the \"--uuid "
28250b57cec5SDimitry Andric "<uuid>\" option must be specified.\n");
28260b57cec5SDimitry Andric return false;
28270b57cec5SDimitry Andric }
28280b57cec5SDimitry Andric return result.Succeeded();
28290b57cec5SDimitry Andric }
28300b57cec5SDimitry Andric
28310b57cec5SDimitry Andric OptionGroupOptions m_option_group;
28320b57cec5SDimitry Andric OptionGroupUUID m_uuid_option_group;
28330b57cec5SDimitry Andric OptionGroupString m_file_option;
28340b57cec5SDimitry Andric OptionGroupBoolean m_load_option;
28350b57cec5SDimitry Andric OptionGroupBoolean m_pc_option;
28360b57cec5SDimitry Andric OptionGroupUInt64 m_slide_option;
28370b57cec5SDimitry Andric };
28380b57cec5SDimitry Andric
28390b57cec5SDimitry Andric // List images with associated information
28409dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_list
28419dba64beSDimitry Andric #include "CommandOptions.inc"
28420b57cec5SDimitry Andric
28430b57cec5SDimitry Andric class CommandObjectTargetModulesList : public CommandObjectParsed {
28440b57cec5SDimitry Andric public:
28450b57cec5SDimitry Andric class CommandOptions : public Options {
28460b57cec5SDimitry Andric public:
CommandOptions()2847*5f7ddb14SDimitry Andric CommandOptions() : Options(), m_format_array() {}
28480b57cec5SDimitry Andric
28490b57cec5SDimitry Andric ~CommandOptions() override = default;
28500b57cec5SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)28510b57cec5SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
28520b57cec5SDimitry Andric ExecutionContext *execution_context) override {
28530b57cec5SDimitry Andric Status error;
28540b57cec5SDimitry Andric
28550b57cec5SDimitry Andric const int short_option = m_getopt_table[option_idx].val;
28560b57cec5SDimitry Andric if (short_option == 'g') {
28570b57cec5SDimitry Andric m_use_global_module_list = true;
28580b57cec5SDimitry Andric } else if (short_option == 'a') {
28590b57cec5SDimitry Andric m_module_addr = OptionArgParser::ToAddress(
28600b57cec5SDimitry Andric execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
28610b57cec5SDimitry Andric } else {
28620b57cec5SDimitry Andric unsigned long width = 0;
28630b57cec5SDimitry Andric option_arg.getAsInteger(0, width);
28640b57cec5SDimitry Andric m_format_array.push_back(std::make_pair(short_option, width));
28650b57cec5SDimitry Andric }
28660b57cec5SDimitry Andric return error;
28670b57cec5SDimitry Andric }
28680b57cec5SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)28690b57cec5SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
28700b57cec5SDimitry Andric m_format_array.clear();
28710b57cec5SDimitry Andric m_use_global_module_list = false;
28720b57cec5SDimitry Andric m_module_addr = LLDB_INVALID_ADDRESS;
28730b57cec5SDimitry Andric }
28740b57cec5SDimitry Andric
GetDefinitions()28750b57cec5SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
28760b57cec5SDimitry Andric return llvm::makeArrayRef(g_target_modules_list_options);
28770b57cec5SDimitry Andric }
28780b57cec5SDimitry Andric
28790b57cec5SDimitry Andric // Instance variables to hold the values for command options.
28800b57cec5SDimitry Andric typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
28810b57cec5SDimitry Andric FormatWidthCollection m_format_array;
2882*5f7ddb14SDimitry Andric bool m_use_global_module_list = false;
2883*5f7ddb14SDimitry Andric lldb::addr_t m_module_addr = LLDB_INVALID_ADDRESS;
28840b57cec5SDimitry Andric };
28850b57cec5SDimitry Andric
CommandObjectTargetModulesList(CommandInterpreter & interpreter)28860b57cec5SDimitry Andric CommandObjectTargetModulesList(CommandInterpreter &interpreter)
28870b57cec5SDimitry Andric : CommandObjectParsed(
28880b57cec5SDimitry Andric interpreter, "target modules list",
28890b57cec5SDimitry Andric "List current executable and dependent shared library images.",
28900b57cec5SDimitry Andric "target modules list [<cmd-options>]"),
28910b57cec5SDimitry Andric m_options() {}
28920b57cec5SDimitry Andric
28930b57cec5SDimitry Andric ~CommandObjectTargetModulesList() override = default;
28940b57cec5SDimitry Andric
GetOptions()28950b57cec5SDimitry Andric Options *GetOptions() override { return &m_options; }
28960b57cec5SDimitry Andric
28970b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)28980b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
28990b57cec5SDimitry Andric Target *target = GetDebugger().GetSelectedTarget().get();
29000b57cec5SDimitry Andric const bool use_global_module_list = m_options.m_use_global_module_list;
29010b57cec5SDimitry Andric // Define a local module list here to ensure it lives longer than any
29020b57cec5SDimitry Andric // "locker" object which might lock its contents below (through the
29030b57cec5SDimitry Andric // "module_list_ptr" variable).
29040b57cec5SDimitry Andric ModuleList module_list;
29050b57cec5SDimitry Andric if (target == nullptr && !use_global_module_list) {
29060b57cec5SDimitry Andric result.AppendError("invalid target, create a debug target using the "
29070b57cec5SDimitry Andric "'target create' command");
29080b57cec5SDimitry Andric return false;
29090b57cec5SDimitry Andric } else {
29100b57cec5SDimitry Andric if (target) {
29110b57cec5SDimitry Andric uint32_t addr_byte_size =
29120b57cec5SDimitry Andric target->GetArchitecture().GetAddressByteSize();
29130b57cec5SDimitry Andric result.GetOutputStream().SetAddressByteSize(addr_byte_size);
29140b57cec5SDimitry Andric result.GetErrorStream().SetAddressByteSize(addr_byte_size);
29150b57cec5SDimitry Andric }
29160b57cec5SDimitry Andric // Dump all sections for all modules images
29170b57cec5SDimitry Andric Stream &strm = result.GetOutputStream();
29180b57cec5SDimitry Andric
29190b57cec5SDimitry Andric if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
29200b57cec5SDimitry Andric if (target) {
29210b57cec5SDimitry Andric Address module_address;
29220b57cec5SDimitry Andric if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
29230b57cec5SDimitry Andric ModuleSP module_sp(module_address.GetModule());
29240b57cec5SDimitry Andric if (module_sp) {
29250b57cec5SDimitry Andric PrintModule(target, module_sp.get(), 0, strm);
29260b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
29270b57cec5SDimitry Andric } else {
29280b57cec5SDimitry Andric result.AppendErrorWithFormat(
29290b57cec5SDimitry Andric "Couldn't find module matching address: 0x%" PRIx64 ".",
29300b57cec5SDimitry Andric m_options.m_module_addr);
29310b57cec5SDimitry Andric }
29320b57cec5SDimitry Andric } else {
29330b57cec5SDimitry Andric result.AppendErrorWithFormat(
29340b57cec5SDimitry Andric "Couldn't find module containing address: 0x%" PRIx64 ".",
29350b57cec5SDimitry Andric m_options.m_module_addr);
29360b57cec5SDimitry Andric }
29370b57cec5SDimitry Andric } else {
29380b57cec5SDimitry Andric result.AppendError(
29390b57cec5SDimitry Andric "Can only look up modules by address with a valid target.");
29400b57cec5SDimitry Andric }
29410b57cec5SDimitry Andric return result.Succeeded();
29420b57cec5SDimitry Andric }
29430b57cec5SDimitry Andric
29440b57cec5SDimitry Andric size_t num_modules = 0;
29450b57cec5SDimitry Andric
29460b57cec5SDimitry Andric // This locker will be locked on the mutex in module_list_ptr if it is
29470b57cec5SDimitry Andric // non-nullptr. Otherwise it will lock the
29480b57cec5SDimitry Andric // AllocationModuleCollectionMutex when accessing the global module list
29490b57cec5SDimitry Andric // directly.
29500b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> guard(
29510b57cec5SDimitry Andric Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
29520b57cec5SDimitry Andric
29530b57cec5SDimitry Andric const ModuleList *module_list_ptr = nullptr;
29540b57cec5SDimitry Andric const size_t argc = command.GetArgumentCount();
29550b57cec5SDimitry Andric if (argc == 0) {
29560b57cec5SDimitry Andric if (use_global_module_list) {
29570b57cec5SDimitry Andric guard.lock();
29580b57cec5SDimitry Andric num_modules = Module::GetNumberAllocatedModules();
29590b57cec5SDimitry Andric } else {
29600b57cec5SDimitry Andric module_list_ptr = &target->GetImages();
29610b57cec5SDimitry Andric }
29620b57cec5SDimitry Andric } else {
29635ffd83dbSDimitry Andric for (const Args::ArgEntry &arg : command) {
29640b57cec5SDimitry Andric // Dump specified images (by basename or fullpath)
29650b57cec5SDimitry Andric const size_t num_matches = FindModulesByName(
29665ffd83dbSDimitry Andric target, arg.c_str(), module_list, use_global_module_list);
29670b57cec5SDimitry Andric if (num_matches == 0) {
29680b57cec5SDimitry Andric if (argc == 1) {
29690b57cec5SDimitry Andric result.AppendErrorWithFormat("no modules found that match '%s'",
29705ffd83dbSDimitry Andric arg.c_str());
29710b57cec5SDimitry Andric return false;
29720b57cec5SDimitry Andric }
29730b57cec5SDimitry Andric }
29740b57cec5SDimitry Andric }
29750b57cec5SDimitry Andric
29760b57cec5SDimitry Andric module_list_ptr = &module_list;
29770b57cec5SDimitry Andric }
29780b57cec5SDimitry Andric
29790b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex> lock;
29800b57cec5SDimitry Andric if (module_list_ptr != nullptr) {
29810b57cec5SDimitry Andric lock =
29820b57cec5SDimitry Andric std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
29830b57cec5SDimitry Andric
29840b57cec5SDimitry Andric num_modules = module_list_ptr->GetSize();
29850b57cec5SDimitry Andric }
29860b57cec5SDimitry Andric
29870b57cec5SDimitry Andric if (num_modules > 0) {
29880b57cec5SDimitry Andric for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
29890b57cec5SDimitry Andric ModuleSP module_sp;
29900b57cec5SDimitry Andric Module *module;
29910b57cec5SDimitry Andric if (module_list_ptr) {
29920b57cec5SDimitry Andric module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
29930b57cec5SDimitry Andric module = module_sp.get();
29940b57cec5SDimitry Andric } else {
29950b57cec5SDimitry Andric module = Module::GetAllocatedModuleAtIndex(image_idx);
29960b57cec5SDimitry Andric module_sp = module->shared_from_this();
29970b57cec5SDimitry Andric }
29980b57cec5SDimitry Andric
29990b57cec5SDimitry Andric const size_t indent = strm.Printf("[%3u] ", image_idx);
30000b57cec5SDimitry Andric PrintModule(target, module, indent, strm);
30010b57cec5SDimitry Andric }
30020b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
30030b57cec5SDimitry Andric } else {
30040b57cec5SDimitry Andric if (argc) {
30050b57cec5SDimitry Andric if (use_global_module_list)
30060b57cec5SDimitry Andric result.AppendError(
30070b57cec5SDimitry Andric "the global module list has no matching modules");
30080b57cec5SDimitry Andric else
30090b57cec5SDimitry Andric result.AppendError("the target has no matching modules");
30100b57cec5SDimitry Andric } else {
30110b57cec5SDimitry Andric if (use_global_module_list)
30120b57cec5SDimitry Andric result.AppendError("the global module list is empty");
30130b57cec5SDimitry Andric else
30140b57cec5SDimitry Andric result.AppendError(
30150b57cec5SDimitry Andric "the target has no associated executable images");
30160b57cec5SDimitry Andric }
30170b57cec5SDimitry Andric return false;
30180b57cec5SDimitry Andric }
30190b57cec5SDimitry Andric }
30200b57cec5SDimitry Andric return result.Succeeded();
30210b57cec5SDimitry Andric }
30220b57cec5SDimitry Andric
PrintModule(Target * target,Module * module,int indent,Stream & strm)30230b57cec5SDimitry Andric void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
30240b57cec5SDimitry Andric if (module == nullptr) {
30250b57cec5SDimitry Andric strm.PutCString("Null module");
30260b57cec5SDimitry Andric return;
30270b57cec5SDimitry Andric }
30280b57cec5SDimitry Andric
30290b57cec5SDimitry Andric bool dump_object_name = false;
30300b57cec5SDimitry Andric if (m_options.m_format_array.empty()) {
30310b57cec5SDimitry Andric m_options.m_format_array.push_back(std::make_pair('u', 0));
30320b57cec5SDimitry Andric m_options.m_format_array.push_back(std::make_pair('h', 0));
30330b57cec5SDimitry Andric m_options.m_format_array.push_back(std::make_pair('f', 0));
30340b57cec5SDimitry Andric m_options.m_format_array.push_back(std::make_pair('S', 0));
30350b57cec5SDimitry Andric }
30360b57cec5SDimitry Andric const size_t num_entries = m_options.m_format_array.size();
30370b57cec5SDimitry Andric bool print_space = false;
30380b57cec5SDimitry Andric for (size_t i = 0; i < num_entries; ++i) {
30390b57cec5SDimitry Andric if (print_space)
30400b57cec5SDimitry Andric strm.PutChar(' ');
30410b57cec5SDimitry Andric print_space = true;
30420b57cec5SDimitry Andric const char format_char = m_options.m_format_array[i].first;
30430b57cec5SDimitry Andric uint32_t width = m_options.m_format_array[i].second;
30440b57cec5SDimitry Andric switch (format_char) {
30450b57cec5SDimitry Andric case 'A':
30460b57cec5SDimitry Andric DumpModuleArchitecture(strm, module, false, width);
30470b57cec5SDimitry Andric break;
30480b57cec5SDimitry Andric
30490b57cec5SDimitry Andric case 't':
30500b57cec5SDimitry Andric DumpModuleArchitecture(strm, module, true, width);
30510b57cec5SDimitry Andric break;
30520b57cec5SDimitry Andric
30530b57cec5SDimitry Andric case 'f':
30540b57cec5SDimitry Andric DumpFullpath(strm, &module->GetFileSpec(), width);
30550b57cec5SDimitry Andric dump_object_name = true;
30560b57cec5SDimitry Andric break;
30570b57cec5SDimitry Andric
30580b57cec5SDimitry Andric case 'd':
30590b57cec5SDimitry Andric DumpDirectory(strm, &module->GetFileSpec(), width);
30600b57cec5SDimitry Andric break;
30610b57cec5SDimitry Andric
30620b57cec5SDimitry Andric case 'b':
30630b57cec5SDimitry Andric DumpBasename(strm, &module->GetFileSpec(), width);
30640b57cec5SDimitry Andric dump_object_name = true;
30650b57cec5SDimitry Andric break;
30660b57cec5SDimitry Andric
30670b57cec5SDimitry Andric case 'h':
30680b57cec5SDimitry Andric case 'o':
30690b57cec5SDimitry Andric // Image header address
30700b57cec5SDimitry Andric {
30710b57cec5SDimitry Andric uint32_t addr_nibble_width =
30720b57cec5SDimitry Andric target ? (target->GetArchitecture().GetAddressByteSize() * 2)
30730b57cec5SDimitry Andric : 16;
30740b57cec5SDimitry Andric
30750b57cec5SDimitry Andric ObjectFile *objfile = module->GetObjectFile();
30760b57cec5SDimitry Andric if (objfile) {
30770b57cec5SDimitry Andric Address base_addr(objfile->GetBaseAddress());
30780b57cec5SDimitry Andric if (base_addr.IsValid()) {
30790b57cec5SDimitry Andric if (target && !target->GetSectionLoadList().IsEmpty()) {
3080480093f4SDimitry Andric lldb::addr_t load_addr = base_addr.GetLoadAddress(target);
30810b57cec5SDimitry Andric if (load_addr == LLDB_INVALID_ADDRESS) {
30820b57cec5SDimitry Andric base_addr.Dump(&strm, target,
30830b57cec5SDimitry Andric Address::DumpStyleModuleWithFileAddress,
30840b57cec5SDimitry Andric Address::DumpStyleFileAddress);
30850b57cec5SDimitry Andric } else {
30860b57cec5SDimitry Andric if (format_char == 'o') {
30870b57cec5SDimitry Andric // Show the offset of slide for the image
3088480093f4SDimitry Andric strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3089480093f4SDimitry Andric addr_nibble_width,
30900b57cec5SDimitry Andric load_addr - base_addr.GetFileAddress());
30910b57cec5SDimitry Andric } else {
30920b57cec5SDimitry Andric // Show the load address of the image
30930b57cec5SDimitry Andric strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
30940b57cec5SDimitry Andric addr_nibble_width, load_addr);
30950b57cec5SDimitry Andric }
30960b57cec5SDimitry Andric }
30970b57cec5SDimitry Andric break;
30980b57cec5SDimitry Andric }
30990b57cec5SDimitry Andric // The address was valid, but the image isn't loaded, output the
31000b57cec5SDimitry Andric // address in an appropriate format
31010b57cec5SDimitry Andric base_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
31020b57cec5SDimitry Andric break;
31030b57cec5SDimitry Andric }
31040b57cec5SDimitry Andric }
31050b57cec5SDimitry Andric strm.Printf("%*s", addr_nibble_width + 2, "");
31060b57cec5SDimitry Andric }
31070b57cec5SDimitry Andric break;
31080b57cec5SDimitry Andric
31090b57cec5SDimitry Andric case 'r': {
31100b57cec5SDimitry Andric size_t ref_count = 0;
31110b57cec5SDimitry Andric ModuleSP module_sp(module->shared_from_this());
31120b57cec5SDimitry Andric if (module_sp) {
31130b57cec5SDimitry Andric // Take one away to make sure we don't count our local "module_sp"
31140b57cec5SDimitry Andric ref_count = module_sp.use_count() - 1;
31150b57cec5SDimitry Andric }
31160b57cec5SDimitry Andric if (width)
31170b57cec5SDimitry Andric strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
31180b57cec5SDimitry Andric else
31190b57cec5SDimitry Andric strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
31200b57cec5SDimitry Andric } break;
31210b57cec5SDimitry Andric
31220b57cec5SDimitry Andric case 's':
31230b57cec5SDimitry Andric case 'S': {
31249dba64beSDimitry Andric if (const SymbolFile *symbol_file = module->GetSymbolFile()) {
31259dba64beSDimitry Andric const FileSpec symfile_spec =
31269dba64beSDimitry Andric symbol_file->GetObjectFile()->GetFileSpec();
31270b57cec5SDimitry Andric if (format_char == 'S') {
31280b57cec5SDimitry Andric // Dump symbol file only if different from module file
31290b57cec5SDimitry Andric if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
31300b57cec5SDimitry Andric print_space = false;
31310b57cec5SDimitry Andric break;
31320b57cec5SDimitry Andric }
31330b57cec5SDimitry Andric // Add a newline and indent past the index
31340b57cec5SDimitry Andric strm.Printf("\n%*s", indent, "");
31350b57cec5SDimitry Andric }
31360b57cec5SDimitry Andric DumpFullpath(strm, &symfile_spec, width);
31370b57cec5SDimitry Andric dump_object_name = true;
31380b57cec5SDimitry Andric break;
31390b57cec5SDimitry Andric }
31400b57cec5SDimitry Andric strm.Printf("%.*s", width, "<NONE>");
31410b57cec5SDimitry Andric } break;
31420b57cec5SDimitry Andric
31430b57cec5SDimitry Andric case 'm':
31440b57cec5SDimitry Andric strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
31450b57cec5SDimitry Andric llvm::AlignStyle::Left, width));
31460b57cec5SDimitry Andric break;
31470b57cec5SDimitry Andric
31480b57cec5SDimitry Andric case 'p':
31490b57cec5SDimitry Andric strm.Printf("%p", static_cast<void *>(module));
31500b57cec5SDimitry Andric break;
31510b57cec5SDimitry Andric
31520b57cec5SDimitry Andric case 'u':
31530b57cec5SDimitry Andric DumpModuleUUID(strm, module);
31540b57cec5SDimitry Andric break;
31550b57cec5SDimitry Andric
31560b57cec5SDimitry Andric default:
31570b57cec5SDimitry Andric break;
31580b57cec5SDimitry Andric }
31590b57cec5SDimitry Andric }
31600b57cec5SDimitry Andric if (dump_object_name) {
31610b57cec5SDimitry Andric const char *object_name = module->GetObjectName().GetCString();
31620b57cec5SDimitry Andric if (object_name)
31630b57cec5SDimitry Andric strm.Printf("(%s)", object_name);
31640b57cec5SDimitry Andric }
31650b57cec5SDimitry Andric strm.EOL();
31660b57cec5SDimitry Andric }
31670b57cec5SDimitry Andric
31680b57cec5SDimitry Andric CommandOptions m_options;
31690b57cec5SDimitry Andric };
31700b57cec5SDimitry Andric
31710b57cec5SDimitry Andric #pragma mark CommandObjectTargetModulesShowUnwind
31720b57cec5SDimitry Andric
31730b57cec5SDimitry Andric // Lookup unwind information in images
31749dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_show_unwind
31759dba64beSDimitry Andric #include "CommandOptions.inc"
31760b57cec5SDimitry Andric
31770b57cec5SDimitry Andric class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
31780b57cec5SDimitry Andric public:
31790b57cec5SDimitry Andric enum {
31800b57cec5SDimitry Andric eLookupTypeInvalid = -1,
31810b57cec5SDimitry Andric eLookupTypeAddress = 0,
31820b57cec5SDimitry Andric eLookupTypeSymbol,
31830b57cec5SDimitry Andric eLookupTypeFunction,
31840b57cec5SDimitry Andric eLookupTypeFunctionOrSymbol,
31850b57cec5SDimitry Andric kNumLookupTypes
31860b57cec5SDimitry Andric };
31870b57cec5SDimitry Andric
31880b57cec5SDimitry Andric class CommandOptions : public Options {
31890b57cec5SDimitry Andric public:
CommandOptions()3190*5f7ddb14SDimitry Andric CommandOptions() : Options(), m_str() {}
31910b57cec5SDimitry Andric
31920b57cec5SDimitry Andric ~CommandOptions() override = default;
31930b57cec5SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)31940b57cec5SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
31950b57cec5SDimitry Andric ExecutionContext *execution_context) override {
31960b57cec5SDimitry Andric Status error;
31970b57cec5SDimitry Andric
31980b57cec5SDimitry Andric const int short_option = m_getopt_table[option_idx].val;
31990b57cec5SDimitry Andric
32000b57cec5SDimitry Andric switch (short_option) {
32010b57cec5SDimitry Andric case 'a': {
32025ffd83dbSDimitry Andric m_str = std::string(option_arg);
32030b57cec5SDimitry Andric m_type = eLookupTypeAddress;
32040b57cec5SDimitry Andric m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
32050b57cec5SDimitry Andric LLDB_INVALID_ADDRESS, &error);
32060b57cec5SDimitry Andric if (m_addr == LLDB_INVALID_ADDRESS)
32070b57cec5SDimitry Andric error.SetErrorStringWithFormat("invalid address string '%s'",
32080b57cec5SDimitry Andric option_arg.str().c_str());
32090b57cec5SDimitry Andric break;
32100b57cec5SDimitry Andric }
32110b57cec5SDimitry Andric
32120b57cec5SDimitry Andric case 'n':
32135ffd83dbSDimitry Andric m_str = std::string(option_arg);
32140b57cec5SDimitry Andric m_type = eLookupTypeFunctionOrSymbol;
32150b57cec5SDimitry Andric break;
32160b57cec5SDimitry Andric
32170b57cec5SDimitry Andric default:
32189dba64beSDimitry Andric llvm_unreachable("Unimplemented option");
32190b57cec5SDimitry Andric }
32200b57cec5SDimitry Andric
32210b57cec5SDimitry Andric return error;
32220b57cec5SDimitry Andric }
32230b57cec5SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)32240b57cec5SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
32250b57cec5SDimitry Andric m_type = eLookupTypeInvalid;
32260b57cec5SDimitry Andric m_str.clear();
32270b57cec5SDimitry Andric m_addr = LLDB_INVALID_ADDRESS;
32280b57cec5SDimitry Andric }
32290b57cec5SDimitry Andric
GetDefinitions()32300b57cec5SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
32310b57cec5SDimitry Andric return llvm::makeArrayRef(g_target_modules_show_unwind_options);
32320b57cec5SDimitry Andric }
32330b57cec5SDimitry Andric
32340b57cec5SDimitry Andric // Instance variables to hold the values for command options.
32350b57cec5SDimitry Andric
3236*5f7ddb14SDimitry Andric int m_type = eLookupTypeInvalid; // Should be a eLookupTypeXXX enum after
3237*5f7ddb14SDimitry Andric // parsing options
32380b57cec5SDimitry Andric std::string m_str; // Holds name lookup
3239*5f7ddb14SDimitry Andric lldb::addr_t m_addr = LLDB_INVALID_ADDRESS; // Holds the address to lookup
32400b57cec5SDimitry Andric };
32410b57cec5SDimitry Andric
CommandObjectTargetModulesShowUnwind(CommandInterpreter & interpreter)32420b57cec5SDimitry Andric CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
32430b57cec5SDimitry Andric : CommandObjectParsed(
32440b57cec5SDimitry Andric interpreter, "target modules show-unwind",
32450b57cec5SDimitry Andric "Show synthesized unwind instructions for a function.", nullptr,
32460b57cec5SDimitry Andric eCommandRequiresTarget | eCommandRequiresProcess |
32470b57cec5SDimitry Andric eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
32480b57cec5SDimitry Andric m_options() {}
32490b57cec5SDimitry Andric
32500b57cec5SDimitry Andric ~CommandObjectTargetModulesShowUnwind() override = default;
32510b57cec5SDimitry Andric
GetOptions()32520b57cec5SDimitry Andric Options *GetOptions() override { return &m_options; }
32530b57cec5SDimitry Andric
32540b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)32550b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
32560b57cec5SDimitry Andric Target *target = m_exe_ctx.GetTargetPtr();
32570b57cec5SDimitry Andric Process *process = m_exe_ctx.GetProcessPtr();
32580b57cec5SDimitry Andric ABI *abi = nullptr;
32590b57cec5SDimitry Andric if (process)
32600b57cec5SDimitry Andric abi = process->GetABI().get();
32610b57cec5SDimitry Andric
32620b57cec5SDimitry Andric if (process == nullptr) {
32630b57cec5SDimitry Andric result.AppendError(
32640b57cec5SDimitry Andric "You must have a process running to use this command.");
32650b57cec5SDimitry Andric return false;
32660b57cec5SDimitry Andric }
32670b57cec5SDimitry Andric
32680b57cec5SDimitry Andric ThreadList threads(process->GetThreadList());
32690b57cec5SDimitry Andric if (threads.GetSize() == 0) {
32700b57cec5SDimitry Andric result.AppendError("The process must be paused to use this command.");
32710b57cec5SDimitry Andric return false;
32720b57cec5SDimitry Andric }
32730b57cec5SDimitry Andric
32740b57cec5SDimitry Andric ThreadSP thread(threads.GetThreadAtIndex(0));
32750b57cec5SDimitry Andric if (!thread) {
32760b57cec5SDimitry Andric result.AppendError("The process must be paused to use this command.");
32770b57cec5SDimitry Andric return false;
32780b57cec5SDimitry Andric }
32790b57cec5SDimitry Andric
32800b57cec5SDimitry Andric SymbolContextList sc_list;
32810b57cec5SDimitry Andric
32820b57cec5SDimitry Andric if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
32830b57cec5SDimitry Andric ConstString function_name(m_options.m_str.c_str());
32840b57cec5SDimitry Andric target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
32859dba64beSDimitry Andric true, false, sc_list);
32860b57cec5SDimitry Andric } else if (m_options.m_type == eLookupTypeAddress && target) {
32870b57cec5SDimitry Andric Address addr;
32880b57cec5SDimitry Andric if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
32890b57cec5SDimitry Andric addr)) {
32900b57cec5SDimitry Andric SymbolContext sc;
32910b57cec5SDimitry Andric ModuleSP module_sp(addr.GetModule());
32920b57cec5SDimitry Andric module_sp->ResolveSymbolContextForAddress(addr,
32930b57cec5SDimitry Andric eSymbolContextEverything, sc);
32940b57cec5SDimitry Andric if (sc.function || sc.symbol) {
32950b57cec5SDimitry Andric sc_list.Append(sc);
32960b57cec5SDimitry Andric }
32970b57cec5SDimitry Andric }
32980b57cec5SDimitry Andric } else {
32990b57cec5SDimitry Andric result.AppendError(
33000b57cec5SDimitry Andric "address-expression or function name option must be specified.");
33010b57cec5SDimitry Andric return false;
33020b57cec5SDimitry Andric }
33030b57cec5SDimitry Andric
33040b57cec5SDimitry Andric size_t num_matches = sc_list.GetSize();
33050b57cec5SDimitry Andric if (num_matches == 0) {
33060b57cec5SDimitry Andric result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
33070b57cec5SDimitry Andric m_options.m_str.c_str());
33080b57cec5SDimitry Andric return false;
33090b57cec5SDimitry Andric }
33100b57cec5SDimitry Andric
33110b57cec5SDimitry Andric for (uint32_t idx = 0; idx < num_matches; idx++) {
33120b57cec5SDimitry Andric SymbolContext sc;
33130b57cec5SDimitry Andric sc_list.GetContextAtIndex(idx, sc);
33140b57cec5SDimitry Andric if (sc.symbol == nullptr && sc.function == nullptr)
33150b57cec5SDimitry Andric continue;
33160b57cec5SDimitry Andric if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
33170b57cec5SDimitry Andric continue;
33180b57cec5SDimitry Andric AddressRange range;
33190b57cec5SDimitry Andric if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
33200b57cec5SDimitry Andric false, range))
33210b57cec5SDimitry Andric continue;
33220b57cec5SDimitry Andric if (!range.GetBaseAddress().IsValid())
33230b57cec5SDimitry Andric continue;
33240b57cec5SDimitry Andric ConstString funcname(sc.GetFunctionName());
33250b57cec5SDimitry Andric if (funcname.IsEmpty())
33260b57cec5SDimitry Andric continue;
33270b57cec5SDimitry Andric addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
33280b57cec5SDimitry Andric if (abi)
33290b57cec5SDimitry Andric start_addr = abi->FixCodeAddress(start_addr);
33300b57cec5SDimitry Andric
33310b57cec5SDimitry Andric FuncUnwindersSP func_unwinders_sp(
33320b57cec5SDimitry Andric sc.module_sp->GetUnwindTable()
33330b57cec5SDimitry Andric .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
33340b57cec5SDimitry Andric if (!func_unwinders_sp)
33350b57cec5SDimitry Andric continue;
33360b57cec5SDimitry Andric
33370b57cec5SDimitry Andric result.GetOutputStream().Printf(
3338af732203SDimitry Andric "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n",
33390b57cec5SDimitry Andric sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
33400b57cec5SDimitry Andric funcname.AsCString(), start_addr);
33410b57cec5SDimitry Andric
3342af732203SDimitry Andric Args args;
3343af732203SDimitry Andric target->GetUserSpecifiedTrapHandlerNames(args);
3344af732203SDimitry Andric size_t count = args.GetArgumentCount();
3345af732203SDimitry Andric for (size_t i = 0; i < count; i++) {
3346af732203SDimitry Andric const char *trap_func_name = args.GetArgumentAtIndex(i);
3347af732203SDimitry Andric if (strcmp(funcname.GetCString(), trap_func_name) == 0)
3348af732203SDimitry Andric result.GetOutputStream().Printf(
3349af732203SDimitry Andric "This function is "
3350af732203SDimitry Andric "treated as a trap handler function via user setting.\n");
3351af732203SDimitry Andric }
3352af732203SDimitry Andric PlatformSP platform_sp(target->GetPlatform());
3353af732203SDimitry Andric if (platform_sp) {
3354af732203SDimitry Andric const std::vector<ConstString> trap_handler_names(
3355af732203SDimitry Andric platform_sp->GetTrapHandlerSymbolNames());
3356af732203SDimitry Andric for (ConstString trap_name : trap_handler_names) {
3357af732203SDimitry Andric if (trap_name == funcname) {
3358af732203SDimitry Andric result.GetOutputStream().Printf(
3359af732203SDimitry Andric "This function's "
3360af732203SDimitry Andric "name is listed by the platform as a trap handler.\n");
3361af732203SDimitry Andric }
3362af732203SDimitry Andric }
3363af732203SDimitry Andric }
3364af732203SDimitry Andric
3365af732203SDimitry Andric result.GetOutputStream().Printf("\n");
3366af732203SDimitry Andric
33670b57cec5SDimitry Andric UnwindPlanSP non_callsite_unwind_plan =
33680b57cec5SDimitry Andric func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread);
33690b57cec5SDimitry Andric if (non_callsite_unwind_plan) {
33700b57cec5SDimitry Andric result.GetOutputStream().Printf(
33710b57cec5SDimitry Andric "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
33720b57cec5SDimitry Andric non_callsite_unwind_plan->GetSourceName().AsCString());
33730b57cec5SDimitry Andric }
33740b57cec5SDimitry Andric UnwindPlanSP callsite_unwind_plan =
33750b57cec5SDimitry Andric func_unwinders_sp->GetUnwindPlanAtCallSite(*target, *thread);
33760b57cec5SDimitry Andric if (callsite_unwind_plan) {
33770b57cec5SDimitry Andric result.GetOutputStream().Printf(
33780b57cec5SDimitry Andric "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
33790b57cec5SDimitry Andric callsite_unwind_plan->GetSourceName().AsCString());
33800b57cec5SDimitry Andric }
33810b57cec5SDimitry Andric UnwindPlanSP fast_unwind_plan =
33820b57cec5SDimitry Andric func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
33830b57cec5SDimitry Andric if (fast_unwind_plan) {
33840b57cec5SDimitry Andric result.GetOutputStream().Printf(
33850b57cec5SDimitry Andric "Fast UnwindPlan is '%s'\n",
33860b57cec5SDimitry Andric fast_unwind_plan->GetSourceName().AsCString());
33870b57cec5SDimitry Andric }
33880b57cec5SDimitry Andric
33890b57cec5SDimitry Andric result.GetOutputStream().Printf("\n");
33900b57cec5SDimitry Andric
33910b57cec5SDimitry Andric UnwindPlanSP assembly_sp =
33920b57cec5SDimitry Andric func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread);
33930b57cec5SDimitry Andric if (assembly_sp) {
33940b57cec5SDimitry Andric result.GetOutputStream().Printf(
33950b57cec5SDimitry Andric "Assembly language inspection UnwindPlan:\n");
33960b57cec5SDimitry Andric assembly_sp->Dump(result.GetOutputStream(), thread.get(),
33970b57cec5SDimitry Andric LLDB_INVALID_ADDRESS);
33980b57cec5SDimitry Andric result.GetOutputStream().Printf("\n");
33990b57cec5SDimitry Andric }
34000b57cec5SDimitry Andric
34019dba64beSDimitry Andric UnwindPlanSP of_unwind_sp =
34029dba64beSDimitry Andric func_unwinders_sp->GetObjectFileUnwindPlan(*target);
34039dba64beSDimitry Andric if (of_unwind_sp) {
34049dba64beSDimitry Andric result.GetOutputStream().Printf("object file UnwindPlan:\n");
34059dba64beSDimitry Andric of_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
34069dba64beSDimitry Andric LLDB_INVALID_ADDRESS);
34079dba64beSDimitry Andric result.GetOutputStream().Printf("\n");
34089dba64beSDimitry Andric }
34099dba64beSDimitry Andric
34109dba64beSDimitry Andric UnwindPlanSP of_unwind_augmented_sp =
3411480093f4SDimitry Andric func_unwinders_sp->GetObjectFileAugmentedUnwindPlan(*target, *thread);
34129dba64beSDimitry Andric if (of_unwind_augmented_sp) {
34139dba64beSDimitry Andric result.GetOutputStream().Printf("object file augmented UnwindPlan:\n");
34149dba64beSDimitry Andric of_unwind_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
34159dba64beSDimitry Andric LLDB_INVALID_ADDRESS);
34169dba64beSDimitry Andric result.GetOutputStream().Printf("\n");
34179dba64beSDimitry Andric }
34189dba64beSDimitry Andric
34190b57cec5SDimitry Andric UnwindPlanSP ehframe_sp =
34200b57cec5SDimitry Andric func_unwinders_sp->GetEHFrameUnwindPlan(*target);
34210b57cec5SDimitry Andric if (ehframe_sp) {
34220b57cec5SDimitry Andric result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
34230b57cec5SDimitry Andric ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
34240b57cec5SDimitry Andric LLDB_INVALID_ADDRESS);
34250b57cec5SDimitry Andric result.GetOutputStream().Printf("\n");
34260b57cec5SDimitry Andric }
34270b57cec5SDimitry Andric
34280b57cec5SDimitry Andric UnwindPlanSP ehframe_augmented_sp =
34290b57cec5SDimitry Andric func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread);
34300b57cec5SDimitry Andric if (ehframe_augmented_sp) {
34310b57cec5SDimitry Andric result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
34320b57cec5SDimitry Andric ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
34330b57cec5SDimitry Andric LLDB_INVALID_ADDRESS);
34340b57cec5SDimitry Andric result.GetOutputStream().Printf("\n");
34350b57cec5SDimitry Andric }
34360b57cec5SDimitry Andric
34370b57cec5SDimitry Andric if (UnwindPlanSP plan_sp =
34380b57cec5SDimitry Andric func_unwinders_sp->GetDebugFrameUnwindPlan(*target)) {
34390b57cec5SDimitry Andric result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
34400b57cec5SDimitry Andric plan_sp->Dump(result.GetOutputStream(), thread.get(),
34410b57cec5SDimitry Andric LLDB_INVALID_ADDRESS);
34420b57cec5SDimitry Andric result.GetOutputStream().Printf("\n");
34430b57cec5SDimitry Andric }
34440b57cec5SDimitry Andric
34450b57cec5SDimitry Andric if (UnwindPlanSP plan_sp =
34460b57cec5SDimitry Andric func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
34470b57cec5SDimitry Andric *thread)) {
34480b57cec5SDimitry Andric result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
34490b57cec5SDimitry Andric plan_sp->Dump(result.GetOutputStream(), thread.get(),
34500b57cec5SDimitry Andric LLDB_INVALID_ADDRESS);
34510b57cec5SDimitry Andric result.GetOutputStream().Printf("\n");
34520b57cec5SDimitry Andric }
34530b57cec5SDimitry Andric
34540b57cec5SDimitry Andric UnwindPlanSP arm_unwind_sp =
34550b57cec5SDimitry Andric func_unwinders_sp->GetArmUnwindUnwindPlan(*target);
34560b57cec5SDimitry Andric if (arm_unwind_sp) {
34570b57cec5SDimitry Andric result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
34580b57cec5SDimitry Andric arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
34590b57cec5SDimitry Andric LLDB_INVALID_ADDRESS);
34600b57cec5SDimitry Andric result.GetOutputStream().Printf("\n");
34610b57cec5SDimitry Andric }
34620b57cec5SDimitry Andric
34630b57cec5SDimitry Andric if (UnwindPlanSP symfile_plan_sp =
34640b57cec5SDimitry Andric func_unwinders_sp->GetSymbolFileUnwindPlan(*thread)) {
34650b57cec5SDimitry Andric result.GetOutputStream().Printf("Symbol file UnwindPlan:\n");
34660b57cec5SDimitry Andric symfile_plan_sp->Dump(result.GetOutputStream(), thread.get(),
34670b57cec5SDimitry Andric LLDB_INVALID_ADDRESS);
34680b57cec5SDimitry Andric result.GetOutputStream().Printf("\n");
34690b57cec5SDimitry Andric }
34700b57cec5SDimitry Andric
34710b57cec5SDimitry Andric UnwindPlanSP compact_unwind_sp =
34720b57cec5SDimitry Andric func_unwinders_sp->GetCompactUnwindUnwindPlan(*target);
34730b57cec5SDimitry Andric if (compact_unwind_sp) {
34740b57cec5SDimitry Andric result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
34750b57cec5SDimitry Andric compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
34760b57cec5SDimitry Andric LLDB_INVALID_ADDRESS);
34770b57cec5SDimitry Andric result.GetOutputStream().Printf("\n");
34780b57cec5SDimitry Andric }
34790b57cec5SDimitry Andric
34800b57cec5SDimitry Andric if (fast_unwind_plan) {
34810b57cec5SDimitry Andric result.GetOutputStream().Printf("Fast UnwindPlan:\n");
34820b57cec5SDimitry Andric fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
34830b57cec5SDimitry Andric LLDB_INVALID_ADDRESS);
34840b57cec5SDimitry Andric result.GetOutputStream().Printf("\n");
34850b57cec5SDimitry Andric }
34860b57cec5SDimitry Andric
34870b57cec5SDimitry Andric ABISP abi_sp = process->GetABI();
34880b57cec5SDimitry Andric if (abi_sp) {
34890b57cec5SDimitry Andric UnwindPlan arch_default(lldb::eRegisterKindGeneric);
34900b57cec5SDimitry Andric if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
34910b57cec5SDimitry Andric result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
34920b57cec5SDimitry Andric arch_default.Dump(result.GetOutputStream(), thread.get(),
34930b57cec5SDimitry Andric LLDB_INVALID_ADDRESS);
34940b57cec5SDimitry Andric result.GetOutputStream().Printf("\n");
34950b57cec5SDimitry Andric }
34960b57cec5SDimitry Andric
34970b57cec5SDimitry Andric UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
34980b57cec5SDimitry Andric if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
34990b57cec5SDimitry Andric result.GetOutputStream().Printf(
35000b57cec5SDimitry Andric "Arch default at entry point UnwindPlan:\n");
35010b57cec5SDimitry Andric arch_entry.Dump(result.GetOutputStream(), thread.get(),
35020b57cec5SDimitry Andric LLDB_INVALID_ADDRESS);
35030b57cec5SDimitry Andric result.GetOutputStream().Printf("\n");
35040b57cec5SDimitry Andric }
35050b57cec5SDimitry Andric }
35060b57cec5SDimitry Andric
35070b57cec5SDimitry Andric result.GetOutputStream().Printf("\n");
35080b57cec5SDimitry Andric }
35090b57cec5SDimitry Andric return result.Succeeded();
35100b57cec5SDimitry Andric }
35110b57cec5SDimitry Andric
35120b57cec5SDimitry Andric CommandOptions m_options;
35130b57cec5SDimitry Andric };
35140b57cec5SDimitry Andric
35150b57cec5SDimitry Andric // Lookup information in images
35169dba64beSDimitry Andric #define LLDB_OPTIONS_target_modules_lookup
35179dba64beSDimitry Andric #include "CommandOptions.inc"
35180b57cec5SDimitry Andric
35190b57cec5SDimitry Andric class CommandObjectTargetModulesLookup : public CommandObjectParsed {
35200b57cec5SDimitry Andric public:
35210b57cec5SDimitry Andric enum {
35220b57cec5SDimitry Andric eLookupTypeInvalid = -1,
35230b57cec5SDimitry Andric eLookupTypeAddress = 0,
35240b57cec5SDimitry Andric eLookupTypeSymbol,
35250b57cec5SDimitry Andric eLookupTypeFileLine, // Line is optional
35260b57cec5SDimitry Andric eLookupTypeFunction,
35270b57cec5SDimitry Andric eLookupTypeFunctionOrSymbol,
35280b57cec5SDimitry Andric eLookupTypeType,
35290b57cec5SDimitry Andric kNumLookupTypes
35300b57cec5SDimitry Andric };
35310b57cec5SDimitry Andric
35320b57cec5SDimitry Andric class CommandOptions : public Options {
35330b57cec5SDimitry Andric public:
CommandOptions()35340b57cec5SDimitry Andric CommandOptions() : Options() { OptionParsingStarting(nullptr); }
35350b57cec5SDimitry Andric
35360b57cec5SDimitry Andric ~CommandOptions() override = default;
35370b57cec5SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)35380b57cec5SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
35390b57cec5SDimitry Andric ExecutionContext *execution_context) override {
35400b57cec5SDimitry Andric Status error;
35410b57cec5SDimitry Andric
35420b57cec5SDimitry Andric const int short_option = m_getopt_table[option_idx].val;
35430b57cec5SDimitry Andric
35440b57cec5SDimitry Andric switch (short_option) {
35450b57cec5SDimitry Andric case 'a': {
35460b57cec5SDimitry Andric m_type = eLookupTypeAddress;
35470b57cec5SDimitry Andric m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
35480b57cec5SDimitry Andric LLDB_INVALID_ADDRESS, &error);
35490b57cec5SDimitry Andric } break;
35500b57cec5SDimitry Andric
35510b57cec5SDimitry Andric case 'o':
35520b57cec5SDimitry Andric if (option_arg.getAsInteger(0, m_offset))
35530b57cec5SDimitry Andric error.SetErrorStringWithFormat("invalid offset string '%s'",
35540b57cec5SDimitry Andric option_arg.str().c_str());
35550b57cec5SDimitry Andric break;
35560b57cec5SDimitry Andric
35570b57cec5SDimitry Andric case 's':
35585ffd83dbSDimitry Andric m_str = std::string(option_arg);
35590b57cec5SDimitry Andric m_type = eLookupTypeSymbol;
35600b57cec5SDimitry Andric break;
35610b57cec5SDimitry Andric
35620b57cec5SDimitry Andric case 'f':
35630b57cec5SDimitry Andric m_file.SetFile(option_arg, FileSpec::Style::native);
35640b57cec5SDimitry Andric m_type = eLookupTypeFileLine;
35650b57cec5SDimitry Andric break;
35660b57cec5SDimitry Andric
35670b57cec5SDimitry Andric case 'i':
35680b57cec5SDimitry Andric m_include_inlines = false;
35690b57cec5SDimitry Andric break;
35700b57cec5SDimitry Andric
35710b57cec5SDimitry Andric case 'l':
35720b57cec5SDimitry Andric if (option_arg.getAsInteger(0, m_line_number))
35730b57cec5SDimitry Andric error.SetErrorStringWithFormat("invalid line number string '%s'",
35740b57cec5SDimitry Andric option_arg.str().c_str());
35750b57cec5SDimitry Andric else if (m_line_number == 0)
35760b57cec5SDimitry Andric error.SetErrorString("zero is an invalid line number");
35770b57cec5SDimitry Andric m_type = eLookupTypeFileLine;
35780b57cec5SDimitry Andric break;
35790b57cec5SDimitry Andric
35800b57cec5SDimitry Andric case 'F':
35815ffd83dbSDimitry Andric m_str = std::string(option_arg);
35820b57cec5SDimitry Andric m_type = eLookupTypeFunction;
35830b57cec5SDimitry Andric break;
35840b57cec5SDimitry Andric
35850b57cec5SDimitry Andric case 'n':
35865ffd83dbSDimitry Andric m_str = std::string(option_arg);
35870b57cec5SDimitry Andric m_type = eLookupTypeFunctionOrSymbol;
35880b57cec5SDimitry Andric break;
35890b57cec5SDimitry Andric
35900b57cec5SDimitry Andric case 't':
35915ffd83dbSDimitry Andric m_str = std::string(option_arg);
35920b57cec5SDimitry Andric m_type = eLookupTypeType;
35930b57cec5SDimitry Andric break;
35940b57cec5SDimitry Andric
35950b57cec5SDimitry Andric case 'v':
35960b57cec5SDimitry Andric m_verbose = true;
35970b57cec5SDimitry Andric break;
35980b57cec5SDimitry Andric
35990b57cec5SDimitry Andric case 'A':
36000b57cec5SDimitry Andric m_print_all = true;
36010b57cec5SDimitry Andric break;
36020b57cec5SDimitry Andric
36030b57cec5SDimitry Andric case 'r':
36040b57cec5SDimitry Andric m_use_regex = true;
36050b57cec5SDimitry Andric break;
36069dba64beSDimitry Andric default:
36079dba64beSDimitry Andric llvm_unreachable("Unimplemented option");
36080b57cec5SDimitry Andric }
36090b57cec5SDimitry Andric
36100b57cec5SDimitry Andric return error;
36110b57cec5SDimitry Andric }
36120b57cec5SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)36130b57cec5SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
36140b57cec5SDimitry Andric m_type = eLookupTypeInvalid;
36150b57cec5SDimitry Andric m_str.clear();
36160b57cec5SDimitry Andric m_file.Clear();
36170b57cec5SDimitry Andric m_addr = LLDB_INVALID_ADDRESS;
36180b57cec5SDimitry Andric m_offset = 0;
36190b57cec5SDimitry Andric m_line_number = 0;
36200b57cec5SDimitry Andric m_use_regex = false;
36210b57cec5SDimitry Andric m_include_inlines = true;
36220b57cec5SDimitry Andric m_verbose = false;
36230b57cec5SDimitry Andric m_print_all = false;
36240b57cec5SDimitry Andric }
36250b57cec5SDimitry Andric
GetDefinitions()36260b57cec5SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
36270b57cec5SDimitry Andric return llvm::makeArrayRef(g_target_modules_lookup_options);
36280b57cec5SDimitry Andric }
36290b57cec5SDimitry Andric
36300b57cec5SDimitry Andric int m_type; // Should be a eLookupTypeXXX enum after parsing options
36310b57cec5SDimitry Andric std::string m_str; // Holds name lookup
36320b57cec5SDimitry Andric FileSpec m_file; // Files for file lookups
36330b57cec5SDimitry Andric lldb::addr_t m_addr; // Holds the address to lookup
36340b57cec5SDimitry Andric lldb::addr_t
36350b57cec5SDimitry Andric m_offset; // Subtract this offset from m_addr before doing lookups.
36360b57cec5SDimitry Andric uint32_t m_line_number; // Line number for file+line lookups
36370b57cec5SDimitry Andric bool m_use_regex; // Name lookups in m_str are regular expressions.
36380b57cec5SDimitry Andric bool m_include_inlines; // Check for inline entries when looking up by
36390b57cec5SDimitry Andric // file/line.
36400b57cec5SDimitry Andric bool m_verbose; // Enable verbose lookup info
36410b57cec5SDimitry Andric bool m_print_all; // Print all matches, even in cases where there's a best
36420b57cec5SDimitry Andric // match.
36430b57cec5SDimitry Andric };
36440b57cec5SDimitry Andric
CommandObjectTargetModulesLookup(CommandInterpreter & interpreter)36450b57cec5SDimitry Andric CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
36460b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "target modules lookup",
36470b57cec5SDimitry Andric "Look up information within executable and "
36480b57cec5SDimitry Andric "dependent shared library images.",
36490b57cec5SDimitry Andric nullptr, eCommandRequiresTarget),
36500b57cec5SDimitry Andric m_options() {
36510b57cec5SDimitry Andric CommandArgumentEntry arg;
36520b57cec5SDimitry Andric CommandArgumentData file_arg;
36530b57cec5SDimitry Andric
36540b57cec5SDimitry Andric // Define the first (and only) variant of this arg.
36550b57cec5SDimitry Andric file_arg.arg_type = eArgTypeFilename;
36560b57cec5SDimitry Andric file_arg.arg_repetition = eArgRepeatStar;
36570b57cec5SDimitry Andric
36580b57cec5SDimitry Andric // There is only one variant this argument could be; put it into the
36590b57cec5SDimitry Andric // argument entry.
36600b57cec5SDimitry Andric arg.push_back(file_arg);
36610b57cec5SDimitry Andric
36620b57cec5SDimitry Andric // Push the data for the first argument into the m_arguments vector.
36630b57cec5SDimitry Andric m_arguments.push_back(arg);
36640b57cec5SDimitry Andric }
36650b57cec5SDimitry Andric
36660b57cec5SDimitry Andric ~CommandObjectTargetModulesLookup() override = default;
36670b57cec5SDimitry Andric
GetOptions()36680b57cec5SDimitry Andric Options *GetOptions() override { return &m_options; }
36690b57cec5SDimitry Andric
LookupHere(CommandInterpreter & interpreter,CommandReturnObject & result,bool & syntax_error)36700b57cec5SDimitry Andric bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
36710b57cec5SDimitry Andric bool &syntax_error) {
36720b57cec5SDimitry Andric switch (m_options.m_type) {
36730b57cec5SDimitry Andric case eLookupTypeAddress:
36740b57cec5SDimitry Andric case eLookupTypeFileLine:
36750b57cec5SDimitry Andric case eLookupTypeFunction:
36760b57cec5SDimitry Andric case eLookupTypeFunctionOrSymbol:
36770b57cec5SDimitry Andric case eLookupTypeSymbol:
36780b57cec5SDimitry Andric default:
36790b57cec5SDimitry Andric return false;
36800b57cec5SDimitry Andric case eLookupTypeType:
36810b57cec5SDimitry Andric break;
36820b57cec5SDimitry Andric }
36830b57cec5SDimitry Andric
36840b57cec5SDimitry Andric StackFrameSP frame = m_exe_ctx.GetFrameSP();
36850b57cec5SDimitry Andric
36860b57cec5SDimitry Andric if (!frame)
36870b57cec5SDimitry Andric return false;
36880b57cec5SDimitry Andric
36890b57cec5SDimitry Andric const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
36900b57cec5SDimitry Andric
36910b57cec5SDimitry Andric if (!sym_ctx.module_sp)
36920b57cec5SDimitry Andric return false;
36930b57cec5SDimitry Andric
36940b57cec5SDimitry Andric switch (m_options.m_type) {
36950b57cec5SDimitry Andric default:
36960b57cec5SDimitry Andric return false;
36970b57cec5SDimitry Andric case eLookupTypeType:
36980b57cec5SDimitry Andric if (!m_options.m_str.empty()) {
3699af732203SDimitry Andric if (LookupTypeHere(&GetSelectedTarget(), m_interpreter,
3700af732203SDimitry Andric result.GetOutputStream(), *sym_ctx.module_sp,
3701af732203SDimitry Andric m_options.m_str.c_str(), m_options.m_use_regex)) {
37020b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
37030b57cec5SDimitry Andric return true;
37040b57cec5SDimitry Andric }
37050b57cec5SDimitry Andric }
37060b57cec5SDimitry Andric break;
37070b57cec5SDimitry Andric }
37080b57cec5SDimitry Andric
3709480093f4SDimitry Andric return false;
37100b57cec5SDimitry Andric }
37110b57cec5SDimitry Andric
LookupInModule(CommandInterpreter & interpreter,Module * module,CommandReturnObject & result,bool & syntax_error)37120b57cec5SDimitry Andric bool LookupInModule(CommandInterpreter &interpreter, Module *module,
37130b57cec5SDimitry Andric CommandReturnObject &result, bool &syntax_error) {
37140b57cec5SDimitry Andric switch (m_options.m_type) {
37150b57cec5SDimitry Andric case eLookupTypeAddress:
37160b57cec5SDimitry Andric if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
37170b57cec5SDimitry Andric if (LookupAddressInModule(
37180b57cec5SDimitry Andric m_interpreter, result.GetOutputStream(), module,
37190b57cec5SDimitry Andric eSymbolContextEverything |
37200b57cec5SDimitry Andric (m_options.m_verbose
37210b57cec5SDimitry Andric ? static_cast<int>(eSymbolContextVariable)
37220b57cec5SDimitry Andric : 0),
37230b57cec5SDimitry Andric m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
37240b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
37250b57cec5SDimitry Andric return true;
37260b57cec5SDimitry Andric }
37270b57cec5SDimitry Andric }
37280b57cec5SDimitry Andric break;
37290b57cec5SDimitry Andric
37300b57cec5SDimitry Andric case eLookupTypeSymbol:
37310b57cec5SDimitry Andric if (!m_options.m_str.empty()) {
37320b57cec5SDimitry Andric if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
37330b57cec5SDimitry Andric module, m_options.m_str.c_str(),
37340b57cec5SDimitry Andric m_options.m_use_regex, m_options.m_verbose)) {
37350b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
37360b57cec5SDimitry Andric return true;
37370b57cec5SDimitry Andric }
37380b57cec5SDimitry Andric }
37390b57cec5SDimitry Andric break;
37400b57cec5SDimitry Andric
37410b57cec5SDimitry Andric case eLookupTypeFileLine:
37420b57cec5SDimitry Andric if (m_options.m_file) {
37430b57cec5SDimitry Andric if (LookupFileAndLineInModule(
37440b57cec5SDimitry Andric m_interpreter, result.GetOutputStream(), module,
37450b57cec5SDimitry Andric m_options.m_file, m_options.m_line_number,
37460b57cec5SDimitry Andric m_options.m_include_inlines, m_options.m_verbose)) {
37470b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
37480b57cec5SDimitry Andric return true;
37490b57cec5SDimitry Andric }
37500b57cec5SDimitry Andric }
37510b57cec5SDimitry Andric break;
37520b57cec5SDimitry Andric
37530b57cec5SDimitry Andric case eLookupTypeFunctionOrSymbol:
37540b57cec5SDimitry Andric case eLookupTypeFunction:
37550b57cec5SDimitry Andric if (!m_options.m_str.empty()) {
37560b57cec5SDimitry Andric if (LookupFunctionInModule(
37570b57cec5SDimitry Andric m_interpreter, result.GetOutputStream(), module,
37580b57cec5SDimitry Andric m_options.m_str.c_str(), m_options.m_use_regex,
37590b57cec5SDimitry Andric m_options.m_include_inlines,
37600b57cec5SDimitry Andric m_options.m_type ==
37610b57cec5SDimitry Andric eLookupTypeFunctionOrSymbol, // include symbols
37620b57cec5SDimitry Andric m_options.m_verbose)) {
37630b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
37640b57cec5SDimitry Andric return true;
37650b57cec5SDimitry Andric }
37660b57cec5SDimitry Andric }
37670b57cec5SDimitry Andric break;
37680b57cec5SDimitry Andric
37690b57cec5SDimitry Andric case eLookupTypeType:
37700b57cec5SDimitry Andric if (!m_options.m_str.empty()) {
3771af732203SDimitry Andric if (LookupTypeInModule(
3772af732203SDimitry Andric &GetSelectedTarget(), m_interpreter, result.GetOutputStream(),
3773af732203SDimitry Andric module, m_options.m_str.c_str(), m_options.m_use_regex)) {
37740b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
37750b57cec5SDimitry Andric return true;
37760b57cec5SDimitry Andric }
37770b57cec5SDimitry Andric }
37780b57cec5SDimitry Andric break;
37790b57cec5SDimitry Andric
37800b57cec5SDimitry Andric default:
37810b57cec5SDimitry Andric m_options.GenerateOptionUsage(
37820b57cec5SDimitry Andric result.GetErrorStream(), this,
37830b57cec5SDimitry Andric GetCommandInterpreter().GetDebugger().GetTerminalWidth());
37840b57cec5SDimitry Andric syntax_error = true;
37850b57cec5SDimitry Andric break;
37860b57cec5SDimitry Andric }
37870b57cec5SDimitry Andric
37880b57cec5SDimitry Andric result.SetStatus(eReturnStatusFailed);
37890b57cec5SDimitry Andric return false;
37900b57cec5SDimitry Andric }
37910b57cec5SDimitry Andric
37920b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)37930b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
37949dba64beSDimitry Andric Target *target = &GetSelectedTarget();
37950b57cec5SDimitry Andric bool syntax_error = false;
37960b57cec5SDimitry Andric uint32_t i;
37970b57cec5SDimitry Andric uint32_t num_successful_lookups = 0;
37980b57cec5SDimitry Andric uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
37990b57cec5SDimitry Andric result.GetOutputStream().SetAddressByteSize(addr_byte_size);
38000b57cec5SDimitry Andric result.GetErrorStream().SetAddressByteSize(addr_byte_size);
38010b57cec5SDimitry Andric // Dump all sections for all modules images
38020b57cec5SDimitry Andric
38030b57cec5SDimitry Andric if (command.GetArgumentCount() == 0) {
38040b57cec5SDimitry Andric ModuleSP current_module;
38050b57cec5SDimitry Andric
38060b57cec5SDimitry Andric // Where it is possible to look in the current symbol context first,
38070b57cec5SDimitry Andric // try that. If this search was successful and --all was not passed,
38080b57cec5SDimitry Andric // don't print anything else.
38090b57cec5SDimitry Andric if (LookupHere(m_interpreter, result, syntax_error)) {
38100b57cec5SDimitry Andric result.GetOutputStream().EOL();
38110b57cec5SDimitry Andric num_successful_lookups++;
38120b57cec5SDimitry Andric if (!m_options.m_print_all) {
38130b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
38140b57cec5SDimitry Andric return result.Succeeded();
38150b57cec5SDimitry Andric }
38160b57cec5SDimitry Andric }
38170b57cec5SDimitry Andric
38180b57cec5SDimitry Andric // Dump all sections for all other modules
38190b57cec5SDimitry Andric
38200b57cec5SDimitry Andric const ModuleList &target_modules = target->GetImages();
38210b57cec5SDimitry Andric std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3822af732203SDimitry Andric if (target_modules.GetSize() == 0) {
38230b57cec5SDimitry Andric result.AppendError("the target has no associated executable images");
38240b57cec5SDimitry Andric return false;
38250b57cec5SDimitry Andric }
3826af732203SDimitry Andric
3827af732203SDimitry Andric for (ModuleSP module_sp : target_modules.ModulesNoLocking()) {
3828af732203SDimitry Andric if (module_sp != current_module &&
3829af732203SDimitry Andric LookupInModule(m_interpreter, module_sp.get(), result,
3830af732203SDimitry Andric syntax_error)) {
3831af732203SDimitry Andric result.GetOutputStream().EOL();
3832af732203SDimitry Andric num_successful_lookups++;
3833af732203SDimitry Andric }
3834af732203SDimitry Andric }
38350b57cec5SDimitry Andric } else {
38360b57cec5SDimitry Andric // Dump specified images (by basename or fullpath)
38370b57cec5SDimitry Andric const char *arg_cstr;
38380b57cec5SDimitry Andric for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
38390b57cec5SDimitry Andric !syntax_error;
38400b57cec5SDimitry Andric ++i) {
38410b57cec5SDimitry Andric ModuleList module_list;
38420b57cec5SDimitry Andric const size_t num_matches =
38430b57cec5SDimitry Andric FindModulesByName(target, arg_cstr, module_list, false);
38440b57cec5SDimitry Andric if (num_matches > 0) {
38450b57cec5SDimitry Andric for (size_t j = 0; j < num_matches; ++j) {
38460b57cec5SDimitry Andric Module *module = module_list.GetModulePointerAtIndex(j);
38470b57cec5SDimitry Andric if (module) {
38489dba64beSDimitry Andric if (LookupInModule(m_interpreter, module, result, syntax_error)) {
38490b57cec5SDimitry Andric result.GetOutputStream().EOL();
38500b57cec5SDimitry Andric num_successful_lookups++;
38510b57cec5SDimitry Andric }
38520b57cec5SDimitry Andric }
38530b57cec5SDimitry Andric }
38540b57cec5SDimitry Andric } else
38550b57cec5SDimitry Andric result.AppendWarningWithFormat(
38560b57cec5SDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
38570b57cec5SDimitry Andric }
38580b57cec5SDimitry Andric }
38590b57cec5SDimitry Andric
38600b57cec5SDimitry Andric if (num_successful_lookups > 0)
38610b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
38620b57cec5SDimitry Andric else
38630b57cec5SDimitry Andric result.SetStatus(eReturnStatusFailed);
38640b57cec5SDimitry Andric return result.Succeeded();
38650b57cec5SDimitry Andric }
38660b57cec5SDimitry Andric
38670b57cec5SDimitry Andric CommandOptions m_options;
38680b57cec5SDimitry Andric };
38690b57cec5SDimitry Andric
38700b57cec5SDimitry Andric #pragma mark CommandObjectMultiwordImageSearchPaths
38710b57cec5SDimitry Andric
38720b57cec5SDimitry Andric // CommandObjectMultiwordImageSearchPaths
38730b57cec5SDimitry Andric
38740b57cec5SDimitry Andric class CommandObjectTargetModulesImageSearchPaths
38750b57cec5SDimitry Andric : public CommandObjectMultiword {
38760b57cec5SDimitry Andric public:
CommandObjectTargetModulesImageSearchPaths(CommandInterpreter & interpreter)38770b57cec5SDimitry Andric CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
38780b57cec5SDimitry Andric : CommandObjectMultiword(
38790b57cec5SDimitry Andric interpreter, "target modules search-paths",
38800b57cec5SDimitry Andric "Commands for managing module search paths for a target.",
38810b57cec5SDimitry Andric "target modules search-paths <subcommand> [<subcommand-options>]") {
38820b57cec5SDimitry Andric LoadSubCommand(
38830b57cec5SDimitry Andric "add", CommandObjectSP(
38840b57cec5SDimitry Andric new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
38850b57cec5SDimitry Andric LoadSubCommand(
38860b57cec5SDimitry Andric "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
38870b57cec5SDimitry Andric interpreter)));
38880b57cec5SDimitry Andric LoadSubCommand(
38890b57cec5SDimitry Andric "insert",
38900b57cec5SDimitry Andric CommandObjectSP(
38910b57cec5SDimitry Andric new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
38920b57cec5SDimitry Andric LoadSubCommand(
38930b57cec5SDimitry Andric "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
38940b57cec5SDimitry Andric interpreter)));
38950b57cec5SDimitry Andric LoadSubCommand(
38960b57cec5SDimitry Andric "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
38970b57cec5SDimitry Andric interpreter)));
38980b57cec5SDimitry Andric }
38990b57cec5SDimitry Andric
39000b57cec5SDimitry Andric ~CommandObjectTargetModulesImageSearchPaths() override = default;
39010b57cec5SDimitry Andric };
39020b57cec5SDimitry Andric
39030b57cec5SDimitry Andric #pragma mark CommandObjectTargetModules
39040b57cec5SDimitry Andric
39050b57cec5SDimitry Andric // CommandObjectTargetModules
39060b57cec5SDimitry Andric
39070b57cec5SDimitry Andric class CommandObjectTargetModules : public CommandObjectMultiword {
39080b57cec5SDimitry Andric public:
39090b57cec5SDimitry Andric // Constructors and Destructors
CommandObjectTargetModules(CommandInterpreter & interpreter)39100b57cec5SDimitry Andric CommandObjectTargetModules(CommandInterpreter &interpreter)
39110b57cec5SDimitry Andric : CommandObjectMultiword(interpreter, "target modules",
39120b57cec5SDimitry Andric "Commands for accessing information for one or "
39130b57cec5SDimitry Andric "more target modules.",
39140b57cec5SDimitry Andric "target modules <sub-command> ...") {
39150b57cec5SDimitry Andric LoadSubCommand(
39160b57cec5SDimitry Andric "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
39170b57cec5SDimitry Andric LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
39180b57cec5SDimitry Andric interpreter)));
39190b57cec5SDimitry Andric LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
39200b57cec5SDimitry Andric interpreter)));
39210b57cec5SDimitry Andric LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
39220b57cec5SDimitry Andric interpreter)));
39230b57cec5SDimitry Andric LoadSubCommand(
39240b57cec5SDimitry Andric "lookup",
39250b57cec5SDimitry Andric CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
39260b57cec5SDimitry Andric LoadSubCommand(
39270b57cec5SDimitry Andric "search-paths",
39280b57cec5SDimitry Andric CommandObjectSP(
39290b57cec5SDimitry Andric new CommandObjectTargetModulesImageSearchPaths(interpreter)));
39300b57cec5SDimitry Andric LoadSubCommand(
39310b57cec5SDimitry Andric "show-unwind",
39320b57cec5SDimitry Andric CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
39330b57cec5SDimitry Andric }
39340b57cec5SDimitry Andric
39350b57cec5SDimitry Andric ~CommandObjectTargetModules() override = default;
39360b57cec5SDimitry Andric
39370b57cec5SDimitry Andric private:
39380b57cec5SDimitry Andric // For CommandObjectTargetModules only
39395ffd83dbSDimitry Andric CommandObjectTargetModules(const CommandObjectTargetModules &) = delete;
39405ffd83dbSDimitry Andric const CommandObjectTargetModules &
39415ffd83dbSDimitry Andric operator=(const CommandObjectTargetModules &) = delete;
39420b57cec5SDimitry Andric };
39430b57cec5SDimitry Andric
39440b57cec5SDimitry Andric class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
39450b57cec5SDimitry Andric public:
CommandObjectTargetSymbolsAdd(CommandInterpreter & interpreter)39460b57cec5SDimitry Andric CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
39470b57cec5SDimitry Andric : CommandObjectParsed(
39480b57cec5SDimitry Andric interpreter, "target symbols add",
39490b57cec5SDimitry Andric "Add a debug symbol file to one of the target's current modules by "
39505ffd83dbSDimitry Andric "specifying a path to a debug symbols file or by using the options "
39515ffd83dbSDimitry Andric "to specify a module.",
39520b57cec5SDimitry Andric "target symbols add <cmd-options> [<symfile>]",
39530b57cec5SDimitry Andric eCommandRequiresTarget),
39540b57cec5SDimitry Andric m_option_group(),
39550b57cec5SDimitry Andric m_file_option(
39560b57cec5SDimitry Andric LLDB_OPT_SET_1, false, "shlib", 's',
39570b57cec5SDimitry Andric CommandCompletions::eModuleCompletion, eArgTypeShlibName,
39585ffd83dbSDimitry Andric "Locate the debug symbols for the shared library specified by "
39595ffd83dbSDimitry Andric "name."),
39600b57cec5SDimitry Andric m_current_frame_option(
39610b57cec5SDimitry Andric LLDB_OPT_SET_2, false, "frame", 'F',
39625ffd83dbSDimitry Andric "Locate the debug symbols for the currently selected frame.",
39635ffd83dbSDimitry Andric false, true)
39640b57cec5SDimitry Andric
39650b57cec5SDimitry Andric {
39660b57cec5SDimitry Andric m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
39670b57cec5SDimitry Andric LLDB_OPT_SET_1);
39680b57cec5SDimitry Andric m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
39690b57cec5SDimitry Andric m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
39700b57cec5SDimitry Andric LLDB_OPT_SET_2);
39710b57cec5SDimitry Andric m_option_group.Finalize();
39720b57cec5SDimitry Andric }
39730b57cec5SDimitry Andric
39740b57cec5SDimitry Andric ~CommandObjectTargetSymbolsAdd() override = default;
39750b57cec5SDimitry Andric
39769dba64beSDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)39779dba64beSDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
39780b57cec5SDimitry Andric OptionElementVector &opt_element_vector) override {
39790b57cec5SDimitry Andric CommandCompletions::InvokeCommonCompletionCallbacks(
39800b57cec5SDimitry Andric GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
39810b57cec5SDimitry Andric request, nullptr);
39820b57cec5SDimitry Andric }
39830b57cec5SDimitry Andric
GetOptions()39840b57cec5SDimitry Andric Options *GetOptions() override { return &m_option_group; }
39850b57cec5SDimitry Andric
39860b57cec5SDimitry Andric protected:
AddModuleSymbols(Target * target,ModuleSpec & module_spec,bool & flush,CommandReturnObject & result)39870b57cec5SDimitry Andric bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
39880b57cec5SDimitry Andric CommandReturnObject &result) {
39890b57cec5SDimitry Andric const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
3990480093f4SDimitry Andric if (!symbol_fspec) {
3991480093f4SDimitry Andric result.AppendError(
3992480093f4SDimitry Andric "one or more executable image paths must be specified");
3993480093f4SDimitry Andric return false;
3994480093f4SDimitry Andric }
3995480093f4SDimitry Andric
39960b57cec5SDimitry Andric char symfile_path[PATH_MAX];
39970b57cec5SDimitry Andric symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
39980b57cec5SDimitry Andric
39990b57cec5SDimitry Andric if (!module_spec.GetUUID().IsValid()) {
40000b57cec5SDimitry Andric if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
40010b57cec5SDimitry Andric module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
40020b57cec5SDimitry Andric }
4003480093f4SDimitry Andric
40045ffd83dbSDimitry Andric // Now module_spec represents a symbol file for a module that might exist
40055ffd83dbSDimitry Andric // in the current target. Let's find possible matches.
40065ffd83dbSDimitry Andric ModuleList matching_modules;
40070b57cec5SDimitry Andric
40080b57cec5SDimitry Andric // First extract all module specs from the symbol file
40090b57cec5SDimitry Andric lldb_private::ModuleSpecList symfile_module_specs;
40100b57cec5SDimitry Andric if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
40110b57cec5SDimitry Andric 0, 0, symfile_module_specs)) {
40120b57cec5SDimitry Andric // Now extract the module spec that matches the target architecture
40130b57cec5SDimitry Andric ModuleSpec target_arch_module_spec;
40140b57cec5SDimitry Andric ModuleSpec symfile_module_spec;
40150b57cec5SDimitry Andric target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
40160b57cec5SDimitry Andric if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
40170b57cec5SDimitry Andric symfile_module_spec)) {
40180b57cec5SDimitry Andric if (symfile_module_spec.GetUUID().IsValid()) {
40190b57cec5SDimitry Andric // It has a UUID, look for this UUID in the target modules
40200b57cec5SDimitry Andric ModuleSpec symfile_uuid_module_spec;
40210b57cec5SDimitry Andric symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
40229dba64beSDimitry Andric target->GetImages().FindModules(symfile_uuid_module_spec,
40235ffd83dbSDimitry Andric matching_modules);
40240b57cec5SDimitry Andric }
40250b57cec5SDimitry Andric }
40260b57cec5SDimitry Andric
40275ffd83dbSDimitry Andric if (matching_modules.IsEmpty()) {
40285ffd83dbSDimitry Andric // No matches yet. Iterate through the module specs to find a UUID
40295ffd83dbSDimitry Andric // value that we can match up to an image in our target.
40305ffd83dbSDimitry Andric const size_t num_symfile_module_specs = symfile_module_specs.GetSize();
40315ffd83dbSDimitry Andric for (size_t i = 0;
40325ffd83dbSDimitry Andric i < num_symfile_module_specs && matching_modules.IsEmpty(); ++i) {
40330b57cec5SDimitry Andric if (symfile_module_specs.GetModuleSpecAtIndex(
40340b57cec5SDimitry Andric i, symfile_module_spec)) {
40350b57cec5SDimitry Andric if (symfile_module_spec.GetUUID().IsValid()) {
40365ffd83dbSDimitry Andric // It has a UUID. Look for this UUID in the target modules.
40370b57cec5SDimitry Andric ModuleSpec symfile_uuid_module_spec;
40380b57cec5SDimitry Andric symfile_uuid_module_spec.GetUUID() =
40390b57cec5SDimitry Andric symfile_module_spec.GetUUID();
40409dba64beSDimitry Andric target->GetImages().FindModules(symfile_uuid_module_spec,
40415ffd83dbSDimitry Andric matching_modules);
40420b57cec5SDimitry Andric }
40430b57cec5SDimitry Andric }
40440b57cec5SDimitry Andric }
40450b57cec5SDimitry Andric }
40460b57cec5SDimitry Andric }
40470b57cec5SDimitry Andric
40480b57cec5SDimitry Andric // Just try to match up the file by basename if we have no matches at
40495ffd83dbSDimitry Andric // this point. For example, module foo might have symbols in foo.debug.
40505ffd83dbSDimitry Andric if (matching_modules.IsEmpty())
40515ffd83dbSDimitry Andric target->GetImages().FindModules(module_spec, matching_modules);
40520b57cec5SDimitry Andric
40535ffd83dbSDimitry Andric while (matching_modules.IsEmpty()) {
40540b57cec5SDimitry Andric ConstString filename_no_extension(
40550b57cec5SDimitry Andric module_spec.GetFileSpec().GetFileNameStrippingExtension());
4056480093f4SDimitry Andric // Empty string returned, let's bail
40570b57cec5SDimitry Andric if (!filename_no_extension)
40580b57cec5SDimitry Andric break;
40590b57cec5SDimitry Andric
4060480093f4SDimitry Andric // Check if there was no extension to strip and the basename is the same
40610b57cec5SDimitry Andric if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
40620b57cec5SDimitry Andric break;
40630b57cec5SDimitry Andric
4064480093f4SDimitry Andric // Replace basename with one fewer extension
40650b57cec5SDimitry Andric module_spec.GetFileSpec().GetFilename() = filename_no_extension;
40665ffd83dbSDimitry Andric target->GetImages().FindModules(module_spec, matching_modules);
40670b57cec5SDimitry Andric }
40680b57cec5SDimitry Andric
40695ffd83dbSDimitry Andric if (matching_modules.GetSize() > 1) {
40700b57cec5SDimitry Andric result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
40710b57cec5SDimitry Andric "use the --uuid option to resolve the "
40720b57cec5SDimitry Andric "ambiguity.\n",
40730b57cec5SDimitry Andric symfile_path);
40745ffd83dbSDimitry Andric return false;
40755ffd83dbSDimitry Andric }
40765ffd83dbSDimitry Andric
40775ffd83dbSDimitry Andric if (matching_modules.GetSize() == 1) {
40785ffd83dbSDimitry Andric ModuleSP module_sp(matching_modules.GetModuleAtIndex(0));
40790b57cec5SDimitry Andric
40800b57cec5SDimitry Andric // The module has not yet created its symbol vendor, we can just give
40810b57cec5SDimitry Andric // the existing target module the symfile path to use for when it
40820b57cec5SDimitry Andric // decides to create it!
40830b57cec5SDimitry Andric module_sp->SetSymbolFileFileSpec(symbol_fspec);
40840b57cec5SDimitry Andric
40859dba64beSDimitry Andric SymbolFile *symbol_file =
40869dba64beSDimitry Andric module_sp->GetSymbolFile(true, &result.GetErrorStream());
40870b57cec5SDimitry Andric if (symbol_file) {
40880b57cec5SDimitry Andric ObjectFile *object_file = symbol_file->GetObjectFile();
40890b57cec5SDimitry Andric if (object_file && object_file->GetFileSpec() == symbol_fspec) {
40900b57cec5SDimitry Andric // Provide feedback that the symfile has been successfully added.
40910b57cec5SDimitry Andric const FileSpec &module_fs = module_sp->GetFileSpec();
40920b57cec5SDimitry Andric result.AppendMessageWithFormat(
40930b57cec5SDimitry Andric "symbol file '%s' has been added to '%s'\n", symfile_path,
40940b57cec5SDimitry Andric module_fs.GetPath().c_str());
40950b57cec5SDimitry Andric
40960b57cec5SDimitry Andric // Let clients know something changed in the module if it is
40970b57cec5SDimitry Andric // currently loaded
40980b57cec5SDimitry Andric ModuleList module_list;
40990b57cec5SDimitry Andric module_list.Append(module_sp);
41000b57cec5SDimitry Andric target->SymbolsDidLoad(module_list);
41010b57cec5SDimitry Andric
41020b57cec5SDimitry Andric // Make sure we load any scripting resources that may be embedded
41030b57cec5SDimitry Andric // in the debug info files in case the platform supports that.
41040b57cec5SDimitry Andric Status error;
41050b57cec5SDimitry Andric StreamString feedback_stream;
41060b57cec5SDimitry Andric module_sp->LoadScriptingResourceInTarget(target, error,
41070b57cec5SDimitry Andric &feedback_stream);
41080b57cec5SDimitry Andric if (error.Fail() && error.AsCString())
41090b57cec5SDimitry Andric result.AppendWarningWithFormat(
41100b57cec5SDimitry Andric "unable to load scripting data for module %s - error "
41110b57cec5SDimitry Andric "reported was %s",
41120b57cec5SDimitry Andric module_sp->GetFileSpec()
41130b57cec5SDimitry Andric .GetFileNameStrippingExtension()
41140b57cec5SDimitry Andric .GetCString(),
41150b57cec5SDimitry Andric error.AsCString());
41160b57cec5SDimitry Andric else if (feedback_stream.GetSize())
41175ffd83dbSDimitry Andric result.AppendWarning(feedback_stream.GetData());
41180b57cec5SDimitry Andric
41190b57cec5SDimitry Andric flush = true;
41200b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
41210b57cec5SDimitry Andric return true;
41220b57cec5SDimitry Andric }
41230b57cec5SDimitry Andric }
41240b57cec5SDimitry Andric // Clear the symbol file spec if anything went wrong
41250b57cec5SDimitry Andric module_sp->SetSymbolFileFileSpec(FileSpec());
41260b57cec5SDimitry Andric }
41270b57cec5SDimitry Andric
41280b57cec5SDimitry Andric StreamString ss_symfile_uuid;
4129480093f4SDimitry Andric if (module_spec.GetUUID().IsValid()) {
4130480093f4SDimitry Andric ss_symfile_uuid << " (";
41310b57cec5SDimitry Andric module_spec.GetUUID().Dump(&ss_symfile_uuid);
4132480093f4SDimitry Andric ss_symfile_uuid << ')';
4133480093f4SDimitry Andric }
41340b57cec5SDimitry Andric result.AppendErrorWithFormat(
4135480093f4SDimitry Andric "symbol file '%s'%s does not match any existing module%s\n",
41360b57cec5SDimitry Andric symfile_path, ss_symfile_uuid.GetData(),
41375ffd83dbSDimitry Andric !llvm::sys::fs::is_regular_file(symbol_fspec.GetPath())
41380b57cec5SDimitry Andric ? "\n please specify the full path to the symbol file"
41390b57cec5SDimitry Andric : "");
41400b57cec5SDimitry Andric return false;
41410b57cec5SDimitry Andric }
41420b57cec5SDimitry Andric
DoExecute(Args & args,CommandReturnObject & result)41430b57cec5SDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
41440b57cec5SDimitry Andric Target *target = m_exe_ctx.GetTargetPtr();
41450b57cec5SDimitry Andric result.SetStatus(eReturnStatusFailed);
41460b57cec5SDimitry Andric bool flush = false;
41470b57cec5SDimitry Andric ModuleSpec module_spec;
41480b57cec5SDimitry Andric const bool uuid_option_set =
41490b57cec5SDimitry Andric m_uuid_option_group.GetOptionValue().OptionWasSet();
41500b57cec5SDimitry Andric const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
41510b57cec5SDimitry Andric const bool frame_option_set =
41520b57cec5SDimitry Andric m_current_frame_option.GetOptionValue().OptionWasSet();
41530b57cec5SDimitry Andric const size_t argc = args.GetArgumentCount();
41540b57cec5SDimitry Andric
41550b57cec5SDimitry Andric if (argc == 0) {
41560b57cec5SDimitry Andric if (uuid_option_set || file_option_set || frame_option_set) {
41570b57cec5SDimitry Andric bool success = false;
41580b57cec5SDimitry Andric bool error_set = false;
41590b57cec5SDimitry Andric if (frame_option_set) {
41600b57cec5SDimitry Andric Process *process = m_exe_ctx.GetProcessPtr();
41610b57cec5SDimitry Andric if (process) {
41620b57cec5SDimitry Andric const StateType process_state = process->GetState();
41630b57cec5SDimitry Andric if (StateIsStoppedState(process_state, true)) {
41640b57cec5SDimitry Andric StackFrame *frame = m_exe_ctx.GetFramePtr();
41650b57cec5SDimitry Andric if (frame) {
41660b57cec5SDimitry Andric ModuleSP frame_module_sp(
41670b57cec5SDimitry Andric frame->GetSymbolContext(eSymbolContextModule).module_sp);
41680b57cec5SDimitry Andric if (frame_module_sp) {
41690b57cec5SDimitry Andric if (FileSystem::Instance().Exists(
41700b57cec5SDimitry Andric frame_module_sp->GetPlatformFileSpec())) {
41710b57cec5SDimitry Andric module_spec.GetArchitecture() =
41720b57cec5SDimitry Andric frame_module_sp->GetArchitecture();
41730b57cec5SDimitry Andric module_spec.GetFileSpec() =
41740b57cec5SDimitry Andric frame_module_sp->GetPlatformFileSpec();
41750b57cec5SDimitry Andric }
41760b57cec5SDimitry Andric module_spec.GetUUID() = frame_module_sp->GetUUID();
41770b57cec5SDimitry Andric success = module_spec.GetUUID().IsValid() ||
41780b57cec5SDimitry Andric module_spec.GetFileSpec();
41790b57cec5SDimitry Andric } else {
41800b57cec5SDimitry Andric result.AppendError("frame has no module");
41810b57cec5SDimitry Andric error_set = true;
41820b57cec5SDimitry Andric }
41830b57cec5SDimitry Andric } else {
41840b57cec5SDimitry Andric result.AppendError("invalid current frame");
41850b57cec5SDimitry Andric error_set = true;
41860b57cec5SDimitry Andric }
41870b57cec5SDimitry Andric } else {
41880b57cec5SDimitry Andric result.AppendErrorWithFormat("process is not stopped: %s",
41890b57cec5SDimitry Andric StateAsCString(process_state));
41900b57cec5SDimitry Andric error_set = true;
41910b57cec5SDimitry Andric }
41920b57cec5SDimitry Andric } else {
41930b57cec5SDimitry Andric result.AppendError(
41940b57cec5SDimitry Andric "a process must exist in order to use the --frame option");
41950b57cec5SDimitry Andric error_set = true;
41960b57cec5SDimitry Andric }
41970b57cec5SDimitry Andric } else {
41980b57cec5SDimitry Andric if (uuid_option_set) {
41990b57cec5SDimitry Andric module_spec.GetUUID() =
42000b57cec5SDimitry Andric m_uuid_option_group.GetOptionValue().GetCurrentValue();
42010b57cec5SDimitry Andric success |= module_spec.GetUUID().IsValid();
42020b57cec5SDimitry Andric } else if (file_option_set) {
42030b57cec5SDimitry Andric module_spec.GetFileSpec() =
42040b57cec5SDimitry Andric m_file_option.GetOptionValue().GetCurrentValue();
42050b57cec5SDimitry Andric ModuleSP module_sp(
42060b57cec5SDimitry Andric target->GetImages().FindFirstModule(module_spec));
42070b57cec5SDimitry Andric if (module_sp) {
42080b57cec5SDimitry Andric module_spec.GetFileSpec() = module_sp->GetFileSpec();
42090b57cec5SDimitry Andric module_spec.GetPlatformFileSpec() =
42100b57cec5SDimitry Andric module_sp->GetPlatformFileSpec();
42110b57cec5SDimitry Andric module_spec.GetUUID() = module_sp->GetUUID();
42120b57cec5SDimitry Andric module_spec.GetArchitecture() = module_sp->GetArchitecture();
42130b57cec5SDimitry Andric } else {
42140b57cec5SDimitry Andric module_spec.GetArchitecture() = target->GetArchitecture();
42150b57cec5SDimitry Andric }
42160b57cec5SDimitry Andric success |= module_spec.GetUUID().IsValid() ||
42170b57cec5SDimitry Andric FileSystem::Instance().Exists(module_spec.GetFileSpec());
42180b57cec5SDimitry Andric }
42190b57cec5SDimitry Andric }
42200b57cec5SDimitry Andric
42210b57cec5SDimitry Andric if (success) {
42220b57cec5SDimitry Andric if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
42230b57cec5SDimitry Andric if (module_spec.GetSymbolFileSpec())
42240b57cec5SDimitry Andric success = AddModuleSymbols(target, module_spec, flush, result);
42250b57cec5SDimitry Andric }
42260b57cec5SDimitry Andric }
42270b57cec5SDimitry Andric
42280b57cec5SDimitry Andric if (!success && !error_set) {
42290b57cec5SDimitry Andric StreamString error_strm;
42300b57cec5SDimitry Andric if (uuid_option_set) {
42310b57cec5SDimitry Andric error_strm.PutCString("unable to find debug symbols for UUID ");
42320b57cec5SDimitry Andric module_spec.GetUUID().Dump(&error_strm);
42330b57cec5SDimitry Andric } else if (file_option_set) {
42340b57cec5SDimitry Andric error_strm.PutCString(
42350b57cec5SDimitry Andric "unable to find debug symbols for the executable file ");
42360b57cec5SDimitry Andric error_strm << module_spec.GetFileSpec();
42370b57cec5SDimitry Andric } else if (frame_option_set) {
42380b57cec5SDimitry Andric error_strm.PutCString(
42390b57cec5SDimitry Andric "unable to find debug symbols for the current frame");
42400b57cec5SDimitry Andric }
42410b57cec5SDimitry Andric result.AppendError(error_strm.GetString());
42420b57cec5SDimitry Andric }
42430b57cec5SDimitry Andric } else {
42440b57cec5SDimitry Andric result.AppendError("one or more symbol file paths must be specified, "
42450b57cec5SDimitry Andric "or options must be specified");
42460b57cec5SDimitry Andric }
42470b57cec5SDimitry Andric } else {
42480b57cec5SDimitry Andric if (uuid_option_set) {
42490b57cec5SDimitry Andric result.AppendError("specify either one or more paths to symbol files "
42500b57cec5SDimitry Andric "or use the --uuid option without arguments");
42510b57cec5SDimitry Andric } else if (frame_option_set) {
42520b57cec5SDimitry Andric result.AppendError("specify either one or more paths to symbol files "
42530b57cec5SDimitry Andric "or use the --frame option without arguments");
42540b57cec5SDimitry Andric } else if (file_option_set && argc > 1) {
42550b57cec5SDimitry Andric result.AppendError("specify at most one symbol file path when "
42560b57cec5SDimitry Andric "--shlib option is set");
42570b57cec5SDimitry Andric } else {
42580b57cec5SDimitry Andric PlatformSP platform_sp(target->GetPlatform());
42590b57cec5SDimitry Andric
42600b57cec5SDimitry Andric for (auto &entry : args.entries()) {
42619dba64beSDimitry Andric if (!entry.ref().empty()) {
42620b57cec5SDimitry Andric auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
42639dba64beSDimitry Andric symbol_file_spec.SetFile(entry.ref(), FileSpec::Style::native);
42640b57cec5SDimitry Andric FileSystem::Instance().Resolve(symbol_file_spec);
42650b57cec5SDimitry Andric if (file_option_set) {
42660b57cec5SDimitry Andric module_spec.GetFileSpec() =
42670b57cec5SDimitry Andric m_file_option.GetOptionValue().GetCurrentValue();
42680b57cec5SDimitry Andric }
42690b57cec5SDimitry Andric if (platform_sp) {
42700b57cec5SDimitry Andric FileSpec symfile_spec;
42710b57cec5SDimitry Andric if (platform_sp
42720b57cec5SDimitry Andric ->ResolveSymbolFile(*target, module_spec, symfile_spec)
42730b57cec5SDimitry Andric .Success())
42740b57cec5SDimitry Andric module_spec.GetSymbolFileSpec() = symfile_spec;
42750b57cec5SDimitry Andric }
42760b57cec5SDimitry Andric
42770b57cec5SDimitry Andric bool symfile_exists =
42780b57cec5SDimitry Andric FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
42790b57cec5SDimitry Andric
42800b57cec5SDimitry Andric if (symfile_exists) {
42810b57cec5SDimitry Andric if (!AddModuleSymbols(target, module_spec, flush, result))
42820b57cec5SDimitry Andric break;
42830b57cec5SDimitry Andric } else {
42840b57cec5SDimitry Andric std::string resolved_symfile_path =
42850b57cec5SDimitry Andric module_spec.GetSymbolFileSpec().GetPath();
42869dba64beSDimitry Andric if (resolved_symfile_path != entry.ref()) {
42870b57cec5SDimitry Andric result.AppendErrorWithFormat(
42880b57cec5SDimitry Andric "invalid module path '%s' with resolved path '%s'\n",
42890b57cec5SDimitry Andric entry.c_str(), resolved_symfile_path.c_str());
42900b57cec5SDimitry Andric break;
42910b57cec5SDimitry Andric }
42920b57cec5SDimitry Andric result.AppendErrorWithFormat("invalid module path '%s'\n",
42930b57cec5SDimitry Andric entry.c_str());
42940b57cec5SDimitry Andric break;
42950b57cec5SDimitry Andric }
42960b57cec5SDimitry Andric }
42970b57cec5SDimitry Andric }
42980b57cec5SDimitry Andric }
42990b57cec5SDimitry Andric }
43000b57cec5SDimitry Andric
43010b57cec5SDimitry Andric if (flush) {
43020b57cec5SDimitry Andric Process *process = m_exe_ctx.GetProcessPtr();
43030b57cec5SDimitry Andric if (process)
43040b57cec5SDimitry Andric process->Flush();
43050b57cec5SDimitry Andric }
43060b57cec5SDimitry Andric return result.Succeeded();
43070b57cec5SDimitry Andric }
43080b57cec5SDimitry Andric
43090b57cec5SDimitry Andric OptionGroupOptions m_option_group;
43100b57cec5SDimitry Andric OptionGroupUUID m_uuid_option_group;
43110b57cec5SDimitry Andric OptionGroupFile m_file_option;
43120b57cec5SDimitry Andric OptionGroupBoolean m_current_frame_option;
43130b57cec5SDimitry Andric };
43140b57cec5SDimitry Andric
43150b57cec5SDimitry Andric #pragma mark CommandObjectTargetSymbols
43160b57cec5SDimitry Andric
43170b57cec5SDimitry Andric // CommandObjectTargetSymbols
43180b57cec5SDimitry Andric
43190b57cec5SDimitry Andric class CommandObjectTargetSymbols : public CommandObjectMultiword {
43200b57cec5SDimitry Andric public:
43210b57cec5SDimitry Andric // Constructors and Destructors
CommandObjectTargetSymbols(CommandInterpreter & interpreter)43220b57cec5SDimitry Andric CommandObjectTargetSymbols(CommandInterpreter &interpreter)
43230b57cec5SDimitry Andric : CommandObjectMultiword(
43240b57cec5SDimitry Andric interpreter, "target symbols",
43250b57cec5SDimitry Andric "Commands for adding and managing debug symbol files.",
43260b57cec5SDimitry Andric "target symbols <sub-command> ...") {
43270b57cec5SDimitry Andric LoadSubCommand(
43280b57cec5SDimitry Andric "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
43290b57cec5SDimitry Andric }
43300b57cec5SDimitry Andric
43310b57cec5SDimitry Andric ~CommandObjectTargetSymbols() override = default;
43320b57cec5SDimitry Andric
43330b57cec5SDimitry Andric private:
43340b57cec5SDimitry Andric // For CommandObjectTargetModules only
43355ffd83dbSDimitry Andric CommandObjectTargetSymbols(const CommandObjectTargetSymbols &) = delete;
43365ffd83dbSDimitry Andric const CommandObjectTargetSymbols &
43375ffd83dbSDimitry Andric operator=(const CommandObjectTargetSymbols &) = delete;
43380b57cec5SDimitry Andric };
43390b57cec5SDimitry Andric
43400b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookAdd
43410b57cec5SDimitry Andric
43420b57cec5SDimitry Andric // CommandObjectTargetStopHookAdd
43439dba64beSDimitry Andric #define LLDB_OPTIONS_target_stop_hook_add
43449dba64beSDimitry Andric #include "CommandOptions.inc"
43450b57cec5SDimitry Andric
43460b57cec5SDimitry Andric class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
43470b57cec5SDimitry Andric public IOHandlerDelegateMultiline {
43480b57cec5SDimitry Andric public:
4349af732203SDimitry Andric class CommandOptions : public OptionGroup {
43500b57cec5SDimitry Andric public:
CommandOptions()4351*5f7ddb14SDimitry Andric CommandOptions() : OptionGroup(), m_line_end(UINT_MAX), m_one_liner() {}
43520b57cec5SDimitry Andric
43530b57cec5SDimitry Andric ~CommandOptions() override = default;
43540b57cec5SDimitry Andric
GetDefinitions()43550b57cec5SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
43560b57cec5SDimitry Andric return llvm::makeArrayRef(g_target_stop_hook_add_options);
43570b57cec5SDimitry Andric }
43580b57cec5SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)43590b57cec5SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
43600b57cec5SDimitry Andric ExecutionContext *execution_context) override {
43610b57cec5SDimitry Andric Status error;
4362af732203SDimitry Andric const int short_option =
4363af732203SDimitry Andric g_target_stop_hook_add_options[option_idx].short_option;
43640b57cec5SDimitry Andric
43650b57cec5SDimitry Andric switch (short_option) {
43660b57cec5SDimitry Andric case 'c':
43675ffd83dbSDimitry Andric m_class_name = std::string(option_arg);
43680b57cec5SDimitry Andric m_sym_ctx_specified = true;
43690b57cec5SDimitry Andric break;
43700b57cec5SDimitry Andric
43710b57cec5SDimitry Andric case 'e':
43720b57cec5SDimitry Andric if (option_arg.getAsInteger(0, m_line_end)) {
43730b57cec5SDimitry Andric error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
43740b57cec5SDimitry Andric option_arg.str().c_str());
43750b57cec5SDimitry Andric break;
43760b57cec5SDimitry Andric }
43770b57cec5SDimitry Andric m_sym_ctx_specified = true;
43780b57cec5SDimitry Andric break;
43790b57cec5SDimitry Andric
43800b57cec5SDimitry Andric case 'G': {
43810b57cec5SDimitry Andric bool value, success;
43820b57cec5SDimitry Andric value = OptionArgParser::ToBoolean(option_arg, false, &success);
43830b57cec5SDimitry Andric if (success) {
43840b57cec5SDimitry Andric m_auto_continue = value;
43850b57cec5SDimitry Andric } else
43860b57cec5SDimitry Andric error.SetErrorStringWithFormat(
43870b57cec5SDimitry Andric "invalid boolean value '%s' passed for -G option",
43880b57cec5SDimitry Andric option_arg.str().c_str());
4389480093f4SDimitry Andric } break;
43900b57cec5SDimitry Andric case 'l':
43910b57cec5SDimitry Andric if (option_arg.getAsInteger(0, m_line_start)) {
43920b57cec5SDimitry Andric error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
43930b57cec5SDimitry Andric option_arg.str().c_str());
43940b57cec5SDimitry Andric break;
43950b57cec5SDimitry Andric }
43960b57cec5SDimitry Andric m_sym_ctx_specified = true;
43970b57cec5SDimitry Andric break;
43980b57cec5SDimitry Andric
43990b57cec5SDimitry Andric case 'i':
44000b57cec5SDimitry Andric m_no_inlines = true;
44010b57cec5SDimitry Andric break;
44020b57cec5SDimitry Andric
44030b57cec5SDimitry Andric case 'n':
44045ffd83dbSDimitry Andric m_function_name = std::string(option_arg);
44050b57cec5SDimitry Andric m_func_name_type_mask |= eFunctionNameTypeAuto;
44060b57cec5SDimitry Andric m_sym_ctx_specified = true;
44070b57cec5SDimitry Andric break;
44080b57cec5SDimitry Andric
44090b57cec5SDimitry Andric case 'f':
44105ffd83dbSDimitry Andric m_file_name = std::string(option_arg);
44110b57cec5SDimitry Andric m_sym_ctx_specified = true;
44120b57cec5SDimitry Andric break;
44130b57cec5SDimitry Andric
44140b57cec5SDimitry Andric case 's':
44155ffd83dbSDimitry Andric m_module_name = std::string(option_arg);
44160b57cec5SDimitry Andric m_sym_ctx_specified = true;
44170b57cec5SDimitry Andric break;
44180b57cec5SDimitry Andric
44190b57cec5SDimitry Andric case 't':
44200b57cec5SDimitry Andric if (option_arg.getAsInteger(0, m_thread_id))
44210b57cec5SDimitry Andric error.SetErrorStringWithFormat("invalid thread id string '%s'",
44220b57cec5SDimitry Andric option_arg.str().c_str());
44230b57cec5SDimitry Andric m_thread_specified = true;
44240b57cec5SDimitry Andric break;
44250b57cec5SDimitry Andric
44260b57cec5SDimitry Andric case 'T':
44275ffd83dbSDimitry Andric m_thread_name = std::string(option_arg);
44280b57cec5SDimitry Andric m_thread_specified = true;
44290b57cec5SDimitry Andric break;
44300b57cec5SDimitry Andric
44310b57cec5SDimitry Andric case 'q':
44325ffd83dbSDimitry Andric m_queue_name = std::string(option_arg);
44330b57cec5SDimitry Andric m_thread_specified = true;
44340b57cec5SDimitry Andric break;
44350b57cec5SDimitry Andric
44360b57cec5SDimitry Andric case 'x':
44370b57cec5SDimitry Andric if (option_arg.getAsInteger(0, m_thread_index))
44380b57cec5SDimitry Andric error.SetErrorStringWithFormat("invalid thread index string '%s'",
44390b57cec5SDimitry Andric option_arg.str().c_str());
44400b57cec5SDimitry Andric m_thread_specified = true;
44410b57cec5SDimitry Andric break;
44420b57cec5SDimitry Andric
44430b57cec5SDimitry Andric case 'o':
44440b57cec5SDimitry Andric m_use_one_liner = true;
44455ffd83dbSDimitry Andric m_one_liner.push_back(std::string(option_arg));
44460b57cec5SDimitry Andric break;
44470b57cec5SDimitry Andric
44480b57cec5SDimitry Andric default:
44499dba64beSDimitry Andric llvm_unreachable("Unimplemented option");
44500b57cec5SDimitry Andric }
44510b57cec5SDimitry Andric return error;
44520b57cec5SDimitry Andric }
44530b57cec5SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)44540b57cec5SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
44550b57cec5SDimitry Andric m_class_name.clear();
44560b57cec5SDimitry Andric m_function_name.clear();
44570b57cec5SDimitry Andric m_line_start = 0;
44580b57cec5SDimitry Andric m_line_end = UINT_MAX;
44590b57cec5SDimitry Andric m_file_name.clear();
44600b57cec5SDimitry Andric m_module_name.clear();
44610b57cec5SDimitry Andric m_func_name_type_mask = eFunctionNameTypeAuto;
44620b57cec5SDimitry Andric m_thread_id = LLDB_INVALID_THREAD_ID;
44630b57cec5SDimitry Andric m_thread_index = UINT32_MAX;
44640b57cec5SDimitry Andric m_thread_name.clear();
44650b57cec5SDimitry Andric m_queue_name.clear();
44660b57cec5SDimitry Andric
44670b57cec5SDimitry Andric m_no_inlines = false;
44680b57cec5SDimitry Andric m_sym_ctx_specified = false;
44690b57cec5SDimitry Andric m_thread_specified = false;
44700b57cec5SDimitry Andric
44710b57cec5SDimitry Andric m_use_one_liner = false;
44720b57cec5SDimitry Andric m_one_liner.clear();
44730b57cec5SDimitry Andric m_auto_continue = false;
44740b57cec5SDimitry Andric }
44750b57cec5SDimitry Andric
44760b57cec5SDimitry Andric std::string m_class_name;
44770b57cec5SDimitry Andric std::string m_function_name;
4478*5f7ddb14SDimitry Andric uint32_t m_line_start = 0;
44790b57cec5SDimitry Andric uint32_t m_line_end;
44800b57cec5SDimitry Andric std::string m_file_name;
44810b57cec5SDimitry Andric std::string m_module_name;
4482*5f7ddb14SDimitry Andric uint32_t m_func_name_type_mask =
4483*5f7ddb14SDimitry Andric eFunctionNameTypeAuto; // A pick from lldb::FunctionNameType.
44840b57cec5SDimitry Andric lldb::tid_t m_thread_id;
44850b57cec5SDimitry Andric uint32_t m_thread_index;
44860b57cec5SDimitry Andric std::string m_thread_name;
44870b57cec5SDimitry Andric std::string m_queue_name;
4488*5f7ddb14SDimitry Andric bool m_sym_ctx_specified = false;
44890b57cec5SDimitry Andric bool m_no_inlines;
4490*5f7ddb14SDimitry Andric bool m_thread_specified = false;
44910b57cec5SDimitry Andric // Instance variables to hold the values for one_liner options.
4492*5f7ddb14SDimitry Andric bool m_use_one_liner = false;
44930b57cec5SDimitry Andric std::vector<std::string> m_one_liner;
4494af732203SDimitry Andric
44950b57cec5SDimitry Andric bool m_auto_continue;
44960b57cec5SDimitry Andric };
44970b57cec5SDimitry Andric
CommandObjectTargetStopHookAdd(CommandInterpreter & interpreter)44980b57cec5SDimitry Andric CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
44990b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "target stop-hook add",
4500af732203SDimitry Andric "Add a hook to be executed when the target stops."
4501af732203SDimitry Andric "The hook can either be a list of commands or an "
4502af732203SDimitry Andric "appropriately defined Python class. You can also "
4503af732203SDimitry Andric "add filters so the hook only runs a certain stop "
4504af732203SDimitry Andric "points.",
45050b57cec5SDimitry Andric "target stop-hook add"),
45060b57cec5SDimitry Andric IOHandlerDelegateMultiline("DONE",
45070b57cec5SDimitry Andric IOHandlerDelegate::Completion::LLDBCommand),
4508af732203SDimitry Andric m_options(), m_python_class_options("scripted stop-hook", true, 'P') {
4509af732203SDimitry Andric SetHelpLong(
4510af732203SDimitry Andric R"(
4511af732203SDimitry Andric Command Based stop-hooks:
4512af732203SDimitry Andric -------------------------
4513af732203SDimitry Andric Stop hooks can run a list of lldb commands by providing one or more
4514af732203SDimitry Andric --one-line-command options. The commands will get run in the order they are
4515af732203SDimitry Andric added. Or you can provide no commands, in which case you will enter a
4516af732203SDimitry Andric command editor where you can enter the commands to be run.
4517af732203SDimitry Andric
4518af732203SDimitry Andric Python Based Stop Hooks:
4519af732203SDimitry Andric ------------------------
4520af732203SDimitry Andric Stop hooks can be implemented with a suitably defined Python class, whose name
4521af732203SDimitry Andric is passed in the --python-class option.
4522af732203SDimitry Andric
4523af732203SDimitry Andric When the stop hook is added, the class is initialized by calling:
4524af732203SDimitry Andric
4525*5f7ddb14SDimitry Andric def __init__(self, target, extra_args, internal_dict):
4526af732203SDimitry Andric
4527af732203SDimitry Andric target: The target that the stop hook is being added to.
4528af732203SDimitry Andric extra_args: An SBStructuredData Dictionary filled with the -key -value
4529af732203SDimitry Andric option pairs passed to the command.
4530af732203SDimitry Andric dict: An implementation detail provided by lldb.
4531af732203SDimitry Andric
4532af732203SDimitry Andric Then when the stop-hook triggers, lldb will run the 'handle_stop' method.
4533af732203SDimitry Andric The method has the signature:
4534af732203SDimitry Andric
4535af732203SDimitry Andric def handle_stop(self, exe_ctx, stream):
4536af732203SDimitry Andric
4537af732203SDimitry Andric exe_ctx: An SBExecutionContext for the thread that has stopped.
4538af732203SDimitry Andric stream: An SBStream, anything written to this stream will be printed in the
4539af732203SDimitry Andric the stop message when the process stops.
4540af732203SDimitry Andric
4541af732203SDimitry Andric Return Value: The method returns "should_stop". If should_stop is false
4542af732203SDimitry Andric from all the stop hook executions on threads that stopped
4543af732203SDimitry Andric with a reason, then the process will continue. Note that this
4544af732203SDimitry Andric will happen only after all the stop hooks are run.
4545af732203SDimitry Andric
4546af732203SDimitry Andric Filter Options:
4547af732203SDimitry Andric ---------------
4548af732203SDimitry Andric Stop hooks can be set to always run, or to only run when the stopped thread
4549af732203SDimitry Andric matches the filter options passed on the command line. The available filter
4550af732203SDimitry Andric options include a shared library or a thread or queue specification,
4551af732203SDimitry Andric a line range in a source file, a function name or a class name.
4552af732203SDimitry Andric )");
4553af732203SDimitry Andric m_all_options.Append(&m_python_class_options,
4554af732203SDimitry Andric LLDB_OPT_SET_1 | LLDB_OPT_SET_2,
4555af732203SDimitry Andric LLDB_OPT_SET_FROM_TO(4, 6));
4556af732203SDimitry Andric m_all_options.Append(&m_options);
4557af732203SDimitry Andric m_all_options.Finalize();
4558af732203SDimitry Andric }
45590b57cec5SDimitry Andric
45600b57cec5SDimitry Andric ~CommandObjectTargetStopHookAdd() override = default;
45610b57cec5SDimitry Andric
GetOptions()4562af732203SDimitry Andric Options *GetOptions() override { return &m_all_options; }
45630b57cec5SDimitry Andric
45640b57cec5SDimitry Andric protected:
IOHandlerActivated(IOHandler & io_handler,bool interactive)45650b57cec5SDimitry Andric void IOHandlerActivated(IOHandler &io_handler, bool interactive) override {
45669dba64beSDimitry Andric StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
45670b57cec5SDimitry Andric if (output_sp && interactive) {
45680b57cec5SDimitry Andric output_sp->PutCString(
45690b57cec5SDimitry Andric "Enter your stop hook command(s). Type 'DONE' to end.\n");
45700b57cec5SDimitry Andric output_sp->Flush();
45710b57cec5SDimitry Andric }
45720b57cec5SDimitry Andric }
45730b57cec5SDimitry Andric
IOHandlerInputComplete(IOHandler & io_handler,std::string & line)45740b57cec5SDimitry Andric void IOHandlerInputComplete(IOHandler &io_handler,
45750b57cec5SDimitry Andric std::string &line) override {
45760b57cec5SDimitry Andric if (m_stop_hook_sp) {
45770b57cec5SDimitry Andric if (line.empty()) {
45789dba64beSDimitry Andric StreamFileSP error_sp(io_handler.GetErrorStreamFileSP());
45790b57cec5SDimitry Andric if (error_sp) {
45800b57cec5SDimitry Andric error_sp->Printf("error: stop hook #%" PRIu64
45810b57cec5SDimitry Andric " aborted, no commands.\n",
45820b57cec5SDimitry Andric m_stop_hook_sp->GetID());
45830b57cec5SDimitry Andric error_sp->Flush();
45840b57cec5SDimitry Andric }
45850b57cec5SDimitry Andric Target *target = GetDebugger().GetSelectedTarget().get();
4586af732203SDimitry Andric if (target) {
4587af732203SDimitry Andric target->UndoCreateStopHook(m_stop_hook_sp->GetID());
4588af732203SDimitry Andric }
45890b57cec5SDimitry Andric } else {
4590af732203SDimitry Andric // The IOHandler editor is only for command lines stop hooks:
4591af732203SDimitry Andric Target::StopHookCommandLine *hook_ptr =
4592af732203SDimitry Andric static_cast<Target::StopHookCommandLine *>(m_stop_hook_sp.get());
4593af732203SDimitry Andric
4594af732203SDimitry Andric hook_ptr->SetActionFromString(line);
45959dba64beSDimitry Andric StreamFileSP output_sp(io_handler.GetOutputStreamFileSP());
45960b57cec5SDimitry Andric if (output_sp) {
45970b57cec5SDimitry Andric output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
45980b57cec5SDimitry Andric m_stop_hook_sp->GetID());
45990b57cec5SDimitry Andric output_sp->Flush();
46000b57cec5SDimitry Andric }
46010b57cec5SDimitry Andric }
46020b57cec5SDimitry Andric m_stop_hook_sp.reset();
46030b57cec5SDimitry Andric }
46040b57cec5SDimitry Andric io_handler.SetIsDone(true);
46050b57cec5SDimitry Andric }
46060b57cec5SDimitry Andric
DoExecute(Args & command,CommandReturnObject & result)46070b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
46080b57cec5SDimitry Andric m_stop_hook_sp.reset();
46090b57cec5SDimitry Andric
46109dba64beSDimitry Andric Target &target = GetSelectedOrDummyTarget();
4611af732203SDimitry Andric Target::StopHookSP new_hook_sp =
4612af732203SDimitry Andric target.CreateStopHook(m_python_class_options.GetName().empty() ?
4613af732203SDimitry Andric Target::StopHook::StopHookKind::CommandBased
4614af732203SDimitry Andric : Target::StopHook::StopHookKind::ScriptBased);
46150b57cec5SDimitry Andric
46160b57cec5SDimitry Andric // First step, make the specifier.
46170b57cec5SDimitry Andric std::unique_ptr<SymbolContextSpecifier> specifier_up;
46180b57cec5SDimitry Andric if (m_options.m_sym_ctx_specified) {
46195ffd83dbSDimitry Andric specifier_up = std::make_unique<SymbolContextSpecifier>(
46205ffd83dbSDimitry Andric GetDebugger().GetSelectedTarget());
46210b57cec5SDimitry Andric
46220b57cec5SDimitry Andric if (!m_options.m_module_name.empty()) {
46230b57cec5SDimitry Andric specifier_up->AddSpecification(
46240b57cec5SDimitry Andric m_options.m_module_name.c_str(),
46250b57cec5SDimitry Andric SymbolContextSpecifier::eModuleSpecified);
46260b57cec5SDimitry Andric }
46270b57cec5SDimitry Andric
46280b57cec5SDimitry Andric if (!m_options.m_class_name.empty()) {
46290b57cec5SDimitry Andric specifier_up->AddSpecification(
46300b57cec5SDimitry Andric m_options.m_class_name.c_str(),
46310b57cec5SDimitry Andric SymbolContextSpecifier::eClassOrNamespaceSpecified);
46320b57cec5SDimitry Andric }
46330b57cec5SDimitry Andric
46340b57cec5SDimitry Andric if (!m_options.m_file_name.empty()) {
46359dba64beSDimitry Andric specifier_up->AddSpecification(m_options.m_file_name.c_str(),
46360b57cec5SDimitry Andric SymbolContextSpecifier::eFileSpecified);
46370b57cec5SDimitry Andric }
46380b57cec5SDimitry Andric
46390b57cec5SDimitry Andric if (m_options.m_line_start != 0) {
46400b57cec5SDimitry Andric specifier_up->AddLineSpecification(
46410b57cec5SDimitry Andric m_options.m_line_start,
46420b57cec5SDimitry Andric SymbolContextSpecifier::eLineStartSpecified);
46430b57cec5SDimitry Andric }
46440b57cec5SDimitry Andric
46450b57cec5SDimitry Andric if (m_options.m_line_end != UINT_MAX) {
46460b57cec5SDimitry Andric specifier_up->AddLineSpecification(
46470b57cec5SDimitry Andric m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
46480b57cec5SDimitry Andric }
46490b57cec5SDimitry Andric
46500b57cec5SDimitry Andric if (!m_options.m_function_name.empty()) {
46510b57cec5SDimitry Andric specifier_up->AddSpecification(
46520b57cec5SDimitry Andric m_options.m_function_name.c_str(),
46530b57cec5SDimitry Andric SymbolContextSpecifier::eFunctionSpecified);
46540b57cec5SDimitry Andric }
46550b57cec5SDimitry Andric }
46560b57cec5SDimitry Andric
46570b57cec5SDimitry Andric if (specifier_up)
46580b57cec5SDimitry Andric new_hook_sp->SetSpecifier(specifier_up.release());
46590b57cec5SDimitry Andric
46600b57cec5SDimitry Andric // Next see if any of the thread options have been entered:
46610b57cec5SDimitry Andric
46620b57cec5SDimitry Andric if (m_options.m_thread_specified) {
46630b57cec5SDimitry Andric ThreadSpec *thread_spec = new ThreadSpec();
46640b57cec5SDimitry Andric
46650b57cec5SDimitry Andric if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
46660b57cec5SDimitry Andric thread_spec->SetTID(m_options.m_thread_id);
46670b57cec5SDimitry Andric }
46680b57cec5SDimitry Andric
46690b57cec5SDimitry Andric if (m_options.m_thread_index != UINT32_MAX)
46700b57cec5SDimitry Andric thread_spec->SetIndex(m_options.m_thread_index);
46710b57cec5SDimitry Andric
46720b57cec5SDimitry Andric if (!m_options.m_thread_name.empty())
46730b57cec5SDimitry Andric thread_spec->SetName(m_options.m_thread_name.c_str());
46740b57cec5SDimitry Andric
46750b57cec5SDimitry Andric if (!m_options.m_queue_name.empty())
46760b57cec5SDimitry Andric thread_spec->SetQueueName(m_options.m_queue_name.c_str());
46770b57cec5SDimitry Andric
46780b57cec5SDimitry Andric new_hook_sp->SetThreadSpecifier(thread_spec);
46790b57cec5SDimitry Andric }
46800b57cec5SDimitry Andric
46810b57cec5SDimitry Andric new_hook_sp->SetAutoContinue(m_options.m_auto_continue);
46820b57cec5SDimitry Andric if (m_options.m_use_one_liner) {
4683af732203SDimitry Andric // This is a command line stop hook:
4684af732203SDimitry Andric Target::StopHookCommandLine *hook_ptr =
4685af732203SDimitry Andric static_cast<Target::StopHookCommandLine *>(new_hook_sp.get());
4686af732203SDimitry Andric hook_ptr->SetActionFromStrings(m_options.m_one_liner);
46870b57cec5SDimitry Andric result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
46880b57cec5SDimitry Andric new_hook_sp->GetID());
4689af732203SDimitry Andric } else if (!m_python_class_options.GetName().empty()) {
4690af732203SDimitry Andric // This is a scripted stop hook:
4691af732203SDimitry Andric Target::StopHookScripted *hook_ptr =
4692af732203SDimitry Andric static_cast<Target::StopHookScripted *>(new_hook_sp.get());
4693af732203SDimitry Andric Status error = hook_ptr->SetScriptCallback(
4694af732203SDimitry Andric m_python_class_options.GetName(),
4695af732203SDimitry Andric m_python_class_options.GetStructuredData());
4696af732203SDimitry Andric if (error.Success())
4697af732203SDimitry Andric result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4698af732203SDimitry Andric new_hook_sp->GetID());
4699af732203SDimitry Andric else {
4700af732203SDimitry Andric // FIXME: Set the stop hook ID counter back.
4701af732203SDimitry Andric result.AppendErrorWithFormat("Couldn't add stop hook: %s",
4702af732203SDimitry Andric error.AsCString());
4703af732203SDimitry Andric target.UndoCreateStopHook(new_hook_sp->GetID());
4704af732203SDimitry Andric return false;
4705af732203SDimitry Andric }
47060b57cec5SDimitry Andric } else {
47070b57cec5SDimitry Andric m_stop_hook_sp = new_hook_sp;
4708480093f4SDimitry Andric m_interpreter.GetLLDBCommandsFromIOHandler("> ", // Prompt
4709480093f4SDimitry Andric *this); // IOHandlerDelegate
47100b57cec5SDimitry Andric }
47110b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult);
47120b57cec5SDimitry Andric
47130b57cec5SDimitry Andric return result.Succeeded();
47140b57cec5SDimitry Andric }
47150b57cec5SDimitry Andric
47160b57cec5SDimitry Andric private:
47170b57cec5SDimitry Andric CommandOptions m_options;
4718af732203SDimitry Andric OptionGroupPythonClassWithDict m_python_class_options;
4719af732203SDimitry Andric OptionGroupOptions m_all_options;
4720af732203SDimitry Andric
47210b57cec5SDimitry Andric Target::StopHookSP m_stop_hook_sp;
47220b57cec5SDimitry Andric };
47230b57cec5SDimitry Andric
47240b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookDelete
47250b57cec5SDimitry Andric
47260b57cec5SDimitry Andric // CommandObjectTargetStopHookDelete
47270b57cec5SDimitry Andric
47280b57cec5SDimitry Andric class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
47290b57cec5SDimitry Andric public:
CommandObjectTargetStopHookDelete(CommandInterpreter & interpreter)47300b57cec5SDimitry Andric CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
47310b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "target stop-hook delete",
47320b57cec5SDimitry Andric "Delete a stop-hook.",
47330b57cec5SDimitry Andric "target stop-hook delete [<idx>]") {}
47340b57cec5SDimitry Andric
47350b57cec5SDimitry Andric ~CommandObjectTargetStopHookDelete() override = default;
47360b57cec5SDimitry Andric
4737af732203SDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)4738af732203SDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
4739af732203SDimitry Andric OptionElementVector &opt_element_vector) override {
4740af732203SDimitry Andric CommandCompletions::InvokeCommonCompletionCallbacks(
4741af732203SDimitry Andric GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
4742af732203SDimitry Andric request, nullptr);
4743af732203SDimitry Andric }
4744af732203SDimitry Andric
47450b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)47460b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
47479dba64beSDimitry Andric Target &target = GetSelectedOrDummyTarget();
47480b57cec5SDimitry Andric // FIXME: see if we can use the breakpoint id style parser?
47490b57cec5SDimitry Andric size_t num_args = command.GetArgumentCount();
47500b57cec5SDimitry Andric if (num_args == 0) {
47510b57cec5SDimitry Andric if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
47520b57cec5SDimitry Andric result.SetStatus(eReturnStatusFailed);
47530b57cec5SDimitry Andric return false;
47540b57cec5SDimitry Andric } else {
47559dba64beSDimitry Andric target.RemoveAllStopHooks();
47560b57cec5SDimitry Andric }
47570b57cec5SDimitry Andric } else {
47580b57cec5SDimitry Andric for (size_t i = 0; i < num_args; i++) {
47595ffd83dbSDimitry Andric lldb::user_id_t user_id;
47605ffd83dbSDimitry Andric if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
47610b57cec5SDimitry Andric result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
47620b57cec5SDimitry Andric command.GetArgumentAtIndex(i));
47630b57cec5SDimitry Andric return false;
47640b57cec5SDimitry Andric }
47655ffd83dbSDimitry Andric if (!target.RemoveStopHookByID(user_id)) {
47660b57cec5SDimitry Andric result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
47670b57cec5SDimitry Andric command.GetArgumentAtIndex(i));
47680b57cec5SDimitry Andric return false;
47690b57cec5SDimitry Andric }
47700b57cec5SDimitry Andric }
47710b57cec5SDimitry Andric }
47720b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult);
47730b57cec5SDimitry Andric return result.Succeeded();
47740b57cec5SDimitry Andric }
47750b57cec5SDimitry Andric };
47760b57cec5SDimitry Andric
47770b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookEnableDisable
47780b57cec5SDimitry Andric
47790b57cec5SDimitry Andric // CommandObjectTargetStopHookEnableDisable
47800b57cec5SDimitry Andric
47810b57cec5SDimitry Andric class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
47820b57cec5SDimitry Andric public:
CommandObjectTargetStopHookEnableDisable(CommandInterpreter & interpreter,bool enable,const char * name,const char * help,const char * syntax)47830b57cec5SDimitry Andric CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
47840b57cec5SDimitry Andric bool enable, const char *name,
47850b57cec5SDimitry Andric const char *help, const char *syntax)
47860b57cec5SDimitry Andric : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
47870b57cec5SDimitry Andric }
47880b57cec5SDimitry Andric
47890b57cec5SDimitry Andric ~CommandObjectTargetStopHookEnableDisable() override = default;
47900b57cec5SDimitry Andric
4791af732203SDimitry Andric void
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)4792af732203SDimitry Andric HandleArgumentCompletion(CompletionRequest &request,
4793af732203SDimitry Andric OptionElementVector &opt_element_vector) override {
4794af732203SDimitry Andric if (request.GetCursorIndex())
4795af732203SDimitry Andric return;
4796af732203SDimitry Andric CommandCompletions::InvokeCommonCompletionCallbacks(
4797af732203SDimitry Andric GetCommandInterpreter(), CommandCompletions::eStopHookIDCompletion,
4798af732203SDimitry Andric request, nullptr);
4799af732203SDimitry Andric }
4800af732203SDimitry Andric
48010b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)48020b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
48039dba64beSDimitry Andric Target &target = GetSelectedOrDummyTarget();
48040b57cec5SDimitry Andric // FIXME: see if we can use the breakpoint id style parser?
48050b57cec5SDimitry Andric size_t num_args = command.GetArgumentCount();
48060b57cec5SDimitry Andric bool success;
48070b57cec5SDimitry Andric
48080b57cec5SDimitry Andric if (num_args == 0) {
48099dba64beSDimitry Andric target.SetAllStopHooksActiveState(m_enable);
48100b57cec5SDimitry Andric } else {
48110b57cec5SDimitry Andric for (size_t i = 0; i < num_args; i++) {
48125ffd83dbSDimitry Andric lldb::user_id_t user_id;
48135ffd83dbSDimitry Andric if (!llvm::to_integer(command.GetArgumentAtIndex(i), user_id)) {
48140b57cec5SDimitry Andric result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
48150b57cec5SDimitry Andric command.GetArgumentAtIndex(i));
48160b57cec5SDimitry Andric return false;
48170b57cec5SDimitry Andric }
48189dba64beSDimitry Andric success = target.SetStopHookActiveStateByID(user_id, m_enable);
48190b57cec5SDimitry Andric if (!success) {
48200b57cec5SDimitry Andric result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
48210b57cec5SDimitry Andric command.GetArgumentAtIndex(i));
48220b57cec5SDimitry Andric return false;
48230b57cec5SDimitry Andric }
48240b57cec5SDimitry Andric }
48250b57cec5SDimitry Andric }
48260b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishNoResult);
48270b57cec5SDimitry Andric return result.Succeeded();
48280b57cec5SDimitry Andric }
48290b57cec5SDimitry Andric
48300b57cec5SDimitry Andric private:
48310b57cec5SDimitry Andric bool m_enable;
48320b57cec5SDimitry Andric };
48330b57cec5SDimitry Andric
48340b57cec5SDimitry Andric #pragma mark CommandObjectTargetStopHookList
48350b57cec5SDimitry Andric
48360b57cec5SDimitry Andric // CommandObjectTargetStopHookList
48370b57cec5SDimitry Andric
48380b57cec5SDimitry Andric class CommandObjectTargetStopHookList : public CommandObjectParsed {
48390b57cec5SDimitry Andric public:
CommandObjectTargetStopHookList(CommandInterpreter & interpreter)48400b57cec5SDimitry Andric CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
48410b57cec5SDimitry Andric : CommandObjectParsed(interpreter, "target stop-hook list",
48420b57cec5SDimitry Andric "List all stop-hooks.",
48430b57cec5SDimitry Andric "target stop-hook list [<type>]") {}
48440b57cec5SDimitry Andric
48450b57cec5SDimitry Andric ~CommandObjectTargetStopHookList() override = default;
48460b57cec5SDimitry Andric
48470b57cec5SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)48480b57cec5SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
48499dba64beSDimitry Andric Target &target = GetSelectedOrDummyTarget();
48500b57cec5SDimitry Andric
48519dba64beSDimitry Andric size_t num_hooks = target.GetNumStopHooks();
48520b57cec5SDimitry Andric if (num_hooks == 0) {
48530b57cec5SDimitry Andric result.GetOutputStream().PutCString("No stop hooks.\n");
48540b57cec5SDimitry Andric } else {
48550b57cec5SDimitry Andric for (size_t i = 0; i < num_hooks; i++) {
48569dba64beSDimitry Andric Target::StopHookSP this_hook = target.GetStopHookAtIndex(i);
48570b57cec5SDimitry Andric if (i > 0)
48580b57cec5SDimitry Andric result.GetOutputStream().PutCString("\n");
48590b57cec5SDimitry Andric this_hook->GetDescription(&(result.GetOutputStream()),
48600b57cec5SDimitry Andric eDescriptionLevelFull);
48610b57cec5SDimitry Andric }
48620b57cec5SDimitry Andric }
48630b57cec5SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
48640b57cec5SDimitry Andric return result.Succeeded();
48650b57cec5SDimitry Andric }
48660b57cec5SDimitry Andric };
48670b57cec5SDimitry Andric
48680b57cec5SDimitry Andric #pragma mark CommandObjectMultiwordTargetStopHooks
48690b57cec5SDimitry Andric
48700b57cec5SDimitry Andric // CommandObjectMultiwordTargetStopHooks
48710b57cec5SDimitry Andric
48720b57cec5SDimitry Andric class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
48730b57cec5SDimitry Andric public:
CommandObjectMultiwordTargetStopHooks(CommandInterpreter & interpreter)48740b57cec5SDimitry Andric CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
48750b57cec5SDimitry Andric : CommandObjectMultiword(
48760b57cec5SDimitry Andric interpreter, "target stop-hook",
48770b57cec5SDimitry Andric "Commands for operating on debugger target stop-hooks.",
48780b57cec5SDimitry Andric "target stop-hook <subcommand> [<subcommand-options>]") {
48790b57cec5SDimitry Andric LoadSubCommand("add", CommandObjectSP(
48800b57cec5SDimitry Andric new CommandObjectTargetStopHookAdd(interpreter)));
48810b57cec5SDimitry Andric LoadSubCommand(
48820b57cec5SDimitry Andric "delete",
48830b57cec5SDimitry Andric CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
48840b57cec5SDimitry Andric LoadSubCommand("disable",
48850b57cec5SDimitry Andric CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
48860b57cec5SDimitry Andric interpreter, false, "target stop-hook disable [<id>]",
48870b57cec5SDimitry Andric "Disable a stop-hook.", "target stop-hook disable")));
48880b57cec5SDimitry Andric LoadSubCommand("enable",
48890b57cec5SDimitry Andric CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
48900b57cec5SDimitry Andric interpreter, true, "target stop-hook enable [<id>]",
48910b57cec5SDimitry Andric "Enable a stop-hook.", "target stop-hook enable")));
48920b57cec5SDimitry Andric LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
48930b57cec5SDimitry Andric interpreter)));
48940b57cec5SDimitry Andric }
48950b57cec5SDimitry Andric
48960b57cec5SDimitry Andric ~CommandObjectMultiwordTargetStopHooks() override = default;
48970b57cec5SDimitry Andric };
48980b57cec5SDimitry Andric
48990b57cec5SDimitry Andric #pragma mark CommandObjectMultiwordTarget
49000b57cec5SDimitry Andric
49010b57cec5SDimitry Andric // CommandObjectMultiwordTarget
49020b57cec5SDimitry Andric
CommandObjectMultiwordTarget(CommandInterpreter & interpreter)49030b57cec5SDimitry Andric CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
49040b57cec5SDimitry Andric CommandInterpreter &interpreter)
49050b57cec5SDimitry Andric : CommandObjectMultiword(interpreter, "target",
49060b57cec5SDimitry Andric "Commands for operating on debugger targets.",
49070b57cec5SDimitry Andric "target <subcommand> [<subcommand-options>]") {
49080b57cec5SDimitry Andric LoadSubCommand("create",
49090b57cec5SDimitry Andric CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
49100b57cec5SDimitry Andric LoadSubCommand("delete",
49110b57cec5SDimitry Andric CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
49120b57cec5SDimitry Andric LoadSubCommand("list",
49130b57cec5SDimitry Andric CommandObjectSP(new CommandObjectTargetList(interpreter)));
49140b57cec5SDimitry Andric LoadSubCommand("select",
49150b57cec5SDimitry Andric CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
49165ffd83dbSDimitry Andric LoadSubCommand("show-launch-environment",
49175ffd83dbSDimitry Andric CommandObjectSP(new CommandObjectTargetShowLaunchEnvironment(
49185ffd83dbSDimitry Andric interpreter)));
49190b57cec5SDimitry Andric LoadSubCommand(
49200b57cec5SDimitry Andric "stop-hook",
49210b57cec5SDimitry Andric CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
49220b57cec5SDimitry Andric LoadSubCommand("modules",
49230b57cec5SDimitry Andric CommandObjectSP(new CommandObjectTargetModules(interpreter)));
49240b57cec5SDimitry Andric LoadSubCommand("symbols",
49250b57cec5SDimitry Andric CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
49260b57cec5SDimitry Andric LoadSubCommand("variable",
49270b57cec5SDimitry Andric CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
49280b57cec5SDimitry Andric }
49290b57cec5SDimitry Andric
49300b57cec5SDimitry Andric CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
4931