blob: 8e1e667896991e382107c42b060753fd519aa309 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectTarget.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000013#include "lldb/Core/Debugger.h"
Greg Clayton44d93782014-01-27 23:43:24 +000014#include "lldb/Core/IOHandler.h"
Greg Clayton1f746072012-08-29 21:13:06 +000015#include "lldb/Core/Module.h"
16#include "lldb/Core/ModuleSpec.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000017#include "lldb/Core/Section.h"
Greg Clayton7260f622011-04-18 08:33:37 +000018#include "lldb/Core/State.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Core/Timer.h"
Greg Clayton644247c2011-07-07 01:59:51 +000020#include "lldb/Core/ValueObjectVariable.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000021#include "lldb/DataFormatters/ValueObjectPrinter.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000022#include "lldb/Host/StringConvert.h"
Greg Claytonc8f814d2012-09-27 03:13:55 +000023#include "lldb/Host/Symbols.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000024#include "lldb/Interpreter/Args.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Interpreter/CommandInterpreter.h"
26#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton7260f622011-04-18 08:33:37 +000027#include "lldb/Interpreter/OptionGroupArchitecture.h"
Greg Claytonaa149cb2011-08-11 02:48:45 +000028#include "lldb/Interpreter/OptionGroupBoolean.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000029#include "lldb/Interpreter/OptionGroupFile.h"
Greg Clayton1deb7962011-10-25 06:44:01 +000030#include "lldb/Interpreter/OptionGroupFormat.h"
Greg Clayton7260f622011-04-18 08:33:37 +000031#include "lldb/Interpreter/OptionGroupPlatform.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000032#include "lldb/Interpreter/OptionGroupString.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000033#include "lldb/Interpreter/OptionGroupUInt64.h"
34#include "lldb/Interpreter/OptionGroupUUID.h"
Greg Clayton644247c2011-07-07 01:59:51 +000035#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000036#include "lldb/Interpreter/OptionGroupVariable.h"
37#include "lldb/Interpreter/Options.h"
Greg Clayton1f746072012-08-29 21:13:06 +000038#include "lldb/Symbol/CompileUnit.h"
Jason Molenda380241a2012-07-12 00:20:07 +000039#include "lldb/Symbol/FuncUnwinders.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000040#include "lldb/Symbol/LineTable.h"
41#include "lldb/Symbol/ObjectFile.h"
42#include "lldb/Symbol/SymbolFile.h"
43#include "lldb/Symbol/SymbolVendor.h"
Jason Molenda380241a2012-07-12 00:20:07 +000044#include "lldb/Symbol/UnwindPlan.h"
Greg Clayton644247c2011-07-07 01:59:51 +000045#include "lldb/Symbol/VariableList.h"
Zachary Turner32abc6e2015-03-03 19:23:09 +000046#include "lldb/Target/ABI.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047#include "lldb/Target/Process.h"
Greg Claytond5944cd2013-12-06 01:12:00 +000048#include "lldb/Target/SectionLoadList.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000049#include "lldb/Target/StackFrame.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050#include "lldb/Target/Thread.h"
Jim Ingham9575d842011-03-11 03:53:59 +000051#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052
Pavel Labath7e2cfbf2016-11-09 09:59:18 +000053// C Includes
54// C++ Includes
55#include <cerrno>
56
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057using namespace lldb;
58using namespace lldb_private;
59
Kate Stoneb9c1b512016-09-06 20:57:50 +000060static void DumpTargetInfo(uint32_t target_idx, Target *target,
61 const char *prefix_cstr,
62 bool show_stopped_process_status, Stream &strm) {
63 const ArchSpec &target_arch = target->GetArchitecture();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000064
Kate Stoneb9c1b512016-09-06 20:57:50 +000065 Module *exe_module = target->GetExecutableModulePointer();
66 char exe_path[PATH_MAX];
67 bool exe_valid = false;
68 if (exe_module)
69 exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000070
Kate Stoneb9c1b512016-09-06 20:57:50 +000071 if (!exe_valid)
72 ::strcpy(exe_path, "<none>");
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000073
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
75 exe_path);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000076
Kate Stoneb9c1b512016-09-06 20:57:50 +000077 uint32_t properties = 0;
78 if (target_arch.IsValid()) {
79 strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
80 target_arch.DumpTriple(strm);
81 properties++;
82 }
83 PlatformSP platform_sp(target->GetPlatform());
84 if (platform_sp)
85 strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ",
86 platform_sp->GetName().GetCString());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000087
Kate Stoneb9c1b512016-09-06 20:57:50 +000088 ProcessSP process_sp(target->GetProcessSP());
89 bool show_process_status = false;
90 if (process_sp) {
91 lldb::pid_t pid = process_sp->GetID();
92 StateType state = process_sp->GetState();
93 if (show_stopped_process_status)
94 show_process_status = StateIsStoppedState(state, true);
95 const char *state_cstr = StateAsCString(state);
96 if (pid != LLDB_INVALID_PROCESS_ID)
97 strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
98 strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
99 }
100 if (properties > 0)
101 strm.PutCString(" )\n");
102 else
103 strm.EOL();
104 if (show_process_status) {
105 const bool only_threads_with_stop_reason = true;
106 const uint32_t start_frame = 0;
107 const uint32_t num_frames = 1;
108 const uint32_t num_frames_with_source = 1;
Jim Ingham6a9767c2016-11-08 20:36:40 +0000109 const bool stop_format = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110 process_sp->GetStatus(strm);
111 process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
112 start_frame, num_frames,
Jim Ingham6a9767c2016-11-08 20:36:40 +0000113 num_frames_with_source, stop_format);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114 }
Greg Clayton7260f622011-04-18 08:33:37 +0000115}
116
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117static uint32_t DumpTargetList(TargetList &target_list,
118 bool show_stopped_process_status, Stream &strm) {
119 const uint32_t num_targets = target_list.GetNumTargets();
120 if (num_targets) {
121 TargetSP selected_target_sp(target_list.GetSelectedTarget());
122 strm.PutCString("Current targets:\n");
123 for (uint32_t i = 0; i < num_targets; ++i) {
124 TargetSP target_sp(target_list.GetTargetAtIndex(i));
125 if (target_sp) {
126 bool is_selected = target_sp.get() == selected_target_sp.get();
127 DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
128 show_stopped_process_status, strm);
129 }
Greg Clayton7260f622011-04-18 08:33:37 +0000130 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131 }
132 return num_targets;
Greg Clayton7260f622011-04-18 08:33:37 +0000133}
Eugene Zelenkof13e6522016-02-25 19:02:39 +0000134
Greg Clayton7260f622011-04-18 08:33:37 +0000135#pragma mark CommandObjectTargetCreate
136
137//-------------------------------------------------------------------------
138// "target create"
139//-------------------------------------------------------------------------
140
Kate Stoneb9c1b512016-09-06 20:57:50 +0000141class CommandObjectTargetCreate : public CommandObjectParsed {
Greg Clayton7260f622011-04-18 08:33:37 +0000142public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143 CommandObjectTargetCreate(CommandInterpreter &interpreter)
144 : CommandObjectParsed(
145 interpreter, "target create",
146 "Create a target using the argument as the main executable.",
147 nullptr),
148 m_option_group(), m_arch_option(),
149 m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
150 "Fullpath to a core file to use for this target."),
151 m_platform_path(LLDB_OPT_SET_1, false, "platform-path", 'P', 0,
152 eArgTypePath,
153 "Path to the remote file to use for this target."),
154 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
155 eArgTypeFilename, "Fullpath to a stand alone debug "
156 "symbols file for when debug symbols "
157 "are not in the executable."),
158 m_remote_file(
159 LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
160 "Fullpath to the file on the remote host if debugging remotely."),
161 m_add_dependents(LLDB_OPT_SET_1, false, "no-dependents", 'd',
162 "Don't load dependent files when creating the target, "
163 "just add the specified executable.",
164 true, true) {
165 CommandArgumentEntry arg;
166 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000167
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168 // Define the first (and only) variant of this arg.
169 file_arg.arg_type = eArgTypeFilename;
170 file_arg.arg_repetition = eArgRepeatPlain;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000171
Kate Stoneb9c1b512016-09-06 20:57:50 +0000172 // There is only one variant this argument could be; put it into the
173 // argument entry.
174 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000175
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176 // Push the data for the first argument into the m_arguments vector.
177 m_arguments.push_back(arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000178
Kate Stoneb9c1b512016-09-06 20:57:50 +0000179 m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
180 m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
181 m_option_group.Append(&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
182 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
183 m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
184 m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
185 m_option_group.Finalize();
186 }
Greg Clayton7260f622011-04-18 08:33:37 +0000187
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 ~CommandObjectTargetCreate() override = default;
Greg Clayton7260f622011-04-18 08:33:37 +0000189
Kate Stoneb9c1b512016-09-06 20:57:50 +0000190 Options *GetOptions() override { return &m_option_group; }
Greg Clayton7260f622011-04-18 08:33:37 +0000191
Kate Stoneb9c1b512016-09-06 20:57:50 +0000192 int HandleArgumentCompletion(Args &input, int &cursor_index,
193 int &cursor_char_position,
194 OptionElementVector &opt_element_vector,
195 int match_start_point, int max_return_elements,
196 bool &word_complete,
197 StringList &matches) override {
198 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
199 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000200
Kate Stoneb9c1b512016-09-06 20:57:50 +0000201 CommandCompletions::InvokeCommonCompletionCallbacks(
202 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
203 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
204 word_complete, matches);
205 return matches.GetSize();
206 }
Jim Ingham5a988412012-06-08 21:56:10 +0000207
208protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209 bool DoExecute(Args &command, CommandReturnObject &result) override {
210 const size_t argc = command.GetArgumentCount();
211 FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
212 FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
Greg Claytonc3776bf2012-02-09 06:16:32 +0000213
Kate Stoneb9c1b512016-09-06 20:57:50 +0000214 if (core_file) {
215 if (!core_file.Exists()) {
216 result.AppendErrorWithFormat("core file '%s' doesn't exist",
217 core_file.GetPath().c_str());
218 result.SetStatus(eReturnStatusFailed);
219 return false;
220 }
221 if (!core_file.Readable()) {
222 result.AppendErrorWithFormat("core file '%s' is not readable",
223 core_file.GetPath().c_str());
224 result.SetStatus(eReturnStatusFailed);
225 return false;
226 }
Greg Clayton7260f622011-04-18 08:33:37 +0000227 }
228
Kate Stoneb9c1b512016-09-06 20:57:50 +0000229 if (argc == 1 || core_file || remote_file) {
230 FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
231 if (symfile) {
232 if (symfile.Exists()) {
233 if (!symfile.Readable()) {
234 result.AppendErrorWithFormat("symbol file '%s' is not readable",
235 symfile.GetPath().c_str());
236 result.SetStatus(eReturnStatusFailed);
237 return false;
238 }
239 } else {
240 char symfile_path[PATH_MAX];
241 symfile.GetPath(symfile_path, sizeof(symfile_path));
242 result.AppendErrorWithFormat("invalid symbol file path '%s'",
243 symfile_path);
244 result.SetStatus(eReturnStatusFailed);
245 return false;
246 }
247 }
248
249 const char *file_path = command.GetArgumentAtIndex(0);
250 Timer scoped_timer(LLVM_PRETTY_FUNCTION, "(lldb) target create '%s'",
251 file_path);
252 FileSpec file_spec;
253
254 if (file_path)
255 file_spec.SetFile(file_path, true);
256
257 bool must_set_platform_path = false;
258
259 Debugger &debugger = m_interpreter.GetDebugger();
260
261 TargetSP target_sp;
262 const char *arch_cstr = m_arch_option.GetArchitectureName();
263 const bool get_dependent_files =
264 m_add_dependents.GetOptionValue().GetCurrentValue();
265 Error error(debugger.GetTargetList().CreateTarget(
266 debugger, file_path, arch_cstr, get_dependent_files, nullptr,
267 target_sp));
268
269 if (target_sp) {
270 // Only get the platform after we create the target because we might
271 // have
272 // switched platforms depending on what the arguments were to
273 // CreateTarget()
274 // we can't rely on the selected platform.
275
276 PlatformSP platform_sp = target_sp->GetPlatform();
277
278 if (remote_file) {
279 if (platform_sp) {
280 // I have a remote file.. two possible cases
281 if (file_spec && file_spec.Exists()) {
282 // if the remote file does not exist, push it there
283 if (!platform_sp->GetFileExists(remote_file)) {
284 Error err = platform_sp->PutFile(file_spec, remote_file);
285 if (err.Fail()) {
286 result.AppendError(err.AsCString());
287 result.SetStatus(eReturnStatusFailed);
288 return false;
289 }
290 }
291 } else {
292 // there is no local file and we need one
293 // in order to make the remote ---> local transfer we need a
294 // platform
295 // TODO: if the user has passed in a --platform argument, use it
296 // to fetch the right platform
297 if (!platform_sp) {
298 result.AppendError(
299 "unable to perform remote debugging without a platform");
300 result.SetStatus(eReturnStatusFailed);
301 return false;
302 }
303 if (file_path) {
304 // copy the remote file to the local file
305 Error err = platform_sp->GetFile(remote_file, file_spec);
306 if (err.Fail()) {
307 result.AppendError(err.AsCString());
308 result.SetStatus(eReturnStatusFailed);
309 return false;
310 }
311 } else {
312 // make up a local file
313 result.AppendError("remote --> local transfer without local "
314 "path is not implemented yet");
315 result.SetStatus(eReturnStatusFailed);
316 return false;
317 }
318 }
319 } else {
320 result.AppendError("no platform found for target");
321 result.SetStatus(eReturnStatusFailed);
322 return false;
323 }
324 }
325
326 if (symfile || remote_file) {
327 ModuleSP module_sp(target_sp->GetExecutableModule());
328 if (module_sp) {
329 if (symfile)
330 module_sp->SetSymbolFileFileSpec(symfile);
331 if (remote_file) {
332 std::string remote_path = remote_file.GetPath();
333 target_sp->SetArg0(remote_path.c_str());
334 module_sp->SetPlatformFileSpec(remote_file);
335 }
336 }
337 }
338
339 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
340 if (must_set_platform_path) {
341 ModuleSpec main_module_spec(file_spec);
342 ModuleSP module_sp = target_sp->GetSharedModule(main_module_spec);
343 if (module_sp)
344 module_sp->SetPlatformFileSpec(remote_file);
345 }
346 if (core_file) {
347 char core_path[PATH_MAX];
348 core_file.GetPath(core_path, sizeof(core_path));
349 if (core_file.Exists()) {
350 if (!core_file.Readable()) {
351 result.AppendMessageWithFormat(
352 "Core file '%s' is not readable.\n", core_path);
353 result.SetStatus(eReturnStatusFailed);
354 return false;
355 }
356 FileSpec core_file_dir;
357 core_file_dir.GetDirectory() = core_file.GetDirectory();
358 target_sp->GetExecutableSearchPaths().Append(core_file_dir);
359
360 ProcessSP process_sp(target_sp->CreateProcess(
361 m_interpreter.GetDebugger().GetListener(), nullptr,
362 &core_file));
363
364 if (process_sp) {
365 // Seems weird that we Launch a core file, but that is
366 // what we do!
367 error = process_sp->LoadCore();
368
369 if (error.Fail()) {
370 result.AppendError(
371 error.AsCString("can't find plug-in for core file"));
372 result.SetStatus(eReturnStatusFailed);
373 return false;
374 } else {
375 result.AppendMessageWithFormat(
376 "Core file '%s' (%s) was loaded.\n", core_path,
377 target_sp->GetArchitecture().GetArchitectureName());
378 result.SetStatus(eReturnStatusSuccessFinishNoResult);
379 }
380 } else {
381 result.AppendErrorWithFormat(
382 "Unable to find process plug-in for core file '%s'\n",
383 core_path);
384 result.SetStatus(eReturnStatusFailed);
385 }
386 } else {
387 result.AppendErrorWithFormat("Core file '%s' does not exist\n",
388 core_path);
389 result.SetStatus(eReturnStatusFailed);
390 }
391 } else {
392 result.AppendMessageWithFormat(
393 "Current executable set to '%s' (%s).\n", file_path,
394 target_sp->GetArchitecture().GetArchitectureName());
395 result.SetStatus(eReturnStatusSuccessFinishNoResult);
396 }
397 } else {
398 result.AppendError(error.AsCString());
399 result.SetStatus(eReturnStatusFailed);
400 }
401 } else {
402 result.AppendErrorWithFormat("'%s' takes exactly one executable path "
403 "argument, or use the --core option.\n",
404 m_cmd_name.c_str());
405 result.SetStatus(eReturnStatusFailed);
406 }
407 return result.Succeeded();
408 }
409
Greg Clayton7260f622011-04-18 08:33:37 +0000410private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000411 OptionGroupOptions m_option_group;
412 OptionGroupArchitecture m_arch_option;
413 OptionGroupFile m_core_file;
414 OptionGroupFile m_platform_path;
415 OptionGroupFile m_symbol_file;
416 OptionGroupFile m_remote_file;
417 OptionGroupBoolean m_add_dependents;
Greg Clayton7260f622011-04-18 08:33:37 +0000418};
419
420#pragma mark CommandObjectTargetList
421
422//----------------------------------------------------------------------
423// "target list"
424//----------------------------------------------------------------------
425
Kate Stoneb9c1b512016-09-06 20:57:50 +0000426class CommandObjectTargetList : public CommandObjectParsed {
Greg Clayton7260f622011-04-18 08:33:37 +0000427public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000428 CommandObjectTargetList(CommandInterpreter &interpreter)
429 : CommandObjectParsed(
430 interpreter, "target list",
431 "List all current targets in the current debug session.", nullptr) {
432 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000433
Kate Stoneb9c1b512016-09-06 20:57:50 +0000434 ~CommandObjectTargetList() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000435
Jim Ingham5a988412012-06-08 21:56:10 +0000436protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000437 bool DoExecute(Args &args, CommandReturnObject &result) override {
438 if (args.GetArgumentCount() == 0) {
439 Stream &strm = result.GetOutputStream();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000440
Kate Stoneb9c1b512016-09-06 20:57:50 +0000441 bool show_stopped_process_status = false;
442 if (DumpTargetList(m_interpreter.GetDebugger().GetTargetList(),
443 show_stopped_process_status, strm) == 0) {
444 strm.PutCString("No targets.\n");
445 }
446 result.SetStatus(eReturnStatusSuccessFinishResult);
447 } else {
448 result.AppendError("the 'target list' command takes no arguments\n");
449 result.SetStatus(eReturnStatusFailed);
Greg Clayton7260f622011-04-18 08:33:37 +0000450 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000451 return result.Succeeded();
452 }
Greg Clayton7260f622011-04-18 08:33:37 +0000453};
454
Greg Clayton7260f622011-04-18 08:33:37 +0000455#pragma mark CommandObjectTargetSelect
456
457//----------------------------------------------------------------------
458// "target select"
459//----------------------------------------------------------------------
460
Kate Stoneb9c1b512016-09-06 20:57:50 +0000461class CommandObjectTargetSelect : public CommandObjectParsed {
Greg Clayton7260f622011-04-18 08:33:37 +0000462public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000463 CommandObjectTargetSelect(CommandInterpreter &interpreter)
464 : CommandObjectParsed(
465 interpreter, "target select",
466 "Select a target as the current target by target index.", nullptr) {
467 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000468
Kate Stoneb9c1b512016-09-06 20:57:50 +0000469 ~CommandObjectTargetSelect() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000470
Jim Ingham5a988412012-06-08 21:56:10 +0000471protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000472 bool DoExecute(Args &args, CommandReturnObject &result) override {
473 if (args.GetArgumentCount() == 1) {
474 bool success = false;
475 const char *target_idx_arg = args.GetArgumentAtIndex(0);
476 uint32_t target_idx =
477 StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success);
478 if (success) {
479 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
480 const uint32_t num_targets = target_list.GetNumTargets();
481 if (target_idx < num_targets) {
482 TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
483 if (target_sp) {
484 Stream &strm = result.GetOutputStream();
485 target_list.SetSelectedTarget(target_sp.get());
486 bool show_stopped_process_status = false;
487 DumpTargetList(target_list, show_stopped_process_status, strm);
488 result.SetStatus(eReturnStatusSuccessFinishResult);
489 } else {
490 result.AppendErrorWithFormat("target #%u is NULL in target list\n",
491 target_idx);
492 result.SetStatus(eReturnStatusFailed);
493 }
494 } else {
495 if (num_targets > 0) {
496 result.AppendErrorWithFormat(
497 "index %u is out of range, valid target indexes are 0 - %u\n",
498 target_idx, num_targets - 1);
499 } else {
500 result.AppendErrorWithFormat(
501 "index %u is out of range since there are no active targets\n",
502 target_idx);
503 }
504 result.SetStatus(eReturnStatusFailed);
Greg Clayton7260f622011-04-18 08:33:37 +0000505 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000506 } else {
507 result.AppendErrorWithFormat("invalid index string value '%s'\n",
508 target_idx_arg);
509 result.SetStatus(eReturnStatusFailed);
510 }
511 } else {
512 result.AppendError(
513 "'target select' takes a single argument: a target index\n");
514 result.SetStatus(eReturnStatusFailed);
Greg Clayton7260f622011-04-18 08:33:37 +0000515 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000516 return result.Succeeded();
517 }
Greg Clayton7260f622011-04-18 08:33:37 +0000518};
519
Greg Clayton3418c852011-08-10 02:10:13 +0000520#pragma mark CommandObjectTargetSelect
521
522//----------------------------------------------------------------------
523// "target delete"
524//----------------------------------------------------------------------
525
Kate Stoneb9c1b512016-09-06 20:57:50 +0000526class CommandObjectTargetDelete : public CommandObjectParsed {
Greg Clayton3418c852011-08-10 02:10:13 +0000527public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000528 CommandObjectTargetDelete(CommandInterpreter &interpreter)
529 : CommandObjectParsed(interpreter, "target delete",
Eugene Zelenkof13e6522016-02-25 19:02:39 +0000530 "Delete one or more targets by target index.",
531 nullptr),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000532 m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
533 "Delete all targets.", false, true),
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000534 m_cleanup_option(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000535 LLDB_OPT_SET_1, false, "clean", 'c',
536 "Perform extra cleanup to minimize memory consumption after "
537 "deleting the target. "
538 "By default, LLDB will keep in memory any modules previously "
539 "loaded by the target as well "
540 "as all of its debug info. Specifying --clean will unload all of "
541 "these shared modules and "
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000542 "cause them to be reparsed again the next time the target is run",
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543 false, true) {
544 m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
545 m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
546 m_option_group.Finalize();
547 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000548
Kate Stoneb9c1b512016-09-06 20:57:50 +0000549 ~CommandObjectTargetDelete() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000550
Kate Stoneb9c1b512016-09-06 20:57:50 +0000551 Options *GetOptions() override { return &m_option_group; }
Jim Ingham5a988412012-06-08 21:56:10 +0000552
553protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000554 bool DoExecute(Args &args, CommandReturnObject &result) override {
555 const size_t argc = args.GetArgumentCount();
556 std::vector<TargetSP> delete_target_list;
557 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
558 TargetSP target_sp;
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000559
Kate Stoneb9c1b512016-09-06 20:57:50 +0000560 if (m_all_option.GetOptionValue()) {
561 for (int i = 0; i < target_list.GetNumTargets(); ++i)
562 delete_target_list.push_back(target_list.GetTargetAtIndex(i));
563 } else if (argc > 0) {
564 const uint32_t num_targets = target_list.GetNumTargets();
565 // Bail out if don't have any targets.
566 if (num_targets == 0) {
567 result.AppendError("no targets to delete");
568 result.SetStatus(eReturnStatusFailed);
569 return false;
570 }
571
Zachary Turner97d2c402016-10-05 23:40:23 +0000572 for (auto &entry : args.entries()) {
573 uint32_t target_idx;
574 if (entry.ref.getAsInteger(0, target_idx)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000575 result.AppendErrorWithFormat("invalid target index '%s'\n",
Zachary Turner97d2c402016-10-05 23:40:23 +0000576 entry.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000577 result.SetStatus(eReturnStatusFailed);
578 return false;
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000579 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000580 if (target_idx < num_targets) {
581 target_sp = target_list.GetTargetAtIndex(target_idx);
582 if (target_sp) {
583 delete_target_list.push_back(target_sp);
584 continue;
585 }
Greg Clayton3418c852011-08-10 02:10:13 +0000586 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000587 if (num_targets > 1)
588 result.AppendErrorWithFormat("target index %u is out of range, valid "
589 "target indexes are 0 - %u\n",
590 target_idx, num_targets - 1);
Greg Clayton3418c852011-08-10 02:10:13 +0000591 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000592 result.AppendErrorWithFormat(
593 "target index %u is out of range, the only valid index is 0\n",
594 target_idx);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000595
Kate Stoneb9c1b512016-09-06 20:57:50 +0000596 result.SetStatus(eReturnStatusFailed);
597 return false;
598 }
599 } else {
600 target_sp = target_list.GetSelectedTarget();
601 if (!target_sp) {
602 result.AppendErrorWithFormat("no target is currently selected\n");
603 result.SetStatus(eReturnStatusFailed);
604 return false;
605 }
606 delete_target_list.push_back(target_sp);
Greg Clayton3418c852011-08-10 02:10:13 +0000607 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000608
Kate Stoneb9c1b512016-09-06 20:57:50 +0000609 const size_t num_targets_to_delete = delete_target_list.size();
610 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
611 target_sp = delete_target_list[idx];
612 target_list.DeleteTarget(target_sp);
613 target_sp->Destroy();
614 }
615 // If "--clean" was specified, prune any orphaned shared modules from
616 // the global shared module list
617 if (m_cleanup_option.GetOptionValue()) {
618 const bool mandatory = true;
619 ModuleList::RemoveOrphanSharedModules(mandatory);
620 }
621 result.GetOutputStream().Printf("%u targets deleted.\n",
622 (uint32_t)num_targets_to_delete);
623 result.SetStatus(eReturnStatusSuccessFinishResult);
624
625 return true;
626 }
627
628 OptionGroupOptions m_option_group;
629 OptionGroupBoolean m_all_option;
630 OptionGroupBoolean m_cleanup_option;
Greg Clayton3418c852011-08-10 02:10:13 +0000631};
632
Greg Clayton644247c2011-07-07 01:59:51 +0000633#pragma mark CommandObjectTargetVariable
634
635//----------------------------------------------------------------------
636// "target variable"
637//----------------------------------------------------------------------
638
Kate Stoneb9c1b512016-09-06 20:57:50 +0000639class CommandObjectTargetVariable : public CommandObjectParsed {
640 static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
641 static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
Saleem Abdulrasool44edda02014-03-18 04:43:47 +0000642
Greg Clayton644247c2011-07-07 01:59:51 +0000643public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000644 CommandObjectTargetVariable(CommandInterpreter &interpreter)
645 : CommandObjectParsed(interpreter, "target variable",
646 "Read global variables for the current target, "
647 "before or while running a process.",
648 nullptr, eCommandRequiresTarget),
649 m_option_group(),
650 m_option_variable(false), // Don't include frame options
651 m_option_format(eFormatDefault),
652 m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
653 0, eArgTypeFilename,
654 "A basename or fullpath to a file that contains "
655 "global variables. This option can be "
656 "specified multiple times."),
657 m_option_shared_libraries(
658 LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
659 eArgTypeFilename,
660 "A basename or fullpath to a shared library to use in the search "
661 "for global "
662 "variables. This option can be specified multiple times."),
663 m_varobj_options() {
664 CommandArgumentEntry arg;
665 CommandArgumentData var_name_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000666
Kate Stoneb9c1b512016-09-06 20:57:50 +0000667 // Define the first (and only) variant of this arg.
668 var_name_arg.arg_type = eArgTypeVarName;
669 var_name_arg.arg_repetition = eArgRepeatPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000670
Kate Stoneb9c1b512016-09-06 20:57:50 +0000671 // There is only one variant this argument could be; put it into the
672 // argument entry.
673 arg.push_back(var_name_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000674
Kate Stoneb9c1b512016-09-06 20:57:50 +0000675 // Push the data for the first argument into the m_arguments vector.
676 m_arguments.push_back(arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000677
Kate Stoneb9c1b512016-09-06 20:57:50 +0000678 m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
679 m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
680 m_option_group.Append(&m_option_format,
681 OptionGroupFormat::OPTION_GROUP_FORMAT |
682 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
683 LLDB_OPT_SET_1);
684 m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
685 LLDB_OPT_SET_1);
686 m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
687 LLDB_OPT_SET_1);
688 m_option_group.Finalize();
689 }
690
691 ~CommandObjectTargetVariable() override = default;
692
693 void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
694 const char *root_name) {
695 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
696
697 if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
698 valobj_sp->IsRuntimeSupportValue())
699 return;
700
701 switch (var_sp->GetScope()) {
702 case eValueTypeVariableGlobal:
703 if (m_option_variable.show_scope)
704 s.PutCString("GLOBAL: ");
705 break;
706
707 case eValueTypeVariableStatic:
708 if (m_option_variable.show_scope)
709 s.PutCString("STATIC: ");
710 break;
711
712 case eValueTypeVariableArgument:
713 if (m_option_variable.show_scope)
714 s.PutCString(" ARG: ");
715 break;
716
717 case eValueTypeVariableLocal:
718 if (m_option_variable.show_scope)
719 s.PutCString(" LOCAL: ");
720 break;
721
722 case eValueTypeVariableThreadLocal:
723 if (m_option_variable.show_scope)
724 s.PutCString("THREAD: ");
725 break;
726
727 default:
728 break;
Greg Clayton644247c2011-07-07 01:59:51 +0000729 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000730
Kate Stoneb9c1b512016-09-06 20:57:50 +0000731 if (m_option_variable.show_decl) {
732 bool show_fullpaths = false;
733 bool show_module = true;
734 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
735 s.PutCString(": ");
Greg Clayton884fb692011-07-08 21:46:14 +0000736 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000737
Kate Stoneb9c1b512016-09-06 20:57:50 +0000738 const Format format = m_option_format.GetFormat();
739 if (format != eFormatDefault)
740 options.SetFormat(format);
Greg Clayton884fb692011-07-08 21:46:14 +0000741
Kate Stoneb9c1b512016-09-06 20:57:50 +0000742 options.SetRootValueObjectName(root_name);
743
744 valobj_sp->Dump(s, options);
745 }
746
747 static size_t GetVariableCallback(void *baton, const char *name,
748 VariableList &variable_list) {
749 Target *target = static_cast<Target *>(baton);
750 if (target) {
751 return target->GetImages().FindGlobalVariables(ConstString(name), true,
752 UINT32_MAX, variable_list);
Jim Ingham5a988412012-06-08 21:56:10 +0000753 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000754 return 0;
755 }
756
757 Options *GetOptions() override { return &m_option_group; }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000758
Jim Ingham5a988412012-06-08 21:56:10 +0000759protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000760 void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
761 const SymbolContext &sc,
762 const VariableList &variable_list, Stream &s) {
763 size_t count = variable_list.GetSize();
764 if (count > 0) {
765 if (sc.module_sp) {
766 if (sc.comp_unit) {
767 s.Printf("Global variables for %s in %s:\n",
768 sc.comp_unit->GetPath().c_str(),
769 sc.module_sp->GetFileSpec().GetPath().c_str());
770 } else {
771 s.Printf("Global variables for %s\n",
772 sc.module_sp->GetFileSpec().GetPath().c_str());
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000773 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000774 } else if (sc.comp_unit) {
775 s.Printf("Global variables for %s\n", sc.comp_unit->GetPath().c_str());
776 }
777
778 for (uint32_t i = 0; i < count; ++i) {
779 VariableSP var_sp(variable_list.GetVariableAtIndex(i));
780 if (var_sp) {
781 ValueObjectSP valobj_sp(ValueObjectVariable::Create(
782 exe_ctx.GetBestExecutionContextScope(), var_sp));
783
784 if (valobj_sp)
785 DumpValueObject(s, var_sp, valobj_sp,
786 var_sp->GetName().GetCString());
787 }
788 }
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000789 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000790 }
Eugene Zelenkof13e6522016-02-25 19:02:39 +0000791
Kate Stoneb9c1b512016-09-06 20:57:50 +0000792 bool DoExecute(Args &args, CommandReturnObject &result) override {
793 Target *target = m_exe_ctx.GetTargetPtr();
794 const size_t argc = args.GetArgumentCount();
795 Stream &s = result.GetOutputStream();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000796
Kate Stoneb9c1b512016-09-06 20:57:50 +0000797 if (argc > 0) {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000798
Zachary Turner97d2c402016-10-05 23:40:23 +0000799 // TODO: Convert to entry-based iteration. Requires converting
800 // DumpValueObject.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000801 for (size_t idx = 0; idx < argc; ++idx) {
802 VariableList variable_list;
803 ValueObjectList valobj_list;
Greg Clayton884fb692011-07-08 21:46:14 +0000804
Kate Stoneb9c1b512016-09-06 20:57:50 +0000805 const char *arg = args.GetArgumentAtIndex(idx);
806 size_t matches = 0;
807 bool use_var_name = false;
808 if (m_option_variable.use_regex) {
Zachary Turner95eae422016-09-21 16:01:28 +0000809 RegularExpression regex(llvm::StringRef::withNullAsEmpty(arg));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000810 if (!regex.IsValid()) {
811 result.GetErrorStream().Printf(
812 "error: invalid regular expression: '%s'\n", arg);
813 result.SetStatus(eReturnStatusFailed);
814 return false;
815 }
816 use_var_name = true;
817 matches = target->GetImages().FindGlobalVariables(
818 regex, true, UINT32_MAX, variable_list);
819 } else {
820 Error error(Variable::GetValuesForVariableExpressionPath(
821 arg, m_exe_ctx.GetBestExecutionContextScope(),
822 GetVariableCallback, target, variable_list, valobj_list));
823 matches = variable_list.GetSize();
Greg Clayton644247c2011-07-07 01:59:51 +0000824 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000825
826 if (matches == 0) {
827 result.GetErrorStream().Printf(
828 "error: can't find global variable '%s'\n", arg);
829 result.SetStatus(eReturnStatusFailed);
830 return false;
831 } else {
832 for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
833 VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
834 if (var_sp) {
835 ValueObjectSP valobj_sp(
836 valobj_list.GetValueObjectAtIndex(global_idx));
837 if (!valobj_sp)
838 valobj_sp = ValueObjectVariable::Create(
839 m_exe_ctx.GetBestExecutionContextScope(), var_sp);
840
841 if (valobj_sp)
842 DumpValueObject(s, var_sp, valobj_sp,
843 use_var_name ? var_sp->GetName().GetCString()
844 : arg);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000845 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000846 }
847 }
848 }
849 } else {
850 const FileSpecList &compile_units =
851 m_option_compile_units.GetOptionValue().GetCurrentValue();
852 const FileSpecList &shlibs =
853 m_option_shared_libraries.GetOptionValue().GetCurrentValue();
854 SymbolContextList sc_list;
855 const size_t num_compile_units = compile_units.GetSize();
856 const size_t num_shlibs = shlibs.GetSize();
857 if (num_compile_units == 0 && num_shlibs == 0) {
858 bool success = false;
859 StackFrame *frame = m_exe_ctx.GetFramePtr();
860 CompileUnit *comp_unit = nullptr;
861 if (frame) {
862 SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
863 if (sc.comp_unit) {
864 const bool can_create = true;
865 VariableListSP comp_unit_varlist_sp(
866 sc.comp_unit->GetVariableList(can_create));
867 if (comp_unit_varlist_sp) {
868 size_t count = comp_unit_varlist_sp->GetSize();
869 if (count > 0) {
870 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
871 success = true;
872 }
873 }
874 }
875 }
876 if (!success) {
877 if (frame) {
878 if (comp_unit)
879 result.AppendErrorWithFormat(
880 "no global variables in current compile unit: %s\n",
881 comp_unit->GetPath().c_str());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000882 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000883 result.AppendErrorWithFormat(
884 "no debug information for frame %u\n",
885 frame->GetFrameIndex());
886 } else
887 result.AppendError("'target variable' takes one or more global "
888 "variable names as arguments\n");
889 result.SetStatus(eReturnStatusFailed);
890 }
891 } else {
892 SymbolContextList sc_list;
893 const bool append = true;
894 // We have one or more compile unit or shlib
895 if (num_shlibs > 0) {
896 for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
897 const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
898 ModuleSpec module_spec(module_file);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000899
Kate Stoneb9c1b512016-09-06 20:57:50 +0000900 ModuleSP module_sp(
901 target->GetImages().FindFirstModule(module_spec));
902 if (module_sp) {
903 if (num_compile_units > 0) {
904 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
905 module_sp->FindCompileUnits(
906 compile_units.GetFileSpecAtIndex(cu_idx), append,
907 sc_list);
908 } else {
909 SymbolContext sc;
910 sc.module_sp = module_sp;
911 sc_list.Append(sc);
912 }
913 } else {
914 // Didn't find matching shlib/module in target...
915 result.AppendErrorWithFormat(
916 "target doesn't contain the specified shared library: %s\n",
917 module_file.GetPath().c_str());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000918 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000919 }
920 } else {
921 // No shared libraries, we just want to find globals for the compile
922 // units files that were specified
923 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
924 target->GetImages().FindCompileUnits(
925 compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
Greg Clayton644247c2011-07-07 01:59:51 +0000926 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000927
Kate Stoneb9c1b512016-09-06 20:57:50 +0000928 const uint32_t num_scs = sc_list.GetSize();
929 if (num_scs > 0) {
930 SymbolContext sc;
931 for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
932 if (sc_list.GetContextAtIndex(sc_idx, sc)) {
933 if (sc.comp_unit) {
934 const bool can_create = true;
935 VariableListSP comp_unit_varlist_sp(
936 sc.comp_unit->GetVariableList(can_create));
937 if (comp_unit_varlist_sp)
938 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
939 s);
940 } else if (sc.module_sp) {
941 // Get all global variables for this module
942 lldb_private::RegularExpression all_globals_regex(
Zachary Turner95eae422016-09-21 16:01:28 +0000943 llvm::StringRef(
944 ".")); // Any global with at least one character
Kate Stoneb9c1b512016-09-06 20:57:50 +0000945 VariableList variable_list;
946 sc.module_sp->FindGlobalVariables(all_globals_regex, append,
947 UINT32_MAX, variable_list);
948 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
949 }
950 }
951 }
Enrico Granata61a80ba2011-08-12 16:42:31 +0000952 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000953 }
Greg Clayton644247c2011-07-07 01:59:51 +0000954 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000955
Kate Stoneb9c1b512016-09-06 20:57:50 +0000956 if (m_interpreter.TruncationWarningNecessary()) {
957 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
958 m_cmd_name.c_str());
959 m_interpreter.TruncationWarningGiven();
960 }
961
962 return result.Succeeded();
963 }
964
965 OptionGroupOptions m_option_group;
966 OptionGroupVariable m_option_variable;
967 OptionGroupFormat m_option_format;
968 OptionGroupFileList m_option_compile_units;
969 OptionGroupFileList m_option_shared_libraries;
970 OptionGroupValueObjectDisplay m_varobj_options;
Greg Clayton644247c2011-07-07 01:59:51 +0000971};
972
Greg Claytoneffe5c92011-05-03 22:09:39 +0000973#pragma mark CommandObjectTargetModulesSearchPathsAdd
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000974
Kate Stoneb9c1b512016-09-06 20:57:50 +0000975class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000976public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000977 CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
978 : CommandObjectParsed(interpreter, "target modules search-paths add",
979 "Add new image search paths substitution pairs to "
980 "the current target.",
981 nullptr) {
982 CommandArgumentEntry arg;
983 CommandArgumentData old_prefix_arg;
984 CommandArgumentData new_prefix_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000985
Kate Stoneb9c1b512016-09-06 20:57:50 +0000986 // Define the first variant of this arg pair.
987 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
988 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000989
Kate Stoneb9c1b512016-09-06 20:57:50 +0000990 // Define the first variant of this arg pair.
991 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
992 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000993
Kate Stoneb9c1b512016-09-06 20:57:50 +0000994 // There are two required arguments that must always occur together, i.e. an
995 // argument "pair". Because they
996 // must always occur together, they are treated as two variants of one
997 // argument rather than two independent
998 // arguments. Push them both into the first argument position for
999 // m_arguments...
Caroline Tice405fe672010-10-04 22:28:36 +00001000
Kate Stoneb9c1b512016-09-06 20:57:50 +00001001 arg.push_back(old_prefix_arg);
1002 arg.push_back(new_prefix_arg);
Caroline Tice405fe672010-10-04 22:28:36 +00001003
Kate Stoneb9c1b512016-09-06 20:57:50 +00001004 m_arguments.push_back(arg);
1005 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001006
Kate Stoneb9c1b512016-09-06 20:57:50 +00001007 ~CommandObjectTargetModulesSearchPathsAdd() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001008
Jim Ingham5a988412012-06-08 21:56:10 +00001009protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001010 bool DoExecute(Args &command, CommandReturnObject &result) override {
1011 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1012 if (target) {
1013 const size_t argc = command.GetArgumentCount();
1014 if (argc & 1) {
1015 result.AppendError("add requires an even number of arguments\n");
1016 result.SetStatus(eReturnStatusFailed);
1017 } else {
1018 for (size_t i = 0; i < argc; i += 2) {
1019 const char *from = command.GetArgumentAtIndex(i);
1020 const char *to = command.GetArgumentAtIndex(i + 1);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001021
Kate Stoneb9c1b512016-09-06 20:57:50 +00001022 if (from[0] && to[0]) {
1023 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
1024 if (log) {
1025 log->Printf("target modules search path adding ImageSearchPath "
1026 "pair: '%s' -> '%s'",
1027 from, to);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001028 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001029 bool last_pair = ((argc - i) == 2);
1030 target->GetImageSearchPathList().Append(
1031 ConstString(from), ConstString(to),
1032 last_pair); // Notify if this is the last pair
1033 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1034 } else {
1035 if (from[0])
1036 result.AppendError("<path-prefix> can't be empty\n");
1037 else
1038 result.AppendError("<new-path-prefix> can't be empty\n");
1039 result.SetStatus(eReturnStatusFailed);
1040 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001041 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001042 }
1043 } else {
1044 result.AppendError("invalid target\n");
1045 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001046 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001047 return result.Succeeded();
1048 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001049};
1050
Greg Claytoneffe5c92011-05-03 22:09:39 +00001051#pragma mark CommandObjectTargetModulesSearchPathsClear
1052
Kate Stoneb9c1b512016-09-06 20:57:50 +00001053class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001054public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001055 CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
1056 : CommandObjectParsed(interpreter, "target modules search-paths clear",
1057 "Clear all current image search path substitution "
1058 "pairs from the current target.",
1059 "target modules search-paths clear") {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001060
Kate Stoneb9c1b512016-09-06 20:57:50 +00001061 ~CommandObjectTargetModulesSearchPathsClear() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001062
Jim Ingham5a988412012-06-08 21:56:10 +00001063protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001064 bool DoExecute(Args &command, CommandReturnObject &result) override {
1065 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1066 if (target) {
1067 bool notify = true;
1068 target->GetImageSearchPathList().Clear(notify);
1069 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1070 } else {
1071 result.AppendError("invalid target\n");
1072 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001073 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001074 return result.Succeeded();
1075 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001076};
1077
Greg Claytoneffe5c92011-05-03 22:09:39 +00001078#pragma mark CommandObjectTargetModulesSearchPathsInsert
1079
Kate Stoneb9c1b512016-09-06 20:57:50 +00001080class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001081public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001082 CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
1083 : CommandObjectParsed(interpreter, "target modules search-paths insert",
1084 "Insert a new image search path substitution pair "
1085 "into the current target at the specified index.",
1086 nullptr) {
1087 CommandArgumentEntry arg1;
1088 CommandArgumentEntry arg2;
1089 CommandArgumentData index_arg;
1090 CommandArgumentData old_prefix_arg;
1091 CommandArgumentData new_prefix_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001092
Kate Stoneb9c1b512016-09-06 20:57:50 +00001093 // Define the first and only variant of this arg.
1094 index_arg.arg_type = eArgTypeIndex;
1095 index_arg.arg_repetition = eArgRepeatPlain;
Caroline Tice405fe672010-10-04 22:28:36 +00001096
Kate Stoneb9c1b512016-09-06 20:57:50 +00001097 // Put the one and only variant into the first arg for m_arguments:
1098 arg1.push_back(index_arg);
Caroline Tice405fe672010-10-04 22:28:36 +00001099
Kate Stoneb9c1b512016-09-06 20:57:50 +00001100 // Define the first variant of this arg pair.
1101 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1102 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001103
Kate Stoneb9c1b512016-09-06 20:57:50 +00001104 // Define the first variant of this arg pair.
1105 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1106 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001107
Kate Stoneb9c1b512016-09-06 20:57:50 +00001108 // There are two required arguments that must always occur together, i.e. an
1109 // argument "pair". Because they
1110 // must always occur together, they are treated as two variants of one
1111 // argument rather than two independent
1112 // arguments. Push them both into the same argument position for
1113 // m_arguments...
Caroline Tice405fe672010-10-04 22:28:36 +00001114
Kate Stoneb9c1b512016-09-06 20:57:50 +00001115 arg2.push_back(old_prefix_arg);
1116 arg2.push_back(new_prefix_arg);
Caroline Tice405fe672010-10-04 22:28:36 +00001117
Kate Stoneb9c1b512016-09-06 20:57:50 +00001118 // Add arguments to m_arguments.
1119 m_arguments.push_back(arg1);
1120 m_arguments.push_back(arg2);
1121 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001122
Kate Stoneb9c1b512016-09-06 20:57:50 +00001123 ~CommandObjectTargetModulesSearchPathsInsert() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001124
Jim Ingham5a988412012-06-08 21:56:10 +00001125protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001126 bool DoExecute(Args &command, CommandReturnObject &result) override {
1127 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1128 if (target) {
1129 size_t argc = command.GetArgumentCount();
1130 // check for at least 3 arguments and an odd number of parameters
1131 if (argc >= 3 && argc & 1) {
1132 bool success = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001133
Kate Stoneb9c1b512016-09-06 20:57:50 +00001134 uint32_t insert_idx = StringConvert::ToUInt32(
1135 command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001136
Kate Stoneb9c1b512016-09-06 20:57:50 +00001137 if (!success) {
1138 result.AppendErrorWithFormat(
1139 "<index> parameter is not an integer: '%s'.\n",
1140 command.GetArgumentAtIndex(0));
1141 result.SetStatus(eReturnStatusFailed);
1142 return result.Succeeded();
1143 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001144
Kate Stoneb9c1b512016-09-06 20:57:50 +00001145 // shift off the index
1146 command.Shift();
1147 argc = command.GetArgumentCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001148
Kate Stoneb9c1b512016-09-06 20:57:50 +00001149 for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1150 const char *from = command.GetArgumentAtIndex(i);
1151 const char *to = command.GetArgumentAtIndex(i + 1);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001152
Kate Stoneb9c1b512016-09-06 20:57:50 +00001153 if (from[0] && to[0]) {
1154 bool last_pair = ((argc - i) == 2);
1155 target->GetImageSearchPathList().Insert(
1156 ConstString(from), ConstString(to), insert_idx, last_pair);
1157 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1158 } else {
1159 if (from[0])
1160 result.AppendError("<path-prefix> can't be empty\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001161 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001162 result.AppendError("<new-path-prefix> can't be empty\n");
1163 result.SetStatus(eReturnStatusFailed);
1164 return false;
1165 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001166 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001167 } else {
1168 result.AppendError("insert requires at least three arguments\n");
1169 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001170 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001171 }
1172
1173 } else {
1174 result.AppendError("invalid target\n");
1175 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001176 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001177 return result.Succeeded();
1178 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001179};
1180
Greg Claytoneffe5c92011-05-03 22:09:39 +00001181#pragma mark CommandObjectTargetModulesSearchPathsList
1182
Kate Stoneb9c1b512016-09-06 20:57:50 +00001183class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001184public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001185 CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
1186 : CommandObjectParsed(interpreter, "target modules search-paths list",
1187 "List all current image search path substitution "
1188 "pairs in the current target.",
1189 "target modules search-paths list") {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001190
Kate Stoneb9c1b512016-09-06 20:57:50 +00001191 ~CommandObjectTargetModulesSearchPathsList() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001192
Jim Ingham5a988412012-06-08 21:56:10 +00001193protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001194 bool DoExecute(Args &command, CommandReturnObject &result) override {
1195 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1196 if (target) {
1197 if (command.GetArgumentCount() != 0) {
1198 result.AppendError("list takes no arguments\n");
1199 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001200 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001201 }
1202
1203 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1204 result.SetStatus(eReturnStatusSuccessFinishResult);
1205 } else {
1206 result.AppendError("invalid target\n");
1207 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001208 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001209 return result.Succeeded();
1210 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001211};
1212
Greg Claytoneffe5c92011-05-03 22:09:39 +00001213#pragma mark CommandObjectTargetModulesSearchPathsQuery
1214
Kate Stoneb9c1b512016-09-06 20:57:50 +00001215class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001216public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001217 CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
1218 : CommandObjectParsed(
1219 interpreter, "target modules search-paths query",
1220 "Transform a path using the first applicable image search path.",
1221 nullptr) {
1222 CommandArgumentEntry arg;
1223 CommandArgumentData path_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001224
Kate Stoneb9c1b512016-09-06 20:57:50 +00001225 // Define the first (and only) variant of this arg.
1226 path_arg.arg_type = eArgTypeDirectoryName;
1227 path_arg.arg_repetition = eArgRepeatPlain;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001228
Kate Stoneb9c1b512016-09-06 20:57:50 +00001229 // There is only one variant this argument could be; put it into the
1230 // argument entry.
1231 arg.push_back(path_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001232
Kate Stoneb9c1b512016-09-06 20:57:50 +00001233 // Push the data for the first argument into the m_arguments vector.
1234 m_arguments.push_back(arg);
1235 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001236
Kate Stoneb9c1b512016-09-06 20:57:50 +00001237 ~CommandObjectTargetModulesSearchPathsQuery() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001238
Jim Ingham5a988412012-06-08 21:56:10 +00001239protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001240 bool DoExecute(Args &command, CommandReturnObject &result) override {
1241 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1242 if (target) {
1243 if (command.GetArgumentCount() != 1) {
1244 result.AppendError("query requires one argument\n");
1245 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001246 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001247 }
1248
1249 ConstString orig(command.GetArgumentAtIndex(0));
1250 ConstString transformed;
1251 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1252 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1253 else
1254 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1255
1256 result.SetStatus(eReturnStatusSuccessFinishResult);
1257 } else {
1258 result.AppendError("invalid target\n");
1259 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001260 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001261 return result.Succeeded();
1262 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001263};
1264
Greg Claytoneffe5c92011-05-03 22:09:39 +00001265//----------------------------------------------------------------------
1266// Static Helper functions
1267//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001268static void DumpModuleArchitecture(Stream &strm, Module *module,
1269 bool full_triple, uint32_t width) {
1270 if (module) {
1271 StreamString arch_strm;
Todd Fiala7df337f2015-10-13 23:41:19 +00001272
Kate Stoneb9c1b512016-09-06 20:57:50 +00001273 if (full_triple)
1274 module->GetArchitecture().DumpTriple(arch_strm);
Greg Clayton3418c852011-08-10 02:10:13 +00001275 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001276 arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1277 std::string arch_str = arch_strm.GetString();
1278
1279 if (width)
1280 strm.Printf("%-*s", width, arch_str.c_str());
1281 else
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00001282 strm.PutCString(arch_str);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001283 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001284}
1285
Kate Stoneb9c1b512016-09-06 20:57:50 +00001286static void DumpModuleUUID(Stream &strm, Module *module) {
1287 if (module && module->GetUUID().IsValid())
1288 module->GetUUID().Dump(&strm);
1289 else
1290 strm.PutCString(" ");
Greg Claytoneffe5c92011-05-03 22:09:39 +00001291}
1292
Kate Stoneb9c1b512016-09-06 20:57:50 +00001293static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
1294 Stream &strm, Module *module,
1295 const FileSpec &file_spec,
1296 bool load_addresses) {
1297 uint32_t num_matches = 0;
1298 if (module) {
1299 SymbolContextList sc_list;
1300 num_matches = module->ResolveSymbolContextsForFileSpec(
1301 file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1302
1303 for (uint32_t i = 0; i < num_matches; ++i) {
1304 SymbolContext sc;
1305 if (sc_list.GetContextAtIndex(i, sc)) {
1306 if (i > 0)
1307 strm << "\n\n";
1308
1309 strm << "Line table for " << *static_cast<FileSpec *>(sc.comp_unit)
1310 << " in `" << module->GetFileSpec().GetFilename() << "\n";
1311 LineTable *line_table = sc.comp_unit->GetLineTable();
1312 if (line_table)
1313 line_table->GetDescription(
1314 &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1315 lldb::eDescriptionLevelBrief);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001316 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001317 strm << "No line table";
1318 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001319 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001320 }
1321 return num_matches;
1322}
1323
1324static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1325 uint32_t width) {
1326 if (file_spec_ptr) {
1327 if (width > 0) {
1328 std::string fullpath = file_spec_ptr->GetPath();
1329 strm.Printf("%-*s", width, fullpath.c_str());
1330 return;
1331 } else {
1332 file_spec_ptr->Dump(&strm);
1333 return;
1334 }
1335 }
1336 // Keep the width spacing correct if things go wrong...
1337 if (width > 0)
1338 strm.Printf("%-*s", width, "");
1339}
1340
1341static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1342 uint32_t width) {
1343 if (file_spec_ptr) {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001344 if (width > 0)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001345 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1346 else
1347 file_spec_ptr->GetDirectory().Dump(&strm);
1348 return;
1349 }
1350 // Keep the width spacing correct if things go wrong...
1351 if (width > 0)
1352 strm.Printf("%-*s", width, "");
Greg Claytoneffe5c92011-05-03 22:09:39 +00001353}
1354
Kate Stoneb9c1b512016-09-06 20:57:50 +00001355static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1356 uint32_t width) {
1357 if (file_spec_ptr) {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001358 if (width > 0)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001359 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1360 else
1361 file_spec_ptr->GetFilename().Dump(&strm);
1362 return;
1363 }
1364 // Keep the width spacing correct if things go wrong...
1365 if (width > 0)
1366 strm.Printf("%-*s", width, "");
Greg Claytoneffe5c92011-05-03 22:09:39 +00001367}
1368
Kate Stoneb9c1b512016-09-06 20:57:50 +00001369static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1370 size_t num_dumped = 0;
1371 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1372 const size_t num_modules = module_list.GetSize();
1373 if (num_modules > 0) {
1374 strm.Printf("Dumping headers for %" PRIu64 " module(s).\n",
1375 static_cast<uint64_t>(num_modules));
Greg Claytonc4a8a762012-05-15 18:43:44 +00001376 strm.IndentMore();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001377 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1378 Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
1379 if (module) {
1380 if (num_dumped++ > 0) {
1381 strm.EOL();
1382 strm.EOL();
1383 }
1384 ObjectFile *objfile = module->GetObjectFile();
1385 objfile->Dump(&strm);
1386 }
Greg Claytonc4a8a762012-05-15 18:43:44 +00001387 }
1388 strm.IndentLess();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001389 }
1390 return num_dumped;
Greg Claytonc4a8a762012-05-15 18:43:44 +00001391}
1392
Kate Stoneb9c1b512016-09-06 20:57:50 +00001393static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1394 Module *module, SortOrder sort_order) {
1395 if (module) {
1396 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1397 if (sym_vendor) {
1398 Symtab *symtab = sym_vendor->GetSymtab();
1399 if (symtab)
1400 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1401 sort_order);
1402 }
1403 }
1404}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001405
Kate Stoneb9c1b512016-09-06 20:57:50 +00001406static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1407 Module *module) {
1408 if (module) {
1409 SectionList *section_list = module->GetSectionList();
1410 if (section_list) {
1411 strm.Printf("Sections for '%s' (%s):\n",
1412 module->GetSpecificationDescription().c_str(),
1413 module->GetArchitecture().GetArchitectureName());
1414 strm.IndentMore();
1415 section_list->Dump(&strm,
1416 interpreter.GetExecutionContext().GetTargetPtr(), true,
1417 UINT32_MAX);
1418 strm.IndentLess();
1419 }
1420 }
1421}
1422
1423static bool DumpModuleSymbolVendor(Stream &strm, Module *module) {
1424 if (module) {
1425 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1426 if (symbol_vendor) {
1427 symbol_vendor->Dump(&strm);
1428 return true;
1429 }
1430 }
1431 return false;
1432}
1433
1434static void DumpAddress(ExecutionContextScope *exe_scope,
1435 const Address &so_addr, bool verbose, Stream &strm) {
1436 strm.IndentMore();
1437 strm.Indent(" Address: ");
1438 so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1439 strm.PutCString(" (");
1440 so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1441 strm.PutCString(")\n");
1442 strm.Indent(" Summary: ");
1443 const uint32_t save_indent = strm.GetIndentLevel();
1444 strm.SetIndentLevel(save_indent + 13);
1445 so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
1446 strm.SetIndentLevel(save_indent);
1447 // Print out detailed address information when verbose is enabled
1448 if (verbose) {
1449 strm.EOL();
1450 so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1451 }
1452 strm.IndentLess();
1453}
1454
1455static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1456 Module *module, uint32_t resolve_mask,
1457 lldb::addr_t raw_addr, lldb::addr_t offset,
1458 bool verbose) {
1459 if (module) {
1460 lldb::addr_t addr = raw_addr - offset;
1461 Address so_addr;
1462 SymbolContext sc;
1463 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1464 if (target && !target->GetSectionLoadList().IsEmpty()) {
1465 if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
1466 return false;
1467 else if (so_addr.GetModule().get() != module)
1468 return false;
1469 } else {
1470 if (!module->ResolveFileAddress(addr, so_addr))
1471 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001472 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001473
Kate Stoneb9c1b512016-09-06 20:57:50 +00001474 ExecutionContextScope *exe_scope =
1475 interpreter.GetExecutionContext().GetBestExecutionContextScope();
1476 DumpAddress(exe_scope, so_addr, verbose, strm);
1477 // strm.IndentMore();
1478 // strm.Indent (" Address: ");
1479 // so_addr.Dump (&strm, exe_scope,
1480 // Address::DumpStyleModuleWithFileAddress);
1481 // strm.PutCString (" (");
1482 // so_addr.Dump (&strm, exe_scope,
1483 // Address::DumpStyleSectionNameOffset);
1484 // strm.PutCString (")\n");
1485 // strm.Indent (" Summary: ");
1486 // const uint32_t save_indent = strm.GetIndentLevel ();
1487 // strm.SetIndentLevel (save_indent + 13);
1488 // so_addr.Dump (&strm, exe_scope,
1489 // Address::DumpStyleResolvedDescription);
1490 // strm.SetIndentLevel (save_indent);
1491 // // Print out detailed address information when verbose is enabled
1492 // if (verbose)
1493 // {
1494 // strm.EOL();
1495 // so_addr.Dump (&strm, exe_scope,
1496 // Address::DumpStyleDetailedSymbolContext);
1497 // }
1498 // strm.IndentLess();
1499 return true;
1500 }
1501
1502 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001503}
1504
Kate Stoneb9c1b512016-09-06 20:57:50 +00001505static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1506 Stream &strm, Module *module,
1507 const char *name, bool name_is_regex,
1508 bool verbose) {
1509 if (module) {
1510 SymbolContext sc;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001511
Kate Stoneb9c1b512016-09-06 20:57:50 +00001512 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1513 if (sym_vendor) {
1514 Symtab *symtab = sym_vendor->GetSymtab();
1515 if (symtab) {
1516 std::vector<uint32_t> match_indexes;
1517 ConstString symbol_name(name);
1518 uint32_t num_matches = 0;
1519 if (name_is_regex) {
Zachary Turner95eae422016-09-21 16:01:28 +00001520 RegularExpression name_regexp(symbol_name.GetStringRef());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001521 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1522 name_regexp, eSymbolTypeAny, match_indexes);
1523 } else {
1524 num_matches =
1525 symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1526 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001527
Kate Stoneb9c1b512016-09-06 20:57:50 +00001528 if (num_matches > 0) {
1529 strm.Indent();
1530 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1531 name_is_regex ? "the regular expression " : "", name);
1532 DumpFullpath(strm, &module->GetFileSpec(), 0);
1533 strm.PutCString(":\n");
1534 strm.IndentMore();
1535 for (uint32_t i = 0; i < num_matches; ++i) {
1536 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1537 if (symbol && symbol->ValueIsAddress()) {
1538 DumpAddress(interpreter.GetExecutionContext()
1539 .GetBestExecutionContextScope(),
1540 symbol->GetAddressRef(), verbose, strm);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001541 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001542 }
1543 strm.IndentLess();
1544 return num_matches;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001545 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001546 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001547 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001548 }
1549 return 0;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001550}
1551
Kate Stoneb9c1b512016-09-06 20:57:50 +00001552static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
1553 Stream &strm, SymbolContextList &sc_list,
1554 bool verbose) {
1555 strm.IndentMore();
Eugene Zelenkof13e6522016-02-25 19:02:39 +00001556
Kate Stoneb9c1b512016-09-06 20:57:50 +00001557 const uint32_t num_matches = sc_list.GetSize();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001558
Kate Stoneb9c1b512016-09-06 20:57:50 +00001559 for (uint32_t i = 0; i < num_matches; ++i) {
1560 SymbolContext sc;
1561 if (sc_list.GetContextAtIndex(i, sc)) {
1562 AddressRange range;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001563
Kate Stoneb9c1b512016-09-06 20:57:50 +00001564 sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001565
Kate Stoneb9c1b512016-09-06 20:57:50 +00001566 DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001567 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001568 }
1569 strm.IndentLess();
Greg Claytoneffe5c92011-05-03 22:09:39 +00001570}
1571
Kate Stoneb9c1b512016-09-06 20:57:50 +00001572static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
1573 Stream &strm, Module *module,
1574 const char *name, bool name_is_regex,
1575 bool include_inlines, bool include_symbols,
1576 bool verbose) {
1577 if (module && name && name[0]) {
1578 SymbolContextList sc_list;
1579 const bool append = true;
1580 size_t num_matches = 0;
1581 if (name_is_regex) {
Zachary Turner95eae422016-09-21 16:01:28 +00001582 RegularExpression function_name_regex((llvm::StringRef(name)));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001583 num_matches = module->FindFunctions(function_name_regex, include_symbols,
1584 include_inlines, append, sc_list);
1585 } else {
1586 ConstString function_name(name);
1587 num_matches = module->FindFunctions(
1588 function_name, nullptr, eFunctionNameTypeAuto, include_symbols,
1589 include_inlines, append, sc_list);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001590 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001591
Kate Stoneb9c1b512016-09-06 20:57:50 +00001592 if (num_matches) {
1593 strm.Indent();
1594 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1595 num_matches > 1 ? "es" : "");
1596 DumpFullpath(strm, &module->GetFileSpec(), 0);
1597 strm.PutCString(":\n");
1598 DumpSymbolContextList(
1599 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1600 strm, sc_list, verbose);
Sean Callanand38b4a92012-06-06 20:49:55 +00001601 }
1602 return num_matches;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001603 }
1604 return 0;
Sean Callanand38b4a92012-06-06 20:49:55 +00001605}
1606
Kate Stoneb9c1b512016-09-06 20:57:50 +00001607static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
1608 Module *module, const char *name_cstr,
1609 bool name_is_regex) {
1610 if (module && name_cstr && name_cstr[0]) {
1611 TypeList type_list;
1612 const uint32_t max_num_matches = UINT32_MAX;
1613 size_t num_matches = 0;
1614 bool name_is_fully_qualified = false;
1615 SymbolContext sc;
1616
1617 ConstString name(name_cstr);
1618 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1619 num_matches =
1620 module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches,
1621 searched_symbol_files, type_list);
1622
1623 if (num_matches) {
1624 strm.Indent();
1625 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1626 num_matches > 1 ? "es" : "");
1627 DumpFullpath(strm, &module->GetFileSpec(), 0);
1628 strm.PutCString(":\n");
1629 for (TypeSP type_sp : type_list.Types()) {
1630 if (type_sp) {
1631 // Resolve the clang type so that any forward references
1632 // to types that haven't yet been parsed will get parsed.
1633 type_sp->GetFullCompilerType();
1634 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1635 // Print all typedef chains
1636 TypeSP typedef_type_sp(type_sp);
1637 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1638 while (typedefed_type_sp) {
1639 strm.EOL();
1640 strm.Printf(" typedef '%s': ",
1641 typedef_type_sp->GetName().GetCString());
1642 typedefed_type_sp->GetFullCompilerType();
1643 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull,
1644 true);
1645 typedef_type_sp = typedefed_type_sp;
1646 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1647 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001648 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001649 strm.EOL();
1650 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001651 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001652 return num_matches;
1653 }
1654 return 0;
1655}
1656
1657static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
1658 const SymbolContext &sym_ctx,
1659 const char *name_cstr, bool name_is_regex) {
1660 if (!sym_ctx.module_sp)
Greg Claytoneffe5c92011-05-03 22:09:39 +00001661 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001662
1663 TypeList type_list;
1664 const uint32_t max_num_matches = UINT32_MAX;
1665 size_t num_matches = 1;
1666 bool name_is_fully_qualified = false;
1667
1668 ConstString name(name_cstr);
1669 llvm::DenseSet<SymbolFile *> searched_symbol_files;
1670 num_matches = sym_ctx.module_sp->FindTypes(
1671 sym_ctx, name, name_is_fully_qualified, max_num_matches,
1672 searched_symbol_files, type_list);
1673
1674 if (num_matches) {
1675 strm.Indent();
1676 strm.PutCString("Best match found in ");
1677 DumpFullpath(strm, &sym_ctx.module_sp->GetFileSpec(), 0);
1678 strm.PutCString(":\n");
1679
1680 TypeSP type_sp(type_list.GetTypeAtIndex(0));
1681 if (type_sp) {
1682 // Resolve the clang type so that any forward references
1683 // to types that haven't yet been parsed will get parsed.
1684 type_sp->GetFullCompilerType();
1685 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1686 // Print all typedef chains
1687 TypeSP typedef_type_sp(type_sp);
1688 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1689 while (typedefed_type_sp) {
1690 strm.EOL();
1691 strm.Printf(" typedef '%s': ",
1692 typedef_type_sp->GetName().GetCString());
1693 typedefed_type_sp->GetFullCompilerType();
1694 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1695 typedef_type_sp = typedefed_type_sp;
1696 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1697 }
1698 }
1699 strm.EOL();
1700 }
1701 return num_matches;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001702}
1703
Kate Stoneb9c1b512016-09-06 20:57:50 +00001704static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
1705 Stream &strm, Module *module,
1706 const FileSpec &file_spec,
1707 uint32_t line, bool check_inlines,
1708 bool verbose) {
1709 if (module && file_spec) {
1710 SymbolContextList sc_list;
1711 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1712 file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1713 if (num_matches > 0) {
1714 strm.Indent();
1715 strm.Printf("%u match%s found in ", num_matches,
1716 num_matches > 1 ? "es" : "");
1717 strm << file_spec;
1718 if (line > 0)
1719 strm.Printf(":%u", line);
1720 strm << " in ";
1721 DumpFullpath(strm, &module->GetFileSpec(), 0);
1722 strm.PutCString(":\n");
1723 DumpSymbolContextList(
1724 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1725 strm, sc_list, verbose);
1726 return num_matches;
Greg Clayton8ee64382011-11-10 01:18:58 +00001727 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001728 }
1729 return 0;
1730}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001731
Kate Stoneb9c1b512016-09-06 20:57:50 +00001732static size_t FindModulesByName(Target *target, const char *module_name,
1733 ModuleList &module_list,
1734 bool check_global_list) {
1735 FileSpec module_file_spec(module_name, false);
1736 ModuleSpec module_spec(module_file_spec);
1737
1738 const size_t initial_size = module_list.GetSize();
1739
1740 if (check_global_list) {
1741 // Check the global list
1742 std::lock_guard<std::recursive_mutex> guard(
1743 Module::GetAllocationModuleCollectionMutex());
1744 const size_t num_modules = Module::GetNumberAllocatedModules();
1745 ModuleSP module_sp;
1746 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1747 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1748
1749 if (module) {
1750 if (module->MatchesModuleSpec(module_spec)) {
1751 module_sp = module->shared_from_this();
1752 module_list.AppendIfNeeded(module_sp);
Greg Claytonf3156262012-07-11 20:46:47 +00001753 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001754 }
Greg Claytonf3156262012-07-11 20:46:47 +00001755 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001756 } else {
1757 if (target) {
1758 const size_t num_matches =
1759 target->GetImages().FindModules(module_spec, module_list);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001760
Kate Stoneb9c1b512016-09-06 20:57:50 +00001761 // Not found in our module list for our target, check the main
1762 // shared module list in case it is a extra file used somewhere
1763 // else
1764 if (num_matches == 0) {
1765 module_spec.GetArchitecture() = target->GetArchitecture();
1766 ModuleList::FindSharedModules(module_spec, module_list);
1767 }
1768 } else {
1769 ModuleList::FindSharedModules(module_spec, module_list);
1770 }
1771 }
1772
1773 return module_list.GetSize() - initial_size;
Greg Clayton8ee64382011-11-10 01:18:58 +00001774}
1775
Greg Claytoneffe5c92011-05-03 22:09:39 +00001776#pragma mark CommandObjectTargetModulesModuleAutoComplete
1777
1778//----------------------------------------------------------------------
1779// A base command object class that can auto complete with module file
1780// paths
1781//----------------------------------------------------------------------
1782
Kate Stoneb9c1b512016-09-06 20:57:50 +00001783class CommandObjectTargetModulesModuleAutoComplete
1784 : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001785public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001786 CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1787 const char *name,
1788 const char *help,
1789 const char *syntax)
1790 : CommandObjectParsed(interpreter, name, help, syntax) {
1791 CommandArgumentEntry arg;
1792 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001793
Kate Stoneb9c1b512016-09-06 20:57:50 +00001794 // Define the first (and only) variant of this arg.
1795 file_arg.arg_type = eArgTypeFilename;
1796 file_arg.arg_repetition = eArgRepeatStar;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001797
Kate Stoneb9c1b512016-09-06 20:57:50 +00001798 // There is only one variant this argument could be; put it into the
1799 // argument entry.
1800 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001801
Kate Stoneb9c1b512016-09-06 20:57:50 +00001802 // Push the data for the first argument into the m_arguments vector.
1803 m_arguments.push_back(arg);
1804 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001805
Kate Stoneb9c1b512016-09-06 20:57:50 +00001806 ~CommandObjectTargetModulesModuleAutoComplete() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001807
Kate Stoneb9c1b512016-09-06 20:57:50 +00001808 int HandleArgumentCompletion(Args &input, int &cursor_index,
1809 int &cursor_char_position,
1810 OptionElementVector &opt_element_vector,
1811 int match_start_point, int max_return_elements,
1812 bool &word_complete,
1813 StringList &matches) override {
1814 // Arguments are the standard module completer.
1815 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
1816 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001817
Kate Stoneb9c1b512016-09-06 20:57:50 +00001818 CommandCompletions::InvokeCommonCompletionCallbacks(
1819 GetCommandInterpreter(), CommandCompletions::eModuleCompletion,
1820 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
1821 word_complete, matches);
1822 return matches.GetSize();
1823 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001824};
1825
1826#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1827
1828//----------------------------------------------------------------------
1829// A base command object class that can auto complete with module source
1830// file paths
1831//----------------------------------------------------------------------
1832
Kate Stoneb9c1b512016-09-06 20:57:50 +00001833class CommandObjectTargetModulesSourceFileAutoComplete
1834 : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001835public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001836 CommandObjectTargetModulesSourceFileAutoComplete(
1837 CommandInterpreter &interpreter, const char *name, const char *help,
1838 const char *syntax, uint32_t flags)
1839 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1840 CommandArgumentEntry arg;
1841 CommandArgumentData source_file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001842
Kate Stoneb9c1b512016-09-06 20:57:50 +00001843 // Define the first (and only) variant of this arg.
1844 source_file_arg.arg_type = eArgTypeSourceFile;
1845 source_file_arg.arg_repetition = eArgRepeatPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001846
Kate Stoneb9c1b512016-09-06 20:57:50 +00001847 // There is only one variant this argument could be; put it into the
1848 // argument entry.
1849 arg.push_back(source_file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001850
Kate Stoneb9c1b512016-09-06 20:57:50 +00001851 // Push the data for the first argument into the m_arguments vector.
1852 m_arguments.push_back(arg);
1853 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001854
Kate Stoneb9c1b512016-09-06 20:57:50 +00001855 ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001856
Kate Stoneb9c1b512016-09-06 20:57:50 +00001857 int HandleArgumentCompletion(Args &input, int &cursor_index,
1858 int &cursor_char_position,
1859 OptionElementVector &opt_element_vector,
1860 int match_start_point, int max_return_elements,
1861 bool &word_complete,
1862 StringList &matches) override {
1863 // Arguments are the standard source file completer.
1864 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
1865 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001866
Kate Stoneb9c1b512016-09-06 20:57:50 +00001867 CommandCompletions::InvokeCommonCompletionCallbacks(
1868 GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
1869 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
1870 word_complete, matches);
1871 return matches.GetSize();
1872 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001873};
1874
Adrian McCarthy543725c2016-04-04 21:21:49 +00001875#pragma mark CommandObjectTargetModulesDumpObjfile
1876
Kate Stoneb9c1b512016-09-06 20:57:50 +00001877class CommandObjectTargetModulesDumpObjfile
1878 : public CommandObjectTargetModulesModuleAutoComplete {
Adrian McCarthy543725c2016-04-04 21:21:49 +00001879public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001880 CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
1881 : CommandObjectTargetModulesModuleAutoComplete(
1882 interpreter, "target modules dump objfile",
1883 "Dump the object file headers from one or more target modules.",
1884 nullptr) {}
Adrian McCarthy543725c2016-04-04 21:21:49 +00001885
Kate Stoneb9c1b512016-09-06 20:57:50 +00001886 ~CommandObjectTargetModulesDumpObjfile() override = default;
Adrian McCarthy543725c2016-04-04 21:21:49 +00001887
1888protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001889 bool DoExecute(Args &command, CommandReturnObject &result) override {
1890 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1891 if (target == nullptr) {
1892 result.AppendError("invalid target, create a debug target using the "
1893 "'target create' command");
1894 result.SetStatus(eReturnStatusFailed);
1895 return false;
Adrian McCarthy543725c2016-04-04 21:21:49 +00001896 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001897
1898 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1899 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1900 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1901
1902 size_t num_dumped = 0;
1903 if (command.GetArgumentCount() == 0) {
1904 // Dump all headers for all modules images
1905 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1906 target->GetImages());
1907 if (num_dumped == 0) {
1908 result.AppendError("the target has no associated executable images");
1909 result.SetStatus(eReturnStatusFailed);
1910 }
1911 } else {
1912 // Find the modules that match the basename or full path.
1913 ModuleList module_list;
1914 const char *arg_cstr;
1915 for (int arg_idx = 0;
1916 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1917 ++arg_idx) {
1918 size_t num_matched =
1919 FindModulesByName(target, arg_cstr, module_list, true);
1920 if (num_matched == 0) {
1921 result.AppendWarningWithFormat(
1922 "Unable to find an image that matches '%s'.\n", arg_cstr);
1923 }
1924 }
1925 // Dump all the modules we found.
1926 num_dumped =
1927 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1928 }
1929
1930 if (num_dumped > 0) {
1931 result.SetStatus(eReturnStatusSuccessFinishResult);
1932 } else {
1933 result.AppendError("no matching executable images found");
1934 result.SetStatus(eReturnStatusFailed);
1935 }
1936 return result.Succeeded();
1937 }
Adrian McCarthy543725c2016-04-04 21:21:49 +00001938};
1939
Greg Claytoneffe5c92011-05-03 22:09:39 +00001940#pragma mark CommandObjectTargetModulesDumpSymtab
1941
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001942static OptionEnumValueElement g_sort_option_enumeration[4] = {
1943 {eSortOrderNone, "none",
1944 "No sorting, use the original symbol table order."},
1945 {eSortOrderByAddress, "address", "Sort output by symbol address."},
1946 {eSortOrderByName, "name", "Sort output by symbol name."},
1947 {0, nullptr, nullptr}};
1948
1949static OptionDefinition g_target_modules_dump_symtab_options[] = {
1950 // clang-format off
1951 { LLDB_OPT_SET_1, false, "sort", 's', OptionParser::eRequiredArgument, nullptr, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table." }
1952 // clang-format on
1953};
1954
Kate Stoneb9c1b512016-09-06 20:57:50 +00001955class CommandObjectTargetModulesDumpSymtab
1956 : public CommandObjectTargetModulesModuleAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001957public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001958 CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
1959 : CommandObjectTargetModulesModuleAutoComplete(
1960 interpreter, "target modules dump symtab",
1961 "Dump the symbol table from one or more target modules.", nullptr),
1962 m_options() {}
1963
1964 ~CommandObjectTargetModulesDumpSymtab() override = default;
1965
1966 Options *GetOptions() override { return &m_options; }
1967
1968 class CommandOptions : public Options {
1969 public:
1970 CommandOptions() : Options(), m_sort_order(eSortOrderNone) {}
1971
1972 ~CommandOptions() override = default;
1973
1974 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
1975 ExecutionContext *execution_context) override {
1976 Error error;
1977 const int short_option = m_getopt_table[option_idx].val;
1978
1979 switch (short_option) {
1980 case 's':
1981 m_sort_order = (SortOrder)Args::StringToOptionEnum(
Zachary Turner8cef4b02016-09-23 17:48:13 +00001982 llvm::StringRef::withNullAsEmpty(option_arg),
1983 GetDefinitions()[option_idx].enum_values, eSortOrderNone, error);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001984 break;
1985
1986 default:
1987 error.SetErrorStringWithFormat("invalid short option character '%c'",
1988 short_option);
1989 break;
1990 }
1991 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001992 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001993
Kate Stoneb9c1b512016-09-06 20:57:50 +00001994 void OptionParsingStarting(ExecutionContext *execution_context) override {
1995 m_sort_order = eSortOrderNone;
Jim Ingham5a988412012-06-08 21:56:10 +00001996 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001997
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001998 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00001999 return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002000 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002001
Kate Stoneb9c1b512016-09-06 20:57:50 +00002002 SortOrder m_sort_order;
2003 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002004
Jim Ingham5a988412012-06-08 21:56:10 +00002005protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002006 bool DoExecute(Args &command, CommandReturnObject &result) override {
2007 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2008 if (target == nullptr) {
2009 result.AppendError("invalid target, create a debug target using the "
2010 "'target create' command");
2011 result.SetStatus(eReturnStatusFailed);
2012 return false;
2013 } else {
2014 uint32_t num_dumped = 0;
2015
2016 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2017 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2018 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2019
2020 if (command.GetArgumentCount() == 0) {
2021 // Dump all sections for all modules images
2022 std::lock_guard<std::recursive_mutex> guard(
2023 target->GetImages().GetMutex());
2024 const size_t num_modules = target->GetImages().GetSize();
2025 if (num_modules > 0) {
2026 result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
2027 " modules.\n",
2028 (uint64_t)num_modules);
2029 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2030 if (num_dumped > 0) {
2031 result.GetOutputStream().EOL();
2032 result.GetOutputStream().EOL();
2033 }
2034 num_dumped++;
2035 DumpModuleSymtab(
2036 m_interpreter, result.GetOutputStream(),
2037 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2038 m_options.m_sort_order);
2039 }
2040 } else {
2041 result.AppendError("the target has no associated executable images");
2042 result.SetStatus(eReturnStatusFailed);
2043 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002044 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002045 } else {
2046 // Dump specified images (by basename or fullpath)
2047 const char *arg_cstr;
2048 for (int arg_idx = 0;
2049 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2050 ++arg_idx) {
2051 ModuleList module_list;
2052 const size_t num_matches =
2053 FindModulesByName(target, arg_cstr, module_list, true);
2054 if (num_matches > 0) {
2055 for (size_t i = 0; i < num_matches; ++i) {
2056 Module *module = module_list.GetModulePointerAtIndex(i);
2057 if (module) {
2058 if (num_dumped > 0) {
2059 result.GetOutputStream().EOL();
2060 result.GetOutputStream().EOL();
Greg Claytoneffe5c92011-05-03 22:09:39 +00002061 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002062 num_dumped++;
2063 DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2064 module, m_options.m_sort_order);
2065 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002066 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002067 } else
2068 result.AppendWarningWithFormat(
2069 "Unable to find an image that matches '%s'.\n", arg_cstr);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002070 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002071 }
2072
2073 if (num_dumped > 0)
2074 result.SetStatus(eReturnStatusSuccessFinishResult);
2075 else {
2076 result.AppendError("no matching executable images found");
2077 result.SetStatus(eReturnStatusFailed);
2078 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002079 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002080 return result.Succeeded();
2081 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002082
Kate Stoneb9c1b512016-09-06 20:57:50 +00002083 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002084};
2085
Greg Claytoneffe5c92011-05-03 22:09:39 +00002086#pragma mark CommandObjectTargetModulesDumpSections
2087
2088//----------------------------------------------------------------------
2089// Image section dumping command
2090//----------------------------------------------------------------------
2091
Kate Stoneb9c1b512016-09-06 20:57:50 +00002092class CommandObjectTargetModulesDumpSections
2093 : public CommandObjectTargetModulesModuleAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002094public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002095 CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
2096 : CommandObjectTargetModulesModuleAutoComplete(
2097 interpreter, "target modules dump sections",
2098 "Dump the sections from one or more target modules.",
2099 //"target modules dump sections [<file1> ...]")
2100 nullptr) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002101
Kate Stoneb9c1b512016-09-06 20:57:50 +00002102 ~CommandObjectTargetModulesDumpSections() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002103
Jim Ingham5a988412012-06-08 21:56:10 +00002104protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002105 bool DoExecute(Args &command, CommandReturnObject &result) override {
2106 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2107 if (target == nullptr) {
2108 result.AppendError("invalid target, create a debug target using the "
2109 "'target create' command");
2110 result.SetStatus(eReturnStatusFailed);
2111 return false;
2112 } else {
2113 uint32_t num_dumped = 0;
2114
2115 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2116 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2117 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2118
2119 if (command.GetArgumentCount() == 0) {
2120 // Dump all sections for all modules images
2121 const size_t num_modules = target->GetImages().GetSize();
2122 if (num_modules > 0) {
2123 result.GetOutputStream().Printf("Dumping sections for %" PRIu64
2124 " modules.\n",
2125 (uint64_t)num_modules);
2126 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2127 num_dumped++;
2128 DumpModuleSections(
2129 m_interpreter, result.GetOutputStream(),
2130 target->GetImages().GetModulePointerAtIndex(image_idx));
2131 }
2132 } else {
2133 result.AppendError("the target has no associated executable images");
2134 result.SetStatus(eReturnStatusFailed);
2135 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002136 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002137 } else {
2138 // Dump specified images (by basename or fullpath)
2139 const char *arg_cstr;
2140 for (int arg_idx = 0;
2141 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2142 ++arg_idx) {
2143 ModuleList module_list;
2144 const size_t num_matches =
2145 FindModulesByName(target, arg_cstr, module_list, true);
2146 if (num_matches > 0) {
2147 for (size_t i = 0; i < num_matches; ++i) {
2148 Module *module = module_list.GetModulePointerAtIndex(i);
2149 if (module) {
2150 num_dumped++;
2151 DumpModuleSections(m_interpreter, result.GetOutputStream(),
2152 module);
2153 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002154 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002155 } else {
2156 // Check the global list
2157 std::lock_guard<std::recursive_mutex> guard(
2158 Module::GetAllocationModuleCollectionMutex());
Greg Clayton8ee64382011-11-10 01:18:58 +00002159
Kate Stoneb9c1b512016-09-06 20:57:50 +00002160 result.AppendWarningWithFormat(
2161 "Unable to find an image that matches '%s'.\n", arg_cstr);
2162 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002163 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002164 }
2165
2166 if (num_dumped > 0)
2167 result.SetStatus(eReturnStatusSuccessFinishResult);
2168 else {
2169 result.AppendError("no matching executable images found");
2170 result.SetStatus(eReturnStatusFailed);
2171 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002172 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002173 return result.Succeeded();
2174 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002175};
2176
Greg Claytoneffe5c92011-05-03 22:09:39 +00002177#pragma mark CommandObjectTargetModulesDumpSymfile
2178
2179//----------------------------------------------------------------------
2180// Image debug symbol dumping command
2181//----------------------------------------------------------------------
2182
Kate Stoneb9c1b512016-09-06 20:57:50 +00002183class CommandObjectTargetModulesDumpSymfile
2184 : public CommandObjectTargetModulesModuleAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002185public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002186 CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
2187 : CommandObjectTargetModulesModuleAutoComplete(
2188 interpreter, "target modules dump symfile",
2189 "Dump the debug symbol file for one or more target modules.",
2190 //"target modules dump symfile [<file1> ...]")
2191 nullptr) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002192
Kate Stoneb9c1b512016-09-06 20:57:50 +00002193 ~CommandObjectTargetModulesDumpSymfile() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002194
Jim Ingham5a988412012-06-08 21:56:10 +00002195protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002196 bool DoExecute(Args &command, CommandReturnObject &result) override {
2197 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2198 if (target == nullptr) {
2199 result.AppendError("invalid target, create a debug target using the "
2200 "'target create' command");
2201 result.SetStatus(eReturnStatusFailed);
2202 return false;
2203 } else {
2204 uint32_t num_dumped = 0;
2205
2206 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2207 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2208 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2209
2210 if (command.GetArgumentCount() == 0) {
2211 // Dump all sections for all modules images
2212 const ModuleList &target_modules = target->GetImages();
2213 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2214 const size_t num_modules = target_modules.GetSize();
2215 if (num_modules > 0) {
2216 result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
2217 " modules.\n",
2218 (uint64_t)num_modules);
2219 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2220 if (DumpModuleSymbolVendor(
2221 result.GetOutputStream(),
2222 target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2223 num_dumped++;
2224 }
2225 } else {
2226 result.AppendError("the target has no associated executable images");
2227 result.SetStatus(eReturnStatusFailed);
2228 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002229 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002230 } else {
2231 // Dump specified images (by basename or fullpath)
2232 const char *arg_cstr;
2233 for (int arg_idx = 0;
2234 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2235 ++arg_idx) {
2236 ModuleList module_list;
2237 const size_t num_matches =
2238 FindModulesByName(target, arg_cstr, module_list, true);
2239 if (num_matches > 0) {
2240 for (size_t i = 0; i < num_matches; ++i) {
2241 Module *module = module_list.GetModulePointerAtIndex(i);
2242 if (module) {
2243 if (DumpModuleSymbolVendor(result.GetOutputStream(), module))
2244 num_dumped++;
2245 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002246 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002247 } else
2248 result.AppendWarningWithFormat(
2249 "Unable to find an image that matches '%s'.\n", arg_cstr);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002250 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002251 }
2252
2253 if (num_dumped > 0)
2254 result.SetStatus(eReturnStatusSuccessFinishResult);
2255 else {
2256 result.AppendError("no matching executable images found");
2257 result.SetStatus(eReturnStatusFailed);
2258 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002259 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002260 return result.Succeeded();
2261 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002262};
2263
Greg Claytoneffe5c92011-05-03 22:09:39 +00002264#pragma mark CommandObjectTargetModulesDumpLineTable
2265
2266//----------------------------------------------------------------------
2267// Image debug line table dumping command
2268//----------------------------------------------------------------------
2269
Kate Stoneb9c1b512016-09-06 20:57:50 +00002270class CommandObjectTargetModulesDumpLineTable
2271 : public CommandObjectTargetModulesSourceFileAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002272public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002273 CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
2274 : CommandObjectTargetModulesSourceFileAutoComplete(
2275 interpreter, "target modules dump line-table",
2276 "Dump the line table for one or more compilation units.", nullptr,
2277 eCommandRequiresTarget) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002278
Kate Stoneb9c1b512016-09-06 20:57:50 +00002279 ~CommandObjectTargetModulesDumpLineTable() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002280
Jim Ingham5a988412012-06-08 21:56:10 +00002281protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002282 bool DoExecute(Args &command, CommandReturnObject &result) override {
2283 Target *target = m_exe_ctx.GetTargetPtr();
2284 uint32_t total_num_dumped = 0;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002285
Kate Stoneb9c1b512016-09-06 20:57:50 +00002286 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2287 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2288 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002289
Kate Stoneb9c1b512016-09-06 20:57:50 +00002290 if (command.GetArgumentCount() == 0) {
2291 result.AppendError("file option must be specified.");
2292 result.SetStatus(eReturnStatusFailed);
2293 return result.Succeeded();
2294 } else {
2295 // Dump specified images (by basename or fullpath)
2296 const char *arg_cstr;
2297 for (int arg_idx = 0;
2298 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2299 ++arg_idx) {
2300 FileSpec file_spec(arg_cstr, false);
2301
2302 const ModuleList &target_modules = target->GetImages();
2303 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2304 const size_t num_modules = target_modules.GetSize();
2305 if (num_modules > 0) {
2306 uint32_t num_dumped = 0;
2307 for (uint32_t i = 0; i < num_modules; ++i) {
2308 if (DumpCompileUnitLineTable(
2309 m_interpreter, result.GetOutputStream(),
2310 target_modules.GetModulePointerAtIndexUnlocked(i),
2311 file_spec, m_exe_ctx.GetProcessPtr() &&
2312 m_exe_ctx.GetProcessRef().IsAlive()))
2313 num_dumped++;
2314 }
2315 if (num_dumped == 0)
2316 result.AppendWarningWithFormat(
2317 "No source filenames matched '%s'.\n", arg_cstr);
2318 else
2319 total_num_dumped += num_dumped;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002320 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002321 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002322 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002323
2324 if (total_num_dumped > 0)
2325 result.SetStatus(eReturnStatusSuccessFinishResult);
2326 else {
2327 result.AppendError("no source filenames matched any command arguments");
2328 result.SetStatus(eReturnStatusFailed);
2329 }
2330 return result.Succeeded();
2331 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002332};
2333
Greg Claytoneffe5c92011-05-03 22:09:39 +00002334#pragma mark CommandObjectTargetModulesDump
2335
2336//----------------------------------------------------------------------
2337// Dump multi-word command for target modules
2338//----------------------------------------------------------------------
2339
Kate Stoneb9c1b512016-09-06 20:57:50 +00002340class CommandObjectTargetModulesDump : public CommandObjectMultiword {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002341public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002342 //------------------------------------------------------------------
2343 // Constructors and Destructors
2344 //------------------------------------------------------------------
2345 CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2346 : CommandObjectMultiword(interpreter, "target modules dump",
2347 "Commands for dumping information about one or "
2348 "more target modules.",
2349 "target modules dump "
2350 "[headers|symtab|sections|symfile|line-table] "
2351 "[<file1> <file2> ...]") {
2352 LoadSubCommand("objfile",
2353 CommandObjectSP(
2354 new CommandObjectTargetModulesDumpObjfile(interpreter)));
2355 LoadSubCommand(
2356 "symtab",
2357 CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
2358 LoadSubCommand("sections",
2359 CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2360 interpreter)));
2361 LoadSubCommand("symfile",
2362 CommandObjectSP(
2363 new CommandObjectTargetModulesDumpSymfile(interpreter)));
2364 LoadSubCommand("line-table",
2365 CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2366 interpreter)));
2367 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002368
Kate Stoneb9c1b512016-09-06 20:57:50 +00002369 ~CommandObjectTargetModulesDump() override = default;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002370};
2371
Kate Stoneb9c1b512016-09-06 20:57:50 +00002372class CommandObjectTargetModulesAdd : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002373public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002374 CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
2375 : CommandObjectParsed(interpreter, "target modules add",
2376 "Add a new module to the current target's modules.",
2377 "target modules add [<module>]"),
Todd Fialae1cfbc72016-08-11 23:51:28 +00002378 m_option_group(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00002379 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2380 eArgTypeFilename, "Fullpath to a stand alone debug "
2381 "symbols file for when debug symbols "
2382 "are not in the executable.") {
2383 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2384 LLDB_OPT_SET_1);
2385 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2386 m_option_group.Finalize();
2387 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002388
Kate Stoneb9c1b512016-09-06 20:57:50 +00002389 ~CommandObjectTargetModulesAdd() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002390
Kate Stoneb9c1b512016-09-06 20:57:50 +00002391 Options *GetOptions() override { return &m_option_group; }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002392
Kate Stoneb9c1b512016-09-06 20:57:50 +00002393 int HandleArgumentCompletion(Args &input, int &cursor_index,
2394 int &cursor_char_position,
2395 OptionElementVector &opt_element_vector,
2396 int match_start_point, int max_return_elements,
2397 bool &word_complete,
2398 StringList &matches) override {
2399 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
2400 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002401
Kate Stoneb9c1b512016-09-06 20:57:50 +00002402 CommandCompletions::InvokeCommonCompletionCallbacks(
2403 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2404 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
2405 word_complete, matches);
2406 return matches.GetSize();
2407 }
Jim Ingham5a988412012-06-08 21:56:10 +00002408
2409protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002410 OptionGroupOptions m_option_group;
2411 OptionGroupUUID m_uuid_option_group;
2412 OptionGroupFile m_symbol_file;
Greg Clayton50a24bd2012-11-29 22:16:27 +00002413
Kate Stoneb9c1b512016-09-06 20:57:50 +00002414 bool DoExecute(Args &args, CommandReturnObject &result) override {
2415 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2416 if (target == nullptr) {
2417 result.AppendError("invalid target, create a debug target using the "
2418 "'target create' command");
2419 result.SetStatus(eReturnStatusFailed);
2420 return false;
2421 } else {
2422 bool flush = false;
2423
2424 const size_t argc = args.GetArgumentCount();
2425 if (argc == 0) {
2426 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2427 // We are given a UUID only, go locate the file
2428 ModuleSpec module_spec;
2429 module_spec.GetUUID() =
2430 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2431 if (m_symbol_file.GetOptionValue().OptionWasSet())
2432 module_spec.GetSymbolFileSpec() =
2433 m_symbol_file.GetOptionValue().GetCurrentValue();
2434 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
2435 ModuleSP module_sp(target->GetSharedModule(module_spec));
2436 if (module_sp) {
2437 result.SetStatus(eReturnStatusSuccessFinishResult);
2438 return true;
2439 } else {
2440 StreamString strm;
2441 module_spec.GetUUID().Dump(&strm);
2442 if (module_spec.GetFileSpec()) {
2443 if (module_spec.GetSymbolFileSpec()) {
2444 result.AppendErrorWithFormat(
2445 "Unable to create the executable or symbol file with "
2446 "UUID %s with path %s and symbol file %s",
2447 strm.GetString().c_str(),
2448 module_spec.GetFileSpec().GetPath().c_str(),
2449 module_spec.GetSymbolFileSpec().GetPath().c_str());
2450 } else {
2451 result.AppendErrorWithFormat(
2452 "Unable to create the executable or symbol file with "
2453 "UUID %s with path %s",
2454 strm.GetString().c_str(),
2455 module_spec.GetFileSpec().GetPath().c_str());
2456 }
2457 } else {
2458 result.AppendErrorWithFormat("Unable to create the executable "
2459 "or symbol file with UUID %s",
2460 strm.GetString().c_str());
2461 }
2462 result.SetStatus(eReturnStatusFailed);
2463 return false;
2464 }
2465 } else {
2466 StreamString strm;
2467 module_spec.GetUUID().Dump(&strm);
2468 result.AppendErrorWithFormat(
2469 "Unable to locate the executable or symbol file with UUID %s",
2470 strm.GetString().c_str());
2471 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002472 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002473 }
2474 } else {
2475 result.AppendError(
2476 "one or more executable image paths must be specified");
2477 result.SetStatus(eReturnStatusFailed);
2478 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002479 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002480 } else {
Zachary Turner97d2c402016-10-05 23:40:23 +00002481 for (auto &entry : args.entries()) {
2482 if (entry.ref.empty())
2483 continue;
2484
2485 FileSpec file_spec(entry.ref, true);
2486 if (file_spec.Exists()) {
2487 ModuleSpec module_spec(file_spec);
2488 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2489 module_spec.GetUUID() =
2490 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2491 if (m_symbol_file.GetOptionValue().OptionWasSet())
2492 module_spec.GetSymbolFileSpec() =
2493 m_symbol_file.GetOptionValue().GetCurrentValue();
2494 if (!module_spec.GetArchitecture().IsValid())
2495 module_spec.GetArchitecture() = target->GetArchitecture();
2496 Error error;
2497 ModuleSP module_sp(target->GetSharedModule(module_spec, &error));
2498 if (!module_sp) {
2499 const char *error_cstr = error.AsCString();
2500 if (error_cstr)
2501 result.AppendError(error_cstr);
2502 else
2503 result.AppendErrorWithFormat("unsupported module: %s",
2504 entry.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002505 result.SetStatus(eReturnStatusFailed);
Zachary Turner97d2c402016-10-05 23:40:23 +00002506 return false;
2507 } else {
2508 flush = true;
2509 }
2510 result.SetStatus(eReturnStatusSuccessFinishResult);
2511 } else {
2512 std::string resolved_path = file_spec.GetPath();
2513 result.SetStatus(eReturnStatusFailed);
2514 if (resolved_path != entry.ref) {
2515 result.AppendErrorWithFormat(
2516 "invalid module path '%s' with resolved path '%s'\n",
2517 entry.ref.str().c_str(), resolved_path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002518 break;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002519 }
Zachary Turner97d2c402016-10-05 23:40:23 +00002520 result.AppendErrorWithFormat("invalid module path '%s'\n",
2521 entry.c_str());
2522 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002523 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002524 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002525 }
2526
2527 if (flush) {
2528 ProcessSP process = target->GetProcessSP();
2529 if (process)
2530 process->Flush();
2531 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002532 }
2533
Kate Stoneb9c1b512016-09-06 20:57:50 +00002534 return result.Succeeded();
2535 }
2536};
2537
2538class CommandObjectTargetModulesLoad
2539 : public CommandObjectTargetModulesModuleAutoComplete {
2540public:
2541 CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
2542 : CommandObjectTargetModulesModuleAutoComplete(
2543 interpreter, "target modules load", "Set the load addresses for "
2544 "one or more sections in a "
2545 "target module.",
2546 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2547 "<address> [<sect-name> <address> ....]"),
2548 m_option_group(),
2549 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2550 "Fullpath or basename for module to load.", ""),
2551 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2552 "Set the load address for all sections to be the "
2553 "virtual address in the file plus the offset.",
2554 0) {
2555 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2556 LLDB_OPT_SET_1);
2557 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2558 m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2559 m_option_group.Finalize();
2560 }
2561
2562 ~CommandObjectTargetModulesLoad() override = default;
2563
2564 Options *GetOptions() override { return &m_option_group; }
2565
2566protected:
2567 bool DoExecute(Args &args, CommandReturnObject &result) override {
2568 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2569 if (target == nullptr) {
2570 result.AppendError("invalid target, create a debug target using the "
2571 "'target create' command");
2572 result.SetStatus(eReturnStatusFailed);
2573 return false;
2574 } else {
2575 const size_t argc = args.GetArgumentCount();
2576 ModuleSpec module_spec;
2577 bool search_using_module_spec = false;
2578 if (m_file_option.GetOptionValue().OptionWasSet()) {
2579 search_using_module_spec = true;
2580 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2581 const bool use_global_module_list = true;
2582 ModuleList module_list;
2583 const size_t num_matches = FindModulesByName(
2584 target, arg_cstr, module_list, use_global_module_list);
2585 if (num_matches == 1) {
2586 module_spec.GetFileSpec() =
2587 module_list.GetModuleAtIndex(0)->GetFileSpec();
2588 } else if (num_matches > 1) {
2589 search_using_module_spec = false;
2590 result.AppendErrorWithFormat(
2591 "more than 1 module matched by name '%s'\n", arg_cstr);
2592 result.SetStatus(eReturnStatusFailed);
2593 } else {
2594 search_using_module_spec = false;
2595 result.AppendErrorWithFormat("no object file for module '%s'\n",
2596 arg_cstr);
2597 result.SetStatus(eReturnStatusFailed);
2598 }
2599 }
2600
2601 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2602 search_using_module_spec = true;
2603 module_spec.GetUUID() =
2604 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2605 }
2606
2607 if (search_using_module_spec) {
2608 ModuleList matching_modules;
2609 const size_t num_matches =
2610 target->GetImages().FindModules(module_spec, matching_modules);
2611
2612 char path[PATH_MAX];
2613 if (num_matches == 1) {
2614 Module *module = matching_modules.GetModulePointerAtIndex(0);
2615 if (module) {
2616 ObjectFile *objfile = module->GetObjectFile();
2617 if (objfile) {
2618 SectionList *section_list = module->GetSectionList();
2619 if (section_list) {
2620 bool changed = false;
2621 if (argc == 0) {
2622 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2623 const addr_t slide =
2624 m_slide_option.GetOptionValue().GetCurrentValue();
2625 const bool slide_is_offset = true;
2626 module->SetLoadAddress(*target, slide, slide_is_offset,
2627 changed);
2628 } else {
2629 result.AppendError("one or more section name + load "
2630 "address pair must be specified");
2631 result.SetStatus(eReturnStatusFailed);
2632 return false;
2633 }
2634 } else {
2635 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2636 result.AppendError("The \"--slide <offset>\" option can't "
2637 "be used in conjunction with setting "
2638 "section load addresses.\n");
2639 result.SetStatus(eReturnStatusFailed);
2640 return false;
2641 }
2642
2643 for (size_t i = 0; i < argc; i += 2) {
2644 const char *sect_name = args.GetArgumentAtIndex(i);
2645 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2646 if (sect_name && load_addr_cstr) {
2647 ConstString const_sect_name(sect_name);
2648 bool success = false;
2649 addr_t load_addr = StringConvert::ToUInt64(
2650 load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2651 if (success) {
2652 SectionSP section_sp(
2653 section_list->FindSectionByName(const_sect_name));
2654 if (section_sp) {
2655 if (section_sp->IsThreadSpecific()) {
2656 result.AppendErrorWithFormat(
2657 "thread specific sections are not yet "
2658 "supported (section '%s')\n",
2659 sect_name);
2660 result.SetStatus(eReturnStatusFailed);
2661 break;
2662 } else {
2663 if (target->GetSectionLoadList()
2664 .SetSectionLoadAddress(section_sp,
2665 load_addr))
2666 changed = true;
2667 result.AppendMessageWithFormat(
2668 "section '%s' loaded at 0x%" PRIx64 "\n",
2669 sect_name, load_addr);
2670 }
2671 } else {
2672 result.AppendErrorWithFormat("no section found that "
2673 "matches the section "
2674 "name '%s'\n",
2675 sect_name);
2676 result.SetStatus(eReturnStatusFailed);
2677 break;
2678 }
2679 } else {
2680 result.AppendErrorWithFormat(
2681 "invalid load address string '%s'\n",
2682 load_addr_cstr);
2683 result.SetStatus(eReturnStatusFailed);
2684 break;
2685 }
2686 } else {
2687 if (sect_name)
2688 result.AppendError("section names must be followed by "
2689 "a load address.\n");
2690 else
2691 result.AppendError("one or more section name + load "
2692 "address pair must be specified.\n");
2693 result.SetStatus(eReturnStatusFailed);
2694 break;
2695 }
2696 }
2697 }
2698
2699 if (changed) {
2700 target->ModulesDidLoad(matching_modules);
2701 Process *process = m_exe_ctx.GetProcessPtr();
2702 if (process)
2703 process->Flush();
2704 }
2705 } else {
2706 module->GetFileSpec().GetPath(path, sizeof(path));
2707 result.AppendErrorWithFormat(
2708 "no sections in object file '%s'\n", path);
2709 result.SetStatus(eReturnStatusFailed);
2710 }
2711 } else {
2712 module->GetFileSpec().GetPath(path, sizeof(path));
2713 result.AppendErrorWithFormat("no object file for module '%s'\n",
2714 path);
2715 result.SetStatus(eReturnStatusFailed);
2716 }
2717 } else {
2718 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2719 if (module_spec_file) {
2720 module_spec_file->GetPath(path, sizeof(path));
2721 result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2722 } else
2723 result.AppendError("no module spec");
2724 result.SetStatus(eReturnStatusFailed);
2725 }
2726 } else {
2727 std::string uuid_str;
2728
2729 if (module_spec.GetFileSpec())
2730 module_spec.GetFileSpec().GetPath(path, sizeof(path));
2731 else
2732 path[0] = '\0';
2733
2734 if (module_spec.GetUUIDPtr())
2735 uuid_str = module_spec.GetUUID().GetAsString();
2736 if (num_matches > 1) {
2737 result.AppendErrorWithFormat(
2738 "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2739 path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2740 for (size_t i = 0; i < num_matches; ++i) {
2741 if (matching_modules.GetModulePointerAtIndex(i)
2742 ->GetFileSpec()
2743 .GetPath(path, sizeof(path)))
2744 result.AppendMessageWithFormat("%s\n", path);
2745 }
2746 } else {
2747 result.AppendErrorWithFormat(
2748 "no modules were found that match%s%s%s%s.\n",
2749 path[0] ? " file=" : "", path,
2750 !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2751 }
2752 result.SetStatus(eReturnStatusFailed);
2753 }
2754 } else {
2755 result.AppendError("either the \"--file <module>\" or the \"--uuid "
2756 "<uuid>\" option must be specified.\n");
2757 result.SetStatus(eReturnStatusFailed);
2758 return false;
2759 }
2760 }
2761 return result.Succeeded();
2762 }
2763
2764 OptionGroupOptions m_option_group;
2765 OptionGroupUUID m_uuid_option_group;
2766 OptionGroupString m_file_option;
2767 OptionGroupUInt64 m_slide_option;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002768};
2769
2770//----------------------------------------------------------------------
2771// List images with associated information
2772//----------------------------------------------------------------------
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002773
2774static OptionDefinition g_target_modules_list_options[] = {
2775 // clang-format off
2776 { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Display the image at this address." },
2777 { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the architecture when listing images." },
2778 { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the triple when listing images." },
2779 { LLDB_OPT_SET_1, false, "header", 'h', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise." },
2780 { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)." },
2781 { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the UUID when listing images." },
2782 { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image object file." },
2783 { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the directory with optional width for the image object file." },
2784 { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the basename with optional width for the image object file." },
2785 { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width." },
2786 { LLDB_OPT_SET_1, false, "symfile-unique", 'S', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file." },
2787 { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the modification time with optional width of the module." },
2788 { LLDB_OPT_SET_1, false, "ref-count", 'r', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache." },
2789 { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the module pointer." },
2790 { LLDB_OPT_SET_1, false, "global", 'g', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target." }
2791 // clang-format on
2792};
2793
Kate Stoneb9c1b512016-09-06 20:57:50 +00002794class CommandObjectTargetModulesList : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002795public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002796 class CommandOptions : public Options {
2797 public:
2798 CommandOptions()
2799 : Options(), m_format_array(), m_use_global_module_list(false),
2800 m_module_addr(LLDB_INVALID_ADDRESS) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002801
Kate Stoneb9c1b512016-09-06 20:57:50 +00002802 ~CommandOptions() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002803
Kate Stoneb9c1b512016-09-06 20:57:50 +00002804 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
2805 ExecutionContext *execution_context) override {
2806 Error error;
Greg Claytonb9d5df52012-12-06 22:49:16 +00002807
Kate Stoneb9c1b512016-09-06 20:57:50 +00002808 const int short_option = m_getopt_table[option_idx].val;
2809 if (short_option == 'g') {
2810 m_use_global_module_list = true;
2811 } else if (short_option == 'a') {
2812 m_module_addr = Args::StringToAddress(execution_context, option_arg,
2813 LLDB_INVALID_ADDRESS, &error);
2814 } else {
2815 unsigned long width = 0;
2816 if (option_arg)
2817 width = strtoul(option_arg, nullptr, 0);
2818 m_format_array.push_back(std::make_pair(short_option, width));
2819 }
2820 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002821 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002822
Kate Stoneb9c1b512016-09-06 20:57:50 +00002823 void OptionParsingStarting(ExecutionContext *execution_context) override {
2824 m_format_array.clear();
2825 m_use_global_module_list = false;
2826 m_module_addr = LLDB_INVALID_ADDRESS;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002827 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002828
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002829 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00002830 return llvm::makeArrayRef(g_target_modules_list_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002831 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002832
2833 // Instance variables to hold the values for command options.
2834 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
2835 FormatWidthCollection m_format_array;
2836 bool m_use_global_module_list;
2837 lldb::addr_t m_module_addr;
2838 };
2839
2840 CommandObjectTargetModulesList(CommandInterpreter &interpreter)
2841 : CommandObjectParsed(
2842 interpreter, "target modules list",
2843 "List current executable and dependent shared library images.",
2844 "target modules list [<cmd-options>]"),
2845 m_options() {}
2846
2847 ~CommandObjectTargetModulesList() override = default;
2848
2849 Options *GetOptions() override { return &m_options; }
2850
Jim Ingham5a988412012-06-08 21:56:10 +00002851protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002852 bool DoExecute(Args &command, CommandReturnObject &result) override {
2853 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2854 const bool use_global_module_list = m_options.m_use_global_module_list;
2855 // Define a local module list here to ensure it lives longer than any
2856 // "locker"
2857 // object which might lock its contents below (through the "module_list_ptr"
2858 // variable).
2859 ModuleList module_list;
2860 if (target == nullptr && !use_global_module_list) {
2861 result.AppendError("invalid target, create a debug target using the "
2862 "'target create' command");
2863 result.SetStatus(eReturnStatusFailed);
2864 return false;
2865 } else {
2866 if (target) {
2867 uint32_t addr_byte_size =
2868 target->GetArchitecture().GetAddressByteSize();
2869 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2870 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2871 }
2872 // Dump all sections for all modules images
2873 Stream &strm = result.GetOutputStream();
2874
2875 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
2876 if (target) {
2877 Address module_address;
2878 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
2879 ModuleSP module_sp(module_address.GetModule());
2880 if (module_sp) {
2881 PrintModule(target, module_sp.get(), 0, strm);
2882 result.SetStatus(eReturnStatusSuccessFinishResult);
2883 } else {
2884 result.AppendErrorWithFormat(
2885 "Couldn't find module matching address: 0x%" PRIx64 ".",
2886 m_options.m_module_addr);
2887 result.SetStatus(eReturnStatusFailed);
Greg Clayton3418c852011-08-10 02:10:13 +00002888 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002889 } else {
2890 result.AppendErrorWithFormat(
2891 "Couldn't find module containing address: 0x%" PRIx64 ".",
2892 m_options.m_module_addr);
2893 result.SetStatus(eReturnStatusFailed);
2894 }
2895 } else {
2896 result.AppendError(
2897 "Can only look up modules by address with a valid target.");
2898 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002899 }
2900 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002901 }
Jim Inghamc10312c2011-10-24 18:36:33 +00002902
Kate Stoneb9c1b512016-09-06 20:57:50 +00002903 size_t num_modules = 0;
2904
2905 // This locker will be locked on the mutex in module_list_ptr if it is
2906 // non-nullptr.
2907 // Otherwise it will lock the AllocationModuleCollectionMutex when
2908 // accessing
2909 // the global module list directly.
2910 std::unique_lock<std::recursive_mutex> guard(
2911 Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
2912
2913 const ModuleList *module_list_ptr = nullptr;
2914 const size_t argc = command.GetArgumentCount();
2915 if (argc == 0) {
2916 if (use_global_module_list) {
2917 guard.lock();
2918 num_modules = Module::GetNumberAllocatedModules();
2919 } else {
2920 module_list_ptr = &target->GetImages();
Jim Ingham28eb5712012-10-12 17:34:26 +00002921 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002922 } else {
Zachary Turner97d2c402016-10-05 23:40:23 +00002923 // TODO: Convert to entry based iteration. Requires converting
2924 // FindModulesByName.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002925 for (size_t i = 0; i < argc; ++i) {
2926 // Dump specified images (by basename or fullpath)
2927 const char *arg_cstr = command.GetArgumentAtIndex(i);
2928 const size_t num_matches = FindModulesByName(
2929 target, arg_cstr, module_list, use_global_module_list);
2930 if (num_matches == 0) {
2931 if (argc == 1) {
2932 result.AppendErrorWithFormat("no modules found that match '%s'",
2933 arg_cstr);
2934 result.SetStatus(eReturnStatusFailed);
2935 return false;
Jim Inghamc10312c2011-10-24 18:36:33 +00002936 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002937 }
Greg Claytonc9660542012-02-05 02:38:54 +00002938 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002939
2940 module_list_ptr = &module_list;
2941 }
2942
2943 std::unique_lock<std::recursive_mutex> lock;
2944 if (module_list_ptr != nullptr) {
2945 lock =
2946 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
2947
2948 num_modules = module_list_ptr->GetSize();
2949 }
2950
2951 if (num_modules > 0) {
2952 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2953 ModuleSP module_sp;
2954 Module *module;
2955 if (module_list_ptr) {
2956 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
2957 module = module_sp.get();
2958 } else {
2959 module = Module::GetAllocatedModuleAtIndex(image_idx);
2960 module_sp = module->shared_from_this();
2961 }
2962
2963 const size_t indent = strm.Printf("[%3u] ", image_idx);
2964 PrintModule(target, module, indent, strm);
Jim Inghamc10312c2011-10-24 18:36:33 +00002965 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002966 result.SetStatus(eReturnStatusSuccessFinishResult);
2967 } else {
2968 if (argc) {
2969 if (use_global_module_list)
2970 result.AppendError(
2971 "the global module list has no matching modules");
2972 else
2973 result.AppendError("the target has no matching modules");
2974 } else {
2975 if (use_global_module_list)
2976 result.AppendError("the global module list is empty");
2977 else
2978 result.AppendError(
2979 "the target has no associated executable images");
2980 }
2981 result.SetStatus(eReturnStatusFailed);
2982 return false;
2983 }
2984 }
2985 return result.Succeeded();
2986 }
2987
2988 void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
2989 if (module == nullptr) {
2990 strm.PutCString("Null module");
2991 return;
Jim Inghamc10312c2011-10-24 18:36:33 +00002992 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002993
Kate Stoneb9c1b512016-09-06 20:57:50 +00002994 bool dump_object_name = false;
2995 if (m_options.m_format_array.empty()) {
2996 m_options.m_format_array.push_back(std::make_pair('u', 0));
2997 m_options.m_format_array.push_back(std::make_pair('h', 0));
2998 m_options.m_format_array.push_back(std::make_pair('f', 0));
2999 m_options.m_format_array.push_back(std::make_pair('S', 0));
3000 }
3001 const size_t num_entries = m_options.m_format_array.size();
3002 bool print_space = false;
3003 for (size_t i = 0; i < num_entries; ++i) {
3004 if (print_space)
3005 strm.PutChar(' ');
3006 print_space = true;
3007 const char format_char = m_options.m_format_array[i].first;
3008 uint32_t width = m_options.m_format_array[i].second;
3009 switch (format_char) {
3010 case 'A':
3011 DumpModuleArchitecture(strm, module, false, width);
3012 break;
3013
3014 case 't':
3015 DumpModuleArchitecture(strm, module, true, width);
3016 break;
3017
3018 case 'f':
3019 DumpFullpath(strm, &module->GetFileSpec(), width);
3020 dump_object_name = true;
3021 break;
3022
3023 case 'd':
3024 DumpDirectory(strm, &module->GetFileSpec(), width);
3025 break;
3026
3027 case 'b':
3028 DumpBasename(strm, &module->GetFileSpec(), width);
3029 dump_object_name = true;
3030 break;
3031
3032 case 'h':
3033 case 'o':
3034 // Image header address
3035 {
3036 uint32_t addr_nibble_width =
3037 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3038 : 16;
3039
3040 ObjectFile *objfile = module->GetObjectFile();
3041 if (objfile) {
3042 Address header_addr(objfile->GetHeaderAddress());
3043 if (header_addr.IsValid()) {
3044 if (target && !target->GetSectionLoadList().IsEmpty()) {
3045 lldb::addr_t header_load_addr =
3046 header_addr.GetLoadAddress(target);
3047 if (header_load_addr == LLDB_INVALID_ADDRESS) {
3048 header_addr.Dump(&strm, target,
3049 Address::DumpStyleModuleWithFileAddress,
3050 Address::DumpStyleFileAddress);
3051 } else {
3052 if (format_char == 'o') {
3053 // Show the offset of slide for the image
3054 strm.Printf(
3055 "0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width,
3056 header_load_addr - header_addr.GetFileAddress());
3057 } else {
3058 // Show the load address of the image
3059 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3060 addr_nibble_width, header_load_addr);
3061 }
3062 }
3063 break;
3064 }
3065 // The address was valid, but the image isn't loaded, output the
3066 // address in an appropriate format
3067 header_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3068 break;
3069 }
3070 }
3071 strm.Printf("%*s", addr_nibble_width + 2, "");
3072 }
3073 break;
3074
3075 case 'r': {
3076 size_t ref_count = 0;
3077 ModuleSP module_sp(module->shared_from_this());
3078 if (module_sp) {
3079 // Take one away to make sure we don't count our local "module_sp"
3080 ref_count = module_sp.use_count() - 1;
3081 }
3082 if (width)
3083 strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3084 else
3085 strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3086 } break;
3087
3088 case 's':
3089 case 'S': {
3090 const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3091 if (symbol_vendor) {
3092 const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3093 if (format_char == 'S') {
3094 // Dump symbol file only if different from module file
3095 if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3096 print_space = false;
3097 break;
3098 }
3099 // Add a newline and indent past the index
3100 strm.Printf("\n%*s", indent, "");
3101 }
3102 DumpFullpath(strm, &symfile_spec, width);
3103 dump_object_name = true;
3104 break;
3105 }
3106 strm.Printf("%.*s", width, "<NONE>");
3107 } break;
3108
3109 case 'm':
Pavel Labath7e2cfbf2016-11-09 09:59:18 +00003110 DumpTimePoint(module->GetModificationTime(), strm, width);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003111 break;
3112
3113 case 'p':
3114 strm.Printf("%p", static_cast<void *>(module));
3115 break;
3116
3117 case 'u':
3118 DumpModuleUUID(strm, module);
3119 break;
3120
3121 default:
3122 break;
3123 }
3124 }
3125 if (dump_object_name) {
3126 const char *object_name = module->GetObjectName().GetCString();
3127 if (object_name)
3128 strm.Printf("(%s)", object_name);
3129 }
3130 strm.EOL();
3131 }
3132
3133 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003134};
3135
Jason Molenda380241a2012-07-12 00:20:07 +00003136#pragma mark CommandObjectTargetModulesShowUnwind
Greg Claytoneffe5c92011-05-03 22:09:39 +00003137
Jason Molenda380241a2012-07-12 00:20:07 +00003138//----------------------------------------------------------------------
3139// Lookup unwind information in images
3140//----------------------------------------------------------------------
3141
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003142static OptionDefinition g_target_modules_show_unwind_options[] = {
3143 // clang-format off
3144 { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name." },
3145 { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" }
3146 // clang-format on
3147};
3148
Kate Stoneb9c1b512016-09-06 20:57:50 +00003149class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
Jason Molenda380241a2012-07-12 00:20:07 +00003150public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003151 enum {
3152 eLookupTypeInvalid = -1,
3153 eLookupTypeAddress = 0,
3154 eLookupTypeSymbol,
3155 eLookupTypeFunction,
3156 eLookupTypeFunctionOrSymbol,
3157 kNumLookupTypes
3158 };
Jason Molenda380241a2012-07-12 00:20:07 +00003159
Kate Stoneb9c1b512016-09-06 20:57:50 +00003160 class CommandOptions : public Options {
3161 public:
3162 CommandOptions()
3163 : Options(), m_type(eLookupTypeInvalid), m_str(),
3164 m_addr(LLDB_INVALID_ADDRESS) {}
Jason Molenda380241a2012-07-12 00:20:07 +00003165
Kate Stoneb9c1b512016-09-06 20:57:50 +00003166 ~CommandOptions() override = default;
Jason Molenda380241a2012-07-12 00:20:07 +00003167
Kate Stoneb9c1b512016-09-06 20:57:50 +00003168 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
3169 ExecutionContext *execution_context) override {
3170 Error error;
Jason Molenda380241a2012-07-12 00:20:07 +00003171
Kate Stoneb9c1b512016-09-06 20:57:50 +00003172 const int short_option = m_getopt_table[option_idx].val;
Jason Molenda380241a2012-07-12 00:20:07 +00003173
Kate Stoneb9c1b512016-09-06 20:57:50 +00003174 switch (short_option) {
3175 case 'a': {
3176 m_str = option_arg;
3177 m_type = eLookupTypeAddress;
3178 m_addr = Args::StringToAddress(execution_context, option_arg,
3179 LLDB_INVALID_ADDRESS, &error);
3180 if (m_addr == LLDB_INVALID_ADDRESS)
3181 error.SetErrorStringWithFormat("invalid address string '%s'",
3182 option_arg);
3183 break;
3184 }
Jason Molenda380241a2012-07-12 00:20:07 +00003185
Kate Stoneb9c1b512016-09-06 20:57:50 +00003186 case 'n':
3187 m_str = option_arg;
3188 m_type = eLookupTypeFunctionOrSymbol;
3189 break;
Michael Sartainb1e15922013-08-22 20:42:30 +00003190
Kate Stoneb9c1b512016-09-06 20:57:50 +00003191 default:
3192 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
3193 break;
3194 }
Jason Molenda380241a2012-07-12 00:20:07 +00003195
Kate Stoneb9c1b512016-09-06 20:57:50 +00003196 return error;
Jason Molenda380241a2012-07-12 00:20:07 +00003197 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003198
Kate Stoneb9c1b512016-09-06 20:57:50 +00003199 void OptionParsingStarting(ExecutionContext *execution_context) override {
3200 m_type = eLookupTypeInvalid;
3201 m_str.clear();
3202 m_addr = LLDB_INVALID_ADDRESS;
Jason Molenda380241a2012-07-12 00:20:07 +00003203 }
3204
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003205 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00003206 return llvm::makeArrayRef(g_target_modules_show_unwind_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003207 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003208
3209 // Instance variables to hold the values for command options.
3210
3211 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3212 std::string m_str; // Holds name lookup
3213 lldb::addr_t m_addr; // Holds the address to lookup
3214 };
3215
3216 CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3217 : CommandObjectParsed(
3218 interpreter, "target modules show-unwind",
3219 "Show synthesized unwind instructions for a function.", nullptr,
3220 eCommandRequiresTarget | eCommandRequiresProcess |
3221 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
3222 m_options() {}
3223
3224 ~CommandObjectTargetModulesShowUnwind() override = default;
3225
3226 Options *GetOptions() override { return &m_options; }
3227
Jason Molenda380241a2012-07-12 00:20:07 +00003228protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003229 bool DoExecute(Args &command, CommandReturnObject &result) override {
3230 Target *target = m_exe_ctx.GetTargetPtr();
3231 Process *process = m_exe_ctx.GetProcessPtr();
3232 ABI *abi = nullptr;
3233 if (process)
3234 abi = process->GetABI().get();
Jason Molenda380241a2012-07-12 00:20:07 +00003235
Kate Stoneb9c1b512016-09-06 20:57:50 +00003236 if (process == nullptr) {
3237 result.AppendError(
3238 "You must have a process running to use this command.");
3239 result.SetStatus(eReturnStatusFailed);
3240 return false;
Jason Molenda380241a2012-07-12 00:20:07 +00003241 }
3242
Kate Stoneb9c1b512016-09-06 20:57:50 +00003243 ThreadList threads(process->GetThreadList());
3244 if (threads.GetSize() == 0) {
3245 result.AppendError("The process must be paused to use this command.");
3246 result.SetStatus(eReturnStatusFailed);
3247 return false;
3248 }
3249
3250 ThreadSP thread(threads.GetThreadAtIndex(0));
3251 if (!thread) {
3252 result.AppendError("The process must be paused to use this command.");
3253 result.SetStatus(eReturnStatusFailed);
3254 return false;
3255 }
3256
3257 SymbolContextList sc_list;
3258
3259 if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3260 ConstString function_name(m_options.m_str.c_str());
3261 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3262 true, false, true, sc_list);
3263 } else if (m_options.m_type == eLookupTypeAddress && target) {
3264 Address addr;
3265 if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3266 addr)) {
3267 SymbolContext sc;
3268 ModuleSP module_sp(addr.GetModule());
3269 module_sp->ResolveSymbolContextForAddress(addr,
3270 eSymbolContextEverything, sc);
3271 if (sc.function || sc.symbol) {
3272 sc_list.Append(sc);
3273 }
3274 }
3275 } else {
3276 result.AppendError(
3277 "address-expression or function name option must be specified.");
3278 result.SetStatus(eReturnStatusFailed);
3279 return false;
3280 }
3281
3282 size_t num_matches = sc_list.GetSize();
3283 if (num_matches == 0) {
3284 result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3285 m_options.m_str.c_str());
3286 result.SetStatus(eReturnStatusFailed);
3287 return false;
3288 }
3289
3290 for (uint32_t idx = 0; idx < num_matches; idx++) {
3291 SymbolContext sc;
3292 sc_list.GetContextAtIndex(idx, sc);
3293 if (sc.symbol == nullptr && sc.function == nullptr)
3294 continue;
3295 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3296 continue;
3297 AddressRange range;
3298 if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3299 false, range))
3300 continue;
3301 if (!range.GetBaseAddress().IsValid())
3302 continue;
3303 ConstString funcname(sc.GetFunctionName());
3304 if (funcname.IsEmpty())
3305 continue;
3306 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3307 if (abi)
3308 start_addr = abi->FixCodeAddress(start_addr);
3309
3310 FuncUnwindersSP func_unwinders_sp(
3311 sc.module_sp->GetObjectFile()
3312 ->GetUnwindTable()
3313 .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3314 if (!func_unwinders_sp)
3315 continue;
3316
3317 result.GetOutputStream().Printf(
3318 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
3319 sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3320 funcname.AsCString(), start_addr);
3321
3322 UnwindPlanSP non_callsite_unwind_plan =
3323 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
3324 if (non_callsite_unwind_plan) {
3325 result.GetOutputStream().Printf(
3326 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3327 non_callsite_unwind_plan->GetSourceName().AsCString());
3328 }
3329 UnwindPlanSP callsite_unwind_plan =
3330 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3331 if (callsite_unwind_plan) {
3332 result.GetOutputStream().Printf(
3333 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3334 callsite_unwind_plan->GetSourceName().AsCString());
3335 }
3336 UnwindPlanSP fast_unwind_plan =
3337 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3338 if (fast_unwind_plan) {
3339 result.GetOutputStream().Printf(
3340 "Fast UnwindPlan is '%s'\n",
3341 fast_unwind_plan->GetSourceName().AsCString());
3342 }
3343
3344 result.GetOutputStream().Printf("\n");
3345
3346 UnwindPlanSP assembly_sp =
3347 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
3348 if (assembly_sp) {
3349 result.GetOutputStream().Printf(
3350 "Assembly language inspection UnwindPlan:\n");
3351 assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3352 LLDB_INVALID_ADDRESS);
3353 result.GetOutputStream().Printf("\n");
3354 }
3355
3356 UnwindPlanSP ehframe_sp =
3357 func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3358 if (ehframe_sp) {
3359 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3360 ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3361 LLDB_INVALID_ADDRESS);
3362 result.GetOutputStream().Printf("\n");
3363 }
3364
3365 UnwindPlanSP ehframe_augmented_sp =
3366 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
3367 if (ehframe_augmented_sp) {
3368 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3369 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3370 LLDB_INVALID_ADDRESS);
3371 result.GetOutputStream().Printf("\n");
3372 }
3373
3374 UnwindPlanSP arm_unwind_sp =
3375 func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
3376 if (arm_unwind_sp) {
3377 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3378 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3379 LLDB_INVALID_ADDRESS);
3380 result.GetOutputStream().Printf("\n");
3381 }
3382
3383 UnwindPlanSP compact_unwind_sp =
3384 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3385 if (compact_unwind_sp) {
3386 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3387 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3388 LLDB_INVALID_ADDRESS);
3389 result.GetOutputStream().Printf("\n");
3390 }
3391
3392 if (fast_unwind_plan) {
3393 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3394 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3395 LLDB_INVALID_ADDRESS);
3396 result.GetOutputStream().Printf("\n");
3397 }
3398
3399 ABISP abi_sp = process->GetABI();
3400 if (abi_sp) {
3401 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3402 if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3403 result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3404 arch_default.Dump(result.GetOutputStream(), thread.get(),
3405 LLDB_INVALID_ADDRESS);
3406 result.GetOutputStream().Printf("\n");
3407 }
3408
3409 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3410 if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3411 result.GetOutputStream().Printf(
3412 "Arch default at entry point UnwindPlan:\n");
3413 arch_entry.Dump(result.GetOutputStream(), thread.get(),
3414 LLDB_INVALID_ADDRESS);
3415 result.GetOutputStream().Printf("\n");
3416 }
3417 }
3418
3419 result.GetOutputStream().Printf("\n");
3420 }
3421 return result.Succeeded();
3422 }
3423
3424 CommandOptions m_options;
Jason Molenda380241a2012-07-12 00:20:07 +00003425};
3426
Greg Claytoneffe5c92011-05-03 22:09:39 +00003427//----------------------------------------------------------------------
3428// Lookup information in images
3429//----------------------------------------------------------------------
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003430
3431static OptionDefinition g_target_modules_lookup_options[] = {
3432 // clang-format off
3433 { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." },
3434 { LLDB_OPT_SET_1, false, "offset", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOffset, "When looking up an address subtract <offset> from any addresses before doing the lookup." },
3435 /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */
3436 { LLDB_OPT_SET_2 | LLDB_OPT_SET_4 | LLDB_OPT_SET_5, false, "regex", 'r', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions." },
3437 { LLDB_OPT_SET_2, true, "symbol", 's', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules." },
3438 { LLDB_OPT_SET_3, true, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules." },
3439 { LLDB_OPT_SET_3, false, "line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)." },
3440 { LLDB_OPT_SET_FROM_TO(3,5), false, "no-inlines", 'i', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)." },
3441 { LLDB_OPT_SET_4, true, "function", 'F', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules." },
3442 { LLDB_OPT_SET_5, true, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules." },
3443 { LLDB_OPT_SET_6, true, "type", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules." },
3444 { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose lookup information." },
3445 { LLDB_OPT_SET_ALL, false, "all", 'A', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available." },
3446 // clang-format on
3447};
3448
Kate Stoneb9c1b512016-09-06 20:57:50 +00003449class CommandObjectTargetModulesLookup : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00003450public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003451 enum {
3452 eLookupTypeInvalid = -1,
3453 eLookupTypeAddress = 0,
3454 eLookupTypeSymbol,
3455 eLookupTypeFileLine, // Line is optional
3456 eLookupTypeFunction,
3457 eLookupTypeFunctionOrSymbol,
3458 eLookupTypeType,
3459 kNumLookupTypes
3460 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003461
Kate Stoneb9c1b512016-09-06 20:57:50 +00003462 class CommandOptions : public Options {
3463 public:
3464 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003465
Kate Stoneb9c1b512016-09-06 20:57:50 +00003466 ~CommandOptions() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003467
Kate Stoneb9c1b512016-09-06 20:57:50 +00003468 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
3469 ExecutionContext *execution_context) override {
3470 Error error;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003471
Kate Stoneb9c1b512016-09-06 20:57:50 +00003472 const int short_option = m_getopt_table[option_idx].val;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003473
Kate Stoneb9c1b512016-09-06 20:57:50 +00003474 switch (short_option) {
3475 case 'a': {
3476 m_type = eLookupTypeAddress;
3477 m_addr = Args::StringToAddress(execution_context, option_arg,
3478 LLDB_INVALID_ADDRESS, &error);
3479 } break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003480
Kate Stoneb9c1b512016-09-06 20:57:50 +00003481 case 'o':
3482 m_offset = StringConvert::ToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3483 if (m_offset == LLDB_INVALID_ADDRESS)
3484 error.SetErrorStringWithFormat("invalid offset string '%s'",
3485 option_arg);
3486 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003487
Kate Stoneb9c1b512016-09-06 20:57:50 +00003488 case 's':
3489 m_str = option_arg;
3490 m_type = eLookupTypeSymbol;
3491 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003492
Kate Stoneb9c1b512016-09-06 20:57:50 +00003493 case 'f':
3494 m_file.SetFile(option_arg, false);
3495 m_type = eLookupTypeFileLine;
3496 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003497
Kate Stoneb9c1b512016-09-06 20:57:50 +00003498 case 'i':
3499 m_include_inlines = false;
3500 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003501
Kate Stoneb9c1b512016-09-06 20:57:50 +00003502 case 'l':
3503 m_line_number = StringConvert::ToUInt32(option_arg, UINT32_MAX);
3504 if (m_line_number == UINT32_MAX)
3505 error.SetErrorStringWithFormat("invalid line number string '%s'",
3506 option_arg);
3507 else if (m_line_number == 0)
3508 error.SetErrorString("zero is an invalid line number");
3509 m_type = eLookupTypeFileLine;
3510 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003511
Kate Stoneb9c1b512016-09-06 20:57:50 +00003512 case 'F':
3513 m_str = option_arg;
3514 m_type = eLookupTypeFunction;
3515 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003516
Kate Stoneb9c1b512016-09-06 20:57:50 +00003517 case 'n':
3518 m_str = option_arg;
3519 m_type = eLookupTypeFunctionOrSymbol;
3520 break;
Greg Claytonc4a8a762012-05-15 18:43:44 +00003521
Kate Stoneb9c1b512016-09-06 20:57:50 +00003522 case 't':
3523 m_str = option_arg;
3524 m_type = eLookupTypeType;
3525 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003526
Kate Stoneb9c1b512016-09-06 20:57:50 +00003527 case 'v':
3528 m_verbose = 1;
3529 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003530
Kate Stoneb9c1b512016-09-06 20:57:50 +00003531 case 'A':
3532 m_print_all = true;
3533 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003534
Kate Stoneb9c1b512016-09-06 20:57:50 +00003535 case 'r':
3536 m_use_regex = true;
3537 break;
3538 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003539
Kate Stoneb9c1b512016-09-06 20:57:50 +00003540 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003541 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003542
Kate Stoneb9c1b512016-09-06 20:57:50 +00003543 void OptionParsingStarting(ExecutionContext *execution_context) override {
3544 m_type = eLookupTypeInvalid;
3545 m_str.clear();
3546 m_file.Clear();
3547 m_addr = LLDB_INVALID_ADDRESS;
3548 m_offset = 0;
3549 m_line_number = 0;
3550 m_use_regex = false;
3551 m_include_inlines = true;
3552 m_verbose = false;
3553 m_print_all = false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003554 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003555
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003556 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00003557 return llvm::makeArrayRef(g_target_modules_lookup_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003558 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003559
Kate Stoneb9c1b512016-09-06 20:57:50 +00003560 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3561 std::string m_str; // Holds name lookup
3562 FileSpec m_file; // Files for file lookups
3563 lldb::addr_t m_addr; // Holds the address to lookup
3564 lldb::addr_t
3565 m_offset; // Subtract this offset from m_addr before doing lookups.
3566 uint32_t m_line_number; // Line number for file+line lookups
3567 bool m_use_regex; // Name lookups in m_str are regular expressions.
3568 bool m_include_inlines; // Check for inline entries when looking up by
3569 // file/line.
3570 bool m_verbose; // Enable verbose lookup info
3571 bool m_print_all; // Print all matches, even in cases where there's a best
3572 // match.
3573 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003574
Kate Stoneb9c1b512016-09-06 20:57:50 +00003575 CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3576 : CommandObjectParsed(interpreter, "target modules lookup",
3577 "Look up information within executable and "
3578 "dependent shared library images.",
3579 nullptr, eCommandRequiresTarget),
3580 m_options() {
3581 CommandArgumentEntry arg;
3582 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003583
Kate Stoneb9c1b512016-09-06 20:57:50 +00003584 // Define the first (and only) variant of this arg.
3585 file_arg.arg_type = eArgTypeFilename;
3586 file_arg.arg_repetition = eArgRepeatStar;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003587
Kate Stoneb9c1b512016-09-06 20:57:50 +00003588 // There is only one variant this argument could be; put it into the
3589 // argument entry.
3590 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003591
Kate Stoneb9c1b512016-09-06 20:57:50 +00003592 // Push the data for the first argument into the m_arguments vector.
3593 m_arguments.push_back(arg);
3594 }
3595
3596 ~CommandObjectTargetModulesLookup() override = default;
3597
3598 Options *GetOptions() override { return &m_options; }
3599
3600 bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3601 bool &syntax_error) {
3602 switch (m_options.m_type) {
3603 case eLookupTypeAddress:
3604 case eLookupTypeFileLine:
3605 case eLookupTypeFunction:
3606 case eLookupTypeFunctionOrSymbol:
3607 case eLookupTypeSymbol:
3608 default:
3609 return false;
3610 case eLookupTypeType:
3611 break;
Sean Callanand38b4a92012-06-06 20:49:55 +00003612 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003613
Kate Stoneb9c1b512016-09-06 20:57:50 +00003614 StackFrameSP frame = m_exe_ctx.GetFrameSP();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003615
Kate Stoneb9c1b512016-09-06 20:57:50 +00003616 if (!frame)
3617 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003618
Kate Stoneb9c1b512016-09-06 20:57:50 +00003619 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
Greg Claytonc4a8a762012-05-15 18:43:44 +00003620
Kate Stoneb9c1b512016-09-06 20:57:50 +00003621 if (!sym_ctx.module_sp)
3622 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003623
Kate Stoneb9c1b512016-09-06 20:57:50 +00003624 switch (m_options.m_type) {
3625 default:
3626 return false;
3627 case eLookupTypeType:
3628 if (!m_options.m_str.empty()) {
3629 if (LookupTypeHere(m_interpreter, result.GetOutputStream(), sym_ctx,
3630 m_options.m_str.c_str(), m_options.m_use_regex)) {
3631 result.SetStatus(eReturnStatusSuccessFinishResult);
3632 return true;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003633 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003634 }
3635 break;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003636 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003637
Kate Stoneb9c1b512016-09-06 20:57:50 +00003638 return true;
3639 }
3640
3641 bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3642 CommandReturnObject &result, bool &syntax_error) {
3643 switch (m_options.m_type) {
3644 case eLookupTypeAddress:
3645 if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3646 if (LookupAddressInModule(
3647 m_interpreter, result.GetOutputStream(), module,
3648 eSymbolContextEverything |
3649 (m_options.m_verbose
3650 ? static_cast<int>(eSymbolContextVariable)
3651 : 0),
3652 m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
3653 result.SetStatus(eReturnStatusSuccessFinishResult);
3654 return true;
3655 }
3656 }
3657 break;
3658
3659 case eLookupTypeSymbol:
3660 if (!m_options.m_str.empty()) {
3661 if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3662 module, m_options.m_str.c_str(),
3663 m_options.m_use_regex, m_options.m_verbose)) {
3664 result.SetStatus(eReturnStatusSuccessFinishResult);
3665 return true;
3666 }
3667 }
3668 break;
3669
3670 case eLookupTypeFileLine:
3671 if (m_options.m_file) {
3672 if (LookupFileAndLineInModule(
3673 m_interpreter, result.GetOutputStream(), module,
3674 m_options.m_file, m_options.m_line_number,
3675 m_options.m_include_inlines, m_options.m_verbose)) {
3676 result.SetStatus(eReturnStatusSuccessFinishResult);
3677 return true;
3678 }
3679 }
3680 break;
3681
3682 case eLookupTypeFunctionOrSymbol:
3683 case eLookupTypeFunction:
3684 if (!m_options.m_str.empty()) {
3685 if (LookupFunctionInModule(
3686 m_interpreter, result.GetOutputStream(), module,
3687 m_options.m_str.c_str(), m_options.m_use_regex,
3688 m_options.m_include_inlines,
3689 m_options.m_type ==
3690 eLookupTypeFunctionOrSymbol, // include symbols
3691 m_options.m_verbose)) {
3692 result.SetStatus(eReturnStatusSuccessFinishResult);
3693 return true;
3694 }
3695 }
3696 break;
3697
3698 case eLookupTypeType:
3699 if (!m_options.m_str.empty()) {
3700 if (LookupTypeInModule(m_interpreter, result.GetOutputStream(), module,
3701 m_options.m_str.c_str(),
3702 m_options.m_use_regex)) {
3703 result.SetStatus(eReturnStatusSuccessFinishResult);
3704 return true;
3705 }
3706 }
3707 break;
3708
3709 default:
3710 m_options.GenerateOptionUsage(
3711 result.GetErrorStream(), this,
3712 GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3713 syntax_error = true;
3714 break;
3715 }
3716
3717 result.SetStatus(eReturnStatusFailed);
3718 return false;
3719 }
3720
Jim Ingham5a988412012-06-08 21:56:10 +00003721protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003722 bool DoExecute(Args &command, CommandReturnObject &result) override {
3723 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3724 if (target == nullptr) {
3725 result.AppendError("invalid target, create a debug target using the "
3726 "'target create' command");
3727 result.SetStatus(eReturnStatusFailed);
3728 return false;
3729 } else {
3730 bool syntax_error = false;
3731 uint32_t i;
3732 uint32_t num_successful_lookups = 0;
3733 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3734 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3735 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3736 // Dump all sections for all modules images
3737
3738 if (command.GetArgumentCount() == 0) {
3739 ModuleSP current_module;
3740
3741 // Where it is possible to look in the current symbol context
3742 // first, try that. If this search was successful and --all
3743 // was not passed, don't print anything else.
3744 if (LookupHere(m_interpreter, result, syntax_error)) {
3745 result.GetOutputStream().EOL();
3746 num_successful_lookups++;
3747 if (!m_options.m_print_all) {
3748 result.SetStatus(eReturnStatusSuccessFinishResult);
3749 return result.Succeeded();
3750 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00003751 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003752
Kate Stoneb9c1b512016-09-06 20:57:50 +00003753 // Dump all sections for all other modules
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003754
Kate Stoneb9c1b512016-09-06 20:57:50 +00003755 const ModuleList &target_modules = target->GetImages();
3756 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3757 const size_t num_modules = target_modules.GetSize();
3758 if (num_modules > 0) {
3759 for (i = 0; i < num_modules && !syntax_error; ++i) {
3760 Module *module_pointer =
3761 target_modules.GetModulePointerAtIndexUnlocked(i);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003762
Kate Stoneb9c1b512016-09-06 20:57:50 +00003763 if (module_pointer != current_module.get() &&
3764 LookupInModule(
3765 m_interpreter,
3766 target_modules.GetModulePointerAtIndexUnlocked(i), result,
3767 syntax_error)) {
3768 result.GetOutputStream().EOL();
3769 num_successful_lookups++;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003770 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003771 }
3772 } else {
3773 result.AppendError("the target has no associated executable images");
3774 result.SetStatus(eReturnStatusFailed);
3775 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003776 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003777 } else {
3778 // Dump specified images (by basename or fullpath)
3779 const char *arg_cstr;
3780 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3781 !syntax_error;
3782 ++i) {
3783 ModuleList module_list;
3784 const size_t num_matches =
3785 FindModulesByName(target, arg_cstr, module_list, false);
3786 if (num_matches > 0) {
3787 for (size_t j = 0; j < num_matches; ++j) {
3788 Module *module = module_list.GetModulePointerAtIndex(j);
3789 if (module) {
3790 if (LookupInModule(m_interpreter, module, result,
3791 syntax_error)) {
3792 result.GetOutputStream().EOL();
3793 num_successful_lookups++;
3794 }
3795 }
3796 }
3797 } else
3798 result.AppendWarningWithFormat(
3799 "Unable to find an image that matches '%s'.\n", arg_cstr);
3800 }
3801 }
3802
3803 if (num_successful_lookups > 0)
3804 result.SetStatus(eReturnStatusSuccessFinishResult);
3805 else
3806 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00003807 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003808 return result.Succeeded();
3809 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003810
Kate Stoneb9c1b512016-09-06 20:57:50 +00003811 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003812};
3813
Jim Ingham9575d842011-03-11 03:53:59 +00003814#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003815
3816//-------------------------------------------------------------------------
3817// CommandObjectMultiwordImageSearchPaths
3818//-------------------------------------------------------------------------
3819
Kate Stoneb9c1b512016-09-06 20:57:50 +00003820class CommandObjectTargetModulesImageSearchPaths
3821 : public CommandObjectMultiword {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003822public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003823 CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
3824 : CommandObjectMultiword(
3825 interpreter, "target modules search-paths",
3826 "Commands for managing module search paths for a target.",
3827 "target modules search-paths <subcommand> [<subcommand-options>]") {
3828 LoadSubCommand(
3829 "add", CommandObjectSP(
3830 new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
3831 LoadSubCommand(
3832 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
3833 interpreter)));
3834 LoadSubCommand(
3835 "insert",
3836 CommandObjectSP(
3837 new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
3838 LoadSubCommand(
3839 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
3840 interpreter)));
3841 LoadSubCommand(
3842 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
3843 interpreter)));
3844 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003845
Kate Stoneb9c1b512016-09-06 20:57:50 +00003846 ~CommandObjectTargetModulesImageSearchPaths() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003847};
3848
Greg Claytoneffe5c92011-05-03 22:09:39 +00003849#pragma mark CommandObjectTargetModules
3850
3851//-------------------------------------------------------------------------
3852// CommandObjectTargetModules
3853//-------------------------------------------------------------------------
3854
Kate Stoneb9c1b512016-09-06 20:57:50 +00003855class CommandObjectTargetModules : public CommandObjectMultiword {
Greg Claytoneffe5c92011-05-03 22:09:39 +00003856public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003857 //------------------------------------------------------------------
3858 // Constructors and Destructors
3859 //------------------------------------------------------------------
3860 CommandObjectTargetModules(CommandInterpreter &interpreter)
3861 : CommandObjectMultiword(interpreter, "target modules",
3862 "Commands for accessing information for one or "
3863 "more target modules.",
3864 "target modules <sub-command> ...") {
3865 LoadSubCommand(
3866 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
3867 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
3868 interpreter)));
3869 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
3870 interpreter)));
3871 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
3872 interpreter)));
3873 LoadSubCommand(
3874 "lookup",
3875 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
3876 LoadSubCommand(
3877 "search-paths",
3878 CommandObjectSP(
3879 new CommandObjectTargetModulesImageSearchPaths(interpreter)));
3880 LoadSubCommand(
3881 "show-unwind",
3882 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
3883 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00003884
Kate Stoneb9c1b512016-09-06 20:57:50 +00003885 ~CommandObjectTargetModules() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003886
Greg Claytoneffe5c92011-05-03 22:09:39 +00003887private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003888 //------------------------------------------------------------------
3889 // For CommandObjectTargetModules only
3890 //------------------------------------------------------------------
3891 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules);
Greg Claytoneffe5c92011-05-03 22:09:39 +00003892};
3893
Kate Stoneb9c1b512016-09-06 20:57:50 +00003894class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
Greg Claytone72dfb32012-02-24 01:59:29 +00003895public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003896 CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
3897 : CommandObjectParsed(
3898 interpreter, "target symbols add",
3899 "Add a debug symbol file to one of the target's current modules by "
3900 "specifying a path to a debug symbols file, or using the options "
3901 "to specify a module to download symbols for.",
3902 "target symbols add [<symfile>]", eCommandRequiresTarget),
Todd Fialae1cfbc72016-08-11 23:51:28 +00003903 m_option_group(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00003904 m_file_option(
3905 LLDB_OPT_SET_1, false, "shlib", 's',
3906 CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3907 "Fullpath or basename for module to find debug symbols for."),
3908 m_current_frame_option(
3909 LLDB_OPT_SET_2, false, "frame", 'F',
3910 "Locate the debug symbols the currently selected frame.", false,
3911 true)
Greg Claytonb5f0fea2012-09-27 22:26:11 +00003912
Kate Stoneb9c1b512016-09-06 20:57:50 +00003913 {
3914 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
3915 LLDB_OPT_SET_1);
3916 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
3917 m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
3918 LLDB_OPT_SET_2);
3919 m_option_group.Finalize();
3920 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003921
Kate Stoneb9c1b512016-09-06 20:57:50 +00003922 ~CommandObjectTargetSymbolsAdd() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003923
Kate Stoneb9c1b512016-09-06 20:57:50 +00003924 int HandleArgumentCompletion(Args &input, int &cursor_index,
3925 int &cursor_char_position,
3926 OptionElementVector &opt_element_vector,
3927 int match_start_point, int max_return_elements,
3928 bool &word_complete,
3929 StringList &matches) override {
3930 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
3931 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003932
Kate Stoneb9c1b512016-09-06 20:57:50 +00003933 CommandCompletions::InvokeCommonCompletionCallbacks(
3934 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
3935 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
3936 word_complete, matches);
3937 return matches.GetSize();
3938 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003939
Kate Stoneb9c1b512016-09-06 20:57:50 +00003940 Options *GetOptions() override { return &m_option_group; }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00003941
Jim Ingham5a988412012-06-08 21:56:10 +00003942protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003943 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
3944 CommandReturnObject &result) {
3945 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
3946 if (symbol_fspec) {
3947 char symfile_path[PATH_MAX];
3948 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003949
Kate Stoneb9c1b512016-09-06 20:57:50 +00003950 if (!module_spec.GetUUID().IsValid()) {
3951 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
3952 module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
3953 }
3954 // We now have a module that represents a symbol file
3955 // that can be used for a module that might exist in the
3956 // current target, so we need to find that module in the
3957 // target
3958 ModuleList matching_module_list;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003959
Kate Stoneb9c1b512016-09-06 20:57:50 +00003960 size_t num_matches = 0;
3961 // First extract all module specs from the symbol file
3962 lldb_private::ModuleSpecList symfile_module_specs;
3963 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
3964 0, 0, symfile_module_specs)) {
3965 // Now extract the module spec that matches the target architecture
3966 ModuleSpec target_arch_module_spec;
3967 ModuleSpec symfile_module_spec;
3968 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
3969 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
3970 symfile_module_spec)) {
3971 // See if it has a UUID?
3972 if (symfile_module_spec.GetUUID().IsValid()) {
3973 // It has a UUID, look for this UUID in the target modules
3974 ModuleSpec symfile_uuid_module_spec;
3975 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
3976 num_matches = target->GetImages().FindModules(
3977 symfile_uuid_module_spec, matching_module_list);
3978 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00003979 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003980
3981 if (num_matches == 0) {
3982 // No matches yet, iterate through the module specs to find a UUID
3983 // value that
3984 // we can match up to an image in our target
3985 const size_t num_symfile_module_specs =
3986 symfile_module_specs.GetSize();
3987 for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0;
3988 ++i) {
3989 if (symfile_module_specs.GetModuleSpecAtIndex(
3990 i, symfile_module_spec)) {
3991 if (symfile_module_spec.GetUUID().IsValid()) {
3992 // It has a UUID, look for this UUID in the target modules
3993 ModuleSpec symfile_uuid_module_spec;
3994 symfile_uuid_module_spec.GetUUID() =
3995 symfile_module_spec.GetUUID();
3996 num_matches = target->GetImages().FindModules(
3997 symfile_uuid_module_spec, matching_module_list);
3998 }
3999 }
4000 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00004001 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004002 }
4003
4004 // Just try to match up the file by basename if we have no matches at this
4005 // point
4006 if (num_matches == 0)
4007 num_matches =
4008 target->GetImages().FindModules(module_spec, matching_module_list);
4009
4010 while (num_matches == 0) {
4011 ConstString filename_no_extension(
4012 module_spec.GetFileSpec().GetFileNameStrippingExtension());
4013 // Empty string returned, lets bail
4014 if (!filename_no_extension)
4015 break;
4016
4017 // Check if there was no extension to strip and the basename is the same
4018 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4019 break;
4020
4021 // Replace basename with one less extension
4022 module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4023
4024 num_matches =
4025 target->GetImages().FindModules(module_spec, matching_module_list);
4026 }
4027
4028 if (num_matches > 1) {
4029 result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4030 "use the --uuid option to resolve the "
4031 "ambiguity.\n",
4032 symfile_path);
4033 } else if (num_matches == 1) {
4034 ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0));
4035
4036 // The module has not yet created its symbol vendor, we can just
4037 // give the existing target module the symfile path to use for
4038 // when it decides to create it!
4039 module_sp->SetSymbolFileFileSpec(symbol_fspec);
4040
4041 SymbolVendor *symbol_vendor =
4042 module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4043 if (symbol_vendor) {
4044 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4045
4046 if (symbol_file) {
4047 ObjectFile *object_file = symbol_file->GetObjectFile();
4048
4049 if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4050 // Provide feedback that the symfile has been successfully added.
4051 const FileSpec &module_fs = module_sp->GetFileSpec();
4052 result.AppendMessageWithFormat(
4053 "symbol file '%s' has been added to '%s'\n", symfile_path,
4054 module_fs.GetPath().c_str());
4055
4056 // Let clients know something changed in the module
4057 // if it is currently loaded
4058 ModuleList module_list;
4059 module_list.Append(module_sp);
4060 target->SymbolsDidLoad(module_list);
4061
4062 // Make sure we load any scripting resources that may be embedded
4063 // in the debug info files in case the platform supports that.
4064 Error error;
4065 StreamString feedback_stream;
4066 module_sp->LoadScriptingResourceInTarget(target, error,
4067 &feedback_stream);
4068 if (error.Fail() && error.AsCString())
4069 result.AppendWarningWithFormat(
4070 "unable to load scripting data for module %s - error "
4071 "reported was %s",
4072 module_sp->GetFileSpec()
4073 .GetFileNameStrippingExtension()
4074 .GetCString(),
4075 error.AsCString());
4076 else if (feedback_stream.GetSize())
4077 result.AppendWarningWithFormat("%s", feedback_stream.GetData());
4078
4079 flush = true;
4080 result.SetStatus(eReturnStatusSuccessFinishResult);
4081 return true;
4082 }
4083 }
4084 }
4085 // Clear the symbol file spec if anything went wrong
4086 module_sp->SetSymbolFileFileSpec(FileSpec());
4087 }
4088
4089 if (module_spec.GetUUID().IsValid()) {
4090 StreamString ss_symfile_uuid;
4091 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4092 result.AppendErrorWithFormat(
4093 "symbol file '%s' (%s) does not match any existing module%s\n",
4094 symfile_path, ss_symfile_uuid.GetData(),
4095 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4096 ? "\n please specify the full path to the symbol file"
4097 : "");
4098 } else {
4099 result.AppendErrorWithFormat(
4100 "symbol file '%s' does not match any existing module%s\n",
4101 symfile_path,
4102 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4103 ? "\n please specify the full path to the symbol file"
4104 : "");
4105 }
4106 } else {
4107 result.AppendError(
4108 "one or more executable image paths must be specified");
4109 }
4110 result.SetStatus(eReturnStatusFailed);
4111 return false;
4112 }
4113
4114 bool DoExecute(Args &args, CommandReturnObject &result) override {
4115 Target *target = m_exe_ctx.GetTargetPtr();
4116 result.SetStatus(eReturnStatusFailed);
4117 bool flush = false;
4118 ModuleSpec module_spec;
4119 const bool uuid_option_set =
4120 m_uuid_option_group.GetOptionValue().OptionWasSet();
4121 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4122 const bool frame_option_set =
4123 m_current_frame_option.GetOptionValue().OptionWasSet();
4124 const size_t argc = args.GetArgumentCount();
4125
4126 if (argc == 0) {
4127 if (uuid_option_set || file_option_set || frame_option_set) {
4128 bool success = false;
4129 bool error_set = false;
4130 if (frame_option_set) {
4131 Process *process = m_exe_ctx.GetProcessPtr();
4132 if (process) {
4133 const StateType process_state = process->GetState();
4134 if (StateIsStoppedState(process_state, true)) {
4135 StackFrame *frame = m_exe_ctx.GetFramePtr();
4136 if (frame) {
4137 ModuleSP frame_module_sp(
4138 frame->GetSymbolContext(eSymbolContextModule).module_sp);
4139 if (frame_module_sp) {
4140 if (frame_module_sp->GetPlatformFileSpec().Exists()) {
4141 module_spec.GetArchitecture() =
4142 frame_module_sp->GetArchitecture();
4143 module_spec.GetFileSpec() =
4144 frame_module_sp->GetPlatformFileSpec();
4145 }
4146 module_spec.GetUUID() = frame_module_sp->GetUUID();
4147 success = module_spec.GetUUID().IsValid() ||
4148 module_spec.GetFileSpec();
4149 } else {
4150 result.AppendError("frame has no module");
4151 error_set = true;
4152 }
4153 } else {
4154 result.AppendError("invalid current frame");
4155 error_set = true;
4156 }
4157 } else {
4158 result.AppendErrorWithFormat("process is not stopped: %s",
4159 StateAsCString(process_state));
4160 error_set = true;
4161 }
4162 } else {
4163 result.AppendError(
4164 "a process must exist in order to use the --frame option");
4165 error_set = true;
4166 }
4167 } else {
4168 if (uuid_option_set) {
4169 module_spec.GetUUID() =
4170 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4171 success |= module_spec.GetUUID().IsValid();
4172 } else if (file_option_set) {
4173 module_spec.GetFileSpec() =
4174 m_file_option.GetOptionValue().GetCurrentValue();
4175 ModuleSP module_sp(
4176 target->GetImages().FindFirstModule(module_spec));
4177 if (module_sp) {
4178 module_spec.GetFileSpec() = module_sp->GetFileSpec();
4179 module_spec.GetPlatformFileSpec() =
4180 module_sp->GetPlatformFileSpec();
4181 module_spec.GetUUID() = module_sp->GetUUID();
4182 module_spec.GetArchitecture() = module_sp->GetArchitecture();
4183 } else {
4184 module_spec.GetArchitecture() = target->GetArchitecture();
4185 }
4186 success |= module_spec.GetUUID().IsValid() ||
4187 module_spec.GetFileSpec().Exists();
4188 }
4189 }
4190
4191 if (success) {
4192 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4193 if (module_spec.GetSymbolFileSpec())
4194 success = AddModuleSymbols(target, module_spec, flush, result);
4195 }
4196 }
4197
4198 if (!success && !error_set) {
4199 StreamString error_strm;
4200 if (uuid_option_set) {
4201 error_strm.PutCString("unable to find debug symbols for UUID ");
4202 module_spec.GetUUID().Dump(&error_strm);
4203 } else if (file_option_set) {
4204 error_strm.PutCString(
4205 "unable to find debug symbols for the executable file ");
4206 error_strm << module_spec.GetFileSpec();
4207 } else if (frame_option_set) {
4208 error_strm.PutCString(
4209 "unable to find debug symbols for the current frame");
4210 }
4211 result.AppendError(error_strm.GetData());
4212 }
4213 } else {
4214 result.AppendError("one or more symbol file paths must be specified, "
4215 "or options must be specified");
4216 }
4217 } else {
4218 if (uuid_option_set) {
4219 result.AppendError("specify either one or more paths to symbol files "
4220 "or use the --uuid option without arguments");
4221 } else if (file_option_set) {
4222 result.AppendError("specify either one or more paths to symbol files "
4223 "or use the --file option without arguments");
4224 } else if (frame_option_set) {
4225 result.AppendError("specify either one or more paths to symbol files "
4226 "or use the --frame option without arguments");
4227 } else {
4228 PlatformSP platform_sp(target->GetPlatform());
4229
Zachary Turner97d2c402016-10-05 23:40:23 +00004230 for (auto &entry : args.entries()) {
4231 if (!entry.ref.empty()) {
4232 module_spec.GetSymbolFileSpec().SetFile(entry.ref, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004233 if (platform_sp) {
4234 FileSpec symfile_spec;
4235 if (platform_sp
4236 ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4237 .Success())
4238 module_spec.GetSymbolFileSpec() = symfile_spec;
4239 }
4240
4241 ArchSpec arch;
4242 bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
4243
4244 if (symfile_exists) {
4245 if (!AddModuleSymbols(target, module_spec, flush, result))
4246 break;
4247 } else {
Zachary Turner97d2c402016-10-05 23:40:23 +00004248 std::string resolved_symfile_path =
4249 module_spec.GetSymbolFileSpec().GetPath();
4250 if (resolved_symfile_path != entry.ref) {
4251 result.AppendErrorWithFormat(
4252 "invalid module path '%s' with resolved path '%s'\n",
4253 entry.c_str(), resolved_symfile_path.c_str());
4254 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004255 }
4256 result.AppendErrorWithFormat("invalid module path '%s'\n",
Zachary Turner97d2c402016-10-05 23:40:23 +00004257 entry.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004258 break;
4259 }
4260 }
4261 }
4262 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00004263 }
4264
Kate Stoneb9c1b512016-09-06 20:57:50 +00004265 if (flush) {
4266 Process *process = m_exe_ctx.GetProcessPtr();
4267 if (process)
4268 process->Flush();
Greg Claytone72dfb32012-02-24 01:59:29 +00004269 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004270 return result.Succeeded();
4271 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004272
Kate Stoneb9c1b512016-09-06 20:57:50 +00004273 OptionGroupOptions m_option_group;
4274 OptionGroupUUID m_uuid_option_group;
4275 OptionGroupFile m_file_option;
4276 OptionGroupBoolean m_current_frame_option;
Greg Claytone72dfb32012-02-24 01:59:29 +00004277};
4278
Greg Claytone72dfb32012-02-24 01:59:29 +00004279#pragma mark CommandObjectTargetSymbols
4280
4281//-------------------------------------------------------------------------
4282// CommandObjectTargetSymbols
4283//-------------------------------------------------------------------------
4284
Kate Stoneb9c1b512016-09-06 20:57:50 +00004285class CommandObjectTargetSymbols : public CommandObjectMultiword {
Greg Claytone72dfb32012-02-24 01:59:29 +00004286public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004287 //------------------------------------------------------------------
4288 // Constructors and Destructors
4289 //------------------------------------------------------------------
4290 CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4291 : CommandObjectMultiword(
4292 interpreter, "target symbols",
4293 "Commands for adding and managing debug symbol files.",
4294 "target symbols <sub-command> ...") {
4295 LoadSubCommand(
4296 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4297 }
Bruce Mitchener13d21e92015-10-07 16:56:17 +00004298
Kate Stoneb9c1b512016-09-06 20:57:50 +00004299 ~CommandObjectTargetSymbols() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004300
Greg Claytone72dfb32012-02-24 01:59:29 +00004301private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004302 //------------------------------------------------------------------
4303 // For CommandObjectTargetModules only
4304 //------------------------------------------------------------------
4305 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols);
Greg Claytone72dfb32012-02-24 01:59:29 +00004306};
4307
Jim Ingham9575d842011-03-11 03:53:59 +00004308#pragma mark CommandObjectTargetStopHookAdd
4309
4310//-------------------------------------------------------------------------
4311// CommandObjectTargetStopHookAdd
4312//-------------------------------------------------------------------------
4313
Zachary Turner1f0f5b52016-09-22 20:22:55 +00004314static OptionDefinition g_target_stop_hook_add_options[] = {
4315 // clang-format off
4316 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeOneLiner, "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
4317 { LLDB_OPT_SET_ALL, false, "shlib", 's', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Set the module within which the stop-hook is to be run." },
4318 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadIndex, "The stop hook is run only for the thread whose index matches this argument." },
4319 { LLDB_OPT_SET_ALL, false, "thread-id", 't', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadID, "The stop hook is run only for the thread whose TID matches this argument." },
4320 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeThreadName, "The stop hook is run only for the thread whose thread name matches this argument." },
4321 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeQueueName, "The stop hook is run only for threads in the queue whose name is given by this argument." },
4322 { LLDB_OPT_SET_1, false, "file", 'f', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSourceFileCompletion, eArgTypeFilename, "Specify the source file within which the stop-hook is to be run." },
4323 { LLDB_OPT_SET_1, false, "start-line", 'l', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Set the start of the line range for which the stop-hook is to be run." },
4324 { LLDB_OPT_SET_1, false, "end-line", 'e', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeLineNum, "Set the end of the line range for which the stop-hook is to be run." },
4325 { LLDB_OPT_SET_2, false, "classname", 'c', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeClassName, "Specify the class within which the stop-hook is to be run." },
4326 { LLDB_OPT_SET_3, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName, "Set the function name within which the stop hook will be run." },
4327 // clang-format on
4328};
4329
Kate Stoneb9c1b512016-09-06 20:57:50 +00004330class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4331 public IOHandlerDelegateMultiline {
Jim Ingham9575d842011-03-11 03:53:59 +00004332public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004333 class CommandOptions : public Options {
4334 public:
4335 CommandOptions()
4336 : Options(), m_line_start(0), m_line_end(UINT_MAX),
4337 m_func_name_type_mask(eFunctionNameTypeAuto),
4338 m_sym_ctx_specified(false), m_thread_specified(false),
4339 m_use_one_liner(false), m_one_liner() {}
4340
4341 ~CommandOptions() override = default;
4342
Zachary Turner1f0f5b52016-09-22 20:22:55 +00004343 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00004344 return llvm::makeArrayRef(g_target_stop_hook_add_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00004345 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004346
4347 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
4348 ExecutionContext *execution_context) override {
4349 Error error;
4350 const int short_option = m_getopt_table[option_idx].val;
4351 bool success;
4352
4353 switch (short_option) {
4354 case 'c':
4355 m_class_name = option_arg;
4356 m_sym_ctx_specified = true;
4357 break;
4358
4359 case 'e':
4360 m_line_end = StringConvert::ToUInt32(option_arg, UINT_MAX, 0, &success);
4361 if (!success) {
4362 error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4363 option_arg);
4364 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004365 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004366 m_sym_ctx_specified = true;
4367 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004368
Kate Stoneb9c1b512016-09-06 20:57:50 +00004369 case 'l':
4370 m_line_start = StringConvert::ToUInt32(option_arg, 0, 0, &success);
4371 if (!success) {
4372 error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4373 option_arg);
4374 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004375 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004376 m_sym_ctx_specified = true;
4377 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004378
Kate Stoneb9c1b512016-09-06 20:57:50 +00004379 case 'i':
4380 m_no_inlines = true;
4381 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004382
Kate Stoneb9c1b512016-09-06 20:57:50 +00004383 case 'n':
4384 m_function_name = option_arg;
4385 m_func_name_type_mask |= eFunctionNameTypeAuto;
4386 m_sym_ctx_specified = true;
4387 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004388
Kate Stoneb9c1b512016-09-06 20:57:50 +00004389 case 'f':
4390 m_file_name = option_arg;
4391 m_sym_ctx_specified = true;
4392 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004393
Kate Stoneb9c1b512016-09-06 20:57:50 +00004394 case 's':
4395 m_module_name = option_arg;
4396 m_sym_ctx_specified = true;
4397 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004398
Kate Stoneb9c1b512016-09-06 20:57:50 +00004399 case 't':
4400 m_thread_id =
4401 StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
4402 if (m_thread_id == LLDB_INVALID_THREAD_ID)
4403 error.SetErrorStringWithFormat("invalid thread id string '%s'",
4404 option_arg);
4405 m_thread_specified = true;
4406 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004407
Kate Stoneb9c1b512016-09-06 20:57:50 +00004408 case 'T':
4409 m_thread_name = option_arg;
4410 m_thread_specified = true;
4411 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004412
Kate Stoneb9c1b512016-09-06 20:57:50 +00004413 case 'q':
4414 m_queue_name = option_arg;
4415 m_thread_specified = true;
4416 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004417
Kate Stoneb9c1b512016-09-06 20:57:50 +00004418 case 'x':
4419 m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
4420 if (m_thread_id == UINT32_MAX)
4421 error.SetErrorStringWithFormat("invalid thread index string '%s'",
4422 option_arg);
4423 m_thread_specified = true;
4424 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004425
Kate Stoneb9c1b512016-09-06 20:57:50 +00004426 case 'o':
4427 m_use_one_liner = true;
4428 m_one_liner = option_arg;
4429 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004430
Kate Stoneb9c1b512016-09-06 20:57:50 +00004431 default:
4432 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
4433 break;
4434 }
4435 return error;
Jim Ingham9575d842011-03-11 03:53:59 +00004436 }
4437
Kate Stoneb9c1b512016-09-06 20:57:50 +00004438 void OptionParsingStarting(ExecutionContext *execution_context) override {
4439 m_class_name.clear();
4440 m_function_name.clear();
4441 m_line_start = 0;
4442 m_line_end = UINT_MAX;
4443 m_file_name.clear();
4444 m_module_name.clear();
4445 m_func_name_type_mask = eFunctionNameTypeAuto;
4446 m_thread_id = LLDB_INVALID_THREAD_ID;
4447 m_thread_index = UINT32_MAX;
4448 m_thread_name.clear();
4449 m_queue_name.clear();
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004450
Kate Stoneb9c1b512016-09-06 20:57:50 +00004451 m_no_inlines = false;
4452 m_sym_ctx_specified = false;
4453 m_thread_specified = false;
4454
4455 m_use_one_liner = false;
4456 m_one_liner.clear();
Jim Ingham9575d842011-03-11 03:53:59 +00004457 }
4458
Kate Stoneb9c1b512016-09-06 20:57:50 +00004459 std::string m_class_name;
4460 std::string m_function_name;
4461 uint32_t m_line_start;
4462 uint32_t m_line_end;
4463 std::string m_file_name;
4464 std::string m_module_name;
4465 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
4466 lldb::tid_t m_thread_id;
4467 uint32_t m_thread_index;
4468 std::string m_thread_name;
4469 std::string m_queue_name;
4470 bool m_sym_ctx_specified;
4471 bool m_no_inlines;
4472 bool m_thread_specified;
4473 // Instance variables to hold the values for one_liner options.
4474 bool m_use_one_liner;
4475 std::string m_one_liner;
4476 };
4477
4478 CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4479 : CommandObjectParsed(interpreter, "target stop-hook add",
4480 "Add a hook to be executed when the target stops.",
4481 "target stop-hook add"),
4482 IOHandlerDelegateMultiline("DONE",
4483 IOHandlerDelegate::Completion::LLDBCommand),
4484 m_options() {}
4485
4486 ~CommandObjectTargetStopHookAdd() override = default;
4487
4488 Options *GetOptions() override { return &m_options; }
4489
Jim Ingham5a988412012-06-08 21:56:10 +00004490protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004491 void IOHandlerActivated(IOHandler &io_handler) override {
4492 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4493 if (output_sp) {
4494 output_sp->PutCString(
4495 "Enter your stop hook command(s). Type 'DONE' to end.\n");
4496 output_sp->Flush();
Greg Clayton44d93782014-01-27 23:43:24 +00004497 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004498 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004499
Kate Stoneb9c1b512016-09-06 20:57:50 +00004500 void IOHandlerInputComplete(IOHandler &io_handler,
4501 std::string &line) override {
4502 if (m_stop_hook_sp) {
4503 if (line.empty()) {
4504 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
4505 if (error_sp) {
4506 error_sp->Printf("error: stop hook #%" PRIu64
4507 " aborted, no commands.\n",
4508 m_stop_hook_sp->GetID());
4509 error_sp->Flush();
Greg Clayton44d93782014-01-27 23:43:24 +00004510 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004511 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Jim Ingham9575d842011-03-11 03:53:59 +00004512 if (target)
Kate Stoneb9c1b512016-09-06 20:57:50 +00004513 target->RemoveStopHookByID(m_stop_hook_sp->GetID());
4514 } else {
4515 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
4516 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4517 if (output_sp) {
4518 output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4519 m_stop_hook_sp->GetID());
4520 output_sp->Flush();
Jim Ingham9575d842011-03-11 03:53:59 +00004521 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004522 }
4523 m_stop_hook_sp.reset();
Jim Ingham9575d842011-03-11 03:53:59 +00004524 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004525 io_handler.SetIsDone(true);
4526 }
4527
4528 bool DoExecute(Args &command, CommandReturnObject &result) override {
4529 m_stop_hook_sp.reset();
4530
4531 Target *target = GetSelectedOrDummyTarget();
4532 if (target) {
4533 Target::StopHookSP new_hook_sp = target->CreateStopHook();
4534
4535 // First step, make the specifier.
4536 std::unique_ptr<SymbolContextSpecifier> specifier_ap;
4537 if (m_options.m_sym_ctx_specified) {
4538 specifier_ap.reset(new SymbolContextSpecifier(
4539 m_interpreter.GetDebugger().GetSelectedTarget()));
4540
4541 if (!m_options.m_module_name.empty()) {
4542 specifier_ap->AddSpecification(
4543 m_options.m_module_name.c_str(),
4544 SymbolContextSpecifier::eModuleSpecified);
4545 }
4546
4547 if (!m_options.m_class_name.empty()) {
4548 specifier_ap->AddSpecification(
4549 m_options.m_class_name.c_str(),
4550 SymbolContextSpecifier::eClassOrNamespaceSpecified);
4551 }
4552
4553 if (!m_options.m_file_name.empty()) {
4554 specifier_ap->AddSpecification(
4555 m_options.m_file_name.c_str(),
4556 SymbolContextSpecifier::eFileSpecified);
4557 }
4558
4559 if (m_options.m_line_start != 0) {
4560 specifier_ap->AddLineSpecification(
4561 m_options.m_line_start,
4562 SymbolContextSpecifier::eLineStartSpecified);
4563 }
4564
4565 if (m_options.m_line_end != UINT_MAX) {
4566 specifier_ap->AddLineSpecification(
4567 m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4568 }
4569
4570 if (!m_options.m_function_name.empty()) {
4571 specifier_ap->AddSpecification(
4572 m_options.m_function_name.c_str(),
4573 SymbolContextSpecifier::eFunctionSpecified);
4574 }
4575 }
4576
4577 if (specifier_ap)
4578 new_hook_sp->SetSpecifier(specifier_ap.release());
4579
4580 // Next see if any of the thread options have been entered:
4581
4582 if (m_options.m_thread_specified) {
4583 ThreadSpec *thread_spec = new ThreadSpec();
4584
4585 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4586 thread_spec->SetTID(m_options.m_thread_id);
4587 }
4588
4589 if (m_options.m_thread_index != UINT32_MAX)
4590 thread_spec->SetIndex(m_options.m_thread_index);
4591
4592 if (!m_options.m_thread_name.empty())
4593 thread_spec->SetName(m_options.m_thread_name.c_str());
4594
4595 if (!m_options.m_queue_name.empty())
4596 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4597
4598 new_hook_sp->SetThreadSpecifier(thread_spec);
4599 }
4600 if (m_options.m_use_one_liner) {
4601 // Use one-liner.
4602 new_hook_sp->GetCommandPointer()->AppendString(
4603 m_options.m_one_liner.c_str());
4604 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4605 new_hook_sp->GetID());
4606 } else {
4607 m_stop_hook_sp = new_hook_sp;
4608 m_interpreter.GetLLDBCommandsFromIOHandler(
4609 "> ", // Prompt
4610 *this, // IOHandlerDelegate
4611 true, // Run IOHandler in async mode
4612 nullptr); // Baton for the "io_handler" that will be passed back
4613 // into our IOHandlerDelegate functions
4614 }
4615 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4616 } else {
4617 result.AppendError("invalid target\n");
4618 result.SetStatus(eReturnStatusFailed);
4619 }
4620
4621 return result.Succeeded();
4622 }
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004623
Jim Ingham9575d842011-03-11 03:53:59 +00004624private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004625 CommandOptions m_options;
4626 Target::StopHookSP m_stop_hook_sp;
Jim Ingham9575d842011-03-11 03:53:59 +00004627};
4628
Jim Ingham9575d842011-03-11 03:53:59 +00004629#pragma mark CommandObjectTargetStopHookDelete
4630
4631//-------------------------------------------------------------------------
4632// CommandObjectTargetStopHookDelete
4633//-------------------------------------------------------------------------
4634
Kate Stoneb9c1b512016-09-06 20:57:50 +00004635class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004636public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004637 CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4638 : CommandObjectParsed(interpreter, "target stop-hook delete",
4639 "Delete a stop-hook.",
4640 "target stop-hook delete [<idx>]") {}
Jim Ingham9575d842011-03-11 03:53:59 +00004641
Kate Stoneb9c1b512016-09-06 20:57:50 +00004642 ~CommandObjectTargetStopHookDelete() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004643
Jim Ingham5a988412012-06-08 21:56:10 +00004644protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004645 bool DoExecute(Args &command, CommandReturnObject &result) override {
4646 Target *target = GetSelectedOrDummyTarget();
4647 if (target) {
4648 // FIXME: see if we can use the breakpoint id style parser?
4649 size_t num_args = command.GetArgumentCount();
4650 if (num_args == 0) {
4651 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4652 result.SetStatus(eReturnStatusFailed);
4653 return false;
4654 } else {
4655 target->RemoveAllStopHooks();
Jim Ingham9575d842011-03-11 03:53:59 +00004656 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004657 } else {
4658 bool success;
4659 for (size_t i = 0; i < num_args; i++) {
4660 lldb::user_id_t user_id = StringConvert::ToUInt32(
4661 command.GetArgumentAtIndex(i), 0, 0, &success);
4662 if (!success) {
4663 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4664 command.GetArgumentAtIndex(i));
4665 result.SetStatus(eReturnStatusFailed);
4666 return false;
4667 }
4668 success = target->RemoveStopHookByID(user_id);
4669 if (!success) {
4670 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4671 command.GetArgumentAtIndex(i));
4672 result.SetStatus(eReturnStatusFailed);
4673 return false;
4674 }
Jim Ingham9575d842011-03-11 03:53:59 +00004675 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004676 }
4677 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4678 } else {
4679 result.AppendError("invalid target\n");
4680 result.SetStatus(eReturnStatusFailed);
Jim Ingham9575d842011-03-11 03:53:59 +00004681 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004682
4683 return result.Succeeded();
4684 }
Jim Ingham9575d842011-03-11 03:53:59 +00004685};
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004686
Jim Ingham9575d842011-03-11 03:53:59 +00004687#pragma mark CommandObjectTargetStopHookEnableDisable
4688
4689//-------------------------------------------------------------------------
4690// CommandObjectTargetStopHookEnableDisable
4691//-------------------------------------------------------------------------
4692
Kate Stoneb9c1b512016-09-06 20:57:50 +00004693class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004694public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004695 CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4696 bool enable, const char *name,
4697 const char *help, const char *syntax)
4698 : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4699 }
Jim Ingham9575d842011-03-11 03:53:59 +00004700
Kate Stoneb9c1b512016-09-06 20:57:50 +00004701 ~CommandObjectTargetStopHookEnableDisable() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004702
Jim Ingham5a988412012-06-08 21:56:10 +00004703protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004704 bool DoExecute(Args &command, CommandReturnObject &result) override {
4705 Target *target = GetSelectedOrDummyTarget();
4706 if (target) {
4707 // FIXME: see if we can use the breakpoint id style parser?
4708 size_t num_args = command.GetArgumentCount();
4709 bool success;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004710
Kate Stoneb9c1b512016-09-06 20:57:50 +00004711 if (num_args == 0) {
4712 target->SetAllStopHooksActiveState(m_enable);
4713 } else {
4714 for (size_t i = 0; i < num_args; i++) {
4715 lldb::user_id_t user_id = StringConvert::ToUInt32(
4716 command.GetArgumentAtIndex(i), 0, 0, &success);
4717 if (!success) {
4718 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4719 command.GetArgumentAtIndex(i));
4720 result.SetStatus(eReturnStatusFailed);
4721 return false;
4722 }
4723 success = target->SetStopHookActiveStateByID(user_id, m_enable);
4724 if (!success) {
4725 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4726 command.GetArgumentAtIndex(i));
4727 result.SetStatus(eReturnStatusFailed);
4728 return false;
4729 }
Jim Ingham9575d842011-03-11 03:53:59 +00004730 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004731 }
4732 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4733 } else {
4734 result.AppendError("invalid target\n");
4735 result.SetStatus(eReturnStatusFailed);
Jim Ingham9575d842011-03-11 03:53:59 +00004736 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004737 return result.Succeeded();
4738 }
4739
Jim Ingham9575d842011-03-11 03:53:59 +00004740private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004741 bool m_enable;
Jim Ingham9575d842011-03-11 03:53:59 +00004742};
4743
4744#pragma mark CommandObjectTargetStopHookList
4745
4746//-------------------------------------------------------------------------
4747// CommandObjectTargetStopHookList
4748//-------------------------------------------------------------------------
4749
Kate Stoneb9c1b512016-09-06 20:57:50 +00004750class CommandObjectTargetStopHookList : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004751public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004752 CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4753 : CommandObjectParsed(interpreter, "target stop-hook list",
4754 "List all stop-hooks.",
4755 "target stop-hook list [<type>]") {}
Jim Ingham9575d842011-03-11 03:53:59 +00004756
Kate Stoneb9c1b512016-09-06 20:57:50 +00004757 ~CommandObjectTargetStopHookList() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004758
Jim Ingham5a988412012-06-08 21:56:10 +00004759protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004760 bool DoExecute(Args &command, CommandReturnObject &result) override {
4761 Target *target = GetSelectedOrDummyTarget();
4762 if (!target) {
4763 result.AppendError("invalid target\n");
4764 result.SetStatus(eReturnStatusFailed);
4765 return result.Succeeded();
Jim Ingham9575d842011-03-11 03:53:59 +00004766 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004767
4768 size_t num_hooks = target->GetNumStopHooks();
4769 if (num_hooks == 0) {
4770 result.GetOutputStream().PutCString("No stop hooks.\n");
4771 } else {
4772 for (size_t i = 0; i < num_hooks; i++) {
4773 Target::StopHookSP this_hook = target->GetStopHookAtIndex(i);
4774 if (i > 0)
4775 result.GetOutputStream().PutCString("\n");
4776 this_hook->GetDescription(&(result.GetOutputStream()),
4777 eDescriptionLevelFull);
4778 }
4779 }
4780 result.SetStatus(eReturnStatusSuccessFinishResult);
4781 return result.Succeeded();
4782 }
Jim Ingham9575d842011-03-11 03:53:59 +00004783};
4784
4785#pragma mark CommandObjectMultiwordTargetStopHooks
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004786
Jim Ingham9575d842011-03-11 03:53:59 +00004787//-------------------------------------------------------------------------
4788// CommandObjectMultiwordTargetStopHooks
4789//-------------------------------------------------------------------------
4790
Kate Stoneb9c1b512016-09-06 20:57:50 +00004791class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
Jim Ingham9575d842011-03-11 03:53:59 +00004792public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004793 CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4794 : CommandObjectMultiword(
4795 interpreter, "target stop-hook",
4796 "Commands for operating on debugger target stop-hooks.",
4797 "target stop-hook <subcommand> [<subcommand-options>]") {
4798 LoadSubCommand("add", CommandObjectSP(
4799 new CommandObjectTargetStopHookAdd(interpreter)));
4800 LoadSubCommand(
4801 "delete",
4802 CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
4803 LoadSubCommand("disable",
4804 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4805 interpreter, false, "target stop-hook disable [<id>]",
4806 "Disable a stop-hook.", "target stop-hook disable")));
4807 LoadSubCommand("enable",
4808 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4809 interpreter, true, "target stop-hook enable [<id>]",
4810 "Enable a stop-hook.", "target stop-hook enable")));
4811 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
4812 interpreter)));
4813 }
Jim Ingham9575d842011-03-11 03:53:59 +00004814
Kate Stoneb9c1b512016-09-06 20:57:50 +00004815 ~CommandObjectMultiwordTargetStopHooks() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004816};
4817
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004818#pragma mark CommandObjectMultiwordTarget
4819
4820//-------------------------------------------------------------------------
4821// CommandObjectMultiwordTarget
4822//-------------------------------------------------------------------------
4823
Kate Stoneb9c1b512016-09-06 20:57:50 +00004824CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
4825 CommandInterpreter &interpreter)
4826 : CommandObjectMultiword(interpreter, "target",
4827 "Commands for operating on debugger targets.",
4828 "target <subcommand> [<subcommand-options>]") {
4829 LoadSubCommand("create",
4830 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
4831 LoadSubCommand("delete",
4832 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
4833 LoadSubCommand("list",
4834 CommandObjectSP(new CommandObjectTargetList(interpreter)));
4835 LoadSubCommand("select",
4836 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
4837 LoadSubCommand(
4838 "stop-hook",
4839 CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
4840 LoadSubCommand("modules",
4841 CommandObjectSP(new CommandObjectTargetModules(interpreter)));
4842 LoadSubCommand("symbols",
4843 CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
4844 LoadSubCommand("variable",
4845 CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004846}
4847
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004848CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;