1ac7ddfbfSEd Maste //===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===//
2ac7ddfbfSEd Maste //
3ac7ddfbfSEd Maste // The LLVM Compiler Infrastructure
4ac7ddfbfSEd Maste //
5ac7ddfbfSEd Maste // This file is distributed under the University of Illinois Open Source
6ac7ddfbfSEd Maste // License. See LICENSE.TXT for details.
7ac7ddfbfSEd Maste //
8ac7ddfbfSEd Maste //===----------------------------------------------------------------------===//
9ac7ddfbfSEd Maste
10ac7ddfbfSEd Maste #include "CommandObjectTarget.h"
11ac7ddfbfSEd Maste
12ac7ddfbfSEd Maste #include "lldb/Core/Debugger.h"
1312b93ac6SEd Maste #include "lldb/Core/IOHandler.h"
14ac7ddfbfSEd Maste #include "lldb/Core/Module.h"
15ac7ddfbfSEd Maste #include "lldb/Core/ModuleSpec.h"
16ac7ddfbfSEd Maste #include "lldb/Core/Section.h"
17ac7ddfbfSEd Maste #include "lldb/Core/ValueObjectVariable.h"
1835617911SEd Maste #include "lldb/DataFormatters/ValueObjectPrinter.h"
19f678e45dSDimitry Andric #include "lldb/Host/OptionParser.h"
201c3bbb01SEd Maste #include "lldb/Host/StringConvert.h"
21ac7ddfbfSEd Maste #include "lldb/Host/Symbols.h"
22ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandInterpreter.h"
23ac7ddfbfSEd Maste #include "lldb/Interpreter/CommandReturnObject.h"
244ba319b5SDimitry Andric #include "lldb/Interpreter/OptionArgParser.h"
25ac7ddfbfSEd Maste #include "lldb/Interpreter/OptionGroupArchitecture.h"
26ac7ddfbfSEd Maste #include "lldb/Interpreter/OptionGroupBoolean.h"
27ac7ddfbfSEd Maste #include "lldb/Interpreter/OptionGroupFile.h"
28ac7ddfbfSEd Maste #include "lldb/Interpreter/OptionGroupFormat.h"
29ac7ddfbfSEd Maste #include "lldb/Interpreter/OptionGroupPlatform.h"
30435933ddSDimitry Andric #include "lldb/Interpreter/OptionGroupString.h"
31ac7ddfbfSEd Maste #include "lldb/Interpreter/OptionGroupUInt64.h"
32ac7ddfbfSEd Maste #include "lldb/Interpreter/OptionGroupUUID.h"
33ac7ddfbfSEd Maste #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
34435933ddSDimitry Andric #include "lldb/Interpreter/OptionGroupVariable.h"
35435933ddSDimitry Andric #include "lldb/Interpreter/Options.h"
36ac7ddfbfSEd Maste #include "lldb/Symbol/CompileUnit.h"
37ac7ddfbfSEd Maste #include "lldb/Symbol/FuncUnwinders.h"
38ac7ddfbfSEd Maste #include "lldb/Symbol/LineTable.h"
39ac7ddfbfSEd Maste #include "lldb/Symbol/ObjectFile.h"
40ac7ddfbfSEd Maste #include "lldb/Symbol/SymbolFile.h"
41ac7ddfbfSEd Maste #include "lldb/Symbol/SymbolVendor.h"
42ac7ddfbfSEd Maste #include "lldb/Symbol/UnwindPlan.h"
43ac7ddfbfSEd Maste #include "lldb/Symbol/VariableList.h"
441c3bbb01SEd Maste #include "lldb/Target/ABI.h"
45ac7ddfbfSEd Maste #include "lldb/Target/Process.h"
464ba319b5SDimitry Andric #include "lldb/Target/RegisterContext.h"
4712b93ac6SEd Maste #include "lldb/Target/SectionLoadList.h"
48ac7ddfbfSEd Maste #include "lldb/Target/StackFrame.h"
49ac7ddfbfSEd Maste #include "lldb/Target/Thread.h"
50ac7ddfbfSEd Maste #include "lldb/Target/ThreadSpec.h"
514ba319b5SDimitry Andric #include "lldb/Utility/Args.h"
52*b5893f02SDimitry Andric #include "lldb/Utility/State.h"
53a580b014SDimitry Andric #include "lldb/Utility/Timer.h"
54ac7ddfbfSEd Maste
55f678e45dSDimitry Andric #include "llvm/Support/FileSystem.h"
56acac075bSDimitry Andric #include "llvm/Support/FormatAdapters.h"
57f678e45dSDimitry Andric
58435933ddSDimitry Andric #include <cerrno>
59435933ddSDimitry Andric
60ac7ddfbfSEd Maste using namespace lldb;
61ac7ddfbfSEd Maste using namespace lldb_private;
62ac7ddfbfSEd Maste
DumpTargetInfo(uint32_t target_idx,Target * target,const char * prefix_cstr,bool show_stopped_process_status,Stream & strm)63435933ddSDimitry Andric static void DumpTargetInfo(uint32_t target_idx, Target *target,
64435933ddSDimitry Andric const char *prefix_cstr,
65435933ddSDimitry Andric bool show_stopped_process_status, Stream &strm) {
66ac7ddfbfSEd Maste const ArchSpec &target_arch = target->GetArchitecture();
67ac7ddfbfSEd Maste
68ac7ddfbfSEd Maste Module *exe_module = target->GetExecutableModulePointer();
69ac7ddfbfSEd Maste char exe_path[PATH_MAX];
70ac7ddfbfSEd Maste bool exe_valid = false;
71ac7ddfbfSEd Maste if (exe_module)
72ac7ddfbfSEd Maste exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
73ac7ddfbfSEd Maste
74ac7ddfbfSEd Maste if (!exe_valid)
75ac7ddfbfSEd Maste ::strcpy(exe_path, "<none>");
76ac7ddfbfSEd Maste
77435933ddSDimitry Andric strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
78435933ddSDimitry Andric exe_path);
79ac7ddfbfSEd Maste
80ac7ddfbfSEd Maste uint32_t properties = 0;
81435933ddSDimitry Andric if (target_arch.IsValid()) {
829f2f44ceSEd Maste strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
839f2f44ceSEd Maste target_arch.DumpTriple(strm);
84ac7ddfbfSEd Maste properties++;
85ac7ddfbfSEd Maste }
86ac7ddfbfSEd Maste PlatformSP platform_sp(target->GetPlatform());
87ac7ddfbfSEd Maste if (platform_sp)
88435933ddSDimitry Andric strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ",
89435933ddSDimitry Andric platform_sp->GetName().GetCString());
90ac7ddfbfSEd Maste
91ac7ddfbfSEd Maste ProcessSP process_sp(target->GetProcessSP());
92ac7ddfbfSEd Maste bool show_process_status = false;
93435933ddSDimitry Andric if (process_sp) {
94ac7ddfbfSEd Maste lldb::pid_t pid = process_sp->GetID();
95ac7ddfbfSEd Maste StateType state = process_sp->GetState();
96ac7ddfbfSEd Maste if (show_stopped_process_status)
97ac7ddfbfSEd Maste show_process_status = StateIsStoppedState(state, true);
98ac7ddfbfSEd Maste const char *state_cstr = StateAsCString(state);
99ac7ddfbfSEd Maste if (pid != LLDB_INVALID_PROCESS_ID)
100ac7ddfbfSEd Maste strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
101ac7ddfbfSEd Maste strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
102ac7ddfbfSEd Maste }
103ac7ddfbfSEd Maste if (properties > 0)
104ac7ddfbfSEd Maste strm.PutCString(" )\n");
105ac7ddfbfSEd Maste else
106ac7ddfbfSEd Maste strm.EOL();
107435933ddSDimitry Andric if (show_process_status) {
108ac7ddfbfSEd Maste const bool only_threads_with_stop_reason = true;
109ac7ddfbfSEd Maste const uint32_t start_frame = 0;
110ac7ddfbfSEd Maste const uint32_t num_frames = 1;
111ac7ddfbfSEd Maste const uint32_t num_frames_with_source = 1;
112435933ddSDimitry Andric const bool stop_format = false;
113ac7ddfbfSEd Maste process_sp->GetStatus(strm);
114435933ddSDimitry Andric process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
115435933ddSDimitry Andric start_frame, num_frames,
116435933ddSDimitry Andric num_frames_with_source, stop_format);
117ac7ddfbfSEd Maste }
118ac7ddfbfSEd Maste }
119ac7ddfbfSEd Maste
DumpTargetList(TargetList & target_list,bool show_stopped_process_status,Stream & strm)120435933ddSDimitry Andric static uint32_t DumpTargetList(TargetList &target_list,
121435933ddSDimitry Andric bool show_stopped_process_status, Stream &strm) {
122ac7ddfbfSEd Maste const uint32_t num_targets = target_list.GetNumTargets();
123435933ddSDimitry Andric if (num_targets) {
124ac7ddfbfSEd Maste TargetSP selected_target_sp(target_list.GetSelectedTarget());
125ac7ddfbfSEd Maste strm.PutCString("Current targets:\n");
126435933ddSDimitry Andric for (uint32_t i = 0; i < num_targets; ++i) {
127ac7ddfbfSEd Maste TargetSP target_sp(target_list.GetTargetAtIndex(i));
128435933ddSDimitry Andric if (target_sp) {
129ac7ddfbfSEd Maste bool is_selected = target_sp.get() == selected_target_sp.get();
130435933ddSDimitry Andric DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
131435933ddSDimitry Andric show_stopped_process_status, strm);
132ac7ddfbfSEd Maste }
133ac7ddfbfSEd Maste }
134ac7ddfbfSEd Maste }
135ac7ddfbfSEd Maste return num_targets;
136ac7ddfbfSEd Maste }
1374bb0738eSEd Maste
138*b5893f02SDimitry Andric // Note that the negation in the argument name causes a slightly confusing
139*b5893f02SDimitry Andric // mapping of the enum values,
140*b5893f02SDimitry Andric static constexpr OptionEnumValueElement g_dependents_enumaration[] = {
141*b5893f02SDimitry Andric {eLoadDependentsDefault, "default",
142*b5893f02SDimitry Andric "Only load dependents when the target is an executable."},
143*b5893f02SDimitry Andric {eLoadDependentsNo, "true",
144*b5893f02SDimitry Andric "Don't load dependents, even if the target is an executable."},
145*b5893f02SDimitry Andric {eLoadDependentsYes, "false",
146*b5893f02SDimitry Andric "Load dependents, even if the target is not an executable."}};
147*b5893f02SDimitry Andric
148*b5893f02SDimitry Andric static constexpr OptionDefinition g_dependents_options[] = {
149*b5893f02SDimitry Andric {LLDB_OPT_SET_1, false, "no-dependents", 'd',
150*b5893f02SDimitry Andric OptionParser::eOptionalArgument, nullptr,
151*b5893f02SDimitry Andric OptionEnumValues(g_dependents_enumaration), 0, eArgTypeValue,
152*b5893f02SDimitry Andric "Whether or not to load dependents when creating a target. If the option "
153*b5893f02SDimitry Andric "is not specified, the value is implicitly 'default'. If the option is "
154*b5893f02SDimitry Andric "specified but without a value, the value is implicitly 'true'."}};
155*b5893f02SDimitry Andric
156*b5893f02SDimitry Andric class OptionGroupDependents : public OptionGroup {
157*b5893f02SDimitry Andric public:
OptionGroupDependents()158*b5893f02SDimitry Andric OptionGroupDependents() {}
159*b5893f02SDimitry Andric
~OptionGroupDependents()160*b5893f02SDimitry Andric ~OptionGroupDependents() override {}
161*b5893f02SDimitry Andric
GetDefinitions()162*b5893f02SDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
163*b5893f02SDimitry Andric return llvm::makeArrayRef(g_dependents_options);
164*b5893f02SDimitry Andric }
165*b5893f02SDimitry Andric
SetOptionValue(uint32_t option_idx,llvm::StringRef option_value,ExecutionContext * execution_context)166*b5893f02SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
167*b5893f02SDimitry Andric ExecutionContext *execution_context) override {
168*b5893f02SDimitry Andric Status error;
169*b5893f02SDimitry Andric
170*b5893f02SDimitry Andric // For compatibility no value means don't load dependents.
171*b5893f02SDimitry Andric if (option_value.empty()) {
172*b5893f02SDimitry Andric m_load_dependent_files = eLoadDependentsNo;
173*b5893f02SDimitry Andric return error;
174*b5893f02SDimitry Andric }
175*b5893f02SDimitry Andric
176*b5893f02SDimitry Andric const char short_option = g_dependents_options[option_idx].short_option;
177*b5893f02SDimitry Andric if (short_option == 'd') {
178*b5893f02SDimitry Andric LoadDependentFiles tmp_load_dependents;
179*b5893f02SDimitry Andric tmp_load_dependents = (LoadDependentFiles)OptionArgParser::ToOptionEnum(
180*b5893f02SDimitry Andric option_value, g_dependents_options[option_idx].enum_values, 0, error);
181*b5893f02SDimitry Andric if (error.Success())
182*b5893f02SDimitry Andric m_load_dependent_files = tmp_load_dependents;
183*b5893f02SDimitry Andric } else {
184*b5893f02SDimitry Andric error.SetErrorStringWithFormat("unrecognized short option '%c'",
185*b5893f02SDimitry Andric short_option);
186*b5893f02SDimitry Andric }
187*b5893f02SDimitry Andric
188*b5893f02SDimitry Andric return error;
189*b5893f02SDimitry Andric }
190*b5893f02SDimitry Andric
191*b5893f02SDimitry Andric Status SetOptionValue(uint32_t, const char *, ExecutionContext *) = delete;
192*b5893f02SDimitry Andric
OptionParsingStarting(ExecutionContext * execution_context)193*b5893f02SDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
194*b5893f02SDimitry Andric m_load_dependent_files = eLoadDependentsDefault;
195*b5893f02SDimitry Andric }
196*b5893f02SDimitry Andric
197*b5893f02SDimitry Andric LoadDependentFiles m_load_dependent_files;
198*b5893f02SDimitry Andric
199*b5893f02SDimitry Andric private:
200*b5893f02SDimitry Andric DISALLOW_COPY_AND_ASSIGN(OptionGroupDependents);
201*b5893f02SDimitry Andric };
202*b5893f02SDimitry Andric
203ac7ddfbfSEd Maste #pragma mark CommandObjectTargetCreate
204ac7ddfbfSEd Maste
205ac7ddfbfSEd Maste //-------------------------------------------------------------------------
206ac7ddfbfSEd Maste // "target create"
207ac7ddfbfSEd Maste //-------------------------------------------------------------------------
208ac7ddfbfSEd Maste
209435933ddSDimitry Andric class CommandObjectTargetCreate : public CommandObjectParsed {
210ac7ddfbfSEd Maste public:
CommandObjectTargetCreate(CommandInterpreter & interpreter)211435933ddSDimitry Andric CommandObjectTargetCreate(CommandInterpreter &interpreter)
212435933ddSDimitry Andric : CommandObjectParsed(
213435933ddSDimitry Andric interpreter, "target create",
214ac7ddfbfSEd Maste "Create a target using the argument as the main executable.",
2154bb0738eSEd Maste nullptr),
216435933ddSDimitry Andric m_option_group(), m_arch_option(),
217435933ddSDimitry Andric m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
218435933ddSDimitry Andric "Fullpath to a core file to use for this target."),
219435933ddSDimitry Andric m_platform_path(LLDB_OPT_SET_1, false, "platform-path", 'P', 0,
220435933ddSDimitry Andric eArgTypePath,
221435933ddSDimitry Andric "Path to the remote file to use for this target."),
222435933ddSDimitry Andric m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
223*b5893f02SDimitry Andric eArgTypeFilename,
224*b5893f02SDimitry Andric "Fullpath to a stand alone debug "
225435933ddSDimitry Andric "symbols file for when debug symbols "
226435933ddSDimitry Andric "are not in the executable."),
227435933ddSDimitry Andric m_remote_file(
228435933ddSDimitry Andric LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
229435933ddSDimitry Andric "Fullpath to the file on the remote host if debugging remotely."),
230*b5893f02SDimitry Andric m_add_dependents() {
231ac7ddfbfSEd Maste CommandArgumentEntry arg;
232ac7ddfbfSEd Maste CommandArgumentData file_arg;
233ac7ddfbfSEd Maste
234ac7ddfbfSEd Maste // Define the first (and only) variant of this arg.
235ac7ddfbfSEd Maste file_arg.arg_type = eArgTypeFilename;
236ac7ddfbfSEd Maste file_arg.arg_repetition = eArgRepeatPlain;
237ac7ddfbfSEd Maste
238435933ddSDimitry Andric // There is only one variant this argument could be; put it into the
239435933ddSDimitry Andric // argument entry.
240ac7ddfbfSEd Maste arg.push_back(file_arg);
241ac7ddfbfSEd Maste
242ac7ddfbfSEd Maste // Push the data for the first argument into the m_arguments vector.
243ac7ddfbfSEd Maste m_arguments.push_back(arg);
244ac7ddfbfSEd Maste
245ac7ddfbfSEd Maste m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
246ac7ddfbfSEd Maste m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
24735617911SEd Maste m_option_group.Append(&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
248ac7ddfbfSEd Maste m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
249ac7ddfbfSEd Maste m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
250ac7ddfbfSEd Maste m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
251ac7ddfbfSEd Maste m_option_group.Finalize();
252ac7ddfbfSEd Maste }
253ac7ddfbfSEd Maste
2544bb0738eSEd Maste ~CommandObjectTargetCreate() override = default;
255ac7ddfbfSEd Maste
GetOptions()256435933ddSDimitry Andric Options *GetOptions() override { return &m_option_group; }
257ac7ddfbfSEd Maste
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)2584ba319b5SDimitry Andric int HandleArgumentCompletion(
2594ba319b5SDimitry Andric CompletionRequest &request,
2604ba319b5SDimitry Andric OptionElementVector &opt_element_vector) override {
261435933ddSDimitry Andric CommandCompletions::InvokeCommonCompletionCallbacks(
262435933ddSDimitry Andric GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2634ba319b5SDimitry Andric request, nullptr);
2644ba319b5SDimitry Andric return request.GetNumberOfMatches();
265ac7ddfbfSEd Maste }
266ac7ddfbfSEd Maste
267ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)268435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
269ac7ddfbfSEd Maste const size_t argc = command.GetArgumentCount();
270ac7ddfbfSEd Maste FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
271ac7ddfbfSEd Maste FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
272ac7ddfbfSEd Maste
273435933ddSDimitry Andric if (core_file) {
274*b5893f02SDimitry Andric if (!FileSystem::Instance().Exists(core_file)) {
275435933ddSDimitry Andric result.AppendErrorWithFormat("core file '%s' doesn't exist",
276435933ddSDimitry Andric core_file.GetPath().c_str());
2770127ef0fSEd Maste result.SetStatus(eReturnStatusFailed);
2780127ef0fSEd Maste return false;
2790127ef0fSEd Maste }
280*b5893f02SDimitry Andric if (!FileSystem::Instance().Readable(core_file)) {
281435933ddSDimitry Andric result.AppendErrorWithFormat("core file '%s' is not readable",
282435933ddSDimitry Andric core_file.GetPath().c_str());
2830127ef0fSEd Maste result.SetStatus(eReturnStatusFailed);
2840127ef0fSEd Maste return false;
2850127ef0fSEd Maste }
2860127ef0fSEd Maste }
2870127ef0fSEd Maste
288435933ddSDimitry Andric if (argc == 1 || core_file || remote_file) {
289ac7ddfbfSEd Maste FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
290435933ddSDimitry Andric if (symfile) {
291*b5893f02SDimitry Andric if (FileSystem::Instance().Exists(symfile)) {
292*b5893f02SDimitry Andric if (!FileSystem::Instance().Readable(symfile)) {
293435933ddSDimitry Andric result.AppendErrorWithFormat("symbol file '%s' is not readable",
294435933ddSDimitry Andric symfile.GetPath().c_str());
2950127ef0fSEd Maste result.SetStatus(eReturnStatusFailed);
2960127ef0fSEd Maste return false;
2970127ef0fSEd Maste }
298435933ddSDimitry Andric } else {
299ac7ddfbfSEd Maste char symfile_path[PATH_MAX];
300ac7ddfbfSEd Maste symfile.GetPath(symfile_path, sizeof(symfile_path));
301435933ddSDimitry Andric result.AppendErrorWithFormat("invalid symbol file path '%s'",
302435933ddSDimitry Andric symfile_path);
303ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
304ac7ddfbfSEd Maste return false;
305ac7ddfbfSEd Maste }
306ac7ddfbfSEd Maste }
307ac7ddfbfSEd Maste
308ac7ddfbfSEd Maste const char *file_path = command.GetArgumentAtIndex(0);
3095517e702SDimitry Andric static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
3105517e702SDimitry Andric Timer scoped_timer(func_cat, "(lldb) target create '%s'", file_path);
31135617911SEd Maste FileSpec file_spec;
31235617911SEd Maste
313*b5893f02SDimitry Andric if (file_path) {
314*b5893f02SDimitry Andric file_spec.SetFile(file_path, FileSpec::Style::native);
315*b5893f02SDimitry Andric FileSystem::Instance().Resolve(file_spec);
316*b5893f02SDimitry Andric }
31735617911SEd Maste
31835617911SEd Maste bool must_set_platform_path = false;
31935617911SEd Maste
320ac7ddfbfSEd Maste Debugger &debugger = m_interpreter.GetDebugger();
3211c3bbb01SEd Maste
3221c3bbb01SEd Maste TargetSP target_sp;
323435933ddSDimitry Andric llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
3245517e702SDimitry Andric Status error(debugger.GetTargetList().CreateTarget(
325*b5893f02SDimitry Andric debugger, file_path, arch_cstr,
326*b5893f02SDimitry Andric m_add_dependents.m_load_dependent_files, nullptr, target_sp));
3271c3bbb01SEd Maste
328435933ddSDimitry Andric if (target_sp) {
329435933ddSDimitry Andric // Only get the platform after we create the target because we might
3304ba319b5SDimitry Andric // have switched platforms depending on what the arguments were to
3314ba319b5SDimitry Andric // CreateTarget() we can't rely on the selected platform.
3321c3bbb01SEd Maste
3331c3bbb01SEd Maste PlatformSP platform_sp = target_sp->GetPlatform();
33435617911SEd Maste
335435933ddSDimitry Andric if (remote_file) {
336435933ddSDimitry Andric if (platform_sp) {
33735617911SEd Maste // I have a remote file.. two possible cases
338*b5893f02SDimitry Andric if (file_spec && FileSystem::Instance().Exists(file_spec)) {
33935617911SEd Maste // if the remote file does not exist, push it there
340435933ddSDimitry Andric if (!platform_sp->GetFileExists(remote_file)) {
3415517e702SDimitry Andric Status err = platform_sp->PutFile(file_spec, remote_file);
342435933ddSDimitry Andric if (err.Fail()) {
34335617911SEd Maste result.AppendError(err.AsCString());
34435617911SEd Maste result.SetStatus(eReturnStatusFailed);
34535617911SEd Maste return false;
34635617911SEd Maste }
34735617911SEd Maste }
348435933ddSDimitry Andric } else {
34935617911SEd Maste // there is no local file and we need one
350435933ddSDimitry Andric // in order to make the remote ---> local transfer we need a
351435933ddSDimitry Andric // platform
352435933ddSDimitry Andric // TODO: if the user has passed in a --platform argument, use it
353435933ddSDimitry Andric // to fetch the right platform
354435933ddSDimitry Andric if (!platform_sp) {
355435933ddSDimitry Andric result.AppendError(
356435933ddSDimitry Andric "unable to perform remote debugging without a platform");
35735617911SEd Maste result.SetStatus(eReturnStatusFailed);
35835617911SEd Maste return false;
35935617911SEd Maste }
360435933ddSDimitry Andric if (file_path) {
36135617911SEd Maste // copy the remote file to the local file
3625517e702SDimitry Andric Status err = platform_sp->GetFile(remote_file, file_spec);
363435933ddSDimitry Andric if (err.Fail()) {
36435617911SEd Maste result.AppendError(err.AsCString());
36535617911SEd Maste result.SetStatus(eReturnStatusFailed);
36635617911SEd Maste return false;
36735617911SEd Maste }
368435933ddSDimitry Andric } else {
36935617911SEd Maste // make up a local file
370435933ddSDimitry Andric result.AppendError("remote --> local transfer without local "
371435933ddSDimitry Andric "path is not implemented yet");
37235617911SEd Maste result.SetStatus(eReturnStatusFailed);
37335617911SEd Maste return false;
37435617911SEd Maste }
37535617911SEd Maste }
376435933ddSDimitry Andric } else {
3771c3bbb01SEd Maste result.AppendError("no platform found for target");
3781c3bbb01SEd Maste result.SetStatus(eReturnStatusFailed);
3791c3bbb01SEd Maste return false;
3801c3bbb01SEd Maste }
3811c3bbb01SEd Maste }
3821c3bbb01SEd Maste
383435933ddSDimitry Andric if (symfile || remote_file) {
384ac7ddfbfSEd Maste ModuleSP module_sp(target_sp->GetExecutableModule());
385435933ddSDimitry Andric if (module_sp) {
386ac7ddfbfSEd Maste if (symfile)
387ac7ddfbfSEd Maste module_sp->SetSymbolFileFileSpec(symfile);
388435933ddSDimitry Andric if (remote_file) {
389ac7ddfbfSEd Maste std::string remote_path = remote_file.GetPath();
390ac7ddfbfSEd Maste target_sp->SetArg0(remote_path.c_str());
391ac7ddfbfSEd Maste module_sp->SetPlatformFileSpec(remote_file);
392ac7ddfbfSEd Maste }
393ac7ddfbfSEd Maste }
394ac7ddfbfSEd Maste }
395ac7ddfbfSEd Maste
396ac7ddfbfSEd Maste debugger.GetTargetList().SetSelectedTarget(target_sp.get());
397435933ddSDimitry Andric if (must_set_platform_path) {
39835617911SEd Maste ModuleSpec main_module_spec(file_spec);
39935617911SEd Maste ModuleSP module_sp = target_sp->GetSharedModule(main_module_spec);
40035617911SEd Maste if (module_sp)
40135617911SEd Maste module_sp->SetPlatformFileSpec(remote_file);
40235617911SEd Maste }
403435933ddSDimitry Andric if (core_file) {
404ac7ddfbfSEd Maste char core_path[PATH_MAX];
405ac7ddfbfSEd Maste core_file.GetPath(core_path, sizeof(core_path));
406*b5893f02SDimitry Andric if (FileSystem::Instance().Exists(core_file)) {
407*b5893f02SDimitry Andric if (!FileSystem::Instance().Readable(core_file)) {
408435933ddSDimitry Andric result.AppendMessageWithFormat(
409435933ddSDimitry Andric "Core file '%s' is not readable.\n", core_path);
4101c3bbb01SEd Maste result.SetStatus(eReturnStatusFailed);
4111c3bbb01SEd Maste return false;
4121c3bbb01SEd Maste }
413ac7ddfbfSEd Maste FileSpec core_file_dir;
414ac7ddfbfSEd Maste core_file_dir.GetDirectory() = core_file.GetDirectory();
415ac7ddfbfSEd Maste target_sp->GetExecutableSearchPaths().Append(core_file_dir);
416ac7ddfbfSEd Maste
417435933ddSDimitry Andric ProcessSP process_sp(target_sp->CreateProcess(
418435933ddSDimitry Andric m_interpreter.GetDebugger().GetListener(), llvm::StringRef(),
419435933ddSDimitry Andric &core_file));
420ac7ddfbfSEd Maste
421435933ddSDimitry Andric if (process_sp) {
4224ba319b5SDimitry Andric // Seems weird that we Launch a core file, but that is what we
4234ba319b5SDimitry Andric // do!
424ac7ddfbfSEd Maste error = process_sp->LoadCore();
425ac7ddfbfSEd Maste
426435933ddSDimitry Andric if (error.Fail()) {
427435933ddSDimitry Andric result.AppendError(
428435933ddSDimitry Andric error.AsCString("can't find plug-in for core file"));
429ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
430ac7ddfbfSEd Maste return false;
431435933ddSDimitry Andric } else {
432435933ddSDimitry Andric result.AppendMessageWithFormat(
433435933ddSDimitry Andric "Core file '%s' (%s) was loaded.\n", core_path,
434435933ddSDimitry Andric target_sp->GetArchitecture().GetArchitectureName());
435ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
436ac7ddfbfSEd Maste }
437435933ddSDimitry Andric } else {
438435933ddSDimitry Andric result.AppendErrorWithFormat(
439435933ddSDimitry Andric "Unable to find process plug-in for core file '%s'\n",
440435933ddSDimitry Andric core_path);
441ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
442ac7ddfbfSEd Maste }
443435933ddSDimitry Andric } else {
444435933ddSDimitry Andric result.AppendErrorWithFormat("Core file '%s' does not exist\n",
445435933ddSDimitry Andric core_path);
446ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
447ac7ddfbfSEd Maste }
448435933ddSDimitry Andric } else {
449435933ddSDimitry Andric result.AppendMessageWithFormat(
450435933ddSDimitry Andric "Current executable set to '%s' (%s).\n", file_path,
451435933ddSDimitry Andric target_sp->GetArchitecture().GetArchitectureName());
452ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
453ac7ddfbfSEd Maste }
454435933ddSDimitry Andric } else {
455ac7ddfbfSEd Maste result.AppendError(error.AsCString());
456ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
457ac7ddfbfSEd Maste }
458435933ddSDimitry Andric } else {
459435933ddSDimitry Andric result.AppendErrorWithFormat("'%s' takes exactly one executable path "
460435933ddSDimitry Andric "argument, or use the --core option.\n",
461435933ddSDimitry Andric m_cmd_name.c_str());
462ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
463ac7ddfbfSEd Maste }
464ac7ddfbfSEd Maste return result.Succeeded();
465ac7ddfbfSEd Maste }
466ac7ddfbfSEd Maste
467ac7ddfbfSEd Maste private:
468ac7ddfbfSEd Maste OptionGroupOptions m_option_group;
469ac7ddfbfSEd Maste OptionGroupArchitecture m_arch_option;
470ac7ddfbfSEd Maste OptionGroupFile m_core_file;
47135617911SEd Maste OptionGroupFile m_platform_path;
472ac7ddfbfSEd Maste OptionGroupFile m_symbol_file;
473ac7ddfbfSEd Maste OptionGroupFile m_remote_file;
474*b5893f02SDimitry Andric OptionGroupDependents m_add_dependents;
475ac7ddfbfSEd Maste };
476ac7ddfbfSEd Maste
477ac7ddfbfSEd Maste #pragma mark CommandObjectTargetList
478ac7ddfbfSEd Maste
479ac7ddfbfSEd Maste //----------------------------------------------------------------------
480ac7ddfbfSEd Maste // "target list"
481ac7ddfbfSEd Maste //----------------------------------------------------------------------
482ac7ddfbfSEd Maste
483435933ddSDimitry Andric class CommandObjectTargetList : public CommandObjectParsed {
484ac7ddfbfSEd Maste public:
CommandObjectTargetList(CommandInterpreter & interpreter)485435933ddSDimitry Andric CommandObjectTargetList(CommandInterpreter &interpreter)
486435933ddSDimitry Andric : CommandObjectParsed(
487435933ddSDimitry Andric interpreter, "target list",
488435933ddSDimitry Andric "List all current targets in the current debug session.", nullptr) {
489ac7ddfbfSEd Maste }
490ac7ddfbfSEd Maste
4914bb0738eSEd Maste ~CommandObjectTargetList() override = default;
492ac7ddfbfSEd Maste
493ac7ddfbfSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)494435933ddSDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
495435933ddSDimitry Andric if (args.GetArgumentCount() == 0) {
496ac7ddfbfSEd Maste Stream &strm = result.GetOutputStream();
497ac7ddfbfSEd Maste
498ac7ddfbfSEd Maste bool show_stopped_process_status = false;
499435933ddSDimitry Andric if (DumpTargetList(m_interpreter.GetDebugger().GetTargetList(),
500435933ddSDimitry Andric show_stopped_process_status, strm) == 0) {
501ac7ddfbfSEd Maste strm.PutCString("No targets.\n");
502ac7ddfbfSEd Maste }
503ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
504435933ddSDimitry Andric } else {
505ac7ddfbfSEd Maste result.AppendError("the 'target list' command takes no arguments\n");
506ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
507ac7ddfbfSEd Maste }
508ac7ddfbfSEd Maste return result.Succeeded();
509ac7ddfbfSEd Maste }
510ac7ddfbfSEd Maste };
511ac7ddfbfSEd Maste
512ac7ddfbfSEd Maste #pragma mark CommandObjectTargetSelect
513ac7ddfbfSEd Maste
514ac7ddfbfSEd Maste //----------------------------------------------------------------------
515ac7ddfbfSEd Maste // "target select"
516ac7ddfbfSEd Maste //----------------------------------------------------------------------
517ac7ddfbfSEd Maste
518435933ddSDimitry Andric class CommandObjectTargetSelect : public CommandObjectParsed {
519ac7ddfbfSEd Maste public:
CommandObjectTargetSelect(CommandInterpreter & interpreter)520435933ddSDimitry Andric CommandObjectTargetSelect(CommandInterpreter &interpreter)
521435933ddSDimitry Andric : CommandObjectParsed(
522435933ddSDimitry Andric interpreter, "target select",
523435933ddSDimitry Andric "Select a target as the current target by target index.", nullptr) {
524ac7ddfbfSEd Maste }
525ac7ddfbfSEd Maste
5264bb0738eSEd Maste ~CommandObjectTargetSelect() override = default;
527ac7ddfbfSEd Maste
528ac7ddfbfSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)529435933ddSDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
530435933ddSDimitry Andric if (args.GetArgumentCount() == 1) {
531ac7ddfbfSEd Maste bool success = false;
532ac7ddfbfSEd Maste const char *target_idx_arg = args.GetArgumentAtIndex(0);
533435933ddSDimitry Andric uint32_t target_idx =
534435933ddSDimitry Andric StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success);
535435933ddSDimitry Andric if (success) {
536ac7ddfbfSEd Maste TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
537ac7ddfbfSEd Maste const uint32_t num_targets = target_list.GetNumTargets();
538435933ddSDimitry Andric if (target_idx < num_targets) {
539ac7ddfbfSEd Maste TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
540435933ddSDimitry Andric if (target_sp) {
541ac7ddfbfSEd Maste Stream &strm = result.GetOutputStream();
542ac7ddfbfSEd Maste target_list.SetSelectedTarget(target_sp.get());
543ac7ddfbfSEd Maste bool show_stopped_process_status = false;
544ac7ddfbfSEd Maste DumpTargetList(target_list, show_stopped_process_status, strm);
545ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
546435933ddSDimitry Andric } else {
547435933ddSDimitry Andric result.AppendErrorWithFormat("target #%u is NULL in target list\n",
548435933ddSDimitry Andric target_idx);
549ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
550ac7ddfbfSEd Maste }
551435933ddSDimitry Andric } else {
552435933ddSDimitry Andric if (num_targets > 0) {
553435933ddSDimitry Andric result.AppendErrorWithFormat(
554435933ddSDimitry Andric "index %u is out of range, valid target indexes are 0 - %u\n",
555435933ddSDimitry Andric target_idx, num_targets - 1);
556435933ddSDimitry Andric } else {
557435933ddSDimitry Andric result.AppendErrorWithFormat(
558435933ddSDimitry Andric "index %u is out of range since there are no active targets\n",
5590127ef0fSEd Maste target_idx);
5600127ef0fSEd Maste }
561ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
562ac7ddfbfSEd Maste }
563435933ddSDimitry Andric } else {
564435933ddSDimitry Andric result.AppendErrorWithFormat("invalid index string value '%s'\n",
565435933ddSDimitry Andric target_idx_arg);
566ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
567ac7ddfbfSEd Maste }
568435933ddSDimitry Andric } else {
569435933ddSDimitry Andric result.AppendError(
570435933ddSDimitry Andric "'target select' takes a single argument: a target index\n");
571ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
572ac7ddfbfSEd Maste }
573ac7ddfbfSEd Maste return result.Succeeded();
574ac7ddfbfSEd Maste }
575ac7ddfbfSEd Maste };
576ac7ddfbfSEd Maste
577ac7ddfbfSEd Maste #pragma mark CommandObjectTargetSelect
578ac7ddfbfSEd Maste
579ac7ddfbfSEd Maste //----------------------------------------------------------------------
580ac7ddfbfSEd Maste // "target delete"
581ac7ddfbfSEd Maste //----------------------------------------------------------------------
582ac7ddfbfSEd Maste
583435933ddSDimitry Andric class CommandObjectTargetDelete : public CommandObjectParsed {
584ac7ddfbfSEd Maste public:
CommandObjectTargetDelete(CommandInterpreter & interpreter)585435933ddSDimitry Andric CommandObjectTargetDelete(CommandInterpreter &interpreter)
586435933ddSDimitry Andric : CommandObjectParsed(interpreter, "target delete",
587ac7ddfbfSEd Maste "Delete one or more targets by target index.",
5884bb0738eSEd Maste nullptr),
589435933ddSDimitry Andric m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
590435933ddSDimitry Andric "Delete all targets.", false, true),
5911c3bbb01SEd Maste m_cleanup_option(
592435933ddSDimitry Andric LLDB_OPT_SET_1, false, "clean", 'c',
593435933ddSDimitry Andric "Perform extra cleanup to minimize memory consumption after "
594435933ddSDimitry Andric "deleting the target. "
595435933ddSDimitry Andric "By default, LLDB will keep in memory any modules previously "
596435933ddSDimitry Andric "loaded by the target as well "
597435933ddSDimitry Andric "as all of its debug info. Specifying --clean will unload all of "
598435933ddSDimitry Andric "these shared modules and "
5991c3bbb01SEd Maste "cause them to be reparsed again the next time the target is run",
600435933ddSDimitry Andric false, true) {
6011c3bbb01SEd Maste m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
602ac7ddfbfSEd Maste m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
603ac7ddfbfSEd Maste m_option_group.Finalize();
604ac7ddfbfSEd Maste }
605ac7ddfbfSEd Maste
6064bb0738eSEd Maste ~CommandObjectTargetDelete() override = default;
607ac7ddfbfSEd Maste
GetOptions()608435933ddSDimitry Andric Options *GetOptions() override { return &m_option_group; }
609ac7ddfbfSEd Maste
610ac7ddfbfSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)611435933ddSDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
612ac7ddfbfSEd Maste const size_t argc = args.GetArgumentCount();
613ac7ddfbfSEd Maste std::vector<TargetSP> delete_target_list;
614ac7ddfbfSEd Maste TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
615ac7ddfbfSEd Maste TargetSP target_sp;
6161c3bbb01SEd Maste
617435933ddSDimitry Andric if (m_all_option.GetOptionValue()) {
6181c3bbb01SEd Maste for (int i = 0; i < target_list.GetNumTargets(); ++i)
6191c3bbb01SEd Maste delete_target_list.push_back(target_list.GetTargetAtIndex(i));
620435933ddSDimitry Andric } else if (argc > 0) {
621ac7ddfbfSEd Maste const uint32_t num_targets = target_list.GetNumTargets();
622ac7ddfbfSEd Maste // Bail out if don't have any targets.
623ac7ddfbfSEd Maste if (num_targets == 0) {
624ac7ddfbfSEd Maste result.AppendError("no targets to delete");
625ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
6261c3bbb01SEd Maste return false;
627ac7ddfbfSEd Maste }
628ac7ddfbfSEd Maste
629435933ddSDimitry Andric for (auto &entry : args.entries()) {
630435933ddSDimitry Andric uint32_t target_idx;
631435933ddSDimitry Andric if (entry.ref.getAsInteger(0, target_idx)) {
632435933ddSDimitry Andric result.AppendErrorWithFormat("invalid target index '%s'\n",
633435933ddSDimitry Andric entry.c_str());
6341c3bbb01SEd Maste result.SetStatus(eReturnStatusFailed);
6351c3bbb01SEd Maste return false;
6361c3bbb01SEd Maste }
637435933ddSDimitry Andric if (target_idx < num_targets) {
638ac7ddfbfSEd Maste target_sp = target_list.GetTargetAtIndex(target_idx);
639435933ddSDimitry Andric if (target_sp) {
640ac7ddfbfSEd Maste delete_target_list.push_back(target_sp);
641ac7ddfbfSEd Maste continue;
642ac7ddfbfSEd Maste }
643ac7ddfbfSEd Maste }
644ac7ddfbfSEd Maste if (num_targets > 1)
645435933ddSDimitry Andric result.AppendErrorWithFormat("target index %u is out of range, valid "
646435933ddSDimitry Andric "target indexes are 0 - %u\n",
647435933ddSDimitry Andric target_idx, num_targets - 1);
648ac7ddfbfSEd Maste else
649435933ddSDimitry Andric result.AppendErrorWithFormat(
650435933ddSDimitry Andric "target index %u is out of range, the only valid index is 0\n",
651ac7ddfbfSEd Maste target_idx);
652ac7ddfbfSEd Maste
653ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
6541c3bbb01SEd Maste return false;
655ac7ddfbfSEd Maste }
656435933ddSDimitry Andric } else {
657ac7ddfbfSEd Maste target_sp = target_list.GetSelectedTarget();
658435933ddSDimitry Andric if (!target_sp) {
659ac7ddfbfSEd Maste result.AppendErrorWithFormat("no target is currently selected\n");
660ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
6611c3bbb01SEd Maste return false;
662ac7ddfbfSEd Maste }
6631c3bbb01SEd Maste delete_target_list.push_back(target_sp);
664ac7ddfbfSEd Maste }
6651c3bbb01SEd Maste
666ac7ddfbfSEd Maste const size_t num_targets_to_delete = delete_target_list.size();
667435933ddSDimitry Andric for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
668ac7ddfbfSEd Maste target_sp = delete_target_list[idx];
669ac7ddfbfSEd Maste target_list.DeleteTarget(target_sp);
670ac7ddfbfSEd Maste target_sp->Destroy();
671ac7ddfbfSEd Maste }
6724ba319b5SDimitry Andric // If "--clean" was specified, prune any orphaned shared modules from the
6734ba319b5SDimitry Andric // global shared module list
674435933ddSDimitry Andric if (m_cleanup_option.GetOptionValue()) {
675ac7ddfbfSEd Maste const bool mandatory = true;
676ac7ddfbfSEd Maste ModuleList::RemoveOrphanSharedModules(mandatory);
677ac7ddfbfSEd Maste }
678435933ddSDimitry Andric result.GetOutputStream().Printf("%u targets deleted.\n",
679435933ddSDimitry Andric (uint32_t)num_targets_to_delete);
680ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
681ac7ddfbfSEd Maste
6821c3bbb01SEd Maste return true;
683ac7ddfbfSEd Maste }
684ac7ddfbfSEd Maste
685ac7ddfbfSEd Maste OptionGroupOptions m_option_group;
6861c3bbb01SEd Maste OptionGroupBoolean m_all_option;
687ac7ddfbfSEd Maste OptionGroupBoolean m_cleanup_option;
688ac7ddfbfSEd Maste };
689ac7ddfbfSEd Maste
690ac7ddfbfSEd Maste #pragma mark CommandObjectTargetVariable
691ac7ddfbfSEd Maste
692ac7ddfbfSEd Maste //----------------------------------------------------------------------
693ac7ddfbfSEd Maste // "target variable"
694ac7ddfbfSEd Maste //----------------------------------------------------------------------
695ac7ddfbfSEd Maste
696435933ddSDimitry Andric class CommandObjectTargetVariable : public CommandObjectParsed {
6970127ef0fSEd Maste static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
6980127ef0fSEd Maste static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
6990127ef0fSEd Maste
700ac7ddfbfSEd Maste public:
CommandObjectTargetVariable(CommandInterpreter & interpreter)7014bb0738eSEd Maste CommandObjectTargetVariable(CommandInterpreter &interpreter)
7024bb0738eSEd Maste : CommandObjectParsed(interpreter, "target variable",
703435933ddSDimitry Andric "Read global variables for the current target, "
704435933ddSDimitry Andric "before or while running a process.",
7054bb0738eSEd Maste nullptr, eCommandRequiresTarget),
706435933ddSDimitry Andric m_option_group(),
707ac7ddfbfSEd Maste m_option_variable(false), // Don't include frame options
708ac7ddfbfSEd Maste m_option_format(eFormatDefault),
709435933ddSDimitry Andric m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
710435933ddSDimitry Andric 0, eArgTypeFilename,
711435933ddSDimitry Andric "A basename or fullpath to a file that contains "
712435933ddSDimitry Andric "global variables. This option can be "
7134bb0738eSEd Maste "specified multiple times."),
714435933ddSDimitry Andric m_option_shared_libraries(
715435933ddSDimitry Andric LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
716435933ddSDimitry Andric eArgTypeFilename,
717435933ddSDimitry Andric "A basename or fullpath to a shared library to use in the search "
718435933ddSDimitry Andric "for global "
7194bb0738eSEd Maste "variables. This option can be specified multiple times."),
720435933ddSDimitry Andric m_varobj_options() {
721ac7ddfbfSEd Maste CommandArgumentEntry arg;
722ac7ddfbfSEd Maste CommandArgumentData var_name_arg;
723ac7ddfbfSEd Maste
724ac7ddfbfSEd Maste // Define the first (and only) variant of this arg.
725ac7ddfbfSEd Maste var_name_arg.arg_type = eArgTypeVarName;
726ac7ddfbfSEd Maste var_name_arg.arg_repetition = eArgRepeatPlus;
727ac7ddfbfSEd Maste
728435933ddSDimitry Andric // There is only one variant this argument could be; put it into the
729435933ddSDimitry Andric // argument entry.
730ac7ddfbfSEd Maste arg.push_back(var_name_arg);
731ac7ddfbfSEd Maste
732ac7ddfbfSEd Maste // Push the data for the first argument into the m_arguments vector.
733ac7ddfbfSEd Maste m_arguments.push_back(arg);
734ac7ddfbfSEd Maste
735ac7ddfbfSEd Maste m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
736ac7ddfbfSEd Maste m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
737435933ddSDimitry Andric m_option_group.Append(&m_option_format,
738435933ddSDimitry Andric OptionGroupFormat::OPTION_GROUP_FORMAT |
739435933ddSDimitry Andric OptionGroupFormat::OPTION_GROUP_GDB_FMT,
740435933ddSDimitry Andric LLDB_OPT_SET_1);
741435933ddSDimitry Andric m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
742435933ddSDimitry Andric LLDB_OPT_SET_1);
743435933ddSDimitry Andric m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
744435933ddSDimitry Andric LLDB_OPT_SET_1);
745ac7ddfbfSEd Maste m_option_group.Finalize();
746ac7ddfbfSEd Maste }
747ac7ddfbfSEd Maste
7484bb0738eSEd Maste ~CommandObjectTargetVariable() override = default;
749ac7ddfbfSEd Maste
DumpValueObject(Stream & s,VariableSP & var_sp,ValueObjectSP & valobj_sp,const char * root_name)750435933ddSDimitry Andric void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
751435933ddSDimitry Andric const char *root_name) {
75235617911SEd Maste DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
753ac7ddfbfSEd Maste
7544bb0738eSEd Maste if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
7554bb0738eSEd Maste valobj_sp->IsRuntimeSupportValue())
7561c3bbb01SEd Maste return;
7571c3bbb01SEd Maste
758435933ddSDimitry Andric switch (var_sp->GetScope()) {
759ac7ddfbfSEd Maste case eValueTypeVariableGlobal:
760ac7ddfbfSEd Maste if (m_option_variable.show_scope)
761ac7ddfbfSEd Maste s.PutCString("GLOBAL: ");
762ac7ddfbfSEd Maste break;
763ac7ddfbfSEd Maste
764ac7ddfbfSEd Maste case eValueTypeVariableStatic:
765ac7ddfbfSEd Maste if (m_option_variable.show_scope)
766ac7ddfbfSEd Maste s.PutCString("STATIC: ");
767ac7ddfbfSEd Maste break;
768ac7ddfbfSEd Maste
769ac7ddfbfSEd Maste case eValueTypeVariableArgument:
770ac7ddfbfSEd Maste if (m_option_variable.show_scope)
771ac7ddfbfSEd Maste s.PutCString(" ARG: ");
772ac7ddfbfSEd Maste break;
773ac7ddfbfSEd Maste
774ac7ddfbfSEd Maste case eValueTypeVariableLocal:
775ac7ddfbfSEd Maste if (m_option_variable.show_scope)
776ac7ddfbfSEd Maste s.PutCString(" LOCAL: ");
777ac7ddfbfSEd Maste break;
778ac7ddfbfSEd Maste
7794bb0738eSEd Maste case eValueTypeVariableThreadLocal:
7804bb0738eSEd Maste if (m_option_variable.show_scope)
7814bb0738eSEd Maste s.PutCString("THREAD: ");
7824bb0738eSEd Maste break;
7834bb0738eSEd Maste
784ac7ddfbfSEd Maste default:
785ac7ddfbfSEd Maste break;
786ac7ddfbfSEd Maste }
787ac7ddfbfSEd Maste
788435933ddSDimitry Andric if (m_option_variable.show_decl) {
789ac7ddfbfSEd Maste bool show_fullpaths = false;
790ac7ddfbfSEd Maste bool show_module = true;
791ac7ddfbfSEd Maste if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
792ac7ddfbfSEd Maste s.PutCString(": ");
793ac7ddfbfSEd Maste }
794ac7ddfbfSEd Maste
795ac7ddfbfSEd Maste const Format format = m_option_format.GetFormat();
796ac7ddfbfSEd Maste if (format != eFormatDefault)
797ac7ddfbfSEd Maste options.SetFormat(format);
798ac7ddfbfSEd Maste
799ac7ddfbfSEd Maste options.SetRootValueObjectName(root_name);
800ac7ddfbfSEd Maste
80135617911SEd Maste valobj_sp->Dump(s, options);
802ac7ddfbfSEd Maste }
803ac7ddfbfSEd Maste
GetVariableCallback(void * baton,const char * name,VariableList & variable_list)804435933ddSDimitry Andric static size_t GetVariableCallback(void *baton, const char *name,
805435933ddSDimitry Andric VariableList &variable_list) {
806ac7ddfbfSEd Maste Target *target = static_cast<Target *>(baton);
807435933ddSDimitry Andric if (target) {
8084ba319b5SDimitry Andric return target->GetImages().FindGlobalVariables(ConstString(name),
809435933ddSDimitry Andric UINT32_MAX, variable_list);
810ac7ddfbfSEd Maste }
811ac7ddfbfSEd Maste return 0;
812ac7ddfbfSEd Maste }
813ac7ddfbfSEd Maste
GetOptions()814435933ddSDimitry Andric Options *GetOptions() override { return &m_option_group; }
815ac7ddfbfSEd Maste
816ac7ddfbfSEd Maste protected:
DumpGlobalVariableList(const ExecutionContext & exe_ctx,const SymbolContext & sc,const VariableList & variable_list,Stream & s)817435933ddSDimitry Andric void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
818435933ddSDimitry Andric const SymbolContext &sc,
819435933ddSDimitry Andric const VariableList &variable_list, Stream &s) {
820ac7ddfbfSEd Maste size_t count = variable_list.GetSize();
821435933ddSDimitry Andric if (count > 0) {
822435933ddSDimitry Andric if (sc.module_sp) {
823435933ddSDimitry Andric if (sc.comp_unit) {
824ac7ddfbfSEd Maste s.Printf("Global variables for %s in %s:\n",
825ac7ddfbfSEd Maste sc.comp_unit->GetPath().c_str(),
826ac7ddfbfSEd Maste sc.module_sp->GetFileSpec().GetPath().c_str());
827435933ddSDimitry Andric } else {
828ac7ddfbfSEd Maste s.Printf("Global variables for %s\n",
829ac7ddfbfSEd Maste sc.module_sp->GetFileSpec().GetPath().c_str());
830ac7ddfbfSEd Maste }
831435933ddSDimitry Andric } else if (sc.comp_unit) {
832435933ddSDimitry Andric s.Printf("Global variables for %s\n", sc.comp_unit->GetPath().c_str());
833ac7ddfbfSEd Maste }
834ac7ddfbfSEd Maste
835435933ddSDimitry Andric for (uint32_t i = 0; i < count; ++i) {
836ac7ddfbfSEd Maste VariableSP var_sp(variable_list.GetVariableAtIndex(i));
837435933ddSDimitry Andric if (var_sp) {
838435933ddSDimitry Andric ValueObjectSP valobj_sp(ValueObjectVariable::Create(
839435933ddSDimitry Andric exe_ctx.GetBestExecutionContextScope(), var_sp));
840ac7ddfbfSEd Maste
841ac7ddfbfSEd Maste if (valobj_sp)
842435933ddSDimitry Andric DumpValueObject(s, var_sp, valobj_sp,
843435933ddSDimitry Andric var_sp->GetName().GetCString());
844ac7ddfbfSEd Maste }
845ac7ddfbfSEd Maste }
846ac7ddfbfSEd Maste }
847ac7ddfbfSEd Maste }
8484bb0738eSEd Maste
DoExecute(Args & args,CommandReturnObject & result)849435933ddSDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
850ac7ddfbfSEd Maste Target *target = m_exe_ctx.GetTargetPtr();
851ac7ddfbfSEd Maste const size_t argc = args.GetArgumentCount();
852ac7ddfbfSEd Maste Stream &s = result.GetOutputStream();
853ac7ddfbfSEd Maste
854435933ddSDimitry Andric if (argc > 0) {
855ac7ddfbfSEd Maste
856435933ddSDimitry Andric // TODO: Convert to entry-based iteration. Requires converting
857435933ddSDimitry Andric // DumpValueObject.
858435933ddSDimitry Andric for (size_t idx = 0; idx < argc; ++idx) {
859ac7ddfbfSEd Maste VariableList variable_list;
860ac7ddfbfSEd Maste ValueObjectList valobj_list;
861ac7ddfbfSEd Maste
862ac7ddfbfSEd Maste const char *arg = args.GetArgumentAtIndex(idx);
863ac7ddfbfSEd Maste size_t matches = 0;
864ac7ddfbfSEd Maste bool use_var_name = false;
865435933ddSDimitry Andric if (m_option_variable.use_regex) {
866435933ddSDimitry Andric RegularExpression regex(llvm::StringRef::withNullAsEmpty(arg));
867435933ddSDimitry Andric if (!regex.IsValid()) {
868435933ddSDimitry Andric result.GetErrorStream().Printf(
869435933ddSDimitry Andric "error: invalid regular expression: '%s'\n", arg);
870ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
871ac7ddfbfSEd Maste return false;
872ac7ddfbfSEd Maste }
873ac7ddfbfSEd Maste use_var_name = true;
8744ba319b5SDimitry Andric matches = target->GetImages().FindGlobalVariables(regex, UINT32_MAX,
8754ba319b5SDimitry Andric variable_list);
876435933ddSDimitry Andric } else {
8775517e702SDimitry Andric Status error(Variable::GetValuesForVariableExpressionPath(
878435933ddSDimitry Andric arg, m_exe_ctx.GetBestExecutionContextScope(),
879435933ddSDimitry Andric GetVariableCallback, target, variable_list, valobj_list));
880ac7ddfbfSEd Maste matches = variable_list.GetSize();
881ac7ddfbfSEd Maste }
882ac7ddfbfSEd Maste
883435933ddSDimitry Andric if (matches == 0) {
884435933ddSDimitry Andric result.GetErrorStream().Printf(
885435933ddSDimitry Andric "error: can't find global variable '%s'\n", arg);
886ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
887ac7ddfbfSEd Maste return false;
888435933ddSDimitry Andric } else {
889435933ddSDimitry Andric for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
890ac7ddfbfSEd Maste VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
891435933ddSDimitry Andric if (var_sp) {
892435933ddSDimitry Andric ValueObjectSP valobj_sp(
893435933ddSDimitry Andric valobj_list.GetValueObjectAtIndex(global_idx));
894ac7ddfbfSEd Maste if (!valobj_sp)
895435933ddSDimitry Andric valobj_sp = ValueObjectVariable::Create(
896435933ddSDimitry Andric m_exe_ctx.GetBestExecutionContextScope(), var_sp);
897ac7ddfbfSEd Maste
898ac7ddfbfSEd Maste if (valobj_sp)
899435933ddSDimitry Andric DumpValueObject(s, var_sp, valobj_sp,
900435933ddSDimitry Andric use_var_name ? var_sp->GetName().GetCString()
901435933ddSDimitry Andric : arg);
902ac7ddfbfSEd Maste }
903ac7ddfbfSEd Maste }
904ac7ddfbfSEd Maste }
905ac7ddfbfSEd Maste }
906435933ddSDimitry Andric } else {
907435933ddSDimitry Andric const FileSpecList &compile_units =
908435933ddSDimitry Andric m_option_compile_units.GetOptionValue().GetCurrentValue();
909435933ddSDimitry Andric const FileSpecList &shlibs =
910435933ddSDimitry Andric m_option_shared_libraries.GetOptionValue().GetCurrentValue();
911ac7ddfbfSEd Maste SymbolContextList sc_list;
912ac7ddfbfSEd Maste const size_t num_compile_units = compile_units.GetSize();
913ac7ddfbfSEd Maste const size_t num_shlibs = shlibs.GetSize();
914435933ddSDimitry Andric if (num_compile_units == 0 && num_shlibs == 0) {
915ac7ddfbfSEd Maste bool success = false;
916ac7ddfbfSEd Maste StackFrame *frame = m_exe_ctx.GetFramePtr();
9174bb0738eSEd Maste CompileUnit *comp_unit = nullptr;
918435933ddSDimitry Andric if (frame) {
919ac7ddfbfSEd Maste SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
920435933ddSDimitry Andric if (sc.comp_unit) {
921ac7ddfbfSEd Maste const bool can_create = true;
922435933ddSDimitry Andric VariableListSP comp_unit_varlist_sp(
923435933ddSDimitry Andric sc.comp_unit->GetVariableList(can_create));
924435933ddSDimitry Andric if (comp_unit_varlist_sp) {
925ac7ddfbfSEd Maste size_t count = comp_unit_varlist_sp->GetSize();
926435933ddSDimitry Andric if (count > 0) {
927ac7ddfbfSEd Maste DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
928ac7ddfbfSEd Maste success = true;
929ac7ddfbfSEd Maste }
930ac7ddfbfSEd Maste }
931ac7ddfbfSEd Maste }
932ac7ddfbfSEd Maste }
933435933ddSDimitry Andric if (!success) {
934435933ddSDimitry Andric if (frame) {
935ac7ddfbfSEd Maste if (comp_unit)
936435933ddSDimitry Andric result.AppendErrorWithFormat(
937435933ddSDimitry Andric "no global variables in current compile unit: %s\n",
938ac7ddfbfSEd Maste comp_unit->GetPath().c_str());
939ac7ddfbfSEd Maste else
940435933ddSDimitry Andric result.AppendErrorWithFormat(
941435933ddSDimitry Andric "no debug information for frame %u\n",
942435933ddSDimitry Andric frame->GetFrameIndex());
943435933ddSDimitry Andric } else
944435933ddSDimitry Andric result.AppendError("'target variable' takes one or more global "
945435933ddSDimitry Andric "variable names as arguments\n");
946ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
947ac7ddfbfSEd Maste }
948435933ddSDimitry Andric } else {
949ac7ddfbfSEd Maste SymbolContextList sc_list;
950ac7ddfbfSEd Maste const bool append = true;
951ac7ddfbfSEd Maste // We have one or more compile unit or shlib
952435933ddSDimitry Andric if (num_shlibs > 0) {
953435933ddSDimitry Andric for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
954ac7ddfbfSEd Maste const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
955ac7ddfbfSEd Maste ModuleSpec module_spec(module_file);
956ac7ddfbfSEd Maste
957435933ddSDimitry Andric ModuleSP module_sp(
958435933ddSDimitry Andric target->GetImages().FindFirstModule(module_spec));
959435933ddSDimitry Andric if (module_sp) {
960435933ddSDimitry Andric if (num_compile_units > 0) {
961ac7ddfbfSEd Maste for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
962435933ddSDimitry Andric module_sp->FindCompileUnits(
963435933ddSDimitry Andric compile_units.GetFileSpecAtIndex(cu_idx), append,
964435933ddSDimitry Andric sc_list);
965435933ddSDimitry Andric } else {
966ac7ddfbfSEd Maste SymbolContext sc;
967ac7ddfbfSEd Maste sc.module_sp = module_sp;
968ac7ddfbfSEd Maste sc_list.Append(sc);
969ac7ddfbfSEd Maste }
970435933ddSDimitry Andric } else {
971ac7ddfbfSEd Maste // Didn't find matching shlib/module in target...
972435933ddSDimitry Andric result.AppendErrorWithFormat(
973435933ddSDimitry Andric "target doesn't contain the specified shared library: %s\n",
974ac7ddfbfSEd Maste module_file.GetPath().c_str());
975ac7ddfbfSEd Maste }
976ac7ddfbfSEd Maste }
977435933ddSDimitry Andric } else {
978435933ddSDimitry Andric // No shared libraries, we just want to find globals for the compile
979435933ddSDimitry Andric // units files that were specified
980ac7ddfbfSEd Maste for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
981435933ddSDimitry Andric target->GetImages().FindCompileUnits(
982435933ddSDimitry Andric compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
983ac7ddfbfSEd Maste }
984ac7ddfbfSEd Maste
985ac7ddfbfSEd Maste const uint32_t num_scs = sc_list.GetSize();
986435933ddSDimitry Andric if (num_scs > 0) {
987ac7ddfbfSEd Maste SymbolContext sc;
988435933ddSDimitry Andric for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
989435933ddSDimitry Andric if (sc_list.GetContextAtIndex(sc_idx, sc)) {
990435933ddSDimitry Andric if (sc.comp_unit) {
991ac7ddfbfSEd Maste const bool can_create = true;
992435933ddSDimitry Andric VariableListSP comp_unit_varlist_sp(
993435933ddSDimitry Andric sc.comp_unit->GetVariableList(can_create));
994ac7ddfbfSEd Maste if (comp_unit_varlist_sp)
995435933ddSDimitry Andric DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
996435933ddSDimitry Andric s);
997435933ddSDimitry Andric } else if (sc.module_sp) {
998ac7ddfbfSEd Maste // Get all global variables for this module
999435933ddSDimitry Andric lldb_private::RegularExpression all_globals_regex(
1000435933ddSDimitry Andric llvm::StringRef(
1001435933ddSDimitry Andric ".")); // Any global with at least one character
1002ac7ddfbfSEd Maste VariableList variable_list;
10034ba319b5SDimitry Andric sc.module_sp->FindGlobalVariables(all_globals_regex, UINT32_MAX,
10044ba319b5SDimitry Andric variable_list);
1005ac7ddfbfSEd Maste DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
1006ac7ddfbfSEd Maste }
1007ac7ddfbfSEd Maste }
1008ac7ddfbfSEd Maste }
1009ac7ddfbfSEd Maste }
1010ac7ddfbfSEd Maste }
1011ac7ddfbfSEd Maste }
1012ac7ddfbfSEd Maste
1013435933ddSDimitry Andric if (m_interpreter.TruncationWarningNecessary()) {
1014ac7ddfbfSEd Maste result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
1015ac7ddfbfSEd Maste m_cmd_name.c_str());
1016ac7ddfbfSEd Maste m_interpreter.TruncationWarningGiven();
1017ac7ddfbfSEd Maste }
1018ac7ddfbfSEd Maste
1019ac7ddfbfSEd Maste return result.Succeeded();
1020ac7ddfbfSEd Maste }
1021ac7ddfbfSEd Maste
1022ac7ddfbfSEd Maste OptionGroupOptions m_option_group;
1023ac7ddfbfSEd Maste OptionGroupVariable m_option_variable;
1024ac7ddfbfSEd Maste OptionGroupFormat m_option_format;
1025ac7ddfbfSEd Maste OptionGroupFileList m_option_compile_units;
1026ac7ddfbfSEd Maste OptionGroupFileList m_option_shared_libraries;
1027ac7ddfbfSEd Maste OptionGroupValueObjectDisplay m_varobj_options;
1028ac7ddfbfSEd Maste };
1029ac7ddfbfSEd Maste
1030ac7ddfbfSEd Maste #pragma mark CommandObjectTargetModulesSearchPathsAdd
1031ac7ddfbfSEd Maste
1032435933ddSDimitry Andric class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
1033ac7ddfbfSEd Maste public:
CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter & interpreter)1034435933ddSDimitry Andric CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
1035435933ddSDimitry Andric : CommandObjectParsed(interpreter, "target modules search-paths add",
1036435933ddSDimitry Andric "Add new image search paths substitution pairs to "
1037435933ddSDimitry Andric "the current target.",
1038435933ddSDimitry Andric nullptr) {
1039ac7ddfbfSEd Maste CommandArgumentEntry arg;
1040ac7ddfbfSEd Maste CommandArgumentData old_prefix_arg;
1041ac7ddfbfSEd Maste CommandArgumentData new_prefix_arg;
1042ac7ddfbfSEd Maste
1043ac7ddfbfSEd Maste // Define the first variant of this arg pair.
1044ac7ddfbfSEd Maste old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1045ac7ddfbfSEd Maste old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1046ac7ddfbfSEd Maste
1047ac7ddfbfSEd Maste // Define the first variant of this arg pair.
1048ac7ddfbfSEd Maste new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1049ac7ddfbfSEd Maste new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1050ac7ddfbfSEd Maste
10514ba319b5SDimitry Andric // There are two required arguments that must always occur together, i.e.
10524ba319b5SDimitry Andric // an argument "pair". Because they must always occur together, they are
10534ba319b5SDimitry Andric // treated as two variants of one argument rather than two independent
1054435933ddSDimitry Andric // arguments. Push them both into the first argument position for
1055435933ddSDimitry Andric // m_arguments...
1056ac7ddfbfSEd Maste
1057ac7ddfbfSEd Maste arg.push_back(old_prefix_arg);
1058ac7ddfbfSEd Maste arg.push_back(new_prefix_arg);
1059ac7ddfbfSEd Maste
1060ac7ddfbfSEd Maste m_arguments.push_back(arg);
1061ac7ddfbfSEd Maste }
1062ac7ddfbfSEd Maste
10634bb0738eSEd Maste ~CommandObjectTargetModulesSearchPathsAdd() override = default;
1064ac7ddfbfSEd Maste
1065ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)1066435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
1067ac7ddfbfSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1068435933ddSDimitry Andric if (target) {
1069ac7ddfbfSEd Maste const size_t argc = command.GetArgumentCount();
1070435933ddSDimitry Andric if (argc & 1) {
1071ac7ddfbfSEd Maste result.AppendError("add requires an even number of arguments\n");
1072ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
1073435933ddSDimitry Andric } else {
1074435933ddSDimitry Andric for (size_t i = 0; i < argc; i += 2) {
1075ac7ddfbfSEd Maste const char *from = command.GetArgumentAtIndex(i);
1076ac7ddfbfSEd Maste const char *to = command.GetArgumentAtIndex(i + 1);
1077ac7ddfbfSEd Maste
1078435933ddSDimitry Andric if (from[0] && to[0]) {
10799f2f44ceSEd Maste Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
1080435933ddSDimitry Andric if (log) {
1081435933ddSDimitry Andric log->Printf("target modules search path adding ImageSearchPath "
1082435933ddSDimitry Andric "pair: '%s' -> '%s'",
10839f2f44ceSEd Maste from, to);
10849f2f44ceSEd Maste }
1085ac7ddfbfSEd Maste bool last_pair = ((argc - i) == 2);
1086435933ddSDimitry Andric target->GetImageSearchPathList().Append(
1087435933ddSDimitry Andric ConstString(from), ConstString(to),
1088ac7ddfbfSEd Maste last_pair); // Notify if this is the last pair
1089ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
1090435933ddSDimitry Andric } else {
1091ac7ddfbfSEd Maste if (from[0])
1092ac7ddfbfSEd Maste result.AppendError("<path-prefix> can't be empty\n");
1093ac7ddfbfSEd Maste else
1094ac7ddfbfSEd Maste result.AppendError("<new-path-prefix> can't be empty\n");
1095ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
1096ac7ddfbfSEd Maste }
1097ac7ddfbfSEd Maste }
1098ac7ddfbfSEd Maste }
1099435933ddSDimitry Andric } else {
1100ac7ddfbfSEd Maste result.AppendError("invalid target\n");
1101ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
1102ac7ddfbfSEd Maste }
1103ac7ddfbfSEd Maste return result.Succeeded();
1104ac7ddfbfSEd Maste }
1105ac7ddfbfSEd Maste };
1106ac7ddfbfSEd Maste
1107ac7ddfbfSEd Maste #pragma mark CommandObjectTargetModulesSearchPathsClear
1108ac7ddfbfSEd Maste
1109435933ddSDimitry Andric class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
1110ac7ddfbfSEd Maste public:
CommandObjectTargetModulesSearchPathsClear(CommandInterpreter & interpreter)1111435933ddSDimitry Andric CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
1112435933ddSDimitry Andric : CommandObjectParsed(interpreter, "target modules search-paths clear",
1113435933ddSDimitry Andric "Clear all current image search path substitution "
1114435933ddSDimitry Andric "pairs from the current target.",
1115435933ddSDimitry Andric "target modules search-paths clear") {}
1116ac7ddfbfSEd Maste
11174bb0738eSEd Maste ~CommandObjectTargetModulesSearchPathsClear() override = default;
1118ac7ddfbfSEd Maste
1119ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)1120435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
1121ac7ddfbfSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1122435933ddSDimitry Andric if (target) {
1123ac7ddfbfSEd Maste bool notify = true;
1124ac7ddfbfSEd Maste target->GetImageSearchPathList().Clear(notify);
1125ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
1126435933ddSDimitry Andric } else {
1127ac7ddfbfSEd Maste result.AppendError("invalid target\n");
1128ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
1129ac7ddfbfSEd Maste }
1130ac7ddfbfSEd Maste return result.Succeeded();
1131ac7ddfbfSEd Maste }
1132ac7ddfbfSEd Maste };
1133ac7ddfbfSEd Maste
1134ac7ddfbfSEd Maste #pragma mark CommandObjectTargetModulesSearchPathsInsert
1135ac7ddfbfSEd Maste
1136435933ddSDimitry Andric class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
1137ac7ddfbfSEd Maste public:
CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter & interpreter)1138435933ddSDimitry Andric CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
1139435933ddSDimitry Andric : CommandObjectParsed(interpreter, "target modules search-paths insert",
1140435933ddSDimitry Andric "Insert a new image search path substitution pair "
1141435933ddSDimitry Andric "into the current target at the specified index.",
1142435933ddSDimitry Andric nullptr) {
1143ac7ddfbfSEd Maste CommandArgumentEntry arg1;
1144ac7ddfbfSEd Maste CommandArgumentEntry arg2;
1145ac7ddfbfSEd Maste CommandArgumentData index_arg;
1146ac7ddfbfSEd Maste CommandArgumentData old_prefix_arg;
1147ac7ddfbfSEd Maste CommandArgumentData new_prefix_arg;
1148ac7ddfbfSEd Maste
1149ac7ddfbfSEd Maste // Define the first and only variant of this arg.
1150ac7ddfbfSEd Maste index_arg.arg_type = eArgTypeIndex;
1151ac7ddfbfSEd Maste index_arg.arg_repetition = eArgRepeatPlain;
1152ac7ddfbfSEd Maste
1153ac7ddfbfSEd Maste // Put the one and only variant into the first arg for m_arguments:
1154ac7ddfbfSEd Maste arg1.push_back(index_arg);
1155ac7ddfbfSEd Maste
1156ac7ddfbfSEd Maste // Define the first variant of this arg pair.
1157ac7ddfbfSEd Maste old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1158ac7ddfbfSEd Maste old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1159ac7ddfbfSEd Maste
1160ac7ddfbfSEd Maste // Define the first variant of this arg pair.
1161ac7ddfbfSEd Maste new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1162ac7ddfbfSEd Maste new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1163ac7ddfbfSEd Maste
11644ba319b5SDimitry Andric // There are two required arguments that must always occur together, i.e.
11654ba319b5SDimitry Andric // an argument "pair". Because they must always occur together, they are
11664ba319b5SDimitry Andric // treated as two variants of one argument rather than two independent
1167435933ddSDimitry Andric // arguments. Push them both into the same argument position for
1168435933ddSDimitry Andric // m_arguments...
1169ac7ddfbfSEd Maste
1170ac7ddfbfSEd Maste arg2.push_back(old_prefix_arg);
1171ac7ddfbfSEd Maste arg2.push_back(new_prefix_arg);
1172ac7ddfbfSEd Maste
1173ac7ddfbfSEd Maste // Add arguments to m_arguments.
1174ac7ddfbfSEd Maste m_arguments.push_back(arg1);
1175ac7ddfbfSEd Maste m_arguments.push_back(arg2);
1176ac7ddfbfSEd Maste }
1177ac7ddfbfSEd Maste
11784bb0738eSEd Maste ~CommandObjectTargetModulesSearchPathsInsert() override = default;
1179ac7ddfbfSEd Maste
1180ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)1181435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
1182ac7ddfbfSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1183435933ddSDimitry Andric if (target) {
1184ac7ddfbfSEd Maste size_t argc = command.GetArgumentCount();
11859f2f44ceSEd Maste // check for at least 3 arguments and an odd number of parameters
1186435933ddSDimitry Andric if (argc >= 3 && argc & 1) {
1187ac7ddfbfSEd Maste bool success = false;
1188ac7ddfbfSEd Maste
1189435933ddSDimitry Andric uint32_t insert_idx = StringConvert::ToUInt32(
1190435933ddSDimitry Andric command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
1191ac7ddfbfSEd Maste
1192435933ddSDimitry Andric if (!success) {
1193435933ddSDimitry Andric result.AppendErrorWithFormat(
1194435933ddSDimitry Andric "<index> parameter is not an integer: '%s'.\n",
1195435933ddSDimitry Andric command.GetArgumentAtIndex(0));
1196ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
1197ac7ddfbfSEd Maste return result.Succeeded();
1198ac7ddfbfSEd Maste }
1199ac7ddfbfSEd Maste
1200ac7ddfbfSEd Maste // shift off the index
1201ac7ddfbfSEd Maste command.Shift();
1202ac7ddfbfSEd Maste argc = command.GetArgumentCount();
1203ac7ddfbfSEd Maste
1204435933ddSDimitry Andric for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1205ac7ddfbfSEd Maste const char *from = command.GetArgumentAtIndex(i);
1206ac7ddfbfSEd Maste const char *to = command.GetArgumentAtIndex(i + 1);
1207ac7ddfbfSEd Maste
1208435933ddSDimitry Andric if (from[0] && to[0]) {
1209ac7ddfbfSEd Maste bool last_pair = ((argc - i) == 2);
1210435933ddSDimitry Andric target->GetImageSearchPathList().Insert(
1211435933ddSDimitry Andric ConstString(from), ConstString(to), insert_idx, last_pair);
1212ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
1213435933ddSDimitry Andric } else {
1214ac7ddfbfSEd Maste if (from[0])
1215ac7ddfbfSEd Maste result.AppendError("<path-prefix> can't be empty\n");
1216ac7ddfbfSEd Maste else
1217ac7ddfbfSEd Maste result.AppendError("<new-path-prefix> can't be empty\n");
1218ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
1219ac7ddfbfSEd Maste return false;
1220ac7ddfbfSEd Maste }
1221ac7ddfbfSEd Maste }
1222435933ddSDimitry Andric } else {
1223ac7ddfbfSEd Maste result.AppendError("insert requires at least three arguments\n");
1224ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
1225ac7ddfbfSEd Maste return result.Succeeded();
1226ac7ddfbfSEd Maste }
1227ac7ddfbfSEd Maste
1228435933ddSDimitry Andric } else {
1229ac7ddfbfSEd Maste result.AppendError("invalid target\n");
1230ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
1231ac7ddfbfSEd Maste }
1232ac7ddfbfSEd Maste return result.Succeeded();
1233ac7ddfbfSEd Maste }
1234ac7ddfbfSEd Maste };
1235ac7ddfbfSEd Maste
1236ac7ddfbfSEd Maste #pragma mark CommandObjectTargetModulesSearchPathsList
1237ac7ddfbfSEd Maste
1238435933ddSDimitry Andric class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
1239ac7ddfbfSEd Maste public:
CommandObjectTargetModulesSearchPathsList(CommandInterpreter & interpreter)1240435933ddSDimitry Andric CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
1241435933ddSDimitry Andric : CommandObjectParsed(interpreter, "target modules search-paths list",
1242435933ddSDimitry Andric "List all current image search path substitution "
1243435933ddSDimitry Andric "pairs in the current target.",
1244435933ddSDimitry Andric "target modules search-paths list") {}
1245ac7ddfbfSEd Maste
12464bb0738eSEd Maste ~CommandObjectTargetModulesSearchPathsList() override = default;
1247ac7ddfbfSEd Maste
1248ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)1249435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
1250ac7ddfbfSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1251435933ddSDimitry Andric if (target) {
1252435933ddSDimitry Andric if (command.GetArgumentCount() != 0) {
1253ac7ddfbfSEd Maste result.AppendError("list takes no arguments\n");
1254ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
1255ac7ddfbfSEd Maste return result.Succeeded();
1256ac7ddfbfSEd Maste }
1257ac7ddfbfSEd Maste
1258ac7ddfbfSEd Maste target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1259ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
1260435933ddSDimitry Andric } else {
1261ac7ddfbfSEd Maste result.AppendError("invalid target\n");
1262ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
1263ac7ddfbfSEd Maste }
1264ac7ddfbfSEd Maste return result.Succeeded();
1265ac7ddfbfSEd Maste }
1266ac7ddfbfSEd Maste };
1267ac7ddfbfSEd Maste
1268ac7ddfbfSEd Maste #pragma mark CommandObjectTargetModulesSearchPathsQuery
1269ac7ddfbfSEd Maste
1270435933ddSDimitry Andric class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
1271ac7ddfbfSEd Maste public:
CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter & interpreter)1272435933ddSDimitry Andric CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
1273435933ddSDimitry Andric : CommandObjectParsed(
1274435933ddSDimitry Andric interpreter, "target modules search-paths query",
1275ac7ddfbfSEd Maste "Transform a path using the first applicable image search path.",
1276435933ddSDimitry Andric nullptr) {
1277ac7ddfbfSEd Maste CommandArgumentEntry arg;
1278ac7ddfbfSEd Maste CommandArgumentData path_arg;
1279ac7ddfbfSEd Maste
1280ac7ddfbfSEd Maste // Define the first (and only) variant of this arg.
1281ac7ddfbfSEd Maste path_arg.arg_type = eArgTypeDirectoryName;
1282ac7ddfbfSEd Maste path_arg.arg_repetition = eArgRepeatPlain;
1283ac7ddfbfSEd Maste
1284435933ddSDimitry Andric // There is only one variant this argument could be; put it into the
1285435933ddSDimitry Andric // argument entry.
1286ac7ddfbfSEd Maste arg.push_back(path_arg);
1287ac7ddfbfSEd Maste
1288ac7ddfbfSEd Maste // Push the data for the first argument into the m_arguments vector.
1289ac7ddfbfSEd Maste m_arguments.push_back(arg);
1290ac7ddfbfSEd Maste }
1291ac7ddfbfSEd Maste
12924bb0738eSEd Maste ~CommandObjectTargetModulesSearchPathsQuery() override = default;
1293ac7ddfbfSEd Maste
1294ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)1295435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
1296ac7ddfbfSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1297435933ddSDimitry Andric if (target) {
1298435933ddSDimitry Andric if (command.GetArgumentCount() != 1) {
1299ac7ddfbfSEd Maste result.AppendError("query requires one argument\n");
1300ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
1301ac7ddfbfSEd Maste return result.Succeeded();
1302ac7ddfbfSEd Maste }
1303ac7ddfbfSEd Maste
1304ac7ddfbfSEd Maste ConstString orig(command.GetArgumentAtIndex(0));
1305ac7ddfbfSEd Maste ConstString transformed;
1306ac7ddfbfSEd Maste if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1307ac7ddfbfSEd Maste result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1308ac7ddfbfSEd Maste else
1309ac7ddfbfSEd Maste result.GetOutputStream().Printf("%s\n", orig.GetCString());
1310ac7ddfbfSEd Maste
1311ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
1312435933ddSDimitry Andric } else {
1313ac7ddfbfSEd Maste result.AppendError("invalid target\n");
1314ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
1315ac7ddfbfSEd Maste }
1316ac7ddfbfSEd Maste return result.Succeeded();
1317ac7ddfbfSEd Maste }
1318ac7ddfbfSEd Maste };
1319ac7ddfbfSEd Maste
1320ac7ddfbfSEd Maste //----------------------------------------------------------------------
1321ac7ddfbfSEd Maste // Static Helper functions
1322ac7ddfbfSEd Maste //----------------------------------------------------------------------
DumpModuleArchitecture(Stream & strm,Module * module,bool full_triple,uint32_t width)1323435933ddSDimitry Andric static void DumpModuleArchitecture(Stream &strm, Module *module,
1324435933ddSDimitry Andric bool full_triple, uint32_t width) {
1325435933ddSDimitry Andric if (module) {
13269f2f44ceSEd Maste StreamString arch_strm;
13279f2f44ceSEd Maste
1328ac7ddfbfSEd Maste if (full_triple)
13299f2f44ceSEd Maste module->GetArchitecture().DumpTriple(arch_strm);
1330ac7ddfbfSEd Maste else
13319f2f44ceSEd Maste arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
13329f2f44ceSEd Maste std::string arch_str = arch_strm.GetString();
13339f2f44ceSEd Maste
1334ac7ddfbfSEd Maste if (width)
13359f2f44ceSEd Maste strm.Printf("%-*s", width, arch_str.c_str());
1336ac7ddfbfSEd Maste else
1337435933ddSDimitry Andric strm.PutCString(arch_str);
1338ac7ddfbfSEd Maste }
1339ac7ddfbfSEd Maste }
1340ac7ddfbfSEd Maste
DumpModuleUUID(Stream & strm,Module * module)1341435933ddSDimitry Andric static void DumpModuleUUID(Stream &strm, Module *module) {
1342ac7ddfbfSEd Maste if (module && module->GetUUID().IsValid())
1343ac7ddfbfSEd Maste module->GetUUID().Dump(&strm);
1344ac7ddfbfSEd Maste else
1345ac7ddfbfSEd Maste strm.PutCString(" ");
1346ac7ddfbfSEd Maste }
1347ac7ddfbfSEd Maste
DumpCompileUnitLineTable(CommandInterpreter & interpreter,Stream & strm,Module * module,const FileSpec & file_spec,bool load_addresses)1348435933ddSDimitry Andric static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
1349435933ddSDimitry Andric Stream &strm, Module *module,
1350ac7ddfbfSEd Maste const FileSpec &file_spec,
1351435933ddSDimitry Andric bool load_addresses) {
1352ac7ddfbfSEd Maste uint32_t num_matches = 0;
1353435933ddSDimitry Andric if (module) {
1354ac7ddfbfSEd Maste SymbolContextList sc_list;
1355435933ddSDimitry Andric num_matches = module->ResolveSymbolContextsForFileSpec(
1356435933ddSDimitry Andric file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1357ac7ddfbfSEd Maste
1358435933ddSDimitry Andric for (uint32_t i = 0; i < num_matches; ++i) {
1359ac7ddfbfSEd Maste SymbolContext sc;
1360435933ddSDimitry Andric if (sc_list.GetContextAtIndex(i, sc)) {
1361ac7ddfbfSEd Maste if (i > 0)
1362ac7ddfbfSEd Maste strm << "\n\n";
1363ac7ddfbfSEd Maste
1364435933ddSDimitry Andric strm << "Line table for " << *static_cast<FileSpec *>(sc.comp_unit)
1365435933ddSDimitry Andric << " in `" << module->GetFileSpec().GetFilename() << "\n";
1366ac7ddfbfSEd Maste LineTable *line_table = sc.comp_unit->GetLineTable();
1367ac7ddfbfSEd Maste if (line_table)
1368435933ddSDimitry Andric line_table->GetDescription(
1369435933ddSDimitry Andric &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1370ac7ddfbfSEd Maste lldb::eDescriptionLevelBrief);
1371ac7ddfbfSEd Maste else
1372ac7ddfbfSEd Maste strm << "No line table";
1373ac7ddfbfSEd Maste }
1374ac7ddfbfSEd Maste }
1375ac7ddfbfSEd Maste }
1376ac7ddfbfSEd Maste return num_matches;
1377ac7ddfbfSEd Maste }
1378ac7ddfbfSEd Maste
DumpFullpath(Stream & strm,const FileSpec * file_spec_ptr,uint32_t width)1379435933ddSDimitry Andric static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1380435933ddSDimitry Andric uint32_t width) {
1381435933ddSDimitry Andric if (file_spec_ptr) {
1382435933ddSDimitry Andric if (width > 0) {
1383ac7ddfbfSEd Maste std::string fullpath = file_spec_ptr->GetPath();
1384ac7ddfbfSEd Maste strm.Printf("%-*s", width, fullpath.c_str());
1385ac7ddfbfSEd Maste return;
1386435933ddSDimitry Andric } else {
1387ac7ddfbfSEd Maste file_spec_ptr->Dump(&strm);
1388ac7ddfbfSEd Maste return;
1389ac7ddfbfSEd Maste }
1390ac7ddfbfSEd Maste }
1391ac7ddfbfSEd Maste // Keep the width spacing correct if things go wrong...
1392ac7ddfbfSEd Maste if (width > 0)
1393ac7ddfbfSEd Maste strm.Printf("%-*s", width, "");
1394ac7ddfbfSEd Maste }
1395ac7ddfbfSEd Maste
DumpDirectory(Stream & strm,const FileSpec * file_spec_ptr,uint32_t width)1396435933ddSDimitry Andric static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1397435933ddSDimitry Andric uint32_t width) {
1398435933ddSDimitry Andric if (file_spec_ptr) {
1399ac7ddfbfSEd Maste if (width > 0)
1400ac7ddfbfSEd Maste strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1401ac7ddfbfSEd Maste else
1402ac7ddfbfSEd Maste file_spec_ptr->GetDirectory().Dump(&strm);
1403ac7ddfbfSEd Maste return;
1404ac7ddfbfSEd Maste }
1405ac7ddfbfSEd Maste // Keep the width spacing correct if things go wrong...
1406ac7ddfbfSEd Maste if (width > 0)
1407ac7ddfbfSEd Maste strm.Printf("%-*s", width, "");
1408ac7ddfbfSEd Maste }
1409ac7ddfbfSEd Maste
DumpBasename(Stream & strm,const FileSpec * file_spec_ptr,uint32_t width)1410435933ddSDimitry Andric static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1411435933ddSDimitry Andric uint32_t width) {
1412435933ddSDimitry Andric if (file_spec_ptr) {
1413ac7ddfbfSEd Maste if (width > 0)
1414ac7ddfbfSEd Maste strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1415ac7ddfbfSEd Maste else
1416ac7ddfbfSEd Maste file_spec_ptr->GetFilename().Dump(&strm);
1417ac7ddfbfSEd Maste return;
1418ac7ddfbfSEd Maste }
1419ac7ddfbfSEd Maste // Keep the width spacing correct if things go wrong...
1420ac7ddfbfSEd Maste if (width > 0)
1421ac7ddfbfSEd Maste strm.Printf("%-*s", width, "");
1422ac7ddfbfSEd Maste }
1423ac7ddfbfSEd Maste
DumpModuleObjfileHeaders(Stream & strm,ModuleList & module_list)1424435933ddSDimitry Andric static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
14254bb0738eSEd Maste size_t num_dumped = 0;
14264bb0738eSEd Maste std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
14274bb0738eSEd Maste const size_t num_modules = module_list.GetSize();
1428435933ddSDimitry Andric if (num_modules > 0) {
1429435933ddSDimitry Andric strm.Printf("Dumping headers for %" PRIu64 " module(s).\n",
1430435933ddSDimitry Andric static_cast<uint64_t>(num_modules));
14314bb0738eSEd Maste strm.IndentMore();
1432435933ddSDimitry Andric for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
14334bb0738eSEd Maste Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
1434435933ddSDimitry Andric if (module) {
1435435933ddSDimitry Andric if (num_dumped++ > 0) {
14364bb0738eSEd Maste strm.EOL();
14374bb0738eSEd Maste strm.EOL();
14384bb0738eSEd Maste }
14394bb0738eSEd Maste ObjectFile *objfile = module->GetObjectFile();
14404ba319b5SDimitry Andric if (objfile)
14414bb0738eSEd Maste objfile->Dump(&strm);
14424ba319b5SDimitry Andric else {
14434ba319b5SDimitry Andric strm.Format("No object file for module: {0:F}\n",
14444ba319b5SDimitry Andric module->GetFileSpec());
14454ba319b5SDimitry Andric }
14464bb0738eSEd Maste }
14474bb0738eSEd Maste }
14484bb0738eSEd Maste strm.IndentLess();
14494bb0738eSEd Maste }
14504bb0738eSEd Maste return num_dumped;
14514bb0738eSEd Maste }
1452ac7ddfbfSEd Maste
DumpModuleSymtab(CommandInterpreter & interpreter,Stream & strm,Module * module,SortOrder sort_order)1453435933ddSDimitry Andric static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1454435933ddSDimitry Andric Module *module, SortOrder sort_order) {
1455435933ddSDimitry Andric if (module) {
1456ac7ddfbfSEd Maste SymbolVendor *sym_vendor = module->GetSymbolVendor();
1457435933ddSDimitry Andric if (sym_vendor) {
1458ac7ddfbfSEd Maste Symtab *symtab = sym_vendor->GetSymtab();
1459ac7ddfbfSEd Maste if (symtab)
1460435933ddSDimitry Andric symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1461435933ddSDimitry Andric sort_order);
1462ac7ddfbfSEd Maste }
1463ac7ddfbfSEd Maste }
1464ac7ddfbfSEd Maste }
1465ac7ddfbfSEd Maste
DumpModuleSections(CommandInterpreter & interpreter,Stream & strm,Module * module)1466435933ddSDimitry Andric static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1467435933ddSDimitry Andric Module *module) {
1468435933ddSDimitry Andric if (module) {
1469ac7ddfbfSEd Maste SectionList *section_list = module->GetSectionList();
1470435933ddSDimitry Andric if (section_list) {
1471ac7ddfbfSEd Maste strm.Printf("Sections for '%s' (%s):\n",
1472ac7ddfbfSEd Maste module->GetSpecificationDescription().c_str(),
1473ac7ddfbfSEd Maste module->GetArchitecture().GetArchitectureName());
1474ac7ddfbfSEd Maste strm.IndentMore();
1475435933ddSDimitry Andric section_list->Dump(&strm,
1476435933ddSDimitry Andric interpreter.GetExecutionContext().GetTargetPtr(), true,
1477435933ddSDimitry Andric UINT32_MAX);
1478ac7ddfbfSEd Maste strm.IndentLess();
1479ac7ddfbfSEd Maste }
1480ac7ddfbfSEd Maste }
1481ac7ddfbfSEd Maste }
1482ac7ddfbfSEd Maste
DumpModuleSymbolVendor(Stream & strm,Module * module)1483435933ddSDimitry Andric static bool DumpModuleSymbolVendor(Stream &strm, Module *module) {
1484435933ddSDimitry Andric if (module) {
1485ac7ddfbfSEd Maste SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1486435933ddSDimitry Andric if (symbol_vendor) {
1487ac7ddfbfSEd Maste symbol_vendor->Dump(&strm);
1488ac7ddfbfSEd Maste return true;
1489ac7ddfbfSEd Maste }
1490ac7ddfbfSEd Maste }
1491ac7ddfbfSEd Maste return false;
1492ac7ddfbfSEd Maste }
1493ac7ddfbfSEd Maste
DumpAddress(ExecutionContextScope * exe_scope,const Address & so_addr,bool verbose,Stream & strm)1494435933ddSDimitry Andric static void DumpAddress(ExecutionContextScope *exe_scope,
1495435933ddSDimitry Andric const Address &so_addr, bool verbose, Stream &strm) {
1496ac7ddfbfSEd Maste strm.IndentMore();
1497ac7ddfbfSEd Maste strm.Indent(" Address: ");
1498ac7ddfbfSEd Maste so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1499ac7ddfbfSEd Maste strm.PutCString(" (");
1500ac7ddfbfSEd Maste so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1501ac7ddfbfSEd Maste strm.PutCString(")\n");
1502ac7ddfbfSEd Maste strm.Indent(" Summary: ");
1503ac7ddfbfSEd Maste const uint32_t save_indent = strm.GetIndentLevel();
1504ac7ddfbfSEd Maste strm.SetIndentLevel(save_indent + 13);
1505ac7ddfbfSEd Maste so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
1506ac7ddfbfSEd Maste strm.SetIndentLevel(save_indent);
1507ac7ddfbfSEd Maste // Print out detailed address information when verbose is enabled
1508435933ddSDimitry Andric if (verbose) {
1509ac7ddfbfSEd Maste strm.EOL();
1510ac7ddfbfSEd Maste so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1511ac7ddfbfSEd Maste }
1512ac7ddfbfSEd Maste strm.IndentLess();
1513ac7ddfbfSEd Maste }
1514ac7ddfbfSEd Maste
LookupAddressInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,uint32_t resolve_mask,lldb::addr_t raw_addr,lldb::addr_t offset,bool verbose)1515435933ddSDimitry Andric static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1516435933ddSDimitry Andric Module *module, uint32_t resolve_mask,
1517435933ddSDimitry Andric lldb::addr_t raw_addr, lldb::addr_t offset,
1518435933ddSDimitry Andric bool verbose) {
1519435933ddSDimitry Andric if (module) {
1520ac7ddfbfSEd Maste lldb::addr_t addr = raw_addr - offset;
1521ac7ddfbfSEd Maste Address so_addr;
1522ac7ddfbfSEd Maste SymbolContext sc;
1523ac7ddfbfSEd Maste Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1524435933ddSDimitry Andric if (target && !target->GetSectionLoadList().IsEmpty()) {
1525ac7ddfbfSEd Maste if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
1526ac7ddfbfSEd Maste return false;
1527ac7ddfbfSEd Maste else if (so_addr.GetModule().get() != module)
1528ac7ddfbfSEd Maste return false;
1529435933ddSDimitry Andric } else {
1530ac7ddfbfSEd Maste if (!module->ResolveFileAddress(addr, so_addr))
1531ac7ddfbfSEd Maste return false;
1532ac7ddfbfSEd Maste }
1533ac7ddfbfSEd Maste
1534435933ddSDimitry Andric ExecutionContextScope *exe_scope =
1535435933ddSDimitry Andric interpreter.GetExecutionContext().GetBestExecutionContextScope();
1536ac7ddfbfSEd Maste DumpAddress(exe_scope, so_addr, verbose, strm);
1537ac7ddfbfSEd Maste // strm.IndentMore();
1538ac7ddfbfSEd Maste // strm.Indent (" Address: ");
1539435933ddSDimitry Andric // so_addr.Dump (&strm, exe_scope,
1540435933ddSDimitry Andric // Address::DumpStyleModuleWithFileAddress);
1541ac7ddfbfSEd Maste // strm.PutCString (" (");
1542435933ddSDimitry Andric // so_addr.Dump (&strm, exe_scope,
1543435933ddSDimitry Andric // Address::DumpStyleSectionNameOffset);
1544ac7ddfbfSEd Maste // strm.PutCString (")\n");
1545ac7ddfbfSEd Maste // strm.Indent (" Summary: ");
1546ac7ddfbfSEd Maste // const uint32_t save_indent = strm.GetIndentLevel ();
1547ac7ddfbfSEd Maste // strm.SetIndentLevel (save_indent + 13);
1548435933ddSDimitry Andric // so_addr.Dump (&strm, exe_scope,
1549435933ddSDimitry Andric // Address::DumpStyleResolvedDescription);
1550ac7ddfbfSEd Maste // strm.SetIndentLevel (save_indent);
1551ac7ddfbfSEd Maste // // Print out detailed address information when verbose is enabled
1552ac7ddfbfSEd Maste // if (verbose)
1553ac7ddfbfSEd Maste // {
1554ac7ddfbfSEd Maste // strm.EOL();
1555435933ddSDimitry Andric // so_addr.Dump (&strm, exe_scope,
1556435933ddSDimitry Andric // Address::DumpStyleDetailedSymbolContext);
1557ac7ddfbfSEd Maste // }
1558ac7ddfbfSEd Maste // strm.IndentLess();
1559ac7ddfbfSEd Maste return true;
1560ac7ddfbfSEd Maste }
1561ac7ddfbfSEd Maste
1562ac7ddfbfSEd Maste return false;
1563ac7ddfbfSEd Maste }
1564ac7ddfbfSEd Maste
LookupSymbolInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const char * name,bool name_is_regex,bool verbose)1565435933ddSDimitry Andric static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1566435933ddSDimitry Andric Stream &strm, Module *module,
1567435933ddSDimitry Andric const char *name, bool name_is_regex,
1568435933ddSDimitry Andric bool verbose) {
1569435933ddSDimitry Andric if (module) {
1570ac7ddfbfSEd Maste SymbolContext sc;
1571ac7ddfbfSEd Maste
1572ac7ddfbfSEd Maste SymbolVendor *sym_vendor = module->GetSymbolVendor();
1573435933ddSDimitry Andric if (sym_vendor) {
1574ac7ddfbfSEd Maste Symtab *symtab = sym_vendor->GetSymtab();
1575435933ddSDimitry Andric if (symtab) {
1576ac7ddfbfSEd Maste std::vector<uint32_t> match_indexes;
1577ac7ddfbfSEd Maste ConstString symbol_name(name);
1578ac7ddfbfSEd Maste uint32_t num_matches = 0;
1579435933ddSDimitry Andric if (name_is_regex) {
1580435933ddSDimitry Andric RegularExpression name_regexp(symbol_name.GetStringRef());
1581435933ddSDimitry Andric num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1582435933ddSDimitry Andric name_regexp, eSymbolTypeAny, match_indexes);
1583435933ddSDimitry Andric } else {
1584435933ddSDimitry Andric num_matches =
1585435933ddSDimitry Andric symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1586ac7ddfbfSEd Maste }
1587ac7ddfbfSEd Maste
1588435933ddSDimitry Andric if (num_matches > 0) {
1589ac7ddfbfSEd Maste strm.Indent();
1590ac7ddfbfSEd Maste strm.Printf("%u symbols match %s'%s' in ", num_matches,
1591ac7ddfbfSEd Maste name_is_regex ? "the regular expression " : "", name);
1592ac7ddfbfSEd Maste DumpFullpath(strm, &module->GetFileSpec(), 0);
1593ac7ddfbfSEd Maste strm.PutCString(":\n");
1594ac7ddfbfSEd Maste strm.IndentMore();
1595435933ddSDimitry Andric for (uint32_t i = 0; i < num_matches; ++i) {
1596ac7ddfbfSEd Maste Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1597435933ddSDimitry Andric if (symbol && symbol->ValueIsAddress()) {
1598435933ddSDimitry Andric DumpAddress(interpreter.GetExecutionContext()
1599435933ddSDimitry Andric .GetBestExecutionContextScope(),
1600435933ddSDimitry Andric symbol->GetAddressRef(), verbose, strm);
16011c3bbb01SEd Maste }
1602ac7ddfbfSEd Maste }
1603ac7ddfbfSEd Maste strm.IndentLess();
1604ac7ddfbfSEd Maste return num_matches;
1605ac7ddfbfSEd Maste }
1606ac7ddfbfSEd Maste }
1607ac7ddfbfSEd Maste }
1608ac7ddfbfSEd Maste }
1609ac7ddfbfSEd Maste return 0;
1610ac7ddfbfSEd Maste }
1611ac7ddfbfSEd Maste
DumpSymbolContextList(ExecutionContextScope * exe_scope,Stream & strm,SymbolContextList & sc_list,bool verbose)1612435933ddSDimitry Andric static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
1613435933ddSDimitry Andric Stream &strm, SymbolContextList &sc_list,
1614435933ddSDimitry Andric bool verbose) {
1615ac7ddfbfSEd Maste strm.IndentMore();
16164bb0738eSEd Maste
1617ac7ddfbfSEd Maste const uint32_t num_matches = sc_list.GetSize();
1618ac7ddfbfSEd Maste
1619435933ddSDimitry Andric for (uint32_t i = 0; i < num_matches; ++i) {
1620ac7ddfbfSEd Maste SymbolContext sc;
1621435933ddSDimitry Andric if (sc_list.GetContextAtIndex(i, sc)) {
1622ac7ddfbfSEd Maste AddressRange range;
1623ac7ddfbfSEd Maste
1624435933ddSDimitry Andric sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
1625ac7ddfbfSEd Maste
1626ac7ddfbfSEd Maste DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
1627ac7ddfbfSEd Maste }
1628ac7ddfbfSEd Maste }
1629ac7ddfbfSEd Maste strm.IndentLess();
1630ac7ddfbfSEd Maste }
1631ac7ddfbfSEd Maste
LookupFunctionInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const char * name,bool name_is_regex,bool include_inlines,bool include_symbols,bool verbose)1632435933ddSDimitry Andric static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
1633435933ddSDimitry Andric Stream &strm, Module *module,
1634435933ddSDimitry Andric const char *name, bool name_is_regex,
1635435933ddSDimitry Andric bool include_inlines, bool include_symbols,
1636435933ddSDimitry Andric bool verbose) {
1637435933ddSDimitry Andric if (module && name && name[0]) {
1638ac7ddfbfSEd Maste SymbolContextList sc_list;
1639ac7ddfbfSEd Maste const bool append = true;
1640ac7ddfbfSEd Maste size_t num_matches = 0;
1641435933ddSDimitry Andric if (name_is_regex) {
1642435933ddSDimitry Andric RegularExpression function_name_regex((llvm::StringRef(name)));
1643435933ddSDimitry Andric num_matches = module->FindFunctions(function_name_regex, include_symbols,
1644435933ddSDimitry Andric include_inlines, append, sc_list);
1645435933ddSDimitry Andric } else {
1646ac7ddfbfSEd Maste ConstString function_name(name);
1647435933ddSDimitry Andric num_matches = module->FindFunctions(
1648435933ddSDimitry Andric function_name, nullptr, eFunctionNameTypeAuto, include_symbols,
1649435933ddSDimitry Andric include_inlines, append, sc_list);
1650ac7ddfbfSEd Maste }
1651ac7ddfbfSEd Maste
1652435933ddSDimitry Andric if (num_matches) {
1653ac7ddfbfSEd Maste strm.Indent();
1654435933ddSDimitry Andric strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1655435933ddSDimitry Andric num_matches > 1 ? "es" : "");
1656ac7ddfbfSEd Maste DumpFullpath(strm, &module->GetFileSpec(), 0);
1657ac7ddfbfSEd Maste strm.PutCString(":\n");
1658435933ddSDimitry Andric DumpSymbolContextList(
1659435933ddSDimitry Andric interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1660435933ddSDimitry Andric strm, sc_list, verbose);
1661ac7ddfbfSEd Maste }
1662ac7ddfbfSEd Maste return num_matches;
1663ac7ddfbfSEd Maste }
1664ac7ddfbfSEd Maste return 0;
1665ac7ddfbfSEd Maste }
1666ac7ddfbfSEd Maste
LookupTypeInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const char * name_cstr,bool name_is_regex)1667435933ddSDimitry Andric static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
1668435933ddSDimitry Andric Module *module, const char *name_cstr,
1669435933ddSDimitry Andric bool name_is_regex) {
1670435933ddSDimitry Andric if (module && name_cstr && name_cstr[0]) {
1671ac7ddfbfSEd Maste TypeList type_list;
1672ac7ddfbfSEd Maste const uint32_t max_num_matches = UINT32_MAX;
1673ac7ddfbfSEd Maste size_t num_matches = 0;
1674ac7ddfbfSEd Maste bool name_is_fully_qualified = false;
1675ac7ddfbfSEd Maste
1676ac7ddfbfSEd Maste ConstString name(name_cstr);
16774bb0738eSEd Maste llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1678435933ddSDimitry Andric num_matches =
1679*b5893f02SDimitry Andric module->FindTypes(name, name_is_fully_qualified, max_num_matches,
1680435933ddSDimitry Andric searched_symbol_files, type_list);
1681ac7ddfbfSEd Maste
1682435933ddSDimitry Andric if (num_matches) {
1683ac7ddfbfSEd Maste strm.Indent();
1684435933ddSDimitry Andric strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1685435933ddSDimitry Andric num_matches > 1 ? "es" : "");
1686ac7ddfbfSEd Maste DumpFullpath(strm, &module->GetFileSpec(), 0);
1687ac7ddfbfSEd Maste strm.PutCString(":\n");
1688435933ddSDimitry Andric for (TypeSP type_sp : type_list.Types()) {
1689435933ddSDimitry Andric if (type_sp) {
16904ba319b5SDimitry Andric // Resolve the clang type so that any forward references to types
16914ba319b5SDimitry Andric // that haven't yet been parsed will get parsed.
16929f2f44ceSEd Maste type_sp->GetFullCompilerType();
1693ac7ddfbfSEd Maste type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1694ac7ddfbfSEd Maste // Print all typedef chains
1695ac7ddfbfSEd Maste TypeSP typedef_type_sp(type_sp);
1696ac7ddfbfSEd Maste TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1697435933ddSDimitry Andric while (typedefed_type_sp) {
1698ac7ddfbfSEd Maste strm.EOL();
1699435933ddSDimitry Andric strm.Printf(" typedef '%s': ",
1700435933ddSDimitry Andric typedef_type_sp->GetName().GetCString());
17019f2f44ceSEd Maste typedefed_type_sp->GetFullCompilerType();
1702435933ddSDimitry Andric typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull,
1703435933ddSDimitry Andric true);
1704ac7ddfbfSEd Maste typedef_type_sp = typedefed_type_sp;
1705ac7ddfbfSEd Maste typedefed_type_sp = typedef_type_sp->GetTypedefType();
1706ac7ddfbfSEd Maste }
1707ac7ddfbfSEd Maste }
1708ac7ddfbfSEd Maste strm.EOL();
1709ac7ddfbfSEd Maste }
1710ac7ddfbfSEd Maste }
1711ac7ddfbfSEd Maste return num_matches;
1712ac7ddfbfSEd Maste }
1713ac7ddfbfSEd Maste return 0;
1714ac7ddfbfSEd Maste }
1715ac7ddfbfSEd Maste
LookupTypeHere(CommandInterpreter & interpreter,Stream & strm,Module & module,const char * name_cstr,bool name_is_regex)1716435933ddSDimitry Andric static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
1717*b5893f02SDimitry Andric Module &module, const char *name_cstr,
1718*b5893f02SDimitry Andric bool name_is_regex) {
1719ac7ddfbfSEd Maste TypeList type_list;
1720ac7ddfbfSEd Maste const uint32_t max_num_matches = UINT32_MAX;
1721ac7ddfbfSEd Maste size_t num_matches = 1;
1722ac7ddfbfSEd Maste bool name_is_fully_qualified = false;
1723ac7ddfbfSEd Maste
1724ac7ddfbfSEd Maste ConstString name(name_cstr);
17254bb0738eSEd Maste llvm::DenseSet<SymbolFile *> searched_symbol_files;
1726*b5893f02SDimitry Andric num_matches = module.FindTypes(name, name_is_fully_qualified, max_num_matches,
1727435933ddSDimitry Andric searched_symbol_files, type_list);
1728ac7ddfbfSEd Maste
1729435933ddSDimitry Andric if (num_matches) {
1730ac7ddfbfSEd Maste strm.Indent();
1731ac7ddfbfSEd Maste strm.PutCString("Best match found in ");
1732*b5893f02SDimitry Andric DumpFullpath(strm, &module.GetFileSpec(), 0);
1733ac7ddfbfSEd Maste strm.PutCString(":\n");
1734ac7ddfbfSEd Maste
1735ac7ddfbfSEd Maste TypeSP type_sp(type_list.GetTypeAtIndex(0));
1736435933ddSDimitry Andric if (type_sp) {
17374ba319b5SDimitry Andric // Resolve the clang type so that any forward references to types that
17384ba319b5SDimitry Andric // haven't yet been parsed will get parsed.
17399f2f44ceSEd Maste type_sp->GetFullCompilerType();
1740ac7ddfbfSEd Maste type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1741ac7ddfbfSEd Maste // Print all typedef chains
1742ac7ddfbfSEd Maste TypeSP typedef_type_sp(type_sp);
1743ac7ddfbfSEd Maste TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1744435933ddSDimitry Andric while (typedefed_type_sp) {
1745ac7ddfbfSEd Maste strm.EOL();
1746435933ddSDimitry Andric strm.Printf(" typedef '%s': ",
1747435933ddSDimitry Andric typedef_type_sp->GetName().GetCString());
17489f2f44ceSEd Maste typedefed_type_sp->GetFullCompilerType();
1749ac7ddfbfSEd Maste typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1750ac7ddfbfSEd Maste typedef_type_sp = typedefed_type_sp;
1751ac7ddfbfSEd Maste typedefed_type_sp = typedef_type_sp->GetTypedefType();
1752ac7ddfbfSEd Maste }
1753ac7ddfbfSEd Maste }
1754ac7ddfbfSEd Maste strm.EOL();
1755ac7ddfbfSEd Maste }
1756ac7ddfbfSEd Maste return num_matches;
1757ac7ddfbfSEd Maste }
1758ac7ddfbfSEd Maste
LookupFileAndLineInModule(CommandInterpreter & interpreter,Stream & strm,Module * module,const FileSpec & file_spec,uint32_t line,bool check_inlines,bool verbose)1759435933ddSDimitry Andric static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
1760435933ddSDimitry Andric Stream &strm, Module *module,
1761ac7ddfbfSEd Maste const FileSpec &file_spec,
1762435933ddSDimitry Andric uint32_t line, bool check_inlines,
1763435933ddSDimitry Andric bool verbose) {
1764435933ddSDimitry Andric if (module && file_spec) {
1765ac7ddfbfSEd Maste SymbolContextList sc_list;
1766435933ddSDimitry Andric const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1767435933ddSDimitry Andric file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1768435933ddSDimitry Andric if (num_matches > 0) {
1769ac7ddfbfSEd Maste strm.Indent();
1770435933ddSDimitry Andric strm.Printf("%u match%s found in ", num_matches,
1771435933ddSDimitry Andric num_matches > 1 ? "es" : "");
1772ac7ddfbfSEd Maste strm << file_spec;
1773ac7ddfbfSEd Maste if (line > 0)
1774ac7ddfbfSEd Maste strm.Printf(":%u", line);
1775ac7ddfbfSEd Maste strm << " in ";
1776ac7ddfbfSEd Maste DumpFullpath(strm, &module->GetFileSpec(), 0);
1777ac7ddfbfSEd Maste strm.PutCString(":\n");
1778435933ddSDimitry Andric DumpSymbolContextList(
1779435933ddSDimitry Andric interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1780435933ddSDimitry Andric strm, sc_list, verbose);
1781ac7ddfbfSEd Maste return num_matches;
1782ac7ddfbfSEd Maste }
1783ac7ddfbfSEd Maste }
1784ac7ddfbfSEd Maste return 0;
1785ac7ddfbfSEd Maste }
1786ac7ddfbfSEd Maste
FindModulesByName(Target * target,const char * module_name,ModuleList & module_list,bool check_global_list)1787435933ddSDimitry Andric static size_t FindModulesByName(Target *target, const char *module_name,
1788ac7ddfbfSEd Maste ModuleList &module_list,
1789435933ddSDimitry Andric bool check_global_list) {
1790*b5893f02SDimitry Andric FileSpec module_file_spec(module_name);
1791ac7ddfbfSEd Maste ModuleSpec module_spec(module_file_spec);
1792ac7ddfbfSEd Maste
1793ac7ddfbfSEd Maste const size_t initial_size = module_list.GetSize();
1794ac7ddfbfSEd Maste
1795435933ddSDimitry Andric if (check_global_list) {
1796ac7ddfbfSEd Maste // Check the global list
1797435933ddSDimitry Andric std::lock_guard<std::recursive_mutex> guard(
1798435933ddSDimitry Andric Module::GetAllocationModuleCollectionMutex());
1799ac7ddfbfSEd Maste const size_t num_modules = Module::GetNumberAllocatedModules();
1800ac7ddfbfSEd Maste ModuleSP module_sp;
1801435933ddSDimitry Andric for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1802ac7ddfbfSEd Maste Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1803ac7ddfbfSEd Maste
1804435933ddSDimitry Andric if (module) {
1805435933ddSDimitry Andric if (module->MatchesModuleSpec(module_spec)) {
1806ac7ddfbfSEd Maste module_sp = module->shared_from_this();
1807ac7ddfbfSEd Maste module_list.AppendIfNeeded(module_sp);
1808ac7ddfbfSEd Maste }
1809ac7ddfbfSEd Maste }
1810ac7ddfbfSEd Maste }
1811435933ddSDimitry Andric } else {
1812435933ddSDimitry Andric if (target) {
1813435933ddSDimitry Andric const size_t num_matches =
1814435933ddSDimitry Andric target->GetImages().FindModules(module_spec, module_list);
1815ac7ddfbfSEd Maste
18164ba319b5SDimitry Andric // Not found in our module list for our target, check the main shared
18174ba319b5SDimitry Andric // module list in case it is a extra file used somewhere else
1818435933ddSDimitry Andric if (num_matches == 0) {
1819ac7ddfbfSEd Maste module_spec.GetArchitecture() = target->GetArchitecture();
1820ac7ddfbfSEd Maste ModuleList::FindSharedModules(module_spec, module_list);
1821ac7ddfbfSEd Maste }
1822435933ddSDimitry Andric } else {
1823ac7ddfbfSEd Maste ModuleList::FindSharedModules(module_spec, module_list);
1824ac7ddfbfSEd Maste }
1825ac7ddfbfSEd Maste }
1826ac7ddfbfSEd Maste
1827ac7ddfbfSEd Maste return module_list.GetSize() - initial_size;
1828ac7ddfbfSEd Maste }
1829ac7ddfbfSEd Maste
1830ac7ddfbfSEd Maste #pragma mark CommandObjectTargetModulesModuleAutoComplete
1831ac7ddfbfSEd Maste
1832ac7ddfbfSEd Maste //----------------------------------------------------------------------
1833ac7ddfbfSEd Maste // A base command object class that can auto complete with module file
1834ac7ddfbfSEd Maste // paths
1835ac7ddfbfSEd Maste //----------------------------------------------------------------------
1836ac7ddfbfSEd Maste
1837435933ddSDimitry Andric class CommandObjectTargetModulesModuleAutoComplete
1838435933ddSDimitry Andric : public CommandObjectParsed {
1839ac7ddfbfSEd Maste public:
CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax)1840ac7ddfbfSEd Maste CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1841ac7ddfbfSEd Maste const char *name,
1842ac7ddfbfSEd Maste const char *help,
1843435933ddSDimitry Andric const char *syntax)
1844435933ddSDimitry Andric : CommandObjectParsed(interpreter, name, help, syntax) {
1845ac7ddfbfSEd Maste CommandArgumentEntry arg;
1846ac7ddfbfSEd Maste CommandArgumentData file_arg;
1847ac7ddfbfSEd Maste
1848ac7ddfbfSEd Maste // Define the first (and only) variant of this arg.
1849ac7ddfbfSEd Maste file_arg.arg_type = eArgTypeFilename;
1850ac7ddfbfSEd Maste file_arg.arg_repetition = eArgRepeatStar;
1851ac7ddfbfSEd Maste
1852435933ddSDimitry Andric // There is only one variant this argument could be; put it into the
1853435933ddSDimitry Andric // argument entry.
1854ac7ddfbfSEd Maste arg.push_back(file_arg);
1855ac7ddfbfSEd Maste
1856ac7ddfbfSEd Maste // Push the data for the first argument into the m_arguments vector.
1857ac7ddfbfSEd Maste m_arguments.push_back(arg);
1858ac7ddfbfSEd Maste }
1859ac7ddfbfSEd Maste
18604bb0738eSEd Maste ~CommandObjectTargetModulesModuleAutoComplete() override = default;
1861ac7ddfbfSEd Maste
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)18624ba319b5SDimitry Andric int HandleArgumentCompletion(
18634ba319b5SDimitry Andric CompletionRequest &request,
18644ba319b5SDimitry Andric OptionElementVector &opt_element_vector) override {
1865435933ddSDimitry Andric CommandCompletions::InvokeCommonCompletionCallbacks(
18664ba319b5SDimitry Andric GetCommandInterpreter(), CommandCompletions::eModuleCompletion, request,
18674ba319b5SDimitry Andric nullptr);
18684ba319b5SDimitry Andric return request.GetNumberOfMatches();
1869ac7ddfbfSEd Maste }
1870ac7ddfbfSEd Maste };
1871ac7ddfbfSEd Maste
1872ac7ddfbfSEd Maste #pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1873ac7ddfbfSEd Maste
1874ac7ddfbfSEd Maste //----------------------------------------------------------------------
1875ac7ddfbfSEd Maste // A base command object class that can auto complete with module source
1876ac7ddfbfSEd Maste // file paths
1877ac7ddfbfSEd Maste //----------------------------------------------------------------------
1878ac7ddfbfSEd Maste
1879435933ddSDimitry Andric class CommandObjectTargetModulesSourceFileAutoComplete
1880435933ddSDimitry Andric : public CommandObjectParsed {
1881ac7ddfbfSEd Maste public:
CommandObjectTargetModulesSourceFileAutoComplete(CommandInterpreter & interpreter,const char * name,const char * help,const char * syntax,uint32_t flags)1882435933ddSDimitry Andric CommandObjectTargetModulesSourceFileAutoComplete(
1883435933ddSDimitry Andric CommandInterpreter &interpreter, const char *name, const char *help,
1884435933ddSDimitry Andric const char *syntax, uint32_t flags)
1885435933ddSDimitry Andric : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1886ac7ddfbfSEd Maste CommandArgumentEntry arg;
1887ac7ddfbfSEd Maste CommandArgumentData source_file_arg;
1888ac7ddfbfSEd Maste
1889ac7ddfbfSEd Maste // Define the first (and only) variant of this arg.
1890ac7ddfbfSEd Maste source_file_arg.arg_type = eArgTypeSourceFile;
1891ac7ddfbfSEd Maste source_file_arg.arg_repetition = eArgRepeatPlus;
1892ac7ddfbfSEd Maste
1893435933ddSDimitry Andric // There is only one variant this argument could be; put it into the
1894435933ddSDimitry Andric // argument entry.
1895ac7ddfbfSEd Maste arg.push_back(source_file_arg);
1896ac7ddfbfSEd Maste
1897ac7ddfbfSEd Maste // Push the data for the first argument into the m_arguments vector.
1898ac7ddfbfSEd Maste m_arguments.push_back(arg);
1899ac7ddfbfSEd Maste }
1900ac7ddfbfSEd Maste
19014bb0738eSEd Maste ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
1902ac7ddfbfSEd Maste
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)19034ba319b5SDimitry Andric int HandleArgumentCompletion(
19044ba319b5SDimitry Andric CompletionRequest &request,
19054ba319b5SDimitry Andric OptionElementVector &opt_element_vector) override {
1906435933ddSDimitry Andric CommandCompletions::InvokeCommonCompletionCallbacks(
1907435933ddSDimitry Andric GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
19084ba319b5SDimitry Andric request, nullptr);
19094ba319b5SDimitry Andric return request.GetNumberOfMatches();
1910ac7ddfbfSEd Maste }
1911ac7ddfbfSEd Maste };
1912ac7ddfbfSEd Maste
19134bb0738eSEd Maste #pragma mark CommandObjectTargetModulesDumpObjfile
19144bb0738eSEd Maste
1915435933ddSDimitry Andric class CommandObjectTargetModulesDumpObjfile
1916435933ddSDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
19174bb0738eSEd Maste public:
CommandObjectTargetModulesDumpObjfile(CommandInterpreter & interpreter)19184bb0738eSEd Maste CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
1919435933ddSDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
1920435933ddSDimitry Andric interpreter, "target modules dump objfile",
19214bb0738eSEd Maste "Dump the object file headers from one or more target modules.",
1922435933ddSDimitry Andric nullptr) {}
19234bb0738eSEd Maste
19244bb0738eSEd Maste ~CommandObjectTargetModulesDumpObjfile() override = default;
19254bb0738eSEd Maste
19264bb0738eSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)1927435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
19284bb0738eSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1929435933ddSDimitry Andric if (target == nullptr) {
1930435933ddSDimitry Andric result.AppendError("invalid target, create a debug target using the "
1931435933ddSDimitry Andric "'target create' command");
19324bb0738eSEd Maste result.SetStatus(eReturnStatusFailed);
19334bb0738eSEd Maste return false;
19344bb0738eSEd Maste }
19354bb0738eSEd Maste
19364bb0738eSEd Maste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
19374bb0738eSEd Maste result.GetOutputStream().SetAddressByteSize(addr_byte_size);
19384bb0738eSEd Maste result.GetErrorStream().SetAddressByteSize(addr_byte_size);
19394bb0738eSEd Maste
19404bb0738eSEd Maste size_t num_dumped = 0;
1941435933ddSDimitry Andric if (command.GetArgumentCount() == 0) {
19424bb0738eSEd Maste // Dump all headers for all modules images
1943435933ddSDimitry Andric num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1944435933ddSDimitry Andric target->GetImages());
1945435933ddSDimitry Andric if (num_dumped == 0) {
19464bb0738eSEd Maste result.AppendError("the target has no associated executable images");
19474bb0738eSEd Maste result.SetStatus(eReturnStatusFailed);
19484bb0738eSEd Maste }
1949435933ddSDimitry Andric } else {
19504bb0738eSEd Maste // Find the modules that match the basename or full path.
19514bb0738eSEd Maste ModuleList module_list;
19524bb0738eSEd Maste const char *arg_cstr;
1953435933ddSDimitry Andric for (int arg_idx = 0;
1954435933ddSDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1955435933ddSDimitry Andric ++arg_idx) {
1956435933ddSDimitry Andric size_t num_matched =
1957435933ddSDimitry Andric FindModulesByName(target, arg_cstr, module_list, true);
1958435933ddSDimitry Andric if (num_matched == 0) {
1959435933ddSDimitry Andric result.AppendWarningWithFormat(
1960435933ddSDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
19614bb0738eSEd Maste }
19624bb0738eSEd Maste }
19634bb0738eSEd Maste // Dump all the modules we found.
1964435933ddSDimitry Andric num_dumped =
1965435933ddSDimitry Andric DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
19664bb0738eSEd Maste }
19674bb0738eSEd Maste
1968435933ddSDimitry Andric if (num_dumped > 0) {
19694bb0738eSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
1970435933ddSDimitry Andric } else {
19714bb0738eSEd Maste result.AppendError("no matching executable images found");
19724bb0738eSEd Maste result.SetStatus(eReturnStatusFailed);
19734bb0738eSEd Maste }
19744bb0738eSEd Maste return result.Succeeded();
19754bb0738eSEd Maste }
19764bb0738eSEd Maste };
1977ac7ddfbfSEd Maste
1978ac7ddfbfSEd Maste #pragma mark CommandObjectTargetModulesDumpSymtab
1979ac7ddfbfSEd Maste
1980*b5893f02SDimitry Andric static constexpr OptionEnumValueElement g_sort_option_enumeration[] = {
1981435933ddSDimitry Andric {eSortOrderNone, "none",
1982435933ddSDimitry Andric "No sorting, use the original symbol table order."},
1983435933ddSDimitry Andric {eSortOrderByAddress, "address", "Sort output by symbol address."},
1984*b5893f02SDimitry Andric {eSortOrderByName, "name", "Sort output by symbol name."} };
1985435933ddSDimitry Andric
1986*b5893f02SDimitry Andric static constexpr OptionDefinition g_target_modules_dump_symtab_options[] = {
1987435933ddSDimitry Andric // clang-format off
1988*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, nullptr, OptionEnumValues(g_sort_option_enumeration), 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table." }
1989435933ddSDimitry Andric // clang-format on
1990435933ddSDimitry Andric };
1991435933ddSDimitry Andric
1992435933ddSDimitry Andric class CommandObjectTargetModulesDumpSymtab
1993435933ddSDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
1994ac7ddfbfSEd Maste public:
CommandObjectTargetModulesDumpSymtab(CommandInterpreter & interpreter)1995435933ddSDimitry Andric CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
1996435933ddSDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
1997435933ddSDimitry Andric interpreter, "target modules dump symtab",
1998435933ddSDimitry Andric "Dump the symbol table from one or more target modules.", nullptr),
1999435933ddSDimitry Andric m_options() {}
2000ac7ddfbfSEd Maste
20014bb0738eSEd Maste ~CommandObjectTargetModulesDumpSymtab() override = default;
2002ac7ddfbfSEd Maste
GetOptions()2003435933ddSDimitry Andric Options *GetOptions() override { return &m_options; }
2004ac7ddfbfSEd Maste
2005435933ddSDimitry Andric class CommandOptions : public Options {
2006ac7ddfbfSEd Maste public:
CommandOptions()2007435933ddSDimitry Andric CommandOptions() : Options(), m_sort_order(eSortOrderNone) {}
2008ac7ddfbfSEd Maste
20094bb0738eSEd Maste ~CommandOptions() override = default;
2010ac7ddfbfSEd Maste
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)20115517e702SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2012435933ddSDimitry Andric ExecutionContext *execution_context) override {
20135517e702SDimitry Andric Status error;
2014ac7ddfbfSEd Maste const int short_option = m_getopt_table[option_idx].val;
2015ac7ddfbfSEd Maste
2016435933ddSDimitry Andric switch (short_option) {
2017ac7ddfbfSEd Maste case 's':
20184ba319b5SDimitry Andric m_sort_order = (SortOrder)OptionArgParser::ToOptionEnum(
2019435933ddSDimitry Andric option_arg, GetDefinitions()[option_idx].enum_values,
2020435933ddSDimitry Andric eSortOrderNone, error);
2021ac7ddfbfSEd Maste break;
2022ac7ddfbfSEd Maste
2023ac7ddfbfSEd Maste default:
2024435933ddSDimitry Andric error.SetErrorStringWithFormat("invalid short option character '%c'",
2025435933ddSDimitry Andric short_option);
2026ac7ddfbfSEd Maste break;
2027ac7ddfbfSEd Maste }
2028ac7ddfbfSEd Maste return error;
2029ac7ddfbfSEd Maste }
2030ac7ddfbfSEd Maste
OptionParsingStarting(ExecutionContext * execution_context)2031435933ddSDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
2032ac7ddfbfSEd Maste m_sort_order = eSortOrderNone;
2033ac7ddfbfSEd Maste }
2034ac7ddfbfSEd Maste
GetDefinitions()2035435933ddSDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
2036435933ddSDimitry Andric return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
2037ac7ddfbfSEd Maste }
2038ac7ddfbfSEd Maste
2039ac7ddfbfSEd Maste SortOrder m_sort_order;
2040ac7ddfbfSEd Maste };
2041ac7ddfbfSEd Maste
2042ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)2043435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
2044ac7ddfbfSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2045435933ddSDimitry Andric if (target == nullptr) {
2046435933ddSDimitry Andric result.AppendError("invalid target, create a debug target using the "
2047435933ddSDimitry Andric "'target create' command");
2048ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2049ac7ddfbfSEd Maste return false;
2050435933ddSDimitry Andric } else {
2051ac7ddfbfSEd Maste uint32_t num_dumped = 0;
2052ac7ddfbfSEd Maste
2053ac7ddfbfSEd Maste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2054ac7ddfbfSEd Maste result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2055ac7ddfbfSEd Maste result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2056ac7ddfbfSEd Maste
2057435933ddSDimitry Andric if (command.GetArgumentCount() == 0) {
2058ac7ddfbfSEd Maste // Dump all sections for all modules images
2059435933ddSDimitry Andric std::lock_guard<std::recursive_mutex> guard(
2060435933ddSDimitry Andric target->GetImages().GetMutex());
2061ac7ddfbfSEd Maste const size_t num_modules = target->GetImages().GetSize();
2062435933ddSDimitry Andric if (num_modules > 0) {
2063435933ddSDimitry Andric result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
2064435933ddSDimitry Andric " modules.\n",
2065435933ddSDimitry Andric (uint64_t)num_modules);
2066435933ddSDimitry Andric for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2067435933ddSDimitry Andric if (num_dumped > 0) {
2068ac7ddfbfSEd Maste result.GetOutputStream().EOL();
2069ac7ddfbfSEd Maste result.GetOutputStream().EOL();
2070ac7ddfbfSEd Maste }
2071acac075bSDimitry Andric if (m_interpreter.WasInterrupted())
2072acac075bSDimitry Andric break;
2073ac7ddfbfSEd Maste num_dumped++;
2074435933ddSDimitry Andric DumpModuleSymtab(
2075435933ddSDimitry Andric m_interpreter, result.GetOutputStream(),
2076ac7ddfbfSEd Maste target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2077ac7ddfbfSEd Maste m_options.m_sort_order);
2078ac7ddfbfSEd Maste }
2079435933ddSDimitry Andric } else {
2080ac7ddfbfSEd Maste result.AppendError("the target has no associated executable images");
2081ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2082ac7ddfbfSEd Maste return false;
2083ac7ddfbfSEd Maste }
2084435933ddSDimitry Andric } else {
2085ac7ddfbfSEd Maste // Dump specified images (by basename or fullpath)
2086ac7ddfbfSEd Maste const char *arg_cstr;
2087435933ddSDimitry Andric for (int arg_idx = 0;
2088435933ddSDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2089435933ddSDimitry Andric ++arg_idx) {
2090ac7ddfbfSEd Maste ModuleList module_list;
2091435933ddSDimitry Andric const size_t num_matches =
2092435933ddSDimitry Andric FindModulesByName(target, arg_cstr, module_list, true);
2093435933ddSDimitry Andric if (num_matches > 0) {
2094435933ddSDimitry Andric for (size_t i = 0; i < num_matches; ++i) {
2095ac7ddfbfSEd Maste Module *module = module_list.GetModulePointerAtIndex(i);
2096435933ddSDimitry Andric if (module) {
2097435933ddSDimitry Andric if (num_dumped > 0) {
2098ac7ddfbfSEd Maste result.GetOutputStream().EOL();
2099ac7ddfbfSEd Maste result.GetOutputStream().EOL();
2100ac7ddfbfSEd Maste }
2101acac075bSDimitry Andric if (m_interpreter.WasInterrupted())
2102acac075bSDimitry Andric break;
2103ac7ddfbfSEd Maste num_dumped++;
2104435933ddSDimitry Andric DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2105435933ddSDimitry Andric module, m_options.m_sort_order);
2106ac7ddfbfSEd Maste }
2107ac7ddfbfSEd Maste }
2108435933ddSDimitry Andric } else
2109435933ddSDimitry Andric result.AppendWarningWithFormat(
2110435933ddSDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
2111ac7ddfbfSEd Maste }
2112ac7ddfbfSEd Maste }
2113ac7ddfbfSEd Maste
2114ac7ddfbfSEd Maste if (num_dumped > 0)
2115ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
2116435933ddSDimitry Andric else {
2117ac7ddfbfSEd Maste result.AppendError("no matching executable images found");
2118ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2119ac7ddfbfSEd Maste }
2120ac7ddfbfSEd Maste }
2121ac7ddfbfSEd Maste return result.Succeeded();
2122ac7ddfbfSEd Maste }
2123ac7ddfbfSEd Maste
2124ac7ddfbfSEd Maste CommandOptions m_options;
2125ac7ddfbfSEd Maste };
2126ac7ddfbfSEd Maste
2127ac7ddfbfSEd Maste #pragma mark CommandObjectTargetModulesDumpSections
2128ac7ddfbfSEd Maste
2129ac7ddfbfSEd Maste //----------------------------------------------------------------------
2130ac7ddfbfSEd Maste // Image section dumping command
2131ac7ddfbfSEd Maste //----------------------------------------------------------------------
2132ac7ddfbfSEd Maste
2133435933ddSDimitry Andric class CommandObjectTargetModulesDumpSections
2134435933ddSDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
2135ac7ddfbfSEd Maste public:
CommandObjectTargetModulesDumpSections(CommandInterpreter & interpreter)2136435933ddSDimitry Andric CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
2137435933ddSDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
2138435933ddSDimitry Andric interpreter, "target modules dump sections",
2139ac7ddfbfSEd Maste "Dump the sections from one or more target modules.",
2140ac7ddfbfSEd Maste //"target modules dump sections [<file1> ...]")
2141435933ddSDimitry Andric nullptr) {}
2142ac7ddfbfSEd Maste
21434bb0738eSEd Maste ~CommandObjectTargetModulesDumpSections() override = default;
2144ac7ddfbfSEd Maste
2145ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)2146435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
2147ac7ddfbfSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2148435933ddSDimitry Andric if (target == nullptr) {
2149435933ddSDimitry Andric result.AppendError("invalid target, create a debug target using the "
2150435933ddSDimitry Andric "'target create' command");
2151ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2152ac7ddfbfSEd Maste return false;
2153435933ddSDimitry Andric } else {
2154ac7ddfbfSEd Maste uint32_t num_dumped = 0;
2155ac7ddfbfSEd Maste
2156ac7ddfbfSEd Maste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2157ac7ddfbfSEd Maste result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2158ac7ddfbfSEd Maste result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2159ac7ddfbfSEd Maste
2160435933ddSDimitry Andric if (command.GetArgumentCount() == 0) {
2161ac7ddfbfSEd Maste // Dump all sections for all modules images
2162ac7ddfbfSEd Maste const size_t num_modules = target->GetImages().GetSize();
2163435933ddSDimitry Andric if (num_modules > 0) {
2164435933ddSDimitry Andric result.GetOutputStream().Printf("Dumping sections for %" PRIu64
2165435933ddSDimitry Andric " modules.\n",
2166435933ddSDimitry Andric (uint64_t)num_modules);
2167435933ddSDimitry Andric for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2168acac075bSDimitry Andric if (m_interpreter.WasInterrupted())
2169acac075bSDimitry Andric break;
2170ac7ddfbfSEd Maste num_dumped++;
2171435933ddSDimitry Andric DumpModuleSections(
2172435933ddSDimitry Andric m_interpreter, result.GetOutputStream(),
2173435933ddSDimitry Andric target->GetImages().GetModulePointerAtIndex(image_idx));
2174ac7ddfbfSEd Maste }
2175435933ddSDimitry Andric } else {
2176ac7ddfbfSEd Maste result.AppendError("the target has no associated executable images");
2177ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2178ac7ddfbfSEd Maste return false;
2179ac7ddfbfSEd Maste }
2180435933ddSDimitry Andric } else {
2181ac7ddfbfSEd Maste // Dump specified images (by basename or fullpath)
2182ac7ddfbfSEd Maste const char *arg_cstr;
2183435933ddSDimitry Andric for (int arg_idx = 0;
2184435933ddSDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2185435933ddSDimitry Andric ++arg_idx) {
2186ac7ddfbfSEd Maste ModuleList module_list;
2187435933ddSDimitry Andric const size_t num_matches =
2188435933ddSDimitry Andric FindModulesByName(target, arg_cstr, module_list, true);
2189435933ddSDimitry Andric if (num_matches > 0) {
2190435933ddSDimitry Andric for (size_t i = 0; i < num_matches; ++i) {
2191acac075bSDimitry Andric if (m_interpreter.WasInterrupted())
2192acac075bSDimitry Andric break;
2193ac7ddfbfSEd Maste Module *module = module_list.GetModulePointerAtIndex(i);
2194435933ddSDimitry Andric if (module) {
2195ac7ddfbfSEd Maste num_dumped++;
2196435933ddSDimitry Andric DumpModuleSections(m_interpreter, result.GetOutputStream(),
2197435933ddSDimitry Andric module);
2198ac7ddfbfSEd Maste }
2199ac7ddfbfSEd Maste }
2200435933ddSDimitry Andric } else {
2201ac7ddfbfSEd Maste // Check the global list
2202435933ddSDimitry Andric std::lock_guard<std::recursive_mutex> guard(
2203435933ddSDimitry Andric Module::GetAllocationModuleCollectionMutex());
2204ac7ddfbfSEd Maste
2205435933ddSDimitry Andric result.AppendWarningWithFormat(
2206435933ddSDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
2207ac7ddfbfSEd Maste }
2208ac7ddfbfSEd Maste }
2209ac7ddfbfSEd Maste }
2210ac7ddfbfSEd Maste
2211ac7ddfbfSEd Maste if (num_dumped > 0)
2212ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
2213435933ddSDimitry Andric else {
2214ac7ddfbfSEd Maste result.AppendError("no matching executable images found");
2215ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2216ac7ddfbfSEd Maste }
2217ac7ddfbfSEd Maste }
2218ac7ddfbfSEd Maste return result.Succeeded();
2219ac7ddfbfSEd Maste }
2220ac7ddfbfSEd Maste };
2221ac7ddfbfSEd Maste
2222*b5893f02SDimitry Andric #pragma mark CommandObjectTargetModulesDumpSections
2223*b5893f02SDimitry Andric
2224*b5893f02SDimitry Andric //----------------------------------------------------------------------
2225*b5893f02SDimitry Andric // Clang AST dumping command
2226*b5893f02SDimitry Andric //----------------------------------------------------------------------
2227*b5893f02SDimitry Andric
2228*b5893f02SDimitry Andric class CommandObjectTargetModulesDumpClangAST
2229*b5893f02SDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
2230*b5893f02SDimitry Andric public:
CommandObjectTargetModulesDumpClangAST(CommandInterpreter & interpreter)2231*b5893f02SDimitry Andric CommandObjectTargetModulesDumpClangAST(CommandInterpreter &interpreter)
2232*b5893f02SDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
2233*b5893f02SDimitry Andric interpreter, "target modules dump ast",
2234*b5893f02SDimitry Andric "Dump the clang ast for a given module's symbol file.",
2235*b5893f02SDimitry Andric //"target modules dump ast [<file1> ...]")
2236*b5893f02SDimitry Andric nullptr) {}
2237*b5893f02SDimitry Andric
2238*b5893f02SDimitry Andric ~CommandObjectTargetModulesDumpClangAST() override = default;
2239*b5893f02SDimitry Andric
2240*b5893f02SDimitry Andric protected:
DoExecute(Args & command,CommandReturnObject & result)2241*b5893f02SDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
2242*b5893f02SDimitry Andric Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2243*b5893f02SDimitry Andric if (target == nullptr) {
2244*b5893f02SDimitry Andric result.AppendError("invalid target, create a debug target using the "
2245*b5893f02SDimitry Andric "'target create' command");
2246*b5893f02SDimitry Andric result.SetStatus(eReturnStatusFailed);
2247*b5893f02SDimitry Andric return false;
2248*b5893f02SDimitry Andric }
2249*b5893f02SDimitry Andric
2250*b5893f02SDimitry Andric const size_t num_modules = target->GetImages().GetSize();
2251*b5893f02SDimitry Andric if (num_modules == 0) {
2252*b5893f02SDimitry Andric result.AppendError("the target has no associated executable images");
2253*b5893f02SDimitry Andric result.SetStatus(eReturnStatusFailed);
2254*b5893f02SDimitry Andric return false;
2255*b5893f02SDimitry Andric }
2256*b5893f02SDimitry Andric
2257*b5893f02SDimitry Andric if (command.GetArgumentCount() == 0) {
2258*b5893f02SDimitry Andric // Dump all ASTs for all modules images
2259*b5893f02SDimitry Andric result.GetOutputStream().Printf("Dumping clang ast for %" PRIu64
2260*b5893f02SDimitry Andric " modules.\n",
2261*b5893f02SDimitry Andric (uint64_t)num_modules);
2262*b5893f02SDimitry Andric for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2263*b5893f02SDimitry Andric if (m_interpreter.WasInterrupted())
2264*b5893f02SDimitry Andric break;
2265*b5893f02SDimitry Andric Module *m = target->GetImages().GetModulePointerAtIndex(image_idx);
2266*b5893f02SDimitry Andric SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile();
2267*b5893f02SDimitry Andric sf->DumpClangAST(result.GetOutputStream());
2268*b5893f02SDimitry Andric }
2269*b5893f02SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
2270*b5893f02SDimitry Andric return true;
2271*b5893f02SDimitry Andric }
2272*b5893f02SDimitry Andric
2273*b5893f02SDimitry Andric // Dump specified ASTs (by basename or fullpath)
2274*b5893f02SDimitry Andric for (const Args::ArgEntry &arg : command.entries()) {
2275*b5893f02SDimitry Andric ModuleList module_list;
2276*b5893f02SDimitry Andric const size_t num_matches =
2277*b5893f02SDimitry Andric FindModulesByName(target, arg.c_str(), module_list, true);
2278*b5893f02SDimitry Andric if (num_matches == 0) {
2279*b5893f02SDimitry Andric // Check the global list
2280*b5893f02SDimitry Andric std::lock_guard<std::recursive_mutex> guard(
2281*b5893f02SDimitry Andric Module::GetAllocationModuleCollectionMutex());
2282*b5893f02SDimitry Andric
2283*b5893f02SDimitry Andric result.AppendWarningWithFormat(
2284*b5893f02SDimitry Andric "Unable to find an image that matches '%s'.\n", arg.c_str());
2285*b5893f02SDimitry Andric continue;
2286*b5893f02SDimitry Andric }
2287*b5893f02SDimitry Andric
2288*b5893f02SDimitry Andric for (size_t i = 0; i < num_matches; ++i) {
2289*b5893f02SDimitry Andric if (m_interpreter.WasInterrupted())
2290*b5893f02SDimitry Andric break;
2291*b5893f02SDimitry Andric Module *m = module_list.GetModulePointerAtIndex(i);
2292*b5893f02SDimitry Andric SymbolFile *sf = m->GetSymbolVendor()->GetSymbolFile();
2293*b5893f02SDimitry Andric sf->DumpClangAST(result.GetOutputStream());
2294*b5893f02SDimitry Andric }
2295*b5893f02SDimitry Andric }
2296*b5893f02SDimitry Andric result.SetStatus(eReturnStatusSuccessFinishResult);
2297*b5893f02SDimitry Andric return true;
2298*b5893f02SDimitry Andric }
2299*b5893f02SDimitry Andric };
2300*b5893f02SDimitry Andric
2301ac7ddfbfSEd Maste #pragma mark CommandObjectTargetModulesDumpSymfile
2302ac7ddfbfSEd Maste
2303ac7ddfbfSEd Maste //----------------------------------------------------------------------
2304ac7ddfbfSEd Maste // Image debug symbol dumping command
2305ac7ddfbfSEd Maste //----------------------------------------------------------------------
2306ac7ddfbfSEd Maste
2307435933ddSDimitry Andric class CommandObjectTargetModulesDumpSymfile
2308435933ddSDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
2309ac7ddfbfSEd Maste public:
CommandObjectTargetModulesDumpSymfile(CommandInterpreter & interpreter)2310435933ddSDimitry Andric CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
2311435933ddSDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
2312435933ddSDimitry Andric interpreter, "target modules dump symfile",
2313ac7ddfbfSEd Maste "Dump the debug symbol file for one or more target modules.",
2314ac7ddfbfSEd Maste //"target modules dump symfile [<file1> ...]")
2315435933ddSDimitry Andric nullptr) {}
2316ac7ddfbfSEd Maste
23174bb0738eSEd Maste ~CommandObjectTargetModulesDumpSymfile() override = default;
2318ac7ddfbfSEd Maste
2319ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)2320435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
2321ac7ddfbfSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2322435933ddSDimitry Andric if (target == nullptr) {
2323435933ddSDimitry Andric result.AppendError("invalid target, create a debug target using the "
2324435933ddSDimitry Andric "'target create' command");
2325ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2326ac7ddfbfSEd Maste return false;
2327435933ddSDimitry Andric } else {
2328ac7ddfbfSEd Maste uint32_t num_dumped = 0;
2329ac7ddfbfSEd Maste
2330ac7ddfbfSEd Maste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2331ac7ddfbfSEd Maste result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2332ac7ddfbfSEd Maste result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2333ac7ddfbfSEd Maste
2334435933ddSDimitry Andric if (command.GetArgumentCount() == 0) {
2335ac7ddfbfSEd Maste // Dump all sections for all modules images
2336ac7ddfbfSEd Maste const ModuleList &target_modules = target->GetImages();
23374bb0738eSEd Maste std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2338ac7ddfbfSEd Maste const size_t num_modules = target_modules.GetSize();
2339435933ddSDimitry Andric if (num_modules > 0) {
2340435933ddSDimitry Andric result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
2341435933ddSDimitry Andric " modules.\n",
2342435933ddSDimitry Andric (uint64_t)num_modules);
2343435933ddSDimitry Andric for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2344acac075bSDimitry Andric if (m_interpreter.WasInterrupted())
2345acac075bSDimitry Andric break;
2346435933ddSDimitry Andric if (DumpModuleSymbolVendor(
2347435933ddSDimitry Andric result.GetOutputStream(),
2348435933ddSDimitry Andric target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2349ac7ddfbfSEd Maste num_dumped++;
2350ac7ddfbfSEd Maste }
2351435933ddSDimitry Andric } else {
2352ac7ddfbfSEd Maste result.AppendError("the target has no associated executable images");
2353ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2354ac7ddfbfSEd Maste return false;
2355ac7ddfbfSEd Maste }
2356435933ddSDimitry Andric } else {
2357ac7ddfbfSEd Maste // Dump specified images (by basename or fullpath)
2358ac7ddfbfSEd Maste const char *arg_cstr;
2359435933ddSDimitry Andric for (int arg_idx = 0;
2360435933ddSDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2361435933ddSDimitry Andric ++arg_idx) {
2362ac7ddfbfSEd Maste ModuleList module_list;
2363435933ddSDimitry Andric const size_t num_matches =
2364435933ddSDimitry Andric FindModulesByName(target, arg_cstr, module_list, true);
2365435933ddSDimitry Andric if (num_matches > 0) {
2366435933ddSDimitry Andric for (size_t i = 0; i < num_matches; ++i) {
2367acac075bSDimitry Andric if (m_interpreter.WasInterrupted())
2368acac075bSDimitry Andric break;
2369ac7ddfbfSEd Maste Module *module = module_list.GetModulePointerAtIndex(i);
2370435933ddSDimitry Andric if (module) {
2371ac7ddfbfSEd Maste if (DumpModuleSymbolVendor(result.GetOutputStream(), module))
2372ac7ddfbfSEd Maste num_dumped++;
2373ac7ddfbfSEd Maste }
2374ac7ddfbfSEd Maste }
2375435933ddSDimitry Andric } else
2376435933ddSDimitry Andric result.AppendWarningWithFormat(
2377435933ddSDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
2378ac7ddfbfSEd Maste }
2379ac7ddfbfSEd Maste }
2380ac7ddfbfSEd Maste
2381ac7ddfbfSEd Maste if (num_dumped > 0)
2382ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
2383435933ddSDimitry Andric else {
2384ac7ddfbfSEd Maste result.AppendError("no matching executable images found");
2385ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2386ac7ddfbfSEd Maste }
2387ac7ddfbfSEd Maste }
2388ac7ddfbfSEd Maste return result.Succeeded();
2389ac7ddfbfSEd Maste }
2390ac7ddfbfSEd Maste };
2391ac7ddfbfSEd Maste
2392ac7ddfbfSEd Maste #pragma mark CommandObjectTargetModulesDumpLineTable
2393ac7ddfbfSEd Maste
2394ac7ddfbfSEd Maste //----------------------------------------------------------------------
2395ac7ddfbfSEd Maste // Image debug line table dumping command
2396ac7ddfbfSEd Maste //----------------------------------------------------------------------
2397ac7ddfbfSEd Maste
2398435933ddSDimitry Andric class CommandObjectTargetModulesDumpLineTable
2399435933ddSDimitry Andric : public CommandObjectTargetModulesSourceFileAutoComplete {
2400ac7ddfbfSEd Maste public:
CommandObjectTargetModulesDumpLineTable(CommandInterpreter & interpreter)2401435933ddSDimitry Andric CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
2402435933ddSDimitry Andric : CommandObjectTargetModulesSourceFileAutoComplete(
2403435933ddSDimitry Andric interpreter, "target modules dump line-table",
2404435933ddSDimitry Andric "Dump the line table for one or more compilation units.", nullptr,
2405435933ddSDimitry Andric eCommandRequiresTarget) {}
2406ac7ddfbfSEd Maste
24074bb0738eSEd Maste ~CommandObjectTargetModulesDumpLineTable() override = default;
2408ac7ddfbfSEd Maste
2409ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)2410435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
2411ac7ddfbfSEd Maste Target *target = m_exe_ctx.GetTargetPtr();
2412ac7ddfbfSEd Maste uint32_t total_num_dumped = 0;
2413ac7ddfbfSEd Maste
2414ac7ddfbfSEd Maste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2415ac7ddfbfSEd Maste result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2416ac7ddfbfSEd Maste result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2417ac7ddfbfSEd Maste
2418435933ddSDimitry Andric if (command.GetArgumentCount() == 0) {
2419a1bd240cSDimitry Andric result.AppendError("file option must be specified.");
2420ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2421a1bd240cSDimitry Andric return result.Succeeded();
2422435933ddSDimitry Andric } else {
2423ac7ddfbfSEd Maste // Dump specified images (by basename or fullpath)
2424ac7ddfbfSEd Maste const char *arg_cstr;
2425435933ddSDimitry Andric for (int arg_idx = 0;
2426435933ddSDimitry Andric (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2427435933ddSDimitry Andric ++arg_idx) {
2428*b5893f02SDimitry Andric FileSpec file_spec(arg_cstr);
2429ac7ddfbfSEd Maste
2430ac7ddfbfSEd Maste const ModuleList &target_modules = target->GetImages();
24314bb0738eSEd Maste std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2432ac7ddfbfSEd Maste const size_t num_modules = target_modules.GetSize();
2433435933ddSDimitry Andric if (num_modules > 0) {
2434ac7ddfbfSEd Maste uint32_t num_dumped = 0;
2435435933ddSDimitry Andric for (uint32_t i = 0; i < num_modules; ++i) {
2436acac075bSDimitry Andric if (m_interpreter.WasInterrupted())
2437acac075bSDimitry Andric break;
2438435933ddSDimitry Andric if (DumpCompileUnitLineTable(
2439435933ddSDimitry Andric m_interpreter, result.GetOutputStream(),
2440ac7ddfbfSEd Maste target_modules.GetModulePointerAtIndexUnlocked(i),
2441435933ddSDimitry Andric file_spec, m_exe_ctx.GetProcessPtr() &&
2442435933ddSDimitry Andric m_exe_ctx.GetProcessRef().IsAlive()))
2443ac7ddfbfSEd Maste num_dumped++;
2444ac7ddfbfSEd Maste }
2445ac7ddfbfSEd Maste if (num_dumped == 0)
2446435933ddSDimitry Andric result.AppendWarningWithFormat(
2447435933ddSDimitry Andric "No source filenames matched '%s'.\n", arg_cstr);
2448ac7ddfbfSEd Maste else
2449ac7ddfbfSEd Maste total_num_dumped += num_dumped;
2450ac7ddfbfSEd Maste }
2451ac7ddfbfSEd Maste }
2452ac7ddfbfSEd Maste }
2453ac7ddfbfSEd Maste
2454ac7ddfbfSEd Maste if (total_num_dumped > 0)
2455ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
2456435933ddSDimitry Andric else {
2457ac7ddfbfSEd Maste result.AppendError("no source filenames matched any command arguments");
2458ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2459ac7ddfbfSEd Maste }
2460ac7ddfbfSEd Maste return result.Succeeded();
2461ac7ddfbfSEd Maste }
2462ac7ddfbfSEd Maste };
2463ac7ddfbfSEd Maste
2464ac7ddfbfSEd Maste #pragma mark CommandObjectTargetModulesDump
2465ac7ddfbfSEd Maste
2466ac7ddfbfSEd Maste //----------------------------------------------------------------------
2467ac7ddfbfSEd Maste // Dump multi-word command for target modules
2468ac7ddfbfSEd Maste //----------------------------------------------------------------------
2469ac7ddfbfSEd Maste
2470435933ddSDimitry Andric class CommandObjectTargetModulesDump : public CommandObjectMultiword {
2471ac7ddfbfSEd Maste public:
2472ac7ddfbfSEd Maste //------------------------------------------------------------------
2473ac7ddfbfSEd Maste // Constructors and Destructors
2474ac7ddfbfSEd Maste //------------------------------------------------------------------
CommandObjectTargetModulesDump(CommandInterpreter & interpreter)24754bb0738eSEd Maste CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2476*b5893f02SDimitry Andric : CommandObjectMultiword(
2477*b5893f02SDimitry Andric interpreter, "target modules dump",
2478435933ddSDimitry Andric "Commands for dumping information about one or "
2479435933ddSDimitry Andric "more target modules.",
2480435933ddSDimitry Andric "target modules dump "
2481*b5893f02SDimitry Andric "[headers|symtab|sections|ast|symfile|line-table] "
2482435933ddSDimitry Andric "[<file1> <file2> ...]") {
2483435933ddSDimitry Andric LoadSubCommand("objfile",
2484435933ddSDimitry Andric CommandObjectSP(
2485435933ddSDimitry Andric new CommandObjectTargetModulesDumpObjfile(interpreter)));
2486435933ddSDimitry Andric LoadSubCommand(
2487435933ddSDimitry Andric "symtab",
2488435933ddSDimitry Andric CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
2489435933ddSDimitry Andric LoadSubCommand("sections",
2490435933ddSDimitry Andric CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2491435933ddSDimitry Andric interpreter)));
2492435933ddSDimitry Andric LoadSubCommand("symfile",
2493435933ddSDimitry Andric CommandObjectSP(
2494435933ddSDimitry Andric new CommandObjectTargetModulesDumpSymfile(interpreter)));
2495*b5893f02SDimitry Andric LoadSubCommand(
2496*b5893f02SDimitry Andric "ast", CommandObjectSP(
2497*b5893f02SDimitry Andric new CommandObjectTargetModulesDumpClangAST(interpreter)));
2498435933ddSDimitry Andric LoadSubCommand("line-table",
2499435933ddSDimitry Andric CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2500435933ddSDimitry Andric interpreter)));
2501ac7ddfbfSEd Maste }
2502ac7ddfbfSEd Maste
25034bb0738eSEd Maste ~CommandObjectTargetModulesDump() override = default;
2504ac7ddfbfSEd Maste };
2505ac7ddfbfSEd Maste
2506435933ddSDimitry Andric class CommandObjectTargetModulesAdd : public CommandObjectParsed {
2507ac7ddfbfSEd Maste public:
CommandObjectTargetModulesAdd(CommandInterpreter & interpreter)2508435933ddSDimitry Andric CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
2509435933ddSDimitry Andric : CommandObjectParsed(interpreter, "target modules add",
2510ac7ddfbfSEd Maste "Add a new module to the current target's modules.",
2511ac7ddfbfSEd Maste "target modules add [<module>]"),
2512435933ddSDimitry Andric m_option_group(),
2513435933ddSDimitry Andric m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2514435933ddSDimitry Andric eArgTypeFilename, "Fullpath to a stand alone debug "
2515435933ddSDimitry Andric "symbols file for when debug symbols "
2516435933ddSDimitry Andric "are not in the executable.") {
2517435933ddSDimitry Andric m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2518435933ddSDimitry Andric LLDB_OPT_SET_1);
2519ac7ddfbfSEd Maste m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2520ac7ddfbfSEd Maste m_option_group.Finalize();
2521ac7ddfbfSEd Maste }
2522ac7ddfbfSEd Maste
25234bb0738eSEd Maste ~CommandObjectTargetModulesAdd() override = default;
2524ac7ddfbfSEd Maste
GetOptions()2525435933ddSDimitry Andric Options *GetOptions() override { return &m_option_group; }
2526ac7ddfbfSEd Maste
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)25274ba319b5SDimitry Andric int HandleArgumentCompletion(
25284ba319b5SDimitry Andric CompletionRequest &request,
25294ba319b5SDimitry Andric OptionElementVector &opt_element_vector) override {
2530435933ddSDimitry Andric CommandCompletions::InvokeCommonCompletionCallbacks(
2531435933ddSDimitry Andric GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
25324ba319b5SDimitry Andric request, nullptr);
25334ba319b5SDimitry Andric return request.GetNumberOfMatches();
2534ac7ddfbfSEd Maste }
2535ac7ddfbfSEd Maste
2536ac7ddfbfSEd Maste protected:
2537ac7ddfbfSEd Maste OptionGroupOptions m_option_group;
2538ac7ddfbfSEd Maste OptionGroupUUID m_uuid_option_group;
2539ac7ddfbfSEd Maste OptionGroupFile m_symbol_file;
2540ac7ddfbfSEd Maste
DoExecute(Args & args,CommandReturnObject & result)2541435933ddSDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
2542ac7ddfbfSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2543435933ddSDimitry Andric if (target == nullptr) {
2544435933ddSDimitry Andric result.AppendError("invalid target, create a debug target using the "
2545435933ddSDimitry Andric "'target create' command");
2546ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2547ac7ddfbfSEd Maste return false;
2548435933ddSDimitry Andric } else {
2549ac7ddfbfSEd Maste bool flush = false;
2550ac7ddfbfSEd Maste
2551ac7ddfbfSEd Maste const size_t argc = args.GetArgumentCount();
2552435933ddSDimitry Andric if (argc == 0) {
2553435933ddSDimitry Andric if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2554ac7ddfbfSEd Maste // We are given a UUID only, go locate the file
2555ac7ddfbfSEd Maste ModuleSpec module_spec;
2556435933ddSDimitry Andric module_spec.GetUUID() =
2557435933ddSDimitry Andric m_uuid_option_group.GetOptionValue().GetCurrentValue();
2558ac7ddfbfSEd Maste if (m_symbol_file.GetOptionValue().OptionWasSet())
2559435933ddSDimitry Andric module_spec.GetSymbolFileSpec() =
2560435933ddSDimitry Andric m_symbol_file.GetOptionValue().GetCurrentValue();
2561435933ddSDimitry Andric if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
2562ac7ddfbfSEd Maste ModuleSP module_sp(target->GetSharedModule(module_spec));
2563435933ddSDimitry Andric if (module_sp) {
2564ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
2565ac7ddfbfSEd Maste return true;
2566435933ddSDimitry Andric } else {
2567ac7ddfbfSEd Maste StreamString strm;
2568ac7ddfbfSEd Maste module_spec.GetUUID().Dump(&strm);
2569435933ddSDimitry Andric if (module_spec.GetFileSpec()) {
2570435933ddSDimitry Andric if (module_spec.GetSymbolFileSpec()) {
2571435933ddSDimitry Andric result.AppendErrorWithFormat(
2572435933ddSDimitry Andric "Unable to create the executable or symbol file with "
2573435933ddSDimitry Andric "UUID %s with path %s and symbol file %s",
2574435933ddSDimitry Andric strm.GetData(),
2575ac7ddfbfSEd Maste module_spec.GetFileSpec().GetPath().c_str(),
2576ac7ddfbfSEd Maste module_spec.GetSymbolFileSpec().GetPath().c_str());
2577435933ddSDimitry Andric } else {
2578435933ddSDimitry Andric result.AppendErrorWithFormat(
2579435933ddSDimitry Andric "Unable to create the executable or symbol file with "
2580435933ddSDimitry Andric "UUID %s with path %s",
2581435933ddSDimitry Andric strm.GetData(),
2582ac7ddfbfSEd Maste module_spec.GetFileSpec().GetPath().c_str());
2583ac7ddfbfSEd Maste }
2584435933ddSDimitry Andric } else {
2585435933ddSDimitry Andric result.AppendErrorWithFormat("Unable to create the executable "
2586435933ddSDimitry Andric "or symbol file with UUID %s",
2587435933ddSDimitry Andric strm.GetData());
2588ac7ddfbfSEd Maste }
2589ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2590ac7ddfbfSEd Maste return false;
2591ac7ddfbfSEd Maste }
2592435933ddSDimitry Andric } else {
2593ac7ddfbfSEd Maste StreamString strm;
2594ac7ddfbfSEd Maste module_spec.GetUUID().Dump(&strm);
2595435933ddSDimitry Andric result.AppendErrorWithFormat(
2596435933ddSDimitry Andric "Unable to locate the executable or symbol file with UUID %s",
2597435933ddSDimitry Andric strm.GetData());
2598ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2599ac7ddfbfSEd Maste return false;
2600ac7ddfbfSEd Maste }
2601435933ddSDimitry Andric } else {
2602435933ddSDimitry Andric result.AppendError(
2603435933ddSDimitry Andric "one or more executable image paths must be specified");
2604ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2605ac7ddfbfSEd Maste return false;
2606ac7ddfbfSEd Maste }
2607435933ddSDimitry Andric } else {
2608435933ddSDimitry Andric for (auto &entry : args.entries()) {
2609435933ddSDimitry Andric if (entry.ref.empty())
2610435933ddSDimitry Andric continue;
2611435933ddSDimitry Andric
2612*b5893f02SDimitry Andric FileSpec file_spec(entry.ref);
2613*b5893f02SDimitry Andric if (FileSystem::Instance().Exists(file_spec)) {
2614ac7ddfbfSEd Maste ModuleSpec module_spec(file_spec);
2615ac7ddfbfSEd Maste if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2616435933ddSDimitry Andric module_spec.GetUUID() =
2617435933ddSDimitry Andric m_uuid_option_group.GetOptionValue().GetCurrentValue();
2618ac7ddfbfSEd Maste if (m_symbol_file.GetOptionValue().OptionWasSet())
2619435933ddSDimitry Andric module_spec.GetSymbolFileSpec() =
2620435933ddSDimitry Andric m_symbol_file.GetOptionValue().GetCurrentValue();
262135617911SEd Maste if (!module_spec.GetArchitecture().IsValid())
262235617911SEd Maste module_spec.GetArchitecture() = target->GetArchitecture();
26235517e702SDimitry Andric Status error;
2624ac7ddfbfSEd Maste ModuleSP module_sp(target->GetSharedModule(module_spec, &error));
2625435933ddSDimitry Andric if (!module_sp) {
2626ac7ddfbfSEd Maste const char *error_cstr = error.AsCString();
2627ac7ddfbfSEd Maste if (error_cstr)
2628ac7ddfbfSEd Maste result.AppendError(error_cstr);
2629ac7ddfbfSEd Maste else
2630435933ddSDimitry Andric result.AppendErrorWithFormat("unsupported module: %s",
2631435933ddSDimitry Andric entry.c_str());
2632ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2633ac7ddfbfSEd Maste return false;
2634435933ddSDimitry Andric } else {
2635ac7ddfbfSEd Maste flush = true;
2636ac7ddfbfSEd Maste }
2637ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
2638435933ddSDimitry Andric } else {
2639435933ddSDimitry Andric std::string resolved_path = file_spec.GetPath();
2640ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2641435933ddSDimitry Andric if (resolved_path != entry.ref) {
2642435933ddSDimitry Andric result.AppendErrorWithFormat(
2643435933ddSDimitry Andric "invalid module path '%s' with resolved path '%s'\n",
2644435933ddSDimitry Andric entry.ref.str().c_str(), resolved_path.c_str());
2645ac7ddfbfSEd Maste break;
2646ac7ddfbfSEd Maste }
2647435933ddSDimitry Andric result.AppendErrorWithFormat("invalid module path '%s'\n",
2648435933ddSDimitry Andric entry.c_str());
2649ac7ddfbfSEd Maste break;
2650ac7ddfbfSEd Maste }
2651ac7ddfbfSEd Maste }
2652ac7ddfbfSEd Maste }
2653ac7ddfbfSEd Maste
2654435933ddSDimitry Andric if (flush) {
2655ac7ddfbfSEd Maste ProcessSP process = target->GetProcessSP();
2656ac7ddfbfSEd Maste if (process)
2657ac7ddfbfSEd Maste process->Flush();
2658ac7ddfbfSEd Maste }
2659ac7ddfbfSEd Maste }
2660ac7ddfbfSEd Maste
2661ac7ddfbfSEd Maste return result.Succeeded();
2662ac7ddfbfSEd Maste }
2663ac7ddfbfSEd Maste };
2664ac7ddfbfSEd Maste
2665435933ddSDimitry Andric class CommandObjectTargetModulesLoad
2666435933ddSDimitry Andric : public CommandObjectTargetModulesModuleAutoComplete {
2667ac7ddfbfSEd Maste public:
CommandObjectTargetModulesLoad(CommandInterpreter & interpreter)2668435933ddSDimitry Andric CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
2669435933ddSDimitry Andric : CommandObjectTargetModulesModuleAutoComplete(
2670435933ddSDimitry Andric interpreter, "target modules load", "Set the load addresses for "
2671435933ddSDimitry Andric "one or more sections in a "
2672435933ddSDimitry Andric "target module.",
2673435933ddSDimitry Andric "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2674435933ddSDimitry Andric "<address> [<sect-name> <address> ....]"),
2675435933ddSDimitry Andric m_option_group(),
2676435933ddSDimitry Andric m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2677435933ddSDimitry Andric "Fullpath or basename for module to load.", ""),
2678f678e45dSDimitry Andric m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2679f678e45dSDimitry Andric "Write file contents to the memory.", false, true),
2680acac075bSDimitry Andric m_pc_option(LLDB_OPT_SET_1, false, "set-pc-to-entry", 'p',
2681f678e45dSDimitry Andric "Set PC to the entry point."
2682f678e45dSDimitry Andric " Only applicable with '--load' option.",
2683f678e45dSDimitry Andric false, true),
2684435933ddSDimitry Andric m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2685435933ddSDimitry Andric "Set the load address for all sections to be the "
2686435933ddSDimitry Andric "virtual address in the file plus the offset.",
2687435933ddSDimitry Andric 0) {
2688435933ddSDimitry Andric m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2689435933ddSDimitry Andric LLDB_OPT_SET_1);
2690ac7ddfbfSEd Maste m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2691f678e45dSDimitry Andric m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2692f678e45dSDimitry Andric m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2693ac7ddfbfSEd Maste m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2694ac7ddfbfSEd Maste m_option_group.Finalize();
2695ac7ddfbfSEd Maste }
2696ac7ddfbfSEd Maste
26974bb0738eSEd Maste ~CommandObjectTargetModulesLoad() override = default;
2698ac7ddfbfSEd Maste
GetOptions()2699435933ddSDimitry Andric Options *GetOptions() override { return &m_option_group; }
2700ac7ddfbfSEd Maste
2701ac7ddfbfSEd Maste protected:
DoExecute(Args & args,CommandReturnObject & result)2702435933ddSDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
2703ac7ddfbfSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2704f678e45dSDimitry Andric const bool load = m_load_option.GetOptionValue().GetCurrentValue();
2705f678e45dSDimitry Andric const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
2706435933ddSDimitry Andric if (target == nullptr) {
2707435933ddSDimitry Andric result.AppendError("invalid target, create a debug target using the "
2708435933ddSDimitry Andric "'target create' command");
2709ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2710ac7ddfbfSEd Maste return false;
2711435933ddSDimitry Andric } else {
2712ac7ddfbfSEd Maste const size_t argc = args.GetArgumentCount();
2713ac7ddfbfSEd Maste ModuleSpec module_spec;
2714ac7ddfbfSEd Maste bool search_using_module_spec = false;
2715f678e45dSDimitry Andric
27164ba319b5SDimitry Andric // Allow "load" option to work without --file or --uuid option.
2717f678e45dSDimitry Andric if (load) {
2718f678e45dSDimitry Andric if (!m_file_option.GetOptionValue().OptionWasSet() &&
2719f678e45dSDimitry Andric !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2720f678e45dSDimitry Andric ModuleList &module_list = target->GetImages();
2721f678e45dSDimitry Andric if (module_list.GetSize() == 1) {
2722f678e45dSDimitry Andric search_using_module_spec = true;
2723f678e45dSDimitry Andric module_spec.GetFileSpec() =
2724f678e45dSDimitry Andric module_list.GetModuleAtIndex(0)->GetFileSpec();
2725f678e45dSDimitry Andric }
2726f678e45dSDimitry Andric }
2727f678e45dSDimitry Andric }
2728f678e45dSDimitry Andric
2729435933ddSDimitry Andric if (m_file_option.GetOptionValue().OptionWasSet()) {
2730ac7ddfbfSEd Maste search_using_module_spec = true;
27317aa51b79SEd Maste const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
27327aa51b79SEd Maste const bool use_global_module_list = true;
27337aa51b79SEd Maste ModuleList module_list;
2734435933ddSDimitry Andric const size_t num_matches = FindModulesByName(
2735435933ddSDimitry Andric target, arg_cstr, module_list, use_global_module_list);
2736435933ddSDimitry Andric if (num_matches == 1) {
2737435933ddSDimitry Andric module_spec.GetFileSpec() =
2738435933ddSDimitry Andric module_list.GetModuleAtIndex(0)->GetFileSpec();
2739435933ddSDimitry Andric } else if (num_matches > 1) {
27407aa51b79SEd Maste search_using_module_spec = false;
2741435933ddSDimitry Andric result.AppendErrorWithFormat(
2742435933ddSDimitry Andric "more than 1 module matched by name '%s'\n", arg_cstr);
27437aa51b79SEd Maste result.SetStatus(eReturnStatusFailed);
2744435933ddSDimitry Andric } else {
27457aa51b79SEd Maste search_using_module_spec = false;
2746435933ddSDimitry Andric result.AppendErrorWithFormat("no object file for module '%s'\n",
2747435933ddSDimitry Andric arg_cstr);
27487aa51b79SEd Maste result.SetStatus(eReturnStatusFailed);
27497aa51b79SEd Maste }
2750ac7ddfbfSEd Maste }
2751ac7ddfbfSEd Maste
2752435933ddSDimitry Andric if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2753ac7ddfbfSEd Maste search_using_module_spec = true;
2754435933ddSDimitry Andric module_spec.GetUUID() =
2755435933ddSDimitry Andric m_uuid_option_group.GetOptionValue().GetCurrentValue();
2756ac7ddfbfSEd Maste }
2757ac7ddfbfSEd Maste
2758435933ddSDimitry Andric if (search_using_module_spec) {
2759ac7ddfbfSEd Maste ModuleList matching_modules;
2760435933ddSDimitry Andric const size_t num_matches =
2761435933ddSDimitry Andric target->GetImages().FindModules(module_spec, matching_modules);
2762ac7ddfbfSEd Maste
2763ac7ddfbfSEd Maste char path[PATH_MAX];
2764435933ddSDimitry Andric if (num_matches == 1) {
2765ac7ddfbfSEd Maste Module *module = matching_modules.GetModulePointerAtIndex(0);
2766435933ddSDimitry Andric if (module) {
2767ac7ddfbfSEd Maste ObjectFile *objfile = module->GetObjectFile();
2768435933ddSDimitry Andric if (objfile) {
2769ac7ddfbfSEd Maste SectionList *section_list = module->GetSectionList();
2770435933ddSDimitry Andric if (section_list) {
2771ac7ddfbfSEd Maste bool changed = false;
2772435933ddSDimitry Andric if (argc == 0) {
2773435933ddSDimitry Andric if (m_slide_option.GetOptionValue().OptionWasSet()) {
2774435933ddSDimitry Andric const addr_t slide =
2775435933ddSDimitry Andric m_slide_option.GetOptionValue().GetCurrentValue();
277612b93ac6SEd Maste const bool slide_is_offset = true;
2777435933ddSDimitry Andric module->SetLoadAddress(*target, slide, slide_is_offset,
2778435933ddSDimitry Andric changed);
2779435933ddSDimitry Andric } else {
2780435933ddSDimitry Andric result.AppendError("one or more section name + load "
2781435933ddSDimitry Andric "address pair must be specified");
2782ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2783ac7ddfbfSEd Maste return false;
2784ac7ddfbfSEd Maste }
2785435933ddSDimitry Andric } else {
2786435933ddSDimitry Andric if (m_slide_option.GetOptionValue().OptionWasSet()) {
2787435933ddSDimitry Andric result.AppendError("The \"--slide <offset>\" option can't "
2788435933ddSDimitry Andric "be used in conjunction with setting "
2789435933ddSDimitry Andric "section load addresses.\n");
2790ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2791ac7ddfbfSEd Maste return false;
2792ac7ddfbfSEd Maste }
2793ac7ddfbfSEd Maste
2794435933ddSDimitry Andric for (size_t i = 0; i < argc; i += 2) {
2795ac7ddfbfSEd Maste const char *sect_name = args.GetArgumentAtIndex(i);
2796ac7ddfbfSEd Maste const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2797435933ddSDimitry Andric if (sect_name && load_addr_cstr) {
2798ac7ddfbfSEd Maste ConstString const_sect_name(sect_name);
2799ac7ddfbfSEd Maste bool success = false;
2800435933ddSDimitry Andric addr_t load_addr = StringConvert::ToUInt64(
2801435933ddSDimitry Andric load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2802435933ddSDimitry Andric if (success) {
2803435933ddSDimitry Andric SectionSP section_sp(
2804435933ddSDimitry Andric section_list->FindSectionByName(const_sect_name));
2805435933ddSDimitry Andric if (section_sp) {
2806435933ddSDimitry Andric if (section_sp->IsThreadSpecific()) {
2807435933ddSDimitry Andric result.AppendErrorWithFormat(
2808435933ddSDimitry Andric "thread specific sections are not yet "
2809435933ddSDimitry Andric "supported (section '%s')\n",
2810435933ddSDimitry Andric sect_name);
2811ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2812ac7ddfbfSEd Maste break;
2813435933ddSDimitry Andric } else {
2814435933ddSDimitry Andric if (target->GetSectionLoadList()
2815435933ddSDimitry Andric .SetSectionLoadAddress(section_sp,
2816435933ddSDimitry Andric load_addr))
2817ac7ddfbfSEd Maste changed = true;
2818435933ddSDimitry Andric result.AppendMessageWithFormat(
2819435933ddSDimitry Andric "section '%s' loaded at 0x%" PRIx64 "\n",
2820435933ddSDimitry Andric sect_name, load_addr);
2821ac7ddfbfSEd Maste }
2822435933ddSDimitry Andric } else {
2823435933ddSDimitry Andric result.AppendErrorWithFormat("no section found that "
2824435933ddSDimitry Andric "matches the section "
2825435933ddSDimitry Andric "name '%s'\n",
2826435933ddSDimitry Andric sect_name);
2827ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2828ac7ddfbfSEd Maste break;
2829ac7ddfbfSEd Maste }
2830435933ddSDimitry Andric } else {
2831435933ddSDimitry Andric result.AppendErrorWithFormat(
2832435933ddSDimitry Andric "invalid load address string '%s'\n",
2833435933ddSDimitry Andric load_addr_cstr);
2834ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2835ac7ddfbfSEd Maste break;
2836ac7ddfbfSEd Maste }
2837435933ddSDimitry Andric } else {
2838ac7ddfbfSEd Maste if (sect_name)
2839435933ddSDimitry Andric result.AppendError("section names must be followed by "
2840435933ddSDimitry Andric "a load address.\n");
2841ac7ddfbfSEd Maste else
2842435933ddSDimitry Andric result.AppendError("one or more section name + load "
2843435933ddSDimitry Andric "address pair must be specified.\n");
2844ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2845ac7ddfbfSEd Maste break;
2846ac7ddfbfSEd Maste }
2847ac7ddfbfSEd Maste }
2848ac7ddfbfSEd Maste }
2849ac7ddfbfSEd Maste
2850435933ddSDimitry Andric if (changed) {
2851ac7ddfbfSEd Maste target->ModulesDidLoad(matching_modules);
2852ac7ddfbfSEd Maste Process *process = m_exe_ctx.GetProcessPtr();
2853ac7ddfbfSEd Maste if (process)
2854ac7ddfbfSEd Maste process->Flush();
2855ac7ddfbfSEd Maste }
2856f678e45dSDimitry Andric if (load) {
28574ba319b5SDimitry Andric ProcessSP process = target->CalculateProcess();
28584ba319b5SDimitry Andric Address file_entry = objfile->GetEntryPointAddress();
28594ba319b5SDimitry Andric if (!process) {
28604ba319b5SDimitry Andric result.AppendError("No process");
28614ba319b5SDimitry Andric return false;
28624ba319b5SDimitry Andric }
28634ba319b5SDimitry Andric if (set_pc && !file_entry.IsValid()) {
28644ba319b5SDimitry Andric result.AppendError("No entry address in object file");
28654ba319b5SDimitry Andric return false;
28664ba319b5SDimitry Andric }
28674ba319b5SDimitry Andric std::vector<ObjectFile::LoadableData> loadables(
28684ba319b5SDimitry Andric objfile->GetLoadableData(*target));
28694ba319b5SDimitry Andric if (loadables.size() == 0) {
28704ba319b5SDimitry Andric result.AppendError("No loadable sections");
28714ba319b5SDimitry Andric return false;
28724ba319b5SDimitry Andric }
28734ba319b5SDimitry Andric Status error = process->WriteObjectFile(std::move(loadables));
2874f678e45dSDimitry Andric if (error.Fail()) {
2875f678e45dSDimitry Andric result.AppendError(error.AsCString());
2876f678e45dSDimitry Andric return false;
2877f678e45dSDimitry Andric }
28784ba319b5SDimitry Andric if (set_pc) {
28794ba319b5SDimitry Andric ThreadList &thread_list = process->GetThreadList();
28804ba319b5SDimitry Andric RegisterContextSP reg_context(
2881*b5893f02SDimitry Andric thread_list.GetSelectedThread()->GetRegisterContext());
2882*b5893f02SDimitry Andric addr_t file_entry_addr = file_entry.GetLoadAddress(target);
2883*b5893f02SDimitry Andric if (!reg_context->SetPC(file_entry_addr)) {
2884*b5893f02SDimitry Andric result.AppendErrorWithFormat("failed to set PC value to "
2885*b5893f02SDimitry Andric "0x%" PRIx64 "\n",
2886*b5893f02SDimitry Andric file_entry_addr);
2887*b5893f02SDimitry Andric result.SetStatus(eReturnStatusFailed);
2888*b5893f02SDimitry Andric }
28894ba319b5SDimitry Andric }
2890f678e45dSDimitry Andric }
2891435933ddSDimitry Andric } else {
2892ac7ddfbfSEd Maste module->GetFileSpec().GetPath(path, sizeof(path));
2893435933ddSDimitry Andric result.AppendErrorWithFormat(
2894435933ddSDimitry Andric "no sections in object file '%s'\n", path);
2895ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2896ac7ddfbfSEd Maste }
2897435933ddSDimitry Andric } else {
2898ac7ddfbfSEd Maste module->GetFileSpec().GetPath(path, sizeof(path));
2899435933ddSDimitry Andric result.AppendErrorWithFormat("no object file for module '%s'\n",
2900435933ddSDimitry Andric path);
2901ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2902ac7ddfbfSEd Maste }
2903435933ddSDimitry Andric } else {
2904ac7ddfbfSEd Maste FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2905435933ddSDimitry Andric if (module_spec_file) {
2906ac7ddfbfSEd Maste module_spec_file->GetPath(path, sizeof(path));
2907ac7ddfbfSEd Maste result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2908435933ddSDimitry Andric } else
2909ac7ddfbfSEd Maste result.AppendError("no module spec");
2910ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2911ac7ddfbfSEd Maste }
2912435933ddSDimitry Andric } else {
2913ac7ddfbfSEd Maste std::string uuid_str;
2914ac7ddfbfSEd Maste
2915ac7ddfbfSEd Maste if (module_spec.GetFileSpec())
2916ac7ddfbfSEd Maste module_spec.GetFileSpec().GetPath(path, sizeof(path));
2917ac7ddfbfSEd Maste else
2918ac7ddfbfSEd Maste path[0] = '\0';
2919ac7ddfbfSEd Maste
2920ac7ddfbfSEd Maste if (module_spec.GetUUIDPtr())
2921ac7ddfbfSEd Maste uuid_str = module_spec.GetUUID().GetAsString();
2922435933ddSDimitry Andric if (num_matches > 1) {
2923435933ddSDimitry Andric result.AppendErrorWithFormat(
2924435933ddSDimitry Andric "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2925435933ddSDimitry Andric path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2926435933ddSDimitry Andric for (size_t i = 0; i < num_matches; ++i) {
2927435933ddSDimitry Andric if (matching_modules.GetModulePointerAtIndex(i)
2928435933ddSDimitry Andric ->GetFileSpec()
2929435933ddSDimitry Andric .GetPath(path, sizeof(path)))
2930ac7ddfbfSEd Maste result.AppendMessageWithFormat("%s\n", path);
2931ac7ddfbfSEd Maste }
2932435933ddSDimitry Andric } else {
2933435933ddSDimitry Andric result.AppendErrorWithFormat(
2934435933ddSDimitry Andric "no modules were found that match%s%s%s%s.\n",
2935435933ddSDimitry Andric path[0] ? " file=" : "", path,
2936435933ddSDimitry Andric !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2937ac7ddfbfSEd Maste }
2938ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2939ac7ddfbfSEd Maste }
2940435933ddSDimitry Andric } else {
2941435933ddSDimitry Andric result.AppendError("either the \"--file <module>\" or the \"--uuid "
2942435933ddSDimitry Andric "<uuid>\" option must be specified.\n");
2943ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
2944ac7ddfbfSEd Maste return false;
2945ac7ddfbfSEd Maste }
2946ac7ddfbfSEd Maste }
2947ac7ddfbfSEd Maste return result.Succeeded();
2948ac7ddfbfSEd Maste }
2949ac7ddfbfSEd Maste
2950ac7ddfbfSEd Maste OptionGroupOptions m_option_group;
2951ac7ddfbfSEd Maste OptionGroupUUID m_uuid_option_group;
29527aa51b79SEd Maste OptionGroupString m_file_option;
2953f678e45dSDimitry Andric OptionGroupBoolean m_load_option;
2954f678e45dSDimitry Andric OptionGroupBoolean m_pc_option;
2955ac7ddfbfSEd Maste OptionGroupUInt64 m_slide_option;
2956ac7ddfbfSEd Maste };
2957ac7ddfbfSEd Maste
2958ac7ddfbfSEd Maste //----------------------------------------------------------------------
2959ac7ddfbfSEd Maste // List images with associated information
2960ac7ddfbfSEd Maste //----------------------------------------------------------------------
2961435933ddSDimitry Andric
2962*b5893f02SDimitry Andric static constexpr OptionDefinition g_target_modules_list_options[] = {
2963435933ddSDimitry Andric // clang-format off
2964*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Display the image at this address." },
2965*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the architecture when listing images." },
2966*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the triple when listing images." },
2967*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "header", 'h', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the image base address as a load address if debugging, a file address otherwise." },
2968*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the image load address offset from the base file address (the slide amount)." },
2969*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the UUID when listing images." },
2970*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the fullpath to the image object file." },
2971*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the directory with optional width for the image object file." },
2972*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the basename with optional width for the image object file." },
2973*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width." },
2974*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file." },
2975*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the modification time with optional width of the module." },
2976*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "ref-count", 'r', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache." },
2977*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, {}, 0, eArgTypeNone, "Display the module pointer." },
2978*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "global", 'g', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target." }
2979435933ddSDimitry Andric // clang-format on
2980435933ddSDimitry Andric };
2981435933ddSDimitry Andric
2982435933ddSDimitry Andric class CommandObjectTargetModulesList : public CommandObjectParsed {
2983ac7ddfbfSEd Maste public:
2984435933ddSDimitry Andric class CommandOptions : public Options {
2985ac7ddfbfSEd Maste public:
CommandOptions()2986435933ddSDimitry Andric CommandOptions()
2987435933ddSDimitry Andric : Options(), m_format_array(), m_use_global_module_list(false),
2988435933ddSDimitry Andric m_module_addr(LLDB_INVALID_ADDRESS) {}
2989ac7ddfbfSEd Maste
29904bb0738eSEd Maste ~CommandOptions() override = default;
2991ac7ddfbfSEd Maste
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)29925517e702SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
2993435933ddSDimitry Andric ExecutionContext *execution_context) override {
29945517e702SDimitry Andric Status error;
2995ac7ddfbfSEd Maste
2996ac7ddfbfSEd Maste const int short_option = m_getopt_table[option_idx].val;
2997435933ddSDimitry Andric if (short_option == 'g') {
2998ac7ddfbfSEd Maste m_use_global_module_list = true;
2999435933ddSDimitry Andric } else if (short_option == 'a') {
30004ba319b5SDimitry Andric m_module_addr = OptionArgParser::ToAddress(
30014ba319b5SDimitry Andric execution_context, option_arg, LLDB_INVALID_ADDRESS, &error);
3002435933ddSDimitry Andric } else {
3003ac7ddfbfSEd Maste unsigned long width = 0;
3004435933ddSDimitry Andric option_arg.getAsInteger(0, width);
3005ac7ddfbfSEd Maste m_format_array.push_back(std::make_pair(short_option, width));
3006ac7ddfbfSEd Maste }
3007ac7ddfbfSEd Maste return error;
3008ac7ddfbfSEd Maste }
3009ac7ddfbfSEd Maste
OptionParsingStarting(ExecutionContext * execution_context)3010435933ddSDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
3011ac7ddfbfSEd Maste m_format_array.clear();
3012ac7ddfbfSEd Maste m_use_global_module_list = false;
3013ac7ddfbfSEd Maste m_module_addr = LLDB_INVALID_ADDRESS;
3014ac7ddfbfSEd Maste }
3015ac7ddfbfSEd Maste
GetDefinitions()3016435933ddSDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3017435933ddSDimitry Andric return llvm::makeArrayRef(g_target_modules_list_options);
3018ac7ddfbfSEd Maste }
3019ac7ddfbfSEd Maste
3020ac7ddfbfSEd Maste // Instance variables to hold the values for command options.
3021ac7ddfbfSEd Maste typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
3022ac7ddfbfSEd Maste FormatWidthCollection m_format_array;
3023ac7ddfbfSEd Maste bool m_use_global_module_list;
3024ac7ddfbfSEd Maste lldb::addr_t m_module_addr;
3025ac7ddfbfSEd Maste };
3026ac7ddfbfSEd Maste
CommandObjectTargetModulesList(CommandInterpreter & interpreter)3027435933ddSDimitry Andric CommandObjectTargetModulesList(CommandInterpreter &interpreter)
3028435933ddSDimitry Andric : CommandObjectParsed(
3029435933ddSDimitry Andric interpreter, "target modules list",
3030ac7ddfbfSEd Maste "List current executable and dependent shared library images.",
3031ac7ddfbfSEd Maste "target modules list [<cmd-options>]"),
3032435933ddSDimitry Andric m_options() {}
3033ac7ddfbfSEd Maste
30344bb0738eSEd Maste ~CommandObjectTargetModulesList() override = default;
3035ac7ddfbfSEd Maste
GetOptions()3036435933ddSDimitry Andric Options *GetOptions() override { return &m_options; }
3037ac7ddfbfSEd Maste
3038ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)3039435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
3040ac7ddfbfSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3041ac7ddfbfSEd Maste const bool use_global_module_list = m_options.m_use_global_module_list;
3042435933ddSDimitry Andric // Define a local module list here to ensure it lives longer than any
30434ba319b5SDimitry Andric // "locker" object which might lock its contents below (through the
30444ba319b5SDimitry Andric // "module_list_ptr" variable).
3045ac7ddfbfSEd Maste ModuleList module_list;
3046435933ddSDimitry Andric if (target == nullptr && !use_global_module_list) {
3047435933ddSDimitry Andric result.AppendError("invalid target, create a debug target using the "
3048435933ddSDimitry Andric "'target create' command");
3049ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
3050ac7ddfbfSEd Maste return false;
3051435933ddSDimitry Andric } else {
3052435933ddSDimitry Andric if (target) {
3053435933ddSDimitry Andric uint32_t addr_byte_size =
3054435933ddSDimitry Andric target->GetArchitecture().GetAddressByteSize();
3055ac7ddfbfSEd Maste result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3056ac7ddfbfSEd Maste result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3057ac7ddfbfSEd Maste }
3058ac7ddfbfSEd Maste // Dump all sections for all modules images
3059ac7ddfbfSEd Maste Stream &strm = result.GetOutputStream();
3060ac7ddfbfSEd Maste
3061435933ddSDimitry Andric if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
3062435933ddSDimitry Andric if (target) {
3063ac7ddfbfSEd Maste Address module_address;
3064435933ddSDimitry Andric if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
3065ac7ddfbfSEd Maste ModuleSP module_sp(module_address.GetModule());
3066435933ddSDimitry Andric if (module_sp) {
3067ac7ddfbfSEd Maste PrintModule(target, module_sp.get(), 0, strm);
3068ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
3069435933ddSDimitry Andric } else {
3070435933ddSDimitry Andric result.AppendErrorWithFormat(
3071435933ddSDimitry Andric "Couldn't find module matching address: 0x%" PRIx64 ".",
3072435933ddSDimitry Andric m_options.m_module_addr);
3073ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
3074ac7ddfbfSEd Maste }
3075435933ddSDimitry Andric } else {
3076435933ddSDimitry Andric result.AppendErrorWithFormat(
3077435933ddSDimitry Andric "Couldn't find module containing address: 0x%" PRIx64 ".",
3078435933ddSDimitry Andric m_options.m_module_addr);
3079ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
3080ac7ddfbfSEd Maste }
3081435933ddSDimitry Andric } else {
3082435933ddSDimitry Andric result.AppendError(
3083435933ddSDimitry Andric "Can only look up modules by address with a valid target.");
3084ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
3085ac7ddfbfSEd Maste }
3086ac7ddfbfSEd Maste return result.Succeeded();
3087ac7ddfbfSEd Maste }
3088ac7ddfbfSEd Maste
3089ac7ddfbfSEd Maste size_t num_modules = 0;
30904bb0738eSEd Maste
3091435933ddSDimitry Andric // This locker will be locked on the mutex in module_list_ptr if it is
30924ba319b5SDimitry Andric // non-nullptr. Otherwise it will lock the
30934ba319b5SDimitry Andric // AllocationModuleCollectionMutex when accessing the global module list
30944ba319b5SDimitry Andric // directly.
3095435933ddSDimitry Andric std::unique_lock<std::recursive_mutex> guard(
3096435933ddSDimitry Andric Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
30974bb0738eSEd Maste
30984bb0738eSEd Maste const ModuleList *module_list_ptr = nullptr;
3099ac7ddfbfSEd Maste const size_t argc = command.GetArgumentCount();
3100435933ddSDimitry Andric if (argc == 0) {
3101435933ddSDimitry Andric if (use_global_module_list) {
31024bb0738eSEd Maste guard.lock();
3103ac7ddfbfSEd Maste num_modules = Module::GetNumberAllocatedModules();
3104435933ddSDimitry Andric } else {
3105ac7ddfbfSEd Maste module_list_ptr = &target->GetImages();
3106ac7ddfbfSEd Maste }
3107435933ddSDimitry Andric } else {
3108435933ddSDimitry Andric // TODO: Convert to entry based iteration. Requires converting
3109435933ddSDimitry Andric // FindModulesByName.
3110435933ddSDimitry Andric for (size_t i = 0; i < argc; ++i) {
3111ac7ddfbfSEd Maste // Dump specified images (by basename or fullpath)
3112ac7ddfbfSEd Maste const char *arg_cstr = command.GetArgumentAtIndex(i);
3113435933ddSDimitry Andric const size_t num_matches = FindModulesByName(
3114435933ddSDimitry Andric target, arg_cstr, module_list, use_global_module_list);
3115435933ddSDimitry Andric if (num_matches == 0) {
3116435933ddSDimitry Andric if (argc == 1) {
3117435933ddSDimitry Andric result.AppendErrorWithFormat("no modules found that match '%s'",
3118435933ddSDimitry Andric arg_cstr);
3119ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
3120ac7ddfbfSEd Maste return false;
3121ac7ddfbfSEd Maste }
3122ac7ddfbfSEd Maste }
3123ac7ddfbfSEd Maste }
3124ac7ddfbfSEd Maste
3125ac7ddfbfSEd Maste module_list_ptr = &module_list;
3126ac7ddfbfSEd Maste }
3127ac7ddfbfSEd Maste
31284bb0738eSEd Maste std::unique_lock<std::recursive_mutex> lock;
3129435933ddSDimitry Andric if (module_list_ptr != nullptr) {
3130435933ddSDimitry Andric lock =
3131435933ddSDimitry Andric std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
31324bb0738eSEd Maste
3133ac7ddfbfSEd Maste num_modules = module_list_ptr->GetSize();
3134ac7ddfbfSEd Maste }
3135ac7ddfbfSEd Maste
3136435933ddSDimitry Andric if (num_modules > 0) {
3137435933ddSDimitry Andric for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3138ac7ddfbfSEd Maste ModuleSP module_sp;
3139ac7ddfbfSEd Maste Module *module;
3140435933ddSDimitry Andric if (module_list_ptr) {
3141ac7ddfbfSEd Maste module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3142ac7ddfbfSEd Maste module = module_sp.get();
3143435933ddSDimitry Andric } else {
3144ac7ddfbfSEd Maste module = Module::GetAllocatedModuleAtIndex(image_idx);
3145ac7ddfbfSEd Maste module_sp = module->shared_from_this();
3146ac7ddfbfSEd Maste }
3147ac7ddfbfSEd Maste
3148ac7ddfbfSEd Maste const size_t indent = strm.Printf("[%3u] ", image_idx);
3149ac7ddfbfSEd Maste PrintModule(target, module, indent, strm);
3150ac7ddfbfSEd Maste }
3151ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
3152435933ddSDimitry Andric } else {
3153435933ddSDimitry Andric if (argc) {
3154ac7ddfbfSEd Maste if (use_global_module_list)
3155435933ddSDimitry Andric result.AppendError(
3156435933ddSDimitry Andric "the global module list has no matching modules");
3157ac7ddfbfSEd Maste else
3158ac7ddfbfSEd Maste result.AppendError("the target has no matching modules");
3159435933ddSDimitry Andric } else {
3160ac7ddfbfSEd Maste if (use_global_module_list)
3161ac7ddfbfSEd Maste result.AppendError("the global module list is empty");
3162ac7ddfbfSEd Maste else
3163435933ddSDimitry Andric result.AppendError(
3164435933ddSDimitry Andric "the target has no associated executable images");
3165ac7ddfbfSEd Maste }
3166ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
3167ac7ddfbfSEd Maste return false;
3168ac7ddfbfSEd Maste }
3169ac7ddfbfSEd Maste }
3170ac7ddfbfSEd Maste return result.Succeeded();
3171ac7ddfbfSEd Maste }
3172ac7ddfbfSEd Maste
PrintModule(Target * target,Module * module,int indent,Stream & strm)3173435933ddSDimitry Andric void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
3174435933ddSDimitry Andric if (module == nullptr) {
3175ac7ddfbfSEd Maste strm.PutCString("Null module");
3176ac7ddfbfSEd Maste return;
3177ac7ddfbfSEd Maste }
3178ac7ddfbfSEd Maste
3179ac7ddfbfSEd Maste bool dump_object_name = false;
3180435933ddSDimitry Andric if (m_options.m_format_array.empty()) {
3181ac7ddfbfSEd Maste m_options.m_format_array.push_back(std::make_pair('u', 0));
3182ac7ddfbfSEd Maste m_options.m_format_array.push_back(std::make_pair('h', 0));
3183ac7ddfbfSEd Maste m_options.m_format_array.push_back(std::make_pair('f', 0));
3184ac7ddfbfSEd Maste m_options.m_format_array.push_back(std::make_pair('S', 0));
3185ac7ddfbfSEd Maste }
3186ac7ddfbfSEd Maste const size_t num_entries = m_options.m_format_array.size();
3187ac7ddfbfSEd Maste bool print_space = false;
3188435933ddSDimitry Andric for (size_t i = 0; i < num_entries; ++i) {
3189ac7ddfbfSEd Maste if (print_space)
3190ac7ddfbfSEd Maste strm.PutChar(' ');
3191ac7ddfbfSEd Maste print_space = true;
3192ac7ddfbfSEd Maste const char format_char = m_options.m_format_array[i].first;
3193ac7ddfbfSEd Maste uint32_t width = m_options.m_format_array[i].second;
3194435933ddSDimitry Andric switch (format_char) {
3195ac7ddfbfSEd Maste case 'A':
3196ac7ddfbfSEd Maste DumpModuleArchitecture(strm, module, false, width);
3197ac7ddfbfSEd Maste break;
3198ac7ddfbfSEd Maste
3199ac7ddfbfSEd Maste case 't':
3200ac7ddfbfSEd Maste DumpModuleArchitecture(strm, module, true, width);
3201ac7ddfbfSEd Maste break;
3202ac7ddfbfSEd Maste
3203ac7ddfbfSEd Maste case 'f':
3204ac7ddfbfSEd Maste DumpFullpath(strm, &module->GetFileSpec(), width);
3205ac7ddfbfSEd Maste dump_object_name = true;
3206ac7ddfbfSEd Maste break;
3207ac7ddfbfSEd Maste
3208ac7ddfbfSEd Maste case 'd':
3209ac7ddfbfSEd Maste DumpDirectory(strm, &module->GetFileSpec(), width);
3210ac7ddfbfSEd Maste break;
3211ac7ddfbfSEd Maste
3212ac7ddfbfSEd Maste case 'b':
3213ac7ddfbfSEd Maste DumpBasename(strm, &module->GetFileSpec(), width);
3214ac7ddfbfSEd Maste dump_object_name = true;
3215ac7ddfbfSEd Maste break;
3216ac7ddfbfSEd Maste
3217ac7ddfbfSEd Maste case 'h':
3218ac7ddfbfSEd Maste case 'o':
3219ac7ddfbfSEd Maste // Image header address
3220ac7ddfbfSEd Maste {
3221435933ddSDimitry Andric uint32_t addr_nibble_width =
3222435933ddSDimitry Andric target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3223435933ddSDimitry Andric : 16;
3224ac7ddfbfSEd Maste
3225ac7ddfbfSEd Maste ObjectFile *objfile = module->GetObjectFile();
3226435933ddSDimitry Andric if (objfile) {
3227*b5893f02SDimitry Andric Address base_addr(objfile->GetBaseAddress());
3228*b5893f02SDimitry Andric if (base_addr.IsValid()) {
3229435933ddSDimitry Andric if (target && !target->GetSectionLoadList().IsEmpty()) {
3230*b5893f02SDimitry Andric lldb::addr_t load_addr =
3231*b5893f02SDimitry Andric base_addr.GetLoadAddress(target);
3232*b5893f02SDimitry Andric if (load_addr == LLDB_INVALID_ADDRESS) {
3233*b5893f02SDimitry Andric base_addr.Dump(&strm, target,
3234435933ddSDimitry Andric Address::DumpStyleModuleWithFileAddress,
3235435933ddSDimitry Andric Address::DumpStyleFileAddress);
3236435933ddSDimitry Andric } else {
3237435933ddSDimitry Andric if (format_char == 'o') {
3238ac7ddfbfSEd Maste // Show the offset of slide for the image
3239435933ddSDimitry Andric strm.Printf(
3240435933ddSDimitry Andric "0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width,
3241*b5893f02SDimitry Andric load_addr - base_addr.GetFileAddress());
3242435933ddSDimitry Andric } else {
3243ac7ddfbfSEd Maste // Show the load address of the image
3244435933ddSDimitry Andric strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3245*b5893f02SDimitry Andric addr_nibble_width, load_addr);
3246ac7ddfbfSEd Maste }
3247ac7ddfbfSEd Maste }
3248ac7ddfbfSEd Maste break;
3249ac7ddfbfSEd Maste }
3250435933ddSDimitry Andric // The address was valid, but the image isn't loaded, output the
3251435933ddSDimitry Andric // address in an appropriate format
3252*b5893f02SDimitry Andric base_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3253ac7ddfbfSEd Maste break;
3254ac7ddfbfSEd Maste }
3255ac7ddfbfSEd Maste }
3256ac7ddfbfSEd Maste strm.Printf("%*s", addr_nibble_width + 2, "");
3257ac7ddfbfSEd Maste }
3258ac7ddfbfSEd Maste break;
32594bb0738eSEd Maste
3260435933ddSDimitry Andric case 'r': {
3261ac7ddfbfSEd Maste size_t ref_count = 0;
3262ac7ddfbfSEd Maste ModuleSP module_sp(module->shared_from_this());
3263435933ddSDimitry Andric if (module_sp) {
3264ac7ddfbfSEd Maste // Take one away to make sure we don't count our local "module_sp"
3265ac7ddfbfSEd Maste ref_count = module_sp.use_count() - 1;
3266ac7ddfbfSEd Maste }
3267ac7ddfbfSEd Maste if (width)
32680127ef0fSEd Maste strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3269ac7ddfbfSEd Maste else
32700127ef0fSEd Maste strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3271435933ddSDimitry Andric } break;
3272ac7ddfbfSEd Maste
3273ac7ddfbfSEd Maste case 's':
3274435933ddSDimitry Andric case 'S': {
32751c3bbb01SEd Maste const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3276435933ddSDimitry Andric if (symbol_vendor) {
32771c3bbb01SEd Maste const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3278435933ddSDimitry Andric if (format_char == 'S') {
3279ac7ddfbfSEd Maste // Dump symbol file only if different from module file
3280435933ddSDimitry Andric if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3281ac7ddfbfSEd Maste print_space = false;
3282ac7ddfbfSEd Maste break;
3283ac7ddfbfSEd Maste }
3284ac7ddfbfSEd Maste // Add a newline and indent past the index
3285ac7ddfbfSEd Maste strm.Printf("\n%*s", indent, "");
3286ac7ddfbfSEd Maste }
32871c3bbb01SEd Maste DumpFullpath(strm, &symfile_spec, width);
3288ac7ddfbfSEd Maste dump_object_name = true;
3289ac7ddfbfSEd Maste break;
3290ac7ddfbfSEd Maste }
3291ac7ddfbfSEd Maste strm.Printf("%.*s", width, "<NONE>");
3292435933ddSDimitry Andric } break;
3293ac7ddfbfSEd Maste
3294ac7ddfbfSEd Maste case 'm':
3295acac075bSDimitry Andric strm.Format("{0:%c}", llvm::fmt_align(module->GetModificationTime(),
3296acac075bSDimitry Andric llvm::AlignStyle::Left, width));
3297ac7ddfbfSEd Maste break;
3298ac7ddfbfSEd Maste
3299ac7ddfbfSEd Maste case 'p':
33000127ef0fSEd Maste strm.Printf("%p", static_cast<void *>(module));
3301ac7ddfbfSEd Maste break;
3302ac7ddfbfSEd Maste
3303ac7ddfbfSEd Maste case 'u':
3304ac7ddfbfSEd Maste DumpModuleUUID(strm, module);
3305ac7ddfbfSEd Maste break;
3306ac7ddfbfSEd Maste
3307ac7ddfbfSEd Maste default:
3308ac7ddfbfSEd Maste break;
3309ac7ddfbfSEd Maste }
3310ac7ddfbfSEd Maste }
3311435933ddSDimitry Andric if (dump_object_name) {
3312ac7ddfbfSEd Maste const char *object_name = module->GetObjectName().GetCString();
3313ac7ddfbfSEd Maste if (object_name)
3314ac7ddfbfSEd Maste strm.Printf("(%s)", object_name);
3315ac7ddfbfSEd Maste }
3316ac7ddfbfSEd Maste strm.EOL();
3317ac7ddfbfSEd Maste }
3318ac7ddfbfSEd Maste
3319ac7ddfbfSEd Maste CommandOptions m_options;
3320ac7ddfbfSEd Maste };
3321ac7ddfbfSEd Maste
3322ac7ddfbfSEd Maste #pragma mark CommandObjectTargetModulesShowUnwind
3323ac7ddfbfSEd Maste
3324ac7ddfbfSEd Maste //----------------------------------------------------------------------
3325ac7ddfbfSEd Maste // Lookup unwind information in images
3326ac7ddfbfSEd Maste //----------------------------------------------------------------------
3327ac7ddfbfSEd Maste
3328*b5893f02SDimitry Andric static constexpr OptionDefinition g_target_modules_show_unwind_options[] = {
3329435933ddSDimitry Andric // clang-format off
3330*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name." },
3331*b5893f02SDimitry Andric { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" }
3332435933ddSDimitry Andric // clang-format on
3333435933ddSDimitry Andric };
3334435933ddSDimitry Andric
3335435933ddSDimitry Andric class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
3336ac7ddfbfSEd Maste public:
3337435933ddSDimitry Andric enum {
3338ac7ddfbfSEd Maste eLookupTypeInvalid = -1,
3339ac7ddfbfSEd Maste eLookupTypeAddress = 0,
3340ac7ddfbfSEd Maste eLookupTypeSymbol,
3341ac7ddfbfSEd Maste eLookupTypeFunction,
3342ac7ddfbfSEd Maste eLookupTypeFunctionOrSymbol,
3343ac7ddfbfSEd Maste kNumLookupTypes
3344ac7ddfbfSEd Maste };
3345ac7ddfbfSEd Maste
3346435933ddSDimitry Andric class CommandOptions : public Options {
3347ac7ddfbfSEd Maste public:
CommandOptions()3348435933ddSDimitry Andric CommandOptions()
3349435933ddSDimitry Andric : Options(), m_type(eLookupTypeInvalid), m_str(),
3350435933ddSDimitry Andric m_addr(LLDB_INVALID_ADDRESS) {}
3351ac7ddfbfSEd Maste
33524bb0738eSEd Maste ~CommandOptions() override = default;
3353ac7ddfbfSEd Maste
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)33545517e702SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3355435933ddSDimitry Andric ExecutionContext *execution_context) override {
33565517e702SDimitry Andric Status error;
3357ac7ddfbfSEd Maste
3358ac7ddfbfSEd Maste const int short_option = m_getopt_table[option_idx].val;
3359ac7ddfbfSEd Maste
3360435933ddSDimitry Andric switch (short_option) {
3361435933ddSDimitry Andric case 'a': {
336235617911SEd Maste m_str = option_arg;
3363ac7ddfbfSEd Maste m_type = eLookupTypeAddress;
33644ba319b5SDimitry Andric m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3365435933ddSDimitry Andric LLDB_INVALID_ADDRESS, &error);
3366ac7ddfbfSEd Maste if (m_addr == LLDB_INVALID_ADDRESS)
3367435933ddSDimitry Andric error.SetErrorStringWithFormat("invalid address string '%s'",
3368435933ddSDimitry Andric option_arg.str().c_str());
3369ac7ddfbfSEd Maste break;
3370ac7ddfbfSEd Maste }
3371ac7ddfbfSEd Maste
3372ac7ddfbfSEd Maste case 'n':
3373ac7ddfbfSEd Maste m_str = option_arg;
3374ac7ddfbfSEd Maste m_type = eLookupTypeFunctionOrSymbol;
3375ac7ddfbfSEd Maste break;
337635617911SEd Maste
337735617911SEd Maste default:
337835617911SEd Maste error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
337935617911SEd Maste break;
3380ac7ddfbfSEd Maste }
3381ac7ddfbfSEd Maste
3382ac7ddfbfSEd Maste return error;
3383ac7ddfbfSEd Maste }
3384ac7ddfbfSEd Maste
OptionParsingStarting(ExecutionContext * execution_context)3385435933ddSDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
3386ac7ddfbfSEd Maste m_type = eLookupTypeInvalid;
3387ac7ddfbfSEd Maste m_str.clear();
3388ac7ddfbfSEd Maste m_addr = LLDB_INVALID_ADDRESS;
3389ac7ddfbfSEd Maste }
3390ac7ddfbfSEd Maste
GetDefinitions()3391435933ddSDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3392435933ddSDimitry Andric return llvm::makeArrayRef(g_target_modules_show_unwind_options);
3393ac7ddfbfSEd Maste }
3394ac7ddfbfSEd Maste
3395ac7ddfbfSEd Maste // Instance variables to hold the values for command options.
3396ac7ddfbfSEd Maste
3397ac7ddfbfSEd Maste int m_type; // Should be a eLookupTypeXXX enum after parsing options
3398ac7ddfbfSEd Maste std::string m_str; // Holds name lookup
3399ac7ddfbfSEd Maste lldb::addr_t m_addr; // Holds the address to lookup
3400ac7ddfbfSEd Maste };
3401ac7ddfbfSEd Maste
CommandObjectTargetModulesShowUnwind(CommandInterpreter & interpreter)3402435933ddSDimitry Andric CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3403435933ddSDimitry Andric : CommandObjectParsed(
3404435933ddSDimitry Andric interpreter, "target modules show-unwind",
3405435933ddSDimitry Andric "Show synthesized unwind instructions for a function.", nullptr,
3406435933ddSDimitry Andric eCommandRequiresTarget | eCommandRequiresProcess |
3407435933ddSDimitry Andric eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
3408435933ddSDimitry Andric m_options() {}
3409ac7ddfbfSEd Maste
34104bb0738eSEd Maste ~CommandObjectTargetModulesShowUnwind() override = default;
3411ac7ddfbfSEd Maste
GetOptions()3412435933ddSDimitry Andric Options *GetOptions() override { return &m_options; }
3413ac7ddfbfSEd Maste
3414ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)3415435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
3416ac7ddfbfSEd Maste Target *target = m_exe_ctx.GetTargetPtr();
3417ac7ddfbfSEd Maste Process *process = m_exe_ctx.GetProcessPtr();
34184bb0738eSEd Maste ABI *abi = nullptr;
3419ac7ddfbfSEd Maste if (process)
3420ac7ddfbfSEd Maste abi = process->GetABI().get();
3421ac7ddfbfSEd Maste
3422435933ddSDimitry Andric if (process == nullptr) {
3423435933ddSDimitry Andric result.AppendError(
3424435933ddSDimitry Andric "You must have a process running to use this command.");
3425ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
3426ac7ddfbfSEd Maste return false;
3427ac7ddfbfSEd Maste }
3428ac7ddfbfSEd Maste
3429ac7ddfbfSEd Maste ThreadList threads(process->GetThreadList());
3430435933ddSDimitry Andric if (threads.GetSize() == 0) {
3431ac7ddfbfSEd Maste result.AppendError("The process must be paused to use this command.");
3432ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
3433ac7ddfbfSEd Maste return false;
3434ac7ddfbfSEd Maste }
3435ac7ddfbfSEd Maste
3436ac7ddfbfSEd Maste ThreadSP thread(threads.GetThreadAtIndex(0));
3437435933ddSDimitry Andric if (!thread) {
3438ac7ddfbfSEd Maste result.AppendError("The process must be paused to use this command.");
3439ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
3440ac7ddfbfSEd Maste return false;
3441ac7ddfbfSEd Maste }
3442ac7ddfbfSEd Maste
3443ac7ddfbfSEd Maste SymbolContextList sc_list;
3444ac7ddfbfSEd Maste
3445435933ddSDimitry Andric if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3446ac7ddfbfSEd Maste ConstString function_name(m_options.m_str.c_str());
3447435933ddSDimitry Andric target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3448435933ddSDimitry Andric true, false, true, sc_list);
3449435933ddSDimitry Andric } else if (m_options.m_type == eLookupTypeAddress && target) {
3450ac7ddfbfSEd Maste Address addr;
3451435933ddSDimitry Andric if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3452435933ddSDimitry Andric addr)) {
3453ac7ddfbfSEd Maste SymbolContext sc;
3454ac7ddfbfSEd Maste ModuleSP module_sp(addr.GetModule());
3455435933ddSDimitry Andric module_sp->ResolveSymbolContextForAddress(addr,
3456435933ddSDimitry Andric eSymbolContextEverything, sc);
3457435933ddSDimitry Andric if (sc.function || sc.symbol) {
3458ac7ddfbfSEd Maste sc_list.Append(sc);
3459ac7ddfbfSEd Maste }
3460ac7ddfbfSEd Maste }
3461435933ddSDimitry Andric } else {
3462435933ddSDimitry Andric result.AppendError(
3463435933ddSDimitry Andric "address-expression or function name option must be specified.");
346435617911SEd Maste result.SetStatus(eReturnStatusFailed);
346535617911SEd Maste return false;
346635617911SEd Maste }
3467ac7ddfbfSEd Maste
3468ac7ddfbfSEd Maste size_t num_matches = sc_list.GetSize();
3469435933ddSDimitry Andric if (num_matches == 0) {
3470435933ddSDimitry Andric result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3471435933ddSDimitry Andric m_options.m_str.c_str());
347235617911SEd Maste result.SetStatus(eReturnStatusFailed);
347335617911SEd Maste return false;
347435617911SEd Maste }
347535617911SEd Maste
3476435933ddSDimitry Andric for (uint32_t idx = 0; idx < num_matches; idx++) {
3477ac7ddfbfSEd Maste SymbolContext sc;
3478ac7ddfbfSEd Maste sc_list.GetContextAtIndex(idx, sc);
34794bb0738eSEd Maste if (sc.symbol == nullptr && sc.function == nullptr)
3480ac7ddfbfSEd Maste continue;
34814bb0738eSEd Maste if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3482ac7ddfbfSEd Maste continue;
3483ac7ddfbfSEd Maste AddressRange range;
3484435933ddSDimitry Andric if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3485435933ddSDimitry Andric false, range))
3486ac7ddfbfSEd Maste continue;
3487ac7ddfbfSEd Maste if (!range.GetBaseAddress().IsValid())
3488ac7ddfbfSEd Maste continue;
3489ac7ddfbfSEd Maste ConstString funcname(sc.GetFunctionName());
3490ac7ddfbfSEd Maste if (funcname.IsEmpty())
3491ac7ddfbfSEd Maste continue;
3492ac7ddfbfSEd Maste addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3493ac7ddfbfSEd Maste if (abi)
3494ac7ddfbfSEd Maste start_addr = abi->FixCodeAddress(start_addr);
3495ac7ddfbfSEd Maste
3496435933ddSDimitry Andric FuncUnwindersSP func_unwinders_sp(
3497435933ddSDimitry Andric sc.module_sp->GetObjectFile()
3498435933ddSDimitry Andric ->GetUnwindTable()
3499435933ddSDimitry Andric .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
35004bb0738eSEd Maste if (!func_unwinders_sp)
3501ac7ddfbfSEd Maste continue;
3502ac7ddfbfSEd Maste
3503435933ddSDimitry Andric result.GetOutputStream().Printf(
3504435933ddSDimitry Andric "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
3505435933ddSDimitry Andric sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3506435933ddSDimitry Andric funcname.AsCString(), start_addr);
3507ac7ddfbfSEd Maste
3508435933ddSDimitry Andric UnwindPlanSP non_callsite_unwind_plan =
3509435933ddSDimitry Andric func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
3510435933ddSDimitry Andric if (non_callsite_unwind_plan) {
3511435933ddSDimitry Andric result.GetOutputStream().Printf(
3512435933ddSDimitry Andric "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3513435933ddSDimitry Andric non_callsite_unwind_plan->GetSourceName().AsCString());
3514ac7ddfbfSEd Maste }
3515435933ddSDimitry Andric UnwindPlanSP callsite_unwind_plan =
3516435933ddSDimitry Andric func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3517435933ddSDimitry Andric if (callsite_unwind_plan) {
3518435933ddSDimitry Andric result.GetOutputStream().Printf(
3519435933ddSDimitry Andric "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3520435933ddSDimitry Andric callsite_unwind_plan->GetSourceName().AsCString());
3521ac7ddfbfSEd Maste }
3522435933ddSDimitry Andric UnwindPlanSP fast_unwind_plan =
3523435933ddSDimitry Andric func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3524435933ddSDimitry Andric if (fast_unwind_plan) {
3525435933ddSDimitry Andric result.GetOutputStream().Printf(
3526435933ddSDimitry Andric "Fast UnwindPlan is '%s'\n",
3527435933ddSDimitry Andric fast_unwind_plan->GetSourceName().AsCString());
35287aa51b79SEd Maste }
35297aa51b79SEd Maste
35307aa51b79SEd Maste result.GetOutputStream().Printf("\n");
35317aa51b79SEd Maste
3532435933ddSDimitry Andric UnwindPlanSP assembly_sp =
3533435933ddSDimitry Andric func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
3534435933ddSDimitry Andric if (assembly_sp) {
3535435933ddSDimitry Andric result.GetOutputStream().Printf(
3536435933ddSDimitry Andric "Assembly language inspection UnwindPlan:\n");
3537435933ddSDimitry Andric assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3538435933ddSDimitry Andric LLDB_INVALID_ADDRESS);
35397aa51b79SEd Maste result.GetOutputStream().Printf("\n");
35407aa51b79SEd Maste }
35417aa51b79SEd Maste
3542435933ddSDimitry Andric UnwindPlanSP ehframe_sp =
3543435933ddSDimitry Andric func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3544435933ddSDimitry Andric if (ehframe_sp) {
35457aa51b79SEd Maste result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3546435933ddSDimitry Andric ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3547435933ddSDimitry Andric LLDB_INVALID_ADDRESS);
35487aa51b79SEd Maste result.GetOutputStream().Printf("\n");
35497aa51b79SEd Maste }
35507aa51b79SEd Maste
3551435933ddSDimitry Andric UnwindPlanSP ehframe_augmented_sp =
3552435933ddSDimitry Andric func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
3553435933ddSDimitry Andric if (ehframe_augmented_sp) {
35547aa51b79SEd Maste result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3555435933ddSDimitry Andric ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3556435933ddSDimitry Andric LLDB_INVALID_ADDRESS);
35577aa51b79SEd Maste result.GetOutputStream().Printf("\n");
35587aa51b79SEd Maste }
35597aa51b79SEd Maste
3560a580b014SDimitry Andric if (UnwindPlanSP plan_sp =
3561a580b014SDimitry Andric func_unwinders_sp->GetDebugFrameUnwindPlan(*target, 0)) {
3562a580b014SDimitry Andric result.GetOutputStream().Printf("debug_frame UnwindPlan:\n");
3563a580b014SDimitry Andric plan_sp->Dump(result.GetOutputStream(), thread.get(),
3564a580b014SDimitry Andric LLDB_INVALID_ADDRESS);
3565a580b014SDimitry Andric result.GetOutputStream().Printf("\n");
3566a580b014SDimitry Andric }
3567a580b014SDimitry Andric
3568a580b014SDimitry Andric if (UnwindPlanSP plan_sp =
3569a580b014SDimitry Andric func_unwinders_sp->GetDebugFrameAugmentedUnwindPlan(*target,
3570a580b014SDimitry Andric *thread, 0)) {
3571a580b014SDimitry Andric result.GetOutputStream().Printf("debug_frame augmented UnwindPlan:\n");
3572a580b014SDimitry Andric plan_sp->Dump(result.GetOutputStream(), thread.get(),
3573a580b014SDimitry Andric LLDB_INVALID_ADDRESS);
3574a580b014SDimitry Andric result.GetOutputStream().Printf("\n");
3575a580b014SDimitry Andric }
3576a580b014SDimitry Andric
3577435933ddSDimitry Andric UnwindPlanSP arm_unwind_sp =
3578435933ddSDimitry Andric func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
3579435933ddSDimitry Andric if (arm_unwind_sp) {
35809f2f44ceSEd Maste result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3581435933ddSDimitry Andric arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3582435933ddSDimitry Andric LLDB_INVALID_ADDRESS);
35839f2f44ceSEd Maste result.GetOutputStream().Printf("\n");
35849f2f44ceSEd Maste }
35859f2f44ceSEd Maste
3586435933ddSDimitry Andric UnwindPlanSP compact_unwind_sp =
3587435933ddSDimitry Andric func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3588435933ddSDimitry Andric if (compact_unwind_sp) {
35897aa51b79SEd Maste result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3590435933ddSDimitry Andric compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3591435933ddSDimitry Andric LLDB_INVALID_ADDRESS);
35927aa51b79SEd Maste result.GetOutputStream().Printf("\n");
35937aa51b79SEd Maste }
35947aa51b79SEd Maste
3595435933ddSDimitry Andric if (fast_unwind_plan) {
35967aa51b79SEd Maste result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3597435933ddSDimitry Andric fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3598435933ddSDimitry Andric LLDB_INVALID_ADDRESS);
3599ac7ddfbfSEd Maste result.GetOutputStream().Printf("\n");
3600ac7ddfbfSEd Maste }
3601ac7ddfbfSEd Maste
36027aa51b79SEd Maste ABISP abi_sp = process->GetABI();
3603435933ddSDimitry Andric if (abi_sp) {
36047aa51b79SEd Maste UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3605435933ddSDimitry Andric if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
36067aa51b79SEd Maste result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3607435933ddSDimitry Andric arch_default.Dump(result.GetOutputStream(), thread.get(),
3608435933ddSDimitry Andric LLDB_INVALID_ADDRESS);
36097aa51b79SEd Maste result.GetOutputStream().Printf("\n");
36107aa51b79SEd Maste }
36117aa51b79SEd Maste
36127aa51b79SEd Maste UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3613435933ddSDimitry Andric if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3614435933ddSDimitry Andric result.GetOutputStream().Printf(
3615435933ddSDimitry Andric "Arch default at entry point UnwindPlan:\n");
3616435933ddSDimitry Andric arch_entry.Dump(result.GetOutputStream(), thread.get(),
3617435933ddSDimitry Andric LLDB_INVALID_ADDRESS);
36187aa51b79SEd Maste result.GetOutputStream().Printf("\n");
36197aa51b79SEd Maste }
36207aa51b79SEd Maste }
3621ac7ddfbfSEd Maste
3622ac7ddfbfSEd Maste result.GetOutputStream().Printf("\n");
3623ac7ddfbfSEd Maste }
3624ac7ddfbfSEd Maste return result.Succeeded();
3625ac7ddfbfSEd Maste }
3626ac7ddfbfSEd Maste
3627ac7ddfbfSEd Maste CommandOptions m_options;
3628ac7ddfbfSEd Maste };
3629ac7ddfbfSEd Maste
3630ac7ddfbfSEd Maste //----------------------------------------------------------------------
3631ac7ddfbfSEd Maste // Lookup information in images
3632ac7ddfbfSEd Maste //----------------------------------------------------------------------
3633435933ddSDimitry Andric
3634*b5893f02SDimitry Andric static constexpr OptionDefinition g_target_modules_lookup_options[] = {
3635435933ddSDimitry Andric // clang-format off
3636*b5893f02SDimitry Andric { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." },
3637*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOffset, "When looking up an address subtract <offset> from any addresses before doing the lookup." },
3638435933ddSDimitry Andric /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */
3639*b5893f02SDimitry Andric { LLDB_OPT_SET_2 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5, false, "regex", 'r', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions." },
3640*b5893f02SDimitry Andric { LLDB_OPT_SET_2, true, "symbol", 's', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules." },
3641*b5893f02SDimitry Andric { LLDB_OPT_SET_3, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules." },
3642*b5893f02SDimitry Andric { LLDB_OPT_SET_3, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)." },
3643*b5893f02SDimitry Andric { LLDB_OPT_SET_FROM_TO(3,5), false, "no-inlines", 'i', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)." },
3644*b5893f02SDimitry Andric { LLDB_OPT_SET_4, true, "function", 'F', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules." },
3645*b5893f02SDimitry Andric { LLDB_OPT_SET_5, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules." },
3646*b5893f02SDimitry Andric { LLDB_OPT_SET_6, true, "type", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules." },
3647*b5893f02SDimitry Andric { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Enable verbose lookup information." },
3648*b5893f02SDimitry Andric { LLDB_OPT_SET_ALL, false, "all", 'A', OptionParser::eNoArgument, nullptr, {}, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available." },
3649435933ddSDimitry Andric // clang-format on
3650435933ddSDimitry Andric };
3651435933ddSDimitry Andric
3652435933ddSDimitry Andric class CommandObjectTargetModulesLookup : public CommandObjectParsed {
3653ac7ddfbfSEd Maste public:
3654435933ddSDimitry Andric enum {
3655ac7ddfbfSEd Maste eLookupTypeInvalid = -1,
3656ac7ddfbfSEd Maste eLookupTypeAddress = 0,
3657ac7ddfbfSEd Maste eLookupTypeSymbol,
3658ac7ddfbfSEd Maste eLookupTypeFileLine, // Line is optional
3659ac7ddfbfSEd Maste eLookupTypeFunction,
3660ac7ddfbfSEd Maste eLookupTypeFunctionOrSymbol,
3661ac7ddfbfSEd Maste eLookupTypeType,
3662ac7ddfbfSEd Maste kNumLookupTypes
3663ac7ddfbfSEd Maste };
3664ac7ddfbfSEd Maste
3665435933ddSDimitry Andric class CommandOptions : public Options {
3666ac7ddfbfSEd Maste public:
CommandOptions()3667435933ddSDimitry Andric CommandOptions() : Options() { OptionParsingStarting(nullptr); }
3668ac7ddfbfSEd Maste
36694bb0738eSEd Maste ~CommandOptions() override = default;
3670ac7ddfbfSEd Maste
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)36715517e702SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
3672435933ddSDimitry Andric ExecutionContext *execution_context) override {
36735517e702SDimitry Andric Status error;
3674ac7ddfbfSEd Maste
3675ac7ddfbfSEd Maste const int short_option = m_getopt_table[option_idx].val;
3676ac7ddfbfSEd Maste
3677435933ddSDimitry Andric switch (short_option) {
3678435933ddSDimitry Andric case 'a': {
3679ac7ddfbfSEd Maste m_type = eLookupTypeAddress;
36804ba319b5SDimitry Andric m_addr = OptionArgParser::ToAddress(execution_context, option_arg,
3681435933ddSDimitry Andric LLDB_INVALID_ADDRESS, &error);
3682435933ddSDimitry Andric } break;
3683ac7ddfbfSEd Maste
3684ac7ddfbfSEd Maste case 'o':
3685435933ddSDimitry Andric if (option_arg.getAsInteger(0, m_offset))
3686435933ddSDimitry Andric error.SetErrorStringWithFormat("invalid offset string '%s'",
3687435933ddSDimitry Andric option_arg.str().c_str());
3688ac7ddfbfSEd Maste break;
3689ac7ddfbfSEd Maste
3690ac7ddfbfSEd Maste case 's':
3691ac7ddfbfSEd Maste m_str = option_arg;
3692ac7ddfbfSEd Maste m_type = eLookupTypeSymbol;
3693ac7ddfbfSEd Maste break;
3694ac7ddfbfSEd Maste
3695ac7ddfbfSEd Maste case 'f':
3696*b5893f02SDimitry Andric m_file.SetFile(option_arg, FileSpec::Style::native);
3697ac7ddfbfSEd Maste m_type = eLookupTypeFileLine;
3698ac7ddfbfSEd Maste break;
3699ac7ddfbfSEd Maste
3700ac7ddfbfSEd Maste case 'i':
3701ac7ddfbfSEd Maste m_include_inlines = false;
3702ac7ddfbfSEd Maste break;
3703ac7ddfbfSEd Maste
3704ac7ddfbfSEd Maste case 'l':
3705435933ddSDimitry Andric if (option_arg.getAsInteger(0, m_line_number))
3706435933ddSDimitry Andric error.SetErrorStringWithFormat("invalid line number string '%s'",
3707435933ddSDimitry Andric option_arg.str().c_str());
3708ac7ddfbfSEd Maste else if (m_line_number == 0)
3709ac7ddfbfSEd Maste error.SetErrorString("zero is an invalid line number");
3710ac7ddfbfSEd Maste m_type = eLookupTypeFileLine;
3711ac7ddfbfSEd Maste break;
3712ac7ddfbfSEd Maste
3713ac7ddfbfSEd Maste case 'F':
3714ac7ddfbfSEd Maste m_str = option_arg;
3715ac7ddfbfSEd Maste m_type = eLookupTypeFunction;
3716ac7ddfbfSEd Maste break;
3717ac7ddfbfSEd Maste
3718ac7ddfbfSEd Maste case 'n':
3719ac7ddfbfSEd Maste m_str = option_arg;
3720ac7ddfbfSEd Maste m_type = eLookupTypeFunctionOrSymbol;
3721ac7ddfbfSEd Maste break;
3722ac7ddfbfSEd Maste
3723ac7ddfbfSEd Maste case 't':
3724ac7ddfbfSEd Maste m_str = option_arg;
3725ac7ddfbfSEd Maste m_type = eLookupTypeType;
3726ac7ddfbfSEd Maste break;
3727ac7ddfbfSEd Maste
3728ac7ddfbfSEd Maste case 'v':
3729ac7ddfbfSEd Maste m_verbose = 1;
3730ac7ddfbfSEd Maste break;
3731ac7ddfbfSEd Maste
3732ac7ddfbfSEd Maste case 'A':
3733ac7ddfbfSEd Maste m_print_all = true;
3734ac7ddfbfSEd Maste break;
3735ac7ddfbfSEd Maste
3736ac7ddfbfSEd Maste case 'r':
3737ac7ddfbfSEd Maste m_use_regex = true;
3738ac7ddfbfSEd Maste break;
3739ac7ddfbfSEd Maste }
3740ac7ddfbfSEd Maste
3741ac7ddfbfSEd Maste return error;
3742ac7ddfbfSEd Maste }
3743ac7ddfbfSEd Maste
OptionParsingStarting(ExecutionContext * execution_context)3744435933ddSDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
3745ac7ddfbfSEd Maste m_type = eLookupTypeInvalid;
3746ac7ddfbfSEd Maste m_str.clear();
3747ac7ddfbfSEd Maste m_file.Clear();
3748ac7ddfbfSEd Maste m_addr = LLDB_INVALID_ADDRESS;
3749ac7ddfbfSEd Maste m_offset = 0;
3750ac7ddfbfSEd Maste m_line_number = 0;
3751ac7ddfbfSEd Maste m_use_regex = false;
3752ac7ddfbfSEd Maste m_include_inlines = true;
3753ac7ddfbfSEd Maste m_verbose = false;
3754ac7ddfbfSEd Maste m_print_all = false;
3755ac7ddfbfSEd Maste }
3756ac7ddfbfSEd Maste
GetDefinitions()3757435933ddSDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
3758435933ddSDimitry Andric return llvm::makeArrayRef(g_target_modules_lookup_options);
3759ac7ddfbfSEd Maste }
3760ac7ddfbfSEd Maste
3761ac7ddfbfSEd Maste int m_type; // Should be a eLookupTypeXXX enum after parsing options
3762ac7ddfbfSEd Maste std::string m_str; // Holds name lookup
3763ac7ddfbfSEd Maste FileSpec m_file; // Files for file lookups
3764ac7ddfbfSEd Maste lldb::addr_t m_addr; // Holds the address to lookup
3765435933ddSDimitry Andric lldb::addr_t
3766435933ddSDimitry Andric m_offset; // Subtract this offset from m_addr before doing lookups.
3767ac7ddfbfSEd Maste uint32_t m_line_number; // Line number for file+line lookups
3768ac7ddfbfSEd Maste bool m_use_regex; // Name lookups in m_str are regular expressions.
3769435933ddSDimitry Andric bool m_include_inlines; // Check for inline entries when looking up by
3770435933ddSDimitry Andric // file/line.
3771ac7ddfbfSEd Maste bool m_verbose; // Enable verbose lookup info
3772435933ddSDimitry Andric bool m_print_all; // Print all matches, even in cases where there's a best
3773435933ddSDimitry Andric // match.
3774ac7ddfbfSEd Maste };
3775ac7ddfbfSEd Maste
CommandObjectTargetModulesLookup(CommandInterpreter & interpreter)3776435933ddSDimitry Andric CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3777435933ddSDimitry Andric : CommandObjectParsed(interpreter, "target modules lookup",
3778435933ddSDimitry Andric "Look up information within executable and "
3779435933ddSDimitry Andric "dependent shared library images.",
3780435933ddSDimitry Andric nullptr, eCommandRequiresTarget),
3781435933ddSDimitry Andric m_options() {
3782ac7ddfbfSEd Maste CommandArgumentEntry arg;
3783ac7ddfbfSEd Maste CommandArgumentData file_arg;
3784ac7ddfbfSEd Maste
3785ac7ddfbfSEd Maste // Define the first (and only) variant of this arg.
3786ac7ddfbfSEd Maste file_arg.arg_type = eArgTypeFilename;
3787ac7ddfbfSEd Maste file_arg.arg_repetition = eArgRepeatStar;
3788ac7ddfbfSEd Maste
3789435933ddSDimitry Andric // There is only one variant this argument could be; put it into the
3790435933ddSDimitry Andric // argument entry.
3791ac7ddfbfSEd Maste arg.push_back(file_arg);
3792ac7ddfbfSEd Maste
3793ac7ddfbfSEd Maste // Push the data for the first argument into the m_arguments vector.
3794ac7ddfbfSEd Maste m_arguments.push_back(arg);
3795ac7ddfbfSEd Maste }
3796ac7ddfbfSEd Maste
37974bb0738eSEd Maste ~CommandObjectTargetModulesLookup() override = default;
3798ac7ddfbfSEd Maste
GetOptions()3799435933ddSDimitry Andric Options *GetOptions() override { return &m_options; }
3800ac7ddfbfSEd Maste
LookupHere(CommandInterpreter & interpreter,CommandReturnObject & result,bool & syntax_error)3801435933ddSDimitry Andric bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3802435933ddSDimitry Andric bool &syntax_error) {
3803435933ddSDimitry Andric switch (m_options.m_type) {
3804ac7ddfbfSEd Maste case eLookupTypeAddress:
3805ac7ddfbfSEd Maste case eLookupTypeFileLine:
3806ac7ddfbfSEd Maste case eLookupTypeFunction:
3807ac7ddfbfSEd Maste case eLookupTypeFunctionOrSymbol:
3808ac7ddfbfSEd Maste case eLookupTypeSymbol:
3809ac7ddfbfSEd Maste default:
3810ac7ddfbfSEd Maste return false;
3811ac7ddfbfSEd Maste case eLookupTypeType:
3812ac7ddfbfSEd Maste break;
3813ac7ddfbfSEd Maste }
3814ac7ddfbfSEd Maste
3815ac7ddfbfSEd Maste StackFrameSP frame = m_exe_ctx.GetFrameSP();
3816ac7ddfbfSEd Maste
3817ac7ddfbfSEd Maste if (!frame)
3818ac7ddfbfSEd Maste return false;
3819ac7ddfbfSEd Maste
3820ac7ddfbfSEd Maste const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3821ac7ddfbfSEd Maste
3822ac7ddfbfSEd Maste if (!sym_ctx.module_sp)
3823ac7ddfbfSEd Maste return false;
3824ac7ddfbfSEd Maste
3825435933ddSDimitry Andric switch (m_options.m_type) {
3826ac7ddfbfSEd Maste default:
3827ac7ddfbfSEd Maste return false;
3828ac7ddfbfSEd Maste case eLookupTypeType:
3829435933ddSDimitry Andric if (!m_options.m_str.empty()) {
3830*b5893f02SDimitry Andric if (LookupTypeHere(m_interpreter, result.GetOutputStream(),
3831*b5893f02SDimitry Andric *sym_ctx.module_sp, m_options.m_str.c_str(),
3832*b5893f02SDimitry Andric m_options.m_use_regex)) {
3833ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
3834ac7ddfbfSEd Maste return true;
3835ac7ddfbfSEd Maste }
3836ac7ddfbfSEd Maste }
3837ac7ddfbfSEd Maste break;
3838ac7ddfbfSEd Maste }
3839ac7ddfbfSEd Maste
3840ac7ddfbfSEd Maste return true;
3841ac7ddfbfSEd Maste }
3842ac7ddfbfSEd Maste
LookupInModule(CommandInterpreter & interpreter,Module * module,CommandReturnObject & result,bool & syntax_error)3843435933ddSDimitry Andric bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3844435933ddSDimitry Andric CommandReturnObject &result, bool &syntax_error) {
3845435933ddSDimitry Andric switch (m_options.m_type) {
3846ac7ddfbfSEd Maste case eLookupTypeAddress:
3847435933ddSDimitry Andric if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3848435933ddSDimitry Andric if (LookupAddressInModule(
3849435933ddSDimitry Andric m_interpreter, result.GetOutputStream(), module,
3850435933ddSDimitry Andric eSymbolContextEverything |
3851435933ddSDimitry Andric (m_options.m_verbose
3852435933ddSDimitry Andric ? static_cast<int>(eSymbolContextVariable)
3853435933ddSDimitry Andric : 0),
3854435933ddSDimitry Andric m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
3855ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
3856ac7ddfbfSEd Maste return true;
3857ac7ddfbfSEd Maste }
3858ac7ddfbfSEd Maste }
3859ac7ddfbfSEd Maste break;
3860ac7ddfbfSEd Maste
3861ac7ddfbfSEd Maste case eLookupTypeSymbol:
3862435933ddSDimitry Andric if (!m_options.m_str.empty()) {
3863435933ddSDimitry Andric if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3864435933ddSDimitry Andric module, m_options.m_str.c_str(),
3865435933ddSDimitry Andric m_options.m_use_regex, m_options.m_verbose)) {
3866ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
3867ac7ddfbfSEd Maste return true;
3868ac7ddfbfSEd Maste }
3869ac7ddfbfSEd Maste }
3870ac7ddfbfSEd Maste break;
3871ac7ddfbfSEd Maste
3872ac7ddfbfSEd Maste case eLookupTypeFileLine:
3873435933ddSDimitry Andric if (m_options.m_file) {
3874435933ddSDimitry Andric if (LookupFileAndLineInModule(
3875435933ddSDimitry Andric m_interpreter, result.GetOutputStream(), module,
3876435933ddSDimitry Andric m_options.m_file, m_options.m_line_number,
3877435933ddSDimitry Andric m_options.m_include_inlines, m_options.m_verbose)) {
3878ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
3879ac7ddfbfSEd Maste return true;
3880ac7ddfbfSEd Maste }
3881ac7ddfbfSEd Maste }
3882ac7ddfbfSEd Maste break;
3883ac7ddfbfSEd Maste
3884ac7ddfbfSEd Maste case eLookupTypeFunctionOrSymbol:
3885ac7ddfbfSEd Maste case eLookupTypeFunction:
3886435933ddSDimitry Andric if (!m_options.m_str.empty()) {
3887435933ddSDimitry Andric if (LookupFunctionInModule(
3888435933ddSDimitry Andric m_interpreter, result.GetOutputStream(), module,
3889435933ddSDimitry Andric m_options.m_str.c_str(), m_options.m_use_regex,
3890ac7ddfbfSEd Maste m_options.m_include_inlines,
3891435933ddSDimitry Andric m_options.m_type ==
3892435933ddSDimitry Andric eLookupTypeFunctionOrSymbol, // include symbols
3893435933ddSDimitry Andric m_options.m_verbose)) {
3894ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
3895ac7ddfbfSEd Maste return true;
3896ac7ddfbfSEd Maste }
3897ac7ddfbfSEd Maste }
3898ac7ddfbfSEd Maste break;
3899ac7ddfbfSEd Maste
3900ac7ddfbfSEd Maste case eLookupTypeType:
3901435933ddSDimitry Andric if (!m_options.m_str.empty()) {
3902435933ddSDimitry Andric if (LookupTypeInModule(m_interpreter, result.GetOutputStream(), module,
3903ac7ddfbfSEd Maste m_options.m_str.c_str(),
3904435933ddSDimitry Andric m_options.m_use_regex)) {
3905ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
3906ac7ddfbfSEd Maste return true;
3907ac7ddfbfSEd Maste }
3908ac7ddfbfSEd Maste }
3909ac7ddfbfSEd Maste break;
3910ac7ddfbfSEd Maste
3911ac7ddfbfSEd Maste default:
3912435933ddSDimitry Andric m_options.GenerateOptionUsage(
3913435933ddSDimitry Andric result.GetErrorStream(), this,
3914435933ddSDimitry Andric GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3915ac7ddfbfSEd Maste syntax_error = true;
3916ac7ddfbfSEd Maste break;
3917ac7ddfbfSEd Maste }
3918ac7ddfbfSEd Maste
3919ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
3920ac7ddfbfSEd Maste return false;
3921ac7ddfbfSEd Maste }
3922ac7ddfbfSEd Maste
3923ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)3924435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
3925ac7ddfbfSEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3926435933ddSDimitry Andric if (target == nullptr) {
3927435933ddSDimitry Andric result.AppendError("invalid target, create a debug target using the "
3928435933ddSDimitry Andric "'target create' command");
3929ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
3930ac7ddfbfSEd Maste return false;
3931435933ddSDimitry Andric } else {
3932ac7ddfbfSEd Maste bool syntax_error = false;
3933ac7ddfbfSEd Maste uint32_t i;
3934ac7ddfbfSEd Maste uint32_t num_successful_lookups = 0;
3935ac7ddfbfSEd Maste uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3936ac7ddfbfSEd Maste result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3937ac7ddfbfSEd Maste result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3938ac7ddfbfSEd Maste // Dump all sections for all modules images
3939ac7ddfbfSEd Maste
3940435933ddSDimitry Andric if (command.GetArgumentCount() == 0) {
3941ac7ddfbfSEd Maste ModuleSP current_module;
3942ac7ddfbfSEd Maste
39434ba319b5SDimitry Andric // Where it is possible to look in the current symbol context first,
39444ba319b5SDimitry Andric // try that. If this search was successful and --all was not passed,
39454ba319b5SDimitry Andric // don't print anything else.
3946435933ddSDimitry Andric if (LookupHere(m_interpreter, result, syntax_error)) {
3947ac7ddfbfSEd Maste result.GetOutputStream().EOL();
3948ac7ddfbfSEd Maste num_successful_lookups++;
3949435933ddSDimitry Andric if (!m_options.m_print_all) {
3950ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
3951ac7ddfbfSEd Maste return result.Succeeded();
3952ac7ddfbfSEd Maste }
3953ac7ddfbfSEd Maste }
3954ac7ddfbfSEd Maste
3955ac7ddfbfSEd Maste // Dump all sections for all other modules
3956ac7ddfbfSEd Maste
3957ac7ddfbfSEd Maste const ModuleList &target_modules = target->GetImages();
39584bb0738eSEd Maste std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3959ac7ddfbfSEd Maste const size_t num_modules = target_modules.GetSize();
3960435933ddSDimitry Andric if (num_modules > 0) {
3961435933ddSDimitry Andric for (i = 0; i < num_modules && !syntax_error; ++i) {
3962435933ddSDimitry Andric Module *module_pointer =
3963435933ddSDimitry Andric target_modules.GetModulePointerAtIndexUnlocked(i);
3964ac7ddfbfSEd Maste
3965ac7ddfbfSEd Maste if (module_pointer != current_module.get() &&
3966435933ddSDimitry Andric LookupInModule(
3967435933ddSDimitry Andric m_interpreter,
3968435933ddSDimitry Andric target_modules.GetModulePointerAtIndexUnlocked(i), result,
3969435933ddSDimitry Andric syntax_error)) {
3970ac7ddfbfSEd Maste result.GetOutputStream().EOL();
3971ac7ddfbfSEd Maste num_successful_lookups++;
3972ac7ddfbfSEd Maste }
3973ac7ddfbfSEd Maste }
3974435933ddSDimitry Andric } else {
3975ac7ddfbfSEd Maste result.AppendError("the target has no associated executable images");
3976ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
3977ac7ddfbfSEd Maste return false;
3978ac7ddfbfSEd Maste }
3979435933ddSDimitry Andric } else {
3980ac7ddfbfSEd Maste // Dump specified images (by basename or fullpath)
3981ac7ddfbfSEd Maste const char *arg_cstr;
3982435933ddSDimitry Andric for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3983435933ddSDimitry Andric !syntax_error;
3984435933ddSDimitry Andric ++i) {
3985ac7ddfbfSEd Maste ModuleList module_list;
3986435933ddSDimitry Andric const size_t num_matches =
3987435933ddSDimitry Andric FindModulesByName(target, arg_cstr, module_list, false);
3988435933ddSDimitry Andric if (num_matches > 0) {
3989435933ddSDimitry Andric for (size_t j = 0; j < num_matches; ++j) {
3990ac7ddfbfSEd Maste Module *module = module_list.GetModulePointerAtIndex(j);
3991435933ddSDimitry Andric if (module) {
3992435933ddSDimitry Andric if (LookupInModule(m_interpreter, module, result,
3993435933ddSDimitry Andric syntax_error)) {
3994ac7ddfbfSEd Maste result.GetOutputStream().EOL();
3995ac7ddfbfSEd Maste num_successful_lookups++;
3996ac7ddfbfSEd Maste }
3997ac7ddfbfSEd Maste }
3998ac7ddfbfSEd Maste }
3999435933ddSDimitry Andric } else
4000435933ddSDimitry Andric result.AppendWarningWithFormat(
4001435933ddSDimitry Andric "Unable to find an image that matches '%s'.\n", arg_cstr);
4002ac7ddfbfSEd Maste }
4003ac7ddfbfSEd Maste }
4004ac7ddfbfSEd Maste
4005ac7ddfbfSEd Maste if (num_successful_lookups > 0)
4006ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
4007ac7ddfbfSEd Maste else
4008ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
4009ac7ddfbfSEd Maste }
4010ac7ddfbfSEd Maste return result.Succeeded();
4011ac7ddfbfSEd Maste }
4012ac7ddfbfSEd Maste
4013ac7ddfbfSEd Maste CommandOptions m_options;
4014ac7ddfbfSEd Maste };
4015ac7ddfbfSEd Maste
4016ac7ddfbfSEd Maste #pragma mark CommandObjectMultiwordImageSearchPaths
4017ac7ddfbfSEd Maste
4018ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4019ac7ddfbfSEd Maste // CommandObjectMultiwordImageSearchPaths
4020ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4021ac7ddfbfSEd Maste
4022435933ddSDimitry Andric class CommandObjectTargetModulesImageSearchPaths
4023435933ddSDimitry Andric : public CommandObjectMultiword {
4024ac7ddfbfSEd Maste public:
CommandObjectTargetModulesImageSearchPaths(CommandInterpreter & interpreter)40254bb0738eSEd Maste CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
4026435933ddSDimitry Andric : CommandObjectMultiword(
4027435933ddSDimitry Andric interpreter, "target modules search-paths",
40284bb0738eSEd Maste "Commands for managing module search paths for a target.",
4029435933ddSDimitry Andric "target modules search-paths <subcommand> [<subcommand-options>]") {
4030435933ddSDimitry Andric LoadSubCommand(
4031435933ddSDimitry Andric "add", CommandObjectSP(
4032435933ddSDimitry Andric new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
4033435933ddSDimitry Andric LoadSubCommand(
4034435933ddSDimitry Andric "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
4035435933ddSDimitry Andric interpreter)));
4036435933ddSDimitry Andric LoadSubCommand(
4037435933ddSDimitry Andric "insert",
4038435933ddSDimitry Andric CommandObjectSP(
4039435933ddSDimitry Andric new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
4040435933ddSDimitry Andric LoadSubCommand(
4041435933ddSDimitry Andric "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
4042435933ddSDimitry Andric interpreter)));
4043435933ddSDimitry Andric LoadSubCommand(
4044435933ddSDimitry Andric "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
4045435933ddSDimitry Andric interpreter)));
4046ac7ddfbfSEd Maste }
4047ac7ddfbfSEd Maste
40484bb0738eSEd Maste ~CommandObjectTargetModulesImageSearchPaths() override = default;
4049ac7ddfbfSEd Maste };
4050ac7ddfbfSEd Maste
4051ac7ddfbfSEd Maste #pragma mark CommandObjectTargetModules
4052ac7ddfbfSEd Maste
4053ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4054ac7ddfbfSEd Maste // CommandObjectTargetModules
4055ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4056ac7ddfbfSEd Maste
4057435933ddSDimitry Andric class CommandObjectTargetModules : public CommandObjectMultiword {
4058ac7ddfbfSEd Maste public:
4059ac7ddfbfSEd Maste //------------------------------------------------------------------
4060ac7ddfbfSEd Maste // Constructors and Destructors
4061ac7ddfbfSEd Maste //------------------------------------------------------------------
CommandObjectTargetModules(CommandInterpreter & interpreter)40624bb0738eSEd Maste CommandObjectTargetModules(CommandInterpreter &interpreter)
40634bb0738eSEd Maste : CommandObjectMultiword(interpreter, "target modules",
4064435933ddSDimitry Andric "Commands for accessing information for one or "
4065435933ddSDimitry Andric "more target modules.",
4066435933ddSDimitry Andric "target modules <sub-command> ...") {
4067435933ddSDimitry Andric LoadSubCommand(
4068435933ddSDimitry Andric "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
4069435933ddSDimitry Andric LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
4070435933ddSDimitry Andric interpreter)));
4071435933ddSDimitry Andric LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
4072435933ddSDimitry Andric interpreter)));
4073435933ddSDimitry Andric LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
4074435933ddSDimitry Andric interpreter)));
4075435933ddSDimitry Andric LoadSubCommand(
4076435933ddSDimitry Andric "lookup",
4077435933ddSDimitry Andric CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
4078435933ddSDimitry Andric LoadSubCommand(
4079435933ddSDimitry Andric "search-paths",
4080435933ddSDimitry Andric CommandObjectSP(
4081435933ddSDimitry Andric new CommandObjectTargetModulesImageSearchPaths(interpreter)));
4082435933ddSDimitry Andric LoadSubCommand(
4083435933ddSDimitry Andric "show-unwind",
4084435933ddSDimitry Andric CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
4085ac7ddfbfSEd Maste }
40869f2f44ceSEd Maste
40874bb0738eSEd Maste ~CommandObjectTargetModules() override = default;
4088ac7ddfbfSEd Maste
4089ac7ddfbfSEd Maste private:
4090ac7ddfbfSEd Maste //------------------------------------------------------------------
4091ac7ddfbfSEd Maste // For CommandObjectTargetModules only
4092ac7ddfbfSEd Maste //------------------------------------------------------------------
4093ac7ddfbfSEd Maste DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules);
4094ac7ddfbfSEd Maste };
4095ac7ddfbfSEd Maste
4096435933ddSDimitry Andric class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
4097ac7ddfbfSEd Maste public:
CommandObjectTargetSymbolsAdd(CommandInterpreter & interpreter)4098435933ddSDimitry Andric CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
4099435933ddSDimitry Andric : CommandObjectParsed(
4100435933ddSDimitry Andric interpreter, "target symbols add",
4101435933ddSDimitry Andric "Add a debug symbol file to one of the target's current modules by "
4102435933ddSDimitry Andric "specifying a path to a debug symbols file, or using the options "
4103435933ddSDimitry Andric "to specify a module to download symbols for.",
4104acac075bSDimitry Andric "target symbols add <cmd-options> [<symfile>]",
4105acac075bSDimitry Andric eCommandRequiresTarget),
4106435933ddSDimitry Andric m_option_group(),
4107435933ddSDimitry Andric m_file_option(
4108435933ddSDimitry Andric LLDB_OPT_SET_1, false, "shlib", 's',
4109435933ddSDimitry Andric CommandCompletions::eModuleCompletion, eArgTypeShlibName,
4110435933ddSDimitry Andric "Fullpath or basename for module to find debug symbols for."),
4111435933ddSDimitry Andric m_current_frame_option(
4112435933ddSDimitry Andric LLDB_OPT_SET_2, false, "frame", 'F',
4113435933ddSDimitry Andric "Locate the debug symbols the currently selected frame.", false,
4114435933ddSDimitry Andric true)
4115ac7ddfbfSEd Maste
4116ac7ddfbfSEd Maste {
4117435933ddSDimitry Andric m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
4118435933ddSDimitry Andric LLDB_OPT_SET_1);
4119ac7ddfbfSEd Maste m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4120435933ddSDimitry Andric m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
4121435933ddSDimitry Andric LLDB_OPT_SET_2);
4122ac7ddfbfSEd Maste m_option_group.Finalize();
4123ac7ddfbfSEd Maste }
4124ac7ddfbfSEd Maste
41254bb0738eSEd Maste ~CommandObjectTargetSymbolsAdd() override = default;
4126ac7ddfbfSEd Maste
HandleArgumentCompletion(CompletionRequest & request,OptionElementVector & opt_element_vector)41274ba319b5SDimitry Andric int HandleArgumentCompletion(
41284ba319b5SDimitry Andric CompletionRequest &request,
41294ba319b5SDimitry Andric OptionElementVector &opt_element_vector) override {
4130435933ddSDimitry Andric CommandCompletions::InvokeCommonCompletionCallbacks(
4131435933ddSDimitry Andric GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
41324ba319b5SDimitry Andric request, nullptr);
41334ba319b5SDimitry Andric return request.GetNumberOfMatches();
4134ac7ddfbfSEd Maste }
4135ac7ddfbfSEd Maste
GetOptions()4136435933ddSDimitry Andric Options *GetOptions() override { return &m_option_group; }
4137ac7ddfbfSEd Maste
4138ac7ddfbfSEd Maste protected:
AddModuleSymbols(Target * target,ModuleSpec & module_spec,bool & flush,CommandReturnObject & result)4139435933ddSDimitry Andric bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
4140435933ddSDimitry Andric CommandReturnObject &result) {
4141ac7ddfbfSEd Maste const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
4142435933ddSDimitry Andric if (symbol_fspec) {
4143ac7ddfbfSEd Maste char symfile_path[PATH_MAX];
4144ac7ddfbfSEd Maste symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
4145ac7ddfbfSEd Maste
4146435933ddSDimitry Andric if (!module_spec.GetUUID().IsValid()) {
4147ac7ddfbfSEd Maste if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4148ac7ddfbfSEd Maste module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4149ac7ddfbfSEd Maste }
41504ba319b5SDimitry Andric // We now have a module that represents a symbol file that can be used
41514ba319b5SDimitry Andric // for a module that might exist in the current target, so we need to
41524ba319b5SDimitry Andric // find that module in the target
4153ac7ddfbfSEd Maste ModuleList matching_module_list;
4154ac7ddfbfSEd Maste
4155ac7ddfbfSEd Maste size_t num_matches = 0;
4156ac7ddfbfSEd Maste // First extract all module specs from the symbol file
4157ac7ddfbfSEd Maste lldb_private::ModuleSpecList symfile_module_specs;
4158435933ddSDimitry Andric if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
4159435933ddSDimitry Andric 0, 0, symfile_module_specs)) {
4160ac7ddfbfSEd Maste // Now extract the module spec that matches the target architecture
4161ac7ddfbfSEd Maste ModuleSpec target_arch_module_spec;
4162ac7ddfbfSEd Maste ModuleSpec symfile_module_spec;
4163ac7ddfbfSEd Maste target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4164435933ddSDimitry Andric if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4165435933ddSDimitry Andric symfile_module_spec)) {
4166ac7ddfbfSEd Maste // See if it has a UUID?
4167435933ddSDimitry Andric if (symfile_module_spec.GetUUID().IsValid()) {
4168ac7ddfbfSEd Maste // It has a UUID, look for this UUID in the target modules
4169ac7ddfbfSEd Maste ModuleSpec symfile_uuid_module_spec;
4170ac7ddfbfSEd Maste symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4171435933ddSDimitry Andric num_matches = target->GetImages().FindModules(
4172435933ddSDimitry Andric symfile_uuid_module_spec, matching_module_list);
4173ac7ddfbfSEd Maste }
4174ac7ddfbfSEd Maste }
4175ac7ddfbfSEd Maste
4176435933ddSDimitry Andric if (num_matches == 0) {
4177435933ddSDimitry Andric // No matches yet, iterate through the module specs to find a UUID
41784ba319b5SDimitry Andric // value that we can match up to an image in our target
4179435933ddSDimitry Andric const size_t num_symfile_module_specs =
4180435933ddSDimitry Andric symfile_module_specs.GetSize();
4181435933ddSDimitry Andric for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0;
4182435933ddSDimitry Andric ++i) {
4183435933ddSDimitry Andric if (symfile_module_specs.GetModuleSpecAtIndex(
4184435933ddSDimitry Andric i, symfile_module_spec)) {
4185435933ddSDimitry Andric if (symfile_module_spec.GetUUID().IsValid()) {
4186ac7ddfbfSEd Maste // It has a UUID, look for this UUID in the target modules
4187ac7ddfbfSEd Maste ModuleSpec symfile_uuid_module_spec;
4188435933ddSDimitry Andric symfile_uuid_module_spec.GetUUID() =
4189435933ddSDimitry Andric symfile_module_spec.GetUUID();
4190435933ddSDimitry Andric num_matches = target->GetImages().FindModules(
4191435933ddSDimitry Andric symfile_uuid_module_spec, matching_module_list);
4192ac7ddfbfSEd Maste }
4193ac7ddfbfSEd Maste }
4194ac7ddfbfSEd Maste }
4195ac7ddfbfSEd Maste }
4196ac7ddfbfSEd Maste }
4197ac7ddfbfSEd Maste
41984ba319b5SDimitry Andric // Just try to match up the file by basename if we have no matches at
41994ba319b5SDimitry Andric // this point
4200ac7ddfbfSEd Maste if (num_matches == 0)
4201435933ddSDimitry Andric num_matches =
4202435933ddSDimitry Andric target->GetImages().FindModules(module_spec, matching_module_list);
4203ac7ddfbfSEd Maste
4204435933ddSDimitry Andric while (num_matches == 0) {
4205435933ddSDimitry Andric ConstString filename_no_extension(
4206435933ddSDimitry Andric module_spec.GetFileSpec().GetFileNameStrippingExtension());
4207ac7ddfbfSEd Maste // Empty string returned, lets bail
4208ac7ddfbfSEd Maste if (!filename_no_extension)
4209ac7ddfbfSEd Maste break;
4210ac7ddfbfSEd Maste
42114ba319b5SDimitry Andric // Check if there was no extension to strip and the basename is the
42124ba319b5SDimitry Andric // same
4213ac7ddfbfSEd Maste if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4214ac7ddfbfSEd Maste break;
4215ac7ddfbfSEd Maste
4216ac7ddfbfSEd Maste // Replace basename with one less extension
4217ac7ddfbfSEd Maste module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4218ac7ddfbfSEd Maste
4219435933ddSDimitry Andric num_matches =
4220435933ddSDimitry Andric target->GetImages().FindModules(module_spec, matching_module_list);
4221ac7ddfbfSEd Maste }
4222ac7ddfbfSEd Maste
4223435933ddSDimitry Andric if (num_matches > 1) {
4224435933ddSDimitry Andric result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4225435933ddSDimitry Andric "use the --uuid option to resolve the "
4226435933ddSDimitry Andric "ambiguity.\n",
4227435933ddSDimitry Andric symfile_path);
4228435933ddSDimitry Andric } else if (num_matches == 1) {
4229ac7ddfbfSEd Maste ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0));
4230ac7ddfbfSEd Maste
42314ba319b5SDimitry Andric // The module has not yet created its symbol vendor, we can just give
42324ba319b5SDimitry Andric // the existing target module the symfile path to use for when it
42334ba319b5SDimitry Andric // decides to create it!
4234ac7ddfbfSEd Maste module_sp->SetSymbolFileFileSpec(symbol_fspec);
4235ac7ddfbfSEd Maste
4236435933ddSDimitry Andric SymbolVendor *symbol_vendor =
4237435933ddSDimitry Andric module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4238435933ddSDimitry Andric if (symbol_vendor) {
4239ac7ddfbfSEd Maste SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4240ac7ddfbfSEd Maste
4241435933ddSDimitry Andric if (symbol_file) {
4242ac7ddfbfSEd Maste ObjectFile *object_file = symbol_file->GetObjectFile();
4243ac7ddfbfSEd Maste
4244435933ddSDimitry Andric if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4245ac7ddfbfSEd Maste // Provide feedback that the symfile has been successfully added.
4246ac7ddfbfSEd Maste const FileSpec &module_fs = module_sp->GetFileSpec();
4247435933ddSDimitry Andric result.AppendMessageWithFormat(
4248435933ddSDimitry Andric "symbol file '%s' has been added to '%s'\n", symfile_path,
4249ac7ddfbfSEd Maste module_fs.GetPath().c_str());
4250ac7ddfbfSEd Maste
42514ba319b5SDimitry Andric // Let clients know something changed in the module if it is
42524ba319b5SDimitry Andric // currently loaded
4253ac7ddfbfSEd Maste ModuleList module_list;
4254ac7ddfbfSEd Maste module_list.Append(module_sp);
4255ac7ddfbfSEd Maste target->SymbolsDidLoad(module_list);
4256ac7ddfbfSEd Maste
4257ac7ddfbfSEd Maste // Make sure we load any scripting resources that may be embedded
4258ac7ddfbfSEd Maste // in the debug info files in case the platform supports that.
42595517e702SDimitry Andric Status error;
4260ac7ddfbfSEd Maste StreamString feedback_stream;
4261435933ddSDimitry Andric module_sp->LoadScriptingResourceInTarget(target, error,
4262435933ddSDimitry Andric &feedback_stream);
4263ac7ddfbfSEd Maste if (error.Fail() && error.AsCString())
4264435933ddSDimitry Andric result.AppendWarningWithFormat(
4265435933ddSDimitry Andric "unable to load scripting data for module %s - error "
4266435933ddSDimitry Andric "reported was %s",
4267435933ddSDimitry Andric module_sp->GetFileSpec()
4268435933ddSDimitry Andric .GetFileNameStrippingExtension()
4269435933ddSDimitry Andric .GetCString(),
4270ac7ddfbfSEd Maste error.AsCString());
4271ac7ddfbfSEd Maste else if (feedback_stream.GetSize())
4272ac7ddfbfSEd Maste result.AppendWarningWithFormat("%s", feedback_stream.GetData());
4273ac7ddfbfSEd Maste
4274ac7ddfbfSEd Maste flush = true;
4275ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
4276ac7ddfbfSEd Maste return true;
4277ac7ddfbfSEd Maste }
4278ac7ddfbfSEd Maste }
4279ac7ddfbfSEd Maste }
4280ac7ddfbfSEd Maste // Clear the symbol file spec if anything went wrong
4281ac7ddfbfSEd Maste module_sp->SetSymbolFileFileSpec(FileSpec());
4282ac7ddfbfSEd Maste }
4283ac7ddfbfSEd Maste
4284f678e45dSDimitry Andric namespace fs = llvm::sys::fs;
4285435933ddSDimitry Andric if (module_spec.GetUUID().IsValid()) {
4286ac7ddfbfSEd Maste StreamString ss_symfile_uuid;
4287ac7ddfbfSEd Maste module_spec.GetUUID().Dump(&ss_symfile_uuid);
4288435933ddSDimitry Andric result.AppendErrorWithFormat(
4289435933ddSDimitry Andric "symbol file '%s' (%s) does not match any existing module%s\n",
4290435933ddSDimitry Andric symfile_path, ss_symfile_uuid.GetData(),
4291f678e45dSDimitry Andric !fs::is_regular_file(symbol_fspec.GetPath())
4292ac7ddfbfSEd Maste ? "\n please specify the full path to the symbol file"
4293ac7ddfbfSEd Maste : "");
4294435933ddSDimitry Andric } else {
4295435933ddSDimitry Andric result.AppendErrorWithFormat(
4296435933ddSDimitry Andric "symbol file '%s' does not match any existing module%s\n",
4297ac7ddfbfSEd Maste symfile_path,
4298f678e45dSDimitry Andric !fs::is_regular_file(symbol_fspec.GetPath())
4299ac7ddfbfSEd Maste ? "\n please specify the full path to the symbol file"
4300ac7ddfbfSEd Maste : "");
4301ac7ddfbfSEd Maste }
4302435933ddSDimitry Andric } else {
4303435933ddSDimitry Andric result.AppendError(
4304435933ddSDimitry Andric "one or more executable image paths must be specified");
4305ac7ddfbfSEd Maste }
4306ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
4307ac7ddfbfSEd Maste return false;
4308ac7ddfbfSEd Maste }
4309ac7ddfbfSEd Maste
DoExecute(Args & args,CommandReturnObject & result)4310435933ddSDimitry Andric bool DoExecute(Args &args, CommandReturnObject &result) override {
4311ac7ddfbfSEd Maste Target *target = m_exe_ctx.GetTargetPtr();
4312ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
4313ac7ddfbfSEd Maste bool flush = false;
4314ac7ddfbfSEd Maste ModuleSpec module_spec;
4315435933ddSDimitry Andric const bool uuid_option_set =
4316435933ddSDimitry Andric m_uuid_option_group.GetOptionValue().OptionWasSet();
4317ac7ddfbfSEd Maste const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4318435933ddSDimitry Andric const bool frame_option_set =
4319435933ddSDimitry Andric m_current_frame_option.GetOptionValue().OptionWasSet();
4320ac7ddfbfSEd Maste const size_t argc = args.GetArgumentCount();
43214bb0738eSEd Maste
4322435933ddSDimitry Andric if (argc == 0) {
4323435933ddSDimitry Andric if (uuid_option_set || file_option_set || frame_option_set) {
4324ac7ddfbfSEd Maste bool success = false;
4325ac7ddfbfSEd Maste bool error_set = false;
4326435933ddSDimitry Andric if (frame_option_set) {
4327ac7ddfbfSEd Maste Process *process = m_exe_ctx.GetProcessPtr();
4328435933ddSDimitry Andric if (process) {
4329ac7ddfbfSEd Maste const StateType process_state = process->GetState();
4330435933ddSDimitry Andric if (StateIsStoppedState(process_state, true)) {
4331ac7ddfbfSEd Maste StackFrame *frame = m_exe_ctx.GetFramePtr();
4332435933ddSDimitry Andric if (frame) {
4333435933ddSDimitry Andric ModuleSP frame_module_sp(
4334435933ddSDimitry Andric frame->GetSymbolContext(eSymbolContextModule).module_sp);
4335435933ddSDimitry Andric if (frame_module_sp) {
4336*b5893f02SDimitry Andric if (FileSystem::Instance().Exists(
4337*b5893f02SDimitry Andric frame_module_sp->GetPlatformFileSpec())) {
4338435933ddSDimitry Andric module_spec.GetArchitecture() =
4339435933ddSDimitry Andric frame_module_sp->GetArchitecture();
4340435933ddSDimitry Andric module_spec.GetFileSpec() =
4341435933ddSDimitry Andric frame_module_sp->GetPlatformFileSpec();
4342ac7ddfbfSEd Maste }
4343ac7ddfbfSEd Maste module_spec.GetUUID() = frame_module_sp->GetUUID();
4344435933ddSDimitry Andric success = module_spec.GetUUID().IsValid() ||
4345435933ddSDimitry Andric module_spec.GetFileSpec();
4346435933ddSDimitry Andric } else {
4347ac7ddfbfSEd Maste result.AppendError("frame has no module");
4348ac7ddfbfSEd Maste error_set = true;
4349ac7ddfbfSEd Maste }
4350435933ddSDimitry Andric } else {
4351ac7ddfbfSEd Maste result.AppendError("invalid current frame");
4352ac7ddfbfSEd Maste error_set = true;
4353ac7ddfbfSEd Maste }
4354435933ddSDimitry Andric } else {
4355435933ddSDimitry Andric result.AppendErrorWithFormat("process is not stopped: %s",
4356435933ddSDimitry Andric StateAsCString(process_state));
4357ac7ddfbfSEd Maste error_set = true;
4358ac7ddfbfSEd Maste }
4359435933ddSDimitry Andric } else {
4360435933ddSDimitry Andric result.AppendError(
4361435933ddSDimitry Andric "a process must exist in order to use the --frame option");
4362ac7ddfbfSEd Maste error_set = true;
4363ac7ddfbfSEd Maste }
4364435933ddSDimitry Andric } else {
4365435933ddSDimitry Andric if (uuid_option_set) {
4366435933ddSDimitry Andric module_spec.GetUUID() =
4367435933ddSDimitry Andric m_uuid_option_group.GetOptionValue().GetCurrentValue();
4368ac7ddfbfSEd Maste success |= module_spec.GetUUID().IsValid();
4369435933ddSDimitry Andric } else if (file_option_set) {
4370435933ddSDimitry Andric module_spec.GetFileSpec() =
4371435933ddSDimitry Andric m_file_option.GetOptionValue().GetCurrentValue();
4372435933ddSDimitry Andric ModuleSP module_sp(
4373435933ddSDimitry Andric target->GetImages().FindFirstModule(module_spec));
4374435933ddSDimitry Andric if (module_sp) {
4375ac7ddfbfSEd Maste module_spec.GetFileSpec() = module_sp->GetFileSpec();
4376435933ddSDimitry Andric module_spec.GetPlatformFileSpec() =
4377435933ddSDimitry Andric module_sp->GetPlatformFileSpec();
4378ac7ddfbfSEd Maste module_spec.GetUUID() = module_sp->GetUUID();
4379ac7ddfbfSEd Maste module_spec.GetArchitecture() = module_sp->GetArchitecture();
4380435933ddSDimitry Andric } else {
4381ac7ddfbfSEd Maste module_spec.GetArchitecture() = target->GetArchitecture();
4382ac7ddfbfSEd Maste }
4383435933ddSDimitry Andric success |= module_spec.GetUUID().IsValid() ||
4384*b5893f02SDimitry Andric FileSystem::Instance().Exists(module_spec.GetFileSpec());
4385ac7ddfbfSEd Maste }
4386ac7ddfbfSEd Maste }
4387ac7ddfbfSEd Maste
4388435933ddSDimitry Andric if (success) {
4389435933ddSDimitry Andric if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4390ac7ddfbfSEd Maste if (module_spec.GetSymbolFileSpec())
4391ac7ddfbfSEd Maste success = AddModuleSymbols(target, module_spec, flush, result);
4392ac7ddfbfSEd Maste }
4393ac7ddfbfSEd Maste }
4394ac7ddfbfSEd Maste
4395435933ddSDimitry Andric if (!success && !error_set) {
4396ac7ddfbfSEd Maste StreamString error_strm;
4397435933ddSDimitry Andric if (uuid_option_set) {
4398ac7ddfbfSEd Maste error_strm.PutCString("unable to find debug symbols for UUID ");
4399ac7ddfbfSEd Maste module_spec.GetUUID().Dump(&error_strm);
4400435933ddSDimitry Andric } else if (file_option_set) {
4401435933ddSDimitry Andric error_strm.PutCString(
4402435933ddSDimitry Andric "unable to find debug symbols for the executable file ");
4403ac7ddfbfSEd Maste error_strm << module_spec.GetFileSpec();
4404435933ddSDimitry Andric } else if (frame_option_set) {
4405435933ddSDimitry Andric error_strm.PutCString(
4406435933ddSDimitry Andric "unable to find debug symbols for the current frame");
4407ac7ddfbfSEd Maste }
4408435933ddSDimitry Andric result.AppendError(error_strm.GetString());
4409ac7ddfbfSEd Maste }
4410435933ddSDimitry Andric } else {
4411435933ddSDimitry Andric result.AppendError("one or more symbol file paths must be specified, "
4412435933ddSDimitry Andric "or options must be specified");
4413ac7ddfbfSEd Maste }
4414435933ddSDimitry Andric } else {
4415435933ddSDimitry Andric if (uuid_option_set) {
4416435933ddSDimitry Andric result.AppendError("specify either one or more paths to symbol files "
4417435933ddSDimitry Andric "or use the --uuid option without arguments");
4418435933ddSDimitry Andric } else if (frame_option_set) {
4419435933ddSDimitry Andric result.AppendError("specify either one or more paths to symbol files "
4420435933ddSDimitry Andric "or use the --frame option without arguments");
4421acac075bSDimitry Andric } else if (file_option_set && argc > 1) {
4422acac075bSDimitry Andric result.AppendError("specify at most one symbol file path when "
4423acac075bSDimitry Andric "--shlib option is set");
4424435933ddSDimitry Andric } else {
4425ac7ddfbfSEd Maste PlatformSP platform_sp(target->GetPlatform());
4426ac7ddfbfSEd Maste
4427435933ddSDimitry Andric for (auto &entry : args.entries()) {
4428435933ddSDimitry Andric if (!entry.ref.empty()) {
4429*b5893f02SDimitry Andric auto &symbol_file_spec = module_spec.GetSymbolFileSpec();
4430*b5893f02SDimitry Andric symbol_file_spec.SetFile(entry.ref, FileSpec::Style::native);
4431*b5893f02SDimitry Andric FileSystem::Instance().Resolve(symbol_file_spec);
4432acac075bSDimitry Andric if (file_option_set) {
4433acac075bSDimitry Andric module_spec.GetFileSpec() =
4434acac075bSDimitry Andric m_file_option.GetOptionValue().GetCurrentValue();
4435acac075bSDimitry Andric }
4436435933ddSDimitry Andric if (platform_sp) {
4437ac7ddfbfSEd Maste FileSpec symfile_spec;
4438435933ddSDimitry Andric if (platform_sp
4439435933ddSDimitry Andric ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4440435933ddSDimitry Andric .Success())
4441ac7ddfbfSEd Maste module_spec.GetSymbolFileSpec() = symfile_spec;
4442ac7ddfbfSEd Maste }
4443ac7ddfbfSEd Maste
4444ac7ddfbfSEd Maste ArchSpec arch;
4445*b5893f02SDimitry Andric bool symfile_exists =
4446*b5893f02SDimitry Andric FileSystem::Instance().Exists(module_spec.GetSymbolFileSpec());
4447ac7ddfbfSEd Maste
4448435933ddSDimitry Andric if (symfile_exists) {
4449ac7ddfbfSEd Maste if (!AddModuleSymbols(target, module_spec, flush, result))
4450ac7ddfbfSEd Maste break;
4451435933ddSDimitry Andric } else {
4452435933ddSDimitry Andric std::string resolved_symfile_path =
4453435933ddSDimitry Andric module_spec.GetSymbolFileSpec().GetPath();
4454435933ddSDimitry Andric if (resolved_symfile_path != entry.ref) {
4455435933ddSDimitry Andric result.AppendErrorWithFormat(
4456435933ddSDimitry Andric "invalid module path '%s' with resolved path '%s'\n",
4457435933ddSDimitry Andric entry.c_str(), resolved_symfile_path.c_str());
4458ac7ddfbfSEd Maste break;
4459ac7ddfbfSEd Maste }
4460435933ddSDimitry Andric result.AppendErrorWithFormat("invalid module path '%s'\n",
4461435933ddSDimitry Andric entry.c_str());
4462ac7ddfbfSEd Maste break;
4463ac7ddfbfSEd Maste }
4464ac7ddfbfSEd Maste }
4465ac7ddfbfSEd Maste }
4466ac7ddfbfSEd Maste }
4467ac7ddfbfSEd Maste }
4468ac7ddfbfSEd Maste
4469435933ddSDimitry Andric if (flush) {
4470ac7ddfbfSEd Maste Process *process = m_exe_ctx.GetProcessPtr();
4471ac7ddfbfSEd Maste if (process)
4472ac7ddfbfSEd Maste process->Flush();
4473ac7ddfbfSEd Maste }
4474ac7ddfbfSEd Maste return result.Succeeded();
4475ac7ddfbfSEd Maste }
4476ac7ddfbfSEd Maste
4477ac7ddfbfSEd Maste OptionGroupOptions m_option_group;
4478ac7ddfbfSEd Maste OptionGroupUUID m_uuid_option_group;
4479ac7ddfbfSEd Maste OptionGroupFile m_file_option;
4480ac7ddfbfSEd Maste OptionGroupBoolean m_current_frame_option;
4481ac7ddfbfSEd Maste };
4482ac7ddfbfSEd Maste
4483ac7ddfbfSEd Maste #pragma mark CommandObjectTargetSymbols
4484ac7ddfbfSEd Maste
4485ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4486ac7ddfbfSEd Maste // CommandObjectTargetSymbols
4487ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4488ac7ddfbfSEd Maste
4489435933ddSDimitry Andric class CommandObjectTargetSymbols : public CommandObjectMultiword {
4490ac7ddfbfSEd Maste public:
4491ac7ddfbfSEd Maste //------------------------------------------------------------------
4492ac7ddfbfSEd Maste // Constructors and Destructors
4493ac7ddfbfSEd Maste //------------------------------------------------------------------
CommandObjectTargetSymbols(CommandInterpreter & interpreter)44944bb0738eSEd Maste CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4495435933ddSDimitry Andric : CommandObjectMultiword(
4496435933ddSDimitry Andric interpreter, "target symbols",
4497435933ddSDimitry Andric "Commands for adding and managing debug symbol files.",
4498435933ddSDimitry Andric "target symbols <sub-command> ...") {
4499435933ddSDimitry Andric LoadSubCommand(
4500435933ddSDimitry Andric "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4501ac7ddfbfSEd Maste }
45029f2f44ceSEd Maste
45034bb0738eSEd Maste ~CommandObjectTargetSymbols() override = default;
4504ac7ddfbfSEd Maste
4505ac7ddfbfSEd Maste private:
4506ac7ddfbfSEd Maste //------------------------------------------------------------------
4507ac7ddfbfSEd Maste // For CommandObjectTargetModules only
4508ac7ddfbfSEd Maste //------------------------------------------------------------------
4509ac7ddfbfSEd Maste DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols);
4510ac7ddfbfSEd Maste };
4511ac7ddfbfSEd Maste
4512ac7ddfbfSEd Maste #pragma mark CommandObjectTargetStopHookAdd
4513ac7ddfbfSEd Maste
4514ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4515ac7ddfbfSEd Maste // CommandObjectTargetStopHookAdd
4516ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4517ac7ddfbfSEd Maste
4518*b5893f02SDimitry Andric static constexpr OptionDefinition g_target_stop_hook_add_options[] = {
4519435933ddSDimitry Andric // clang-format off
4520*b5893f02SDimitry Andric { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeOneLiner, "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
4521*b5893f02SDimitry Andric { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the module within which the stop-hook is to be run." },
4522*b5893f02SDimitry Andric { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadIndex, "The stop hook is run only for the thread whose index matches this argument." },
4523*b5893f02SDimitry Andric { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadID, "The stop hook is run only for the thread whose TID matches this argument." },
4524*b5893f02SDimitry Andric { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeThreadName, "The stop hook is run only for the thread whose thread name matches this argument." },
4525*b5893f02SDimitry Andric { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeQueueName, "The stop hook is run only for threads in the queue whose name is given by this argument." },
4526*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the source file within which the stop-hook is to be run." },
4527*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Set the start of the line range for which the stop-hook is to be run." },
4528*b5893f02SDimitry Andric { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeLineNum, "Set the end of the line range for which the stop-hook is to be run." },
4529*b5893f02SDimitry Andric { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, nullptr, {}, 0, eArgTypeClassName, "Specify the class within which the stop-hook is to be run." },
4530*b5893f02SDimitry Andric { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, {}, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the function name within which the stop hook will be run." },
4531435933ddSDimitry Andric // clang-format on
4532435933ddSDimitry Andric };
4533435933ddSDimitry Andric
4534435933ddSDimitry Andric class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4535435933ddSDimitry Andric public IOHandlerDelegateMultiline {
4536ac7ddfbfSEd Maste public:
4537435933ddSDimitry Andric class CommandOptions : public Options {
4538ac7ddfbfSEd Maste public:
CommandOptions()4539435933ddSDimitry Andric CommandOptions()
4540435933ddSDimitry Andric : Options(), m_line_start(0), m_line_end(UINT_MAX),
4541ac7ddfbfSEd Maste m_func_name_type_mask(eFunctionNameTypeAuto),
4542435933ddSDimitry Andric m_sym_ctx_specified(false), m_thread_specified(false),
4543435933ddSDimitry Andric m_use_one_liner(false), m_one_liner() {}
4544ac7ddfbfSEd Maste
45454bb0738eSEd Maste ~CommandOptions() override = default;
4546ac7ddfbfSEd Maste
GetDefinitions()4547435933ddSDimitry Andric llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
4548435933ddSDimitry Andric return llvm::makeArrayRef(g_target_stop_hook_add_options);
4549ac7ddfbfSEd Maste }
4550ac7ddfbfSEd Maste
SetOptionValue(uint32_t option_idx,llvm::StringRef option_arg,ExecutionContext * execution_context)45515517e702SDimitry Andric Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
4552435933ddSDimitry Andric ExecutionContext *execution_context) override {
45535517e702SDimitry Andric Status error;
4554ac7ddfbfSEd Maste const int short_option = m_getopt_table[option_idx].val;
4555ac7ddfbfSEd Maste
4556435933ddSDimitry Andric switch (short_option) {
4557ac7ddfbfSEd Maste case 'c':
4558ac7ddfbfSEd Maste m_class_name = option_arg;
4559ac7ddfbfSEd Maste m_sym_ctx_specified = true;
4560ac7ddfbfSEd Maste break;
4561ac7ddfbfSEd Maste
4562ac7ddfbfSEd Maste case 'e':
4563435933ddSDimitry Andric if (option_arg.getAsInteger(0, m_line_end)) {
4564435933ddSDimitry Andric error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4565435933ddSDimitry Andric option_arg.str().c_str());
4566ac7ddfbfSEd Maste break;
4567ac7ddfbfSEd Maste }
4568ac7ddfbfSEd Maste m_sym_ctx_specified = true;
4569ac7ddfbfSEd Maste break;
4570ac7ddfbfSEd Maste
4571ac7ddfbfSEd Maste case 'l':
4572435933ddSDimitry Andric if (option_arg.getAsInteger(0, m_line_start)) {
4573435933ddSDimitry Andric error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4574435933ddSDimitry Andric option_arg.str().c_str());
4575ac7ddfbfSEd Maste break;
4576ac7ddfbfSEd Maste }
4577ac7ddfbfSEd Maste m_sym_ctx_specified = true;
4578ac7ddfbfSEd Maste break;
4579ac7ddfbfSEd Maste
4580ac7ddfbfSEd Maste case 'i':
4581ac7ddfbfSEd Maste m_no_inlines = true;
4582ac7ddfbfSEd Maste break;
4583ac7ddfbfSEd Maste
4584ac7ddfbfSEd Maste case 'n':
4585ac7ddfbfSEd Maste m_function_name = option_arg;
4586ac7ddfbfSEd Maste m_func_name_type_mask |= eFunctionNameTypeAuto;
4587ac7ddfbfSEd Maste m_sym_ctx_specified = true;
4588ac7ddfbfSEd Maste break;
4589ac7ddfbfSEd Maste
4590ac7ddfbfSEd Maste case 'f':
4591ac7ddfbfSEd Maste m_file_name = option_arg;
4592ac7ddfbfSEd Maste m_sym_ctx_specified = true;
4593ac7ddfbfSEd Maste break;
45944bb0738eSEd Maste
4595ac7ddfbfSEd Maste case 's':
4596ac7ddfbfSEd Maste m_module_name = option_arg;
4597ac7ddfbfSEd Maste m_sym_ctx_specified = true;
4598ac7ddfbfSEd Maste break;
45994bb0738eSEd Maste
4600ac7ddfbfSEd Maste case 't':
4601435933ddSDimitry Andric if (option_arg.getAsInteger(0, m_thread_id))
4602435933ddSDimitry Andric error.SetErrorStringWithFormat("invalid thread id string '%s'",
4603435933ddSDimitry Andric option_arg.str().c_str());
4604ac7ddfbfSEd Maste m_thread_specified = true;
4605ac7ddfbfSEd Maste break;
46064bb0738eSEd Maste
4607ac7ddfbfSEd Maste case 'T':
4608ac7ddfbfSEd Maste m_thread_name = option_arg;
4609ac7ddfbfSEd Maste m_thread_specified = true;
4610ac7ddfbfSEd Maste break;
46114bb0738eSEd Maste
4612ac7ddfbfSEd Maste case 'q':
4613ac7ddfbfSEd Maste m_queue_name = option_arg;
4614ac7ddfbfSEd Maste m_thread_specified = true;
4615ac7ddfbfSEd Maste break;
46164bb0738eSEd Maste
4617ac7ddfbfSEd Maste case 'x':
4618435933ddSDimitry Andric if (option_arg.getAsInteger(0, m_thread_index))
4619435933ddSDimitry Andric error.SetErrorStringWithFormat("invalid thread index string '%s'",
4620435933ddSDimitry Andric option_arg.str().c_str());
4621ac7ddfbfSEd Maste m_thread_specified = true;
4622ac7ddfbfSEd Maste break;
46234bb0738eSEd Maste
4624ac7ddfbfSEd Maste case 'o':
4625ac7ddfbfSEd Maste m_use_one_liner = true;
4626ac7ddfbfSEd Maste m_one_liner = option_arg;
4627ac7ddfbfSEd Maste break;
46284bb0738eSEd Maste
4629ac7ddfbfSEd Maste default:
4630ac7ddfbfSEd Maste error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
4631ac7ddfbfSEd Maste break;
4632ac7ddfbfSEd Maste }
4633ac7ddfbfSEd Maste return error;
4634ac7ddfbfSEd Maste }
4635ac7ddfbfSEd Maste
OptionParsingStarting(ExecutionContext * execution_context)4636435933ddSDimitry Andric void OptionParsingStarting(ExecutionContext *execution_context) override {
4637ac7ddfbfSEd Maste m_class_name.clear();
4638ac7ddfbfSEd Maste m_function_name.clear();
4639ac7ddfbfSEd Maste m_line_start = 0;
4640ac7ddfbfSEd Maste m_line_end = UINT_MAX;
4641ac7ddfbfSEd Maste m_file_name.clear();
4642ac7ddfbfSEd Maste m_module_name.clear();
4643ac7ddfbfSEd Maste m_func_name_type_mask = eFunctionNameTypeAuto;
4644ac7ddfbfSEd Maste m_thread_id = LLDB_INVALID_THREAD_ID;
4645ac7ddfbfSEd Maste m_thread_index = UINT32_MAX;
4646ac7ddfbfSEd Maste m_thread_name.clear();
4647ac7ddfbfSEd Maste m_queue_name.clear();
4648ac7ddfbfSEd Maste
4649ac7ddfbfSEd Maste m_no_inlines = false;
4650ac7ddfbfSEd Maste m_sym_ctx_specified = false;
4651ac7ddfbfSEd Maste m_thread_specified = false;
4652ac7ddfbfSEd Maste
4653ac7ddfbfSEd Maste m_use_one_liner = false;
4654ac7ddfbfSEd Maste m_one_liner.clear();
4655ac7ddfbfSEd Maste }
4656ac7ddfbfSEd Maste
4657ac7ddfbfSEd Maste std::string m_class_name;
4658ac7ddfbfSEd Maste std::string m_function_name;
4659ac7ddfbfSEd Maste uint32_t m_line_start;
4660ac7ddfbfSEd Maste uint32_t m_line_end;
4661ac7ddfbfSEd Maste std::string m_file_name;
4662ac7ddfbfSEd Maste std::string m_module_name;
4663ac7ddfbfSEd Maste uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
4664ac7ddfbfSEd Maste lldb::tid_t m_thread_id;
4665ac7ddfbfSEd Maste uint32_t m_thread_index;
4666ac7ddfbfSEd Maste std::string m_thread_name;
4667ac7ddfbfSEd Maste std::string m_queue_name;
4668ac7ddfbfSEd Maste bool m_sym_ctx_specified;
4669ac7ddfbfSEd Maste bool m_no_inlines;
4670ac7ddfbfSEd Maste bool m_thread_specified;
4671ac7ddfbfSEd Maste // Instance variables to hold the values for one_liner options.
4672ac7ddfbfSEd Maste bool m_use_one_liner;
4673ac7ddfbfSEd Maste std::string m_one_liner;
4674ac7ddfbfSEd Maste };
4675ac7ddfbfSEd Maste
CommandObjectTargetStopHookAdd(CommandInterpreter & interpreter)4676435933ddSDimitry Andric CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4677435933ddSDimitry Andric : CommandObjectParsed(interpreter, "target stop-hook add",
4678ac7ddfbfSEd Maste "Add a hook to be executed when the target stops.",
4679ac7ddfbfSEd Maste "target stop-hook add"),
4680435933ddSDimitry Andric IOHandlerDelegateMultiline("DONE",
4681435933ddSDimitry Andric IOHandlerDelegate::Completion::LLDBCommand),
4682435933ddSDimitry Andric m_options() {}
4683ac7ddfbfSEd Maste
46844bb0738eSEd Maste ~CommandObjectTargetStopHookAdd() override = default;
46854bb0738eSEd Maste
GetOptions()4686435933ddSDimitry Andric Options *GetOptions() override { return &m_options; }
4687ac7ddfbfSEd Maste
4688ac7ddfbfSEd Maste protected:
IOHandlerActivated(IOHandler & io_handler)4689435933ddSDimitry Andric void IOHandlerActivated(IOHandler &io_handler) override {
469012b93ac6SEd Maste StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4691435933ddSDimitry Andric if (output_sp) {
4692435933ddSDimitry Andric output_sp->PutCString(
4693435933ddSDimitry Andric "Enter your stop hook command(s). Type 'DONE' to end.\n");
469412b93ac6SEd Maste output_sp->Flush();
469512b93ac6SEd Maste }
469612b93ac6SEd Maste }
469712b93ac6SEd Maste
IOHandlerInputComplete(IOHandler & io_handler,std::string & line)4698435933ddSDimitry Andric void IOHandlerInputComplete(IOHandler &io_handler,
4699435933ddSDimitry Andric std::string &line) override {
4700435933ddSDimitry Andric if (m_stop_hook_sp) {
4701435933ddSDimitry Andric if (line.empty()) {
470212b93ac6SEd Maste StreamFileSP error_sp(io_handler.GetErrorStreamFile());
4703435933ddSDimitry Andric if (error_sp) {
4704435933ddSDimitry Andric error_sp->Printf("error: stop hook #%" PRIu64
4705435933ddSDimitry Andric " aborted, no commands.\n",
4706435933ddSDimitry Andric m_stop_hook_sp->GetID());
470712b93ac6SEd Maste error_sp->Flush();
470812b93ac6SEd Maste }
470912b93ac6SEd Maste Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
471012b93ac6SEd Maste if (target)
471112b93ac6SEd Maste target->RemoveStopHookByID(m_stop_hook_sp->GetID());
4712435933ddSDimitry Andric } else {
471312b93ac6SEd Maste m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
471412b93ac6SEd Maste StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4715435933ddSDimitry Andric if (output_sp) {
4716435933ddSDimitry Andric output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4717435933ddSDimitry Andric m_stop_hook_sp->GetID());
471812b93ac6SEd Maste output_sp->Flush();
471912b93ac6SEd Maste }
472012b93ac6SEd Maste }
472112b93ac6SEd Maste m_stop_hook_sp.reset();
472212b93ac6SEd Maste }
472312b93ac6SEd Maste io_handler.SetIsDone(true);
472412b93ac6SEd Maste }
472512b93ac6SEd Maste
DoExecute(Args & command,CommandReturnObject & result)4726435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
472712b93ac6SEd Maste m_stop_hook_sp.reset();
472812b93ac6SEd Maste
47297aa51b79SEd Maste Target *target = GetSelectedOrDummyTarget();
4730435933ddSDimitry Andric if (target) {
473112b93ac6SEd Maste Target::StopHookSP new_hook_sp = target->CreateStopHook();
4732ac7ddfbfSEd Maste
4733ac7ddfbfSEd Maste // First step, make the specifier.
4734ac7ddfbfSEd Maste std::unique_ptr<SymbolContextSpecifier> specifier_ap;
4735435933ddSDimitry Andric if (m_options.m_sym_ctx_specified) {
4736435933ddSDimitry Andric specifier_ap.reset(new SymbolContextSpecifier(
4737435933ddSDimitry Andric m_interpreter.GetDebugger().GetSelectedTarget()));
4738ac7ddfbfSEd Maste
4739435933ddSDimitry Andric if (!m_options.m_module_name.empty()) {
4740435933ddSDimitry Andric specifier_ap->AddSpecification(
4741435933ddSDimitry Andric m_options.m_module_name.c_str(),
4742435933ddSDimitry Andric SymbolContextSpecifier::eModuleSpecified);
4743ac7ddfbfSEd Maste }
4744ac7ddfbfSEd Maste
4745435933ddSDimitry Andric if (!m_options.m_class_name.empty()) {
4746435933ddSDimitry Andric specifier_ap->AddSpecification(
4747435933ddSDimitry Andric m_options.m_class_name.c_str(),
4748435933ddSDimitry Andric SymbolContextSpecifier::eClassOrNamespaceSpecified);
4749ac7ddfbfSEd Maste }
4750ac7ddfbfSEd Maste
4751435933ddSDimitry Andric if (!m_options.m_file_name.empty()) {
4752435933ddSDimitry Andric specifier_ap->AddSpecification(
4753435933ddSDimitry Andric m_options.m_file_name.c_str(),
4754435933ddSDimitry Andric SymbolContextSpecifier::eFileSpecified);
4755ac7ddfbfSEd Maste }
4756ac7ddfbfSEd Maste
4757435933ddSDimitry Andric if (m_options.m_line_start != 0) {
4758435933ddSDimitry Andric specifier_ap->AddLineSpecification(
4759435933ddSDimitry Andric m_options.m_line_start,
4760435933ddSDimitry Andric SymbolContextSpecifier::eLineStartSpecified);
4761ac7ddfbfSEd Maste }
4762ac7ddfbfSEd Maste
4763435933ddSDimitry Andric if (m_options.m_line_end != UINT_MAX) {
4764435933ddSDimitry Andric specifier_ap->AddLineSpecification(
4765435933ddSDimitry Andric m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4766ac7ddfbfSEd Maste }
4767ac7ddfbfSEd Maste
4768435933ddSDimitry Andric if (!m_options.m_function_name.empty()) {
4769435933ddSDimitry Andric specifier_ap->AddSpecification(
4770435933ddSDimitry Andric m_options.m_function_name.c_str(),
4771435933ddSDimitry Andric SymbolContextSpecifier::eFunctionSpecified);
4772ac7ddfbfSEd Maste }
4773ac7ddfbfSEd Maste }
4774ac7ddfbfSEd Maste
47754bb0738eSEd Maste if (specifier_ap)
4776ac7ddfbfSEd Maste new_hook_sp->SetSpecifier(specifier_ap.release());
4777ac7ddfbfSEd Maste
4778ac7ddfbfSEd Maste // Next see if any of the thread options have been entered:
4779ac7ddfbfSEd Maste
4780435933ddSDimitry Andric if (m_options.m_thread_specified) {
4781ac7ddfbfSEd Maste ThreadSpec *thread_spec = new ThreadSpec();
4782ac7ddfbfSEd Maste
4783435933ddSDimitry Andric if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4784ac7ddfbfSEd Maste thread_spec->SetTID(m_options.m_thread_id);
4785ac7ddfbfSEd Maste }
4786ac7ddfbfSEd Maste
4787ac7ddfbfSEd Maste if (m_options.m_thread_index != UINT32_MAX)
4788ac7ddfbfSEd Maste thread_spec->SetIndex(m_options.m_thread_index);
4789ac7ddfbfSEd Maste
4790ac7ddfbfSEd Maste if (!m_options.m_thread_name.empty())
4791ac7ddfbfSEd Maste thread_spec->SetName(m_options.m_thread_name.c_str());
4792ac7ddfbfSEd Maste
4793ac7ddfbfSEd Maste if (!m_options.m_queue_name.empty())
4794ac7ddfbfSEd Maste thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4795ac7ddfbfSEd Maste
4796ac7ddfbfSEd Maste new_hook_sp->SetThreadSpecifier(thread_spec);
4797ac7ddfbfSEd Maste }
4798435933ddSDimitry Andric if (m_options.m_use_one_liner) {
4799ac7ddfbfSEd Maste // Use one-liner.
4800435933ddSDimitry Andric new_hook_sp->GetCommandPointer()->AppendString(
4801435933ddSDimitry Andric m_options.m_one_liner.c_str());
4802435933ddSDimitry Andric result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4803435933ddSDimitry Andric new_hook_sp->GetID());
4804435933ddSDimitry Andric } else {
480512b93ac6SEd Maste m_stop_hook_sp = new_hook_sp;
4806435933ddSDimitry Andric m_interpreter.GetLLDBCommandsFromIOHandler(
4807435933ddSDimitry Andric "> ", // Prompt
480812b93ac6SEd Maste *this, // IOHandlerDelegate
480912b93ac6SEd Maste true, // Run IOHandler in async mode
4810435933ddSDimitry Andric nullptr); // Baton for the "io_handler" that will be passed back
4811435933ddSDimitry Andric // into our IOHandlerDelegate functions
4812ac7ddfbfSEd Maste }
4813ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
4814435933ddSDimitry Andric } else {
4815ac7ddfbfSEd Maste result.AppendError("invalid target\n");
4816ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
4817ac7ddfbfSEd Maste }
4818ac7ddfbfSEd Maste
4819ac7ddfbfSEd Maste return result.Succeeded();
4820ac7ddfbfSEd Maste }
48214bb0738eSEd Maste
4822ac7ddfbfSEd Maste private:
4823ac7ddfbfSEd Maste CommandOptions m_options;
482412b93ac6SEd Maste Target::StopHookSP m_stop_hook_sp;
4825ac7ddfbfSEd Maste };
4826ac7ddfbfSEd Maste
4827ac7ddfbfSEd Maste #pragma mark CommandObjectTargetStopHookDelete
4828ac7ddfbfSEd Maste
4829ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4830ac7ddfbfSEd Maste // CommandObjectTargetStopHookDelete
4831ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4832ac7ddfbfSEd Maste
4833435933ddSDimitry Andric class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
4834ac7ddfbfSEd Maste public:
CommandObjectTargetStopHookDelete(CommandInterpreter & interpreter)4835435933ddSDimitry Andric CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4836435933ddSDimitry Andric : CommandObjectParsed(interpreter, "target stop-hook delete",
4837ac7ddfbfSEd Maste "Delete a stop-hook.",
4838435933ddSDimitry Andric "target stop-hook delete [<idx>]") {}
4839ac7ddfbfSEd Maste
48404bb0738eSEd Maste ~CommandObjectTargetStopHookDelete() override = default;
4841ac7ddfbfSEd Maste
4842ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)4843435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
48447aa51b79SEd Maste Target *target = GetSelectedOrDummyTarget();
4845435933ddSDimitry Andric if (target) {
4846ac7ddfbfSEd Maste // FIXME: see if we can use the breakpoint id style parser?
4847ac7ddfbfSEd Maste size_t num_args = command.GetArgumentCount();
4848435933ddSDimitry Andric if (num_args == 0) {
4849435933ddSDimitry Andric if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4850ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
4851ac7ddfbfSEd Maste return false;
4852435933ddSDimitry Andric } else {
4853ac7ddfbfSEd Maste target->RemoveAllStopHooks();
4854ac7ddfbfSEd Maste }
4855435933ddSDimitry Andric } else {
4856ac7ddfbfSEd Maste bool success;
4857435933ddSDimitry Andric for (size_t i = 0; i < num_args; i++) {
4858435933ddSDimitry Andric lldb::user_id_t user_id = StringConvert::ToUInt32(
4859435933ddSDimitry Andric command.GetArgumentAtIndex(i), 0, 0, &success);
4860435933ddSDimitry Andric if (!success) {
4861435933ddSDimitry Andric result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4862435933ddSDimitry Andric command.GetArgumentAtIndex(i));
4863ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
4864ac7ddfbfSEd Maste return false;
4865ac7ddfbfSEd Maste }
4866ac7ddfbfSEd Maste success = target->RemoveStopHookByID(user_id);
4867435933ddSDimitry Andric if (!success) {
4868435933ddSDimitry Andric result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4869435933ddSDimitry Andric command.GetArgumentAtIndex(i));
4870ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
4871ac7ddfbfSEd Maste return false;
4872ac7ddfbfSEd Maste }
4873ac7ddfbfSEd Maste }
4874ac7ddfbfSEd Maste }
4875ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
4876435933ddSDimitry Andric } else {
4877ac7ddfbfSEd Maste result.AppendError("invalid target\n");
4878ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
4879ac7ddfbfSEd Maste }
4880ac7ddfbfSEd Maste
4881ac7ddfbfSEd Maste return result.Succeeded();
4882ac7ddfbfSEd Maste }
4883ac7ddfbfSEd Maste };
48844bb0738eSEd Maste
4885ac7ddfbfSEd Maste #pragma mark CommandObjectTargetStopHookEnableDisable
4886ac7ddfbfSEd Maste
4887ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4888ac7ddfbfSEd Maste // CommandObjectTargetStopHookEnableDisable
4889ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4890ac7ddfbfSEd Maste
4891435933ddSDimitry Andric class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
4892ac7ddfbfSEd Maste public:
CommandObjectTargetStopHookEnableDisable(CommandInterpreter & interpreter,bool enable,const char * name,const char * help,const char * syntax)4893435933ddSDimitry Andric CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4894435933ddSDimitry Andric bool enable, const char *name,
4895435933ddSDimitry Andric const char *help, const char *syntax)
4896435933ddSDimitry Andric : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4897ac7ddfbfSEd Maste }
4898ac7ddfbfSEd Maste
48994bb0738eSEd Maste ~CommandObjectTargetStopHookEnableDisable() override = default;
4900ac7ddfbfSEd Maste
4901ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)4902435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
49037aa51b79SEd Maste Target *target = GetSelectedOrDummyTarget();
4904435933ddSDimitry Andric if (target) {
4905ac7ddfbfSEd Maste // FIXME: see if we can use the breakpoint id style parser?
4906ac7ddfbfSEd Maste size_t num_args = command.GetArgumentCount();
4907ac7ddfbfSEd Maste bool success;
4908ac7ddfbfSEd Maste
4909435933ddSDimitry Andric if (num_args == 0) {
4910ac7ddfbfSEd Maste target->SetAllStopHooksActiveState(m_enable);
4911435933ddSDimitry Andric } else {
4912435933ddSDimitry Andric for (size_t i = 0; i < num_args; i++) {
4913435933ddSDimitry Andric lldb::user_id_t user_id = StringConvert::ToUInt32(
4914435933ddSDimitry Andric command.GetArgumentAtIndex(i), 0, 0, &success);
4915435933ddSDimitry Andric if (!success) {
4916435933ddSDimitry Andric result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4917435933ddSDimitry Andric command.GetArgumentAtIndex(i));
4918ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
4919ac7ddfbfSEd Maste return false;
4920ac7ddfbfSEd Maste }
4921ac7ddfbfSEd Maste success = target->SetStopHookActiveStateByID(user_id, m_enable);
4922435933ddSDimitry Andric if (!success) {
4923435933ddSDimitry Andric result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4924435933ddSDimitry Andric command.GetArgumentAtIndex(i));
4925ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
4926ac7ddfbfSEd Maste return false;
4927ac7ddfbfSEd Maste }
4928ac7ddfbfSEd Maste }
4929ac7ddfbfSEd Maste }
4930ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishNoResult);
4931435933ddSDimitry Andric } else {
4932ac7ddfbfSEd Maste result.AppendError("invalid target\n");
4933ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
4934ac7ddfbfSEd Maste }
4935ac7ddfbfSEd Maste return result.Succeeded();
4936ac7ddfbfSEd Maste }
4937435933ddSDimitry Andric
4938ac7ddfbfSEd Maste private:
4939ac7ddfbfSEd Maste bool m_enable;
4940ac7ddfbfSEd Maste };
4941ac7ddfbfSEd Maste
4942ac7ddfbfSEd Maste #pragma mark CommandObjectTargetStopHookList
4943ac7ddfbfSEd Maste
4944ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4945ac7ddfbfSEd Maste // CommandObjectTargetStopHookList
4946ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4947ac7ddfbfSEd Maste
4948435933ddSDimitry Andric class CommandObjectTargetStopHookList : public CommandObjectParsed {
4949ac7ddfbfSEd Maste public:
CommandObjectTargetStopHookList(CommandInterpreter & interpreter)4950435933ddSDimitry Andric CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4951435933ddSDimitry Andric : CommandObjectParsed(interpreter, "target stop-hook list",
4952ac7ddfbfSEd Maste "List all stop-hooks.",
4953435933ddSDimitry Andric "target stop-hook list [<type>]") {}
4954ac7ddfbfSEd Maste
49554bb0738eSEd Maste ~CommandObjectTargetStopHookList() override = default;
4956ac7ddfbfSEd Maste
4957ac7ddfbfSEd Maste protected:
DoExecute(Args & command,CommandReturnObject & result)4958435933ddSDimitry Andric bool DoExecute(Args &command, CommandReturnObject &result) override {
49597aa51b79SEd Maste Target *target = GetSelectedOrDummyTarget();
4960435933ddSDimitry Andric if (!target) {
4961ac7ddfbfSEd Maste result.AppendError("invalid target\n");
4962ac7ddfbfSEd Maste result.SetStatus(eReturnStatusFailed);
4963ac7ddfbfSEd Maste return result.Succeeded();
4964ac7ddfbfSEd Maste }
4965ac7ddfbfSEd Maste
4966ac7ddfbfSEd Maste size_t num_hooks = target->GetNumStopHooks();
4967435933ddSDimitry Andric if (num_hooks == 0) {
4968ac7ddfbfSEd Maste result.GetOutputStream().PutCString("No stop hooks.\n");
4969435933ddSDimitry Andric } else {
4970435933ddSDimitry Andric for (size_t i = 0; i < num_hooks; i++) {
4971ac7ddfbfSEd Maste Target::StopHookSP this_hook = target->GetStopHookAtIndex(i);
4972ac7ddfbfSEd Maste if (i > 0)
4973ac7ddfbfSEd Maste result.GetOutputStream().PutCString("\n");
4974435933ddSDimitry Andric this_hook->GetDescription(&(result.GetOutputStream()),
4975435933ddSDimitry Andric eDescriptionLevelFull);
4976ac7ddfbfSEd Maste }
4977ac7ddfbfSEd Maste }
4978ac7ddfbfSEd Maste result.SetStatus(eReturnStatusSuccessFinishResult);
4979ac7ddfbfSEd Maste return result.Succeeded();
4980ac7ddfbfSEd Maste }
4981ac7ddfbfSEd Maste };
4982ac7ddfbfSEd Maste
4983ac7ddfbfSEd Maste #pragma mark CommandObjectMultiwordTargetStopHooks
49844bb0738eSEd Maste
4985ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4986ac7ddfbfSEd Maste // CommandObjectMultiwordTargetStopHooks
4987ac7ddfbfSEd Maste //-------------------------------------------------------------------------
4988ac7ddfbfSEd Maste
4989435933ddSDimitry Andric class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
4990ac7ddfbfSEd Maste public:
CommandObjectMultiwordTargetStopHooks(CommandInterpreter & interpreter)49914bb0738eSEd Maste CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4992435933ddSDimitry Andric : CommandObjectMultiword(
4993435933ddSDimitry Andric interpreter, "target stop-hook",
49944bb0738eSEd Maste "Commands for operating on debugger target stop-hooks.",
4995435933ddSDimitry Andric "target stop-hook <subcommand> [<subcommand-options>]") {
4996435933ddSDimitry Andric LoadSubCommand("add", CommandObjectSP(
4997435933ddSDimitry Andric new CommandObjectTargetStopHookAdd(interpreter)));
4998435933ddSDimitry Andric LoadSubCommand(
4999435933ddSDimitry Andric "delete",
5000435933ddSDimitry Andric CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
5001435933ddSDimitry Andric LoadSubCommand("disable",
5002435933ddSDimitry Andric CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
5003435933ddSDimitry Andric interpreter, false, "target stop-hook disable [<id>]",
5004435933ddSDimitry Andric "Disable a stop-hook.", "target stop-hook disable")));
5005435933ddSDimitry Andric LoadSubCommand("enable",
5006435933ddSDimitry Andric CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
5007435933ddSDimitry Andric interpreter, true, "target stop-hook enable [<id>]",
5008435933ddSDimitry Andric "Enable a stop-hook.", "target stop-hook enable")));
5009435933ddSDimitry Andric LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
5010435933ddSDimitry Andric interpreter)));
5011ac7ddfbfSEd Maste }
5012ac7ddfbfSEd Maste
50134bb0738eSEd Maste ~CommandObjectMultiwordTargetStopHooks() override = default;
5014ac7ddfbfSEd Maste };
5015ac7ddfbfSEd Maste
5016ac7ddfbfSEd Maste #pragma mark CommandObjectMultiwordTarget
5017ac7ddfbfSEd Maste
5018ac7ddfbfSEd Maste //-------------------------------------------------------------------------
5019ac7ddfbfSEd Maste // CommandObjectMultiwordTarget
5020ac7ddfbfSEd Maste //-------------------------------------------------------------------------
5021ac7ddfbfSEd Maste
CommandObjectMultiwordTarget(CommandInterpreter & interpreter)5022435933ddSDimitry Andric CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
5023435933ddSDimitry Andric CommandInterpreter &interpreter)
5024435933ddSDimitry Andric : CommandObjectMultiword(interpreter, "target",
5025435933ddSDimitry Andric "Commands for operating on debugger targets.",
5026435933ddSDimitry Andric "target <subcommand> [<subcommand-options>]") {
5027435933ddSDimitry Andric LoadSubCommand("create",
5028435933ddSDimitry Andric CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
5029435933ddSDimitry Andric LoadSubCommand("delete",
5030435933ddSDimitry Andric CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
5031435933ddSDimitry Andric LoadSubCommand("list",
5032435933ddSDimitry Andric CommandObjectSP(new CommandObjectTargetList(interpreter)));
5033435933ddSDimitry Andric LoadSubCommand("select",
5034435933ddSDimitry Andric CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
5035435933ddSDimitry Andric LoadSubCommand(
5036435933ddSDimitry Andric "stop-hook",
5037435933ddSDimitry Andric CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
5038435933ddSDimitry Andric LoadSubCommand("modules",
5039435933ddSDimitry Andric CommandObjectSP(new CommandObjectTargetModules(interpreter)));
5040435933ddSDimitry Andric LoadSubCommand("symbols",
5041435933ddSDimitry Andric CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
5042435933ddSDimitry Andric LoadSubCommand("variable",
5043435933ddSDimitry Andric CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
5044ac7ddfbfSEd Maste }
5045ac7ddfbfSEd Maste
50464bb0738eSEd Maste CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;
5047