blob: 61e9e9bcd940ae276d50429b976f2ae559edd4c0 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectTarget.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000013#include "lldb/Core/Debugger.h"
Greg Clayton44d93782014-01-27 23:43:24 +000014#include "lldb/Core/IOHandler.h"
Greg Clayton1f746072012-08-29 21:13:06 +000015#include "lldb/Core/Module.h"
16#include "lldb/Core/ModuleSpec.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000017#include "lldb/Core/Section.h"
Greg Clayton7260f622011-04-18 08:33:37 +000018#include "lldb/Core/State.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Core/Timer.h"
Greg Clayton644247c2011-07-07 01:59:51 +000020#include "lldb/Core/ValueObjectVariable.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000021#include "lldb/DataFormatters/ValueObjectPrinter.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000022#include "lldb/Host/StringConvert.h"
Greg Claytonc8f814d2012-09-27 03:13:55 +000023#include "lldb/Host/Symbols.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000024#include "lldb/Interpreter/Args.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Interpreter/CommandInterpreter.h"
26#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton7260f622011-04-18 08:33:37 +000027#include "lldb/Interpreter/OptionGroupArchitecture.h"
Greg Claytonaa149cb2011-08-11 02:48:45 +000028#include "lldb/Interpreter/OptionGroupBoolean.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000029#include "lldb/Interpreter/OptionGroupFile.h"
Greg Clayton1deb7962011-10-25 06:44:01 +000030#include "lldb/Interpreter/OptionGroupFormat.h"
Greg Clayton7260f622011-04-18 08:33:37 +000031#include "lldb/Interpreter/OptionGroupPlatform.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000032#include "lldb/Interpreter/OptionGroupString.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000033#include "lldb/Interpreter/OptionGroupUInt64.h"
34#include "lldb/Interpreter/OptionGroupUUID.h"
Greg Clayton644247c2011-07-07 01:59:51 +000035#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000036#include "lldb/Interpreter/OptionGroupVariable.h"
37#include "lldb/Interpreter/Options.h"
Greg Clayton1f746072012-08-29 21:13:06 +000038#include "lldb/Symbol/CompileUnit.h"
Jason Molenda380241a2012-07-12 00:20:07 +000039#include "lldb/Symbol/FuncUnwinders.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000040#include "lldb/Symbol/LineTable.h"
41#include "lldb/Symbol/ObjectFile.h"
42#include "lldb/Symbol/SymbolFile.h"
43#include "lldb/Symbol/SymbolVendor.h"
Jason Molenda380241a2012-07-12 00:20:07 +000044#include "lldb/Symbol/UnwindPlan.h"
Greg Clayton644247c2011-07-07 01:59:51 +000045#include "lldb/Symbol/VariableList.h"
Zachary Turner32abc6e2015-03-03 19:23:09 +000046#include "lldb/Target/ABI.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047#include "lldb/Target/Process.h"
Greg Claytond5944cd2013-12-06 01:12:00 +000048#include "lldb/Target/SectionLoadList.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000049#include "lldb/Target/StackFrame.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050#include "lldb/Target/Thread.h"
Jim Ingham9575d842011-03-11 03:53:59 +000051#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052
Pavel Labath7e2cfbf2016-11-09 09:59:18 +000053// C Includes
54// C++ Includes
55#include <cerrno>
56
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057using namespace lldb;
58using namespace lldb_private;
59
Kate Stoneb9c1b512016-09-06 20:57:50 +000060static void DumpTargetInfo(uint32_t target_idx, Target *target,
61 const char *prefix_cstr,
62 bool show_stopped_process_status, Stream &strm) {
63 const ArchSpec &target_arch = target->GetArchitecture();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000064
Kate Stoneb9c1b512016-09-06 20:57:50 +000065 Module *exe_module = target->GetExecutableModulePointer();
66 char exe_path[PATH_MAX];
67 bool exe_valid = false;
68 if (exe_module)
69 exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000070
Kate Stoneb9c1b512016-09-06 20:57:50 +000071 if (!exe_valid)
72 ::strcpy(exe_path, "<none>");
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000073
Kate Stoneb9c1b512016-09-06 20:57:50 +000074 strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
75 exe_path);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000076
Kate Stoneb9c1b512016-09-06 20:57:50 +000077 uint32_t properties = 0;
78 if (target_arch.IsValid()) {
79 strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
80 target_arch.DumpTriple(strm);
81 properties++;
82 }
83 PlatformSP platform_sp(target->GetPlatform());
84 if (platform_sp)
85 strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ",
86 platform_sp->GetName().GetCString());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000087
Kate Stoneb9c1b512016-09-06 20:57:50 +000088 ProcessSP process_sp(target->GetProcessSP());
89 bool show_process_status = false;
90 if (process_sp) {
91 lldb::pid_t pid = process_sp->GetID();
92 StateType state = process_sp->GetState();
93 if (show_stopped_process_status)
94 show_process_status = StateIsStoppedState(state, true);
95 const char *state_cstr = StateAsCString(state);
96 if (pid != LLDB_INVALID_PROCESS_ID)
97 strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
98 strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
99 }
100 if (properties > 0)
101 strm.PutCString(" )\n");
102 else
103 strm.EOL();
104 if (show_process_status) {
105 const bool only_threads_with_stop_reason = true;
106 const uint32_t start_frame = 0;
107 const uint32_t num_frames = 1;
108 const uint32_t num_frames_with_source = 1;
Jim Ingham6a9767c2016-11-08 20:36:40 +0000109 const bool stop_format = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000110 process_sp->GetStatus(strm);
111 process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
112 start_frame, num_frames,
Jim Ingham6a9767c2016-11-08 20:36:40 +0000113 num_frames_with_source, stop_format);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000114 }
Greg Clayton7260f622011-04-18 08:33:37 +0000115}
116
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117static uint32_t DumpTargetList(TargetList &target_list,
118 bool show_stopped_process_status, Stream &strm) {
119 const uint32_t num_targets = target_list.GetNumTargets();
120 if (num_targets) {
121 TargetSP selected_target_sp(target_list.GetSelectedTarget());
122 strm.PutCString("Current targets:\n");
123 for (uint32_t i = 0; i < num_targets; ++i) {
124 TargetSP target_sp(target_list.GetTargetAtIndex(i));
125 if (target_sp) {
126 bool is_selected = target_sp.get() == selected_target_sp.get();
127 DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
128 show_stopped_process_status, strm);
129 }
Greg Clayton7260f622011-04-18 08:33:37 +0000130 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131 }
132 return num_targets;
Greg Clayton7260f622011-04-18 08:33:37 +0000133}
Eugene Zelenkof13e6522016-02-25 19:02:39 +0000134
Pavel Labath8cb1cd92016-11-16 10:54:22 +0000135// TODO: Remove this once llvm can pretty-print time points
136static void DumpTimePoint(llvm::sys::TimePoint<> tp, Stream &s, uint32_t width) {
137#ifndef LLDB_DISABLE_POSIX
138 char time_buf[32];
139 time_t time = llvm::sys::toTimeT(tp);
140 char *time_cstr = ::ctime_r(&time, time_buf);
141 if (time_cstr) {
142 char *newline = ::strpbrk(time_cstr, "\n\r");
143 if (newline)
144 *newline = '\0';
145 if (width > 0)
146 s.Printf("%-*s", width, time_cstr);
147 else
148 s.PutCString(time_cstr);
149 } else if (width > 0)
150 s.Printf("%-*s", width, "");
151#endif
152}
153
Greg Clayton7260f622011-04-18 08:33:37 +0000154#pragma mark CommandObjectTargetCreate
155
156//-------------------------------------------------------------------------
157// "target create"
158//-------------------------------------------------------------------------
159
Kate Stoneb9c1b512016-09-06 20:57:50 +0000160class CommandObjectTargetCreate : public CommandObjectParsed {
Greg Clayton7260f622011-04-18 08:33:37 +0000161public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162 CommandObjectTargetCreate(CommandInterpreter &interpreter)
163 : CommandObjectParsed(
164 interpreter, "target create",
165 "Create a target using the argument as the main executable.",
166 nullptr),
167 m_option_group(), m_arch_option(),
168 m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
169 "Fullpath to a core file to use for this target."),
170 m_platform_path(LLDB_OPT_SET_1, false, "platform-path", 'P', 0,
171 eArgTypePath,
172 "Path to the remote file to use for this target."),
173 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
174 eArgTypeFilename, "Fullpath to a stand alone debug "
175 "symbols file for when debug symbols "
176 "are not in the executable."),
177 m_remote_file(
178 LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
179 "Fullpath to the file on the remote host if debugging remotely."),
180 m_add_dependents(LLDB_OPT_SET_1, false, "no-dependents", 'd',
181 "Don't load dependent files when creating the target, "
182 "just add the specified executable.",
183 true, true) {
184 CommandArgumentEntry arg;
185 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000186
Kate Stoneb9c1b512016-09-06 20:57:50 +0000187 // Define the first (and only) variant of this arg.
188 file_arg.arg_type = eArgTypeFilename;
189 file_arg.arg_repetition = eArgRepeatPlain;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000190
Kate Stoneb9c1b512016-09-06 20:57:50 +0000191 // There is only one variant this argument could be; put it into the
192 // argument entry.
193 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000194
Kate Stoneb9c1b512016-09-06 20:57:50 +0000195 // Push the data for the first argument into the m_arguments vector.
196 m_arguments.push_back(arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000197
Kate Stoneb9c1b512016-09-06 20:57:50 +0000198 m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
199 m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
200 m_option_group.Append(&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
201 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
202 m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
203 m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
204 m_option_group.Finalize();
205 }
Greg Clayton7260f622011-04-18 08:33:37 +0000206
Kate Stoneb9c1b512016-09-06 20:57:50 +0000207 ~CommandObjectTargetCreate() override = default;
Greg Clayton7260f622011-04-18 08:33:37 +0000208
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209 Options *GetOptions() override { return &m_option_group; }
Greg Clayton7260f622011-04-18 08:33:37 +0000210
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211 int HandleArgumentCompletion(Args &input, int &cursor_index,
212 int &cursor_char_position,
213 OptionElementVector &opt_element_vector,
214 int match_start_point, int max_return_elements,
215 bool &word_complete,
216 StringList &matches) override {
217 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
218 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000219
Kate Stoneb9c1b512016-09-06 20:57:50 +0000220 CommandCompletions::InvokeCommonCompletionCallbacks(
221 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
222 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
223 word_complete, matches);
224 return matches.GetSize();
225 }
Jim Ingham5a988412012-06-08 21:56:10 +0000226
227protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000228 bool DoExecute(Args &command, CommandReturnObject &result) override {
229 const size_t argc = command.GetArgumentCount();
230 FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
231 FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
Greg Claytonc3776bf2012-02-09 06:16:32 +0000232
Kate Stoneb9c1b512016-09-06 20:57:50 +0000233 if (core_file) {
234 if (!core_file.Exists()) {
235 result.AppendErrorWithFormat("core file '%s' doesn't exist",
236 core_file.GetPath().c_str());
237 result.SetStatus(eReturnStatusFailed);
238 return false;
239 }
240 if (!core_file.Readable()) {
241 result.AppendErrorWithFormat("core file '%s' is not readable",
242 core_file.GetPath().c_str());
243 result.SetStatus(eReturnStatusFailed);
244 return false;
245 }
Greg Clayton7260f622011-04-18 08:33:37 +0000246 }
247
Kate Stoneb9c1b512016-09-06 20:57:50 +0000248 if (argc == 1 || core_file || remote_file) {
249 FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
250 if (symfile) {
251 if (symfile.Exists()) {
252 if (!symfile.Readable()) {
253 result.AppendErrorWithFormat("symbol file '%s' is not readable",
254 symfile.GetPath().c_str());
255 result.SetStatus(eReturnStatusFailed);
256 return false;
257 }
258 } else {
259 char symfile_path[PATH_MAX];
260 symfile.GetPath(symfile_path, sizeof(symfile_path));
261 result.AppendErrorWithFormat("invalid symbol file path '%s'",
262 symfile_path);
263 result.SetStatus(eReturnStatusFailed);
264 return false;
265 }
266 }
267
268 const char *file_path = command.GetArgumentAtIndex(0);
269 Timer scoped_timer(LLVM_PRETTY_FUNCTION, "(lldb) target create '%s'",
270 file_path);
271 FileSpec file_spec;
272
273 if (file_path)
274 file_spec.SetFile(file_path, true);
275
276 bool must_set_platform_path = false;
277
278 Debugger &debugger = m_interpreter.GetDebugger();
279
280 TargetSP target_sp;
Zachary Turnera47464b2016-11-18 20:44:46 +0000281 llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000282 const bool get_dependent_files =
283 m_add_dependents.GetOptionValue().GetCurrentValue();
284 Error error(debugger.GetTargetList().CreateTarget(
285 debugger, file_path, arch_cstr, get_dependent_files, nullptr,
286 target_sp));
287
288 if (target_sp) {
289 // Only get the platform after we create the target because we might
290 // have
291 // switched platforms depending on what the arguments were to
292 // CreateTarget()
293 // we can't rely on the selected platform.
294
295 PlatformSP platform_sp = target_sp->GetPlatform();
296
297 if (remote_file) {
298 if (platform_sp) {
299 // I have a remote file.. two possible cases
300 if (file_spec && file_spec.Exists()) {
301 // if the remote file does not exist, push it there
302 if (!platform_sp->GetFileExists(remote_file)) {
303 Error err = platform_sp->PutFile(file_spec, remote_file);
304 if (err.Fail()) {
305 result.AppendError(err.AsCString());
306 result.SetStatus(eReturnStatusFailed);
307 return false;
308 }
309 }
310 } else {
311 // there is no local file and we need one
312 // in order to make the remote ---> local transfer we need a
313 // platform
314 // TODO: if the user has passed in a --platform argument, use it
315 // to fetch the right platform
316 if (!platform_sp) {
317 result.AppendError(
318 "unable to perform remote debugging without a platform");
319 result.SetStatus(eReturnStatusFailed);
320 return false;
321 }
322 if (file_path) {
323 // copy the remote file to the local file
324 Error err = platform_sp->GetFile(remote_file, file_spec);
325 if (err.Fail()) {
326 result.AppendError(err.AsCString());
327 result.SetStatus(eReturnStatusFailed);
328 return false;
329 }
330 } else {
331 // make up a local file
332 result.AppendError("remote --> local transfer without local "
333 "path is not implemented yet");
334 result.SetStatus(eReturnStatusFailed);
335 return false;
336 }
337 }
338 } else {
339 result.AppendError("no platform found for target");
340 result.SetStatus(eReturnStatusFailed);
341 return false;
342 }
343 }
344
345 if (symfile || remote_file) {
346 ModuleSP module_sp(target_sp->GetExecutableModule());
347 if (module_sp) {
348 if (symfile)
349 module_sp->SetSymbolFileFileSpec(symfile);
350 if (remote_file) {
351 std::string remote_path = remote_file.GetPath();
352 target_sp->SetArg0(remote_path.c_str());
353 module_sp->SetPlatformFileSpec(remote_file);
354 }
355 }
356 }
357
358 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
359 if (must_set_platform_path) {
360 ModuleSpec main_module_spec(file_spec);
361 ModuleSP module_sp = target_sp->GetSharedModule(main_module_spec);
362 if (module_sp)
363 module_sp->SetPlatformFileSpec(remote_file);
364 }
365 if (core_file) {
366 char core_path[PATH_MAX];
367 core_file.GetPath(core_path, sizeof(core_path));
368 if (core_file.Exists()) {
369 if (!core_file.Readable()) {
370 result.AppendMessageWithFormat(
371 "Core file '%s' is not readable.\n", core_path);
372 result.SetStatus(eReturnStatusFailed);
373 return false;
374 }
375 FileSpec core_file_dir;
376 core_file_dir.GetDirectory() = core_file.GetDirectory();
377 target_sp->GetExecutableSearchPaths().Append(core_file_dir);
378
379 ProcessSP process_sp(target_sp->CreateProcess(
Zachary Turner31659452016-11-17 21:15:14 +0000380 m_interpreter.GetDebugger().GetListener(), llvm::StringRef(),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000381 &core_file));
382
383 if (process_sp) {
384 // Seems weird that we Launch a core file, but that is
385 // what we do!
386 error = process_sp->LoadCore();
387
388 if (error.Fail()) {
389 result.AppendError(
390 error.AsCString("can't find plug-in for core file"));
391 result.SetStatus(eReturnStatusFailed);
392 return false;
393 } else {
394 result.AppendMessageWithFormat(
395 "Core file '%s' (%s) was loaded.\n", core_path,
396 target_sp->GetArchitecture().GetArchitectureName());
397 result.SetStatus(eReturnStatusSuccessFinishNoResult);
398 }
399 } else {
400 result.AppendErrorWithFormat(
401 "Unable to find process plug-in for core file '%s'\n",
402 core_path);
403 result.SetStatus(eReturnStatusFailed);
404 }
405 } else {
406 result.AppendErrorWithFormat("Core file '%s' does not exist\n",
407 core_path);
408 result.SetStatus(eReturnStatusFailed);
409 }
410 } else {
411 result.AppendMessageWithFormat(
412 "Current executable set to '%s' (%s).\n", file_path,
413 target_sp->GetArchitecture().GetArchitectureName());
414 result.SetStatus(eReturnStatusSuccessFinishNoResult);
415 }
416 } else {
417 result.AppendError(error.AsCString());
418 result.SetStatus(eReturnStatusFailed);
419 }
420 } else {
421 result.AppendErrorWithFormat("'%s' takes exactly one executable path "
422 "argument, or use the --core option.\n",
423 m_cmd_name.c_str());
424 result.SetStatus(eReturnStatusFailed);
425 }
426 return result.Succeeded();
427 }
428
Greg Clayton7260f622011-04-18 08:33:37 +0000429private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000430 OptionGroupOptions m_option_group;
431 OptionGroupArchitecture m_arch_option;
432 OptionGroupFile m_core_file;
433 OptionGroupFile m_platform_path;
434 OptionGroupFile m_symbol_file;
435 OptionGroupFile m_remote_file;
436 OptionGroupBoolean m_add_dependents;
Greg Clayton7260f622011-04-18 08:33:37 +0000437};
438
439#pragma mark CommandObjectTargetList
440
441//----------------------------------------------------------------------
442// "target list"
443//----------------------------------------------------------------------
444
Kate Stoneb9c1b512016-09-06 20:57:50 +0000445class CommandObjectTargetList : public CommandObjectParsed {
Greg Clayton7260f622011-04-18 08:33:37 +0000446public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000447 CommandObjectTargetList(CommandInterpreter &interpreter)
448 : CommandObjectParsed(
449 interpreter, "target list",
450 "List all current targets in the current debug session.", nullptr) {
451 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000452
Kate Stoneb9c1b512016-09-06 20:57:50 +0000453 ~CommandObjectTargetList() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000454
Jim Ingham5a988412012-06-08 21:56:10 +0000455protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000456 bool DoExecute(Args &args, CommandReturnObject &result) override {
457 if (args.GetArgumentCount() == 0) {
458 Stream &strm = result.GetOutputStream();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000459
Kate Stoneb9c1b512016-09-06 20:57:50 +0000460 bool show_stopped_process_status = false;
461 if (DumpTargetList(m_interpreter.GetDebugger().GetTargetList(),
462 show_stopped_process_status, strm) == 0) {
463 strm.PutCString("No targets.\n");
464 }
465 result.SetStatus(eReturnStatusSuccessFinishResult);
466 } else {
467 result.AppendError("the 'target list' command takes no arguments\n");
468 result.SetStatus(eReturnStatusFailed);
Greg Clayton7260f622011-04-18 08:33:37 +0000469 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000470 return result.Succeeded();
471 }
Greg Clayton7260f622011-04-18 08:33:37 +0000472};
473
Greg Clayton7260f622011-04-18 08:33:37 +0000474#pragma mark CommandObjectTargetSelect
475
476//----------------------------------------------------------------------
477// "target select"
478//----------------------------------------------------------------------
479
Kate Stoneb9c1b512016-09-06 20:57:50 +0000480class CommandObjectTargetSelect : public CommandObjectParsed {
Greg Clayton7260f622011-04-18 08:33:37 +0000481public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000482 CommandObjectTargetSelect(CommandInterpreter &interpreter)
483 : CommandObjectParsed(
484 interpreter, "target select",
485 "Select a target as the current target by target index.", nullptr) {
486 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000487
Kate Stoneb9c1b512016-09-06 20:57:50 +0000488 ~CommandObjectTargetSelect() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000489
Jim Ingham5a988412012-06-08 21:56:10 +0000490protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000491 bool DoExecute(Args &args, CommandReturnObject &result) override {
492 if (args.GetArgumentCount() == 1) {
493 bool success = false;
494 const char *target_idx_arg = args.GetArgumentAtIndex(0);
495 uint32_t target_idx =
496 StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success);
497 if (success) {
498 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
499 const uint32_t num_targets = target_list.GetNumTargets();
500 if (target_idx < num_targets) {
501 TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
502 if (target_sp) {
503 Stream &strm = result.GetOutputStream();
504 target_list.SetSelectedTarget(target_sp.get());
505 bool show_stopped_process_status = false;
506 DumpTargetList(target_list, show_stopped_process_status, strm);
507 result.SetStatus(eReturnStatusSuccessFinishResult);
508 } else {
509 result.AppendErrorWithFormat("target #%u is NULL in target list\n",
510 target_idx);
511 result.SetStatus(eReturnStatusFailed);
512 }
513 } else {
514 if (num_targets > 0) {
515 result.AppendErrorWithFormat(
516 "index %u is out of range, valid target indexes are 0 - %u\n",
517 target_idx, num_targets - 1);
518 } else {
519 result.AppendErrorWithFormat(
520 "index %u is out of range since there are no active targets\n",
521 target_idx);
522 }
523 result.SetStatus(eReturnStatusFailed);
Greg Clayton7260f622011-04-18 08:33:37 +0000524 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000525 } else {
526 result.AppendErrorWithFormat("invalid index string value '%s'\n",
527 target_idx_arg);
528 result.SetStatus(eReturnStatusFailed);
529 }
530 } else {
531 result.AppendError(
532 "'target select' takes a single argument: a target index\n");
533 result.SetStatus(eReturnStatusFailed);
Greg Clayton7260f622011-04-18 08:33:37 +0000534 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000535 return result.Succeeded();
536 }
Greg Clayton7260f622011-04-18 08:33:37 +0000537};
538
Greg Clayton3418c852011-08-10 02:10:13 +0000539#pragma mark CommandObjectTargetSelect
540
541//----------------------------------------------------------------------
542// "target delete"
543//----------------------------------------------------------------------
544
Kate Stoneb9c1b512016-09-06 20:57:50 +0000545class CommandObjectTargetDelete : public CommandObjectParsed {
Greg Clayton3418c852011-08-10 02:10:13 +0000546public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000547 CommandObjectTargetDelete(CommandInterpreter &interpreter)
548 : CommandObjectParsed(interpreter, "target delete",
Eugene Zelenkof13e6522016-02-25 19:02:39 +0000549 "Delete one or more targets by target index.",
550 nullptr),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000551 m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
552 "Delete all targets.", false, true),
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000553 m_cleanup_option(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000554 LLDB_OPT_SET_1, false, "clean", 'c',
555 "Perform extra cleanup to minimize memory consumption after "
556 "deleting the target. "
557 "By default, LLDB will keep in memory any modules previously "
558 "loaded by the target as well "
559 "as all of its debug info. Specifying --clean will unload all of "
560 "these shared modules and "
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000561 "cause them to be reparsed again the next time the target is run",
Kate Stoneb9c1b512016-09-06 20:57:50 +0000562 false, true) {
563 m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
564 m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
565 m_option_group.Finalize();
566 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000567
Kate Stoneb9c1b512016-09-06 20:57:50 +0000568 ~CommandObjectTargetDelete() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000569
Kate Stoneb9c1b512016-09-06 20:57:50 +0000570 Options *GetOptions() override { return &m_option_group; }
Jim Ingham5a988412012-06-08 21:56:10 +0000571
572protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000573 bool DoExecute(Args &args, CommandReturnObject &result) override {
574 const size_t argc = args.GetArgumentCount();
575 std::vector<TargetSP> delete_target_list;
576 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
577 TargetSP target_sp;
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000578
Kate Stoneb9c1b512016-09-06 20:57:50 +0000579 if (m_all_option.GetOptionValue()) {
580 for (int i = 0; i < target_list.GetNumTargets(); ++i)
581 delete_target_list.push_back(target_list.GetTargetAtIndex(i));
582 } else if (argc > 0) {
583 const uint32_t num_targets = target_list.GetNumTargets();
584 // Bail out if don't have any targets.
585 if (num_targets == 0) {
586 result.AppendError("no targets to delete");
587 result.SetStatus(eReturnStatusFailed);
588 return false;
589 }
590
Zachary Turner97d2c402016-10-05 23:40:23 +0000591 for (auto &entry : args.entries()) {
592 uint32_t target_idx;
593 if (entry.ref.getAsInteger(0, target_idx)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000594 result.AppendErrorWithFormat("invalid target index '%s'\n",
Zachary Turner97d2c402016-10-05 23:40:23 +0000595 entry.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000596 result.SetStatus(eReturnStatusFailed);
597 return false;
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000598 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000599 if (target_idx < num_targets) {
600 target_sp = target_list.GetTargetAtIndex(target_idx);
601 if (target_sp) {
602 delete_target_list.push_back(target_sp);
603 continue;
604 }
Greg Clayton3418c852011-08-10 02:10:13 +0000605 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000606 if (num_targets > 1)
607 result.AppendErrorWithFormat("target index %u is out of range, valid "
608 "target indexes are 0 - %u\n",
609 target_idx, num_targets - 1);
Greg Clayton3418c852011-08-10 02:10:13 +0000610 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000611 result.AppendErrorWithFormat(
612 "target index %u is out of range, the only valid index is 0\n",
613 target_idx);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000614
Kate Stoneb9c1b512016-09-06 20:57:50 +0000615 result.SetStatus(eReturnStatusFailed);
616 return false;
617 }
618 } else {
619 target_sp = target_list.GetSelectedTarget();
620 if (!target_sp) {
621 result.AppendErrorWithFormat("no target is currently selected\n");
622 result.SetStatus(eReturnStatusFailed);
623 return false;
624 }
625 delete_target_list.push_back(target_sp);
Greg Clayton3418c852011-08-10 02:10:13 +0000626 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000627
Kate Stoneb9c1b512016-09-06 20:57:50 +0000628 const size_t num_targets_to_delete = delete_target_list.size();
629 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
630 target_sp = delete_target_list[idx];
631 target_list.DeleteTarget(target_sp);
632 target_sp->Destroy();
633 }
634 // If "--clean" was specified, prune any orphaned shared modules from
635 // the global shared module list
636 if (m_cleanup_option.GetOptionValue()) {
637 const bool mandatory = true;
638 ModuleList::RemoveOrphanSharedModules(mandatory);
639 }
640 result.GetOutputStream().Printf("%u targets deleted.\n",
641 (uint32_t)num_targets_to_delete);
642 result.SetStatus(eReturnStatusSuccessFinishResult);
643
644 return true;
645 }
646
647 OptionGroupOptions m_option_group;
648 OptionGroupBoolean m_all_option;
649 OptionGroupBoolean m_cleanup_option;
Greg Clayton3418c852011-08-10 02:10:13 +0000650};
651
Greg Clayton644247c2011-07-07 01:59:51 +0000652#pragma mark CommandObjectTargetVariable
653
654//----------------------------------------------------------------------
655// "target variable"
656//----------------------------------------------------------------------
657
Kate Stoneb9c1b512016-09-06 20:57:50 +0000658class CommandObjectTargetVariable : public CommandObjectParsed {
659 static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
660 static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
Saleem Abdulrasool44edda02014-03-18 04:43:47 +0000661
Greg Clayton644247c2011-07-07 01:59:51 +0000662public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000663 CommandObjectTargetVariable(CommandInterpreter &interpreter)
664 : CommandObjectParsed(interpreter, "target variable",
665 "Read global variables for the current target, "
666 "before or while running a process.",
667 nullptr, eCommandRequiresTarget),
668 m_option_group(),
669 m_option_variable(false), // Don't include frame options
670 m_option_format(eFormatDefault),
671 m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
672 0, eArgTypeFilename,
673 "A basename or fullpath to a file that contains "
674 "global variables. This option can be "
675 "specified multiple times."),
676 m_option_shared_libraries(
677 LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
678 eArgTypeFilename,
679 "A basename or fullpath to a shared library to use in the search "
680 "for global "
681 "variables. This option can be specified multiple times."),
682 m_varobj_options() {
683 CommandArgumentEntry arg;
684 CommandArgumentData var_name_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000685
Kate Stoneb9c1b512016-09-06 20:57:50 +0000686 // Define the first (and only) variant of this arg.
687 var_name_arg.arg_type = eArgTypeVarName;
688 var_name_arg.arg_repetition = eArgRepeatPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000689
Kate Stoneb9c1b512016-09-06 20:57:50 +0000690 // There is only one variant this argument could be; put it into the
691 // argument entry.
692 arg.push_back(var_name_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000693
Kate Stoneb9c1b512016-09-06 20:57:50 +0000694 // Push the data for the first argument into the m_arguments vector.
695 m_arguments.push_back(arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000696
Kate Stoneb9c1b512016-09-06 20:57:50 +0000697 m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
698 m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
699 m_option_group.Append(&m_option_format,
700 OptionGroupFormat::OPTION_GROUP_FORMAT |
701 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
702 LLDB_OPT_SET_1);
703 m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
704 LLDB_OPT_SET_1);
705 m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
706 LLDB_OPT_SET_1);
707 m_option_group.Finalize();
708 }
709
710 ~CommandObjectTargetVariable() override = default;
711
712 void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
713 const char *root_name) {
714 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
715
716 if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
717 valobj_sp->IsRuntimeSupportValue())
718 return;
719
720 switch (var_sp->GetScope()) {
721 case eValueTypeVariableGlobal:
722 if (m_option_variable.show_scope)
723 s.PutCString("GLOBAL: ");
724 break;
725
726 case eValueTypeVariableStatic:
727 if (m_option_variable.show_scope)
728 s.PutCString("STATIC: ");
729 break;
730
731 case eValueTypeVariableArgument:
732 if (m_option_variable.show_scope)
733 s.PutCString(" ARG: ");
734 break;
735
736 case eValueTypeVariableLocal:
737 if (m_option_variable.show_scope)
738 s.PutCString(" LOCAL: ");
739 break;
740
741 case eValueTypeVariableThreadLocal:
742 if (m_option_variable.show_scope)
743 s.PutCString("THREAD: ");
744 break;
745
746 default:
747 break;
Greg Clayton644247c2011-07-07 01:59:51 +0000748 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000749
Kate Stoneb9c1b512016-09-06 20:57:50 +0000750 if (m_option_variable.show_decl) {
751 bool show_fullpaths = false;
752 bool show_module = true;
753 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
754 s.PutCString(": ");
Greg Clayton884fb692011-07-08 21:46:14 +0000755 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000756
Kate Stoneb9c1b512016-09-06 20:57:50 +0000757 const Format format = m_option_format.GetFormat();
758 if (format != eFormatDefault)
759 options.SetFormat(format);
Greg Clayton884fb692011-07-08 21:46:14 +0000760
Kate Stoneb9c1b512016-09-06 20:57:50 +0000761 options.SetRootValueObjectName(root_name);
762
763 valobj_sp->Dump(s, options);
764 }
765
766 static size_t GetVariableCallback(void *baton, const char *name,
767 VariableList &variable_list) {
768 Target *target = static_cast<Target *>(baton);
769 if (target) {
770 return target->GetImages().FindGlobalVariables(ConstString(name), true,
771 UINT32_MAX, variable_list);
Jim Ingham5a988412012-06-08 21:56:10 +0000772 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000773 return 0;
774 }
775
776 Options *GetOptions() override { return &m_option_group; }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000777
Jim Ingham5a988412012-06-08 21:56:10 +0000778protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000779 void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
780 const SymbolContext &sc,
781 const VariableList &variable_list, Stream &s) {
782 size_t count = variable_list.GetSize();
783 if (count > 0) {
784 if (sc.module_sp) {
785 if (sc.comp_unit) {
786 s.Printf("Global variables for %s in %s:\n",
787 sc.comp_unit->GetPath().c_str(),
788 sc.module_sp->GetFileSpec().GetPath().c_str());
789 } else {
790 s.Printf("Global variables for %s\n",
791 sc.module_sp->GetFileSpec().GetPath().c_str());
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000792 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000793 } else if (sc.comp_unit) {
794 s.Printf("Global variables for %s\n", sc.comp_unit->GetPath().c_str());
795 }
796
797 for (uint32_t i = 0; i < count; ++i) {
798 VariableSP var_sp(variable_list.GetVariableAtIndex(i));
799 if (var_sp) {
800 ValueObjectSP valobj_sp(ValueObjectVariable::Create(
801 exe_ctx.GetBestExecutionContextScope(), var_sp));
802
803 if (valobj_sp)
804 DumpValueObject(s, var_sp, valobj_sp,
805 var_sp->GetName().GetCString());
806 }
807 }
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000808 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000809 }
Eugene Zelenkof13e6522016-02-25 19:02:39 +0000810
Kate Stoneb9c1b512016-09-06 20:57:50 +0000811 bool DoExecute(Args &args, CommandReturnObject &result) override {
812 Target *target = m_exe_ctx.GetTargetPtr();
813 const size_t argc = args.GetArgumentCount();
814 Stream &s = result.GetOutputStream();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000815
Kate Stoneb9c1b512016-09-06 20:57:50 +0000816 if (argc > 0) {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000817
Zachary Turner97d2c402016-10-05 23:40:23 +0000818 // TODO: Convert to entry-based iteration. Requires converting
819 // DumpValueObject.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000820 for (size_t idx = 0; idx < argc; ++idx) {
821 VariableList variable_list;
822 ValueObjectList valobj_list;
Greg Clayton884fb692011-07-08 21:46:14 +0000823
Kate Stoneb9c1b512016-09-06 20:57:50 +0000824 const char *arg = args.GetArgumentAtIndex(idx);
825 size_t matches = 0;
826 bool use_var_name = false;
827 if (m_option_variable.use_regex) {
Zachary Turner95eae422016-09-21 16:01:28 +0000828 RegularExpression regex(llvm::StringRef::withNullAsEmpty(arg));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000829 if (!regex.IsValid()) {
830 result.GetErrorStream().Printf(
831 "error: invalid regular expression: '%s'\n", arg);
832 result.SetStatus(eReturnStatusFailed);
833 return false;
834 }
835 use_var_name = true;
836 matches = target->GetImages().FindGlobalVariables(
837 regex, true, UINT32_MAX, variable_list);
838 } else {
839 Error error(Variable::GetValuesForVariableExpressionPath(
840 arg, m_exe_ctx.GetBestExecutionContextScope(),
841 GetVariableCallback, target, variable_list, valobj_list));
842 matches = variable_list.GetSize();
Greg Clayton644247c2011-07-07 01:59:51 +0000843 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000844
845 if (matches == 0) {
846 result.GetErrorStream().Printf(
847 "error: can't find global variable '%s'\n", arg);
848 result.SetStatus(eReturnStatusFailed);
849 return false;
850 } else {
851 for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
852 VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
853 if (var_sp) {
854 ValueObjectSP valobj_sp(
855 valobj_list.GetValueObjectAtIndex(global_idx));
856 if (!valobj_sp)
857 valobj_sp = ValueObjectVariable::Create(
858 m_exe_ctx.GetBestExecutionContextScope(), var_sp);
859
860 if (valobj_sp)
861 DumpValueObject(s, var_sp, valobj_sp,
862 use_var_name ? var_sp->GetName().GetCString()
863 : arg);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000864 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000865 }
866 }
867 }
868 } else {
869 const FileSpecList &compile_units =
870 m_option_compile_units.GetOptionValue().GetCurrentValue();
871 const FileSpecList &shlibs =
872 m_option_shared_libraries.GetOptionValue().GetCurrentValue();
873 SymbolContextList sc_list;
874 const size_t num_compile_units = compile_units.GetSize();
875 const size_t num_shlibs = shlibs.GetSize();
876 if (num_compile_units == 0 && num_shlibs == 0) {
877 bool success = false;
878 StackFrame *frame = m_exe_ctx.GetFramePtr();
879 CompileUnit *comp_unit = nullptr;
880 if (frame) {
881 SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
882 if (sc.comp_unit) {
883 const bool can_create = true;
884 VariableListSP comp_unit_varlist_sp(
885 sc.comp_unit->GetVariableList(can_create));
886 if (comp_unit_varlist_sp) {
887 size_t count = comp_unit_varlist_sp->GetSize();
888 if (count > 0) {
889 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
890 success = true;
891 }
892 }
893 }
894 }
895 if (!success) {
896 if (frame) {
897 if (comp_unit)
898 result.AppendErrorWithFormat(
899 "no global variables in current compile unit: %s\n",
900 comp_unit->GetPath().c_str());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000901 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000902 result.AppendErrorWithFormat(
903 "no debug information for frame %u\n",
904 frame->GetFrameIndex());
905 } else
906 result.AppendError("'target variable' takes one or more global "
907 "variable names as arguments\n");
908 result.SetStatus(eReturnStatusFailed);
909 }
910 } else {
911 SymbolContextList sc_list;
912 const bool append = true;
913 // We have one or more compile unit or shlib
914 if (num_shlibs > 0) {
915 for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
916 const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
917 ModuleSpec module_spec(module_file);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000918
Kate Stoneb9c1b512016-09-06 20:57:50 +0000919 ModuleSP module_sp(
920 target->GetImages().FindFirstModule(module_spec));
921 if (module_sp) {
922 if (num_compile_units > 0) {
923 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
924 module_sp->FindCompileUnits(
925 compile_units.GetFileSpecAtIndex(cu_idx), append,
926 sc_list);
927 } else {
928 SymbolContext sc;
929 sc.module_sp = module_sp;
930 sc_list.Append(sc);
931 }
932 } else {
933 // Didn't find matching shlib/module in target...
934 result.AppendErrorWithFormat(
935 "target doesn't contain the specified shared library: %s\n",
936 module_file.GetPath().c_str());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000937 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000938 }
939 } else {
940 // No shared libraries, we just want to find globals for the compile
941 // units files that were specified
942 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
943 target->GetImages().FindCompileUnits(
944 compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
Greg Clayton644247c2011-07-07 01:59:51 +0000945 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000946
Kate Stoneb9c1b512016-09-06 20:57:50 +0000947 const uint32_t num_scs = sc_list.GetSize();
948 if (num_scs > 0) {
949 SymbolContext sc;
950 for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
951 if (sc_list.GetContextAtIndex(sc_idx, sc)) {
952 if (sc.comp_unit) {
953 const bool can_create = true;
954 VariableListSP comp_unit_varlist_sp(
955 sc.comp_unit->GetVariableList(can_create));
956 if (comp_unit_varlist_sp)
957 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
958 s);
959 } else if (sc.module_sp) {
960 // Get all global variables for this module
961 lldb_private::RegularExpression all_globals_regex(
Zachary Turner95eae422016-09-21 16:01:28 +0000962 llvm::StringRef(
963 ".")); // Any global with at least one character
Kate Stoneb9c1b512016-09-06 20:57:50 +0000964 VariableList variable_list;
965 sc.module_sp->FindGlobalVariables(all_globals_regex, append,
966 UINT32_MAX, variable_list);
967 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
968 }
969 }
970 }
Enrico Granata61a80ba2011-08-12 16:42:31 +0000971 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000972 }
Greg Clayton644247c2011-07-07 01:59:51 +0000973 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000974
Kate Stoneb9c1b512016-09-06 20:57:50 +0000975 if (m_interpreter.TruncationWarningNecessary()) {
976 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
977 m_cmd_name.c_str());
978 m_interpreter.TruncationWarningGiven();
979 }
980
981 return result.Succeeded();
982 }
983
984 OptionGroupOptions m_option_group;
985 OptionGroupVariable m_option_variable;
986 OptionGroupFormat m_option_format;
987 OptionGroupFileList m_option_compile_units;
988 OptionGroupFileList m_option_shared_libraries;
989 OptionGroupValueObjectDisplay m_varobj_options;
Greg Clayton644247c2011-07-07 01:59:51 +0000990};
991
Greg Claytoneffe5c92011-05-03 22:09:39 +0000992#pragma mark CommandObjectTargetModulesSearchPathsAdd
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000993
Kate Stoneb9c1b512016-09-06 20:57:50 +0000994class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000995public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000996 CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
997 : CommandObjectParsed(interpreter, "target modules search-paths add",
998 "Add new image search paths substitution pairs to "
999 "the current target.",
1000 nullptr) {
1001 CommandArgumentEntry arg;
1002 CommandArgumentData old_prefix_arg;
1003 CommandArgumentData new_prefix_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001004
Kate Stoneb9c1b512016-09-06 20:57:50 +00001005 // Define the first variant of this arg pair.
1006 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1007 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001008
Kate Stoneb9c1b512016-09-06 20:57:50 +00001009 // Define the first variant of this arg pair.
1010 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1011 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001012
Kate Stoneb9c1b512016-09-06 20:57:50 +00001013 // There are two required arguments that must always occur together, i.e. an
1014 // argument "pair". Because they
1015 // must always occur together, they are treated as two variants of one
1016 // argument rather than two independent
1017 // arguments. Push them both into the first argument position for
1018 // m_arguments...
Caroline Tice405fe672010-10-04 22:28:36 +00001019
Kate Stoneb9c1b512016-09-06 20:57:50 +00001020 arg.push_back(old_prefix_arg);
1021 arg.push_back(new_prefix_arg);
Caroline Tice405fe672010-10-04 22:28:36 +00001022
Kate Stoneb9c1b512016-09-06 20:57:50 +00001023 m_arguments.push_back(arg);
1024 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001025
Kate Stoneb9c1b512016-09-06 20:57:50 +00001026 ~CommandObjectTargetModulesSearchPathsAdd() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001027
Jim Ingham5a988412012-06-08 21:56:10 +00001028protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001029 bool DoExecute(Args &command, CommandReturnObject &result) override {
1030 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1031 if (target) {
1032 const size_t argc = command.GetArgumentCount();
1033 if (argc & 1) {
1034 result.AppendError("add requires an even number of arguments\n");
1035 result.SetStatus(eReturnStatusFailed);
1036 } else {
1037 for (size_t i = 0; i < argc; i += 2) {
1038 const char *from = command.GetArgumentAtIndex(i);
1039 const char *to = command.GetArgumentAtIndex(i + 1);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001040
Kate Stoneb9c1b512016-09-06 20:57:50 +00001041 if (from[0] && to[0]) {
1042 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
1043 if (log) {
1044 log->Printf("target modules search path adding ImageSearchPath "
1045 "pair: '%s' -> '%s'",
1046 from, to);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001047 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001048 bool last_pair = ((argc - i) == 2);
1049 target->GetImageSearchPathList().Append(
1050 ConstString(from), ConstString(to),
1051 last_pair); // Notify if this is the last pair
1052 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1053 } else {
1054 if (from[0])
1055 result.AppendError("<path-prefix> can't be empty\n");
1056 else
1057 result.AppendError("<new-path-prefix> can't be empty\n");
1058 result.SetStatus(eReturnStatusFailed);
1059 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001060 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001061 }
1062 } else {
1063 result.AppendError("invalid target\n");
1064 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001065 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001066 return result.Succeeded();
1067 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001068};
1069
Greg Claytoneffe5c92011-05-03 22:09:39 +00001070#pragma mark CommandObjectTargetModulesSearchPathsClear
1071
Kate Stoneb9c1b512016-09-06 20:57:50 +00001072class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001073public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001074 CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
1075 : CommandObjectParsed(interpreter, "target modules search-paths clear",
1076 "Clear all current image search path substitution "
1077 "pairs from the current target.",
1078 "target modules search-paths clear") {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001079
Kate Stoneb9c1b512016-09-06 20:57:50 +00001080 ~CommandObjectTargetModulesSearchPathsClear() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001081
Jim Ingham5a988412012-06-08 21:56:10 +00001082protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001083 bool DoExecute(Args &command, CommandReturnObject &result) override {
1084 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1085 if (target) {
1086 bool notify = true;
1087 target->GetImageSearchPathList().Clear(notify);
1088 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1089 } else {
1090 result.AppendError("invalid target\n");
1091 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001092 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001093 return result.Succeeded();
1094 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001095};
1096
Greg Claytoneffe5c92011-05-03 22:09:39 +00001097#pragma mark CommandObjectTargetModulesSearchPathsInsert
1098
Kate Stoneb9c1b512016-09-06 20:57:50 +00001099class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001100public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001101 CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
1102 : CommandObjectParsed(interpreter, "target modules search-paths insert",
1103 "Insert a new image search path substitution pair "
1104 "into the current target at the specified index.",
1105 nullptr) {
1106 CommandArgumentEntry arg1;
1107 CommandArgumentEntry arg2;
1108 CommandArgumentData index_arg;
1109 CommandArgumentData old_prefix_arg;
1110 CommandArgumentData new_prefix_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001111
Kate Stoneb9c1b512016-09-06 20:57:50 +00001112 // Define the first and only variant of this arg.
1113 index_arg.arg_type = eArgTypeIndex;
1114 index_arg.arg_repetition = eArgRepeatPlain;
Caroline Tice405fe672010-10-04 22:28:36 +00001115
Kate Stoneb9c1b512016-09-06 20:57:50 +00001116 // Put the one and only variant into the first arg for m_arguments:
1117 arg1.push_back(index_arg);
Caroline Tice405fe672010-10-04 22:28:36 +00001118
Kate Stoneb9c1b512016-09-06 20:57:50 +00001119 // Define the first variant of this arg pair.
1120 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1121 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001122
Kate Stoneb9c1b512016-09-06 20:57:50 +00001123 // Define the first variant of this arg pair.
1124 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1125 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001126
Kate Stoneb9c1b512016-09-06 20:57:50 +00001127 // There are two required arguments that must always occur together, i.e. an
1128 // argument "pair". Because they
1129 // must always occur together, they are treated as two variants of one
1130 // argument rather than two independent
1131 // arguments. Push them both into the same argument position for
1132 // m_arguments...
Caroline Tice405fe672010-10-04 22:28:36 +00001133
Kate Stoneb9c1b512016-09-06 20:57:50 +00001134 arg2.push_back(old_prefix_arg);
1135 arg2.push_back(new_prefix_arg);
Caroline Tice405fe672010-10-04 22:28:36 +00001136
Kate Stoneb9c1b512016-09-06 20:57:50 +00001137 // Add arguments to m_arguments.
1138 m_arguments.push_back(arg1);
1139 m_arguments.push_back(arg2);
1140 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001141
Kate Stoneb9c1b512016-09-06 20:57:50 +00001142 ~CommandObjectTargetModulesSearchPathsInsert() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001143
Jim Ingham5a988412012-06-08 21:56:10 +00001144protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001145 bool DoExecute(Args &command, CommandReturnObject &result) override {
1146 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1147 if (target) {
1148 size_t argc = command.GetArgumentCount();
1149 // check for at least 3 arguments and an odd number of parameters
1150 if (argc >= 3 && argc & 1) {
1151 bool success = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001152
Kate Stoneb9c1b512016-09-06 20:57:50 +00001153 uint32_t insert_idx = StringConvert::ToUInt32(
1154 command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001155
Kate Stoneb9c1b512016-09-06 20:57:50 +00001156 if (!success) {
1157 result.AppendErrorWithFormat(
1158 "<index> parameter is not an integer: '%s'.\n",
1159 command.GetArgumentAtIndex(0));
1160 result.SetStatus(eReturnStatusFailed);
1161 return result.Succeeded();
1162 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001163
Kate Stoneb9c1b512016-09-06 20:57:50 +00001164 // shift off the index
1165 command.Shift();
1166 argc = command.GetArgumentCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001167
Kate Stoneb9c1b512016-09-06 20:57:50 +00001168 for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1169 const char *from = command.GetArgumentAtIndex(i);
1170 const char *to = command.GetArgumentAtIndex(i + 1);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001171
Kate Stoneb9c1b512016-09-06 20:57:50 +00001172 if (from[0] && to[0]) {
1173 bool last_pair = ((argc - i) == 2);
1174 target->GetImageSearchPathList().Insert(
1175 ConstString(from), ConstString(to), insert_idx, last_pair);
1176 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1177 } else {
1178 if (from[0])
1179 result.AppendError("<path-prefix> can't be empty\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001180 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001181 result.AppendError("<new-path-prefix> can't be empty\n");
1182 result.SetStatus(eReturnStatusFailed);
1183 return false;
1184 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001185 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001186 } else {
1187 result.AppendError("insert requires at least three arguments\n");
1188 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001189 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001190 }
1191
1192 } else {
1193 result.AppendError("invalid target\n");
1194 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001195 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001196 return result.Succeeded();
1197 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001198};
1199
Greg Claytoneffe5c92011-05-03 22:09:39 +00001200#pragma mark CommandObjectTargetModulesSearchPathsList
1201
Kate Stoneb9c1b512016-09-06 20:57:50 +00001202class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001203public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001204 CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
1205 : CommandObjectParsed(interpreter, "target modules search-paths list",
1206 "List all current image search path substitution "
1207 "pairs in the current target.",
1208 "target modules search-paths list") {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001209
Kate Stoneb9c1b512016-09-06 20:57:50 +00001210 ~CommandObjectTargetModulesSearchPathsList() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001211
Jim Ingham5a988412012-06-08 21:56:10 +00001212protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001213 bool DoExecute(Args &command, CommandReturnObject &result) override {
1214 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1215 if (target) {
1216 if (command.GetArgumentCount() != 0) {
1217 result.AppendError("list takes no arguments\n");
1218 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001219 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001220 }
1221
1222 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1223 result.SetStatus(eReturnStatusSuccessFinishResult);
1224 } else {
1225 result.AppendError("invalid target\n");
1226 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001227 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001228 return result.Succeeded();
1229 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001230};
1231
Greg Claytoneffe5c92011-05-03 22:09:39 +00001232#pragma mark CommandObjectTargetModulesSearchPathsQuery
1233
Kate Stoneb9c1b512016-09-06 20:57:50 +00001234class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001235public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001236 CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
1237 : CommandObjectParsed(
1238 interpreter, "target modules search-paths query",
1239 "Transform a path using the first applicable image search path.",
1240 nullptr) {
1241 CommandArgumentEntry arg;
1242 CommandArgumentData path_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001243
Kate Stoneb9c1b512016-09-06 20:57:50 +00001244 // Define the first (and only) variant of this arg.
1245 path_arg.arg_type = eArgTypeDirectoryName;
1246 path_arg.arg_repetition = eArgRepeatPlain;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001247
Kate Stoneb9c1b512016-09-06 20:57:50 +00001248 // There is only one variant this argument could be; put it into the
1249 // argument entry.
1250 arg.push_back(path_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001251
Kate Stoneb9c1b512016-09-06 20:57:50 +00001252 // Push the data for the first argument into the m_arguments vector.
1253 m_arguments.push_back(arg);
1254 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001255
Kate Stoneb9c1b512016-09-06 20:57:50 +00001256 ~CommandObjectTargetModulesSearchPathsQuery() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001257
Jim Ingham5a988412012-06-08 21:56:10 +00001258protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001259 bool DoExecute(Args &command, CommandReturnObject &result) override {
1260 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1261 if (target) {
1262 if (command.GetArgumentCount() != 1) {
1263 result.AppendError("query requires one argument\n");
1264 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001265 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001266 }
1267
1268 ConstString orig(command.GetArgumentAtIndex(0));
1269 ConstString transformed;
1270 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1271 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1272 else
1273 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1274
1275 result.SetStatus(eReturnStatusSuccessFinishResult);
1276 } else {
1277 result.AppendError("invalid target\n");
1278 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001279 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001280 return result.Succeeded();
1281 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001282};
1283
Greg Claytoneffe5c92011-05-03 22:09:39 +00001284//----------------------------------------------------------------------
1285// Static Helper functions
1286//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001287static void DumpModuleArchitecture(Stream &strm, Module *module,
1288 bool full_triple, uint32_t width) {
1289 if (module) {
1290 StreamString arch_strm;
Todd Fiala7df337f2015-10-13 23:41:19 +00001291
Kate Stoneb9c1b512016-09-06 20:57:50 +00001292 if (full_triple)
1293 module->GetArchitecture().DumpTriple(arch_strm);
Greg Clayton3418c852011-08-10 02:10:13 +00001294 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001295 arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1296 std::string arch_str = arch_strm.GetString();
1297
1298 if (width)
1299 strm.Printf("%-*s", width, arch_str.c_str());
1300 else
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00001301 strm.PutCString(arch_str);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001302 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001303}
1304
Kate Stoneb9c1b512016-09-06 20:57:50 +00001305static void DumpModuleUUID(Stream &strm, Module *module) {
1306 if (module && module->GetUUID().IsValid())
1307 module->GetUUID().Dump(&strm);
1308 else
1309 strm.PutCString(" ");
Greg Claytoneffe5c92011-05-03 22:09:39 +00001310}
1311
Kate Stoneb9c1b512016-09-06 20:57:50 +00001312static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
1313 Stream &strm, Module *module,
1314 const FileSpec &file_spec,
1315 bool load_addresses) {
1316 uint32_t num_matches = 0;
1317 if (module) {
1318 SymbolContextList sc_list;
1319 num_matches = module->ResolveSymbolContextsForFileSpec(
1320 file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1321
1322 for (uint32_t i = 0; i < num_matches; ++i) {
1323 SymbolContext sc;
1324 if (sc_list.GetContextAtIndex(i, sc)) {
1325 if (i > 0)
1326 strm << "\n\n";
1327
1328 strm << "Line table for " << *static_cast<FileSpec *>(sc.comp_unit)
1329 << " in `" << module->GetFileSpec().GetFilename() << "\n";
1330 LineTable *line_table = sc.comp_unit->GetLineTable();
1331 if (line_table)
1332 line_table->GetDescription(
1333 &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1334 lldb::eDescriptionLevelBrief);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001335 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001336 strm << "No line table";
1337 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001338 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001339 }
1340 return num_matches;
1341}
1342
1343static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1344 uint32_t width) {
1345 if (file_spec_ptr) {
1346 if (width > 0) {
1347 std::string fullpath = file_spec_ptr->GetPath();
1348 strm.Printf("%-*s", width, fullpath.c_str());
1349 return;
1350 } else {
1351 file_spec_ptr->Dump(&strm);
1352 return;
1353 }
1354 }
1355 // Keep the width spacing correct if things go wrong...
1356 if (width > 0)
1357 strm.Printf("%-*s", width, "");
1358}
1359
1360static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1361 uint32_t width) {
1362 if (file_spec_ptr) {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001363 if (width > 0)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001364 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1365 else
1366 file_spec_ptr->GetDirectory().Dump(&strm);
1367 return;
1368 }
1369 // Keep the width spacing correct if things go wrong...
1370 if (width > 0)
1371 strm.Printf("%-*s", width, "");
Greg Claytoneffe5c92011-05-03 22:09:39 +00001372}
1373
Kate Stoneb9c1b512016-09-06 20:57:50 +00001374static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1375 uint32_t width) {
1376 if (file_spec_ptr) {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001377 if (width > 0)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001378 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1379 else
1380 file_spec_ptr->GetFilename().Dump(&strm);
1381 return;
1382 }
1383 // Keep the width spacing correct if things go wrong...
1384 if (width > 0)
1385 strm.Printf("%-*s", width, "");
Greg Claytoneffe5c92011-05-03 22:09:39 +00001386}
1387
Kate Stoneb9c1b512016-09-06 20:57:50 +00001388static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1389 size_t num_dumped = 0;
1390 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1391 const size_t num_modules = module_list.GetSize();
1392 if (num_modules > 0) {
1393 strm.Printf("Dumping headers for %" PRIu64 " module(s).\n",
1394 static_cast<uint64_t>(num_modules));
Greg Claytonc4a8a762012-05-15 18:43:44 +00001395 strm.IndentMore();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001396 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1397 Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
1398 if (module) {
1399 if (num_dumped++ > 0) {
1400 strm.EOL();
1401 strm.EOL();
1402 }
1403 ObjectFile *objfile = module->GetObjectFile();
1404 objfile->Dump(&strm);
1405 }
Greg Claytonc4a8a762012-05-15 18:43:44 +00001406 }
1407 strm.IndentLess();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001408 }
1409 return num_dumped;
Greg Claytonc4a8a762012-05-15 18:43:44 +00001410}
1411
Kate Stoneb9c1b512016-09-06 20:57:50 +00001412static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1413 Module *module, SortOrder sort_order) {
1414 if (module) {
1415 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1416 if (sym_vendor) {
1417 Symtab *symtab = sym_vendor->GetSymtab();
1418 if (symtab)
1419 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1420 sort_order);
1421 }
1422 }
1423}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001424
Kate Stoneb9c1b512016-09-06 20:57:50 +00001425static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1426 Module *module) {
1427 if (module) {
1428 SectionList *section_list = module->GetSectionList();
1429 if (section_list) {
1430 strm.Printf("Sections for '%s' (%s):\n",
1431 module->GetSpecificationDescription().c_str(),
1432 module->GetArchitecture().GetArchitectureName());
1433 strm.IndentMore();
1434 section_list->Dump(&strm,
1435 interpreter.GetExecutionContext().GetTargetPtr(), true,
1436 UINT32_MAX);
1437 strm.IndentLess();
1438 }
1439 }
1440}
1441
1442static bool DumpModuleSymbolVendor(Stream &strm, Module *module) {
1443 if (module) {
1444 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1445 if (symbol_vendor) {
1446 symbol_vendor->Dump(&strm);
1447 return true;
1448 }
1449 }
1450 return false;
1451}
1452
1453static void DumpAddress(ExecutionContextScope *exe_scope,
1454 const Address &so_addr, bool verbose, Stream &strm) {
1455 strm.IndentMore();
1456 strm.Indent(" Address: ");
1457 so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1458 strm.PutCString(" (");
1459 so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1460 strm.PutCString(")\n");
1461 strm.Indent(" Summary: ");
1462 const uint32_t save_indent = strm.GetIndentLevel();
1463 strm.SetIndentLevel(save_indent + 13);
1464 so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
1465 strm.SetIndentLevel(save_indent);
1466 // Print out detailed address information when verbose is enabled
1467 if (verbose) {
1468 strm.EOL();
1469 so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1470 }
1471 strm.IndentLess();
1472}
1473
1474static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1475 Module *module, uint32_t resolve_mask,
1476 lldb::addr_t raw_addr, lldb::addr_t offset,
1477 bool verbose) {
1478 if (module) {
1479 lldb::addr_t addr = raw_addr - offset;
1480 Address so_addr;
1481 SymbolContext sc;
1482 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1483 if (target && !target->GetSectionLoadList().IsEmpty()) {
1484 if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
1485 return false;
1486 else if (so_addr.GetModule().get() != module)
1487 return false;
1488 } else {
1489 if (!module->ResolveFileAddress(addr, so_addr))
1490 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001491 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001492
Kate Stoneb9c1b512016-09-06 20:57:50 +00001493 ExecutionContextScope *exe_scope =
1494 interpreter.GetExecutionContext().GetBestExecutionContextScope();
1495 DumpAddress(exe_scope, so_addr, verbose, strm);
1496 // strm.IndentMore();
1497 // strm.Indent (" Address: ");
1498 // so_addr.Dump (&strm, exe_scope,
1499 // Address::DumpStyleModuleWithFileAddress);
1500 // strm.PutCString (" (");
1501 // so_addr.Dump (&strm, exe_scope,
1502 // Address::DumpStyleSectionNameOffset);
1503 // strm.PutCString (")\n");
1504 // strm.Indent (" Summary: ");
1505 // const uint32_t save_indent = strm.GetIndentLevel ();
1506 // strm.SetIndentLevel (save_indent + 13);
1507 // so_addr.Dump (&strm, exe_scope,
1508 // Address::DumpStyleResolvedDescription);
1509 // strm.SetIndentLevel (save_indent);
1510 // // Print out detailed address information when verbose is enabled
1511 // if (verbose)
1512 // {
1513 // strm.EOL();
1514 // so_addr.Dump (&strm, exe_scope,
1515 // Address::DumpStyleDetailedSymbolContext);
1516 // }
1517 // strm.IndentLess();
1518 return true;
1519 }
1520
1521 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001522}
1523
Kate Stoneb9c1b512016-09-06 20:57:50 +00001524static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1525 Stream &strm, Module *module,
1526 const char *name, bool name_is_regex,
1527 bool verbose) {
1528 if (module) {
1529 SymbolContext sc;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001530
Kate Stoneb9c1b512016-09-06 20:57:50 +00001531 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1532 if (sym_vendor) {
1533 Symtab *symtab = sym_vendor->GetSymtab();
1534 if (symtab) {
1535 std::vector<uint32_t> match_indexes;
1536 ConstString symbol_name(name);
1537 uint32_t num_matches = 0;
1538 if (name_is_regex) {
Zachary Turner95eae422016-09-21 16:01:28 +00001539 RegularExpression name_regexp(symbol_name.GetStringRef());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001540 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1541 name_regexp, eSymbolTypeAny, match_indexes);
1542 } else {
1543 num_matches =
1544 symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1545 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001546
Kate Stoneb9c1b512016-09-06 20:57:50 +00001547 if (num_matches > 0) {
1548 strm.Indent();
1549 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1550 name_is_regex ? "the regular expression " : "", name);
1551 DumpFullpath(strm, &module->GetFileSpec(), 0);
1552 strm.PutCString(":\n");
1553 strm.IndentMore();
1554 for (uint32_t i = 0; i < num_matches; ++i) {
1555 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1556 if (symbol && symbol->ValueIsAddress()) {
1557 DumpAddress(interpreter.GetExecutionContext()
1558 .GetBestExecutionContextScope(),
1559 symbol->GetAddressRef(), verbose, strm);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001560 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001561 }
1562 strm.IndentLess();
1563 return num_matches;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001564 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001565 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001566 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001567 }
1568 return 0;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001569}
1570
Kate Stoneb9c1b512016-09-06 20:57:50 +00001571static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
1572 Stream &strm, SymbolContextList &sc_list,
1573 bool verbose) {
1574 strm.IndentMore();
Eugene Zelenkof13e6522016-02-25 19:02:39 +00001575
Kate Stoneb9c1b512016-09-06 20:57:50 +00001576 const uint32_t num_matches = sc_list.GetSize();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001577
Kate Stoneb9c1b512016-09-06 20:57:50 +00001578 for (uint32_t i = 0; i < num_matches; ++i) {
1579 SymbolContext sc;
1580 if (sc_list.GetContextAtIndex(i, sc)) {
1581 AddressRange range;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001582
Kate Stoneb9c1b512016-09-06 20:57:50 +00001583 sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001584
Kate Stoneb9c1b512016-09-06 20:57:50 +00001585 DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001586 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001587 }
1588 strm.IndentLess();
Greg Claytoneffe5c92011-05-03 22:09:39 +00001589}
1590
Kate Stoneb9c1b512016-09-06 20:57:50 +00001591static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
1592 Stream &strm, Module *module,
1593 const char *name, bool name_is_regex,
1594 bool include_inlines, bool include_symbols,
1595 bool verbose) {
1596 if (module && name && name[0]) {
1597 SymbolContextList sc_list;
1598 const bool append = true;
1599 size_t num_matches = 0;
1600 if (name_is_regex) {
Zachary Turner95eae422016-09-21 16:01:28 +00001601 RegularExpression function_name_regex((llvm::StringRef(name)));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001602 num_matches = module->FindFunctions(function_name_regex, include_symbols,
1603 include_inlines, append, sc_list);
1604 } else {
1605 ConstString function_name(name);
1606 num_matches = module->FindFunctions(
1607 function_name, nullptr, eFunctionNameTypeAuto, include_symbols,
1608 include_inlines, append, sc_list);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001609 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001610
Kate Stoneb9c1b512016-09-06 20:57:50 +00001611 if (num_matches) {
1612 strm.Indent();
1613 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1614 num_matches > 1 ? "es" : "");
1615 DumpFullpath(strm, &module->GetFileSpec(), 0);
1616 strm.PutCString(":\n");
1617 DumpSymbolContextList(
1618 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1619 strm, sc_list, verbose);
Sean Callanand38b4a92012-06-06 20:49:55 +00001620 }
1621 return num_matches;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001622 }
1623 return 0;
Sean Callanand38b4a92012-06-06 20:49:55 +00001624}
1625
Kate Stoneb9c1b512016-09-06 20:57:50 +00001626static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
1627 Module *module, const char *name_cstr,
1628 bool name_is_regex) {
1629 if (module && name_cstr && name_cstr[0]) {
1630 TypeList type_list;
1631 const uint32_t max_num_matches = UINT32_MAX;
1632 size_t num_matches = 0;
1633 bool name_is_fully_qualified = false;
1634 SymbolContext sc;
1635
1636 ConstString name(name_cstr);
1637 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1638 num_matches =
1639 module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches,
1640 searched_symbol_files, type_list);
1641
1642 if (num_matches) {
1643 strm.Indent();
1644 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1645 num_matches > 1 ? "es" : "");
1646 DumpFullpath(strm, &module->GetFileSpec(), 0);
1647 strm.PutCString(":\n");
1648 for (TypeSP type_sp : type_list.Types()) {
1649 if (type_sp) {
1650 // Resolve the clang type so that any forward references
1651 // to types that haven't yet been parsed will get parsed.
1652 type_sp->GetFullCompilerType();
1653 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1654 // Print all typedef chains
1655 TypeSP typedef_type_sp(type_sp);
1656 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1657 while (typedefed_type_sp) {
1658 strm.EOL();
1659 strm.Printf(" typedef '%s': ",
1660 typedef_type_sp->GetName().GetCString());
1661 typedefed_type_sp->GetFullCompilerType();
1662 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull,
1663 true);
1664 typedef_type_sp = typedefed_type_sp;
1665 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1666 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001667 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001668 strm.EOL();
1669 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001670 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001671 return num_matches;
1672 }
1673 return 0;
1674}
1675
1676static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
1677 const SymbolContext &sym_ctx,
1678 const char *name_cstr, bool name_is_regex) {
1679 if (!sym_ctx.module_sp)
Greg Claytoneffe5c92011-05-03 22:09:39 +00001680 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001681
1682 TypeList type_list;
1683 const uint32_t max_num_matches = UINT32_MAX;
1684 size_t num_matches = 1;
1685 bool name_is_fully_qualified = false;
1686
1687 ConstString name(name_cstr);
1688 llvm::DenseSet<SymbolFile *> searched_symbol_files;
1689 num_matches = sym_ctx.module_sp->FindTypes(
1690 sym_ctx, name, name_is_fully_qualified, max_num_matches,
1691 searched_symbol_files, type_list);
1692
1693 if (num_matches) {
1694 strm.Indent();
1695 strm.PutCString("Best match found in ");
1696 DumpFullpath(strm, &sym_ctx.module_sp->GetFileSpec(), 0);
1697 strm.PutCString(":\n");
1698
1699 TypeSP type_sp(type_list.GetTypeAtIndex(0));
1700 if (type_sp) {
1701 // Resolve the clang type so that any forward references
1702 // to types that haven't yet been parsed will get parsed.
1703 type_sp->GetFullCompilerType();
1704 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1705 // Print all typedef chains
1706 TypeSP typedef_type_sp(type_sp);
1707 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1708 while (typedefed_type_sp) {
1709 strm.EOL();
1710 strm.Printf(" typedef '%s': ",
1711 typedef_type_sp->GetName().GetCString());
1712 typedefed_type_sp->GetFullCompilerType();
1713 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1714 typedef_type_sp = typedefed_type_sp;
1715 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1716 }
1717 }
1718 strm.EOL();
1719 }
1720 return num_matches;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001721}
1722
Kate Stoneb9c1b512016-09-06 20:57:50 +00001723static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
1724 Stream &strm, Module *module,
1725 const FileSpec &file_spec,
1726 uint32_t line, bool check_inlines,
1727 bool verbose) {
1728 if (module && file_spec) {
1729 SymbolContextList sc_list;
1730 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1731 file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1732 if (num_matches > 0) {
1733 strm.Indent();
1734 strm.Printf("%u match%s found in ", num_matches,
1735 num_matches > 1 ? "es" : "");
1736 strm << file_spec;
1737 if (line > 0)
1738 strm.Printf(":%u", line);
1739 strm << " in ";
1740 DumpFullpath(strm, &module->GetFileSpec(), 0);
1741 strm.PutCString(":\n");
1742 DumpSymbolContextList(
1743 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1744 strm, sc_list, verbose);
1745 return num_matches;
Greg Clayton8ee64382011-11-10 01:18:58 +00001746 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001747 }
1748 return 0;
1749}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001750
Kate Stoneb9c1b512016-09-06 20:57:50 +00001751static size_t FindModulesByName(Target *target, const char *module_name,
1752 ModuleList &module_list,
1753 bool check_global_list) {
1754 FileSpec module_file_spec(module_name, false);
1755 ModuleSpec module_spec(module_file_spec);
1756
1757 const size_t initial_size = module_list.GetSize();
1758
1759 if (check_global_list) {
1760 // Check the global list
1761 std::lock_guard<std::recursive_mutex> guard(
1762 Module::GetAllocationModuleCollectionMutex());
1763 const size_t num_modules = Module::GetNumberAllocatedModules();
1764 ModuleSP module_sp;
1765 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1766 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1767
1768 if (module) {
1769 if (module->MatchesModuleSpec(module_spec)) {
1770 module_sp = module->shared_from_this();
1771 module_list.AppendIfNeeded(module_sp);
Greg Claytonf3156262012-07-11 20:46:47 +00001772 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001773 }
Greg Claytonf3156262012-07-11 20:46:47 +00001774 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001775 } else {
1776 if (target) {
1777 const size_t num_matches =
1778 target->GetImages().FindModules(module_spec, module_list);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001779
Kate Stoneb9c1b512016-09-06 20:57:50 +00001780 // Not found in our module list for our target, check the main
1781 // shared module list in case it is a extra file used somewhere
1782 // else
1783 if (num_matches == 0) {
1784 module_spec.GetArchitecture() = target->GetArchitecture();
1785 ModuleList::FindSharedModules(module_spec, module_list);
1786 }
1787 } else {
1788 ModuleList::FindSharedModules(module_spec, module_list);
1789 }
1790 }
1791
1792 return module_list.GetSize() - initial_size;
Greg Clayton8ee64382011-11-10 01:18:58 +00001793}
1794
Greg Claytoneffe5c92011-05-03 22:09:39 +00001795#pragma mark CommandObjectTargetModulesModuleAutoComplete
1796
1797//----------------------------------------------------------------------
1798// A base command object class that can auto complete with module file
1799// paths
1800//----------------------------------------------------------------------
1801
Kate Stoneb9c1b512016-09-06 20:57:50 +00001802class CommandObjectTargetModulesModuleAutoComplete
1803 : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001804public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001805 CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1806 const char *name,
1807 const char *help,
1808 const char *syntax)
1809 : CommandObjectParsed(interpreter, name, help, syntax) {
1810 CommandArgumentEntry arg;
1811 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001812
Kate Stoneb9c1b512016-09-06 20:57:50 +00001813 // Define the first (and only) variant of this arg.
1814 file_arg.arg_type = eArgTypeFilename;
1815 file_arg.arg_repetition = eArgRepeatStar;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001816
Kate Stoneb9c1b512016-09-06 20:57:50 +00001817 // There is only one variant this argument could be; put it into the
1818 // argument entry.
1819 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001820
Kate Stoneb9c1b512016-09-06 20:57:50 +00001821 // Push the data for the first argument into the m_arguments vector.
1822 m_arguments.push_back(arg);
1823 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001824
Kate Stoneb9c1b512016-09-06 20:57:50 +00001825 ~CommandObjectTargetModulesModuleAutoComplete() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001826
Kate Stoneb9c1b512016-09-06 20:57:50 +00001827 int HandleArgumentCompletion(Args &input, int &cursor_index,
1828 int &cursor_char_position,
1829 OptionElementVector &opt_element_vector,
1830 int match_start_point, int max_return_elements,
1831 bool &word_complete,
1832 StringList &matches) override {
1833 // Arguments are the standard module completer.
1834 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
1835 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001836
Kate Stoneb9c1b512016-09-06 20:57:50 +00001837 CommandCompletions::InvokeCommonCompletionCallbacks(
1838 GetCommandInterpreter(), CommandCompletions::eModuleCompletion,
1839 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
1840 word_complete, matches);
1841 return matches.GetSize();
1842 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001843};
1844
1845#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1846
1847//----------------------------------------------------------------------
1848// A base command object class that can auto complete with module source
1849// file paths
1850//----------------------------------------------------------------------
1851
Kate Stoneb9c1b512016-09-06 20:57:50 +00001852class CommandObjectTargetModulesSourceFileAutoComplete
1853 : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001854public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001855 CommandObjectTargetModulesSourceFileAutoComplete(
1856 CommandInterpreter &interpreter, const char *name, const char *help,
1857 const char *syntax, uint32_t flags)
1858 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1859 CommandArgumentEntry arg;
1860 CommandArgumentData source_file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001861
Kate Stoneb9c1b512016-09-06 20:57:50 +00001862 // Define the first (and only) variant of this arg.
1863 source_file_arg.arg_type = eArgTypeSourceFile;
1864 source_file_arg.arg_repetition = eArgRepeatPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001865
Kate Stoneb9c1b512016-09-06 20:57:50 +00001866 // There is only one variant this argument could be; put it into the
1867 // argument entry.
1868 arg.push_back(source_file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001869
Kate Stoneb9c1b512016-09-06 20:57:50 +00001870 // Push the data for the first argument into the m_arguments vector.
1871 m_arguments.push_back(arg);
1872 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001873
Kate Stoneb9c1b512016-09-06 20:57:50 +00001874 ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001875
Kate Stoneb9c1b512016-09-06 20:57:50 +00001876 int HandleArgumentCompletion(Args &input, int &cursor_index,
1877 int &cursor_char_position,
1878 OptionElementVector &opt_element_vector,
1879 int match_start_point, int max_return_elements,
1880 bool &word_complete,
1881 StringList &matches) override {
1882 // Arguments are the standard source file completer.
1883 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
1884 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001885
Kate Stoneb9c1b512016-09-06 20:57:50 +00001886 CommandCompletions::InvokeCommonCompletionCallbacks(
1887 GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
1888 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
1889 word_complete, matches);
1890 return matches.GetSize();
1891 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001892};
1893
Adrian McCarthy543725c2016-04-04 21:21:49 +00001894#pragma mark CommandObjectTargetModulesDumpObjfile
1895
Kate Stoneb9c1b512016-09-06 20:57:50 +00001896class CommandObjectTargetModulesDumpObjfile
1897 : public CommandObjectTargetModulesModuleAutoComplete {
Adrian McCarthy543725c2016-04-04 21:21:49 +00001898public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001899 CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
1900 : CommandObjectTargetModulesModuleAutoComplete(
1901 interpreter, "target modules dump objfile",
1902 "Dump the object file headers from one or more target modules.",
1903 nullptr) {}
Adrian McCarthy543725c2016-04-04 21:21:49 +00001904
Kate Stoneb9c1b512016-09-06 20:57:50 +00001905 ~CommandObjectTargetModulesDumpObjfile() override = default;
Adrian McCarthy543725c2016-04-04 21:21:49 +00001906
1907protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001908 bool DoExecute(Args &command, CommandReturnObject &result) override {
1909 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1910 if (target == nullptr) {
1911 result.AppendError("invalid target, create a debug target using the "
1912 "'target create' command");
1913 result.SetStatus(eReturnStatusFailed);
1914 return false;
Adrian McCarthy543725c2016-04-04 21:21:49 +00001915 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001916
1917 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1918 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1919 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1920
1921 size_t num_dumped = 0;
1922 if (command.GetArgumentCount() == 0) {
1923 // Dump all headers for all modules images
1924 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1925 target->GetImages());
1926 if (num_dumped == 0) {
1927 result.AppendError("the target has no associated executable images");
1928 result.SetStatus(eReturnStatusFailed);
1929 }
1930 } else {
1931 // Find the modules that match the basename or full path.
1932 ModuleList module_list;
1933 const char *arg_cstr;
1934 for (int arg_idx = 0;
1935 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1936 ++arg_idx) {
1937 size_t num_matched =
1938 FindModulesByName(target, arg_cstr, module_list, true);
1939 if (num_matched == 0) {
1940 result.AppendWarningWithFormat(
1941 "Unable to find an image that matches '%s'.\n", arg_cstr);
1942 }
1943 }
1944 // Dump all the modules we found.
1945 num_dumped =
1946 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1947 }
1948
1949 if (num_dumped > 0) {
1950 result.SetStatus(eReturnStatusSuccessFinishResult);
1951 } else {
1952 result.AppendError("no matching executable images found");
1953 result.SetStatus(eReturnStatusFailed);
1954 }
1955 return result.Succeeded();
1956 }
Adrian McCarthy543725c2016-04-04 21:21:49 +00001957};
1958
Greg Claytoneffe5c92011-05-03 22:09:39 +00001959#pragma mark CommandObjectTargetModulesDumpSymtab
1960
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001961static OptionEnumValueElement g_sort_option_enumeration[4] = {
1962 {eSortOrderNone, "none",
1963 "No sorting, use the original symbol table order."},
1964 {eSortOrderByAddress, "address", "Sort output by symbol address."},
1965 {eSortOrderByName, "name", "Sort output by symbol name."},
1966 {0, nullptr, nullptr}};
1967
1968static OptionDefinition g_target_modules_dump_symtab_options[] = {
1969 // clang-format off
1970 { 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." }
1971 // clang-format on
1972};
1973
Kate Stoneb9c1b512016-09-06 20:57:50 +00001974class CommandObjectTargetModulesDumpSymtab
1975 : public CommandObjectTargetModulesModuleAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001976public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001977 CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
1978 : CommandObjectTargetModulesModuleAutoComplete(
1979 interpreter, "target modules dump symtab",
1980 "Dump the symbol table from one or more target modules.", nullptr),
1981 m_options() {}
1982
1983 ~CommandObjectTargetModulesDumpSymtab() override = default;
1984
1985 Options *GetOptions() override { return &m_options; }
1986
1987 class CommandOptions : public Options {
1988 public:
1989 CommandOptions() : Options(), m_sort_order(eSortOrderNone) {}
1990
1991 ~CommandOptions() override = default;
1992
Zachary Turnerfe114832016-11-12 16:56:47 +00001993 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001994 ExecutionContext *execution_context) override {
1995 Error error;
1996 const int short_option = m_getopt_table[option_idx].val;
1997
1998 switch (short_option) {
1999 case 's':
2000 m_sort_order = (SortOrder)Args::StringToOptionEnum(
Zachary Turnerfe114832016-11-12 16:56:47 +00002001 option_arg, GetDefinitions()[option_idx].enum_values,
2002 eSortOrderNone, error);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002003 break;
2004
2005 default:
2006 error.SetErrorStringWithFormat("invalid short option character '%c'",
2007 short_option);
2008 break;
2009 }
2010 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002011 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002012
Kate Stoneb9c1b512016-09-06 20:57:50 +00002013 void OptionParsingStarting(ExecutionContext *execution_context) override {
2014 m_sort_order = eSortOrderNone;
Jim Ingham5a988412012-06-08 21:56:10 +00002015 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002016
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002017 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00002018 return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002019 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002020
Kate Stoneb9c1b512016-09-06 20:57:50 +00002021 SortOrder m_sort_order;
2022 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002023
Jim Ingham5a988412012-06-08 21:56:10 +00002024protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002025 bool DoExecute(Args &command, CommandReturnObject &result) override {
2026 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2027 if (target == nullptr) {
2028 result.AppendError("invalid target, create a debug target using the "
2029 "'target create' command");
2030 result.SetStatus(eReturnStatusFailed);
2031 return false;
2032 } else {
2033 uint32_t num_dumped = 0;
2034
2035 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2036 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2037 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2038
2039 if (command.GetArgumentCount() == 0) {
2040 // Dump all sections for all modules images
2041 std::lock_guard<std::recursive_mutex> guard(
2042 target->GetImages().GetMutex());
2043 const size_t num_modules = target->GetImages().GetSize();
2044 if (num_modules > 0) {
2045 result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
2046 " modules.\n",
2047 (uint64_t)num_modules);
2048 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2049 if (num_dumped > 0) {
2050 result.GetOutputStream().EOL();
2051 result.GetOutputStream().EOL();
2052 }
2053 num_dumped++;
2054 DumpModuleSymtab(
2055 m_interpreter, result.GetOutputStream(),
2056 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2057 m_options.m_sort_order);
2058 }
2059 } else {
2060 result.AppendError("the target has no associated executable images");
2061 result.SetStatus(eReturnStatusFailed);
2062 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002063 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002064 } else {
2065 // Dump specified images (by basename or fullpath)
2066 const char *arg_cstr;
2067 for (int arg_idx = 0;
2068 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2069 ++arg_idx) {
2070 ModuleList module_list;
2071 const size_t num_matches =
2072 FindModulesByName(target, arg_cstr, module_list, true);
2073 if (num_matches > 0) {
2074 for (size_t i = 0; i < num_matches; ++i) {
2075 Module *module = module_list.GetModulePointerAtIndex(i);
2076 if (module) {
2077 if (num_dumped > 0) {
2078 result.GetOutputStream().EOL();
2079 result.GetOutputStream().EOL();
Greg Claytoneffe5c92011-05-03 22:09:39 +00002080 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002081 num_dumped++;
2082 DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2083 module, m_options.m_sort_order);
2084 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002085 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002086 } else
2087 result.AppendWarningWithFormat(
2088 "Unable to find an image that matches '%s'.\n", arg_cstr);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002089 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002090 }
2091
2092 if (num_dumped > 0)
2093 result.SetStatus(eReturnStatusSuccessFinishResult);
2094 else {
2095 result.AppendError("no matching executable images found");
2096 result.SetStatus(eReturnStatusFailed);
2097 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002098 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002099 return result.Succeeded();
2100 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002101
Kate Stoneb9c1b512016-09-06 20:57:50 +00002102 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002103};
2104
Greg Claytoneffe5c92011-05-03 22:09:39 +00002105#pragma mark CommandObjectTargetModulesDumpSections
2106
2107//----------------------------------------------------------------------
2108// Image section dumping command
2109//----------------------------------------------------------------------
2110
Kate Stoneb9c1b512016-09-06 20:57:50 +00002111class CommandObjectTargetModulesDumpSections
2112 : public CommandObjectTargetModulesModuleAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002113public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002114 CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
2115 : CommandObjectTargetModulesModuleAutoComplete(
2116 interpreter, "target modules dump sections",
2117 "Dump the sections from one or more target modules.",
2118 //"target modules dump sections [<file1> ...]")
2119 nullptr) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002120
Kate Stoneb9c1b512016-09-06 20:57:50 +00002121 ~CommandObjectTargetModulesDumpSections() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002122
Jim Ingham5a988412012-06-08 21:56:10 +00002123protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002124 bool DoExecute(Args &command, CommandReturnObject &result) override {
2125 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2126 if (target == nullptr) {
2127 result.AppendError("invalid target, create a debug target using the "
2128 "'target create' command");
2129 result.SetStatus(eReturnStatusFailed);
2130 return false;
2131 } else {
2132 uint32_t num_dumped = 0;
2133
2134 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2135 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2136 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2137
2138 if (command.GetArgumentCount() == 0) {
2139 // Dump all sections for all modules images
2140 const size_t num_modules = target->GetImages().GetSize();
2141 if (num_modules > 0) {
2142 result.GetOutputStream().Printf("Dumping sections for %" PRIu64
2143 " modules.\n",
2144 (uint64_t)num_modules);
2145 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2146 num_dumped++;
2147 DumpModuleSections(
2148 m_interpreter, result.GetOutputStream(),
2149 target->GetImages().GetModulePointerAtIndex(image_idx));
2150 }
2151 } else {
2152 result.AppendError("the target has no associated executable images");
2153 result.SetStatus(eReturnStatusFailed);
2154 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002155 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002156 } else {
2157 // Dump specified images (by basename or fullpath)
2158 const char *arg_cstr;
2159 for (int arg_idx = 0;
2160 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2161 ++arg_idx) {
2162 ModuleList module_list;
2163 const size_t num_matches =
2164 FindModulesByName(target, arg_cstr, module_list, true);
2165 if (num_matches > 0) {
2166 for (size_t i = 0; i < num_matches; ++i) {
2167 Module *module = module_list.GetModulePointerAtIndex(i);
2168 if (module) {
2169 num_dumped++;
2170 DumpModuleSections(m_interpreter, result.GetOutputStream(),
2171 module);
2172 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002173 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002174 } else {
2175 // Check the global list
2176 std::lock_guard<std::recursive_mutex> guard(
2177 Module::GetAllocationModuleCollectionMutex());
Greg Clayton8ee64382011-11-10 01:18:58 +00002178
Kate Stoneb9c1b512016-09-06 20:57:50 +00002179 result.AppendWarningWithFormat(
2180 "Unable to find an image that matches '%s'.\n", arg_cstr);
2181 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002182 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002183 }
2184
2185 if (num_dumped > 0)
2186 result.SetStatus(eReturnStatusSuccessFinishResult);
2187 else {
2188 result.AppendError("no matching executable images found");
2189 result.SetStatus(eReturnStatusFailed);
2190 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002191 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002192 return result.Succeeded();
2193 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002194};
2195
Greg Claytoneffe5c92011-05-03 22:09:39 +00002196#pragma mark CommandObjectTargetModulesDumpSymfile
2197
2198//----------------------------------------------------------------------
2199// Image debug symbol dumping command
2200//----------------------------------------------------------------------
2201
Kate Stoneb9c1b512016-09-06 20:57:50 +00002202class CommandObjectTargetModulesDumpSymfile
2203 : public CommandObjectTargetModulesModuleAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002204public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002205 CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
2206 : CommandObjectTargetModulesModuleAutoComplete(
2207 interpreter, "target modules dump symfile",
2208 "Dump the debug symbol file for one or more target modules.",
2209 //"target modules dump symfile [<file1> ...]")
2210 nullptr) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002211
Kate Stoneb9c1b512016-09-06 20:57:50 +00002212 ~CommandObjectTargetModulesDumpSymfile() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002213
Jim Ingham5a988412012-06-08 21:56:10 +00002214protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002215 bool DoExecute(Args &command, CommandReturnObject &result) override {
2216 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2217 if (target == nullptr) {
2218 result.AppendError("invalid target, create a debug target using the "
2219 "'target create' command");
2220 result.SetStatus(eReturnStatusFailed);
2221 return false;
2222 } else {
2223 uint32_t num_dumped = 0;
2224
2225 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2226 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2227 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2228
2229 if (command.GetArgumentCount() == 0) {
2230 // Dump all sections for all modules images
2231 const ModuleList &target_modules = target->GetImages();
2232 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2233 const size_t num_modules = target_modules.GetSize();
2234 if (num_modules > 0) {
2235 result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
2236 " modules.\n",
2237 (uint64_t)num_modules);
2238 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2239 if (DumpModuleSymbolVendor(
2240 result.GetOutputStream(),
2241 target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2242 num_dumped++;
2243 }
2244 } else {
2245 result.AppendError("the target has no associated executable images");
2246 result.SetStatus(eReturnStatusFailed);
2247 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002248 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002249 } else {
2250 // Dump specified images (by basename or fullpath)
2251 const char *arg_cstr;
2252 for (int arg_idx = 0;
2253 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2254 ++arg_idx) {
2255 ModuleList module_list;
2256 const size_t num_matches =
2257 FindModulesByName(target, arg_cstr, module_list, true);
2258 if (num_matches > 0) {
2259 for (size_t i = 0; i < num_matches; ++i) {
2260 Module *module = module_list.GetModulePointerAtIndex(i);
2261 if (module) {
2262 if (DumpModuleSymbolVendor(result.GetOutputStream(), module))
2263 num_dumped++;
2264 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002265 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002266 } else
2267 result.AppendWarningWithFormat(
2268 "Unable to find an image that matches '%s'.\n", arg_cstr);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002269 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002270 }
2271
2272 if (num_dumped > 0)
2273 result.SetStatus(eReturnStatusSuccessFinishResult);
2274 else {
2275 result.AppendError("no matching executable images found");
2276 result.SetStatus(eReturnStatusFailed);
2277 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002278 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002279 return result.Succeeded();
2280 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002281};
2282
Greg Claytoneffe5c92011-05-03 22:09:39 +00002283#pragma mark CommandObjectTargetModulesDumpLineTable
2284
2285//----------------------------------------------------------------------
2286// Image debug line table dumping command
2287//----------------------------------------------------------------------
2288
Kate Stoneb9c1b512016-09-06 20:57:50 +00002289class CommandObjectTargetModulesDumpLineTable
2290 : public CommandObjectTargetModulesSourceFileAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002291public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002292 CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
2293 : CommandObjectTargetModulesSourceFileAutoComplete(
2294 interpreter, "target modules dump line-table",
2295 "Dump the line table for one or more compilation units.", nullptr,
2296 eCommandRequiresTarget) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002297
Kate Stoneb9c1b512016-09-06 20:57:50 +00002298 ~CommandObjectTargetModulesDumpLineTable() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002299
Jim Ingham5a988412012-06-08 21:56:10 +00002300protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002301 bool DoExecute(Args &command, CommandReturnObject &result) override {
2302 Target *target = m_exe_ctx.GetTargetPtr();
2303 uint32_t total_num_dumped = 0;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002304
Kate Stoneb9c1b512016-09-06 20:57:50 +00002305 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2306 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2307 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002308
Kate Stoneb9c1b512016-09-06 20:57:50 +00002309 if (command.GetArgumentCount() == 0) {
2310 result.AppendError("file option must be specified.");
2311 result.SetStatus(eReturnStatusFailed);
2312 return result.Succeeded();
2313 } else {
2314 // Dump specified images (by basename or fullpath)
2315 const char *arg_cstr;
2316 for (int arg_idx = 0;
2317 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2318 ++arg_idx) {
2319 FileSpec file_spec(arg_cstr, false);
2320
2321 const ModuleList &target_modules = target->GetImages();
2322 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2323 const size_t num_modules = target_modules.GetSize();
2324 if (num_modules > 0) {
2325 uint32_t num_dumped = 0;
2326 for (uint32_t i = 0; i < num_modules; ++i) {
2327 if (DumpCompileUnitLineTable(
2328 m_interpreter, result.GetOutputStream(),
2329 target_modules.GetModulePointerAtIndexUnlocked(i),
2330 file_spec, m_exe_ctx.GetProcessPtr() &&
2331 m_exe_ctx.GetProcessRef().IsAlive()))
2332 num_dumped++;
2333 }
2334 if (num_dumped == 0)
2335 result.AppendWarningWithFormat(
2336 "No source filenames matched '%s'.\n", arg_cstr);
2337 else
2338 total_num_dumped += num_dumped;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002339 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002340 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002341 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002342
2343 if (total_num_dumped > 0)
2344 result.SetStatus(eReturnStatusSuccessFinishResult);
2345 else {
2346 result.AppendError("no source filenames matched any command arguments");
2347 result.SetStatus(eReturnStatusFailed);
2348 }
2349 return result.Succeeded();
2350 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002351};
2352
Greg Claytoneffe5c92011-05-03 22:09:39 +00002353#pragma mark CommandObjectTargetModulesDump
2354
2355//----------------------------------------------------------------------
2356// Dump multi-word command for target modules
2357//----------------------------------------------------------------------
2358
Kate Stoneb9c1b512016-09-06 20:57:50 +00002359class CommandObjectTargetModulesDump : public CommandObjectMultiword {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002360public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002361 //------------------------------------------------------------------
2362 // Constructors and Destructors
2363 //------------------------------------------------------------------
2364 CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2365 : CommandObjectMultiword(interpreter, "target modules dump",
2366 "Commands for dumping information about one or "
2367 "more target modules.",
2368 "target modules dump "
2369 "[headers|symtab|sections|symfile|line-table] "
2370 "[<file1> <file2> ...]") {
2371 LoadSubCommand("objfile",
2372 CommandObjectSP(
2373 new CommandObjectTargetModulesDumpObjfile(interpreter)));
2374 LoadSubCommand(
2375 "symtab",
2376 CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
2377 LoadSubCommand("sections",
2378 CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2379 interpreter)));
2380 LoadSubCommand("symfile",
2381 CommandObjectSP(
2382 new CommandObjectTargetModulesDumpSymfile(interpreter)));
2383 LoadSubCommand("line-table",
2384 CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2385 interpreter)));
2386 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002387
Kate Stoneb9c1b512016-09-06 20:57:50 +00002388 ~CommandObjectTargetModulesDump() override = default;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002389};
2390
Kate Stoneb9c1b512016-09-06 20:57:50 +00002391class CommandObjectTargetModulesAdd : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002392public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002393 CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
2394 : CommandObjectParsed(interpreter, "target modules add",
2395 "Add a new module to the current target's modules.",
2396 "target modules add [<module>]"),
Todd Fialae1cfbc72016-08-11 23:51:28 +00002397 m_option_group(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00002398 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2399 eArgTypeFilename, "Fullpath to a stand alone debug "
2400 "symbols file for when debug symbols "
2401 "are not in the executable.") {
2402 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2403 LLDB_OPT_SET_1);
2404 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2405 m_option_group.Finalize();
2406 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002407
Kate Stoneb9c1b512016-09-06 20:57:50 +00002408 ~CommandObjectTargetModulesAdd() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002409
Kate Stoneb9c1b512016-09-06 20:57:50 +00002410 Options *GetOptions() override { return &m_option_group; }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002411
Kate Stoneb9c1b512016-09-06 20:57:50 +00002412 int HandleArgumentCompletion(Args &input, int &cursor_index,
2413 int &cursor_char_position,
2414 OptionElementVector &opt_element_vector,
2415 int match_start_point, int max_return_elements,
2416 bool &word_complete,
2417 StringList &matches) override {
2418 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
2419 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002420
Kate Stoneb9c1b512016-09-06 20:57:50 +00002421 CommandCompletions::InvokeCommonCompletionCallbacks(
2422 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2423 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
2424 word_complete, matches);
2425 return matches.GetSize();
2426 }
Jim Ingham5a988412012-06-08 21:56:10 +00002427
2428protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002429 OptionGroupOptions m_option_group;
2430 OptionGroupUUID m_uuid_option_group;
2431 OptionGroupFile m_symbol_file;
Greg Clayton50a24bd2012-11-29 22:16:27 +00002432
Kate Stoneb9c1b512016-09-06 20:57:50 +00002433 bool DoExecute(Args &args, CommandReturnObject &result) override {
2434 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2435 if (target == nullptr) {
2436 result.AppendError("invalid target, create a debug target using the "
2437 "'target create' command");
2438 result.SetStatus(eReturnStatusFailed);
2439 return false;
2440 } else {
2441 bool flush = false;
2442
2443 const size_t argc = args.GetArgumentCount();
2444 if (argc == 0) {
2445 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2446 // We are given a UUID only, go locate the file
2447 ModuleSpec module_spec;
2448 module_spec.GetUUID() =
2449 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2450 if (m_symbol_file.GetOptionValue().OptionWasSet())
2451 module_spec.GetSymbolFileSpec() =
2452 m_symbol_file.GetOptionValue().GetCurrentValue();
2453 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
2454 ModuleSP module_sp(target->GetSharedModule(module_spec));
2455 if (module_sp) {
2456 result.SetStatus(eReturnStatusSuccessFinishResult);
2457 return true;
2458 } else {
2459 StreamString strm;
2460 module_spec.GetUUID().Dump(&strm);
2461 if (module_spec.GetFileSpec()) {
2462 if (module_spec.GetSymbolFileSpec()) {
2463 result.AppendErrorWithFormat(
2464 "Unable to create the executable or symbol file with "
2465 "UUID %s with path %s and symbol file %s",
Zachary Turnerc1564272016-11-16 21:15:24 +00002466 strm.GetData(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00002467 module_spec.GetFileSpec().GetPath().c_str(),
2468 module_spec.GetSymbolFileSpec().GetPath().c_str());
2469 } else {
2470 result.AppendErrorWithFormat(
2471 "Unable to create the executable or symbol file with "
2472 "UUID %s with path %s",
Zachary Turnerc1564272016-11-16 21:15:24 +00002473 strm.GetData(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00002474 module_spec.GetFileSpec().GetPath().c_str());
2475 }
2476 } else {
2477 result.AppendErrorWithFormat("Unable to create the executable "
2478 "or symbol file with UUID %s",
Zachary Turnerc1564272016-11-16 21:15:24 +00002479 strm.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002480 }
2481 result.SetStatus(eReturnStatusFailed);
2482 return false;
2483 }
2484 } else {
2485 StreamString strm;
2486 module_spec.GetUUID().Dump(&strm);
2487 result.AppendErrorWithFormat(
2488 "Unable to locate the executable or symbol file with UUID %s",
Zachary Turnerc1564272016-11-16 21:15:24 +00002489 strm.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002490 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002491 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002492 }
2493 } else {
2494 result.AppendError(
2495 "one or more executable image paths must be specified");
2496 result.SetStatus(eReturnStatusFailed);
2497 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002498 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002499 } else {
Zachary Turner97d2c402016-10-05 23:40:23 +00002500 for (auto &entry : args.entries()) {
2501 if (entry.ref.empty())
2502 continue;
2503
2504 FileSpec file_spec(entry.ref, true);
2505 if (file_spec.Exists()) {
2506 ModuleSpec module_spec(file_spec);
2507 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2508 module_spec.GetUUID() =
2509 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2510 if (m_symbol_file.GetOptionValue().OptionWasSet())
2511 module_spec.GetSymbolFileSpec() =
2512 m_symbol_file.GetOptionValue().GetCurrentValue();
2513 if (!module_spec.GetArchitecture().IsValid())
2514 module_spec.GetArchitecture() = target->GetArchitecture();
2515 Error error;
2516 ModuleSP module_sp(target->GetSharedModule(module_spec, &error));
2517 if (!module_sp) {
2518 const char *error_cstr = error.AsCString();
2519 if (error_cstr)
2520 result.AppendError(error_cstr);
2521 else
2522 result.AppendErrorWithFormat("unsupported module: %s",
2523 entry.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002524 result.SetStatus(eReturnStatusFailed);
Zachary Turner97d2c402016-10-05 23:40:23 +00002525 return false;
2526 } else {
2527 flush = true;
2528 }
2529 result.SetStatus(eReturnStatusSuccessFinishResult);
2530 } else {
2531 std::string resolved_path = file_spec.GetPath();
2532 result.SetStatus(eReturnStatusFailed);
2533 if (resolved_path != entry.ref) {
2534 result.AppendErrorWithFormat(
2535 "invalid module path '%s' with resolved path '%s'\n",
2536 entry.ref.str().c_str(), resolved_path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002537 break;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002538 }
Zachary Turner97d2c402016-10-05 23:40:23 +00002539 result.AppendErrorWithFormat("invalid module path '%s'\n",
2540 entry.c_str());
2541 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002542 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002543 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002544 }
2545
2546 if (flush) {
2547 ProcessSP process = target->GetProcessSP();
2548 if (process)
2549 process->Flush();
2550 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002551 }
2552
Kate Stoneb9c1b512016-09-06 20:57:50 +00002553 return result.Succeeded();
2554 }
2555};
2556
2557class CommandObjectTargetModulesLoad
2558 : public CommandObjectTargetModulesModuleAutoComplete {
2559public:
2560 CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
2561 : CommandObjectTargetModulesModuleAutoComplete(
2562 interpreter, "target modules load", "Set the load addresses for "
2563 "one or more sections in a "
2564 "target module.",
2565 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2566 "<address> [<sect-name> <address> ....]"),
2567 m_option_group(),
2568 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2569 "Fullpath or basename for module to load.", ""),
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002570 m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
2571 "Write file contents to the memory.",
2572 false, true),
Kate Stoneb9c1b512016-09-06 20:57:50 +00002573 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2574 "Set the load address for all sections to be the "
2575 "virtual address in the file plus the offset.",
2576 0) {
2577 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2578 LLDB_OPT_SET_1);
2579 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002580 m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002581 m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2582 m_option_group.Finalize();
2583 }
2584
2585 ~CommandObjectTargetModulesLoad() override = default;
2586
2587 Options *GetOptions() override { return &m_option_group; }
2588
2589protected:
2590 bool DoExecute(Args &args, CommandReturnObject &result) override {
2591 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002592 const bool load = m_load_option.GetOptionValue().GetCurrentValue();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002593 if (target == nullptr) {
2594 result.AppendError("invalid target, create a debug target using the "
2595 "'target create' command");
2596 result.SetStatus(eReturnStatusFailed);
2597 return false;
2598 } else {
2599 const size_t argc = args.GetArgumentCount();
2600 ModuleSpec module_spec;
2601 bool search_using_module_spec = false;
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002602
2603 // Allow "load" option to work without --file or --uuid
2604 // option.
2605 if (load) {
2606 if (!m_file_option.GetOptionValue().OptionWasSet() &&
2607 !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2608 ModuleList &module_list = target->GetImages();
2609 if (module_list.GetSize() == 1) {
2610 search_using_module_spec = true;
2611 module_spec.GetFileSpec() =
2612 module_list.GetModuleAtIndex(0)->GetFileSpec();
2613 }
2614 }
2615 }
2616
Kate Stoneb9c1b512016-09-06 20:57:50 +00002617 if (m_file_option.GetOptionValue().OptionWasSet()) {
2618 search_using_module_spec = true;
2619 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2620 const bool use_global_module_list = true;
2621 ModuleList module_list;
2622 const size_t num_matches = FindModulesByName(
2623 target, arg_cstr, module_list, use_global_module_list);
2624 if (num_matches == 1) {
2625 module_spec.GetFileSpec() =
2626 module_list.GetModuleAtIndex(0)->GetFileSpec();
2627 } else if (num_matches > 1) {
2628 search_using_module_spec = false;
2629 result.AppendErrorWithFormat(
2630 "more than 1 module matched by name '%s'\n", arg_cstr);
2631 result.SetStatus(eReturnStatusFailed);
2632 } else {
2633 search_using_module_spec = false;
2634 result.AppendErrorWithFormat("no object file for module '%s'\n",
2635 arg_cstr);
2636 result.SetStatus(eReturnStatusFailed);
2637 }
2638 }
2639
2640 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2641 search_using_module_spec = true;
2642 module_spec.GetUUID() =
2643 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2644 }
2645
2646 if (search_using_module_spec) {
2647 ModuleList matching_modules;
2648 const size_t num_matches =
2649 target->GetImages().FindModules(module_spec, matching_modules);
2650
2651 char path[PATH_MAX];
2652 if (num_matches == 1) {
2653 Module *module = matching_modules.GetModulePointerAtIndex(0);
2654 if (module) {
2655 ObjectFile *objfile = module->GetObjectFile();
2656 if (objfile) {
2657 SectionList *section_list = module->GetSectionList();
2658 if (section_list) {
2659 bool changed = false;
2660 if (argc == 0) {
2661 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2662 const addr_t slide =
2663 m_slide_option.GetOptionValue().GetCurrentValue();
2664 const bool slide_is_offset = true;
2665 module->SetLoadAddress(*target, slide, slide_is_offset,
2666 changed);
2667 } else {
2668 result.AppendError("one or more section name + load "
2669 "address pair must be specified");
2670 result.SetStatus(eReturnStatusFailed);
2671 return false;
2672 }
2673 } else {
2674 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2675 result.AppendError("The \"--slide <offset>\" option can't "
2676 "be used in conjunction with setting "
2677 "section load addresses.\n");
2678 result.SetStatus(eReturnStatusFailed);
2679 return false;
2680 }
2681
2682 for (size_t i = 0; i < argc; i += 2) {
2683 const char *sect_name = args.GetArgumentAtIndex(i);
2684 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2685 if (sect_name && load_addr_cstr) {
2686 ConstString const_sect_name(sect_name);
2687 bool success = false;
2688 addr_t load_addr = StringConvert::ToUInt64(
2689 load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2690 if (success) {
2691 SectionSP section_sp(
2692 section_list->FindSectionByName(const_sect_name));
2693 if (section_sp) {
2694 if (section_sp->IsThreadSpecific()) {
2695 result.AppendErrorWithFormat(
2696 "thread specific sections are not yet "
2697 "supported (section '%s')\n",
2698 sect_name);
2699 result.SetStatus(eReturnStatusFailed);
2700 break;
2701 } else {
2702 if (target->GetSectionLoadList()
2703 .SetSectionLoadAddress(section_sp,
2704 load_addr))
2705 changed = true;
2706 result.AppendMessageWithFormat(
2707 "section '%s' loaded at 0x%" PRIx64 "\n",
2708 sect_name, load_addr);
2709 }
2710 } else {
2711 result.AppendErrorWithFormat("no section found that "
2712 "matches the section "
2713 "name '%s'\n",
2714 sect_name);
2715 result.SetStatus(eReturnStatusFailed);
2716 break;
2717 }
2718 } else {
2719 result.AppendErrorWithFormat(
2720 "invalid load address string '%s'\n",
2721 load_addr_cstr);
2722 result.SetStatus(eReturnStatusFailed);
2723 break;
2724 }
2725 } else {
2726 if (sect_name)
2727 result.AppendError("section names must be followed by "
2728 "a load address.\n");
2729 else
2730 result.AppendError("one or more section name + load "
2731 "address pair must be specified.\n");
2732 result.SetStatus(eReturnStatusFailed);
2733 break;
2734 }
2735 }
2736 }
2737
2738 if (changed) {
2739 target->ModulesDidLoad(matching_modules);
2740 Process *process = m_exe_ctx.GetProcessPtr();
2741 if (process)
2742 process->Flush();
2743 }
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002744 if (load) {
2745 Error error = module->LoadInMemory(*target);
2746 if (error.Fail()) {
2747 result.AppendError(error.AsCString());
2748 return false;
2749 }
2750 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002751 } else {
2752 module->GetFileSpec().GetPath(path, sizeof(path));
2753 result.AppendErrorWithFormat(
2754 "no sections in object file '%s'\n", path);
2755 result.SetStatus(eReturnStatusFailed);
2756 }
2757 } else {
2758 module->GetFileSpec().GetPath(path, sizeof(path));
2759 result.AppendErrorWithFormat("no object file for module '%s'\n",
2760 path);
2761 result.SetStatus(eReturnStatusFailed);
2762 }
2763 } else {
2764 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2765 if (module_spec_file) {
2766 module_spec_file->GetPath(path, sizeof(path));
2767 result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2768 } else
2769 result.AppendError("no module spec");
2770 result.SetStatus(eReturnStatusFailed);
2771 }
2772 } else {
2773 std::string uuid_str;
2774
2775 if (module_spec.GetFileSpec())
2776 module_spec.GetFileSpec().GetPath(path, sizeof(path));
2777 else
2778 path[0] = '\0';
2779
2780 if (module_spec.GetUUIDPtr())
2781 uuid_str = module_spec.GetUUID().GetAsString();
2782 if (num_matches > 1) {
2783 result.AppendErrorWithFormat(
2784 "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2785 path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2786 for (size_t i = 0; i < num_matches; ++i) {
2787 if (matching_modules.GetModulePointerAtIndex(i)
2788 ->GetFileSpec()
2789 .GetPath(path, sizeof(path)))
2790 result.AppendMessageWithFormat("%s\n", path);
2791 }
2792 } else {
2793 result.AppendErrorWithFormat(
2794 "no modules were found that match%s%s%s%s.\n",
2795 path[0] ? " file=" : "", path,
2796 !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2797 }
2798 result.SetStatus(eReturnStatusFailed);
2799 }
2800 } else {
2801 result.AppendError("either the \"--file <module>\" or the \"--uuid "
2802 "<uuid>\" option must be specified.\n");
2803 result.SetStatus(eReturnStatusFailed);
2804 return false;
2805 }
2806 }
2807 return result.Succeeded();
2808 }
2809
2810 OptionGroupOptions m_option_group;
2811 OptionGroupUUID m_uuid_option_group;
2812 OptionGroupString m_file_option;
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002813 OptionGroupBoolean m_load_option;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002814 OptionGroupUInt64 m_slide_option;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002815};
2816
2817//----------------------------------------------------------------------
2818// List images with associated information
2819//----------------------------------------------------------------------
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002820
2821static OptionDefinition g_target_modules_list_options[] = {
2822 // clang-format off
2823 { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Display the image at this address." },
2824 { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the architecture when listing images." },
2825 { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the triple when listing images." },
2826 { 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." },
2827 { 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)." },
2828 { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the UUID when listing images." },
2829 { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image object file." },
2830 { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the directory with optional width for the image object file." },
2831 { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the basename with optional width for the image object file." },
2832 { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width." },
2833 { 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." },
2834 { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the modification time with optional width of the module." },
2835 { 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." },
2836 { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the module pointer." },
2837 { 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." }
2838 // clang-format on
2839};
2840
Kate Stoneb9c1b512016-09-06 20:57:50 +00002841class CommandObjectTargetModulesList : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002842public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002843 class CommandOptions : public Options {
2844 public:
2845 CommandOptions()
2846 : Options(), m_format_array(), m_use_global_module_list(false),
2847 m_module_addr(LLDB_INVALID_ADDRESS) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002848
Kate Stoneb9c1b512016-09-06 20:57:50 +00002849 ~CommandOptions() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002850
Zachary Turnerfe114832016-11-12 16:56:47 +00002851 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002852 ExecutionContext *execution_context) override {
2853 Error error;
Greg Claytonb9d5df52012-12-06 22:49:16 +00002854
Kate Stoneb9c1b512016-09-06 20:57:50 +00002855 const int short_option = m_getopt_table[option_idx].val;
2856 if (short_option == 'g') {
2857 m_use_global_module_list = true;
2858 } else if (short_option == 'a') {
2859 m_module_addr = Args::StringToAddress(execution_context, option_arg,
2860 LLDB_INVALID_ADDRESS, &error);
2861 } else {
2862 unsigned long width = 0;
Zachary Turnerfe114832016-11-12 16:56:47 +00002863 option_arg.getAsInteger(0, width);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002864 m_format_array.push_back(std::make_pair(short_option, width));
2865 }
2866 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002867 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002868
Kate Stoneb9c1b512016-09-06 20:57:50 +00002869 void OptionParsingStarting(ExecutionContext *execution_context) override {
2870 m_format_array.clear();
2871 m_use_global_module_list = false;
2872 m_module_addr = LLDB_INVALID_ADDRESS;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002873 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002874
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002875 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00002876 return llvm::makeArrayRef(g_target_modules_list_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002877 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002878
2879 // Instance variables to hold the values for command options.
2880 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
2881 FormatWidthCollection m_format_array;
2882 bool m_use_global_module_list;
2883 lldb::addr_t m_module_addr;
2884 };
2885
2886 CommandObjectTargetModulesList(CommandInterpreter &interpreter)
2887 : CommandObjectParsed(
2888 interpreter, "target modules list",
2889 "List current executable and dependent shared library images.",
2890 "target modules list [<cmd-options>]"),
2891 m_options() {}
2892
2893 ~CommandObjectTargetModulesList() override = default;
2894
2895 Options *GetOptions() override { return &m_options; }
2896
Jim Ingham5a988412012-06-08 21:56:10 +00002897protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002898 bool DoExecute(Args &command, CommandReturnObject &result) override {
2899 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2900 const bool use_global_module_list = m_options.m_use_global_module_list;
2901 // Define a local module list here to ensure it lives longer than any
2902 // "locker"
2903 // object which might lock its contents below (through the "module_list_ptr"
2904 // variable).
2905 ModuleList module_list;
2906 if (target == nullptr && !use_global_module_list) {
2907 result.AppendError("invalid target, create a debug target using the "
2908 "'target create' command");
2909 result.SetStatus(eReturnStatusFailed);
2910 return false;
2911 } else {
2912 if (target) {
2913 uint32_t addr_byte_size =
2914 target->GetArchitecture().GetAddressByteSize();
2915 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2916 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2917 }
2918 // Dump all sections for all modules images
2919 Stream &strm = result.GetOutputStream();
2920
2921 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
2922 if (target) {
2923 Address module_address;
2924 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
2925 ModuleSP module_sp(module_address.GetModule());
2926 if (module_sp) {
2927 PrintModule(target, module_sp.get(), 0, strm);
2928 result.SetStatus(eReturnStatusSuccessFinishResult);
2929 } else {
2930 result.AppendErrorWithFormat(
2931 "Couldn't find module matching address: 0x%" PRIx64 ".",
2932 m_options.m_module_addr);
2933 result.SetStatus(eReturnStatusFailed);
Greg Clayton3418c852011-08-10 02:10:13 +00002934 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002935 } else {
2936 result.AppendErrorWithFormat(
2937 "Couldn't find module containing address: 0x%" PRIx64 ".",
2938 m_options.m_module_addr);
2939 result.SetStatus(eReturnStatusFailed);
2940 }
2941 } else {
2942 result.AppendError(
2943 "Can only look up modules by address with a valid target.");
2944 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002945 }
2946 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002947 }
Jim Inghamc10312c2011-10-24 18:36:33 +00002948
Kate Stoneb9c1b512016-09-06 20:57:50 +00002949 size_t num_modules = 0;
2950
2951 // This locker will be locked on the mutex in module_list_ptr if it is
2952 // non-nullptr.
2953 // Otherwise it will lock the AllocationModuleCollectionMutex when
2954 // accessing
2955 // the global module list directly.
2956 std::unique_lock<std::recursive_mutex> guard(
2957 Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
2958
2959 const ModuleList *module_list_ptr = nullptr;
2960 const size_t argc = command.GetArgumentCount();
2961 if (argc == 0) {
2962 if (use_global_module_list) {
2963 guard.lock();
2964 num_modules = Module::GetNumberAllocatedModules();
2965 } else {
2966 module_list_ptr = &target->GetImages();
Jim Ingham28eb5712012-10-12 17:34:26 +00002967 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002968 } else {
Zachary Turner97d2c402016-10-05 23:40:23 +00002969 // TODO: Convert to entry based iteration. Requires converting
2970 // FindModulesByName.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002971 for (size_t i = 0; i < argc; ++i) {
2972 // Dump specified images (by basename or fullpath)
2973 const char *arg_cstr = command.GetArgumentAtIndex(i);
2974 const size_t num_matches = FindModulesByName(
2975 target, arg_cstr, module_list, use_global_module_list);
2976 if (num_matches == 0) {
2977 if (argc == 1) {
2978 result.AppendErrorWithFormat("no modules found that match '%s'",
2979 arg_cstr);
2980 result.SetStatus(eReturnStatusFailed);
2981 return false;
Jim Inghamc10312c2011-10-24 18:36:33 +00002982 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002983 }
Greg Claytonc9660542012-02-05 02:38:54 +00002984 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002985
2986 module_list_ptr = &module_list;
2987 }
2988
2989 std::unique_lock<std::recursive_mutex> lock;
2990 if (module_list_ptr != nullptr) {
2991 lock =
2992 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
2993
2994 num_modules = module_list_ptr->GetSize();
2995 }
2996
2997 if (num_modules > 0) {
2998 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2999 ModuleSP module_sp;
3000 Module *module;
3001 if (module_list_ptr) {
3002 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3003 module = module_sp.get();
3004 } else {
3005 module = Module::GetAllocatedModuleAtIndex(image_idx);
3006 module_sp = module->shared_from_this();
3007 }
3008
3009 const size_t indent = strm.Printf("[%3u] ", image_idx);
3010 PrintModule(target, module, indent, strm);
Jim Inghamc10312c2011-10-24 18:36:33 +00003011 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003012 result.SetStatus(eReturnStatusSuccessFinishResult);
3013 } else {
3014 if (argc) {
3015 if (use_global_module_list)
3016 result.AppendError(
3017 "the global module list has no matching modules");
3018 else
3019 result.AppendError("the target has no matching modules");
3020 } else {
3021 if (use_global_module_list)
3022 result.AppendError("the global module list is empty");
3023 else
3024 result.AppendError(
3025 "the target has no associated executable images");
3026 }
3027 result.SetStatus(eReturnStatusFailed);
3028 return false;
3029 }
3030 }
3031 return result.Succeeded();
3032 }
3033
3034 void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
3035 if (module == nullptr) {
3036 strm.PutCString("Null module");
3037 return;
Jim Inghamc10312c2011-10-24 18:36:33 +00003038 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003039
Kate Stoneb9c1b512016-09-06 20:57:50 +00003040 bool dump_object_name = false;
3041 if (m_options.m_format_array.empty()) {
3042 m_options.m_format_array.push_back(std::make_pair('u', 0));
3043 m_options.m_format_array.push_back(std::make_pair('h', 0));
3044 m_options.m_format_array.push_back(std::make_pair('f', 0));
3045 m_options.m_format_array.push_back(std::make_pair('S', 0));
3046 }
3047 const size_t num_entries = m_options.m_format_array.size();
3048 bool print_space = false;
3049 for (size_t i = 0; i < num_entries; ++i) {
3050 if (print_space)
3051 strm.PutChar(' ');
3052 print_space = true;
3053 const char format_char = m_options.m_format_array[i].first;
3054 uint32_t width = m_options.m_format_array[i].second;
3055 switch (format_char) {
3056 case 'A':
3057 DumpModuleArchitecture(strm, module, false, width);
3058 break;
3059
3060 case 't':
3061 DumpModuleArchitecture(strm, module, true, width);
3062 break;
3063
3064 case 'f':
3065 DumpFullpath(strm, &module->GetFileSpec(), width);
3066 dump_object_name = true;
3067 break;
3068
3069 case 'd':
3070 DumpDirectory(strm, &module->GetFileSpec(), width);
3071 break;
3072
3073 case 'b':
3074 DumpBasename(strm, &module->GetFileSpec(), width);
3075 dump_object_name = true;
3076 break;
3077
3078 case 'h':
3079 case 'o':
3080 // Image header address
3081 {
3082 uint32_t addr_nibble_width =
3083 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3084 : 16;
3085
3086 ObjectFile *objfile = module->GetObjectFile();
3087 if (objfile) {
3088 Address header_addr(objfile->GetHeaderAddress());
3089 if (header_addr.IsValid()) {
3090 if (target && !target->GetSectionLoadList().IsEmpty()) {
3091 lldb::addr_t header_load_addr =
3092 header_addr.GetLoadAddress(target);
3093 if (header_load_addr == LLDB_INVALID_ADDRESS) {
3094 header_addr.Dump(&strm, target,
3095 Address::DumpStyleModuleWithFileAddress,
3096 Address::DumpStyleFileAddress);
3097 } else {
3098 if (format_char == 'o') {
3099 // Show the offset of slide for the image
3100 strm.Printf(
3101 "0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width,
3102 header_load_addr - header_addr.GetFileAddress());
3103 } else {
3104 // Show the load address of the image
3105 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3106 addr_nibble_width, header_load_addr);
3107 }
3108 }
3109 break;
3110 }
3111 // The address was valid, but the image isn't loaded, output the
3112 // address in an appropriate format
3113 header_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3114 break;
3115 }
3116 }
3117 strm.Printf("%*s", addr_nibble_width + 2, "");
3118 }
3119 break;
3120
3121 case 'r': {
3122 size_t ref_count = 0;
3123 ModuleSP module_sp(module->shared_from_this());
3124 if (module_sp) {
3125 // Take one away to make sure we don't count our local "module_sp"
3126 ref_count = module_sp.use_count() - 1;
3127 }
3128 if (width)
3129 strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3130 else
3131 strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3132 } break;
3133
3134 case 's':
3135 case 'S': {
3136 const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3137 if (symbol_vendor) {
3138 const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3139 if (format_char == 'S') {
3140 // Dump symbol file only if different from module file
3141 if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3142 print_space = false;
3143 break;
3144 }
3145 // Add a newline and indent past the index
3146 strm.Printf("\n%*s", indent, "");
3147 }
3148 DumpFullpath(strm, &symfile_spec, width);
3149 dump_object_name = true;
3150 break;
3151 }
3152 strm.Printf("%.*s", width, "<NONE>");
3153 } break;
3154
3155 case 'm':
Pavel Labath7e2cfbf2016-11-09 09:59:18 +00003156 DumpTimePoint(module->GetModificationTime(), strm, width);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003157 break;
3158
3159 case 'p':
3160 strm.Printf("%p", static_cast<void *>(module));
3161 break;
3162
3163 case 'u':
3164 DumpModuleUUID(strm, module);
3165 break;
3166
3167 default:
3168 break;
3169 }
3170 }
3171 if (dump_object_name) {
3172 const char *object_name = module->GetObjectName().GetCString();
3173 if (object_name)
3174 strm.Printf("(%s)", object_name);
3175 }
3176 strm.EOL();
3177 }
3178
3179 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003180};
3181
Jason Molenda380241a2012-07-12 00:20:07 +00003182#pragma mark CommandObjectTargetModulesShowUnwind
Greg Claytoneffe5c92011-05-03 22:09:39 +00003183
Jason Molenda380241a2012-07-12 00:20:07 +00003184//----------------------------------------------------------------------
3185// Lookup unwind information in images
3186//----------------------------------------------------------------------
3187
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003188static OptionDefinition g_target_modules_show_unwind_options[] = {
3189 // clang-format off
3190 { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name." },
3191 { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" }
3192 // clang-format on
3193};
3194
Kate Stoneb9c1b512016-09-06 20:57:50 +00003195class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
Jason Molenda380241a2012-07-12 00:20:07 +00003196public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003197 enum {
3198 eLookupTypeInvalid = -1,
3199 eLookupTypeAddress = 0,
3200 eLookupTypeSymbol,
3201 eLookupTypeFunction,
3202 eLookupTypeFunctionOrSymbol,
3203 kNumLookupTypes
3204 };
Jason Molenda380241a2012-07-12 00:20:07 +00003205
Kate Stoneb9c1b512016-09-06 20:57:50 +00003206 class CommandOptions : public Options {
3207 public:
3208 CommandOptions()
3209 : Options(), m_type(eLookupTypeInvalid), m_str(),
3210 m_addr(LLDB_INVALID_ADDRESS) {}
Jason Molenda380241a2012-07-12 00:20:07 +00003211
Kate Stoneb9c1b512016-09-06 20:57:50 +00003212 ~CommandOptions() override = default;
Jason Molenda380241a2012-07-12 00:20:07 +00003213
Zachary Turnerfe114832016-11-12 16:56:47 +00003214 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
Kate Stoneb9c1b512016-09-06 20:57:50 +00003215 ExecutionContext *execution_context) override {
3216 Error error;
Jason Molenda380241a2012-07-12 00:20:07 +00003217
Kate Stoneb9c1b512016-09-06 20:57:50 +00003218 const int short_option = m_getopt_table[option_idx].val;
Jason Molenda380241a2012-07-12 00:20:07 +00003219
Kate Stoneb9c1b512016-09-06 20:57:50 +00003220 switch (short_option) {
3221 case 'a': {
3222 m_str = option_arg;
3223 m_type = eLookupTypeAddress;
3224 m_addr = Args::StringToAddress(execution_context, option_arg,
3225 LLDB_INVALID_ADDRESS, &error);
3226 if (m_addr == LLDB_INVALID_ADDRESS)
3227 error.SetErrorStringWithFormat("invalid address string '%s'",
Zachary Turnerfe114832016-11-12 16:56:47 +00003228 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003229 break;
3230 }
Jason Molenda380241a2012-07-12 00:20:07 +00003231
Kate Stoneb9c1b512016-09-06 20:57:50 +00003232 case 'n':
3233 m_str = option_arg;
3234 m_type = eLookupTypeFunctionOrSymbol;
3235 break;
Michael Sartainb1e15922013-08-22 20:42:30 +00003236
Kate Stoneb9c1b512016-09-06 20:57:50 +00003237 default:
3238 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
3239 break;
3240 }
Jason Molenda380241a2012-07-12 00:20:07 +00003241
Kate Stoneb9c1b512016-09-06 20:57:50 +00003242 return error;
Jason Molenda380241a2012-07-12 00:20:07 +00003243 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003244
Kate Stoneb9c1b512016-09-06 20:57:50 +00003245 void OptionParsingStarting(ExecutionContext *execution_context) override {
3246 m_type = eLookupTypeInvalid;
3247 m_str.clear();
3248 m_addr = LLDB_INVALID_ADDRESS;
Jason Molenda380241a2012-07-12 00:20:07 +00003249 }
3250
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003251 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00003252 return llvm::makeArrayRef(g_target_modules_show_unwind_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003253 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003254
3255 // Instance variables to hold the values for command options.
3256
3257 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3258 std::string m_str; // Holds name lookup
3259 lldb::addr_t m_addr; // Holds the address to lookup
3260 };
3261
3262 CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3263 : CommandObjectParsed(
3264 interpreter, "target modules show-unwind",
3265 "Show synthesized unwind instructions for a function.", nullptr,
3266 eCommandRequiresTarget | eCommandRequiresProcess |
3267 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
3268 m_options() {}
3269
3270 ~CommandObjectTargetModulesShowUnwind() override = default;
3271
3272 Options *GetOptions() override { return &m_options; }
3273
Jason Molenda380241a2012-07-12 00:20:07 +00003274protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003275 bool DoExecute(Args &command, CommandReturnObject &result) override {
3276 Target *target = m_exe_ctx.GetTargetPtr();
3277 Process *process = m_exe_ctx.GetProcessPtr();
3278 ABI *abi = nullptr;
3279 if (process)
3280 abi = process->GetABI().get();
Jason Molenda380241a2012-07-12 00:20:07 +00003281
Kate Stoneb9c1b512016-09-06 20:57:50 +00003282 if (process == nullptr) {
3283 result.AppendError(
3284 "You must have a process running to use this command.");
3285 result.SetStatus(eReturnStatusFailed);
3286 return false;
Jason Molenda380241a2012-07-12 00:20:07 +00003287 }
3288
Kate Stoneb9c1b512016-09-06 20:57:50 +00003289 ThreadList threads(process->GetThreadList());
3290 if (threads.GetSize() == 0) {
3291 result.AppendError("The process must be paused to use this command.");
3292 result.SetStatus(eReturnStatusFailed);
3293 return false;
3294 }
3295
3296 ThreadSP thread(threads.GetThreadAtIndex(0));
3297 if (!thread) {
3298 result.AppendError("The process must be paused to use this command.");
3299 result.SetStatus(eReturnStatusFailed);
3300 return false;
3301 }
3302
3303 SymbolContextList sc_list;
3304
3305 if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3306 ConstString function_name(m_options.m_str.c_str());
3307 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3308 true, false, true, sc_list);
3309 } else if (m_options.m_type == eLookupTypeAddress && target) {
3310 Address addr;
3311 if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3312 addr)) {
3313 SymbolContext sc;
3314 ModuleSP module_sp(addr.GetModule());
3315 module_sp->ResolveSymbolContextForAddress(addr,
3316 eSymbolContextEverything, sc);
3317 if (sc.function || sc.symbol) {
3318 sc_list.Append(sc);
3319 }
3320 }
3321 } else {
3322 result.AppendError(
3323 "address-expression or function name option must be specified.");
3324 result.SetStatus(eReturnStatusFailed);
3325 return false;
3326 }
3327
3328 size_t num_matches = sc_list.GetSize();
3329 if (num_matches == 0) {
3330 result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3331 m_options.m_str.c_str());
3332 result.SetStatus(eReturnStatusFailed);
3333 return false;
3334 }
3335
3336 for (uint32_t idx = 0; idx < num_matches; idx++) {
3337 SymbolContext sc;
3338 sc_list.GetContextAtIndex(idx, sc);
3339 if (sc.symbol == nullptr && sc.function == nullptr)
3340 continue;
3341 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3342 continue;
3343 AddressRange range;
3344 if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3345 false, range))
3346 continue;
3347 if (!range.GetBaseAddress().IsValid())
3348 continue;
3349 ConstString funcname(sc.GetFunctionName());
3350 if (funcname.IsEmpty())
3351 continue;
3352 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3353 if (abi)
3354 start_addr = abi->FixCodeAddress(start_addr);
3355
3356 FuncUnwindersSP func_unwinders_sp(
3357 sc.module_sp->GetObjectFile()
3358 ->GetUnwindTable()
3359 .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3360 if (!func_unwinders_sp)
3361 continue;
3362
3363 result.GetOutputStream().Printf(
3364 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
3365 sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3366 funcname.AsCString(), start_addr);
3367
3368 UnwindPlanSP non_callsite_unwind_plan =
3369 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
3370 if (non_callsite_unwind_plan) {
3371 result.GetOutputStream().Printf(
3372 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3373 non_callsite_unwind_plan->GetSourceName().AsCString());
3374 }
3375 UnwindPlanSP callsite_unwind_plan =
3376 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3377 if (callsite_unwind_plan) {
3378 result.GetOutputStream().Printf(
3379 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3380 callsite_unwind_plan->GetSourceName().AsCString());
3381 }
3382 UnwindPlanSP fast_unwind_plan =
3383 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3384 if (fast_unwind_plan) {
3385 result.GetOutputStream().Printf(
3386 "Fast UnwindPlan is '%s'\n",
3387 fast_unwind_plan->GetSourceName().AsCString());
3388 }
3389
3390 result.GetOutputStream().Printf("\n");
3391
3392 UnwindPlanSP assembly_sp =
3393 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
3394 if (assembly_sp) {
3395 result.GetOutputStream().Printf(
3396 "Assembly language inspection UnwindPlan:\n");
3397 assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3398 LLDB_INVALID_ADDRESS);
3399 result.GetOutputStream().Printf("\n");
3400 }
3401
3402 UnwindPlanSP ehframe_sp =
3403 func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3404 if (ehframe_sp) {
3405 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3406 ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3407 LLDB_INVALID_ADDRESS);
3408 result.GetOutputStream().Printf("\n");
3409 }
3410
3411 UnwindPlanSP ehframe_augmented_sp =
3412 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
3413 if (ehframe_augmented_sp) {
3414 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3415 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3416 LLDB_INVALID_ADDRESS);
3417 result.GetOutputStream().Printf("\n");
3418 }
3419
3420 UnwindPlanSP arm_unwind_sp =
3421 func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
3422 if (arm_unwind_sp) {
3423 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3424 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3425 LLDB_INVALID_ADDRESS);
3426 result.GetOutputStream().Printf("\n");
3427 }
3428
3429 UnwindPlanSP compact_unwind_sp =
3430 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3431 if (compact_unwind_sp) {
3432 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3433 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3434 LLDB_INVALID_ADDRESS);
3435 result.GetOutputStream().Printf("\n");
3436 }
3437
3438 if (fast_unwind_plan) {
3439 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3440 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3441 LLDB_INVALID_ADDRESS);
3442 result.GetOutputStream().Printf("\n");
3443 }
3444
3445 ABISP abi_sp = process->GetABI();
3446 if (abi_sp) {
3447 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3448 if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3449 result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3450 arch_default.Dump(result.GetOutputStream(), thread.get(),
3451 LLDB_INVALID_ADDRESS);
3452 result.GetOutputStream().Printf("\n");
3453 }
3454
3455 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3456 if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3457 result.GetOutputStream().Printf(
3458 "Arch default at entry point UnwindPlan:\n");
3459 arch_entry.Dump(result.GetOutputStream(), thread.get(),
3460 LLDB_INVALID_ADDRESS);
3461 result.GetOutputStream().Printf("\n");
3462 }
3463 }
3464
3465 result.GetOutputStream().Printf("\n");
3466 }
3467 return result.Succeeded();
3468 }
3469
3470 CommandOptions m_options;
Jason Molenda380241a2012-07-12 00:20:07 +00003471};
3472
Greg Claytoneffe5c92011-05-03 22:09:39 +00003473//----------------------------------------------------------------------
3474// Lookup information in images
3475//----------------------------------------------------------------------
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003476
3477static OptionDefinition g_target_modules_lookup_options[] = {
3478 // clang-format off
3479 { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." },
3480 { 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." },
3481 /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */
3482 { 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." },
3483 { 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." },
3484 { 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." },
3485 { 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)." },
3486 { 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)." },
3487 { 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." },
3488 { 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." },
3489 { 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." },
3490 { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose lookup information." },
3491 { 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." },
3492 // clang-format on
3493};
3494
Kate Stoneb9c1b512016-09-06 20:57:50 +00003495class CommandObjectTargetModulesLookup : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00003496public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003497 enum {
3498 eLookupTypeInvalid = -1,
3499 eLookupTypeAddress = 0,
3500 eLookupTypeSymbol,
3501 eLookupTypeFileLine, // Line is optional
3502 eLookupTypeFunction,
3503 eLookupTypeFunctionOrSymbol,
3504 eLookupTypeType,
3505 kNumLookupTypes
3506 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003507
Kate Stoneb9c1b512016-09-06 20:57:50 +00003508 class CommandOptions : public Options {
3509 public:
3510 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003511
Kate Stoneb9c1b512016-09-06 20:57:50 +00003512 ~CommandOptions() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003513
Zachary Turnerfe114832016-11-12 16:56:47 +00003514 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
Kate Stoneb9c1b512016-09-06 20:57:50 +00003515 ExecutionContext *execution_context) override {
3516 Error error;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003517
Kate Stoneb9c1b512016-09-06 20:57:50 +00003518 const int short_option = m_getopt_table[option_idx].val;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003519
Kate Stoneb9c1b512016-09-06 20:57:50 +00003520 switch (short_option) {
3521 case 'a': {
3522 m_type = eLookupTypeAddress;
3523 m_addr = Args::StringToAddress(execution_context, option_arg,
3524 LLDB_INVALID_ADDRESS, &error);
3525 } break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003526
Kate Stoneb9c1b512016-09-06 20:57:50 +00003527 case 'o':
Zachary Turnerfe114832016-11-12 16:56:47 +00003528 if (option_arg.getAsInteger(0, m_offset))
Kate Stoneb9c1b512016-09-06 20:57:50 +00003529 error.SetErrorStringWithFormat("invalid offset string '%s'",
Zachary Turnerfe114832016-11-12 16:56:47 +00003530 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003531 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003532
Kate Stoneb9c1b512016-09-06 20:57:50 +00003533 case 's':
3534 m_str = option_arg;
3535 m_type = eLookupTypeSymbol;
3536 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003537
Kate Stoneb9c1b512016-09-06 20:57:50 +00003538 case 'f':
3539 m_file.SetFile(option_arg, false);
3540 m_type = eLookupTypeFileLine;
3541 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003542
Kate Stoneb9c1b512016-09-06 20:57:50 +00003543 case 'i':
3544 m_include_inlines = false;
3545 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003546
Kate Stoneb9c1b512016-09-06 20:57:50 +00003547 case 'l':
Zachary Turnerfe114832016-11-12 16:56:47 +00003548 if (option_arg.getAsInteger(0, m_line_number))
Kate Stoneb9c1b512016-09-06 20:57:50 +00003549 error.SetErrorStringWithFormat("invalid line number string '%s'",
Zachary Turnerfe114832016-11-12 16:56:47 +00003550 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003551 else if (m_line_number == 0)
3552 error.SetErrorString("zero is an invalid line number");
3553 m_type = eLookupTypeFileLine;
3554 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003555
Kate Stoneb9c1b512016-09-06 20:57:50 +00003556 case 'F':
3557 m_str = option_arg;
3558 m_type = eLookupTypeFunction;
3559 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003560
Kate Stoneb9c1b512016-09-06 20:57:50 +00003561 case 'n':
3562 m_str = option_arg;
3563 m_type = eLookupTypeFunctionOrSymbol;
3564 break;
Greg Claytonc4a8a762012-05-15 18:43:44 +00003565
Kate Stoneb9c1b512016-09-06 20:57:50 +00003566 case 't':
3567 m_str = option_arg;
3568 m_type = eLookupTypeType;
3569 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003570
Kate Stoneb9c1b512016-09-06 20:57:50 +00003571 case 'v':
3572 m_verbose = 1;
3573 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003574
Kate Stoneb9c1b512016-09-06 20:57:50 +00003575 case 'A':
3576 m_print_all = true;
3577 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003578
Kate Stoneb9c1b512016-09-06 20:57:50 +00003579 case 'r':
3580 m_use_regex = true;
3581 break;
3582 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003583
Kate Stoneb9c1b512016-09-06 20:57:50 +00003584 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003585 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003586
Kate Stoneb9c1b512016-09-06 20:57:50 +00003587 void OptionParsingStarting(ExecutionContext *execution_context) override {
3588 m_type = eLookupTypeInvalid;
3589 m_str.clear();
3590 m_file.Clear();
3591 m_addr = LLDB_INVALID_ADDRESS;
3592 m_offset = 0;
3593 m_line_number = 0;
3594 m_use_regex = false;
3595 m_include_inlines = true;
3596 m_verbose = false;
3597 m_print_all = false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003598 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003599
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003600 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00003601 return llvm::makeArrayRef(g_target_modules_lookup_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003602 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003603
Kate Stoneb9c1b512016-09-06 20:57:50 +00003604 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3605 std::string m_str; // Holds name lookup
3606 FileSpec m_file; // Files for file lookups
3607 lldb::addr_t m_addr; // Holds the address to lookup
3608 lldb::addr_t
3609 m_offset; // Subtract this offset from m_addr before doing lookups.
3610 uint32_t m_line_number; // Line number for file+line lookups
3611 bool m_use_regex; // Name lookups in m_str are regular expressions.
3612 bool m_include_inlines; // Check for inline entries when looking up by
3613 // file/line.
3614 bool m_verbose; // Enable verbose lookup info
3615 bool m_print_all; // Print all matches, even in cases where there's a best
3616 // match.
3617 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003618
Kate Stoneb9c1b512016-09-06 20:57:50 +00003619 CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3620 : CommandObjectParsed(interpreter, "target modules lookup",
3621 "Look up information within executable and "
3622 "dependent shared library images.",
3623 nullptr, eCommandRequiresTarget),
3624 m_options() {
3625 CommandArgumentEntry arg;
3626 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003627
Kate Stoneb9c1b512016-09-06 20:57:50 +00003628 // Define the first (and only) variant of this arg.
3629 file_arg.arg_type = eArgTypeFilename;
3630 file_arg.arg_repetition = eArgRepeatStar;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003631
Kate Stoneb9c1b512016-09-06 20:57:50 +00003632 // There is only one variant this argument could be; put it into the
3633 // argument entry.
3634 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003635
Kate Stoneb9c1b512016-09-06 20:57:50 +00003636 // Push the data for the first argument into the m_arguments vector.
3637 m_arguments.push_back(arg);
3638 }
3639
3640 ~CommandObjectTargetModulesLookup() override = default;
3641
3642 Options *GetOptions() override { return &m_options; }
3643
3644 bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3645 bool &syntax_error) {
3646 switch (m_options.m_type) {
3647 case eLookupTypeAddress:
3648 case eLookupTypeFileLine:
3649 case eLookupTypeFunction:
3650 case eLookupTypeFunctionOrSymbol:
3651 case eLookupTypeSymbol:
3652 default:
3653 return false;
3654 case eLookupTypeType:
3655 break;
Sean Callanand38b4a92012-06-06 20:49:55 +00003656 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003657
Kate Stoneb9c1b512016-09-06 20:57:50 +00003658 StackFrameSP frame = m_exe_ctx.GetFrameSP();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003659
Kate Stoneb9c1b512016-09-06 20:57:50 +00003660 if (!frame)
3661 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003662
Kate Stoneb9c1b512016-09-06 20:57:50 +00003663 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
Greg Claytonc4a8a762012-05-15 18:43:44 +00003664
Kate Stoneb9c1b512016-09-06 20:57:50 +00003665 if (!sym_ctx.module_sp)
3666 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003667
Kate Stoneb9c1b512016-09-06 20:57:50 +00003668 switch (m_options.m_type) {
3669 default:
3670 return false;
3671 case eLookupTypeType:
3672 if (!m_options.m_str.empty()) {
3673 if (LookupTypeHere(m_interpreter, result.GetOutputStream(), sym_ctx,
3674 m_options.m_str.c_str(), m_options.m_use_regex)) {
3675 result.SetStatus(eReturnStatusSuccessFinishResult);
3676 return true;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003677 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003678 }
3679 break;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003680 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003681
Kate Stoneb9c1b512016-09-06 20:57:50 +00003682 return true;
3683 }
3684
3685 bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3686 CommandReturnObject &result, bool &syntax_error) {
3687 switch (m_options.m_type) {
3688 case eLookupTypeAddress:
3689 if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3690 if (LookupAddressInModule(
3691 m_interpreter, result.GetOutputStream(), module,
3692 eSymbolContextEverything |
3693 (m_options.m_verbose
3694 ? static_cast<int>(eSymbolContextVariable)
3695 : 0),
3696 m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
3697 result.SetStatus(eReturnStatusSuccessFinishResult);
3698 return true;
3699 }
3700 }
3701 break;
3702
3703 case eLookupTypeSymbol:
3704 if (!m_options.m_str.empty()) {
3705 if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3706 module, m_options.m_str.c_str(),
3707 m_options.m_use_regex, m_options.m_verbose)) {
3708 result.SetStatus(eReturnStatusSuccessFinishResult);
3709 return true;
3710 }
3711 }
3712 break;
3713
3714 case eLookupTypeFileLine:
3715 if (m_options.m_file) {
3716 if (LookupFileAndLineInModule(
3717 m_interpreter, result.GetOutputStream(), module,
3718 m_options.m_file, m_options.m_line_number,
3719 m_options.m_include_inlines, m_options.m_verbose)) {
3720 result.SetStatus(eReturnStatusSuccessFinishResult);
3721 return true;
3722 }
3723 }
3724 break;
3725
3726 case eLookupTypeFunctionOrSymbol:
3727 case eLookupTypeFunction:
3728 if (!m_options.m_str.empty()) {
3729 if (LookupFunctionInModule(
3730 m_interpreter, result.GetOutputStream(), module,
3731 m_options.m_str.c_str(), m_options.m_use_regex,
3732 m_options.m_include_inlines,
3733 m_options.m_type ==
3734 eLookupTypeFunctionOrSymbol, // include symbols
3735 m_options.m_verbose)) {
3736 result.SetStatus(eReturnStatusSuccessFinishResult);
3737 return true;
3738 }
3739 }
3740 break;
3741
3742 case eLookupTypeType:
3743 if (!m_options.m_str.empty()) {
3744 if (LookupTypeInModule(m_interpreter, result.GetOutputStream(), module,
3745 m_options.m_str.c_str(),
3746 m_options.m_use_regex)) {
3747 result.SetStatus(eReturnStatusSuccessFinishResult);
3748 return true;
3749 }
3750 }
3751 break;
3752
3753 default:
3754 m_options.GenerateOptionUsage(
3755 result.GetErrorStream(), this,
3756 GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3757 syntax_error = true;
3758 break;
3759 }
3760
3761 result.SetStatus(eReturnStatusFailed);
3762 return false;
3763 }
3764
Jim Ingham5a988412012-06-08 21:56:10 +00003765protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003766 bool DoExecute(Args &command, CommandReturnObject &result) override {
3767 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3768 if (target == nullptr) {
3769 result.AppendError("invalid target, create a debug target using the "
3770 "'target create' command");
3771 result.SetStatus(eReturnStatusFailed);
3772 return false;
3773 } else {
3774 bool syntax_error = false;
3775 uint32_t i;
3776 uint32_t num_successful_lookups = 0;
3777 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3778 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3779 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3780 // Dump all sections for all modules images
3781
3782 if (command.GetArgumentCount() == 0) {
3783 ModuleSP current_module;
3784
3785 // Where it is possible to look in the current symbol context
3786 // first, try that. If this search was successful and --all
3787 // was not passed, don't print anything else.
3788 if (LookupHere(m_interpreter, result, syntax_error)) {
3789 result.GetOutputStream().EOL();
3790 num_successful_lookups++;
3791 if (!m_options.m_print_all) {
3792 result.SetStatus(eReturnStatusSuccessFinishResult);
3793 return result.Succeeded();
3794 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00003795 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003796
Kate Stoneb9c1b512016-09-06 20:57:50 +00003797 // Dump all sections for all other modules
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003798
Kate Stoneb9c1b512016-09-06 20:57:50 +00003799 const ModuleList &target_modules = target->GetImages();
3800 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3801 const size_t num_modules = target_modules.GetSize();
3802 if (num_modules > 0) {
3803 for (i = 0; i < num_modules && !syntax_error; ++i) {
3804 Module *module_pointer =
3805 target_modules.GetModulePointerAtIndexUnlocked(i);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003806
Kate Stoneb9c1b512016-09-06 20:57:50 +00003807 if (module_pointer != current_module.get() &&
3808 LookupInModule(
3809 m_interpreter,
3810 target_modules.GetModulePointerAtIndexUnlocked(i), result,
3811 syntax_error)) {
3812 result.GetOutputStream().EOL();
3813 num_successful_lookups++;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003814 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003815 }
3816 } else {
3817 result.AppendError("the target has no associated executable images");
3818 result.SetStatus(eReturnStatusFailed);
3819 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003820 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003821 } else {
3822 // Dump specified images (by basename or fullpath)
3823 const char *arg_cstr;
3824 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3825 !syntax_error;
3826 ++i) {
3827 ModuleList module_list;
3828 const size_t num_matches =
3829 FindModulesByName(target, arg_cstr, module_list, false);
3830 if (num_matches > 0) {
3831 for (size_t j = 0; j < num_matches; ++j) {
3832 Module *module = module_list.GetModulePointerAtIndex(j);
3833 if (module) {
3834 if (LookupInModule(m_interpreter, module, result,
3835 syntax_error)) {
3836 result.GetOutputStream().EOL();
3837 num_successful_lookups++;
3838 }
3839 }
3840 }
3841 } else
3842 result.AppendWarningWithFormat(
3843 "Unable to find an image that matches '%s'.\n", arg_cstr);
3844 }
3845 }
3846
3847 if (num_successful_lookups > 0)
3848 result.SetStatus(eReturnStatusSuccessFinishResult);
3849 else
3850 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00003851 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003852 return result.Succeeded();
3853 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003854
Kate Stoneb9c1b512016-09-06 20:57:50 +00003855 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003856};
3857
Jim Ingham9575d842011-03-11 03:53:59 +00003858#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003859
3860//-------------------------------------------------------------------------
3861// CommandObjectMultiwordImageSearchPaths
3862//-------------------------------------------------------------------------
3863
Kate Stoneb9c1b512016-09-06 20:57:50 +00003864class CommandObjectTargetModulesImageSearchPaths
3865 : public CommandObjectMultiword {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003866public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003867 CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
3868 : CommandObjectMultiword(
3869 interpreter, "target modules search-paths",
3870 "Commands for managing module search paths for a target.",
3871 "target modules search-paths <subcommand> [<subcommand-options>]") {
3872 LoadSubCommand(
3873 "add", CommandObjectSP(
3874 new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
3875 LoadSubCommand(
3876 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
3877 interpreter)));
3878 LoadSubCommand(
3879 "insert",
3880 CommandObjectSP(
3881 new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
3882 LoadSubCommand(
3883 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
3884 interpreter)));
3885 LoadSubCommand(
3886 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
3887 interpreter)));
3888 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003889
Kate Stoneb9c1b512016-09-06 20:57:50 +00003890 ~CommandObjectTargetModulesImageSearchPaths() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003891};
3892
Greg Claytoneffe5c92011-05-03 22:09:39 +00003893#pragma mark CommandObjectTargetModules
3894
3895//-------------------------------------------------------------------------
3896// CommandObjectTargetModules
3897//-------------------------------------------------------------------------
3898
Kate Stoneb9c1b512016-09-06 20:57:50 +00003899class CommandObjectTargetModules : public CommandObjectMultiword {
Greg Claytoneffe5c92011-05-03 22:09:39 +00003900public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003901 //------------------------------------------------------------------
3902 // Constructors and Destructors
3903 //------------------------------------------------------------------
3904 CommandObjectTargetModules(CommandInterpreter &interpreter)
3905 : CommandObjectMultiword(interpreter, "target modules",
3906 "Commands for accessing information for one or "
3907 "more target modules.",
3908 "target modules <sub-command> ...") {
3909 LoadSubCommand(
3910 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
3911 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
3912 interpreter)));
3913 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
3914 interpreter)));
3915 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
3916 interpreter)));
3917 LoadSubCommand(
3918 "lookup",
3919 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
3920 LoadSubCommand(
3921 "search-paths",
3922 CommandObjectSP(
3923 new CommandObjectTargetModulesImageSearchPaths(interpreter)));
3924 LoadSubCommand(
3925 "show-unwind",
3926 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
3927 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00003928
Kate Stoneb9c1b512016-09-06 20:57:50 +00003929 ~CommandObjectTargetModules() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003930
Greg Claytoneffe5c92011-05-03 22:09:39 +00003931private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003932 //------------------------------------------------------------------
3933 // For CommandObjectTargetModules only
3934 //------------------------------------------------------------------
3935 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules);
Greg Claytoneffe5c92011-05-03 22:09:39 +00003936};
3937
Kate Stoneb9c1b512016-09-06 20:57:50 +00003938class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
Greg Claytone72dfb32012-02-24 01:59:29 +00003939public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003940 CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
3941 : CommandObjectParsed(
3942 interpreter, "target symbols add",
3943 "Add a debug symbol file to one of the target's current modules by "
3944 "specifying a path to a debug symbols file, or using the options "
3945 "to specify a module to download symbols for.",
3946 "target symbols add [<symfile>]", eCommandRequiresTarget),
Todd Fialae1cfbc72016-08-11 23:51:28 +00003947 m_option_group(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00003948 m_file_option(
3949 LLDB_OPT_SET_1, false, "shlib", 's',
3950 CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3951 "Fullpath or basename for module to find debug symbols for."),
3952 m_current_frame_option(
3953 LLDB_OPT_SET_2, false, "frame", 'F',
3954 "Locate the debug symbols the currently selected frame.", false,
3955 true)
Greg Claytonb5f0fea2012-09-27 22:26:11 +00003956
Kate Stoneb9c1b512016-09-06 20:57:50 +00003957 {
3958 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
3959 LLDB_OPT_SET_1);
3960 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
3961 m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
3962 LLDB_OPT_SET_2);
3963 m_option_group.Finalize();
3964 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003965
Kate Stoneb9c1b512016-09-06 20:57:50 +00003966 ~CommandObjectTargetSymbolsAdd() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003967
Kate Stoneb9c1b512016-09-06 20:57:50 +00003968 int HandleArgumentCompletion(Args &input, int &cursor_index,
3969 int &cursor_char_position,
3970 OptionElementVector &opt_element_vector,
3971 int match_start_point, int max_return_elements,
3972 bool &word_complete,
3973 StringList &matches) override {
3974 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
3975 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003976
Kate Stoneb9c1b512016-09-06 20:57:50 +00003977 CommandCompletions::InvokeCommonCompletionCallbacks(
3978 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
3979 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
3980 word_complete, matches);
3981 return matches.GetSize();
3982 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003983
Kate Stoneb9c1b512016-09-06 20:57:50 +00003984 Options *GetOptions() override { return &m_option_group; }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00003985
Jim Ingham5a988412012-06-08 21:56:10 +00003986protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003987 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
3988 CommandReturnObject &result) {
3989 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
3990 if (symbol_fspec) {
3991 char symfile_path[PATH_MAX];
3992 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003993
Kate Stoneb9c1b512016-09-06 20:57:50 +00003994 if (!module_spec.GetUUID().IsValid()) {
3995 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
3996 module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
3997 }
3998 // We now have a module that represents a symbol file
3999 // that can be used for a module that might exist in the
4000 // current target, so we need to find that module in the
4001 // target
4002 ModuleList matching_module_list;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004003
Kate Stoneb9c1b512016-09-06 20:57:50 +00004004 size_t num_matches = 0;
4005 // First extract all module specs from the symbol file
4006 lldb_private::ModuleSpecList symfile_module_specs;
4007 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
4008 0, 0, symfile_module_specs)) {
4009 // Now extract the module spec that matches the target architecture
4010 ModuleSpec target_arch_module_spec;
4011 ModuleSpec symfile_module_spec;
4012 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4013 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4014 symfile_module_spec)) {
4015 // See if it has a UUID?
4016 if (symfile_module_spec.GetUUID().IsValid()) {
4017 // It has a UUID, look for this UUID in the target modules
4018 ModuleSpec symfile_uuid_module_spec;
4019 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4020 num_matches = target->GetImages().FindModules(
4021 symfile_uuid_module_spec, matching_module_list);
4022 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00004023 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004024
4025 if (num_matches == 0) {
4026 // No matches yet, iterate through the module specs to find a UUID
4027 // value that
4028 // we can match up to an image in our target
4029 const size_t num_symfile_module_specs =
4030 symfile_module_specs.GetSize();
4031 for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0;
4032 ++i) {
4033 if (symfile_module_specs.GetModuleSpecAtIndex(
4034 i, symfile_module_spec)) {
4035 if (symfile_module_spec.GetUUID().IsValid()) {
4036 // It has a UUID, look for this UUID in the target modules
4037 ModuleSpec symfile_uuid_module_spec;
4038 symfile_uuid_module_spec.GetUUID() =
4039 symfile_module_spec.GetUUID();
4040 num_matches = target->GetImages().FindModules(
4041 symfile_uuid_module_spec, matching_module_list);
4042 }
4043 }
4044 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00004045 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004046 }
4047
4048 // Just try to match up the file by basename if we have no matches at this
4049 // point
4050 if (num_matches == 0)
4051 num_matches =
4052 target->GetImages().FindModules(module_spec, matching_module_list);
4053
4054 while (num_matches == 0) {
4055 ConstString filename_no_extension(
4056 module_spec.GetFileSpec().GetFileNameStrippingExtension());
4057 // Empty string returned, lets bail
4058 if (!filename_no_extension)
4059 break;
4060
4061 // Check if there was no extension to strip and the basename is the same
4062 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4063 break;
4064
4065 // Replace basename with one less extension
4066 module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4067
4068 num_matches =
4069 target->GetImages().FindModules(module_spec, matching_module_list);
4070 }
4071
4072 if (num_matches > 1) {
4073 result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4074 "use the --uuid option to resolve the "
4075 "ambiguity.\n",
4076 symfile_path);
4077 } else if (num_matches == 1) {
4078 ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0));
4079
4080 // The module has not yet created its symbol vendor, we can just
4081 // give the existing target module the symfile path to use for
4082 // when it decides to create it!
4083 module_sp->SetSymbolFileFileSpec(symbol_fspec);
4084
4085 SymbolVendor *symbol_vendor =
4086 module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4087 if (symbol_vendor) {
4088 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4089
4090 if (symbol_file) {
4091 ObjectFile *object_file = symbol_file->GetObjectFile();
4092
4093 if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4094 // Provide feedback that the symfile has been successfully added.
4095 const FileSpec &module_fs = module_sp->GetFileSpec();
4096 result.AppendMessageWithFormat(
4097 "symbol file '%s' has been added to '%s'\n", symfile_path,
4098 module_fs.GetPath().c_str());
4099
4100 // Let clients know something changed in the module
4101 // if it is currently loaded
4102 ModuleList module_list;
4103 module_list.Append(module_sp);
4104 target->SymbolsDidLoad(module_list);
4105
4106 // Make sure we load any scripting resources that may be embedded
4107 // in the debug info files in case the platform supports that.
4108 Error error;
4109 StreamString feedback_stream;
4110 module_sp->LoadScriptingResourceInTarget(target, error,
4111 &feedback_stream);
4112 if (error.Fail() && error.AsCString())
4113 result.AppendWarningWithFormat(
4114 "unable to load scripting data for module %s - error "
4115 "reported was %s",
4116 module_sp->GetFileSpec()
4117 .GetFileNameStrippingExtension()
4118 .GetCString(),
4119 error.AsCString());
4120 else if (feedback_stream.GetSize())
4121 result.AppendWarningWithFormat("%s", feedback_stream.GetData());
4122
4123 flush = true;
4124 result.SetStatus(eReturnStatusSuccessFinishResult);
4125 return true;
4126 }
4127 }
4128 }
4129 // Clear the symbol file spec if anything went wrong
4130 module_sp->SetSymbolFileFileSpec(FileSpec());
4131 }
4132
4133 if (module_spec.GetUUID().IsValid()) {
4134 StreamString ss_symfile_uuid;
4135 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4136 result.AppendErrorWithFormat(
4137 "symbol file '%s' (%s) does not match any existing module%s\n",
4138 symfile_path, ss_symfile_uuid.GetData(),
4139 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4140 ? "\n please specify the full path to the symbol file"
4141 : "");
4142 } else {
4143 result.AppendErrorWithFormat(
4144 "symbol file '%s' does not match any existing module%s\n",
4145 symfile_path,
4146 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4147 ? "\n please specify the full path to the symbol file"
4148 : "");
4149 }
4150 } else {
4151 result.AppendError(
4152 "one or more executable image paths must be specified");
4153 }
4154 result.SetStatus(eReturnStatusFailed);
4155 return false;
4156 }
4157
4158 bool DoExecute(Args &args, CommandReturnObject &result) override {
4159 Target *target = m_exe_ctx.GetTargetPtr();
4160 result.SetStatus(eReturnStatusFailed);
4161 bool flush = false;
4162 ModuleSpec module_spec;
4163 const bool uuid_option_set =
4164 m_uuid_option_group.GetOptionValue().OptionWasSet();
4165 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4166 const bool frame_option_set =
4167 m_current_frame_option.GetOptionValue().OptionWasSet();
4168 const size_t argc = args.GetArgumentCount();
4169
4170 if (argc == 0) {
4171 if (uuid_option_set || file_option_set || frame_option_set) {
4172 bool success = false;
4173 bool error_set = false;
4174 if (frame_option_set) {
4175 Process *process = m_exe_ctx.GetProcessPtr();
4176 if (process) {
4177 const StateType process_state = process->GetState();
4178 if (StateIsStoppedState(process_state, true)) {
4179 StackFrame *frame = m_exe_ctx.GetFramePtr();
4180 if (frame) {
4181 ModuleSP frame_module_sp(
4182 frame->GetSymbolContext(eSymbolContextModule).module_sp);
4183 if (frame_module_sp) {
4184 if (frame_module_sp->GetPlatformFileSpec().Exists()) {
4185 module_spec.GetArchitecture() =
4186 frame_module_sp->GetArchitecture();
4187 module_spec.GetFileSpec() =
4188 frame_module_sp->GetPlatformFileSpec();
4189 }
4190 module_spec.GetUUID() = frame_module_sp->GetUUID();
4191 success = module_spec.GetUUID().IsValid() ||
4192 module_spec.GetFileSpec();
4193 } else {
4194 result.AppendError("frame has no module");
4195 error_set = true;
4196 }
4197 } else {
4198 result.AppendError("invalid current frame");
4199 error_set = true;
4200 }
4201 } else {
4202 result.AppendErrorWithFormat("process is not stopped: %s",
4203 StateAsCString(process_state));
4204 error_set = true;
4205 }
4206 } else {
4207 result.AppendError(
4208 "a process must exist in order to use the --frame option");
4209 error_set = true;
4210 }
4211 } else {
4212 if (uuid_option_set) {
4213 module_spec.GetUUID() =
4214 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4215 success |= module_spec.GetUUID().IsValid();
4216 } else if (file_option_set) {
4217 module_spec.GetFileSpec() =
4218 m_file_option.GetOptionValue().GetCurrentValue();
4219 ModuleSP module_sp(
4220 target->GetImages().FindFirstModule(module_spec));
4221 if (module_sp) {
4222 module_spec.GetFileSpec() = module_sp->GetFileSpec();
4223 module_spec.GetPlatformFileSpec() =
4224 module_sp->GetPlatformFileSpec();
4225 module_spec.GetUUID() = module_sp->GetUUID();
4226 module_spec.GetArchitecture() = module_sp->GetArchitecture();
4227 } else {
4228 module_spec.GetArchitecture() = target->GetArchitecture();
4229 }
4230 success |= module_spec.GetUUID().IsValid() ||
4231 module_spec.GetFileSpec().Exists();
4232 }
4233 }
4234
4235 if (success) {
4236 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4237 if (module_spec.GetSymbolFileSpec())
4238 success = AddModuleSymbols(target, module_spec, flush, result);
4239 }
4240 }
4241
4242 if (!success && !error_set) {
4243 StreamString error_strm;
4244 if (uuid_option_set) {
4245 error_strm.PutCString("unable to find debug symbols for UUID ");
4246 module_spec.GetUUID().Dump(&error_strm);
4247 } else if (file_option_set) {
4248 error_strm.PutCString(
4249 "unable to find debug symbols for the executable file ");
4250 error_strm << module_spec.GetFileSpec();
4251 } else if (frame_option_set) {
4252 error_strm.PutCString(
4253 "unable to find debug symbols for the current frame");
4254 }
Zachary Turnerc1564272016-11-16 21:15:24 +00004255 result.AppendError(error_strm.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004256 }
4257 } else {
4258 result.AppendError("one or more symbol file paths must be specified, "
4259 "or options must be specified");
4260 }
4261 } else {
4262 if (uuid_option_set) {
4263 result.AppendError("specify either one or more paths to symbol files "
4264 "or use the --uuid option without arguments");
4265 } else if (file_option_set) {
4266 result.AppendError("specify either one or more paths to symbol files "
4267 "or use the --file option without arguments");
4268 } else if (frame_option_set) {
4269 result.AppendError("specify either one or more paths to symbol files "
4270 "or use the --frame option without arguments");
4271 } else {
4272 PlatformSP platform_sp(target->GetPlatform());
4273
Zachary Turner97d2c402016-10-05 23:40:23 +00004274 for (auto &entry : args.entries()) {
4275 if (!entry.ref.empty()) {
4276 module_spec.GetSymbolFileSpec().SetFile(entry.ref, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004277 if (platform_sp) {
4278 FileSpec symfile_spec;
4279 if (platform_sp
4280 ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4281 .Success())
4282 module_spec.GetSymbolFileSpec() = symfile_spec;
4283 }
4284
4285 ArchSpec arch;
4286 bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
4287
4288 if (symfile_exists) {
4289 if (!AddModuleSymbols(target, module_spec, flush, result))
4290 break;
4291 } else {
Zachary Turner97d2c402016-10-05 23:40:23 +00004292 std::string resolved_symfile_path =
4293 module_spec.GetSymbolFileSpec().GetPath();
4294 if (resolved_symfile_path != entry.ref) {
4295 result.AppendErrorWithFormat(
4296 "invalid module path '%s' with resolved path '%s'\n",
4297 entry.c_str(), resolved_symfile_path.c_str());
4298 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004299 }
4300 result.AppendErrorWithFormat("invalid module path '%s'\n",
Zachary Turner97d2c402016-10-05 23:40:23 +00004301 entry.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004302 break;
4303 }
4304 }
4305 }
4306 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00004307 }
4308
Kate Stoneb9c1b512016-09-06 20:57:50 +00004309 if (flush) {
4310 Process *process = m_exe_ctx.GetProcessPtr();
4311 if (process)
4312 process->Flush();
Greg Claytone72dfb32012-02-24 01:59:29 +00004313 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004314 return result.Succeeded();
4315 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004316
Kate Stoneb9c1b512016-09-06 20:57:50 +00004317 OptionGroupOptions m_option_group;
4318 OptionGroupUUID m_uuid_option_group;
4319 OptionGroupFile m_file_option;
4320 OptionGroupBoolean m_current_frame_option;
Greg Claytone72dfb32012-02-24 01:59:29 +00004321};
4322
Greg Claytone72dfb32012-02-24 01:59:29 +00004323#pragma mark CommandObjectTargetSymbols
4324
4325//-------------------------------------------------------------------------
4326// CommandObjectTargetSymbols
4327//-------------------------------------------------------------------------
4328
Kate Stoneb9c1b512016-09-06 20:57:50 +00004329class CommandObjectTargetSymbols : public CommandObjectMultiword {
Greg Claytone72dfb32012-02-24 01:59:29 +00004330public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004331 //------------------------------------------------------------------
4332 // Constructors and Destructors
4333 //------------------------------------------------------------------
4334 CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4335 : CommandObjectMultiword(
4336 interpreter, "target symbols",
4337 "Commands for adding and managing debug symbol files.",
4338 "target symbols <sub-command> ...") {
4339 LoadSubCommand(
4340 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4341 }
Bruce Mitchener13d21e92015-10-07 16:56:17 +00004342
Kate Stoneb9c1b512016-09-06 20:57:50 +00004343 ~CommandObjectTargetSymbols() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004344
Greg Claytone72dfb32012-02-24 01:59:29 +00004345private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004346 //------------------------------------------------------------------
4347 // For CommandObjectTargetModules only
4348 //------------------------------------------------------------------
4349 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols);
Greg Claytone72dfb32012-02-24 01:59:29 +00004350};
4351
Jim Ingham9575d842011-03-11 03:53:59 +00004352#pragma mark CommandObjectTargetStopHookAdd
4353
4354//-------------------------------------------------------------------------
4355// CommandObjectTargetStopHookAdd
4356//-------------------------------------------------------------------------
4357
Zachary Turner1f0f5b52016-09-22 20:22:55 +00004358static OptionDefinition g_target_stop_hook_add_options[] = {
4359 // clang-format off
4360 { 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." },
4361 { 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." },
4362 { 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." },
4363 { 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." },
4364 { 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." },
4365 { 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." },
4366 { 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." },
4367 { 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." },
4368 { 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." },
4369 { 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." },
4370 { 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." },
4371 // clang-format on
4372};
4373
Kate Stoneb9c1b512016-09-06 20:57:50 +00004374class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4375 public IOHandlerDelegateMultiline {
Jim Ingham9575d842011-03-11 03:53:59 +00004376public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004377 class CommandOptions : public Options {
4378 public:
4379 CommandOptions()
4380 : Options(), m_line_start(0), m_line_end(UINT_MAX),
4381 m_func_name_type_mask(eFunctionNameTypeAuto),
4382 m_sym_ctx_specified(false), m_thread_specified(false),
4383 m_use_one_liner(false), m_one_liner() {}
4384
4385 ~CommandOptions() override = default;
4386
Zachary Turner1f0f5b52016-09-22 20:22:55 +00004387 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00004388 return llvm::makeArrayRef(g_target_stop_hook_add_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00004389 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004390
Zachary Turnerfe114832016-11-12 16:56:47 +00004391 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
Kate Stoneb9c1b512016-09-06 20:57:50 +00004392 ExecutionContext *execution_context) override {
4393 Error error;
4394 const int short_option = m_getopt_table[option_idx].val;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004395
4396 switch (short_option) {
4397 case 'c':
4398 m_class_name = option_arg;
4399 m_sym_ctx_specified = true;
4400 break;
4401
4402 case 'e':
Zachary Turnerfe114832016-11-12 16:56:47 +00004403 if (option_arg.getAsInteger(0, m_line_end)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00004404 error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
Zachary Turnerfe114832016-11-12 16:56:47 +00004405 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004406 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004407 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004408 m_sym_ctx_specified = true;
4409 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004410
Kate Stoneb9c1b512016-09-06 20:57:50 +00004411 case 'l':
Zachary Turnerfe114832016-11-12 16:56:47 +00004412 if (option_arg.getAsInteger(0, m_line_start)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00004413 error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
Zachary Turnerfe114832016-11-12 16:56:47 +00004414 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004415 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004416 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004417 m_sym_ctx_specified = true;
4418 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004419
Kate Stoneb9c1b512016-09-06 20:57:50 +00004420 case 'i':
4421 m_no_inlines = true;
4422 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004423
Kate Stoneb9c1b512016-09-06 20:57:50 +00004424 case 'n':
4425 m_function_name = option_arg;
4426 m_func_name_type_mask |= eFunctionNameTypeAuto;
4427 m_sym_ctx_specified = true;
4428 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004429
Kate Stoneb9c1b512016-09-06 20:57:50 +00004430 case 'f':
4431 m_file_name = option_arg;
4432 m_sym_ctx_specified = true;
4433 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004434
Kate Stoneb9c1b512016-09-06 20:57:50 +00004435 case 's':
4436 m_module_name = option_arg;
4437 m_sym_ctx_specified = true;
4438 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004439
Kate Stoneb9c1b512016-09-06 20:57:50 +00004440 case 't':
Zachary Turnerfe114832016-11-12 16:56:47 +00004441 if (option_arg.getAsInteger(0, m_thread_id))
Kate Stoneb9c1b512016-09-06 20:57:50 +00004442 error.SetErrorStringWithFormat("invalid thread id string '%s'",
Zachary Turnerfe114832016-11-12 16:56:47 +00004443 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004444 m_thread_specified = true;
4445 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004446
Kate Stoneb9c1b512016-09-06 20:57:50 +00004447 case 'T':
4448 m_thread_name = option_arg;
4449 m_thread_specified = true;
4450 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004451
Kate Stoneb9c1b512016-09-06 20:57:50 +00004452 case 'q':
4453 m_queue_name = option_arg;
4454 m_thread_specified = true;
4455 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004456
Kate Stoneb9c1b512016-09-06 20:57:50 +00004457 case 'x':
Zachary Turnerfe114832016-11-12 16:56:47 +00004458 if (option_arg.getAsInteger(0, m_thread_index))
Kate Stoneb9c1b512016-09-06 20:57:50 +00004459 error.SetErrorStringWithFormat("invalid thread index string '%s'",
Zachary Turnerfe114832016-11-12 16:56:47 +00004460 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004461 m_thread_specified = true;
4462 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004463
Kate Stoneb9c1b512016-09-06 20:57:50 +00004464 case 'o':
4465 m_use_one_liner = true;
4466 m_one_liner = option_arg;
4467 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004468
Kate Stoneb9c1b512016-09-06 20:57:50 +00004469 default:
4470 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
4471 break;
4472 }
4473 return error;
Jim Ingham9575d842011-03-11 03:53:59 +00004474 }
4475
Kate Stoneb9c1b512016-09-06 20:57:50 +00004476 void OptionParsingStarting(ExecutionContext *execution_context) override {
4477 m_class_name.clear();
4478 m_function_name.clear();
4479 m_line_start = 0;
4480 m_line_end = UINT_MAX;
4481 m_file_name.clear();
4482 m_module_name.clear();
4483 m_func_name_type_mask = eFunctionNameTypeAuto;
4484 m_thread_id = LLDB_INVALID_THREAD_ID;
4485 m_thread_index = UINT32_MAX;
4486 m_thread_name.clear();
4487 m_queue_name.clear();
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004488
Kate Stoneb9c1b512016-09-06 20:57:50 +00004489 m_no_inlines = false;
4490 m_sym_ctx_specified = false;
4491 m_thread_specified = false;
4492
4493 m_use_one_liner = false;
4494 m_one_liner.clear();
Jim Ingham9575d842011-03-11 03:53:59 +00004495 }
4496
Kate Stoneb9c1b512016-09-06 20:57:50 +00004497 std::string m_class_name;
4498 std::string m_function_name;
4499 uint32_t m_line_start;
4500 uint32_t m_line_end;
4501 std::string m_file_name;
4502 std::string m_module_name;
4503 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
4504 lldb::tid_t m_thread_id;
4505 uint32_t m_thread_index;
4506 std::string m_thread_name;
4507 std::string m_queue_name;
4508 bool m_sym_ctx_specified;
4509 bool m_no_inlines;
4510 bool m_thread_specified;
4511 // Instance variables to hold the values for one_liner options.
4512 bool m_use_one_liner;
4513 std::string m_one_liner;
4514 };
4515
4516 CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4517 : CommandObjectParsed(interpreter, "target stop-hook add",
4518 "Add a hook to be executed when the target stops.",
4519 "target stop-hook add"),
4520 IOHandlerDelegateMultiline("DONE",
4521 IOHandlerDelegate::Completion::LLDBCommand),
4522 m_options() {}
4523
4524 ~CommandObjectTargetStopHookAdd() override = default;
4525
4526 Options *GetOptions() override { return &m_options; }
4527
Jim Ingham5a988412012-06-08 21:56:10 +00004528protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004529 void IOHandlerActivated(IOHandler &io_handler) override {
4530 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4531 if (output_sp) {
4532 output_sp->PutCString(
4533 "Enter your stop hook command(s). Type 'DONE' to end.\n");
4534 output_sp->Flush();
Greg Clayton44d93782014-01-27 23:43:24 +00004535 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004536 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004537
Kate Stoneb9c1b512016-09-06 20:57:50 +00004538 void IOHandlerInputComplete(IOHandler &io_handler,
4539 std::string &line) override {
4540 if (m_stop_hook_sp) {
4541 if (line.empty()) {
4542 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
4543 if (error_sp) {
4544 error_sp->Printf("error: stop hook #%" PRIu64
4545 " aborted, no commands.\n",
4546 m_stop_hook_sp->GetID());
4547 error_sp->Flush();
Greg Clayton44d93782014-01-27 23:43:24 +00004548 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004549 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Jim Ingham9575d842011-03-11 03:53:59 +00004550 if (target)
Kate Stoneb9c1b512016-09-06 20:57:50 +00004551 target->RemoveStopHookByID(m_stop_hook_sp->GetID());
4552 } else {
4553 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
4554 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4555 if (output_sp) {
4556 output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4557 m_stop_hook_sp->GetID());
4558 output_sp->Flush();
Jim Ingham9575d842011-03-11 03:53:59 +00004559 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004560 }
4561 m_stop_hook_sp.reset();
Jim Ingham9575d842011-03-11 03:53:59 +00004562 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004563 io_handler.SetIsDone(true);
4564 }
4565
4566 bool DoExecute(Args &command, CommandReturnObject &result) override {
4567 m_stop_hook_sp.reset();
4568
4569 Target *target = GetSelectedOrDummyTarget();
4570 if (target) {
4571 Target::StopHookSP new_hook_sp = target->CreateStopHook();
4572
4573 // First step, make the specifier.
4574 std::unique_ptr<SymbolContextSpecifier> specifier_ap;
4575 if (m_options.m_sym_ctx_specified) {
4576 specifier_ap.reset(new SymbolContextSpecifier(
4577 m_interpreter.GetDebugger().GetSelectedTarget()));
4578
4579 if (!m_options.m_module_name.empty()) {
4580 specifier_ap->AddSpecification(
4581 m_options.m_module_name.c_str(),
4582 SymbolContextSpecifier::eModuleSpecified);
4583 }
4584
4585 if (!m_options.m_class_name.empty()) {
4586 specifier_ap->AddSpecification(
4587 m_options.m_class_name.c_str(),
4588 SymbolContextSpecifier::eClassOrNamespaceSpecified);
4589 }
4590
4591 if (!m_options.m_file_name.empty()) {
4592 specifier_ap->AddSpecification(
4593 m_options.m_file_name.c_str(),
4594 SymbolContextSpecifier::eFileSpecified);
4595 }
4596
4597 if (m_options.m_line_start != 0) {
4598 specifier_ap->AddLineSpecification(
4599 m_options.m_line_start,
4600 SymbolContextSpecifier::eLineStartSpecified);
4601 }
4602
4603 if (m_options.m_line_end != UINT_MAX) {
4604 specifier_ap->AddLineSpecification(
4605 m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4606 }
4607
4608 if (!m_options.m_function_name.empty()) {
4609 specifier_ap->AddSpecification(
4610 m_options.m_function_name.c_str(),
4611 SymbolContextSpecifier::eFunctionSpecified);
4612 }
4613 }
4614
4615 if (specifier_ap)
4616 new_hook_sp->SetSpecifier(specifier_ap.release());
4617
4618 // Next see if any of the thread options have been entered:
4619
4620 if (m_options.m_thread_specified) {
4621 ThreadSpec *thread_spec = new ThreadSpec();
4622
4623 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4624 thread_spec->SetTID(m_options.m_thread_id);
4625 }
4626
4627 if (m_options.m_thread_index != UINT32_MAX)
4628 thread_spec->SetIndex(m_options.m_thread_index);
4629
4630 if (!m_options.m_thread_name.empty())
4631 thread_spec->SetName(m_options.m_thread_name.c_str());
4632
4633 if (!m_options.m_queue_name.empty())
4634 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4635
4636 new_hook_sp->SetThreadSpecifier(thread_spec);
4637 }
4638 if (m_options.m_use_one_liner) {
4639 // Use one-liner.
4640 new_hook_sp->GetCommandPointer()->AppendString(
4641 m_options.m_one_liner.c_str());
4642 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4643 new_hook_sp->GetID());
4644 } else {
4645 m_stop_hook_sp = new_hook_sp;
4646 m_interpreter.GetLLDBCommandsFromIOHandler(
4647 "> ", // Prompt
4648 *this, // IOHandlerDelegate
4649 true, // Run IOHandler in async mode
4650 nullptr); // Baton for the "io_handler" that will be passed back
4651 // into our IOHandlerDelegate functions
4652 }
4653 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4654 } else {
4655 result.AppendError("invalid target\n");
4656 result.SetStatus(eReturnStatusFailed);
4657 }
4658
4659 return result.Succeeded();
4660 }
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004661
Jim Ingham9575d842011-03-11 03:53:59 +00004662private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004663 CommandOptions m_options;
4664 Target::StopHookSP m_stop_hook_sp;
Jim Ingham9575d842011-03-11 03:53:59 +00004665};
4666
Jim Ingham9575d842011-03-11 03:53:59 +00004667#pragma mark CommandObjectTargetStopHookDelete
4668
4669//-------------------------------------------------------------------------
4670// CommandObjectTargetStopHookDelete
4671//-------------------------------------------------------------------------
4672
Kate Stoneb9c1b512016-09-06 20:57:50 +00004673class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004674public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004675 CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4676 : CommandObjectParsed(interpreter, "target stop-hook delete",
4677 "Delete a stop-hook.",
4678 "target stop-hook delete [<idx>]") {}
Jim Ingham9575d842011-03-11 03:53:59 +00004679
Kate Stoneb9c1b512016-09-06 20:57:50 +00004680 ~CommandObjectTargetStopHookDelete() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004681
Jim Ingham5a988412012-06-08 21:56:10 +00004682protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004683 bool DoExecute(Args &command, CommandReturnObject &result) override {
4684 Target *target = GetSelectedOrDummyTarget();
4685 if (target) {
4686 // FIXME: see if we can use the breakpoint id style parser?
4687 size_t num_args = command.GetArgumentCount();
4688 if (num_args == 0) {
4689 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4690 result.SetStatus(eReturnStatusFailed);
4691 return false;
4692 } else {
4693 target->RemoveAllStopHooks();
Jim Ingham9575d842011-03-11 03:53:59 +00004694 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004695 } else {
4696 bool success;
4697 for (size_t i = 0; i < num_args; i++) {
4698 lldb::user_id_t user_id = StringConvert::ToUInt32(
4699 command.GetArgumentAtIndex(i), 0, 0, &success);
4700 if (!success) {
4701 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4702 command.GetArgumentAtIndex(i));
4703 result.SetStatus(eReturnStatusFailed);
4704 return false;
4705 }
4706 success = target->RemoveStopHookByID(user_id);
4707 if (!success) {
4708 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4709 command.GetArgumentAtIndex(i));
4710 result.SetStatus(eReturnStatusFailed);
4711 return false;
4712 }
Jim Ingham9575d842011-03-11 03:53:59 +00004713 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004714 }
4715 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4716 } else {
4717 result.AppendError("invalid target\n");
4718 result.SetStatus(eReturnStatusFailed);
Jim Ingham9575d842011-03-11 03:53:59 +00004719 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004720
4721 return result.Succeeded();
4722 }
Jim Ingham9575d842011-03-11 03:53:59 +00004723};
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004724
Jim Ingham9575d842011-03-11 03:53:59 +00004725#pragma mark CommandObjectTargetStopHookEnableDisable
4726
4727//-------------------------------------------------------------------------
4728// CommandObjectTargetStopHookEnableDisable
4729//-------------------------------------------------------------------------
4730
Kate Stoneb9c1b512016-09-06 20:57:50 +00004731class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004732public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004733 CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4734 bool enable, const char *name,
4735 const char *help, const char *syntax)
4736 : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4737 }
Jim Ingham9575d842011-03-11 03:53:59 +00004738
Kate Stoneb9c1b512016-09-06 20:57:50 +00004739 ~CommandObjectTargetStopHookEnableDisable() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004740
Jim Ingham5a988412012-06-08 21:56:10 +00004741protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004742 bool DoExecute(Args &command, CommandReturnObject &result) override {
4743 Target *target = GetSelectedOrDummyTarget();
4744 if (target) {
4745 // FIXME: see if we can use the breakpoint id style parser?
4746 size_t num_args = command.GetArgumentCount();
4747 bool success;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004748
Kate Stoneb9c1b512016-09-06 20:57:50 +00004749 if (num_args == 0) {
4750 target->SetAllStopHooksActiveState(m_enable);
4751 } else {
4752 for (size_t i = 0; i < num_args; i++) {
4753 lldb::user_id_t user_id = StringConvert::ToUInt32(
4754 command.GetArgumentAtIndex(i), 0, 0, &success);
4755 if (!success) {
4756 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4757 command.GetArgumentAtIndex(i));
4758 result.SetStatus(eReturnStatusFailed);
4759 return false;
4760 }
4761 success = target->SetStopHookActiveStateByID(user_id, m_enable);
4762 if (!success) {
4763 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4764 command.GetArgumentAtIndex(i));
4765 result.SetStatus(eReturnStatusFailed);
4766 return false;
4767 }
Jim Ingham9575d842011-03-11 03:53:59 +00004768 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004769 }
4770 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4771 } else {
4772 result.AppendError("invalid target\n");
4773 result.SetStatus(eReturnStatusFailed);
Jim Ingham9575d842011-03-11 03:53:59 +00004774 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004775 return result.Succeeded();
4776 }
4777
Jim Ingham9575d842011-03-11 03:53:59 +00004778private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004779 bool m_enable;
Jim Ingham9575d842011-03-11 03:53:59 +00004780};
4781
4782#pragma mark CommandObjectTargetStopHookList
4783
4784//-------------------------------------------------------------------------
4785// CommandObjectTargetStopHookList
4786//-------------------------------------------------------------------------
4787
Kate Stoneb9c1b512016-09-06 20:57:50 +00004788class CommandObjectTargetStopHookList : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004789public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004790 CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4791 : CommandObjectParsed(interpreter, "target stop-hook list",
4792 "List all stop-hooks.",
4793 "target stop-hook list [<type>]") {}
Jim Ingham9575d842011-03-11 03:53:59 +00004794
Kate Stoneb9c1b512016-09-06 20:57:50 +00004795 ~CommandObjectTargetStopHookList() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004796
Jim Ingham5a988412012-06-08 21:56:10 +00004797protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004798 bool DoExecute(Args &command, CommandReturnObject &result) override {
4799 Target *target = GetSelectedOrDummyTarget();
4800 if (!target) {
4801 result.AppendError("invalid target\n");
4802 result.SetStatus(eReturnStatusFailed);
4803 return result.Succeeded();
Jim Ingham9575d842011-03-11 03:53:59 +00004804 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004805
4806 size_t num_hooks = target->GetNumStopHooks();
4807 if (num_hooks == 0) {
4808 result.GetOutputStream().PutCString("No stop hooks.\n");
4809 } else {
4810 for (size_t i = 0; i < num_hooks; i++) {
4811 Target::StopHookSP this_hook = target->GetStopHookAtIndex(i);
4812 if (i > 0)
4813 result.GetOutputStream().PutCString("\n");
4814 this_hook->GetDescription(&(result.GetOutputStream()),
4815 eDescriptionLevelFull);
4816 }
4817 }
4818 result.SetStatus(eReturnStatusSuccessFinishResult);
4819 return result.Succeeded();
4820 }
Jim Ingham9575d842011-03-11 03:53:59 +00004821};
4822
4823#pragma mark CommandObjectMultiwordTargetStopHooks
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004824
Jim Ingham9575d842011-03-11 03:53:59 +00004825//-------------------------------------------------------------------------
4826// CommandObjectMultiwordTargetStopHooks
4827//-------------------------------------------------------------------------
4828
Kate Stoneb9c1b512016-09-06 20:57:50 +00004829class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
Jim Ingham9575d842011-03-11 03:53:59 +00004830public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004831 CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4832 : CommandObjectMultiword(
4833 interpreter, "target stop-hook",
4834 "Commands for operating on debugger target stop-hooks.",
4835 "target stop-hook <subcommand> [<subcommand-options>]") {
4836 LoadSubCommand("add", CommandObjectSP(
4837 new CommandObjectTargetStopHookAdd(interpreter)));
4838 LoadSubCommand(
4839 "delete",
4840 CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
4841 LoadSubCommand("disable",
4842 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4843 interpreter, false, "target stop-hook disable [<id>]",
4844 "Disable a stop-hook.", "target stop-hook disable")));
4845 LoadSubCommand("enable",
4846 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4847 interpreter, true, "target stop-hook enable [<id>]",
4848 "Enable a stop-hook.", "target stop-hook enable")));
4849 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
4850 interpreter)));
4851 }
Jim Ingham9575d842011-03-11 03:53:59 +00004852
Kate Stoneb9c1b512016-09-06 20:57:50 +00004853 ~CommandObjectMultiwordTargetStopHooks() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004854};
4855
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004856#pragma mark CommandObjectMultiwordTarget
4857
4858//-------------------------------------------------------------------------
4859// CommandObjectMultiwordTarget
4860//-------------------------------------------------------------------------
4861
Kate Stoneb9c1b512016-09-06 20:57:50 +00004862CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
4863 CommandInterpreter &interpreter)
4864 : CommandObjectMultiword(interpreter, "target",
4865 "Commands for operating on debugger targets.",
4866 "target <subcommand> [<subcommand-options>]") {
4867 LoadSubCommand("create",
4868 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
4869 LoadSubCommand("delete",
4870 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
4871 LoadSubCommand("list",
4872 CommandObjectSP(new CommandObjectTargetList(interpreter)));
4873 LoadSubCommand("select",
4874 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
4875 LoadSubCommand(
4876 "stop-hook",
4877 CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
4878 LoadSubCommand("modules",
4879 CommandObjectSP(new CommandObjectTargetModules(interpreter)));
4880 LoadSubCommand("symbols",
4881 CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
4882 LoadSubCommand("variable",
4883 CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004884}
4885
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004886CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;