blob: e6b917b0c6a0d725ae0fe8de18d765fb135c3b62 [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
12// C Includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000013// C++ Includes
Eugene Zelenkof13e6522016-02-25 19:02:39 +000014#include <cerrno>
15
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016// Other libraries and framework includes
17// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "lldb/Core/Debugger.h"
Greg Clayton44d93782014-01-27 23:43:24 +000019#include "lldb/Core/IOHandler.h"
Greg Clayton1f746072012-08-29 21:13:06 +000020#include "lldb/Core/Module.h"
21#include "lldb/Core/ModuleSpec.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000022#include "lldb/Core/Section.h"
Greg Clayton7260f622011-04-18 08:33:37 +000023#include "lldb/Core/State.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Core/Timer.h"
Greg Clayton644247c2011-07-07 01:59:51 +000025#include "lldb/Core/ValueObjectVariable.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000026#include "lldb/DataFormatters/ValueObjectPrinter.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000027#include "lldb/Host/StringConvert.h"
Greg Claytonc8f814d2012-09-27 03:13:55 +000028#include "lldb/Host/Symbols.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000029#include "lldb/Interpreter/Args.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Interpreter/CommandInterpreter.h"
31#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton7260f622011-04-18 08:33:37 +000032#include "lldb/Interpreter/OptionGroupArchitecture.h"
Greg Claytonaa149cb2011-08-11 02:48:45 +000033#include "lldb/Interpreter/OptionGroupBoolean.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000034#include "lldb/Interpreter/OptionGroupFile.h"
Greg Clayton1deb7962011-10-25 06:44:01 +000035#include "lldb/Interpreter/OptionGroupFormat.h"
Greg Clayton7260f622011-04-18 08:33:37 +000036#include "lldb/Interpreter/OptionGroupPlatform.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000037#include "lldb/Interpreter/OptionGroupString.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000038#include "lldb/Interpreter/OptionGroupUInt64.h"
39#include "lldb/Interpreter/OptionGroupUUID.h"
Greg Clayton644247c2011-07-07 01:59:51 +000040#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000041#include "lldb/Interpreter/OptionGroupVariable.h"
42#include "lldb/Interpreter/Options.h"
Greg Clayton1f746072012-08-29 21:13:06 +000043#include "lldb/Symbol/CompileUnit.h"
Jason Molenda380241a2012-07-12 00:20:07 +000044#include "lldb/Symbol/FuncUnwinders.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000045#include "lldb/Symbol/LineTable.h"
46#include "lldb/Symbol/ObjectFile.h"
47#include "lldb/Symbol/SymbolFile.h"
48#include "lldb/Symbol/SymbolVendor.h"
Jason Molenda380241a2012-07-12 00:20:07 +000049#include "lldb/Symbol/UnwindPlan.h"
Greg Clayton644247c2011-07-07 01:59:51 +000050#include "lldb/Symbol/VariableList.h"
Zachary Turner32abc6e2015-03-03 19:23:09 +000051#include "lldb/Target/ABI.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052#include "lldb/Target/Process.h"
Greg Claytond5944cd2013-12-06 01:12:00 +000053#include "lldb/Target/SectionLoadList.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000054#include "lldb/Target/StackFrame.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055#include "lldb/Target/Thread.h"
Jim Ingham9575d842011-03-11 03:53:59 +000056#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057
58using namespace lldb;
59using namespace lldb_private;
60
Kate Stoneb9c1b512016-09-06 20:57:50 +000061static void DumpTargetInfo(uint32_t target_idx, Target *target,
62 const char *prefix_cstr,
63 bool show_stopped_process_status, Stream &strm) {
64 const ArchSpec &target_arch = target->GetArchitecture();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000065
Kate Stoneb9c1b512016-09-06 20:57:50 +000066 Module *exe_module = target->GetExecutableModulePointer();
67 char exe_path[PATH_MAX];
68 bool exe_valid = false;
69 if (exe_module)
70 exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000071
Kate Stoneb9c1b512016-09-06 20:57:50 +000072 if (!exe_valid)
73 ::strcpy(exe_path, "<none>");
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000074
Kate Stoneb9c1b512016-09-06 20:57:50 +000075 strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
76 exe_path);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000077
Kate Stoneb9c1b512016-09-06 20:57:50 +000078 uint32_t properties = 0;
79 if (target_arch.IsValid()) {
80 strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
81 target_arch.DumpTriple(strm);
82 properties++;
83 }
84 PlatformSP platform_sp(target->GetPlatform());
85 if (platform_sp)
86 strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ",
87 platform_sp->GetName().GetCString());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000088
Kate Stoneb9c1b512016-09-06 20:57:50 +000089 ProcessSP process_sp(target->GetProcessSP());
90 bool show_process_status = false;
91 if (process_sp) {
92 lldb::pid_t pid = process_sp->GetID();
93 StateType state = process_sp->GetState();
94 if (show_stopped_process_status)
95 show_process_status = StateIsStoppedState(state, true);
96 const char *state_cstr = StateAsCString(state);
97 if (pid != LLDB_INVALID_PROCESS_ID)
98 strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
99 strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
100 }
101 if (properties > 0)
102 strm.PutCString(" )\n");
103 else
104 strm.EOL();
105 if (show_process_status) {
106 const bool only_threads_with_stop_reason = true;
107 const uint32_t start_frame = 0;
108 const uint32_t num_frames = 1;
109 const uint32_t num_frames_with_source = 1;
Jim Ingham6a9767c2016-11-08 20:36:40 +0000110 const bool stop_format = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000111 process_sp->GetStatus(strm);
112 process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
113 start_frame, num_frames,
Jim Ingham6a9767c2016-11-08 20:36:40 +0000114 num_frames_with_source, stop_format);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000115 }
Greg Clayton7260f622011-04-18 08:33:37 +0000116}
117
Kate Stoneb9c1b512016-09-06 20:57:50 +0000118static uint32_t DumpTargetList(TargetList &target_list,
119 bool show_stopped_process_status, Stream &strm) {
120 const uint32_t num_targets = target_list.GetNumTargets();
121 if (num_targets) {
122 TargetSP selected_target_sp(target_list.GetSelectedTarget());
123 strm.PutCString("Current targets:\n");
124 for (uint32_t i = 0; i < num_targets; ++i) {
125 TargetSP target_sp(target_list.GetTargetAtIndex(i));
126 if (target_sp) {
127 bool is_selected = target_sp.get() == selected_target_sp.get();
128 DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
129 show_stopped_process_status, strm);
130 }
Greg Clayton7260f622011-04-18 08:33:37 +0000131 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000132 }
133 return num_targets;
Greg Clayton7260f622011-04-18 08:33:37 +0000134}
Eugene Zelenkof13e6522016-02-25 19:02:39 +0000135
Greg Clayton7260f622011-04-18 08:33:37 +0000136#pragma mark CommandObjectTargetCreate
137
138//-------------------------------------------------------------------------
139// "target create"
140//-------------------------------------------------------------------------
141
Kate Stoneb9c1b512016-09-06 20:57:50 +0000142class CommandObjectTargetCreate : public CommandObjectParsed {
Greg Clayton7260f622011-04-18 08:33:37 +0000143public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000144 CommandObjectTargetCreate(CommandInterpreter &interpreter)
145 : CommandObjectParsed(
146 interpreter, "target create",
147 "Create a target using the argument as the main executable.",
148 nullptr),
149 m_option_group(), m_arch_option(),
150 m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
151 "Fullpath to a core file to use for this target."),
152 m_platform_path(LLDB_OPT_SET_1, false, "platform-path", 'P', 0,
153 eArgTypePath,
154 "Path to the remote file to use for this target."),
155 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
156 eArgTypeFilename, "Fullpath to a stand alone debug "
157 "symbols file for when debug symbols "
158 "are not in the executable."),
159 m_remote_file(
160 LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
161 "Fullpath to the file on the remote host if debugging remotely."),
162 m_add_dependents(LLDB_OPT_SET_1, false, "no-dependents", 'd',
163 "Don't load dependent files when creating the target, "
164 "just add the specified executable.",
165 true, true) {
166 CommandArgumentEntry arg;
167 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000168
Kate Stoneb9c1b512016-09-06 20:57:50 +0000169 // Define the first (and only) variant of this arg.
170 file_arg.arg_type = eArgTypeFilename;
171 file_arg.arg_repetition = eArgRepeatPlain;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000172
Kate Stoneb9c1b512016-09-06 20:57:50 +0000173 // There is only one variant this argument could be; put it into the
174 // argument entry.
175 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000176
Kate Stoneb9c1b512016-09-06 20:57:50 +0000177 // Push the data for the first argument into the m_arguments vector.
178 m_arguments.push_back(arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000179
Kate Stoneb9c1b512016-09-06 20:57:50 +0000180 m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
181 m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
182 m_option_group.Append(&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
183 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
184 m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
185 m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
186 m_option_group.Finalize();
187 }
Greg Clayton7260f622011-04-18 08:33:37 +0000188
Kate Stoneb9c1b512016-09-06 20:57:50 +0000189 ~CommandObjectTargetCreate() override = default;
Greg Clayton7260f622011-04-18 08:33:37 +0000190
Kate Stoneb9c1b512016-09-06 20:57:50 +0000191 Options *GetOptions() override { return &m_option_group; }
Greg Clayton7260f622011-04-18 08:33:37 +0000192
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193 int HandleArgumentCompletion(Args &input, int &cursor_index,
194 int &cursor_char_position,
195 OptionElementVector &opt_element_vector,
196 int match_start_point, int max_return_elements,
197 bool &word_complete,
198 StringList &matches) override {
199 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
200 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000201
Kate Stoneb9c1b512016-09-06 20:57:50 +0000202 CommandCompletions::InvokeCommonCompletionCallbacks(
203 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
204 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
205 word_complete, matches);
206 return matches.GetSize();
207 }
Jim Ingham5a988412012-06-08 21:56:10 +0000208
209protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000210 bool DoExecute(Args &command, CommandReturnObject &result) override {
211 const size_t argc = command.GetArgumentCount();
212 FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
213 FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
Greg Claytonc3776bf2012-02-09 06:16:32 +0000214
Kate Stoneb9c1b512016-09-06 20:57:50 +0000215 if (core_file) {
216 if (!core_file.Exists()) {
217 result.AppendErrorWithFormat("core file '%s' doesn't exist",
218 core_file.GetPath().c_str());
219 result.SetStatus(eReturnStatusFailed);
220 return false;
221 }
222 if (!core_file.Readable()) {
223 result.AppendErrorWithFormat("core file '%s' is not readable",
224 core_file.GetPath().c_str());
225 result.SetStatus(eReturnStatusFailed);
226 return false;
227 }
Greg Clayton7260f622011-04-18 08:33:37 +0000228 }
229
Kate Stoneb9c1b512016-09-06 20:57:50 +0000230 if (argc == 1 || core_file || remote_file) {
231 FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
232 if (symfile) {
233 if (symfile.Exists()) {
234 if (!symfile.Readable()) {
235 result.AppendErrorWithFormat("symbol file '%s' is not readable",
236 symfile.GetPath().c_str());
237 result.SetStatus(eReturnStatusFailed);
238 return false;
239 }
240 } else {
241 char symfile_path[PATH_MAX];
242 symfile.GetPath(symfile_path, sizeof(symfile_path));
243 result.AppendErrorWithFormat("invalid symbol file path '%s'",
244 symfile_path);
245 result.SetStatus(eReturnStatusFailed);
246 return false;
247 }
248 }
249
250 const char *file_path = command.GetArgumentAtIndex(0);
251 Timer scoped_timer(LLVM_PRETTY_FUNCTION, "(lldb) target create '%s'",
252 file_path);
253 FileSpec file_spec;
254
255 if (file_path)
256 file_spec.SetFile(file_path, true);
257
258 bool must_set_platform_path = false;
259
260 Debugger &debugger = m_interpreter.GetDebugger();
261
262 TargetSP target_sp;
263 const char *arch_cstr = m_arch_option.GetArchitectureName();
264 const bool get_dependent_files =
265 m_add_dependents.GetOptionValue().GetCurrentValue();
266 Error error(debugger.GetTargetList().CreateTarget(
267 debugger, file_path, arch_cstr, get_dependent_files, nullptr,
268 target_sp));
269
270 if (target_sp) {
271 // Only get the platform after we create the target because we might
272 // have
273 // switched platforms depending on what the arguments were to
274 // CreateTarget()
275 // we can't rely on the selected platform.
276
277 PlatformSP platform_sp = target_sp->GetPlatform();
278
279 if (remote_file) {
280 if (platform_sp) {
281 // I have a remote file.. two possible cases
282 if (file_spec && file_spec.Exists()) {
283 // if the remote file does not exist, push it there
284 if (!platform_sp->GetFileExists(remote_file)) {
285 Error err = platform_sp->PutFile(file_spec, remote_file);
286 if (err.Fail()) {
287 result.AppendError(err.AsCString());
288 result.SetStatus(eReturnStatusFailed);
289 return false;
290 }
291 }
292 } else {
293 // there is no local file and we need one
294 // in order to make the remote ---> local transfer we need a
295 // platform
296 // TODO: if the user has passed in a --platform argument, use it
297 // to fetch the right platform
298 if (!platform_sp) {
299 result.AppendError(
300 "unable to perform remote debugging without a platform");
301 result.SetStatus(eReturnStatusFailed);
302 return false;
303 }
304 if (file_path) {
305 // copy the remote file to the local file
306 Error err = platform_sp->GetFile(remote_file, file_spec);
307 if (err.Fail()) {
308 result.AppendError(err.AsCString());
309 result.SetStatus(eReturnStatusFailed);
310 return false;
311 }
312 } else {
313 // make up a local file
314 result.AppendError("remote --> local transfer without local "
315 "path is not implemented yet");
316 result.SetStatus(eReturnStatusFailed);
317 return false;
318 }
319 }
320 } else {
321 result.AppendError("no platform found for target");
322 result.SetStatus(eReturnStatusFailed);
323 return false;
324 }
325 }
326
327 if (symfile || remote_file) {
328 ModuleSP module_sp(target_sp->GetExecutableModule());
329 if (module_sp) {
330 if (symfile)
331 module_sp->SetSymbolFileFileSpec(symfile);
332 if (remote_file) {
333 std::string remote_path = remote_file.GetPath();
334 target_sp->SetArg0(remote_path.c_str());
335 module_sp->SetPlatformFileSpec(remote_file);
336 }
337 }
338 }
339
340 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
341 if (must_set_platform_path) {
342 ModuleSpec main_module_spec(file_spec);
343 ModuleSP module_sp = target_sp->GetSharedModule(main_module_spec);
344 if (module_sp)
345 module_sp->SetPlatformFileSpec(remote_file);
346 }
347 if (core_file) {
348 char core_path[PATH_MAX];
349 core_file.GetPath(core_path, sizeof(core_path));
350 if (core_file.Exists()) {
351 if (!core_file.Readable()) {
352 result.AppendMessageWithFormat(
353 "Core file '%s' is not readable.\n", core_path);
354 result.SetStatus(eReturnStatusFailed);
355 return false;
356 }
357 FileSpec core_file_dir;
358 core_file_dir.GetDirectory() = core_file.GetDirectory();
359 target_sp->GetExecutableSearchPaths().Append(core_file_dir);
360
361 ProcessSP process_sp(target_sp->CreateProcess(
362 m_interpreter.GetDebugger().GetListener(), nullptr,
363 &core_file));
364
365 if (process_sp) {
366 // Seems weird that we Launch a core file, but that is
367 // what we do!
368 error = process_sp->LoadCore();
369
370 if (error.Fail()) {
371 result.AppendError(
372 error.AsCString("can't find plug-in for core file"));
373 result.SetStatus(eReturnStatusFailed);
374 return false;
375 } else {
376 result.AppendMessageWithFormat(
377 "Core file '%s' (%s) was loaded.\n", core_path,
378 target_sp->GetArchitecture().GetArchitectureName());
379 result.SetStatus(eReturnStatusSuccessFinishNoResult);
380 }
381 } else {
382 result.AppendErrorWithFormat(
383 "Unable to find process plug-in for core file '%s'\n",
384 core_path);
385 result.SetStatus(eReturnStatusFailed);
386 }
387 } else {
388 result.AppendErrorWithFormat("Core file '%s' does not exist\n",
389 core_path);
390 result.SetStatus(eReturnStatusFailed);
391 }
392 } else {
393 result.AppendMessageWithFormat(
394 "Current executable set to '%s' (%s).\n", file_path,
395 target_sp->GetArchitecture().GetArchitectureName());
396 result.SetStatus(eReturnStatusSuccessFinishNoResult);
397 }
398 } else {
399 result.AppendError(error.AsCString());
400 result.SetStatus(eReturnStatusFailed);
401 }
402 } else {
403 result.AppendErrorWithFormat("'%s' takes exactly one executable path "
404 "argument, or use the --core option.\n",
405 m_cmd_name.c_str());
406 result.SetStatus(eReturnStatusFailed);
407 }
408 return result.Succeeded();
409 }
410
Greg Clayton7260f622011-04-18 08:33:37 +0000411private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000412 OptionGroupOptions m_option_group;
413 OptionGroupArchitecture m_arch_option;
414 OptionGroupFile m_core_file;
415 OptionGroupFile m_platform_path;
416 OptionGroupFile m_symbol_file;
417 OptionGroupFile m_remote_file;
418 OptionGroupBoolean m_add_dependents;
Greg Clayton7260f622011-04-18 08:33:37 +0000419};
420
421#pragma mark CommandObjectTargetList
422
423//----------------------------------------------------------------------
424// "target list"
425//----------------------------------------------------------------------
426
Kate Stoneb9c1b512016-09-06 20:57:50 +0000427class CommandObjectTargetList : public CommandObjectParsed {
Greg Clayton7260f622011-04-18 08:33:37 +0000428public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000429 CommandObjectTargetList(CommandInterpreter &interpreter)
430 : CommandObjectParsed(
431 interpreter, "target list",
432 "List all current targets in the current debug session.", nullptr) {
433 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000434
Kate Stoneb9c1b512016-09-06 20:57:50 +0000435 ~CommandObjectTargetList() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000436
Jim Ingham5a988412012-06-08 21:56:10 +0000437protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000438 bool DoExecute(Args &args, CommandReturnObject &result) override {
439 if (args.GetArgumentCount() == 0) {
440 Stream &strm = result.GetOutputStream();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000441
Kate Stoneb9c1b512016-09-06 20:57:50 +0000442 bool show_stopped_process_status = false;
443 if (DumpTargetList(m_interpreter.GetDebugger().GetTargetList(),
444 show_stopped_process_status, strm) == 0) {
445 strm.PutCString("No targets.\n");
446 }
447 result.SetStatus(eReturnStatusSuccessFinishResult);
448 } else {
449 result.AppendError("the 'target list' command takes no arguments\n");
450 result.SetStatus(eReturnStatusFailed);
Greg Clayton7260f622011-04-18 08:33:37 +0000451 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000452 return result.Succeeded();
453 }
Greg Clayton7260f622011-04-18 08:33:37 +0000454};
455
Greg Clayton7260f622011-04-18 08:33:37 +0000456#pragma mark CommandObjectTargetSelect
457
458//----------------------------------------------------------------------
459// "target select"
460//----------------------------------------------------------------------
461
Kate Stoneb9c1b512016-09-06 20:57:50 +0000462class CommandObjectTargetSelect : public CommandObjectParsed {
Greg Clayton7260f622011-04-18 08:33:37 +0000463public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000464 CommandObjectTargetSelect(CommandInterpreter &interpreter)
465 : CommandObjectParsed(
466 interpreter, "target select",
467 "Select a target as the current target by target index.", nullptr) {
468 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000469
Kate Stoneb9c1b512016-09-06 20:57:50 +0000470 ~CommandObjectTargetSelect() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000471
Jim Ingham5a988412012-06-08 21:56:10 +0000472protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000473 bool DoExecute(Args &args, CommandReturnObject &result) override {
474 if (args.GetArgumentCount() == 1) {
475 bool success = false;
476 const char *target_idx_arg = args.GetArgumentAtIndex(0);
477 uint32_t target_idx =
478 StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success);
479 if (success) {
480 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
481 const uint32_t num_targets = target_list.GetNumTargets();
482 if (target_idx < num_targets) {
483 TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
484 if (target_sp) {
485 Stream &strm = result.GetOutputStream();
486 target_list.SetSelectedTarget(target_sp.get());
487 bool show_stopped_process_status = false;
488 DumpTargetList(target_list, show_stopped_process_status, strm);
489 result.SetStatus(eReturnStatusSuccessFinishResult);
490 } else {
491 result.AppendErrorWithFormat("target #%u is NULL in target list\n",
492 target_idx);
493 result.SetStatus(eReturnStatusFailed);
494 }
495 } else {
496 if (num_targets > 0) {
497 result.AppendErrorWithFormat(
498 "index %u is out of range, valid target indexes are 0 - %u\n",
499 target_idx, num_targets - 1);
500 } else {
501 result.AppendErrorWithFormat(
502 "index %u is out of range since there are no active targets\n",
503 target_idx);
504 }
505 result.SetStatus(eReturnStatusFailed);
Greg Clayton7260f622011-04-18 08:33:37 +0000506 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000507 } else {
508 result.AppendErrorWithFormat("invalid index string value '%s'\n",
509 target_idx_arg);
510 result.SetStatus(eReturnStatusFailed);
511 }
512 } else {
513 result.AppendError(
514 "'target select' takes a single argument: a target index\n");
515 result.SetStatus(eReturnStatusFailed);
Greg Clayton7260f622011-04-18 08:33:37 +0000516 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000517 return result.Succeeded();
518 }
Greg Clayton7260f622011-04-18 08:33:37 +0000519};
520
Greg Clayton3418c852011-08-10 02:10:13 +0000521#pragma mark CommandObjectTargetSelect
522
523//----------------------------------------------------------------------
524// "target delete"
525//----------------------------------------------------------------------
526
Kate Stoneb9c1b512016-09-06 20:57:50 +0000527class CommandObjectTargetDelete : public CommandObjectParsed {
Greg Clayton3418c852011-08-10 02:10:13 +0000528public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000529 CommandObjectTargetDelete(CommandInterpreter &interpreter)
530 : CommandObjectParsed(interpreter, "target delete",
Eugene Zelenkof13e6522016-02-25 19:02:39 +0000531 "Delete one or more targets by target index.",
532 nullptr),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000533 m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
534 "Delete all targets.", false, true),
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000535 m_cleanup_option(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000536 LLDB_OPT_SET_1, false, "clean", 'c',
537 "Perform extra cleanup to minimize memory consumption after "
538 "deleting the target. "
539 "By default, LLDB will keep in memory any modules previously "
540 "loaded by the target as well "
541 "as all of its debug info. Specifying --clean will unload all of "
542 "these shared modules and "
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000543 "cause them to be reparsed again the next time the target is run",
Kate Stoneb9c1b512016-09-06 20:57:50 +0000544 false, true) {
545 m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
546 m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
547 m_option_group.Finalize();
548 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000549
Kate Stoneb9c1b512016-09-06 20:57:50 +0000550 ~CommandObjectTargetDelete() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000551
Kate Stoneb9c1b512016-09-06 20:57:50 +0000552 Options *GetOptions() override { return &m_option_group; }
Jim Ingham5a988412012-06-08 21:56:10 +0000553
554protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000555 bool DoExecute(Args &args, CommandReturnObject &result) override {
556 const size_t argc = args.GetArgumentCount();
557 std::vector<TargetSP> delete_target_list;
558 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
559 TargetSP target_sp;
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000560
Kate Stoneb9c1b512016-09-06 20:57:50 +0000561 if (m_all_option.GetOptionValue()) {
562 for (int i = 0; i < target_list.GetNumTargets(); ++i)
563 delete_target_list.push_back(target_list.GetTargetAtIndex(i));
564 } else if (argc > 0) {
565 const uint32_t num_targets = target_list.GetNumTargets();
566 // Bail out if don't have any targets.
567 if (num_targets == 0) {
568 result.AppendError("no targets to delete");
569 result.SetStatus(eReturnStatusFailed);
570 return false;
571 }
572
Zachary Turner97d2c402016-10-05 23:40:23 +0000573 for (auto &entry : args.entries()) {
574 uint32_t target_idx;
575 if (entry.ref.getAsInteger(0, target_idx)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000576 result.AppendErrorWithFormat("invalid target index '%s'\n",
Zachary Turner97d2c402016-10-05 23:40:23 +0000577 entry.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000578 result.SetStatus(eReturnStatusFailed);
579 return false;
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000580 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000581 if (target_idx < num_targets) {
582 target_sp = target_list.GetTargetAtIndex(target_idx);
583 if (target_sp) {
584 delete_target_list.push_back(target_sp);
585 continue;
586 }
Greg Clayton3418c852011-08-10 02:10:13 +0000587 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000588 if (num_targets > 1)
589 result.AppendErrorWithFormat("target index %u is out of range, valid "
590 "target indexes are 0 - %u\n",
591 target_idx, num_targets - 1);
Greg Clayton3418c852011-08-10 02:10:13 +0000592 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000593 result.AppendErrorWithFormat(
594 "target index %u is out of range, the only valid index is 0\n",
595 target_idx);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000596
Kate Stoneb9c1b512016-09-06 20:57:50 +0000597 result.SetStatus(eReturnStatusFailed);
598 return false;
599 }
600 } else {
601 target_sp = target_list.GetSelectedTarget();
602 if (!target_sp) {
603 result.AppendErrorWithFormat("no target is currently selected\n");
604 result.SetStatus(eReturnStatusFailed);
605 return false;
606 }
607 delete_target_list.push_back(target_sp);
Greg Clayton3418c852011-08-10 02:10:13 +0000608 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000609
Kate Stoneb9c1b512016-09-06 20:57:50 +0000610 const size_t num_targets_to_delete = delete_target_list.size();
611 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
612 target_sp = delete_target_list[idx];
613 target_list.DeleteTarget(target_sp);
614 target_sp->Destroy();
615 }
616 // If "--clean" was specified, prune any orphaned shared modules from
617 // the global shared module list
618 if (m_cleanup_option.GetOptionValue()) {
619 const bool mandatory = true;
620 ModuleList::RemoveOrphanSharedModules(mandatory);
621 }
622 result.GetOutputStream().Printf("%u targets deleted.\n",
623 (uint32_t)num_targets_to_delete);
624 result.SetStatus(eReturnStatusSuccessFinishResult);
625
626 return true;
627 }
628
629 OptionGroupOptions m_option_group;
630 OptionGroupBoolean m_all_option;
631 OptionGroupBoolean m_cleanup_option;
Greg Clayton3418c852011-08-10 02:10:13 +0000632};
633
Greg Clayton644247c2011-07-07 01:59:51 +0000634#pragma mark CommandObjectTargetVariable
635
636//----------------------------------------------------------------------
637// "target variable"
638//----------------------------------------------------------------------
639
Kate Stoneb9c1b512016-09-06 20:57:50 +0000640class CommandObjectTargetVariable : public CommandObjectParsed {
641 static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
642 static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
Saleem Abdulrasool44edda02014-03-18 04:43:47 +0000643
Greg Clayton644247c2011-07-07 01:59:51 +0000644public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000645 CommandObjectTargetVariable(CommandInterpreter &interpreter)
646 : CommandObjectParsed(interpreter, "target variable",
647 "Read global variables for the current target, "
648 "before or while running a process.",
649 nullptr, eCommandRequiresTarget),
650 m_option_group(),
651 m_option_variable(false), // Don't include frame options
652 m_option_format(eFormatDefault),
653 m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
654 0, eArgTypeFilename,
655 "A basename or fullpath to a file that contains "
656 "global variables. This option can be "
657 "specified multiple times."),
658 m_option_shared_libraries(
659 LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
660 eArgTypeFilename,
661 "A basename or fullpath to a shared library to use in the search "
662 "for global "
663 "variables. This option can be specified multiple times."),
664 m_varobj_options() {
665 CommandArgumentEntry arg;
666 CommandArgumentData var_name_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000667
Kate Stoneb9c1b512016-09-06 20:57:50 +0000668 // Define the first (and only) variant of this arg.
669 var_name_arg.arg_type = eArgTypeVarName;
670 var_name_arg.arg_repetition = eArgRepeatPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000671
Kate Stoneb9c1b512016-09-06 20:57:50 +0000672 // There is only one variant this argument could be; put it into the
673 // argument entry.
674 arg.push_back(var_name_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000675
Kate Stoneb9c1b512016-09-06 20:57:50 +0000676 // Push the data for the first argument into the m_arguments vector.
677 m_arguments.push_back(arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000678
Kate Stoneb9c1b512016-09-06 20:57:50 +0000679 m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
680 m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
681 m_option_group.Append(&m_option_format,
682 OptionGroupFormat::OPTION_GROUP_FORMAT |
683 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
684 LLDB_OPT_SET_1);
685 m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
686 LLDB_OPT_SET_1);
687 m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
688 LLDB_OPT_SET_1);
689 m_option_group.Finalize();
690 }
691
692 ~CommandObjectTargetVariable() override = default;
693
694 void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
695 const char *root_name) {
696 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
697
698 if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
699 valobj_sp->IsRuntimeSupportValue())
700 return;
701
702 switch (var_sp->GetScope()) {
703 case eValueTypeVariableGlobal:
704 if (m_option_variable.show_scope)
705 s.PutCString("GLOBAL: ");
706 break;
707
708 case eValueTypeVariableStatic:
709 if (m_option_variable.show_scope)
710 s.PutCString("STATIC: ");
711 break;
712
713 case eValueTypeVariableArgument:
714 if (m_option_variable.show_scope)
715 s.PutCString(" ARG: ");
716 break;
717
718 case eValueTypeVariableLocal:
719 if (m_option_variable.show_scope)
720 s.PutCString(" LOCAL: ");
721 break;
722
723 case eValueTypeVariableThreadLocal:
724 if (m_option_variable.show_scope)
725 s.PutCString("THREAD: ");
726 break;
727
728 default:
729 break;
Greg Clayton644247c2011-07-07 01:59:51 +0000730 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000731
Kate Stoneb9c1b512016-09-06 20:57:50 +0000732 if (m_option_variable.show_decl) {
733 bool show_fullpaths = false;
734 bool show_module = true;
735 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
736 s.PutCString(": ");
Greg Clayton884fb692011-07-08 21:46:14 +0000737 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000738
Kate Stoneb9c1b512016-09-06 20:57:50 +0000739 const Format format = m_option_format.GetFormat();
740 if (format != eFormatDefault)
741 options.SetFormat(format);
Greg Clayton884fb692011-07-08 21:46:14 +0000742
Kate Stoneb9c1b512016-09-06 20:57:50 +0000743 options.SetRootValueObjectName(root_name);
744
745 valobj_sp->Dump(s, options);
746 }
747
748 static size_t GetVariableCallback(void *baton, const char *name,
749 VariableList &variable_list) {
750 Target *target = static_cast<Target *>(baton);
751 if (target) {
752 return target->GetImages().FindGlobalVariables(ConstString(name), true,
753 UINT32_MAX, variable_list);
Jim Ingham5a988412012-06-08 21:56:10 +0000754 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000755 return 0;
756 }
757
758 Options *GetOptions() override { return &m_option_group; }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000759
Jim Ingham5a988412012-06-08 21:56:10 +0000760protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000761 void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
762 const SymbolContext &sc,
763 const VariableList &variable_list, Stream &s) {
764 size_t count = variable_list.GetSize();
765 if (count > 0) {
766 if (sc.module_sp) {
767 if (sc.comp_unit) {
768 s.Printf("Global variables for %s in %s:\n",
769 sc.comp_unit->GetPath().c_str(),
770 sc.module_sp->GetFileSpec().GetPath().c_str());
771 } else {
772 s.Printf("Global variables for %s\n",
773 sc.module_sp->GetFileSpec().GetPath().c_str());
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000774 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000775 } else if (sc.comp_unit) {
776 s.Printf("Global variables for %s\n", sc.comp_unit->GetPath().c_str());
777 }
778
779 for (uint32_t i = 0; i < count; ++i) {
780 VariableSP var_sp(variable_list.GetVariableAtIndex(i));
781 if (var_sp) {
782 ValueObjectSP valobj_sp(ValueObjectVariable::Create(
783 exe_ctx.GetBestExecutionContextScope(), var_sp));
784
785 if (valobj_sp)
786 DumpValueObject(s, var_sp, valobj_sp,
787 var_sp->GetName().GetCString());
788 }
789 }
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000790 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000791 }
Eugene Zelenkof13e6522016-02-25 19:02:39 +0000792
Kate Stoneb9c1b512016-09-06 20:57:50 +0000793 bool DoExecute(Args &args, CommandReturnObject &result) override {
794 Target *target = m_exe_ctx.GetTargetPtr();
795 const size_t argc = args.GetArgumentCount();
796 Stream &s = result.GetOutputStream();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000797
Kate Stoneb9c1b512016-09-06 20:57:50 +0000798 if (argc > 0) {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000799
Zachary Turner97d2c402016-10-05 23:40:23 +0000800 // TODO: Convert to entry-based iteration. Requires converting
801 // DumpValueObject.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000802 for (size_t idx = 0; idx < argc; ++idx) {
803 VariableList variable_list;
804 ValueObjectList valobj_list;
Greg Clayton884fb692011-07-08 21:46:14 +0000805
Kate Stoneb9c1b512016-09-06 20:57:50 +0000806 const char *arg = args.GetArgumentAtIndex(idx);
807 size_t matches = 0;
808 bool use_var_name = false;
809 if (m_option_variable.use_regex) {
Zachary Turner95eae422016-09-21 16:01:28 +0000810 RegularExpression regex(llvm::StringRef::withNullAsEmpty(arg));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000811 if (!regex.IsValid()) {
812 result.GetErrorStream().Printf(
813 "error: invalid regular expression: '%s'\n", arg);
814 result.SetStatus(eReturnStatusFailed);
815 return false;
816 }
817 use_var_name = true;
818 matches = target->GetImages().FindGlobalVariables(
819 regex, true, UINT32_MAX, variable_list);
820 } else {
821 Error error(Variable::GetValuesForVariableExpressionPath(
822 arg, m_exe_ctx.GetBestExecutionContextScope(),
823 GetVariableCallback, target, variable_list, valobj_list));
824 matches = variable_list.GetSize();
Greg Clayton644247c2011-07-07 01:59:51 +0000825 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000826
827 if (matches == 0) {
828 result.GetErrorStream().Printf(
829 "error: can't find global variable '%s'\n", arg);
830 result.SetStatus(eReturnStatusFailed);
831 return false;
832 } else {
833 for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
834 VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
835 if (var_sp) {
836 ValueObjectSP valobj_sp(
837 valobj_list.GetValueObjectAtIndex(global_idx));
838 if (!valobj_sp)
839 valobj_sp = ValueObjectVariable::Create(
840 m_exe_ctx.GetBestExecutionContextScope(), var_sp);
841
842 if (valobj_sp)
843 DumpValueObject(s, var_sp, valobj_sp,
844 use_var_name ? var_sp->GetName().GetCString()
845 : arg);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000846 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000847 }
848 }
849 }
850 } else {
851 const FileSpecList &compile_units =
852 m_option_compile_units.GetOptionValue().GetCurrentValue();
853 const FileSpecList &shlibs =
854 m_option_shared_libraries.GetOptionValue().GetCurrentValue();
855 SymbolContextList sc_list;
856 const size_t num_compile_units = compile_units.GetSize();
857 const size_t num_shlibs = shlibs.GetSize();
858 if (num_compile_units == 0 && num_shlibs == 0) {
859 bool success = false;
860 StackFrame *frame = m_exe_ctx.GetFramePtr();
861 CompileUnit *comp_unit = nullptr;
862 if (frame) {
863 SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
864 if (sc.comp_unit) {
865 const bool can_create = true;
866 VariableListSP comp_unit_varlist_sp(
867 sc.comp_unit->GetVariableList(can_create));
868 if (comp_unit_varlist_sp) {
869 size_t count = comp_unit_varlist_sp->GetSize();
870 if (count > 0) {
871 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
872 success = true;
873 }
874 }
875 }
876 }
877 if (!success) {
878 if (frame) {
879 if (comp_unit)
880 result.AppendErrorWithFormat(
881 "no global variables in current compile unit: %s\n",
882 comp_unit->GetPath().c_str());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000883 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000884 result.AppendErrorWithFormat(
885 "no debug information for frame %u\n",
886 frame->GetFrameIndex());
887 } else
888 result.AppendError("'target variable' takes one or more global "
889 "variable names as arguments\n");
890 result.SetStatus(eReturnStatusFailed);
891 }
892 } else {
893 SymbolContextList sc_list;
894 const bool append = true;
895 // We have one or more compile unit or shlib
896 if (num_shlibs > 0) {
897 for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
898 const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
899 ModuleSpec module_spec(module_file);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000900
Kate Stoneb9c1b512016-09-06 20:57:50 +0000901 ModuleSP module_sp(
902 target->GetImages().FindFirstModule(module_spec));
903 if (module_sp) {
904 if (num_compile_units > 0) {
905 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
906 module_sp->FindCompileUnits(
907 compile_units.GetFileSpecAtIndex(cu_idx), append,
908 sc_list);
909 } else {
910 SymbolContext sc;
911 sc.module_sp = module_sp;
912 sc_list.Append(sc);
913 }
914 } else {
915 // Didn't find matching shlib/module in target...
916 result.AppendErrorWithFormat(
917 "target doesn't contain the specified shared library: %s\n",
918 module_file.GetPath().c_str());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000919 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000920 }
921 } else {
922 // No shared libraries, we just want to find globals for the compile
923 // units files that were specified
924 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
925 target->GetImages().FindCompileUnits(
926 compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
Greg Clayton644247c2011-07-07 01:59:51 +0000927 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000928
Kate Stoneb9c1b512016-09-06 20:57:50 +0000929 const uint32_t num_scs = sc_list.GetSize();
930 if (num_scs > 0) {
931 SymbolContext sc;
932 for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
933 if (sc_list.GetContextAtIndex(sc_idx, sc)) {
934 if (sc.comp_unit) {
935 const bool can_create = true;
936 VariableListSP comp_unit_varlist_sp(
937 sc.comp_unit->GetVariableList(can_create));
938 if (comp_unit_varlist_sp)
939 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
940 s);
941 } else if (sc.module_sp) {
942 // Get all global variables for this module
943 lldb_private::RegularExpression all_globals_regex(
Zachary Turner95eae422016-09-21 16:01:28 +0000944 llvm::StringRef(
945 ".")); // Any global with at least one character
Kate Stoneb9c1b512016-09-06 20:57:50 +0000946 VariableList variable_list;
947 sc.module_sp->FindGlobalVariables(all_globals_regex, append,
948 UINT32_MAX, variable_list);
949 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
950 }
951 }
952 }
Enrico Granata61a80ba2011-08-12 16:42:31 +0000953 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000954 }
Greg Clayton644247c2011-07-07 01:59:51 +0000955 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000956
Kate Stoneb9c1b512016-09-06 20:57:50 +0000957 if (m_interpreter.TruncationWarningNecessary()) {
958 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
959 m_cmd_name.c_str());
960 m_interpreter.TruncationWarningGiven();
961 }
962
963 return result.Succeeded();
964 }
965
966 OptionGroupOptions m_option_group;
967 OptionGroupVariable m_option_variable;
968 OptionGroupFormat m_option_format;
969 OptionGroupFileList m_option_compile_units;
970 OptionGroupFileList m_option_shared_libraries;
971 OptionGroupValueObjectDisplay m_varobj_options;
Greg Clayton644247c2011-07-07 01:59:51 +0000972};
973
Greg Claytoneffe5c92011-05-03 22:09:39 +0000974#pragma mark CommandObjectTargetModulesSearchPathsAdd
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000975
Kate Stoneb9c1b512016-09-06 20:57:50 +0000976class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000977public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000978 CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
979 : CommandObjectParsed(interpreter, "target modules search-paths add",
980 "Add new image search paths substitution pairs to "
981 "the current target.",
982 nullptr) {
983 CommandArgumentEntry arg;
984 CommandArgumentData old_prefix_arg;
985 CommandArgumentData new_prefix_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000986
Kate Stoneb9c1b512016-09-06 20:57:50 +0000987 // Define the first variant of this arg pair.
988 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
989 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000990
Kate Stoneb9c1b512016-09-06 20:57:50 +0000991 // Define the first variant of this arg pair.
992 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
993 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000994
Kate Stoneb9c1b512016-09-06 20:57:50 +0000995 // There are two required arguments that must always occur together, i.e. an
996 // argument "pair". Because they
997 // must always occur together, they are treated as two variants of one
998 // argument rather than two independent
999 // arguments. Push them both into the first argument position for
1000 // m_arguments...
Caroline Tice405fe672010-10-04 22:28:36 +00001001
Kate Stoneb9c1b512016-09-06 20:57:50 +00001002 arg.push_back(old_prefix_arg);
1003 arg.push_back(new_prefix_arg);
Caroline Tice405fe672010-10-04 22:28:36 +00001004
Kate Stoneb9c1b512016-09-06 20:57:50 +00001005 m_arguments.push_back(arg);
1006 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001007
Kate Stoneb9c1b512016-09-06 20:57:50 +00001008 ~CommandObjectTargetModulesSearchPathsAdd() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001009
Jim Ingham5a988412012-06-08 21:56:10 +00001010protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001011 bool DoExecute(Args &command, CommandReturnObject &result) override {
1012 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1013 if (target) {
1014 const size_t argc = command.GetArgumentCount();
1015 if (argc & 1) {
1016 result.AppendError("add requires an even number of arguments\n");
1017 result.SetStatus(eReturnStatusFailed);
1018 } else {
1019 for (size_t i = 0; i < argc; i += 2) {
1020 const char *from = command.GetArgumentAtIndex(i);
1021 const char *to = command.GetArgumentAtIndex(i + 1);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001022
Kate Stoneb9c1b512016-09-06 20:57:50 +00001023 if (from[0] && to[0]) {
1024 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
1025 if (log) {
1026 log->Printf("target modules search path adding ImageSearchPath "
1027 "pair: '%s' -> '%s'",
1028 from, to);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001029 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001030 bool last_pair = ((argc - i) == 2);
1031 target->GetImageSearchPathList().Append(
1032 ConstString(from), ConstString(to),
1033 last_pair); // Notify if this is the last pair
1034 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1035 } else {
1036 if (from[0])
1037 result.AppendError("<path-prefix> can't be empty\n");
1038 else
1039 result.AppendError("<new-path-prefix> can't be empty\n");
1040 result.SetStatus(eReturnStatusFailed);
1041 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001042 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001043 }
1044 } else {
1045 result.AppendError("invalid target\n");
1046 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001047 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001048 return result.Succeeded();
1049 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001050};
1051
Greg Claytoneffe5c92011-05-03 22:09:39 +00001052#pragma mark CommandObjectTargetModulesSearchPathsClear
1053
Kate Stoneb9c1b512016-09-06 20:57:50 +00001054class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001055public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001056 CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
1057 : CommandObjectParsed(interpreter, "target modules search-paths clear",
1058 "Clear all current image search path substitution "
1059 "pairs from the current target.",
1060 "target modules search-paths clear") {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001061
Kate Stoneb9c1b512016-09-06 20:57:50 +00001062 ~CommandObjectTargetModulesSearchPathsClear() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001063
Jim Ingham5a988412012-06-08 21:56:10 +00001064protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001065 bool DoExecute(Args &command, CommandReturnObject &result) override {
1066 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1067 if (target) {
1068 bool notify = true;
1069 target->GetImageSearchPathList().Clear(notify);
1070 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1071 } else {
1072 result.AppendError("invalid target\n");
1073 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001074 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001075 return result.Succeeded();
1076 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001077};
1078
Greg Claytoneffe5c92011-05-03 22:09:39 +00001079#pragma mark CommandObjectTargetModulesSearchPathsInsert
1080
Kate Stoneb9c1b512016-09-06 20:57:50 +00001081class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001082public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001083 CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
1084 : CommandObjectParsed(interpreter, "target modules search-paths insert",
1085 "Insert a new image search path substitution pair "
1086 "into the current target at the specified index.",
1087 nullptr) {
1088 CommandArgumentEntry arg1;
1089 CommandArgumentEntry arg2;
1090 CommandArgumentData index_arg;
1091 CommandArgumentData old_prefix_arg;
1092 CommandArgumentData new_prefix_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001093
Kate Stoneb9c1b512016-09-06 20:57:50 +00001094 // Define the first and only variant of this arg.
1095 index_arg.arg_type = eArgTypeIndex;
1096 index_arg.arg_repetition = eArgRepeatPlain;
Caroline Tice405fe672010-10-04 22:28:36 +00001097
Kate Stoneb9c1b512016-09-06 20:57:50 +00001098 // Put the one and only variant into the first arg for m_arguments:
1099 arg1.push_back(index_arg);
Caroline Tice405fe672010-10-04 22:28:36 +00001100
Kate Stoneb9c1b512016-09-06 20:57:50 +00001101 // Define the first variant of this arg pair.
1102 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1103 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001104
Kate Stoneb9c1b512016-09-06 20:57:50 +00001105 // Define the first variant of this arg pair.
1106 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1107 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001108
Kate Stoneb9c1b512016-09-06 20:57:50 +00001109 // There are two required arguments that must always occur together, i.e. an
1110 // argument "pair". Because they
1111 // must always occur together, they are treated as two variants of one
1112 // argument rather than two independent
1113 // arguments. Push them both into the same argument position for
1114 // m_arguments...
Caroline Tice405fe672010-10-04 22:28:36 +00001115
Kate Stoneb9c1b512016-09-06 20:57:50 +00001116 arg2.push_back(old_prefix_arg);
1117 arg2.push_back(new_prefix_arg);
Caroline Tice405fe672010-10-04 22:28:36 +00001118
Kate Stoneb9c1b512016-09-06 20:57:50 +00001119 // Add arguments to m_arguments.
1120 m_arguments.push_back(arg1);
1121 m_arguments.push_back(arg2);
1122 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001123
Kate Stoneb9c1b512016-09-06 20:57:50 +00001124 ~CommandObjectTargetModulesSearchPathsInsert() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001125
Jim Ingham5a988412012-06-08 21:56:10 +00001126protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001127 bool DoExecute(Args &command, CommandReturnObject &result) override {
1128 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1129 if (target) {
1130 size_t argc = command.GetArgumentCount();
1131 // check for at least 3 arguments and an odd number of parameters
1132 if (argc >= 3 && argc & 1) {
1133 bool success = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001134
Kate Stoneb9c1b512016-09-06 20:57:50 +00001135 uint32_t insert_idx = StringConvert::ToUInt32(
1136 command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001137
Kate Stoneb9c1b512016-09-06 20:57:50 +00001138 if (!success) {
1139 result.AppendErrorWithFormat(
1140 "<index> parameter is not an integer: '%s'.\n",
1141 command.GetArgumentAtIndex(0));
1142 result.SetStatus(eReturnStatusFailed);
1143 return result.Succeeded();
1144 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001145
Kate Stoneb9c1b512016-09-06 20:57:50 +00001146 // shift off the index
1147 command.Shift();
1148 argc = command.GetArgumentCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001149
Kate Stoneb9c1b512016-09-06 20:57:50 +00001150 for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1151 const char *from = command.GetArgumentAtIndex(i);
1152 const char *to = command.GetArgumentAtIndex(i + 1);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001153
Kate Stoneb9c1b512016-09-06 20:57:50 +00001154 if (from[0] && to[0]) {
1155 bool last_pair = ((argc - i) == 2);
1156 target->GetImageSearchPathList().Insert(
1157 ConstString(from), ConstString(to), insert_idx, last_pair);
1158 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1159 } else {
1160 if (from[0])
1161 result.AppendError("<path-prefix> can't be empty\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001162 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001163 result.AppendError("<new-path-prefix> can't be empty\n");
1164 result.SetStatus(eReturnStatusFailed);
1165 return false;
1166 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001167 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001168 } else {
1169 result.AppendError("insert requires at least three arguments\n");
1170 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001171 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001172 }
1173
1174 } else {
1175 result.AppendError("invalid target\n");
1176 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001177 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001178 return result.Succeeded();
1179 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001180};
1181
Greg Claytoneffe5c92011-05-03 22:09:39 +00001182#pragma mark CommandObjectTargetModulesSearchPathsList
1183
Kate Stoneb9c1b512016-09-06 20:57:50 +00001184class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001185public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001186 CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
1187 : CommandObjectParsed(interpreter, "target modules search-paths list",
1188 "List all current image search path substitution "
1189 "pairs in the current target.",
1190 "target modules search-paths list") {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001191
Kate Stoneb9c1b512016-09-06 20:57:50 +00001192 ~CommandObjectTargetModulesSearchPathsList() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001193
Jim Ingham5a988412012-06-08 21:56:10 +00001194protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001195 bool DoExecute(Args &command, CommandReturnObject &result) override {
1196 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1197 if (target) {
1198 if (command.GetArgumentCount() != 0) {
1199 result.AppendError("list takes no arguments\n");
1200 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001201 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001202 }
1203
1204 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1205 result.SetStatus(eReturnStatusSuccessFinishResult);
1206 } else {
1207 result.AppendError("invalid target\n");
1208 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001209 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001210 return result.Succeeded();
1211 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001212};
1213
Greg Claytoneffe5c92011-05-03 22:09:39 +00001214#pragma mark CommandObjectTargetModulesSearchPathsQuery
1215
Kate Stoneb9c1b512016-09-06 20:57:50 +00001216class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001217public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001218 CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
1219 : CommandObjectParsed(
1220 interpreter, "target modules search-paths query",
1221 "Transform a path using the first applicable image search path.",
1222 nullptr) {
1223 CommandArgumentEntry arg;
1224 CommandArgumentData path_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001225
Kate Stoneb9c1b512016-09-06 20:57:50 +00001226 // Define the first (and only) variant of this arg.
1227 path_arg.arg_type = eArgTypeDirectoryName;
1228 path_arg.arg_repetition = eArgRepeatPlain;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001229
Kate Stoneb9c1b512016-09-06 20:57:50 +00001230 // There is only one variant this argument could be; put it into the
1231 // argument entry.
1232 arg.push_back(path_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001233
Kate Stoneb9c1b512016-09-06 20:57:50 +00001234 // Push the data for the first argument into the m_arguments vector.
1235 m_arguments.push_back(arg);
1236 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001237
Kate Stoneb9c1b512016-09-06 20:57:50 +00001238 ~CommandObjectTargetModulesSearchPathsQuery() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001239
Jim Ingham5a988412012-06-08 21:56:10 +00001240protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001241 bool DoExecute(Args &command, CommandReturnObject &result) override {
1242 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1243 if (target) {
1244 if (command.GetArgumentCount() != 1) {
1245 result.AppendError("query requires one argument\n");
1246 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001247 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001248 }
1249
1250 ConstString orig(command.GetArgumentAtIndex(0));
1251 ConstString transformed;
1252 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1253 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1254 else
1255 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1256
1257 result.SetStatus(eReturnStatusSuccessFinishResult);
1258 } else {
1259 result.AppendError("invalid target\n");
1260 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001261 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001262 return result.Succeeded();
1263 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001264};
1265
Greg Claytoneffe5c92011-05-03 22:09:39 +00001266//----------------------------------------------------------------------
1267// Static Helper functions
1268//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001269static void DumpModuleArchitecture(Stream &strm, Module *module,
1270 bool full_triple, uint32_t width) {
1271 if (module) {
1272 StreamString arch_strm;
Todd Fiala7df337f2015-10-13 23:41:19 +00001273
Kate Stoneb9c1b512016-09-06 20:57:50 +00001274 if (full_triple)
1275 module->GetArchitecture().DumpTriple(arch_strm);
Greg Clayton3418c852011-08-10 02:10:13 +00001276 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001277 arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1278 std::string arch_str = arch_strm.GetString();
1279
1280 if (width)
1281 strm.Printf("%-*s", width, arch_str.c_str());
1282 else
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00001283 strm.PutCString(arch_str);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001284 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001285}
1286
Kate Stoneb9c1b512016-09-06 20:57:50 +00001287static void DumpModuleUUID(Stream &strm, Module *module) {
1288 if (module && module->GetUUID().IsValid())
1289 module->GetUUID().Dump(&strm);
1290 else
1291 strm.PutCString(" ");
Greg Claytoneffe5c92011-05-03 22:09:39 +00001292}
1293
Kate Stoneb9c1b512016-09-06 20:57:50 +00001294static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
1295 Stream &strm, Module *module,
1296 const FileSpec &file_spec,
1297 bool load_addresses) {
1298 uint32_t num_matches = 0;
1299 if (module) {
1300 SymbolContextList sc_list;
1301 num_matches = module->ResolveSymbolContextsForFileSpec(
1302 file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1303
1304 for (uint32_t i = 0; i < num_matches; ++i) {
1305 SymbolContext sc;
1306 if (sc_list.GetContextAtIndex(i, sc)) {
1307 if (i > 0)
1308 strm << "\n\n";
1309
1310 strm << "Line table for " << *static_cast<FileSpec *>(sc.comp_unit)
1311 << " in `" << module->GetFileSpec().GetFilename() << "\n";
1312 LineTable *line_table = sc.comp_unit->GetLineTable();
1313 if (line_table)
1314 line_table->GetDescription(
1315 &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1316 lldb::eDescriptionLevelBrief);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001317 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001318 strm << "No line table";
1319 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001320 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001321 }
1322 return num_matches;
1323}
1324
1325static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1326 uint32_t width) {
1327 if (file_spec_ptr) {
1328 if (width > 0) {
1329 std::string fullpath = file_spec_ptr->GetPath();
1330 strm.Printf("%-*s", width, fullpath.c_str());
1331 return;
1332 } else {
1333 file_spec_ptr->Dump(&strm);
1334 return;
1335 }
1336 }
1337 // Keep the width spacing correct if things go wrong...
1338 if (width > 0)
1339 strm.Printf("%-*s", width, "");
1340}
1341
1342static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1343 uint32_t width) {
1344 if (file_spec_ptr) {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001345 if (width > 0)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001346 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1347 else
1348 file_spec_ptr->GetDirectory().Dump(&strm);
1349 return;
1350 }
1351 // Keep the width spacing correct if things go wrong...
1352 if (width > 0)
1353 strm.Printf("%-*s", width, "");
Greg Claytoneffe5c92011-05-03 22:09:39 +00001354}
1355
Kate Stoneb9c1b512016-09-06 20:57:50 +00001356static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1357 uint32_t width) {
1358 if (file_spec_ptr) {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001359 if (width > 0)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001360 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1361 else
1362 file_spec_ptr->GetFilename().Dump(&strm);
1363 return;
1364 }
1365 // Keep the width spacing correct if things go wrong...
1366 if (width > 0)
1367 strm.Printf("%-*s", width, "");
Greg Claytoneffe5c92011-05-03 22:09:39 +00001368}
1369
Kate Stoneb9c1b512016-09-06 20:57:50 +00001370static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1371 size_t num_dumped = 0;
1372 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1373 const size_t num_modules = module_list.GetSize();
1374 if (num_modules > 0) {
1375 strm.Printf("Dumping headers for %" PRIu64 " module(s).\n",
1376 static_cast<uint64_t>(num_modules));
Greg Claytonc4a8a762012-05-15 18:43:44 +00001377 strm.IndentMore();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001378 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1379 Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
1380 if (module) {
1381 if (num_dumped++ > 0) {
1382 strm.EOL();
1383 strm.EOL();
1384 }
1385 ObjectFile *objfile = module->GetObjectFile();
1386 objfile->Dump(&strm);
1387 }
Greg Claytonc4a8a762012-05-15 18:43:44 +00001388 }
1389 strm.IndentLess();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001390 }
1391 return num_dumped;
Greg Claytonc4a8a762012-05-15 18:43:44 +00001392}
1393
Kate Stoneb9c1b512016-09-06 20:57:50 +00001394static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1395 Module *module, SortOrder sort_order) {
1396 if (module) {
1397 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1398 if (sym_vendor) {
1399 Symtab *symtab = sym_vendor->GetSymtab();
1400 if (symtab)
1401 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1402 sort_order);
1403 }
1404 }
1405}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001406
Kate Stoneb9c1b512016-09-06 20:57:50 +00001407static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1408 Module *module) {
1409 if (module) {
1410 SectionList *section_list = module->GetSectionList();
1411 if (section_list) {
1412 strm.Printf("Sections for '%s' (%s):\n",
1413 module->GetSpecificationDescription().c_str(),
1414 module->GetArchitecture().GetArchitectureName());
1415 strm.IndentMore();
1416 section_list->Dump(&strm,
1417 interpreter.GetExecutionContext().GetTargetPtr(), true,
1418 UINT32_MAX);
1419 strm.IndentLess();
1420 }
1421 }
1422}
1423
1424static bool DumpModuleSymbolVendor(Stream &strm, Module *module) {
1425 if (module) {
1426 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1427 if (symbol_vendor) {
1428 symbol_vendor->Dump(&strm);
1429 return true;
1430 }
1431 }
1432 return false;
1433}
1434
1435static void DumpAddress(ExecutionContextScope *exe_scope,
1436 const Address &so_addr, bool verbose, Stream &strm) {
1437 strm.IndentMore();
1438 strm.Indent(" Address: ");
1439 so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1440 strm.PutCString(" (");
1441 so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1442 strm.PutCString(")\n");
1443 strm.Indent(" Summary: ");
1444 const uint32_t save_indent = strm.GetIndentLevel();
1445 strm.SetIndentLevel(save_indent + 13);
1446 so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
1447 strm.SetIndentLevel(save_indent);
1448 // Print out detailed address information when verbose is enabled
1449 if (verbose) {
1450 strm.EOL();
1451 so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1452 }
1453 strm.IndentLess();
1454}
1455
1456static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1457 Module *module, uint32_t resolve_mask,
1458 lldb::addr_t raw_addr, lldb::addr_t offset,
1459 bool verbose) {
1460 if (module) {
1461 lldb::addr_t addr = raw_addr - offset;
1462 Address so_addr;
1463 SymbolContext sc;
1464 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1465 if (target && !target->GetSectionLoadList().IsEmpty()) {
1466 if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
1467 return false;
1468 else if (so_addr.GetModule().get() != module)
1469 return false;
1470 } else {
1471 if (!module->ResolveFileAddress(addr, so_addr))
1472 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001473 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001474
Kate Stoneb9c1b512016-09-06 20:57:50 +00001475 ExecutionContextScope *exe_scope =
1476 interpreter.GetExecutionContext().GetBestExecutionContextScope();
1477 DumpAddress(exe_scope, so_addr, verbose, strm);
1478 // strm.IndentMore();
1479 // strm.Indent (" Address: ");
1480 // so_addr.Dump (&strm, exe_scope,
1481 // Address::DumpStyleModuleWithFileAddress);
1482 // strm.PutCString (" (");
1483 // so_addr.Dump (&strm, exe_scope,
1484 // Address::DumpStyleSectionNameOffset);
1485 // strm.PutCString (")\n");
1486 // strm.Indent (" Summary: ");
1487 // const uint32_t save_indent = strm.GetIndentLevel ();
1488 // strm.SetIndentLevel (save_indent + 13);
1489 // so_addr.Dump (&strm, exe_scope,
1490 // Address::DumpStyleResolvedDescription);
1491 // strm.SetIndentLevel (save_indent);
1492 // // Print out detailed address information when verbose is enabled
1493 // if (verbose)
1494 // {
1495 // strm.EOL();
1496 // so_addr.Dump (&strm, exe_scope,
1497 // Address::DumpStyleDetailedSymbolContext);
1498 // }
1499 // strm.IndentLess();
1500 return true;
1501 }
1502
1503 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001504}
1505
Kate Stoneb9c1b512016-09-06 20:57:50 +00001506static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1507 Stream &strm, Module *module,
1508 const char *name, bool name_is_regex,
1509 bool verbose) {
1510 if (module) {
1511 SymbolContext sc;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001512
Kate Stoneb9c1b512016-09-06 20:57:50 +00001513 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1514 if (sym_vendor) {
1515 Symtab *symtab = sym_vendor->GetSymtab();
1516 if (symtab) {
1517 std::vector<uint32_t> match_indexes;
1518 ConstString symbol_name(name);
1519 uint32_t num_matches = 0;
1520 if (name_is_regex) {
Zachary Turner95eae422016-09-21 16:01:28 +00001521 RegularExpression name_regexp(symbol_name.GetStringRef());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001522 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1523 name_regexp, eSymbolTypeAny, match_indexes);
1524 } else {
1525 num_matches =
1526 symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1527 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001528
Kate Stoneb9c1b512016-09-06 20:57:50 +00001529 if (num_matches > 0) {
1530 strm.Indent();
1531 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1532 name_is_regex ? "the regular expression " : "", name);
1533 DumpFullpath(strm, &module->GetFileSpec(), 0);
1534 strm.PutCString(":\n");
1535 strm.IndentMore();
1536 for (uint32_t i = 0; i < num_matches; ++i) {
1537 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1538 if (symbol && symbol->ValueIsAddress()) {
1539 DumpAddress(interpreter.GetExecutionContext()
1540 .GetBestExecutionContextScope(),
1541 symbol->GetAddressRef(), verbose, strm);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001542 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001543 }
1544 strm.IndentLess();
1545 return num_matches;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001546 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001547 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001548 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001549 }
1550 return 0;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001551}
1552
Kate Stoneb9c1b512016-09-06 20:57:50 +00001553static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
1554 Stream &strm, SymbolContextList &sc_list,
1555 bool verbose) {
1556 strm.IndentMore();
Eugene Zelenkof13e6522016-02-25 19:02:39 +00001557
Kate Stoneb9c1b512016-09-06 20:57:50 +00001558 const uint32_t num_matches = sc_list.GetSize();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001559
Kate Stoneb9c1b512016-09-06 20:57:50 +00001560 for (uint32_t i = 0; i < num_matches; ++i) {
1561 SymbolContext sc;
1562 if (sc_list.GetContextAtIndex(i, sc)) {
1563 AddressRange range;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001564
Kate Stoneb9c1b512016-09-06 20:57:50 +00001565 sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001566
Kate Stoneb9c1b512016-09-06 20:57:50 +00001567 DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001568 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001569 }
1570 strm.IndentLess();
Greg Claytoneffe5c92011-05-03 22:09:39 +00001571}
1572
Kate Stoneb9c1b512016-09-06 20:57:50 +00001573static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
1574 Stream &strm, Module *module,
1575 const char *name, bool name_is_regex,
1576 bool include_inlines, bool include_symbols,
1577 bool verbose) {
1578 if (module && name && name[0]) {
1579 SymbolContextList sc_list;
1580 const bool append = true;
1581 size_t num_matches = 0;
1582 if (name_is_regex) {
Zachary Turner95eae422016-09-21 16:01:28 +00001583 RegularExpression function_name_regex((llvm::StringRef(name)));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001584 num_matches = module->FindFunctions(function_name_regex, include_symbols,
1585 include_inlines, append, sc_list);
1586 } else {
1587 ConstString function_name(name);
1588 num_matches = module->FindFunctions(
1589 function_name, nullptr, eFunctionNameTypeAuto, include_symbols,
1590 include_inlines, append, sc_list);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001591 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001592
Kate Stoneb9c1b512016-09-06 20:57:50 +00001593 if (num_matches) {
1594 strm.Indent();
1595 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1596 num_matches > 1 ? "es" : "");
1597 DumpFullpath(strm, &module->GetFileSpec(), 0);
1598 strm.PutCString(":\n");
1599 DumpSymbolContextList(
1600 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1601 strm, sc_list, verbose);
Sean Callanand38b4a92012-06-06 20:49:55 +00001602 }
1603 return num_matches;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001604 }
1605 return 0;
Sean Callanand38b4a92012-06-06 20:49:55 +00001606}
1607
Kate Stoneb9c1b512016-09-06 20:57:50 +00001608static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
1609 Module *module, const char *name_cstr,
1610 bool name_is_regex) {
1611 if (module && name_cstr && name_cstr[0]) {
1612 TypeList type_list;
1613 const uint32_t max_num_matches = UINT32_MAX;
1614 size_t num_matches = 0;
1615 bool name_is_fully_qualified = false;
1616 SymbolContext sc;
1617
1618 ConstString name(name_cstr);
1619 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1620 num_matches =
1621 module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches,
1622 searched_symbol_files, type_list);
1623
1624 if (num_matches) {
1625 strm.Indent();
1626 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1627 num_matches > 1 ? "es" : "");
1628 DumpFullpath(strm, &module->GetFileSpec(), 0);
1629 strm.PutCString(":\n");
1630 for (TypeSP type_sp : type_list.Types()) {
1631 if (type_sp) {
1632 // Resolve the clang type so that any forward references
1633 // to types that haven't yet been parsed will get parsed.
1634 type_sp->GetFullCompilerType();
1635 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1636 // Print all typedef chains
1637 TypeSP typedef_type_sp(type_sp);
1638 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1639 while (typedefed_type_sp) {
1640 strm.EOL();
1641 strm.Printf(" typedef '%s': ",
1642 typedef_type_sp->GetName().GetCString());
1643 typedefed_type_sp->GetFullCompilerType();
1644 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull,
1645 true);
1646 typedef_type_sp = typedefed_type_sp;
1647 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1648 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001649 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001650 strm.EOL();
1651 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001652 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001653 return num_matches;
1654 }
1655 return 0;
1656}
1657
1658static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
1659 const SymbolContext &sym_ctx,
1660 const char *name_cstr, bool name_is_regex) {
1661 if (!sym_ctx.module_sp)
Greg Claytoneffe5c92011-05-03 22:09:39 +00001662 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001663
1664 TypeList type_list;
1665 const uint32_t max_num_matches = UINT32_MAX;
1666 size_t num_matches = 1;
1667 bool name_is_fully_qualified = false;
1668
1669 ConstString name(name_cstr);
1670 llvm::DenseSet<SymbolFile *> searched_symbol_files;
1671 num_matches = sym_ctx.module_sp->FindTypes(
1672 sym_ctx, name, name_is_fully_qualified, max_num_matches,
1673 searched_symbol_files, type_list);
1674
1675 if (num_matches) {
1676 strm.Indent();
1677 strm.PutCString("Best match found in ");
1678 DumpFullpath(strm, &sym_ctx.module_sp->GetFileSpec(), 0);
1679 strm.PutCString(":\n");
1680
1681 TypeSP type_sp(type_list.GetTypeAtIndex(0));
1682 if (type_sp) {
1683 // Resolve the clang type so that any forward references
1684 // to types that haven't yet been parsed will get parsed.
1685 type_sp->GetFullCompilerType();
1686 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1687 // Print all typedef chains
1688 TypeSP typedef_type_sp(type_sp);
1689 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1690 while (typedefed_type_sp) {
1691 strm.EOL();
1692 strm.Printf(" typedef '%s': ",
1693 typedef_type_sp->GetName().GetCString());
1694 typedefed_type_sp->GetFullCompilerType();
1695 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1696 typedef_type_sp = typedefed_type_sp;
1697 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1698 }
1699 }
1700 strm.EOL();
1701 }
1702 return num_matches;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001703}
1704
Kate Stoneb9c1b512016-09-06 20:57:50 +00001705static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
1706 Stream &strm, Module *module,
1707 const FileSpec &file_spec,
1708 uint32_t line, bool check_inlines,
1709 bool verbose) {
1710 if (module && file_spec) {
1711 SymbolContextList sc_list;
1712 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1713 file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1714 if (num_matches > 0) {
1715 strm.Indent();
1716 strm.Printf("%u match%s found in ", num_matches,
1717 num_matches > 1 ? "es" : "");
1718 strm << file_spec;
1719 if (line > 0)
1720 strm.Printf(":%u", line);
1721 strm << " in ";
1722 DumpFullpath(strm, &module->GetFileSpec(), 0);
1723 strm.PutCString(":\n");
1724 DumpSymbolContextList(
1725 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1726 strm, sc_list, verbose);
1727 return num_matches;
Greg Clayton8ee64382011-11-10 01:18:58 +00001728 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001729 }
1730 return 0;
1731}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001732
Kate Stoneb9c1b512016-09-06 20:57:50 +00001733static size_t FindModulesByName(Target *target, const char *module_name,
1734 ModuleList &module_list,
1735 bool check_global_list) {
1736 FileSpec module_file_spec(module_name, false);
1737 ModuleSpec module_spec(module_file_spec);
1738
1739 const size_t initial_size = module_list.GetSize();
1740
1741 if (check_global_list) {
1742 // Check the global list
1743 std::lock_guard<std::recursive_mutex> guard(
1744 Module::GetAllocationModuleCollectionMutex());
1745 const size_t num_modules = Module::GetNumberAllocatedModules();
1746 ModuleSP module_sp;
1747 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1748 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1749
1750 if (module) {
1751 if (module->MatchesModuleSpec(module_spec)) {
1752 module_sp = module->shared_from_this();
1753 module_list.AppendIfNeeded(module_sp);
Greg Claytonf3156262012-07-11 20:46:47 +00001754 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001755 }
Greg Claytonf3156262012-07-11 20:46:47 +00001756 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001757 } else {
1758 if (target) {
1759 const size_t num_matches =
1760 target->GetImages().FindModules(module_spec, module_list);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001761
Kate Stoneb9c1b512016-09-06 20:57:50 +00001762 // Not found in our module list for our target, check the main
1763 // shared module list in case it is a extra file used somewhere
1764 // else
1765 if (num_matches == 0) {
1766 module_spec.GetArchitecture() = target->GetArchitecture();
1767 ModuleList::FindSharedModules(module_spec, module_list);
1768 }
1769 } else {
1770 ModuleList::FindSharedModules(module_spec, module_list);
1771 }
1772 }
1773
1774 return module_list.GetSize() - initial_size;
Greg Clayton8ee64382011-11-10 01:18:58 +00001775}
1776
Greg Claytoneffe5c92011-05-03 22:09:39 +00001777#pragma mark CommandObjectTargetModulesModuleAutoComplete
1778
1779//----------------------------------------------------------------------
1780// A base command object class that can auto complete with module file
1781// paths
1782//----------------------------------------------------------------------
1783
Kate Stoneb9c1b512016-09-06 20:57:50 +00001784class CommandObjectTargetModulesModuleAutoComplete
1785 : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001786public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001787 CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1788 const char *name,
1789 const char *help,
1790 const char *syntax)
1791 : CommandObjectParsed(interpreter, name, help, syntax) {
1792 CommandArgumentEntry arg;
1793 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001794
Kate Stoneb9c1b512016-09-06 20:57:50 +00001795 // Define the first (and only) variant of this arg.
1796 file_arg.arg_type = eArgTypeFilename;
1797 file_arg.arg_repetition = eArgRepeatStar;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001798
Kate Stoneb9c1b512016-09-06 20:57:50 +00001799 // There is only one variant this argument could be; put it into the
1800 // argument entry.
1801 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001802
Kate Stoneb9c1b512016-09-06 20:57:50 +00001803 // Push the data for the first argument into the m_arguments vector.
1804 m_arguments.push_back(arg);
1805 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001806
Kate Stoneb9c1b512016-09-06 20:57:50 +00001807 ~CommandObjectTargetModulesModuleAutoComplete() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001808
Kate Stoneb9c1b512016-09-06 20:57:50 +00001809 int HandleArgumentCompletion(Args &input, int &cursor_index,
1810 int &cursor_char_position,
1811 OptionElementVector &opt_element_vector,
1812 int match_start_point, int max_return_elements,
1813 bool &word_complete,
1814 StringList &matches) override {
1815 // Arguments are the standard module completer.
1816 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
1817 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001818
Kate Stoneb9c1b512016-09-06 20:57:50 +00001819 CommandCompletions::InvokeCommonCompletionCallbacks(
1820 GetCommandInterpreter(), CommandCompletions::eModuleCompletion,
1821 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
1822 word_complete, matches);
1823 return matches.GetSize();
1824 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001825};
1826
1827#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1828
1829//----------------------------------------------------------------------
1830// A base command object class that can auto complete with module source
1831// file paths
1832//----------------------------------------------------------------------
1833
Kate Stoneb9c1b512016-09-06 20:57:50 +00001834class CommandObjectTargetModulesSourceFileAutoComplete
1835 : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001836public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001837 CommandObjectTargetModulesSourceFileAutoComplete(
1838 CommandInterpreter &interpreter, const char *name, const char *help,
1839 const char *syntax, uint32_t flags)
1840 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1841 CommandArgumentEntry arg;
1842 CommandArgumentData source_file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001843
Kate Stoneb9c1b512016-09-06 20:57:50 +00001844 // Define the first (and only) variant of this arg.
1845 source_file_arg.arg_type = eArgTypeSourceFile;
1846 source_file_arg.arg_repetition = eArgRepeatPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001847
Kate Stoneb9c1b512016-09-06 20:57:50 +00001848 // There is only one variant this argument could be; put it into the
1849 // argument entry.
1850 arg.push_back(source_file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001851
Kate Stoneb9c1b512016-09-06 20:57:50 +00001852 // Push the data for the first argument into the m_arguments vector.
1853 m_arguments.push_back(arg);
1854 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001855
Kate Stoneb9c1b512016-09-06 20:57:50 +00001856 ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001857
Kate Stoneb9c1b512016-09-06 20:57:50 +00001858 int HandleArgumentCompletion(Args &input, int &cursor_index,
1859 int &cursor_char_position,
1860 OptionElementVector &opt_element_vector,
1861 int match_start_point, int max_return_elements,
1862 bool &word_complete,
1863 StringList &matches) override {
1864 // Arguments are the standard source file completer.
1865 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
1866 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001867
Kate Stoneb9c1b512016-09-06 20:57:50 +00001868 CommandCompletions::InvokeCommonCompletionCallbacks(
1869 GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
1870 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
1871 word_complete, matches);
1872 return matches.GetSize();
1873 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001874};
1875
Adrian McCarthy543725c2016-04-04 21:21:49 +00001876#pragma mark CommandObjectTargetModulesDumpObjfile
1877
Kate Stoneb9c1b512016-09-06 20:57:50 +00001878class CommandObjectTargetModulesDumpObjfile
1879 : public CommandObjectTargetModulesModuleAutoComplete {
Adrian McCarthy543725c2016-04-04 21:21:49 +00001880public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001881 CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
1882 : CommandObjectTargetModulesModuleAutoComplete(
1883 interpreter, "target modules dump objfile",
1884 "Dump the object file headers from one or more target modules.",
1885 nullptr) {}
Adrian McCarthy543725c2016-04-04 21:21:49 +00001886
Kate Stoneb9c1b512016-09-06 20:57:50 +00001887 ~CommandObjectTargetModulesDumpObjfile() override = default;
Adrian McCarthy543725c2016-04-04 21:21:49 +00001888
1889protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001890 bool DoExecute(Args &command, CommandReturnObject &result) override {
1891 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1892 if (target == nullptr) {
1893 result.AppendError("invalid target, create a debug target using the "
1894 "'target create' command");
1895 result.SetStatus(eReturnStatusFailed);
1896 return false;
Adrian McCarthy543725c2016-04-04 21:21:49 +00001897 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001898
1899 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1900 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1901 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1902
1903 size_t num_dumped = 0;
1904 if (command.GetArgumentCount() == 0) {
1905 // Dump all headers for all modules images
1906 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1907 target->GetImages());
1908 if (num_dumped == 0) {
1909 result.AppendError("the target has no associated executable images");
1910 result.SetStatus(eReturnStatusFailed);
1911 }
1912 } else {
1913 // Find the modules that match the basename or full path.
1914 ModuleList module_list;
1915 const char *arg_cstr;
1916 for (int arg_idx = 0;
1917 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1918 ++arg_idx) {
1919 size_t num_matched =
1920 FindModulesByName(target, arg_cstr, module_list, true);
1921 if (num_matched == 0) {
1922 result.AppendWarningWithFormat(
1923 "Unable to find an image that matches '%s'.\n", arg_cstr);
1924 }
1925 }
1926 // Dump all the modules we found.
1927 num_dumped =
1928 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1929 }
1930
1931 if (num_dumped > 0) {
1932 result.SetStatus(eReturnStatusSuccessFinishResult);
1933 } else {
1934 result.AppendError("no matching executable images found");
1935 result.SetStatus(eReturnStatusFailed);
1936 }
1937 return result.Succeeded();
1938 }
Adrian McCarthy543725c2016-04-04 21:21:49 +00001939};
1940
Greg Claytoneffe5c92011-05-03 22:09:39 +00001941#pragma mark CommandObjectTargetModulesDumpSymtab
1942
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001943static OptionEnumValueElement g_sort_option_enumeration[4] = {
1944 {eSortOrderNone, "none",
1945 "No sorting, use the original symbol table order."},
1946 {eSortOrderByAddress, "address", "Sort output by symbol address."},
1947 {eSortOrderByName, "name", "Sort output by symbol name."},
1948 {0, nullptr, nullptr}};
1949
1950static OptionDefinition g_target_modules_dump_symtab_options[] = {
1951 // clang-format off
1952 { 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." }
1953 // clang-format on
1954};
1955
Kate Stoneb9c1b512016-09-06 20:57:50 +00001956class CommandObjectTargetModulesDumpSymtab
1957 : public CommandObjectTargetModulesModuleAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001958public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001959 CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
1960 : CommandObjectTargetModulesModuleAutoComplete(
1961 interpreter, "target modules dump symtab",
1962 "Dump the symbol table from one or more target modules.", nullptr),
1963 m_options() {}
1964
1965 ~CommandObjectTargetModulesDumpSymtab() override = default;
1966
1967 Options *GetOptions() override { return &m_options; }
1968
1969 class CommandOptions : public Options {
1970 public:
1971 CommandOptions() : Options(), m_sort_order(eSortOrderNone) {}
1972
1973 ~CommandOptions() override = default;
1974
1975 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
1976 ExecutionContext *execution_context) override {
1977 Error error;
1978 const int short_option = m_getopt_table[option_idx].val;
1979
1980 switch (short_option) {
1981 case 's':
1982 m_sort_order = (SortOrder)Args::StringToOptionEnum(
Zachary Turner8cef4b02016-09-23 17:48:13 +00001983 llvm::StringRef::withNullAsEmpty(option_arg),
1984 GetDefinitions()[option_idx].enum_values, eSortOrderNone, error);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001985 break;
1986
1987 default:
1988 error.SetErrorStringWithFormat("invalid short option character '%c'",
1989 short_option);
1990 break;
1991 }
1992 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001993 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001994
Kate Stoneb9c1b512016-09-06 20:57:50 +00001995 void OptionParsingStarting(ExecutionContext *execution_context) override {
1996 m_sort_order = eSortOrderNone;
Jim Ingham5a988412012-06-08 21:56:10 +00001997 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001998
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001999 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00002000 return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002001 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002002
Kate Stoneb9c1b512016-09-06 20:57:50 +00002003 SortOrder m_sort_order;
2004 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002005
Jim Ingham5a988412012-06-08 21:56:10 +00002006protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002007 bool DoExecute(Args &command, CommandReturnObject &result) override {
2008 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2009 if (target == nullptr) {
2010 result.AppendError("invalid target, create a debug target using the "
2011 "'target create' command");
2012 result.SetStatus(eReturnStatusFailed);
2013 return false;
2014 } else {
2015 uint32_t num_dumped = 0;
2016
2017 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2018 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2019 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2020
2021 if (command.GetArgumentCount() == 0) {
2022 // Dump all sections for all modules images
2023 std::lock_guard<std::recursive_mutex> guard(
2024 target->GetImages().GetMutex());
2025 const size_t num_modules = target->GetImages().GetSize();
2026 if (num_modules > 0) {
2027 result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
2028 " modules.\n",
2029 (uint64_t)num_modules);
2030 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2031 if (num_dumped > 0) {
2032 result.GetOutputStream().EOL();
2033 result.GetOutputStream().EOL();
2034 }
2035 num_dumped++;
2036 DumpModuleSymtab(
2037 m_interpreter, result.GetOutputStream(),
2038 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2039 m_options.m_sort_order);
2040 }
2041 } else {
2042 result.AppendError("the target has no associated executable images");
2043 result.SetStatus(eReturnStatusFailed);
2044 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002045 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002046 } else {
2047 // Dump specified images (by basename or fullpath)
2048 const char *arg_cstr;
2049 for (int arg_idx = 0;
2050 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2051 ++arg_idx) {
2052 ModuleList module_list;
2053 const size_t num_matches =
2054 FindModulesByName(target, arg_cstr, module_list, true);
2055 if (num_matches > 0) {
2056 for (size_t i = 0; i < num_matches; ++i) {
2057 Module *module = module_list.GetModulePointerAtIndex(i);
2058 if (module) {
2059 if (num_dumped > 0) {
2060 result.GetOutputStream().EOL();
2061 result.GetOutputStream().EOL();
Greg Claytoneffe5c92011-05-03 22:09:39 +00002062 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002063 num_dumped++;
2064 DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2065 module, m_options.m_sort_order);
2066 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002067 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002068 } else
2069 result.AppendWarningWithFormat(
2070 "Unable to find an image that matches '%s'.\n", arg_cstr);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002071 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002072 }
2073
2074 if (num_dumped > 0)
2075 result.SetStatus(eReturnStatusSuccessFinishResult);
2076 else {
2077 result.AppendError("no matching executable images found");
2078 result.SetStatus(eReturnStatusFailed);
2079 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002080 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002081 return result.Succeeded();
2082 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002083
Kate Stoneb9c1b512016-09-06 20:57:50 +00002084 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002085};
2086
Greg Claytoneffe5c92011-05-03 22:09:39 +00002087#pragma mark CommandObjectTargetModulesDumpSections
2088
2089//----------------------------------------------------------------------
2090// Image section dumping command
2091//----------------------------------------------------------------------
2092
Kate Stoneb9c1b512016-09-06 20:57:50 +00002093class CommandObjectTargetModulesDumpSections
2094 : public CommandObjectTargetModulesModuleAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002095public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002096 CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
2097 : CommandObjectTargetModulesModuleAutoComplete(
2098 interpreter, "target modules dump sections",
2099 "Dump the sections from one or more target modules.",
2100 //"target modules dump sections [<file1> ...]")
2101 nullptr) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002102
Kate Stoneb9c1b512016-09-06 20:57:50 +00002103 ~CommandObjectTargetModulesDumpSections() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002104
Jim Ingham5a988412012-06-08 21:56:10 +00002105protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002106 bool DoExecute(Args &command, CommandReturnObject &result) override {
2107 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2108 if (target == nullptr) {
2109 result.AppendError("invalid target, create a debug target using the "
2110 "'target create' command");
2111 result.SetStatus(eReturnStatusFailed);
2112 return false;
2113 } else {
2114 uint32_t num_dumped = 0;
2115
2116 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2117 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2118 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2119
2120 if (command.GetArgumentCount() == 0) {
2121 // Dump all sections for all modules images
2122 const size_t num_modules = target->GetImages().GetSize();
2123 if (num_modules > 0) {
2124 result.GetOutputStream().Printf("Dumping sections for %" PRIu64
2125 " modules.\n",
2126 (uint64_t)num_modules);
2127 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2128 num_dumped++;
2129 DumpModuleSections(
2130 m_interpreter, result.GetOutputStream(),
2131 target->GetImages().GetModulePointerAtIndex(image_idx));
2132 }
2133 } else {
2134 result.AppendError("the target has no associated executable images");
2135 result.SetStatus(eReturnStatusFailed);
2136 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002137 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002138 } else {
2139 // Dump specified images (by basename or fullpath)
2140 const char *arg_cstr;
2141 for (int arg_idx = 0;
2142 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2143 ++arg_idx) {
2144 ModuleList module_list;
2145 const size_t num_matches =
2146 FindModulesByName(target, arg_cstr, module_list, true);
2147 if (num_matches > 0) {
2148 for (size_t i = 0; i < num_matches; ++i) {
2149 Module *module = module_list.GetModulePointerAtIndex(i);
2150 if (module) {
2151 num_dumped++;
2152 DumpModuleSections(m_interpreter, result.GetOutputStream(),
2153 module);
2154 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002155 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002156 } else {
2157 // Check the global list
2158 std::lock_guard<std::recursive_mutex> guard(
2159 Module::GetAllocationModuleCollectionMutex());
Greg Clayton8ee64382011-11-10 01:18:58 +00002160
Kate Stoneb9c1b512016-09-06 20:57:50 +00002161 result.AppendWarningWithFormat(
2162 "Unable to find an image that matches '%s'.\n", arg_cstr);
2163 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002164 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002165 }
2166
2167 if (num_dumped > 0)
2168 result.SetStatus(eReturnStatusSuccessFinishResult);
2169 else {
2170 result.AppendError("no matching executable images found");
2171 result.SetStatus(eReturnStatusFailed);
2172 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002173 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002174 return result.Succeeded();
2175 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002176};
2177
Greg Claytoneffe5c92011-05-03 22:09:39 +00002178#pragma mark CommandObjectTargetModulesDumpSymfile
2179
2180//----------------------------------------------------------------------
2181// Image debug symbol dumping command
2182//----------------------------------------------------------------------
2183
Kate Stoneb9c1b512016-09-06 20:57:50 +00002184class CommandObjectTargetModulesDumpSymfile
2185 : public CommandObjectTargetModulesModuleAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002186public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002187 CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
2188 : CommandObjectTargetModulesModuleAutoComplete(
2189 interpreter, "target modules dump symfile",
2190 "Dump the debug symbol file for one or more target modules.",
2191 //"target modules dump symfile [<file1> ...]")
2192 nullptr) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002193
Kate Stoneb9c1b512016-09-06 20:57:50 +00002194 ~CommandObjectTargetModulesDumpSymfile() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002195
Jim Ingham5a988412012-06-08 21:56:10 +00002196protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002197 bool DoExecute(Args &command, CommandReturnObject &result) override {
2198 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2199 if (target == nullptr) {
2200 result.AppendError("invalid target, create a debug target using the "
2201 "'target create' command");
2202 result.SetStatus(eReturnStatusFailed);
2203 return false;
2204 } else {
2205 uint32_t num_dumped = 0;
2206
2207 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2208 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2209 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2210
2211 if (command.GetArgumentCount() == 0) {
2212 // Dump all sections for all modules images
2213 const ModuleList &target_modules = target->GetImages();
2214 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2215 const size_t num_modules = target_modules.GetSize();
2216 if (num_modules > 0) {
2217 result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
2218 " modules.\n",
2219 (uint64_t)num_modules);
2220 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2221 if (DumpModuleSymbolVendor(
2222 result.GetOutputStream(),
2223 target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2224 num_dumped++;
2225 }
2226 } else {
2227 result.AppendError("the target has no associated executable images");
2228 result.SetStatus(eReturnStatusFailed);
2229 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002230 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002231 } else {
2232 // Dump specified images (by basename or fullpath)
2233 const char *arg_cstr;
2234 for (int arg_idx = 0;
2235 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2236 ++arg_idx) {
2237 ModuleList module_list;
2238 const size_t num_matches =
2239 FindModulesByName(target, arg_cstr, module_list, true);
2240 if (num_matches > 0) {
2241 for (size_t i = 0; i < num_matches; ++i) {
2242 Module *module = module_list.GetModulePointerAtIndex(i);
2243 if (module) {
2244 if (DumpModuleSymbolVendor(result.GetOutputStream(), module))
2245 num_dumped++;
2246 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002247 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002248 } else
2249 result.AppendWarningWithFormat(
2250 "Unable to find an image that matches '%s'.\n", arg_cstr);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002251 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002252 }
2253
2254 if (num_dumped > 0)
2255 result.SetStatus(eReturnStatusSuccessFinishResult);
2256 else {
2257 result.AppendError("no matching executable images found");
2258 result.SetStatus(eReturnStatusFailed);
2259 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002260 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002261 return result.Succeeded();
2262 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002263};
2264
Greg Claytoneffe5c92011-05-03 22:09:39 +00002265#pragma mark CommandObjectTargetModulesDumpLineTable
2266
2267//----------------------------------------------------------------------
2268// Image debug line table dumping command
2269//----------------------------------------------------------------------
2270
Kate Stoneb9c1b512016-09-06 20:57:50 +00002271class CommandObjectTargetModulesDumpLineTable
2272 : public CommandObjectTargetModulesSourceFileAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002273public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002274 CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
2275 : CommandObjectTargetModulesSourceFileAutoComplete(
2276 interpreter, "target modules dump line-table",
2277 "Dump the line table for one or more compilation units.", nullptr,
2278 eCommandRequiresTarget) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002279
Kate Stoneb9c1b512016-09-06 20:57:50 +00002280 ~CommandObjectTargetModulesDumpLineTable() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002281
Jim Ingham5a988412012-06-08 21:56:10 +00002282protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002283 bool DoExecute(Args &command, CommandReturnObject &result) override {
2284 Target *target = m_exe_ctx.GetTargetPtr();
2285 uint32_t total_num_dumped = 0;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002286
Kate Stoneb9c1b512016-09-06 20:57:50 +00002287 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2288 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2289 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002290
Kate Stoneb9c1b512016-09-06 20:57:50 +00002291 if (command.GetArgumentCount() == 0) {
2292 result.AppendError("file option must be specified.");
2293 result.SetStatus(eReturnStatusFailed);
2294 return result.Succeeded();
2295 } else {
2296 // Dump specified images (by basename or fullpath)
2297 const char *arg_cstr;
2298 for (int arg_idx = 0;
2299 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2300 ++arg_idx) {
2301 FileSpec file_spec(arg_cstr, false);
2302
2303 const ModuleList &target_modules = target->GetImages();
2304 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2305 const size_t num_modules = target_modules.GetSize();
2306 if (num_modules > 0) {
2307 uint32_t num_dumped = 0;
2308 for (uint32_t i = 0; i < num_modules; ++i) {
2309 if (DumpCompileUnitLineTable(
2310 m_interpreter, result.GetOutputStream(),
2311 target_modules.GetModulePointerAtIndexUnlocked(i),
2312 file_spec, m_exe_ctx.GetProcessPtr() &&
2313 m_exe_ctx.GetProcessRef().IsAlive()))
2314 num_dumped++;
2315 }
2316 if (num_dumped == 0)
2317 result.AppendWarningWithFormat(
2318 "No source filenames matched '%s'.\n", arg_cstr);
2319 else
2320 total_num_dumped += num_dumped;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002321 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002322 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002323 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002324
2325 if (total_num_dumped > 0)
2326 result.SetStatus(eReturnStatusSuccessFinishResult);
2327 else {
2328 result.AppendError("no source filenames matched any command arguments");
2329 result.SetStatus(eReturnStatusFailed);
2330 }
2331 return result.Succeeded();
2332 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002333};
2334
Greg Claytoneffe5c92011-05-03 22:09:39 +00002335#pragma mark CommandObjectTargetModulesDump
2336
2337//----------------------------------------------------------------------
2338// Dump multi-word command for target modules
2339//----------------------------------------------------------------------
2340
Kate Stoneb9c1b512016-09-06 20:57:50 +00002341class CommandObjectTargetModulesDump : public CommandObjectMultiword {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002342public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002343 //------------------------------------------------------------------
2344 // Constructors and Destructors
2345 //------------------------------------------------------------------
2346 CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2347 : CommandObjectMultiword(interpreter, "target modules dump",
2348 "Commands for dumping information about one or "
2349 "more target modules.",
2350 "target modules dump "
2351 "[headers|symtab|sections|symfile|line-table] "
2352 "[<file1> <file2> ...]") {
2353 LoadSubCommand("objfile",
2354 CommandObjectSP(
2355 new CommandObjectTargetModulesDumpObjfile(interpreter)));
2356 LoadSubCommand(
2357 "symtab",
2358 CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
2359 LoadSubCommand("sections",
2360 CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2361 interpreter)));
2362 LoadSubCommand("symfile",
2363 CommandObjectSP(
2364 new CommandObjectTargetModulesDumpSymfile(interpreter)));
2365 LoadSubCommand("line-table",
2366 CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2367 interpreter)));
2368 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002369
Kate Stoneb9c1b512016-09-06 20:57:50 +00002370 ~CommandObjectTargetModulesDump() override = default;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002371};
2372
Kate Stoneb9c1b512016-09-06 20:57:50 +00002373class CommandObjectTargetModulesAdd : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002374public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002375 CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
2376 : CommandObjectParsed(interpreter, "target modules add",
2377 "Add a new module to the current target's modules.",
2378 "target modules add [<module>]"),
Todd Fialae1cfbc72016-08-11 23:51:28 +00002379 m_option_group(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00002380 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2381 eArgTypeFilename, "Fullpath to a stand alone debug "
2382 "symbols file for when debug symbols "
2383 "are not in the executable.") {
2384 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2385 LLDB_OPT_SET_1);
2386 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2387 m_option_group.Finalize();
2388 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002389
Kate Stoneb9c1b512016-09-06 20:57:50 +00002390 ~CommandObjectTargetModulesAdd() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002391
Kate Stoneb9c1b512016-09-06 20:57:50 +00002392 Options *GetOptions() override { return &m_option_group; }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002393
Kate Stoneb9c1b512016-09-06 20:57:50 +00002394 int HandleArgumentCompletion(Args &input, int &cursor_index,
2395 int &cursor_char_position,
2396 OptionElementVector &opt_element_vector,
2397 int match_start_point, int max_return_elements,
2398 bool &word_complete,
2399 StringList &matches) override {
2400 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
2401 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002402
Kate Stoneb9c1b512016-09-06 20:57:50 +00002403 CommandCompletions::InvokeCommonCompletionCallbacks(
2404 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2405 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
2406 word_complete, matches);
2407 return matches.GetSize();
2408 }
Jim Ingham5a988412012-06-08 21:56:10 +00002409
2410protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002411 OptionGroupOptions m_option_group;
2412 OptionGroupUUID m_uuid_option_group;
2413 OptionGroupFile m_symbol_file;
Greg Clayton50a24bd2012-11-29 22:16:27 +00002414
Kate Stoneb9c1b512016-09-06 20:57:50 +00002415 bool DoExecute(Args &args, CommandReturnObject &result) override {
2416 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2417 if (target == nullptr) {
2418 result.AppendError("invalid target, create a debug target using the "
2419 "'target create' command");
2420 result.SetStatus(eReturnStatusFailed);
2421 return false;
2422 } else {
2423 bool flush = false;
2424
2425 const size_t argc = args.GetArgumentCount();
2426 if (argc == 0) {
2427 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2428 // We are given a UUID only, go locate the file
2429 ModuleSpec module_spec;
2430 module_spec.GetUUID() =
2431 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2432 if (m_symbol_file.GetOptionValue().OptionWasSet())
2433 module_spec.GetSymbolFileSpec() =
2434 m_symbol_file.GetOptionValue().GetCurrentValue();
2435 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
2436 ModuleSP module_sp(target->GetSharedModule(module_spec));
2437 if (module_sp) {
2438 result.SetStatus(eReturnStatusSuccessFinishResult);
2439 return true;
2440 } else {
2441 StreamString strm;
2442 module_spec.GetUUID().Dump(&strm);
2443 if (module_spec.GetFileSpec()) {
2444 if (module_spec.GetSymbolFileSpec()) {
2445 result.AppendErrorWithFormat(
2446 "Unable to create the executable or symbol file with "
2447 "UUID %s with path %s and symbol file %s",
2448 strm.GetString().c_str(),
2449 module_spec.GetFileSpec().GetPath().c_str(),
2450 module_spec.GetSymbolFileSpec().GetPath().c_str());
2451 } else {
2452 result.AppendErrorWithFormat(
2453 "Unable to create the executable or symbol file with "
2454 "UUID %s with path %s",
2455 strm.GetString().c_str(),
2456 module_spec.GetFileSpec().GetPath().c_str());
2457 }
2458 } else {
2459 result.AppendErrorWithFormat("Unable to create the executable "
2460 "or symbol file with UUID %s",
2461 strm.GetString().c_str());
2462 }
2463 result.SetStatus(eReturnStatusFailed);
2464 return false;
2465 }
2466 } else {
2467 StreamString strm;
2468 module_spec.GetUUID().Dump(&strm);
2469 result.AppendErrorWithFormat(
2470 "Unable to locate the executable or symbol file with UUID %s",
2471 strm.GetString().c_str());
2472 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002473 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002474 }
2475 } else {
2476 result.AppendError(
2477 "one or more executable image paths must be specified");
2478 result.SetStatus(eReturnStatusFailed);
2479 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002480 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002481 } else {
Zachary Turner97d2c402016-10-05 23:40:23 +00002482 for (auto &entry : args.entries()) {
2483 if (entry.ref.empty())
2484 continue;
2485
2486 FileSpec file_spec(entry.ref, true);
2487 if (file_spec.Exists()) {
2488 ModuleSpec module_spec(file_spec);
2489 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2490 module_spec.GetUUID() =
2491 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2492 if (m_symbol_file.GetOptionValue().OptionWasSet())
2493 module_spec.GetSymbolFileSpec() =
2494 m_symbol_file.GetOptionValue().GetCurrentValue();
2495 if (!module_spec.GetArchitecture().IsValid())
2496 module_spec.GetArchitecture() = target->GetArchitecture();
2497 Error error;
2498 ModuleSP module_sp(target->GetSharedModule(module_spec, &error));
2499 if (!module_sp) {
2500 const char *error_cstr = error.AsCString();
2501 if (error_cstr)
2502 result.AppendError(error_cstr);
2503 else
2504 result.AppendErrorWithFormat("unsupported module: %s",
2505 entry.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002506 result.SetStatus(eReturnStatusFailed);
Zachary Turner97d2c402016-10-05 23:40:23 +00002507 return false;
2508 } else {
2509 flush = true;
2510 }
2511 result.SetStatus(eReturnStatusSuccessFinishResult);
2512 } else {
2513 std::string resolved_path = file_spec.GetPath();
2514 result.SetStatus(eReturnStatusFailed);
2515 if (resolved_path != entry.ref) {
2516 result.AppendErrorWithFormat(
2517 "invalid module path '%s' with resolved path '%s'\n",
2518 entry.ref.str().c_str(), resolved_path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002519 break;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002520 }
Zachary Turner97d2c402016-10-05 23:40:23 +00002521 result.AppendErrorWithFormat("invalid module path '%s'\n",
2522 entry.c_str());
2523 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002524 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002525 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002526 }
2527
2528 if (flush) {
2529 ProcessSP process = target->GetProcessSP();
2530 if (process)
2531 process->Flush();
2532 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002533 }
2534
Kate Stoneb9c1b512016-09-06 20:57:50 +00002535 return result.Succeeded();
2536 }
2537};
2538
2539class CommandObjectTargetModulesLoad
2540 : public CommandObjectTargetModulesModuleAutoComplete {
2541public:
2542 CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
2543 : CommandObjectTargetModulesModuleAutoComplete(
2544 interpreter, "target modules load", "Set the load addresses for "
2545 "one or more sections in a "
2546 "target module.",
2547 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2548 "<address> [<sect-name> <address> ....]"),
2549 m_option_group(),
2550 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2551 "Fullpath or basename for module to load.", ""),
2552 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2553 "Set the load address for all sections to be the "
2554 "virtual address in the file plus the offset.",
2555 0) {
2556 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2557 LLDB_OPT_SET_1);
2558 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2559 m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2560 m_option_group.Finalize();
2561 }
2562
2563 ~CommandObjectTargetModulesLoad() override = default;
2564
2565 Options *GetOptions() override { return &m_option_group; }
2566
2567protected:
2568 bool DoExecute(Args &args, CommandReturnObject &result) override {
2569 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2570 if (target == nullptr) {
2571 result.AppendError("invalid target, create a debug target using the "
2572 "'target create' command");
2573 result.SetStatus(eReturnStatusFailed);
2574 return false;
2575 } else {
2576 const size_t argc = args.GetArgumentCount();
2577 ModuleSpec module_spec;
2578 bool search_using_module_spec = false;
2579 if (m_file_option.GetOptionValue().OptionWasSet()) {
2580 search_using_module_spec = true;
2581 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2582 const bool use_global_module_list = true;
2583 ModuleList module_list;
2584 const size_t num_matches = FindModulesByName(
2585 target, arg_cstr, module_list, use_global_module_list);
2586 if (num_matches == 1) {
2587 module_spec.GetFileSpec() =
2588 module_list.GetModuleAtIndex(0)->GetFileSpec();
2589 } else if (num_matches > 1) {
2590 search_using_module_spec = false;
2591 result.AppendErrorWithFormat(
2592 "more than 1 module matched by name '%s'\n", arg_cstr);
2593 result.SetStatus(eReturnStatusFailed);
2594 } else {
2595 search_using_module_spec = false;
2596 result.AppendErrorWithFormat("no object file for module '%s'\n",
2597 arg_cstr);
2598 result.SetStatus(eReturnStatusFailed);
2599 }
2600 }
2601
2602 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2603 search_using_module_spec = true;
2604 module_spec.GetUUID() =
2605 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2606 }
2607
2608 if (search_using_module_spec) {
2609 ModuleList matching_modules;
2610 const size_t num_matches =
2611 target->GetImages().FindModules(module_spec, matching_modules);
2612
2613 char path[PATH_MAX];
2614 if (num_matches == 1) {
2615 Module *module = matching_modules.GetModulePointerAtIndex(0);
2616 if (module) {
2617 ObjectFile *objfile = module->GetObjectFile();
2618 if (objfile) {
2619 SectionList *section_list = module->GetSectionList();
2620 if (section_list) {
2621 bool changed = false;
2622 if (argc == 0) {
2623 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2624 const addr_t slide =
2625 m_slide_option.GetOptionValue().GetCurrentValue();
2626 const bool slide_is_offset = true;
2627 module->SetLoadAddress(*target, slide, slide_is_offset,
2628 changed);
2629 } else {
2630 result.AppendError("one or more section name + load "
2631 "address pair must be specified");
2632 result.SetStatus(eReturnStatusFailed);
2633 return false;
2634 }
2635 } else {
2636 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2637 result.AppendError("The \"--slide <offset>\" option can't "
2638 "be used in conjunction with setting "
2639 "section load addresses.\n");
2640 result.SetStatus(eReturnStatusFailed);
2641 return false;
2642 }
2643
2644 for (size_t i = 0; i < argc; i += 2) {
2645 const char *sect_name = args.GetArgumentAtIndex(i);
2646 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2647 if (sect_name && load_addr_cstr) {
2648 ConstString const_sect_name(sect_name);
2649 bool success = false;
2650 addr_t load_addr = StringConvert::ToUInt64(
2651 load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2652 if (success) {
2653 SectionSP section_sp(
2654 section_list->FindSectionByName(const_sect_name));
2655 if (section_sp) {
2656 if (section_sp->IsThreadSpecific()) {
2657 result.AppendErrorWithFormat(
2658 "thread specific sections are not yet "
2659 "supported (section '%s')\n",
2660 sect_name);
2661 result.SetStatus(eReturnStatusFailed);
2662 break;
2663 } else {
2664 if (target->GetSectionLoadList()
2665 .SetSectionLoadAddress(section_sp,
2666 load_addr))
2667 changed = true;
2668 result.AppendMessageWithFormat(
2669 "section '%s' loaded at 0x%" PRIx64 "\n",
2670 sect_name, load_addr);
2671 }
2672 } else {
2673 result.AppendErrorWithFormat("no section found that "
2674 "matches the section "
2675 "name '%s'\n",
2676 sect_name);
2677 result.SetStatus(eReturnStatusFailed);
2678 break;
2679 }
2680 } else {
2681 result.AppendErrorWithFormat(
2682 "invalid load address string '%s'\n",
2683 load_addr_cstr);
2684 result.SetStatus(eReturnStatusFailed);
2685 break;
2686 }
2687 } else {
2688 if (sect_name)
2689 result.AppendError("section names must be followed by "
2690 "a load address.\n");
2691 else
2692 result.AppendError("one or more section name + load "
2693 "address pair must be specified.\n");
2694 result.SetStatus(eReturnStatusFailed);
2695 break;
2696 }
2697 }
2698 }
2699
2700 if (changed) {
2701 target->ModulesDidLoad(matching_modules);
2702 Process *process = m_exe_ctx.GetProcessPtr();
2703 if (process)
2704 process->Flush();
2705 }
2706 } else {
2707 module->GetFileSpec().GetPath(path, sizeof(path));
2708 result.AppendErrorWithFormat(
2709 "no sections in object file '%s'\n", path);
2710 result.SetStatus(eReturnStatusFailed);
2711 }
2712 } else {
2713 module->GetFileSpec().GetPath(path, sizeof(path));
2714 result.AppendErrorWithFormat("no object file for module '%s'\n",
2715 path);
2716 result.SetStatus(eReturnStatusFailed);
2717 }
2718 } else {
2719 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2720 if (module_spec_file) {
2721 module_spec_file->GetPath(path, sizeof(path));
2722 result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2723 } else
2724 result.AppendError("no module spec");
2725 result.SetStatus(eReturnStatusFailed);
2726 }
2727 } else {
2728 std::string uuid_str;
2729
2730 if (module_spec.GetFileSpec())
2731 module_spec.GetFileSpec().GetPath(path, sizeof(path));
2732 else
2733 path[0] = '\0';
2734
2735 if (module_spec.GetUUIDPtr())
2736 uuid_str = module_spec.GetUUID().GetAsString();
2737 if (num_matches > 1) {
2738 result.AppendErrorWithFormat(
2739 "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2740 path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2741 for (size_t i = 0; i < num_matches; ++i) {
2742 if (matching_modules.GetModulePointerAtIndex(i)
2743 ->GetFileSpec()
2744 .GetPath(path, sizeof(path)))
2745 result.AppendMessageWithFormat("%s\n", path);
2746 }
2747 } else {
2748 result.AppendErrorWithFormat(
2749 "no modules were found that match%s%s%s%s.\n",
2750 path[0] ? " file=" : "", path,
2751 !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2752 }
2753 result.SetStatus(eReturnStatusFailed);
2754 }
2755 } else {
2756 result.AppendError("either the \"--file <module>\" or the \"--uuid "
2757 "<uuid>\" option must be specified.\n");
2758 result.SetStatus(eReturnStatusFailed);
2759 return false;
2760 }
2761 }
2762 return result.Succeeded();
2763 }
2764
2765 OptionGroupOptions m_option_group;
2766 OptionGroupUUID m_uuid_option_group;
2767 OptionGroupString m_file_option;
2768 OptionGroupUInt64 m_slide_option;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002769};
2770
2771//----------------------------------------------------------------------
2772// List images with associated information
2773//----------------------------------------------------------------------
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002774
2775static OptionDefinition g_target_modules_list_options[] = {
2776 // clang-format off
2777 { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Display the image at this address." },
2778 { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the architecture when listing images." },
2779 { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the triple when listing images." },
2780 { 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." },
2781 { 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)." },
2782 { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the UUID when listing images." },
2783 { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image object file." },
2784 { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the directory with optional width for the image object file." },
2785 { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the basename with optional width for the image object file." },
2786 { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width." },
2787 { 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." },
2788 { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the modification time with optional width of the module." },
2789 { 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." },
2790 { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the module pointer." },
2791 { 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." }
2792 // clang-format on
2793};
2794
Kate Stoneb9c1b512016-09-06 20:57:50 +00002795class CommandObjectTargetModulesList : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002796public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002797 class CommandOptions : public Options {
2798 public:
2799 CommandOptions()
2800 : Options(), m_format_array(), m_use_global_module_list(false),
2801 m_module_addr(LLDB_INVALID_ADDRESS) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002802
Kate Stoneb9c1b512016-09-06 20:57:50 +00002803 ~CommandOptions() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002804
Kate Stoneb9c1b512016-09-06 20:57:50 +00002805 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
2806 ExecutionContext *execution_context) override {
2807 Error error;
Greg Claytonb9d5df52012-12-06 22:49:16 +00002808
Kate Stoneb9c1b512016-09-06 20:57:50 +00002809 const int short_option = m_getopt_table[option_idx].val;
2810 if (short_option == 'g') {
2811 m_use_global_module_list = true;
2812 } else if (short_option == 'a') {
2813 m_module_addr = Args::StringToAddress(execution_context, option_arg,
2814 LLDB_INVALID_ADDRESS, &error);
2815 } else {
2816 unsigned long width = 0;
2817 if (option_arg)
2818 width = strtoul(option_arg, nullptr, 0);
2819 m_format_array.push_back(std::make_pair(short_option, width));
2820 }
2821 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002822 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002823
Kate Stoneb9c1b512016-09-06 20:57:50 +00002824 void OptionParsingStarting(ExecutionContext *execution_context) override {
2825 m_format_array.clear();
2826 m_use_global_module_list = false;
2827 m_module_addr = LLDB_INVALID_ADDRESS;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002828 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002829
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002830 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00002831 return llvm::makeArrayRef(g_target_modules_list_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002832 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002833
2834 // Instance variables to hold the values for command options.
2835 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
2836 FormatWidthCollection m_format_array;
2837 bool m_use_global_module_list;
2838 lldb::addr_t m_module_addr;
2839 };
2840
2841 CommandObjectTargetModulesList(CommandInterpreter &interpreter)
2842 : CommandObjectParsed(
2843 interpreter, "target modules list",
2844 "List current executable and dependent shared library images.",
2845 "target modules list [<cmd-options>]"),
2846 m_options() {}
2847
2848 ~CommandObjectTargetModulesList() override = default;
2849
2850 Options *GetOptions() override { return &m_options; }
2851
Jim Ingham5a988412012-06-08 21:56:10 +00002852protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002853 bool DoExecute(Args &command, CommandReturnObject &result) override {
2854 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2855 const bool use_global_module_list = m_options.m_use_global_module_list;
2856 // Define a local module list here to ensure it lives longer than any
2857 // "locker"
2858 // object which might lock its contents below (through the "module_list_ptr"
2859 // variable).
2860 ModuleList module_list;
2861 if (target == nullptr && !use_global_module_list) {
2862 result.AppendError("invalid target, create a debug target using the "
2863 "'target create' command");
2864 result.SetStatus(eReturnStatusFailed);
2865 return false;
2866 } else {
2867 if (target) {
2868 uint32_t addr_byte_size =
2869 target->GetArchitecture().GetAddressByteSize();
2870 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2871 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2872 }
2873 // Dump all sections for all modules images
2874 Stream &strm = result.GetOutputStream();
2875
2876 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
2877 if (target) {
2878 Address module_address;
2879 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
2880 ModuleSP module_sp(module_address.GetModule());
2881 if (module_sp) {
2882 PrintModule(target, module_sp.get(), 0, strm);
2883 result.SetStatus(eReturnStatusSuccessFinishResult);
2884 } else {
2885 result.AppendErrorWithFormat(
2886 "Couldn't find module matching address: 0x%" PRIx64 ".",
2887 m_options.m_module_addr);
2888 result.SetStatus(eReturnStatusFailed);
Greg Clayton3418c852011-08-10 02:10:13 +00002889 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002890 } else {
2891 result.AppendErrorWithFormat(
2892 "Couldn't find module containing address: 0x%" PRIx64 ".",
2893 m_options.m_module_addr);
2894 result.SetStatus(eReturnStatusFailed);
2895 }
2896 } else {
2897 result.AppendError(
2898 "Can only look up modules by address with a valid target.");
2899 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002900 }
2901 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002902 }
Jim Inghamc10312c2011-10-24 18:36:33 +00002903
Kate Stoneb9c1b512016-09-06 20:57:50 +00002904 size_t num_modules = 0;
2905
2906 // This locker will be locked on the mutex in module_list_ptr if it is
2907 // non-nullptr.
2908 // Otherwise it will lock the AllocationModuleCollectionMutex when
2909 // accessing
2910 // the global module list directly.
2911 std::unique_lock<std::recursive_mutex> guard(
2912 Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
2913
2914 const ModuleList *module_list_ptr = nullptr;
2915 const size_t argc = command.GetArgumentCount();
2916 if (argc == 0) {
2917 if (use_global_module_list) {
2918 guard.lock();
2919 num_modules = Module::GetNumberAllocatedModules();
2920 } else {
2921 module_list_ptr = &target->GetImages();
Jim Ingham28eb5712012-10-12 17:34:26 +00002922 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002923 } else {
Zachary Turner97d2c402016-10-05 23:40:23 +00002924 // TODO: Convert to entry based iteration. Requires converting
2925 // FindModulesByName.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002926 for (size_t i = 0; i < argc; ++i) {
2927 // Dump specified images (by basename or fullpath)
2928 const char *arg_cstr = command.GetArgumentAtIndex(i);
2929 const size_t num_matches = FindModulesByName(
2930 target, arg_cstr, module_list, use_global_module_list);
2931 if (num_matches == 0) {
2932 if (argc == 1) {
2933 result.AppendErrorWithFormat("no modules found that match '%s'",
2934 arg_cstr);
2935 result.SetStatus(eReturnStatusFailed);
2936 return false;
Jim Inghamc10312c2011-10-24 18:36:33 +00002937 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002938 }
Greg Claytonc9660542012-02-05 02:38:54 +00002939 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002940
2941 module_list_ptr = &module_list;
2942 }
2943
2944 std::unique_lock<std::recursive_mutex> lock;
2945 if (module_list_ptr != nullptr) {
2946 lock =
2947 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
2948
2949 num_modules = module_list_ptr->GetSize();
2950 }
2951
2952 if (num_modules > 0) {
2953 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2954 ModuleSP module_sp;
2955 Module *module;
2956 if (module_list_ptr) {
2957 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
2958 module = module_sp.get();
2959 } else {
2960 module = Module::GetAllocatedModuleAtIndex(image_idx);
2961 module_sp = module->shared_from_this();
2962 }
2963
2964 const size_t indent = strm.Printf("[%3u] ", image_idx);
2965 PrintModule(target, module, indent, strm);
Jim Inghamc10312c2011-10-24 18:36:33 +00002966 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002967 result.SetStatus(eReturnStatusSuccessFinishResult);
2968 } else {
2969 if (argc) {
2970 if (use_global_module_list)
2971 result.AppendError(
2972 "the global module list has no matching modules");
2973 else
2974 result.AppendError("the target has no matching modules");
2975 } else {
2976 if (use_global_module_list)
2977 result.AppendError("the global module list is empty");
2978 else
2979 result.AppendError(
2980 "the target has no associated executable images");
2981 }
2982 result.SetStatus(eReturnStatusFailed);
2983 return false;
2984 }
2985 }
2986 return result.Succeeded();
2987 }
2988
2989 void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
2990 if (module == nullptr) {
2991 strm.PutCString("Null module");
2992 return;
Jim Inghamc10312c2011-10-24 18:36:33 +00002993 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002994
Kate Stoneb9c1b512016-09-06 20:57:50 +00002995 bool dump_object_name = false;
2996 if (m_options.m_format_array.empty()) {
2997 m_options.m_format_array.push_back(std::make_pair('u', 0));
2998 m_options.m_format_array.push_back(std::make_pair('h', 0));
2999 m_options.m_format_array.push_back(std::make_pair('f', 0));
3000 m_options.m_format_array.push_back(std::make_pair('S', 0));
3001 }
3002 const size_t num_entries = m_options.m_format_array.size();
3003 bool print_space = false;
3004 for (size_t i = 0; i < num_entries; ++i) {
3005 if (print_space)
3006 strm.PutChar(' ');
3007 print_space = true;
3008 const char format_char = m_options.m_format_array[i].first;
3009 uint32_t width = m_options.m_format_array[i].second;
3010 switch (format_char) {
3011 case 'A':
3012 DumpModuleArchitecture(strm, module, false, width);
3013 break;
3014
3015 case 't':
3016 DumpModuleArchitecture(strm, module, true, width);
3017 break;
3018
3019 case 'f':
3020 DumpFullpath(strm, &module->GetFileSpec(), width);
3021 dump_object_name = true;
3022 break;
3023
3024 case 'd':
3025 DumpDirectory(strm, &module->GetFileSpec(), width);
3026 break;
3027
3028 case 'b':
3029 DumpBasename(strm, &module->GetFileSpec(), width);
3030 dump_object_name = true;
3031 break;
3032
3033 case 'h':
3034 case 'o':
3035 // Image header address
3036 {
3037 uint32_t addr_nibble_width =
3038 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3039 : 16;
3040
3041 ObjectFile *objfile = module->GetObjectFile();
3042 if (objfile) {
3043 Address header_addr(objfile->GetHeaderAddress());
3044 if (header_addr.IsValid()) {
3045 if (target && !target->GetSectionLoadList().IsEmpty()) {
3046 lldb::addr_t header_load_addr =
3047 header_addr.GetLoadAddress(target);
3048 if (header_load_addr == LLDB_INVALID_ADDRESS) {
3049 header_addr.Dump(&strm, target,
3050 Address::DumpStyleModuleWithFileAddress,
3051 Address::DumpStyleFileAddress);
3052 } else {
3053 if (format_char == 'o') {
3054 // Show the offset of slide for the image
3055 strm.Printf(
3056 "0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width,
3057 header_load_addr - header_addr.GetFileAddress());
3058 } else {
3059 // Show the load address of the image
3060 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3061 addr_nibble_width, header_load_addr);
3062 }
3063 }
3064 break;
3065 }
3066 // The address was valid, but the image isn't loaded, output the
3067 // address in an appropriate format
3068 header_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3069 break;
3070 }
3071 }
3072 strm.Printf("%*s", addr_nibble_width + 2, "");
3073 }
3074 break;
3075
3076 case 'r': {
3077 size_t ref_count = 0;
3078 ModuleSP module_sp(module->shared_from_this());
3079 if (module_sp) {
3080 // Take one away to make sure we don't count our local "module_sp"
3081 ref_count = module_sp.use_count() - 1;
3082 }
3083 if (width)
3084 strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3085 else
3086 strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3087 } break;
3088
3089 case 's':
3090 case 'S': {
3091 const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3092 if (symbol_vendor) {
3093 const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3094 if (format_char == 'S') {
3095 // Dump symbol file only if different from module file
3096 if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3097 print_space = false;
3098 break;
3099 }
3100 // Add a newline and indent past the index
3101 strm.Printf("\n%*s", indent, "");
3102 }
3103 DumpFullpath(strm, &symfile_spec, width);
3104 dump_object_name = true;
3105 break;
3106 }
3107 strm.Printf("%.*s", width, "<NONE>");
3108 } break;
3109
3110 case 'm':
3111 module->GetModificationTime().Dump(&strm, width);
3112 break;
3113
3114 case 'p':
3115 strm.Printf("%p", static_cast<void *>(module));
3116 break;
3117
3118 case 'u':
3119 DumpModuleUUID(strm, module);
3120 break;
3121
3122 default:
3123 break;
3124 }
3125 }
3126 if (dump_object_name) {
3127 const char *object_name = module->GetObjectName().GetCString();
3128 if (object_name)
3129 strm.Printf("(%s)", object_name);
3130 }
3131 strm.EOL();
3132 }
3133
3134 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003135};
3136
Jason Molenda380241a2012-07-12 00:20:07 +00003137#pragma mark CommandObjectTargetModulesShowUnwind
Greg Claytoneffe5c92011-05-03 22:09:39 +00003138
Jason Molenda380241a2012-07-12 00:20:07 +00003139//----------------------------------------------------------------------
3140// Lookup unwind information in images
3141//----------------------------------------------------------------------
3142
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003143static OptionDefinition g_target_modules_show_unwind_options[] = {
3144 // clang-format off
3145 { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name." },
3146 { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" }
3147 // clang-format on
3148};
3149
Kate Stoneb9c1b512016-09-06 20:57:50 +00003150class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
Jason Molenda380241a2012-07-12 00:20:07 +00003151public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003152 enum {
3153 eLookupTypeInvalid = -1,
3154 eLookupTypeAddress = 0,
3155 eLookupTypeSymbol,
3156 eLookupTypeFunction,
3157 eLookupTypeFunctionOrSymbol,
3158 kNumLookupTypes
3159 };
Jason Molenda380241a2012-07-12 00:20:07 +00003160
Kate Stoneb9c1b512016-09-06 20:57:50 +00003161 class CommandOptions : public Options {
3162 public:
3163 CommandOptions()
3164 : Options(), m_type(eLookupTypeInvalid), m_str(),
3165 m_addr(LLDB_INVALID_ADDRESS) {}
Jason Molenda380241a2012-07-12 00:20:07 +00003166
Kate Stoneb9c1b512016-09-06 20:57:50 +00003167 ~CommandOptions() override = default;
Jason Molenda380241a2012-07-12 00:20:07 +00003168
Kate Stoneb9c1b512016-09-06 20:57:50 +00003169 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
3170 ExecutionContext *execution_context) override {
3171 Error error;
Jason Molenda380241a2012-07-12 00:20:07 +00003172
Kate Stoneb9c1b512016-09-06 20:57:50 +00003173 const int short_option = m_getopt_table[option_idx].val;
Jason Molenda380241a2012-07-12 00:20:07 +00003174
Kate Stoneb9c1b512016-09-06 20:57:50 +00003175 switch (short_option) {
3176 case 'a': {
3177 m_str = option_arg;
3178 m_type = eLookupTypeAddress;
3179 m_addr = Args::StringToAddress(execution_context, option_arg,
3180 LLDB_INVALID_ADDRESS, &error);
3181 if (m_addr == LLDB_INVALID_ADDRESS)
3182 error.SetErrorStringWithFormat("invalid address string '%s'",
3183 option_arg);
3184 break;
3185 }
Jason Molenda380241a2012-07-12 00:20:07 +00003186
Kate Stoneb9c1b512016-09-06 20:57:50 +00003187 case 'n':
3188 m_str = option_arg;
3189 m_type = eLookupTypeFunctionOrSymbol;
3190 break;
Michael Sartainb1e15922013-08-22 20:42:30 +00003191
Kate Stoneb9c1b512016-09-06 20:57:50 +00003192 default:
3193 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
3194 break;
3195 }
Jason Molenda380241a2012-07-12 00:20:07 +00003196
Kate Stoneb9c1b512016-09-06 20:57:50 +00003197 return error;
Jason Molenda380241a2012-07-12 00:20:07 +00003198 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003199
Kate Stoneb9c1b512016-09-06 20:57:50 +00003200 void OptionParsingStarting(ExecutionContext *execution_context) override {
3201 m_type = eLookupTypeInvalid;
3202 m_str.clear();
3203 m_addr = LLDB_INVALID_ADDRESS;
Jason Molenda380241a2012-07-12 00:20:07 +00003204 }
3205
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003206 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00003207 return llvm::makeArrayRef(g_target_modules_show_unwind_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003208 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003209
3210 // Instance variables to hold the values for command options.
3211
3212 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3213 std::string m_str; // Holds name lookup
3214 lldb::addr_t m_addr; // Holds the address to lookup
3215 };
3216
3217 CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3218 : CommandObjectParsed(
3219 interpreter, "target modules show-unwind",
3220 "Show synthesized unwind instructions for a function.", nullptr,
3221 eCommandRequiresTarget | eCommandRequiresProcess |
3222 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
3223 m_options() {}
3224
3225 ~CommandObjectTargetModulesShowUnwind() override = default;
3226
3227 Options *GetOptions() override { return &m_options; }
3228
Jason Molenda380241a2012-07-12 00:20:07 +00003229protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003230 bool DoExecute(Args &command, CommandReturnObject &result) override {
3231 Target *target = m_exe_ctx.GetTargetPtr();
3232 Process *process = m_exe_ctx.GetProcessPtr();
3233 ABI *abi = nullptr;
3234 if (process)
3235 abi = process->GetABI().get();
Jason Molenda380241a2012-07-12 00:20:07 +00003236
Kate Stoneb9c1b512016-09-06 20:57:50 +00003237 if (process == nullptr) {
3238 result.AppendError(
3239 "You must have a process running to use this command.");
3240 result.SetStatus(eReturnStatusFailed);
3241 return false;
Jason Molenda380241a2012-07-12 00:20:07 +00003242 }
3243
Kate Stoneb9c1b512016-09-06 20:57:50 +00003244 ThreadList threads(process->GetThreadList());
3245 if (threads.GetSize() == 0) {
3246 result.AppendError("The process must be paused to use this command.");
3247 result.SetStatus(eReturnStatusFailed);
3248 return false;
3249 }
3250
3251 ThreadSP thread(threads.GetThreadAtIndex(0));
3252 if (!thread) {
3253 result.AppendError("The process must be paused to use this command.");
3254 result.SetStatus(eReturnStatusFailed);
3255 return false;
3256 }
3257
3258 SymbolContextList sc_list;
3259
3260 if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3261 ConstString function_name(m_options.m_str.c_str());
3262 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3263 true, false, true, sc_list);
3264 } else if (m_options.m_type == eLookupTypeAddress && target) {
3265 Address addr;
3266 if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3267 addr)) {
3268 SymbolContext sc;
3269 ModuleSP module_sp(addr.GetModule());
3270 module_sp->ResolveSymbolContextForAddress(addr,
3271 eSymbolContextEverything, sc);
3272 if (sc.function || sc.symbol) {
3273 sc_list.Append(sc);
3274 }
3275 }
3276 } else {
3277 result.AppendError(
3278 "address-expression or function name option must be specified.");
3279 result.SetStatus(eReturnStatusFailed);
3280 return false;
3281 }
3282
3283 size_t num_matches = sc_list.GetSize();
3284 if (num_matches == 0) {
3285 result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3286 m_options.m_str.c_str());
3287 result.SetStatus(eReturnStatusFailed);
3288 return false;
3289 }
3290
3291 for (uint32_t idx = 0; idx < num_matches; idx++) {
3292 SymbolContext sc;
3293 sc_list.GetContextAtIndex(idx, sc);
3294 if (sc.symbol == nullptr && sc.function == nullptr)
3295 continue;
3296 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3297 continue;
3298 AddressRange range;
3299 if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3300 false, range))
3301 continue;
3302 if (!range.GetBaseAddress().IsValid())
3303 continue;
3304 ConstString funcname(sc.GetFunctionName());
3305 if (funcname.IsEmpty())
3306 continue;
3307 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3308 if (abi)
3309 start_addr = abi->FixCodeAddress(start_addr);
3310
3311 FuncUnwindersSP func_unwinders_sp(
3312 sc.module_sp->GetObjectFile()
3313 ->GetUnwindTable()
3314 .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3315 if (!func_unwinders_sp)
3316 continue;
3317
3318 result.GetOutputStream().Printf(
3319 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
3320 sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3321 funcname.AsCString(), start_addr);
3322
3323 UnwindPlanSP non_callsite_unwind_plan =
3324 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
3325 if (non_callsite_unwind_plan) {
3326 result.GetOutputStream().Printf(
3327 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3328 non_callsite_unwind_plan->GetSourceName().AsCString());
3329 }
3330 UnwindPlanSP callsite_unwind_plan =
3331 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3332 if (callsite_unwind_plan) {
3333 result.GetOutputStream().Printf(
3334 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3335 callsite_unwind_plan->GetSourceName().AsCString());
3336 }
3337 UnwindPlanSP fast_unwind_plan =
3338 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3339 if (fast_unwind_plan) {
3340 result.GetOutputStream().Printf(
3341 "Fast UnwindPlan is '%s'\n",
3342 fast_unwind_plan->GetSourceName().AsCString());
3343 }
3344
3345 result.GetOutputStream().Printf("\n");
3346
3347 UnwindPlanSP assembly_sp =
3348 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
3349 if (assembly_sp) {
3350 result.GetOutputStream().Printf(
3351 "Assembly language inspection UnwindPlan:\n");
3352 assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3353 LLDB_INVALID_ADDRESS);
3354 result.GetOutputStream().Printf("\n");
3355 }
3356
3357 UnwindPlanSP ehframe_sp =
3358 func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3359 if (ehframe_sp) {
3360 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3361 ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3362 LLDB_INVALID_ADDRESS);
3363 result.GetOutputStream().Printf("\n");
3364 }
3365
3366 UnwindPlanSP ehframe_augmented_sp =
3367 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
3368 if (ehframe_augmented_sp) {
3369 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3370 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3371 LLDB_INVALID_ADDRESS);
3372 result.GetOutputStream().Printf("\n");
3373 }
3374
3375 UnwindPlanSP arm_unwind_sp =
3376 func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
3377 if (arm_unwind_sp) {
3378 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3379 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3380 LLDB_INVALID_ADDRESS);
3381 result.GetOutputStream().Printf("\n");
3382 }
3383
3384 UnwindPlanSP compact_unwind_sp =
3385 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3386 if (compact_unwind_sp) {
3387 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3388 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3389 LLDB_INVALID_ADDRESS);
3390 result.GetOutputStream().Printf("\n");
3391 }
3392
3393 if (fast_unwind_plan) {
3394 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3395 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3396 LLDB_INVALID_ADDRESS);
3397 result.GetOutputStream().Printf("\n");
3398 }
3399
3400 ABISP abi_sp = process->GetABI();
3401 if (abi_sp) {
3402 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3403 if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3404 result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3405 arch_default.Dump(result.GetOutputStream(), thread.get(),
3406 LLDB_INVALID_ADDRESS);
3407 result.GetOutputStream().Printf("\n");
3408 }
3409
3410 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3411 if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3412 result.GetOutputStream().Printf(
3413 "Arch default at entry point UnwindPlan:\n");
3414 arch_entry.Dump(result.GetOutputStream(), thread.get(),
3415 LLDB_INVALID_ADDRESS);
3416 result.GetOutputStream().Printf("\n");
3417 }
3418 }
3419
3420 result.GetOutputStream().Printf("\n");
3421 }
3422 return result.Succeeded();
3423 }
3424
3425 CommandOptions m_options;
Jason Molenda380241a2012-07-12 00:20:07 +00003426};
3427
Greg Claytoneffe5c92011-05-03 22:09:39 +00003428//----------------------------------------------------------------------
3429// Lookup information in images
3430//----------------------------------------------------------------------
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003431
3432static OptionDefinition g_target_modules_lookup_options[] = {
3433 // clang-format off
3434 { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." },
3435 { 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." },
3436 /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */
3437 { 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." },
3438 { 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." },
3439 { 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." },
3440 { 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)." },
3441 { 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)." },
3442 { 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." },
3443 { 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." },
3444 { 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." },
3445 { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose lookup information." },
3446 { 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." },
3447 // clang-format on
3448};
3449
Kate Stoneb9c1b512016-09-06 20:57:50 +00003450class CommandObjectTargetModulesLookup : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00003451public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003452 enum {
3453 eLookupTypeInvalid = -1,
3454 eLookupTypeAddress = 0,
3455 eLookupTypeSymbol,
3456 eLookupTypeFileLine, // Line is optional
3457 eLookupTypeFunction,
3458 eLookupTypeFunctionOrSymbol,
3459 eLookupTypeType,
3460 kNumLookupTypes
3461 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003462
Kate Stoneb9c1b512016-09-06 20:57:50 +00003463 class CommandOptions : public Options {
3464 public:
3465 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003466
Kate Stoneb9c1b512016-09-06 20:57:50 +00003467 ~CommandOptions() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003468
Kate Stoneb9c1b512016-09-06 20:57:50 +00003469 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
3470 ExecutionContext *execution_context) override {
3471 Error error;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003472
Kate Stoneb9c1b512016-09-06 20:57:50 +00003473 const int short_option = m_getopt_table[option_idx].val;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003474
Kate Stoneb9c1b512016-09-06 20:57:50 +00003475 switch (short_option) {
3476 case 'a': {
3477 m_type = eLookupTypeAddress;
3478 m_addr = Args::StringToAddress(execution_context, option_arg,
3479 LLDB_INVALID_ADDRESS, &error);
3480 } break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003481
Kate Stoneb9c1b512016-09-06 20:57:50 +00003482 case 'o':
3483 m_offset = StringConvert::ToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3484 if (m_offset == LLDB_INVALID_ADDRESS)
3485 error.SetErrorStringWithFormat("invalid offset string '%s'",
3486 option_arg);
3487 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003488
Kate Stoneb9c1b512016-09-06 20:57:50 +00003489 case 's':
3490 m_str = option_arg;
3491 m_type = eLookupTypeSymbol;
3492 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003493
Kate Stoneb9c1b512016-09-06 20:57:50 +00003494 case 'f':
3495 m_file.SetFile(option_arg, false);
3496 m_type = eLookupTypeFileLine;
3497 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003498
Kate Stoneb9c1b512016-09-06 20:57:50 +00003499 case 'i':
3500 m_include_inlines = false;
3501 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003502
Kate Stoneb9c1b512016-09-06 20:57:50 +00003503 case 'l':
3504 m_line_number = StringConvert::ToUInt32(option_arg, UINT32_MAX);
3505 if (m_line_number == UINT32_MAX)
3506 error.SetErrorStringWithFormat("invalid line number string '%s'",
3507 option_arg);
3508 else if (m_line_number == 0)
3509 error.SetErrorString("zero is an invalid line number");
3510 m_type = eLookupTypeFileLine;
3511 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003512
Kate Stoneb9c1b512016-09-06 20:57:50 +00003513 case 'F':
3514 m_str = option_arg;
3515 m_type = eLookupTypeFunction;
3516 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003517
Kate Stoneb9c1b512016-09-06 20:57:50 +00003518 case 'n':
3519 m_str = option_arg;
3520 m_type = eLookupTypeFunctionOrSymbol;
3521 break;
Greg Claytonc4a8a762012-05-15 18:43:44 +00003522
Kate Stoneb9c1b512016-09-06 20:57:50 +00003523 case 't':
3524 m_str = option_arg;
3525 m_type = eLookupTypeType;
3526 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003527
Kate Stoneb9c1b512016-09-06 20:57:50 +00003528 case 'v':
3529 m_verbose = 1;
3530 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003531
Kate Stoneb9c1b512016-09-06 20:57:50 +00003532 case 'A':
3533 m_print_all = true;
3534 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003535
Kate Stoneb9c1b512016-09-06 20:57:50 +00003536 case 'r':
3537 m_use_regex = true;
3538 break;
3539 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003540
Kate Stoneb9c1b512016-09-06 20:57:50 +00003541 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003542 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003543
Kate Stoneb9c1b512016-09-06 20:57:50 +00003544 void OptionParsingStarting(ExecutionContext *execution_context) override {
3545 m_type = eLookupTypeInvalid;
3546 m_str.clear();
3547 m_file.Clear();
3548 m_addr = LLDB_INVALID_ADDRESS;
3549 m_offset = 0;
3550 m_line_number = 0;
3551 m_use_regex = false;
3552 m_include_inlines = true;
3553 m_verbose = false;
3554 m_print_all = false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003555 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003556
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003557 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00003558 return llvm::makeArrayRef(g_target_modules_lookup_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003559 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003560
Kate Stoneb9c1b512016-09-06 20:57:50 +00003561 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3562 std::string m_str; // Holds name lookup
3563 FileSpec m_file; // Files for file lookups
3564 lldb::addr_t m_addr; // Holds the address to lookup
3565 lldb::addr_t
3566 m_offset; // Subtract this offset from m_addr before doing lookups.
3567 uint32_t m_line_number; // Line number for file+line lookups
3568 bool m_use_regex; // Name lookups in m_str are regular expressions.
3569 bool m_include_inlines; // Check for inline entries when looking up by
3570 // file/line.
3571 bool m_verbose; // Enable verbose lookup info
3572 bool m_print_all; // Print all matches, even in cases where there's a best
3573 // match.
3574 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003575
Kate Stoneb9c1b512016-09-06 20:57:50 +00003576 CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3577 : CommandObjectParsed(interpreter, "target modules lookup",
3578 "Look up information within executable and "
3579 "dependent shared library images.",
3580 nullptr, eCommandRequiresTarget),
3581 m_options() {
3582 CommandArgumentEntry arg;
3583 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003584
Kate Stoneb9c1b512016-09-06 20:57:50 +00003585 // Define the first (and only) variant of this arg.
3586 file_arg.arg_type = eArgTypeFilename;
3587 file_arg.arg_repetition = eArgRepeatStar;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003588
Kate Stoneb9c1b512016-09-06 20:57:50 +00003589 // There is only one variant this argument could be; put it into the
3590 // argument entry.
3591 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003592
Kate Stoneb9c1b512016-09-06 20:57:50 +00003593 // Push the data for the first argument into the m_arguments vector.
3594 m_arguments.push_back(arg);
3595 }
3596
3597 ~CommandObjectTargetModulesLookup() override = default;
3598
3599 Options *GetOptions() override { return &m_options; }
3600
3601 bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3602 bool &syntax_error) {
3603 switch (m_options.m_type) {
3604 case eLookupTypeAddress:
3605 case eLookupTypeFileLine:
3606 case eLookupTypeFunction:
3607 case eLookupTypeFunctionOrSymbol:
3608 case eLookupTypeSymbol:
3609 default:
3610 return false;
3611 case eLookupTypeType:
3612 break;
Sean Callanand38b4a92012-06-06 20:49:55 +00003613 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003614
Kate Stoneb9c1b512016-09-06 20:57:50 +00003615 StackFrameSP frame = m_exe_ctx.GetFrameSP();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003616
Kate Stoneb9c1b512016-09-06 20:57:50 +00003617 if (!frame)
3618 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003619
Kate Stoneb9c1b512016-09-06 20:57:50 +00003620 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
Greg Claytonc4a8a762012-05-15 18:43:44 +00003621
Kate Stoneb9c1b512016-09-06 20:57:50 +00003622 if (!sym_ctx.module_sp)
3623 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003624
Kate Stoneb9c1b512016-09-06 20:57:50 +00003625 switch (m_options.m_type) {
3626 default:
3627 return false;
3628 case eLookupTypeType:
3629 if (!m_options.m_str.empty()) {
3630 if (LookupTypeHere(m_interpreter, result.GetOutputStream(), sym_ctx,
3631 m_options.m_str.c_str(), m_options.m_use_regex)) {
3632 result.SetStatus(eReturnStatusSuccessFinishResult);
3633 return true;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003634 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003635 }
3636 break;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003637 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003638
Kate Stoneb9c1b512016-09-06 20:57:50 +00003639 return true;
3640 }
3641
3642 bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3643 CommandReturnObject &result, bool &syntax_error) {
3644 switch (m_options.m_type) {
3645 case eLookupTypeAddress:
3646 if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3647 if (LookupAddressInModule(
3648 m_interpreter, result.GetOutputStream(), module,
3649 eSymbolContextEverything |
3650 (m_options.m_verbose
3651 ? static_cast<int>(eSymbolContextVariable)
3652 : 0),
3653 m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
3654 result.SetStatus(eReturnStatusSuccessFinishResult);
3655 return true;
3656 }
3657 }
3658 break;
3659
3660 case eLookupTypeSymbol:
3661 if (!m_options.m_str.empty()) {
3662 if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3663 module, m_options.m_str.c_str(),
3664 m_options.m_use_regex, m_options.m_verbose)) {
3665 result.SetStatus(eReturnStatusSuccessFinishResult);
3666 return true;
3667 }
3668 }
3669 break;
3670
3671 case eLookupTypeFileLine:
3672 if (m_options.m_file) {
3673 if (LookupFileAndLineInModule(
3674 m_interpreter, result.GetOutputStream(), module,
3675 m_options.m_file, m_options.m_line_number,
3676 m_options.m_include_inlines, m_options.m_verbose)) {
3677 result.SetStatus(eReturnStatusSuccessFinishResult);
3678 return true;
3679 }
3680 }
3681 break;
3682
3683 case eLookupTypeFunctionOrSymbol:
3684 case eLookupTypeFunction:
3685 if (!m_options.m_str.empty()) {
3686 if (LookupFunctionInModule(
3687 m_interpreter, result.GetOutputStream(), module,
3688 m_options.m_str.c_str(), m_options.m_use_regex,
3689 m_options.m_include_inlines,
3690 m_options.m_type ==
3691 eLookupTypeFunctionOrSymbol, // include symbols
3692 m_options.m_verbose)) {
3693 result.SetStatus(eReturnStatusSuccessFinishResult);
3694 return true;
3695 }
3696 }
3697 break;
3698
3699 case eLookupTypeType:
3700 if (!m_options.m_str.empty()) {
3701 if (LookupTypeInModule(m_interpreter, result.GetOutputStream(), module,
3702 m_options.m_str.c_str(),
3703 m_options.m_use_regex)) {
3704 result.SetStatus(eReturnStatusSuccessFinishResult);
3705 return true;
3706 }
3707 }
3708 break;
3709
3710 default:
3711 m_options.GenerateOptionUsage(
3712 result.GetErrorStream(), this,
3713 GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3714 syntax_error = true;
3715 break;
3716 }
3717
3718 result.SetStatus(eReturnStatusFailed);
3719 return false;
3720 }
3721
Jim Ingham5a988412012-06-08 21:56:10 +00003722protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003723 bool DoExecute(Args &command, CommandReturnObject &result) override {
3724 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3725 if (target == nullptr) {
3726 result.AppendError("invalid target, create a debug target using the "
3727 "'target create' command");
3728 result.SetStatus(eReturnStatusFailed);
3729 return false;
3730 } else {
3731 bool syntax_error = false;
3732 uint32_t i;
3733 uint32_t num_successful_lookups = 0;
3734 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3735 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3736 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3737 // Dump all sections for all modules images
3738
3739 if (command.GetArgumentCount() == 0) {
3740 ModuleSP current_module;
3741
3742 // Where it is possible to look in the current symbol context
3743 // first, try that. If this search was successful and --all
3744 // was not passed, don't print anything else.
3745 if (LookupHere(m_interpreter, result, syntax_error)) {
3746 result.GetOutputStream().EOL();
3747 num_successful_lookups++;
3748 if (!m_options.m_print_all) {
3749 result.SetStatus(eReturnStatusSuccessFinishResult);
3750 return result.Succeeded();
3751 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00003752 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003753
Kate Stoneb9c1b512016-09-06 20:57:50 +00003754 // Dump all sections for all other modules
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003755
Kate Stoneb9c1b512016-09-06 20:57:50 +00003756 const ModuleList &target_modules = target->GetImages();
3757 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3758 const size_t num_modules = target_modules.GetSize();
3759 if (num_modules > 0) {
3760 for (i = 0; i < num_modules && !syntax_error; ++i) {
3761 Module *module_pointer =
3762 target_modules.GetModulePointerAtIndexUnlocked(i);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003763
Kate Stoneb9c1b512016-09-06 20:57:50 +00003764 if (module_pointer != current_module.get() &&
3765 LookupInModule(
3766 m_interpreter,
3767 target_modules.GetModulePointerAtIndexUnlocked(i), result,
3768 syntax_error)) {
3769 result.GetOutputStream().EOL();
3770 num_successful_lookups++;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003771 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003772 }
3773 } else {
3774 result.AppendError("the target has no associated executable images");
3775 result.SetStatus(eReturnStatusFailed);
3776 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003777 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003778 } else {
3779 // Dump specified images (by basename or fullpath)
3780 const char *arg_cstr;
3781 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3782 !syntax_error;
3783 ++i) {
3784 ModuleList module_list;
3785 const size_t num_matches =
3786 FindModulesByName(target, arg_cstr, module_list, false);
3787 if (num_matches > 0) {
3788 for (size_t j = 0; j < num_matches; ++j) {
3789 Module *module = module_list.GetModulePointerAtIndex(j);
3790 if (module) {
3791 if (LookupInModule(m_interpreter, module, result,
3792 syntax_error)) {
3793 result.GetOutputStream().EOL();
3794 num_successful_lookups++;
3795 }
3796 }
3797 }
3798 } else
3799 result.AppendWarningWithFormat(
3800 "Unable to find an image that matches '%s'.\n", arg_cstr);
3801 }
3802 }
3803
3804 if (num_successful_lookups > 0)
3805 result.SetStatus(eReturnStatusSuccessFinishResult);
3806 else
3807 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00003808 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003809 return result.Succeeded();
3810 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003811
Kate Stoneb9c1b512016-09-06 20:57:50 +00003812 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003813};
3814
Jim Ingham9575d842011-03-11 03:53:59 +00003815#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003816
3817//-------------------------------------------------------------------------
3818// CommandObjectMultiwordImageSearchPaths
3819//-------------------------------------------------------------------------
3820
Kate Stoneb9c1b512016-09-06 20:57:50 +00003821class CommandObjectTargetModulesImageSearchPaths
3822 : public CommandObjectMultiword {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003823public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003824 CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
3825 : CommandObjectMultiword(
3826 interpreter, "target modules search-paths",
3827 "Commands for managing module search paths for a target.",
3828 "target modules search-paths <subcommand> [<subcommand-options>]") {
3829 LoadSubCommand(
3830 "add", CommandObjectSP(
3831 new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
3832 LoadSubCommand(
3833 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
3834 interpreter)));
3835 LoadSubCommand(
3836 "insert",
3837 CommandObjectSP(
3838 new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
3839 LoadSubCommand(
3840 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
3841 interpreter)));
3842 LoadSubCommand(
3843 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
3844 interpreter)));
3845 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003846
Kate Stoneb9c1b512016-09-06 20:57:50 +00003847 ~CommandObjectTargetModulesImageSearchPaths() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003848};
3849
Greg Claytoneffe5c92011-05-03 22:09:39 +00003850#pragma mark CommandObjectTargetModules
3851
3852//-------------------------------------------------------------------------
3853// CommandObjectTargetModules
3854//-------------------------------------------------------------------------
3855
Kate Stoneb9c1b512016-09-06 20:57:50 +00003856class CommandObjectTargetModules : public CommandObjectMultiword {
Greg Claytoneffe5c92011-05-03 22:09:39 +00003857public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003858 //------------------------------------------------------------------
3859 // Constructors and Destructors
3860 //------------------------------------------------------------------
3861 CommandObjectTargetModules(CommandInterpreter &interpreter)
3862 : CommandObjectMultiword(interpreter, "target modules",
3863 "Commands for accessing information for one or "
3864 "more target modules.",
3865 "target modules <sub-command> ...") {
3866 LoadSubCommand(
3867 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
3868 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
3869 interpreter)));
3870 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
3871 interpreter)));
3872 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
3873 interpreter)));
3874 LoadSubCommand(
3875 "lookup",
3876 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
3877 LoadSubCommand(
3878 "search-paths",
3879 CommandObjectSP(
3880 new CommandObjectTargetModulesImageSearchPaths(interpreter)));
3881 LoadSubCommand(
3882 "show-unwind",
3883 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
3884 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00003885
Kate Stoneb9c1b512016-09-06 20:57:50 +00003886 ~CommandObjectTargetModules() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003887
Greg Claytoneffe5c92011-05-03 22:09:39 +00003888private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003889 //------------------------------------------------------------------
3890 // For CommandObjectTargetModules only
3891 //------------------------------------------------------------------
3892 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules);
Greg Claytoneffe5c92011-05-03 22:09:39 +00003893};
3894
Kate Stoneb9c1b512016-09-06 20:57:50 +00003895class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
Greg Claytone72dfb32012-02-24 01:59:29 +00003896public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003897 CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
3898 : CommandObjectParsed(
3899 interpreter, "target symbols add",
3900 "Add a debug symbol file to one of the target's current modules by "
3901 "specifying a path to a debug symbols file, or using the options "
3902 "to specify a module to download symbols for.",
3903 "target symbols add [<symfile>]", eCommandRequiresTarget),
Todd Fialae1cfbc72016-08-11 23:51:28 +00003904 m_option_group(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00003905 m_file_option(
3906 LLDB_OPT_SET_1, false, "shlib", 's',
3907 CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3908 "Fullpath or basename for module to find debug symbols for."),
3909 m_current_frame_option(
3910 LLDB_OPT_SET_2, false, "frame", 'F',
3911 "Locate the debug symbols the currently selected frame.", false,
3912 true)
Greg Claytonb5f0fea2012-09-27 22:26:11 +00003913
Kate Stoneb9c1b512016-09-06 20:57:50 +00003914 {
3915 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
3916 LLDB_OPT_SET_1);
3917 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
3918 m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
3919 LLDB_OPT_SET_2);
3920 m_option_group.Finalize();
3921 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003922
Kate Stoneb9c1b512016-09-06 20:57:50 +00003923 ~CommandObjectTargetSymbolsAdd() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003924
Kate Stoneb9c1b512016-09-06 20:57:50 +00003925 int HandleArgumentCompletion(Args &input, int &cursor_index,
3926 int &cursor_char_position,
3927 OptionElementVector &opt_element_vector,
3928 int match_start_point, int max_return_elements,
3929 bool &word_complete,
3930 StringList &matches) override {
3931 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
3932 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003933
Kate Stoneb9c1b512016-09-06 20:57:50 +00003934 CommandCompletions::InvokeCommonCompletionCallbacks(
3935 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
3936 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
3937 word_complete, matches);
3938 return matches.GetSize();
3939 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003940
Kate Stoneb9c1b512016-09-06 20:57:50 +00003941 Options *GetOptions() override { return &m_option_group; }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00003942
Jim Ingham5a988412012-06-08 21:56:10 +00003943protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003944 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
3945 CommandReturnObject &result) {
3946 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
3947 if (symbol_fspec) {
3948 char symfile_path[PATH_MAX];
3949 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003950
Kate Stoneb9c1b512016-09-06 20:57:50 +00003951 if (!module_spec.GetUUID().IsValid()) {
3952 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
3953 module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
3954 }
3955 // We now have a module that represents a symbol file
3956 // that can be used for a module that might exist in the
3957 // current target, so we need to find that module in the
3958 // target
3959 ModuleList matching_module_list;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003960
Kate Stoneb9c1b512016-09-06 20:57:50 +00003961 size_t num_matches = 0;
3962 // First extract all module specs from the symbol file
3963 lldb_private::ModuleSpecList symfile_module_specs;
3964 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
3965 0, 0, symfile_module_specs)) {
3966 // Now extract the module spec that matches the target architecture
3967 ModuleSpec target_arch_module_spec;
3968 ModuleSpec symfile_module_spec;
3969 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
3970 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
3971 symfile_module_spec)) {
3972 // See if it has a UUID?
3973 if (symfile_module_spec.GetUUID().IsValid()) {
3974 // It has a UUID, look for this UUID in the target modules
3975 ModuleSpec symfile_uuid_module_spec;
3976 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
3977 num_matches = target->GetImages().FindModules(
3978 symfile_uuid_module_spec, matching_module_list);
3979 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00003980 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003981
3982 if (num_matches == 0) {
3983 // No matches yet, iterate through the module specs to find a UUID
3984 // value that
3985 // we can match up to an image in our target
3986 const size_t num_symfile_module_specs =
3987 symfile_module_specs.GetSize();
3988 for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0;
3989 ++i) {
3990 if (symfile_module_specs.GetModuleSpecAtIndex(
3991 i, symfile_module_spec)) {
3992 if (symfile_module_spec.GetUUID().IsValid()) {
3993 // It has a UUID, look for this UUID in the target modules
3994 ModuleSpec symfile_uuid_module_spec;
3995 symfile_uuid_module_spec.GetUUID() =
3996 symfile_module_spec.GetUUID();
3997 num_matches = target->GetImages().FindModules(
3998 symfile_uuid_module_spec, matching_module_list);
3999 }
4000 }
4001 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00004002 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004003 }
4004
4005 // Just try to match up the file by basename if we have no matches at this
4006 // point
4007 if (num_matches == 0)
4008 num_matches =
4009 target->GetImages().FindModules(module_spec, matching_module_list);
4010
4011 while (num_matches == 0) {
4012 ConstString filename_no_extension(
4013 module_spec.GetFileSpec().GetFileNameStrippingExtension());
4014 // Empty string returned, lets bail
4015 if (!filename_no_extension)
4016 break;
4017
4018 // Check if there was no extension to strip and the basename is the same
4019 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4020 break;
4021
4022 // Replace basename with one less extension
4023 module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4024
4025 num_matches =
4026 target->GetImages().FindModules(module_spec, matching_module_list);
4027 }
4028
4029 if (num_matches > 1) {
4030 result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4031 "use the --uuid option to resolve the "
4032 "ambiguity.\n",
4033 symfile_path);
4034 } else if (num_matches == 1) {
4035 ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0));
4036
4037 // The module has not yet created its symbol vendor, we can just
4038 // give the existing target module the symfile path to use for
4039 // when it decides to create it!
4040 module_sp->SetSymbolFileFileSpec(symbol_fspec);
4041
4042 SymbolVendor *symbol_vendor =
4043 module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4044 if (symbol_vendor) {
4045 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4046
4047 if (symbol_file) {
4048 ObjectFile *object_file = symbol_file->GetObjectFile();
4049
4050 if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4051 // Provide feedback that the symfile has been successfully added.
4052 const FileSpec &module_fs = module_sp->GetFileSpec();
4053 result.AppendMessageWithFormat(
4054 "symbol file '%s' has been added to '%s'\n", symfile_path,
4055 module_fs.GetPath().c_str());
4056
4057 // Let clients know something changed in the module
4058 // if it is currently loaded
4059 ModuleList module_list;
4060 module_list.Append(module_sp);
4061 target->SymbolsDidLoad(module_list);
4062
4063 // Make sure we load any scripting resources that may be embedded
4064 // in the debug info files in case the platform supports that.
4065 Error error;
4066 StreamString feedback_stream;
4067 module_sp->LoadScriptingResourceInTarget(target, error,
4068 &feedback_stream);
4069 if (error.Fail() && error.AsCString())
4070 result.AppendWarningWithFormat(
4071 "unable to load scripting data for module %s - error "
4072 "reported was %s",
4073 module_sp->GetFileSpec()
4074 .GetFileNameStrippingExtension()
4075 .GetCString(),
4076 error.AsCString());
4077 else if (feedback_stream.GetSize())
4078 result.AppendWarningWithFormat("%s", feedback_stream.GetData());
4079
4080 flush = true;
4081 result.SetStatus(eReturnStatusSuccessFinishResult);
4082 return true;
4083 }
4084 }
4085 }
4086 // Clear the symbol file spec if anything went wrong
4087 module_sp->SetSymbolFileFileSpec(FileSpec());
4088 }
4089
4090 if (module_spec.GetUUID().IsValid()) {
4091 StreamString ss_symfile_uuid;
4092 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4093 result.AppendErrorWithFormat(
4094 "symbol file '%s' (%s) does not match any existing module%s\n",
4095 symfile_path, ss_symfile_uuid.GetData(),
4096 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4097 ? "\n please specify the full path to the symbol file"
4098 : "");
4099 } else {
4100 result.AppendErrorWithFormat(
4101 "symbol file '%s' does not match any existing module%s\n",
4102 symfile_path,
4103 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4104 ? "\n please specify the full path to the symbol file"
4105 : "");
4106 }
4107 } else {
4108 result.AppendError(
4109 "one or more executable image paths must be specified");
4110 }
4111 result.SetStatus(eReturnStatusFailed);
4112 return false;
4113 }
4114
4115 bool DoExecute(Args &args, CommandReturnObject &result) override {
4116 Target *target = m_exe_ctx.GetTargetPtr();
4117 result.SetStatus(eReturnStatusFailed);
4118 bool flush = false;
4119 ModuleSpec module_spec;
4120 const bool uuid_option_set =
4121 m_uuid_option_group.GetOptionValue().OptionWasSet();
4122 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4123 const bool frame_option_set =
4124 m_current_frame_option.GetOptionValue().OptionWasSet();
4125 const size_t argc = args.GetArgumentCount();
4126
4127 if (argc == 0) {
4128 if (uuid_option_set || file_option_set || frame_option_set) {
4129 bool success = false;
4130 bool error_set = false;
4131 if (frame_option_set) {
4132 Process *process = m_exe_ctx.GetProcessPtr();
4133 if (process) {
4134 const StateType process_state = process->GetState();
4135 if (StateIsStoppedState(process_state, true)) {
4136 StackFrame *frame = m_exe_ctx.GetFramePtr();
4137 if (frame) {
4138 ModuleSP frame_module_sp(
4139 frame->GetSymbolContext(eSymbolContextModule).module_sp);
4140 if (frame_module_sp) {
4141 if (frame_module_sp->GetPlatformFileSpec().Exists()) {
4142 module_spec.GetArchitecture() =
4143 frame_module_sp->GetArchitecture();
4144 module_spec.GetFileSpec() =
4145 frame_module_sp->GetPlatformFileSpec();
4146 }
4147 module_spec.GetUUID() = frame_module_sp->GetUUID();
4148 success = module_spec.GetUUID().IsValid() ||
4149 module_spec.GetFileSpec();
4150 } else {
4151 result.AppendError("frame has no module");
4152 error_set = true;
4153 }
4154 } else {
4155 result.AppendError("invalid current frame");
4156 error_set = true;
4157 }
4158 } else {
4159 result.AppendErrorWithFormat("process is not stopped: %s",
4160 StateAsCString(process_state));
4161 error_set = true;
4162 }
4163 } else {
4164 result.AppendError(
4165 "a process must exist in order to use the --frame option");
4166 error_set = true;
4167 }
4168 } else {
4169 if (uuid_option_set) {
4170 module_spec.GetUUID() =
4171 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4172 success |= module_spec.GetUUID().IsValid();
4173 } else if (file_option_set) {
4174 module_spec.GetFileSpec() =
4175 m_file_option.GetOptionValue().GetCurrentValue();
4176 ModuleSP module_sp(
4177 target->GetImages().FindFirstModule(module_spec));
4178 if (module_sp) {
4179 module_spec.GetFileSpec() = module_sp->GetFileSpec();
4180 module_spec.GetPlatformFileSpec() =
4181 module_sp->GetPlatformFileSpec();
4182 module_spec.GetUUID() = module_sp->GetUUID();
4183 module_spec.GetArchitecture() = module_sp->GetArchitecture();
4184 } else {
4185 module_spec.GetArchitecture() = target->GetArchitecture();
4186 }
4187 success |= module_spec.GetUUID().IsValid() ||
4188 module_spec.GetFileSpec().Exists();
4189 }
4190 }
4191
4192 if (success) {
4193 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4194 if (module_spec.GetSymbolFileSpec())
4195 success = AddModuleSymbols(target, module_spec, flush, result);
4196 }
4197 }
4198
4199 if (!success && !error_set) {
4200 StreamString error_strm;
4201 if (uuid_option_set) {
4202 error_strm.PutCString("unable to find debug symbols for UUID ");
4203 module_spec.GetUUID().Dump(&error_strm);
4204 } else if (file_option_set) {
4205 error_strm.PutCString(
4206 "unable to find debug symbols for the executable file ");
4207 error_strm << module_spec.GetFileSpec();
4208 } else if (frame_option_set) {
4209 error_strm.PutCString(
4210 "unable to find debug symbols for the current frame");
4211 }
4212 result.AppendError(error_strm.GetData());
4213 }
4214 } else {
4215 result.AppendError("one or more symbol file paths must be specified, "
4216 "or options must be specified");
4217 }
4218 } else {
4219 if (uuid_option_set) {
4220 result.AppendError("specify either one or more paths to symbol files "
4221 "or use the --uuid option without arguments");
4222 } else if (file_option_set) {
4223 result.AppendError("specify either one or more paths to symbol files "
4224 "or use the --file option without arguments");
4225 } else if (frame_option_set) {
4226 result.AppendError("specify either one or more paths to symbol files "
4227 "or use the --frame option without arguments");
4228 } else {
4229 PlatformSP platform_sp(target->GetPlatform());
4230
Zachary Turner97d2c402016-10-05 23:40:23 +00004231 for (auto &entry : args.entries()) {
4232 if (!entry.ref.empty()) {
4233 module_spec.GetSymbolFileSpec().SetFile(entry.ref, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004234 if (platform_sp) {
4235 FileSpec symfile_spec;
4236 if (platform_sp
4237 ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4238 .Success())
4239 module_spec.GetSymbolFileSpec() = symfile_spec;
4240 }
4241
4242 ArchSpec arch;
4243 bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
4244
4245 if (symfile_exists) {
4246 if (!AddModuleSymbols(target, module_spec, flush, result))
4247 break;
4248 } else {
Zachary Turner97d2c402016-10-05 23:40:23 +00004249 std::string resolved_symfile_path =
4250 module_spec.GetSymbolFileSpec().GetPath();
4251 if (resolved_symfile_path != entry.ref) {
4252 result.AppendErrorWithFormat(
4253 "invalid module path '%s' with resolved path '%s'\n",
4254 entry.c_str(), resolved_symfile_path.c_str());
4255 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004256 }
4257 result.AppendErrorWithFormat("invalid module path '%s'\n",
Zachary Turner97d2c402016-10-05 23:40:23 +00004258 entry.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004259 break;
4260 }
4261 }
4262 }
4263 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00004264 }
4265
Kate Stoneb9c1b512016-09-06 20:57:50 +00004266 if (flush) {
4267 Process *process = m_exe_ctx.GetProcessPtr();
4268 if (process)
4269 process->Flush();
Greg Claytone72dfb32012-02-24 01:59:29 +00004270 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004271 return result.Succeeded();
4272 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004273
Kate Stoneb9c1b512016-09-06 20:57:50 +00004274 OptionGroupOptions m_option_group;
4275 OptionGroupUUID m_uuid_option_group;
4276 OptionGroupFile m_file_option;
4277 OptionGroupBoolean m_current_frame_option;
Greg Claytone72dfb32012-02-24 01:59:29 +00004278};
4279
Greg Claytone72dfb32012-02-24 01:59:29 +00004280#pragma mark CommandObjectTargetSymbols
4281
4282//-------------------------------------------------------------------------
4283// CommandObjectTargetSymbols
4284//-------------------------------------------------------------------------
4285
Kate Stoneb9c1b512016-09-06 20:57:50 +00004286class CommandObjectTargetSymbols : public CommandObjectMultiword {
Greg Claytone72dfb32012-02-24 01:59:29 +00004287public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004288 //------------------------------------------------------------------
4289 // Constructors and Destructors
4290 //------------------------------------------------------------------
4291 CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4292 : CommandObjectMultiword(
4293 interpreter, "target symbols",
4294 "Commands for adding and managing debug symbol files.",
4295 "target symbols <sub-command> ...") {
4296 LoadSubCommand(
4297 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4298 }
Bruce Mitchener13d21e92015-10-07 16:56:17 +00004299
Kate Stoneb9c1b512016-09-06 20:57:50 +00004300 ~CommandObjectTargetSymbols() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004301
Greg Claytone72dfb32012-02-24 01:59:29 +00004302private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004303 //------------------------------------------------------------------
4304 // For CommandObjectTargetModules only
4305 //------------------------------------------------------------------
4306 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols);
Greg Claytone72dfb32012-02-24 01:59:29 +00004307};
4308
Jim Ingham9575d842011-03-11 03:53:59 +00004309#pragma mark CommandObjectTargetStopHookAdd
4310
4311//-------------------------------------------------------------------------
4312// CommandObjectTargetStopHookAdd
4313//-------------------------------------------------------------------------
4314
Zachary Turner1f0f5b52016-09-22 20:22:55 +00004315static OptionDefinition g_target_stop_hook_add_options[] = {
4316 // clang-format off
4317 { 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." },
4318 { 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." },
4319 { 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." },
4320 { 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." },
4321 { 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." },
4322 { 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." },
4323 { 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." },
4324 { 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." },
4325 { 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." },
4326 { 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." },
4327 { 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." },
4328 // clang-format on
4329};
4330
Kate Stoneb9c1b512016-09-06 20:57:50 +00004331class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4332 public IOHandlerDelegateMultiline {
Jim Ingham9575d842011-03-11 03:53:59 +00004333public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004334 class CommandOptions : public Options {
4335 public:
4336 CommandOptions()
4337 : Options(), m_line_start(0), m_line_end(UINT_MAX),
4338 m_func_name_type_mask(eFunctionNameTypeAuto),
4339 m_sym_ctx_specified(false), m_thread_specified(false),
4340 m_use_one_liner(false), m_one_liner() {}
4341
4342 ~CommandOptions() override = default;
4343
Zachary Turner1f0f5b52016-09-22 20:22:55 +00004344 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00004345 return llvm::makeArrayRef(g_target_stop_hook_add_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00004346 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004347
4348 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
4349 ExecutionContext *execution_context) override {
4350 Error error;
4351 const int short_option = m_getopt_table[option_idx].val;
4352 bool success;
4353
4354 switch (short_option) {
4355 case 'c':
4356 m_class_name = option_arg;
4357 m_sym_ctx_specified = true;
4358 break;
4359
4360 case 'e':
4361 m_line_end = StringConvert::ToUInt32(option_arg, UINT_MAX, 0, &success);
4362 if (!success) {
4363 error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4364 option_arg);
4365 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004366 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004367 m_sym_ctx_specified = true;
4368 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004369
Kate Stoneb9c1b512016-09-06 20:57:50 +00004370 case 'l':
4371 m_line_start = StringConvert::ToUInt32(option_arg, 0, 0, &success);
4372 if (!success) {
4373 error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4374 option_arg);
4375 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004376 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004377 m_sym_ctx_specified = true;
4378 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004379
Kate Stoneb9c1b512016-09-06 20:57:50 +00004380 case 'i':
4381 m_no_inlines = true;
4382 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004383
Kate Stoneb9c1b512016-09-06 20:57:50 +00004384 case 'n':
4385 m_function_name = option_arg;
4386 m_func_name_type_mask |= eFunctionNameTypeAuto;
4387 m_sym_ctx_specified = true;
4388 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004389
Kate Stoneb9c1b512016-09-06 20:57:50 +00004390 case 'f':
4391 m_file_name = option_arg;
4392 m_sym_ctx_specified = true;
4393 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004394
Kate Stoneb9c1b512016-09-06 20:57:50 +00004395 case 's':
4396 m_module_name = option_arg;
4397 m_sym_ctx_specified = true;
4398 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004399
Kate Stoneb9c1b512016-09-06 20:57:50 +00004400 case 't':
4401 m_thread_id =
4402 StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
4403 if (m_thread_id == LLDB_INVALID_THREAD_ID)
4404 error.SetErrorStringWithFormat("invalid thread id string '%s'",
4405 option_arg);
4406 m_thread_specified = true;
4407 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004408
Kate Stoneb9c1b512016-09-06 20:57:50 +00004409 case 'T':
4410 m_thread_name = option_arg;
4411 m_thread_specified = true;
4412 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004413
Kate Stoneb9c1b512016-09-06 20:57:50 +00004414 case 'q':
4415 m_queue_name = option_arg;
4416 m_thread_specified = true;
4417 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004418
Kate Stoneb9c1b512016-09-06 20:57:50 +00004419 case 'x':
4420 m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
4421 if (m_thread_id == UINT32_MAX)
4422 error.SetErrorStringWithFormat("invalid thread index string '%s'",
4423 option_arg);
4424 m_thread_specified = true;
4425 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004426
Kate Stoneb9c1b512016-09-06 20:57:50 +00004427 case 'o':
4428 m_use_one_liner = true;
4429 m_one_liner = option_arg;
4430 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004431
Kate Stoneb9c1b512016-09-06 20:57:50 +00004432 default:
4433 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
4434 break;
4435 }
4436 return error;
Jim Ingham9575d842011-03-11 03:53:59 +00004437 }
4438
Kate Stoneb9c1b512016-09-06 20:57:50 +00004439 void OptionParsingStarting(ExecutionContext *execution_context) override {
4440 m_class_name.clear();
4441 m_function_name.clear();
4442 m_line_start = 0;
4443 m_line_end = UINT_MAX;
4444 m_file_name.clear();
4445 m_module_name.clear();
4446 m_func_name_type_mask = eFunctionNameTypeAuto;
4447 m_thread_id = LLDB_INVALID_THREAD_ID;
4448 m_thread_index = UINT32_MAX;
4449 m_thread_name.clear();
4450 m_queue_name.clear();
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004451
Kate Stoneb9c1b512016-09-06 20:57:50 +00004452 m_no_inlines = false;
4453 m_sym_ctx_specified = false;
4454 m_thread_specified = false;
4455
4456 m_use_one_liner = false;
4457 m_one_liner.clear();
Jim Ingham9575d842011-03-11 03:53:59 +00004458 }
4459
Kate Stoneb9c1b512016-09-06 20:57:50 +00004460 std::string m_class_name;
4461 std::string m_function_name;
4462 uint32_t m_line_start;
4463 uint32_t m_line_end;
4464 std::string m_file_name;
4465 std::string m_module_name;
4466 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
4467 lldb::tid_t m_thread_id;
4468 uint32_t m_thread_index;
4469 std::string m_thread_name;
4470 std::string m_queue_name;
4471 bool m_sym_ctx_specified;
4472 bool m_no_inlines;
4473 bool m_thread_specified;
4474 // Instance variables to hold the values for one_liner options.
4475 bool m_use_one_liner;
4476 std::string m_one_liner;
4477 };
4478
4479 CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4480 : CommandObjectParsed(interpreter, "target stop-hook add",
4481 "Add a hook to be executed when the target stops.",
4482 "target stop-hook add"),
4483 IOHandlerDelegateMultiline("DONE",
4484 IOHandlerDelegate::Completion::LLDBCommand),
4485 m_options() {}
4486
4487 ~CommandObjectTargetStopHookAdd() override = default;
4488
4489 Options *GetOptions() override { return &m_options; }
4490
Jim Ingham5a988412012-06-08 21:56:10 +00004491protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004492 void IOHandlerActivated(IOHandler &io_handler) override {
4493 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4494 if (output_sp) {
4495 output_sp->PutCString(
4496 "Enter your stop hook command(s). Type 'DONE' to end.\n");
4497 output_sp->Flush();
Greg Clayton44d93782014-01-27 23:43:24 +00004498 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004499 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004500
Kate Stoneb9c1b512016-09-06 20:57:50 +00004501 void IOHandlerInputComplete(IOHandler &io_handler,
4502 std::string &line) override {
4503 if (m_stop_hook_sp) {
4504 if (line.empty()) {
4505 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
4506 if (error_sp) {
4507 error_sp->Printf("error: stop hook #%" PRIu64
4508 " aborted, no commands.\n",
4509 m_stop_hook_sp->GetID());
4510 error_sp->Flush();
Greg Clayton44d93782014-01-27 23:43:24 +00004511 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004512 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Jim Ingham9575d842011-03-11 03:53:59 +00004513 if (target)
Kate Stoneb9c1b512016-09-06 20:57:50 +00004514 target->RemoveStopHookByID(m_stop_hook_sp->GetID());
4515 } else {
4516 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
4517 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4518 if (output_sp) {
4519 output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4520 m_stop_hook_sp->GetID());
4521 output_sp->Flush();
Jim Ingham9575d842011-03-11 03:53:59 +00004522 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004523 }
4524 m_stop_hook_sp.reset();
Jim Ingham9575d842011-03-11 03:53:59 +00004525 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004526 io_handler.SetIsDone(true);
4527 }
4528
4529 bool DoExecute(Args &command, CommandReturnObject &result) override {
4530 m_stop_hook_sp.reset();
4531
4532 Target *target = GetSelectedOrDummyTarget();
4533 if (target) {
4534 Target::StopHookSP new_hook_sp = target->CreateStopHook();
4535
4536 // First step, make the specifier.
4537 std::unique_ptr<SymbolContextSpecifier> specifier_ap;
4538 if (m_options.m_sym_ctx_specified) {
4539 specifier_ap.reset(new SymbolContextSpecifier(
4540 m_interpreter.GetDebugger().GetSelectedTarget()));
4541
4542 if (!m_options.m_module_name.empty()) {
4543 specifier_ap->AddSpecification(
4544 m_options.m_module_name.c_str(),
4545 SymbolContextSpecifier::eModuleSpecified);
4546 }
4547
4548 if (!m_options.m_class_name.empty()) {
4549 specifier_ap->AddSpecification(
4550 m_options.m_class_name.c_str(),
4551 SymbolContextSpecifier::eClassOrNamespaceSpecified);
4552 }
4553
4554 if (!m_options.m_file_name.empty()) {
4555 specifier_ap->AddSpecification(
4556 m_options.m_file_name.c_str(),
4557 SymbolContextSpecifier::eFileSpecified);
4558 }
4559
4560 if (m_options.m_line_start != 0) {
4561 specifier_ap->AddLineSpecification(
4562 m_options.m_line_start,
4563 SymbolContextSpecifier::eLineStartSpecified);
4564 }
4565
4566 if (m_options.m_line_end != UINT_MAX) {
4567 specifier_ap->AddLineSpecification(
4568 m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4569 }
4570
4571 if (!m_options.m_function_name.empty()) {
4572 specifier_ap->AddSpecification(
4573 m_options.m_function_name.c_str(),
4574 SymbolContextSpecifier::eFunctionSpecified);
4575 }
4576 }
4577
4578 if (specifier_ap)
4579 new_hook_sp->SetSpecifier(specifier_ap.release());
4580
4581 // Next see if any of the thread options have been entered:
4582
4583 if (m_options.m_thread_specified) {
4584 ThreadSpec *thread_spec = new ThreadSpec();
4585
4586 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4587 thread_spec->SetTID(m_options.m_thread_id);
4588 }
4589
4590 if (m_options.m_thread_index != UINT32_MAX)
4591 thread_spec->SetIndex(m_options.m_thread_index);
4592
4593 if (!m_options.m_thread_name.empty())
4594 thread_spec->SetName(m_options.m_thread_name.c_str());
4595
4596 if (!m_options.m_queue_name.empty())
4597 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4598
4599 new_hook_sp->SetThreadSpecifier(thread_spec);
4600 }
4601 if (m_options.m_use_one_liner) {
4602 // Use one-liner.
4603 new_hook_sp->GetCommandPointer()->AppendString(
4604 m_options.m_one_liner.c_str());
4605 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4606 new_hook_sp->GetID());
4607 } else {
4608 m_stop_hook_sp = new_hook_sp;
4609 m_interpreter.GetLLDBCommandsFromIOHandler(
4610 "> ", // Prompt
4611 *this, // IOHandlerDelegate
4612 true, // Run IOHandler in async mode
4613 nullptr); // Baton for the "io_handler" that will be passed back
4614 // into our IOHandlerDelegate functions
4615 }
4616 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4617 } else {
4618 result.AppendError("invalid target\n");
4619 result.SetStatus(eReturnStatusFailed);
4620 }
4621
4622 return result.Succeeded();
4623 }
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004624
Jim Ingham9575d842011-03-11 03:53:59 +00004625private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004626 CommandOptions m_options;
4627 Target::StopHookSP m_stop_hook_sp;
Jim Ingham9575d842011-03-11 03:53:59 +00004628};
4629
Jim Ingham9575d842011-03-11 03:53:59 +00004630#pragma mark CommandObjectTargetStopHookDelete
4631
4632//-------------------------------------------------------------------------
4633// CommandObjectTargetStopHookDelete
4634//-------------------------------------------------------------------------
4635
Kate Stoneb9c1b512016-09-06 20:57:50 +00004636class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004637public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004638 CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4639 : CommandObjectParsed(interpreter, "target stop-hook delete",
4640 "Delete a stop-hook.",
4641 "target stop-hook delete [<idx>]") {}
Jim Ingham9575d842011-03-11 03:53:59 +00004642
Kate Stoneb9c1b512016-09-06 20:57:50 +00004643 ~CommandObjectTargetStopHookDelete() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004644
Jim Ingham5a988412012-06-08 21:56:10 +00004645protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004646 bool DoExecute(Args &command, CommandReturnObject &result) override {
4647 Target *target = GetSelectedOrDummyTarget();
4648 if (target) {
4649 // FIXME: see if we can use the breakpoint id style parser?
4650 size_t num_args = command.GetArgumentCount();
4651 if (num_args == 0) {
4652 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4653 result.SetStatus(eReturnStatusFailed);
4654 return false;
4655 } else {
4656 target->RemoveAllStopHooks();
Jim Ingham9575d842011-03-11 03:53:59 +00004657 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004658 } else {
4659 bool success;
4660 for (size_t i = 0; i < num_args; i++) {
4661 lldb::user_id_t user_id = StringConvert::ToUInt32(
4662 command.GetArgumentAtIndex(i), 0, 0, &success);
4663 if (!success) {
4664 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4665 command.GetArgumentAtIndex(i));
4666 result.SetStatus(eReturnStatusFailed);
4667 return false;
4668 }
4669 success = target->RemoveStopHookByID(user_id);
4670 if (!success) {
4671 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4672 command.GetArgumentAtIndex(i));
4673 result.SetStatus(eReturnStatusFailed);
4674 return false;
4675 }
Jim Ingham9575d842011-03-11 03:53:59 +00004676 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004677 }
4678 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4679 } else {
4680 result.AppendError("invalid target\n");
4681 result.SetStatus(eReturnStatusFailed);
Jim Ingham9575d842011-03-11 03:53:59 +00004682 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004683
4684 return result.Succeeded();
4685 }
Jim Ingham9575d842011-03-11 03:53:59 +00004686};
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004687
Jim Ingham9575d842011-03-11 03:53:59 +00004688#pragma mark CommandObjectTargetStopHookEnableDisable
4689
4690//-------------------------------------------------------------------------
4691// CommandObjectTargetStopHookEnableDisable
4692//-------------------------------------------------------------------------
4693
Kate Stoneb9c1b512016-09-06 20:57:50 +00004694class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004695public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004696 CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4697 bool enable, const char *name,
4698 const char *help, const char *syntax)
4699 : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4700 }
Jim Ingham9575d842011-03-11 03:53:59 +00004701
Kate Stoneb9c1b512016-09-06 20:57:50 +00004702 ~CommandObjectTargetStopHookEnableDisable() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004703
Jim Ingham5a988412012-06-08 21:56:10 +00004704protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004705 bool DoExecute(Args &command, CommandReturnObject &result) override {
4706 Target *target = GetSelectedOrDummyTarget();
4707 if (target) {
4708 // FIXME: see if we can use the breakpoint id style parser?
4709 size_t num_args = command.GetArgumentCount();
4710 bool success;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004711
Kate Stoneb9c1b512016-09-06 20:57:50 +00004712 if (num_args == 0) {
4713 target->SetAllStopHooksActiveState(m_enable);
4714 } else {
4715 for (size_t i = 0; i < num_args; i++) {
4716 lldb::user_id_t user_id = StringConvert::ToUInt32(
4717 command.GetArgumentAtIndex(i), 0, 0, &success);
4718 if (!success) {
4719 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4720 command.GetArgumentAtIndex(i));
4721 result.SetStatus(eReturnStatusFailed);
4722 return false;
4723 }
4724 success = target->SetStopHookActiveStateByID(user_id, m_enable);
4725 if (!success) {
4726 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4727 command.GetArgumentAtIndex(i));
4728 result.SetStatus(eReturnStatusFailed);
4729 return false;
4730 }
Jim Ingham9575d842011-03-11 03:53:59 +00004731 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004732 }
4733 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4734 } else {
4735 result.AppendError("invalid target\n");
4736 result.SetStatus(eReturnStatusFailed);
Jim Ingham9575d842011-03-11 03:53:59 +00004737 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004738 return result.Succeeded();
4739 }
4740
Jim Ingham9575d842011-03-11 03:53:59 +00004741private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004742 bool m_enable;
Jim Ingham9575d842011-03-11 03:53:59 +00004743};
4744
4745#pragma mark CommandObjectTargetStopHookList
4746
4747//-------------------------------------------------------------------------
4748// CommandObjectTargetStopHookList
4749//-------------------------------------------------------------------------
4750
Kate Stoneb9c1b512016-09-06 20:57:50 +00004751class CommandObjectTargetStopHookList : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004752public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004753 CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4754 : CommandObjectParsed(interpreter, "target stop-hook list",
4755 "List all stop-hooks.",
4756 "target stop-hook list [<type>]") {}
Jim Ingham9575d842011-03-11 03:53:59 +00004757
Kate Stoneb9c1b512016-09-06 20:57:50 +00004758 ~CommandObjectTargetStopHookList() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004759
Jim Ingham5a988412012-06-08 21:56:10 +00004760protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004761 bool DoExecute(Args &command, CommandReturnObject &result) override {
4762 Target *target = GetSelectedOrDummyTarget();
4763 if (!target) {
4764 result.AppendError("invalid target\n");
4765 result.SetStatus(eReturnStatusFailed);
4766 return result.Succeeded();
Jim Ingham9575d842011-03-11 03:53:59 +00004767 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004768
4769 size_t num_hooks = target->GetNumStopHooks();
4770 if (num_hooks == 0) {
4771 result.GetOutputStream().PutCString("No stop hooks.\n");
4772 } else {
4773 for (size_t i = 0; i < num_hooks; i++) {
4774 Target::StopHookSP this_hook = target->GetStopHookAtIndex(i);
4775 if (i > 0)
4776 result.GetOutputStream().PutCString("\n");
4777 this_hook->GetDescription(&(result.GetOutputStream()),
4778 eDescriptionLevelFull);
4779 }
4780 }
4781 result.SetStatus(eReturnStatusSuccessFinishResult);
4782 return result.Succeeded();
4783 }
Jim Ingham9575d842011-03-11 03:53:59 +00004784};
4785
4786#pragma mark CommandObjectMultiwordTargetStopHooks
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004787
Jim Ingham9575d842011-03-11 03:53:59 +00004788//-------------------------------------------------------------------------
4789// CommandObjectMultiwordTargetStopHooks
4790//-------------------------------------------------------------------------
4791
Kate Stoneb9c1b512016-09-06 20:57:50 +00004792class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
Jim Ingham9575d842011-03-11 03:53:59 +00004793public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004794 CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4795 : CommandObjectMultiword(
4796 interpreter, "target stop-hook",
4797 "Commands for operating on debugger target stop-hooks.",
4798 "target stop-hook <subcommand> [<subcommand-options>]") {
4799 LoadSubCommand("add", CommandObjectSP(
4800 new CommandObjectTargetStopHookAdd(interpreter)));
4801 LoadSubCommand(
4802 "delete",
4803 CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
4804 LoadSubCommand("disable",
4805 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4806 interpreter, false, "target stop-hook disable [<id>]",
4807 "Disable a stop-hook.", "target stop-hook disable")));
4808 LoadSubCommand("enable",
4809 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4810 interpreter, true, "target stop-hook enable [<id>]",
4811 "Enable a stop-hook.", "target stop-hook enable")));
4812 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
4813 interpreter)));
4814 }
Jim Ingham9575d842011-03-11 03:53:59 +00004815
Kate Stoneb9c1b512016-09-06 20:57:50 +00004816 ~CommandObjectMultiwordTargetStopHooks() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004817};
4818
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004819#pragma mark CommandObjectMultiwordTarget
4820
4821//-------------------------------------------------------------------------
4822// CommandObjectMultiwordTarget
4823//-------------------------------------------------------------------------
4824
Kate Stoneb9c1b512016-09-06 20:57:50 +00004825CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
4826 CommandInterpreter &interpreter)
4827 : CommandObjectMultiword(interpreter, "target",
4828 "Commands for operating on debugger targets.",
4829 "target <subcommand> [<subcommand-options>]") {
4830 LoadSubCommand("create",
4831 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
4832 LoadSubCommand("delete",
4833 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
4834 LoadSubCommand("list",
4835 CommandObjectSP(new CommandObjectTargetList(interpreter)));
4836 LoadSubCommand("select",
4837 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
4838 LoadSubCommand(
4839 "stop-hook",
4840 CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
4841 LoadSubCommand("modules",
4842 CommandObjectSP(new CommandObjectTargetModules(interpreter)));
4843 LoadSubCommand("symbols",
4844 CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
4845 LoadSubCommand("variable",
4846 CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004847}
4848
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004849CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;