blob: 37dec18480587b296afe51edb86e1f72356b8fd8 [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',
Hafiz Abid Qadeerb10fb962017-01-24 23:07:27 +00002571 "Write file contents to the memory.", false, true),
2572 m_pc_option(LLDB_OPT_SET_1, false, "--set-pc-to-entry", 'p',
2573 "Set PC to the entry point."
2574 " Only applicable with '--load' option.",
2575 false, true),
Kate Stoneb9c1b512016-09-06 20:57:50 +00002576 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2577 "Set the load address for all sections to be the "
2578 "virtual address in the file plus the offset.",
2579 0) {
2580 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2581 LLDB_OPT_SET_1);
2582 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002583 m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Hafiz Abid Qadeerb10fb962017-01-24 23:07:27 +00002584 m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002585 m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2586 m_option_group.Finalize();
2587 }
2588
2589 ~CommandObjectTargetModulesLoad() override = default;
2590
2591 Options *GetOptions() override { return &m_option_group; }
2592
2593protected:
2594 bool DoExecute(Args &args, CommandReturnObject &result) override {
2595 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002596 const bool load = m_load_option.GetOptionValue().GetCurrentValue();
Hafiz Abid Qadeerb10fb962017-01-24 23:07:27 +00002597 const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002598 if (target == nullptr) {
2599 result.AppendError("invalid target, create a debug target using the "
2600 "'target create' command");
2601 result.SetStatus(eReturnStatusFailed);
2602 return false;
2603 } else {
2604 const size_t argc = args.GetArgumentCount();
2605 ModuleSpec module_spec;
2606 bool search_using_module_spec = false;
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002607
2608 // Allow "load" option to work without --file or --uuid
2609 // option.
2610 if (load) {
2611 if (!m_file_option.GetOptionValue().OptionWasSet() &&
2612 !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2613 ModuleList &module_list = target->GetImages();
2614 if (module_list.GetSize() == 1) {
2615 search_using_module_spec = true;
2616 module_spec.GetFileSpec() =
2617 module_list.GetModuleAtIndex(0)->GetFileSpec();
2618 }
2619 }
2620 }
2621
Kate Stoneb9c1b512016-09-06 20:57:50 +00002622 if (m_file_option.GetOptionValue().OptionWasSet()) {
2623 search_using_module_spec = true;
2624 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2625 const bool use_global_module_list = true;
2626 ModuleList module_list;
2627 const size_t num_matches = FindModulesByName(
2628 target, arg_cstr, module_list, use_global_module_list);
2629 if (num_matches == 1) {
2630 module_spec.GetFileSpec() =
2631 module_list.GetModuleAtIndex(0)->GetFileSpec();
2632 } else if (num_matches > 1) {
2633 search_using_module_spec = false;
2634 result.AppendErrorWithFormat(
2635 "more than 1 module matched by name '%s'\n", arg_cstr);
2636 result.SetStatus(eReturnStatusFailed);
2637 } else {
2638 search_using_module_spec = false;
2639 result.AppendErrorWithFormat("no object file for module '%s'\n",
2640 arg_cstr);
2641 result.SetStatus(eReturnStatusFailed);
2642 }
2643 }
2644
2645 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2646 search_using_module_spec = true;
2647 module_spec.GetUUID() =
2648 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2649 }
2650
2651 if (search_using_module_spec) {
2652 ModuleList matching_modules;
2653 const size_t num_matches =
2654 target->GetImages().FindModules(module_spec, matching_modules);
2655
2656 char path[PATH_MAX];
2657 if (num_matches == 1) {
2658 Module *module = matching_modules.GetModulePointerAtIndex(0);
2659 if (module) {
2660 ObjectFile *objfile = module->GetObjectFile();
2661 if (objfile) {
2662 SectionList *section_list = module->GetSectionList();
2663 if (section_list) {
2664 bool changed = false;
2665 if (argc == 0) {
2666 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2667 const addr_t slide =
2668 m_slide_option.GetOptionValue().GetCurrentValue();
2669 const bool slide_is_offset = true;
2670 module->SetLoadAddress(*target, slide, slide_is_offset,
2671 changed);
2672 } else {
2673 result.AppendError("one or more section name + load "
2674 "address pair must be specified");
2675 result.SetStatus(eReturnStatusFailed);
2676 return false;
2677 }
2678 } else {
2679 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2680 result.AppendError("The \"--slide <offset>\" option can't "
2681 "be used in conjunction with setting "
2682 "section load addresses.\n");
2683 result.SetStatus(eReturnStatusFailed);
2684 return false;
2685 }
2686
2687 for (size_t i = 0; i < argc; i += 2) {
2688 const char *sect_name = args.GetArgumentAtIndex(i);
2689 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2690 if (sect_name && load_addr_cstr) {
2691 ConstString const_sect_name(sect_name);
2692 bool success = false;
2693 addr_t load_addr = StringConvert::ToUInt64(
2694 load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2695 if (success) {
2696 SectionSP section_sp(
2697 section_list->FindSectionByName(const_sect_name));
2698 if (section_sp) {
2699 if (section_sp->IsThreadSpecific()) {
2700 result.AppendErrorWithFormat(
2701 "thread specific sections are not yet "
2702 "supported (section '%s')\n",
2703 sect_name);
2704 result.SetStatus(eReturnStatusFailed);
2705 break;
2706 } else {
2707 if (target->GetSectionLoadList()
2708 .SetSectionLoadAddress(section_sp,
2709 load_addr))
2710 changed = true;
2711 result.AppendMessageWithFormat(
2712 "section '%s' loaded at 0x%" PRIx64 "\n",
2713 sect_name, load_addr);
2714 }
2715 } else {
2716 result.AppendErrorWithFormat("no section found that "
2717 "matches the section "
2718 "name '%s'\n",
2719 sect_name);
2720 result.SetStatus(eReturnStatusFailed);
2721 break;
2722 }
2723 } else {
2724 result.AppendErrorWithFormat(
2725 "invalid load address string '%s'\n",
2726 load_addr_cstr);
2727 result.SetStatus(eReturnStatusFailed);
2728 break;
2729 }
2730 } else {
2731 if (sect_name)
2732 result.AppendError("section names must be followed by "
2733 "a load address.\n");
2734 else
2735 result.AppendError("one or more section name + load "
2736 "address pair must be specified.\n");
2737 result.SetStatus(eReturnStatusFailed);
2738 break;
2739 }
2740 }
2741 }
2742
2743 if (changed) {
2744 target->ModulesDidLoad(matching_modules);
2745 Process *process = m_exe_ctx.GetProcessPtr();
2746 if (process)
2747 process->Flush();
2748 }
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002749 if (load) {
Hafiz Abid Qadeerb10fb962017-01-24 23:07:27 +00002750 Error error = module->LoadInMemory(*target, set_pc);
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002751 if (error.Fail()) {
2752 result.AppendError(error.AsCString());
2753 return false;
2754 }
2755 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002756 } else {
2757 module->GetFileSpec().GetPath(path, sizeof(path));
2758 result.AppendErrorWithFormat(
2759 "no sections in object file '%s'\n", path);
2760 result.SetStatus(eReturnStatusFailed);
2761 }
2762 } else {
2763 module->GetFileSpec().GetPath(path, sizeof(path));
2764 result.AppendErrorWithFormat("no object file for module '%s'\n",
2765 path);
2766 result.SetStatus(eReturnStatusFailed);
2767 }
2768 } else {
2769 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2770 if (module_spec_file) {
2771 module_spec_file->GetPath(path, sizeof(path));
2772 result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2773 } else
2774 result.AppendError("no module spec");
2775 result.SetStatus(eReturnStatusFailed);
2776 }
2777 } else {
2778 std::string uuid_str;
2779
2780 if (module_spec.GetFileSpec())
2781 module_spec.GetFileSpec().GetPath(path, sizeof(path));
2782 else
2783 path[0] = '\0';
2784
2785 if (module_spec.GetUUIDPtr())
2786 uuid_str = module_spec.GetUUID().GetAsString();
2787 if (num_matches > 1) {
2788 result.AppendErrorWithFormat(
2789 "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2790 path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2791 for (size_t i = 0; i < num_matches; ++i) {
2792 if (matching_modules.GetModulePointerAtIndex(i)
2793 ->GetFileSpec()
2794 .GetPath(path, sizeof(path)))
2795 result.AppendMessageWithFormat("%s\n", path);
2796 }
2797 } else {
2798 result.AppendErrorWithFormat(
2799 "no modules were found that match%s%s%s%s.\n",
2800 path[0] ? " file=" : "", path,
2801 !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2802 }
2803 result.SetStatus(eReturnStatusFailed);
2804 }
2805 } else {
2806 result.AppendError("either the \"--file <module>\" or the \"--uuid "
2807 "<uuid>\" option must be specified.\n");
2808 result.SetStatus(eReturnStatusFailed);
2809 return false;
2810 }
2811 }
2812 return result.Succeeded();
2813 }
2814
2815 OptionGroupOptions m_option_group;
2816 OptionGroupUUID m_uuid_option_group;
2817 OptionGroupString m_file_option;
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002818 OptionGroupBoolean m_load_option;
Hafiz Abid Qadeerb10fb962017-01-24 23:07:27 +00002819 OptionGroupBoolean m_pc_option;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002820 OptionGroupUInt64 m_slide_option;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002821};
2822
2823//----------------------------------------------------------------------
2824// List images with associated information
2825//----------------------------------------------------------------------
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002826
2827static OptionDefinition g_target_modules_list_options[] = {
2828 // clang-format off
2829 { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Display the image at this address." },
2830 { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the architecture when listing images." },
2831 { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the triple when listing images." },
2832 { 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." },
2833 { 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)." },
2834 { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the UUID when listing images." },
2835 { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image object file." },
2836 { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the directory with optional width for the image object file." },
2837 { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the basename with optional width for the image object file." },
2838 { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width." },
2839 { 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." },
2840 { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the modification time with optional width of the module." },
2841 { 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." },
2842 { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the module pointer." },
2843 { 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." }
2844 // clang-format on
2845};
2846
Kate Stoneb9c1b512016-09-06 20:57:50 +00002847class CommandObjectTargetModulesList : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002848public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002849 class CommandOptions : public Options {
2850 public:
2851 CommandOptions()
2852 : Options(), m_format_array(), m_use_global_module_list(false),
2853 m_module_addr(LLDB_INVALID_ADDRESS) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002854
Kate Stoneb9c1b512016-09-06 20:57:50 +00002855 ~CommandOptions() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002856
Zachary Turnerfe114832016-11-12 16:56:47 +00002857 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002858 ExecutionContext *execution_context) override {
2859 Error error;
Greg Claytonb9d5df52012-12-06 22:49:16 +00002860
Kate Stoneb9c1b512016-09-06 20:57:50 +00002861 const int short_option = m_getopt_table[option_idx].val;
2862 if (short_option == 'g') {
2863 m_use_global_module_list = true;
2864 } else if (short_option == 'a') {
2865 m_module_addr = Args::StringToAddress(execution_context, option_arg,
2866 LLDB_INVALID_ADDRESS, &error);
2867 } else {
2868 unsigned long width = 0;
Zachary Turnerfe114832016-11-12 16:56:47 +00002869 option_arg.getAsInteger(0, width);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002870 m_format_array.push_back(std::make_pair(short_option, width));
2871 }
2872 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002873 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002874
Kate Stoneb9c1b512016-09-06 20:57:50 +00002875 void OptionParsingStarting(ExecutionContext *execution_context) override {
2876 m_format_array.clear();
2877 m_use_global_module_list = false;
2878 m_module_addr = LLDB_INVALID_ADDRESS;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002879 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002880
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002881 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00002882 return llvm::makeArrayRef(g_target_modules_list_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002883 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002884
2885 // Instance variables to hold the values for command options.
2886 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
2887 FormatWidthCollection m_format_array;
2888 bool m_use_global_module_list;
2889 lldb::addr_t m_module_addr;
2890 };
2891
2892 CommandObjectTargetModulesList(CommandInterpreter &interpreter)
2893 : CommandObjectParsed(
2894 interpreter, "target modules list",
2895 "List current executable and dependent shared library images.",
2896 "target modules list [<cmd-options>]"),
2897 m_options() {}
2898
2899 ~CommandObjectTargetModulesList() override = default;
2900
2901 Options *GetOptions() override { return &m_options; }
2902
Jim Ingham5a988412012-06-08 21:56:10 +00002903protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002904 bool DoExecute(Args &command, CommandReturnObject &result) override {
2905 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2906 const bool use_global_module_list = m_options.m_use_global_module_list;
2907 // Define a local module list here to ensure it lives longer than any
2908 // "locker"
2909 // object which might lock its contents below (through the "module_list_ptr"
2910 // variable).
2911 ModuleList module_list;
2912 if (target == nullptr && !use_global_module_list) {
2913 result.AppendError("invalid target, create a debug target using the "
2914 "'target create' command");
2915 result.SetStatus(eReturnStatusFailed);
2916 return false;
2917 } else {
2918 if (target) {
2919 uint32_t addr_byte_size =
2920 target->GetArchitecture().GetAddressByteSize();
2921 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2922 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2923 }
2924 // Dump all sections for all modules images
2925 Stream &strm = result.GetOutputStream();
2926
2927 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
2928 if (target) {
2929 Address module_address;
2930 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
2931 ModuleSP module_sp(module_address.GetModule());
2932 if (module_sp) {
2933 PrintModule(target, module_sp.get(), 0, strm);
2934 result.SetStatus(eReturnStatusSuccessFinishResult);
2935 } else {
2936 result.AppendErrorWithFormat(
2937 "Couldn't find module matching address: 0x%" PRIx64 ".",
2938 m_options.m_module_addr);
2939 result.SetStatus(eReturnStatusFailed);
Greg Clayton3418c852011-08-10 02:10:13 +00002940 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002941 } else {
2942 result.AppendErrorWithFormat(
2943 "Couldn't find module containing address: 0x%" PRIx64 ".",
2944 m_options.m_module_addr);
2945 result.SetStatus(eReturnStatusFailed);
2946 }
2947 } else {
2948 result.AppendError(
2949 "Can only look up modules by address with a valid target.");
2950 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002951 }
2952 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002953 }
Jim Inghamc10312c2011-10-24 18:36:33 +00002954
Kate Stoneb9c1b512016-09-06 20:57:50 +00002955 size_t num_modules = 0;
2956
2957 // This locker will be locked on the mutex in module_list_ptr if it is
2958 // non-nullptr.
2959 // Otherwise it will lock the AllocationModuleCollectionMutex when
2960 // accessing
2961 // the global module list directly.
2962 std::unique_lock<std::recursive_mutex> guard(
2963 Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
2964
2965 const ModuleList *module_list_ptr = nullptr;
2966 const size_t argc = command.GetArgumentCount();
2967 if (argc == 0) {
2968 if (use_global_module_list) {
2969 guard.lock();
2970 num_modules = Module::GetNumberAllocatedModules();
2971 } else {
2972 module_list_ptr = &target->GetImages();
Jim Ingham28eb5712012-10-12 17:34:26 +00002973 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002974 } else {
Zachary Turner97d2c402016-10-05 23:40:23 +00002975 // TODO: Convert to entry based iteration. Requires converting
2976 // FindModulesByName.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002977 for (size_t i = 0; i < argc; ++i) {
2978 // Dump specified images (by basename or fullpath)
2979 const char *arg_cstr = command.GetArgumentAtIndex(i);
2980 const size_t num_matches = FindModulesByName(
2981 target, arg_cstr, module_list, use_global_module_list);
2982 if (num_matches == 0) {
2983 if (argc == 1) {
2984 result.AppendErrorWithFormat("no modules found that match '%s'",
2985 arg_cstr);
2986 result.SetStatus(eReturnStatusFailed);
2987 return false;
Jim Inghamc10312c2011-10-24 18:36:33 +00002988 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002989 }
Greg Claytonc9660542012-02-05 02:38:54 +00002990 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002991
2992 module_list_ptr = &module_list;
2993 }
2994
2995 std::unique_lock<std::recursive_mutex> lock;
2996 if (module_list_ptr != nullptr) {
2997 lock =
2998 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
2999
3000 num_modules = module_list_ptr->GetSize();
3001 }
3002
3003 if (num_modules > 0) {
3004 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3005 ModuleSP module_sp;
3006 Module *module;
3007 if (module_list_ptr) {
3008 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3009 module = module_sp.get();
3010 } else {
3011 module = Module::GetAllocatedModuleAtIndex(image_idx);
3012 module_sp = module->shared_from_this();
3013 }
3014
3015 const size_t indent = strm.Printf("[%3u] ", image_idx);
3016 PrintModule(target, module, indent, strm);
Jim Inghamc10312c2011-10-24 18:36:33 +00003017 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003018 result.SetStatus(eReturnStatusSuccessFinishResult);
3019 } else {
3020 if (argc) {
3021 if (use_global_module_list)
3022 result.AppendError(
3023 "the global module list has no matching modules");
3024 else
3025 result.AppendError("the target has no matching modules");
3026 } else {
3027 if (use_global_module_list)
3028 result.AppendError("the global module list is empty");
3029 else
3030 result.AppendError(
3031 "the target has no associated executable images");
3032 }
3033 result.SetStatus(eReturnStatusFailed);
3034 return false;
3035 }
3036 }
3037 return result.Succeeded();
3038 }
3039
3040 void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
3041 if (module == nullptr) {
3042 strm.PutCString("Null module");
3043 return;
Jim Inghamc10312c2011-10-24 18:36:33 +00003044 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003045
Kate Stoneb9c1b512016-09-06 20:57:50 +00003046 bool dump_object_name = false;
3047 if (m_options.m_format_array.empty()) {
3048 m_options.m_format_array.push_back(std::make_pair('u', 0));
3049 m_options.m_format_array.push_back(std::make_pair('h', 0));
3050 m_options.m_format_array.push_back(std::make_pair('f', 0));
3051 m_options.m_format_array.push_back(std::make_pair('S', 0));
3052 }
3053 const size_t num_entries = m_options.m_format_array.size();
3054 bool print_space = false;
3055 for (size_t i = 0; i < num_entries; ++i) {
3056 if (print_space)
3057 strm.PutChar(' ');
3058 print_space = true;
3059 const char format_char = m_options.m_format_array[i].first;
3060 uint32_t width = m_options.m_format_array[i].second;
3061 switch (format_char) {
3062 case 'A':
3063 DumpModuleArchitecture(strm, module, false, width);
3064 break;
3065
3066 case 't':
3067 DumpModuleArchitecture(strm, module, true, width);
3068 break;
3069
3070 case 'f':
3071 DumpFullpath(strm, &module->GetFileSpec(), width);
3072 dump_object_name = true;
3073 break;
3074
3075 case 'd':
3076 DumpDirectory(strm, &module->GetFileSpec(), width);
3077 break;
3078
3079 case 'b':
3080 DumpBasename(strm, &module->GetFileSpec(), width);
3081 dump_object_name = true;
3082 break;
3083
3084 case 'h':
3085 case 'o':
3086 // Image header address
3087 {
3088 uint32_t addr_nibble_width =
3089 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3090 : 16;
3091
3092 ObjectFile *objfile = module->GetObjectFile();
3093 if (objfile) {
3094 Address header_addr(objfile->GetHeaderAddress());
3095 if (header_addr.IsValid()) {
3096 if (target && !target->GetSectionLoadList().IsEmpty()) {
3097 lldb::addr_t header_load_addr =
3098 header_addr.GetLoadAddress(target);
3099 if (header_load_addr == LLDB_INVALID_ADDRESS) {
3100 header_addr.Dump(&strm, target,
3101 Address::DumpStyleModuleWithFileAddress,
3102 Address::DumpStyleFileAddress);
3103 } else {
3104 if (format_char == 'o') {
3105 // Show the offset of slide for the image
3106 strm.Printf(
3107 "0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width,
3108 header_load_addr - header_addr.GetFileAddress());
3109 } else {
3110 // Show the load address of the image
3111 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3112 addr_nibble_width, header_load_addr);
3113 }
3114 }
3115 break;
3116 }
3117 // The address was valid, but the image isn't loaded, output the
3118 // address in an appropriate format
3119 header_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3120 break;
3121 }
3122 }
3123 strm.Printf("%*s", addr_nibble_width + 2, "");
3124 }
3125 break;
3126
3127 case 'r': {
3128 size_t ref_count = 0;
3129 ModuleSP module_sp(module->shared_from_this());
3130 if (module_sp) {
3131 // Take one away to make sure we don't count our local "module_sp"
3132 ref_count = module_sp.use_count() - 1;
3133 }
3134 if (width)
3135 strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3136 else
3137 strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3138 } break;
3139
3140 case 's':
3141 case 'S': {
3142 const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3143 if (symbol_vendor) {
3144 const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3145 if (format_char == 'S') {
3146 // Dump symbol file only if different from module file
3147 if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3148 print_space = false;
3149 break;
3150 }
3151 // Add a newline and indent past the index
3152 strm.Printf("\n%*s", indent, "");
3153 }
3154 DumpFullpath(strm, &symfile_spec, width);
3155 dump_object_name = true;
3156 break;
3157 }
3158 strm.Printf("%.*s", width, "<NONE>");
3159 } break;
3160
3161 case 'm':
Pavel Labath7e2cfbf2016-11-09 09:59:18 +00003162 DumpTimePoint(module->GetModificationTime(), strm, width);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003163 break;
3164
3165 case 'p':
3166 strm.Printf("%p", static_cast<void *>(module));
3167 break;
3168
3169 case 'u':
3170 DumpModuleUUID(strm, module);
3171 break;
3172
3173 default:
3174 break;
3175 }
3176 }
3177 if (dump_object_name) {
3178 const char *object_name = module->GetObjectName().GetCString();
3179 if (object_name)
3180 strm.Printf("(%s)", object_name);
3181 }
3182 strm.EOL();
3183 }
3184
3185 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003186};
3187
Jason Molenda380241a2012-07-12 00:20:07 +00003188#pragma mark CommandObjectTargetModulesShowUnwind
Greg Claytoneffe5c92011-05-03 22:09:39 +00003189
Jason Molenda380241a2012-07-12 00:20:07 +00003190//----------------------------------------------------------------------
3191// Lookup unwind information in images
3192//----------------------------------------------------------------------
3193
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003194static OptionDefinition g_target_modules_show_unwind_options[] = {
3195 // clang-format off
3196 { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name." },
3197 { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" }
3198 // clang-format on
3199};
3200
Kate Stoneb9c1b512016-09-06 20:57:50 +00003201class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
Jason Molenda380241a2012-07-12 00:20:07 +00003202public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003203 enum {
3204 eLookupTypeInvalid = -1,
3205 eLookupTypeAddress = 0,
3206 eLookupTypeSymbol,
3207 eLookupTypeFunction,
3208 eLookupTypeFunctionOrSymbol,
3209 kNumLookupTypes
3210 };
Jason Molenda380241a2012-07-12 00:20:07 +00003211
Kate Stoneb9c1b512016-09-06 20:57:50 +00003212 class CommandOptions : public Options {
3213 public:
3214 CommandOptions()
3215 : Options(), m_type(eLookupTypeInvalid), m_str(),
3216 m_addr(LLDB_INVALID_ADDRESS) {}
Jason Molenda380241a2012-07-12 00:20:07 +00003217
Kate Stoneb9c1b512016-09-06 20:57:50 +00003218 ~CommandOptions() override = default;
Jason Molenda380241a2012-07-12 00:20:07 +00003219
Zachary Turnerfe114832016-11-12 16:56:47 +00003220 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
Kate Stoneb9c1b512016-09-06 20:57:50 +00003221 ExecutionContext *execution_context) override {
3222 Error error;
Jason Molenda380241a2012-07-12 00:20:07 +00003223
Kate Stoneb9c1b512016-09-06 20:57:50 +00003224 const int short_option = m_getopt_table[option_idx].val;
Jason Molenda380241a2012-07-12 00:20:07 +00003225
Kate Stoneb9c1b512016-09-06 20:57:50 +00003226 switch (short_option) {
3227 case 'a': {
3228 m_str = option_arg;
3229 m_type = eLookupTypeAddress;
3230 m_addr = Args::StringToAddress(execution_context, option_arg,
3231 LLDB_INVALID_ADDRESS, &error);
3232 if (m_addr == LLDB_INVALID_ADDRESS)
3233 error.SetErrorStringWithFormat("invalid address string '%s'",
Zachary Turnerfe114832016-11-12 16:56:47 +00003234 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003235 break;
3236 }
Jason Molenda380241a2012-07-12 00:20:07 +00003237
Kate Stoneb9c1b512016-09-06 20:57:50 +00003238 case 'n':
3239 m_str = option_arg;
3240 m_type = eLookupTypeFunctionOrSymbol;
3241 break;
Michael Sartainb1e15922013-08-22 20:42:30 +00003242
Kate Stoneb9c1b512016-09-06 20:57:50 +00003243 default:
3244 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
3245 break;
3246 }
Jason Molenda380241a2012-07-12 00:20:07 +00003247
Kate Stoneb9c1b512016-09-06 20:57:50 +00003248 return error;
Jason Molenda380241a2012-07-12 00:20:07 +00003249 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003250
Kate Stoneb9c1b512016-09-06 20:57:50 +00003251 void OptionParsingStarting(ExecutionContext *execution_context) override {
3252 m_type = eLookupTypeInvalid;
3253 m_str.clear();
3254 m_addr = LLDB_INVALID_ADDRESS;
Jason Molenda380241a2012-07-12 00:20:07 +00003255 }
3256
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003257 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00003258 return llvm::makeArrayRef(g_target_modules_show_unwind_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003259 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003260
3261 // Instance variables to hold the values for command options.
3262
3263 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3264 std::string m_str; // Holds name lookup
3265 lldb::addr_t m_addr; // Holds the address to lookup
3266 };
3267
3268 CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3269 : CommandObjectParsed(
3270 interpreter, "target modules show-unwind",
3271 "Show synthesized unwind instructions for a function.", nullptr,
3272 eCommandRequiresTarget | eCommandRequiresProcess |
3273 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
3274 m_options() {}
3275
3276 ~CommandObjectTargetModulesShowUnwind() override = default;
3277
3278 Options *GetOptions() override { return &m_options; }
3279
Jason Molenda380241a2012-07-12 00:20:07 +00003280protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003281 bool DoExecute(Args &command, CommandReturnObject &result) override {
3282 Target *target = m_exe_ctx.GetTargetPtr();
3283 Process *process = m_exe_ctx.GetProcessPtr();
3284 ABI *abi = nullptr;
3285 if (process)
3286 abi = process->GetABI().get();
Jason Molenda380241a2012-07-12 00:20:07 +00003287
Kate Stoneb9c1b512016-09-06 20:57:50 +00003288 if (process == nullptr) {
3289 result.AppendError(
3290 "You must have a process running to use this command.");
3291 result.SetStatus(eReturnStatusFailed);
3292 return false;
Jason Molenda380241a2012-07-12 00:20:07 +00003293 }
3294
Kate Stoneb9c1b512016-09-06 20:57:50 +00003295 ThreadList threads(process->GetThreadList());
3296 if (threads.GetSize() == 0) {
3297 result.AppendError("The process must be paused to use this command.");
3298 result.SetStatus(eReturnStatusFailed);
3299 return false;
3300 }
3301
3302 ThreadSP thread(threads.GetThreadAtIndex(0));
3303 if (!thread) {
3304 result.AppendError("The process must be paused to use this command.");
3305 result.SetStatus(eReturnStatusFailed);
3306 return false;
3307 }
3308
3309 SymbolContextList sc_list;
3310
3311 if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3312 ConstString function_name(m_options.m_str.c_str());
3313 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3314 true, false, true, sc_list);
3315 } else if (m_options.m_type == eLookupTypeAddress && target) {
3316 Address addr;
3317 if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3318 addr)) {
3319 SymbolContext sc;
3320 ModuleSP module_sp(addr.GetModule());
3321 module_sp->ResolveSymbolContextForAddress(addr,
3322 eSymbolContextEverything, sc);
3323 if (sc.function || sc.symbol) {
3324 sc_list.Append(sc);
3325 }
3326 }
3327 } else {
3328 result.AppendError(
3329 "address-expression or function name option must be specified.");
3330 result.SetStatus(eReturnStatusFailed);
3331 return false;
3332 }
3333
3334 size_t num_matches = sc_list.GetSize();
3335 if (num_matches == 0) {
3336 result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3337 m_options.m_str.c_str());
3338 result.SetStatus(eReturnStatusFailed);
3339 return false;
3340 }
3341
3342 for (uint32_t idx = 0; idx < num_matches; idx++) {
3343 SymbolContext sc;
3344 sc_list.GetContextAtIndex(idx, sc);
3345 if (sc.symbol == nullptr && sc.function == nullptr)
3346 continue;
3347 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3348 continue;
3349 AddressRange range;
3350 if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3351 false, range))
3352 continue;
3353 if (!range.GetBaseAddress().IsValid())
3354 continue;
3355 ConstString funcname(sc.GetFunctionName());
3356 if (funcname.IsEmpty())
3357 continue;
3358 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3359 if (abi)
3360 start_addr = abi->FixCodeAddress(start_addr);
3361
3362 FuncUnwindersSP func_unwinders_sp(
3363 sc.module_sp->GetObjectFile()
3364 ->GetUnwindTable()
3365 .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3366 if (!func_unwinders_sp)
3367 continue;
3368
3369 result.GetOutputStream().Printf(
3370 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
3371 sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3372 funcname.AsCString(), start_addr);
3373
3374 UnwindPlanSP non_callsite_unwind_plan =
3375 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
3376 if (non_callsite_unwind_plan) {
3377 result.GetOutputStream().Printf(
3378 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3379 non_callsite_unwind_plan->GetSourceName().AsCString());
3380 }
3381 UnwindPlanSP callsite_unwind_plan =
3382 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3383 if (callsite_unwind_plan) {
3384 result.GetOutputStream().Printf(
3385 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3386 callsite_unwind_plan->GetSourceName().AsCString());
3387 }
3388 UnwindPlanSP fast_unwind_plan =
3389 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3390 if (fast_unwind_plan) {
3391 result.GetOutputStream().Printf(
3392 "Fast UnwindPlan is '%s'\n",
3393 fast_unwind_plan->GetSourceName().AsCString());
3394 }
3395
3396 result.GetOutputStream().Printf("\n");
3397
3398 UnwindPlanSP assembly_sp =
3399 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
3400 if (assembly_sp) {
3401 result.GetOutputStream().Printf(
3402 "Assembly language inspection UnwindPlan:\n");
3403 assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3404 LLDB_INVALID_ADDRESS);
3405 result.GetOutputStream().Printf("\n");
3406 }
3407
3408 UnwindPlanSP ehframe_sp =
3409 func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3410 if (ehframe_sp) {
3411 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3412 ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3413 LLDB_INVALID_ADDRESS);
3414 result.GetOutputStream().Printf("\n");
3415 }
3416
3417 UnwindPlanSP ehframe_augmented_sp =
3418 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
3419 if (ehframe_augmented_sp) {
3420 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3421 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3422 LLDB_INVALID_ADDRESS);
3423 result.GetOutputStream().Printf("\n");
3424 }
3425
3426 UnwindPlanSP arm_unwind_sp =
3427 func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
3428 if (arm_unwind_sp) {
3429 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3430 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3431 LLDB_INVALID_ADDRESS);
3432 result.GetOutputStream().Printf("\n");
3433 }
3434
3435 UnwindPlanSP compact_unwind_sp =
3436 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3437 if (compact_unwind_sp) {
3438 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3439 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3440 LLDB_INVALID_ADDRESS);
3441 result.GetOutputStream().Printf("\n");
3442 }
3443
3444 if (fast_unwind_plan) {
3445 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3446 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3447 LLDB_INVALID_ADDRESS);
3448 result.GetOutputStream().Printf("\n");
3449 }
3450
3451 ABISP abi_sp = process->GetABI();
3452 if (abi_sp) {
3453 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3454 if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3455 result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3456 arch_default.Dump(result.GetOutputStream(), thread.get(),
3457 LLDB_INVALID_ADDRESS);
3458 result.GetOutputStream().Printf("\n");
3459 }
3460
3461 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3462 if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3463 result.GetOutputStream().Printf(
3464 "Arch default at entry point UnwindPlan:\n");
3465 arch_entry.Dump(result.GetOutputStream(), thread.get(),
3466 LLDB_INVALID_ADDRESS);
3467 result.GetOutputStream().Printf("\n");
3468 }
3469 }
3470
3471 result.GetOutputStream().Printf("\n");
3472 }
3473 return result.Succeeded();
3474 }
3475
3476 CommandOptions m_options;
Jason Molenda380241a2012-07-12 00:20:07 +00003477};
3478
Greg Claytoneffe5c92011-05-03 22:09:39 +00003479//----------------------------------------------------------------------
3480// Lookup information in images
3481//----------------------------------------------------------------------
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003482
3483static OptionDefinition g_target_modules_lookup_options[] = {
3484 // clang-format off
3485 { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." },
3486 { 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." },
3487 /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */
3488 { 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." },
3489 { 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." },
3490 { 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." },
3491 { 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)." },
3492 { 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)." },
3493 { 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." },
3494 { 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." },
3495 { 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." },
3496 { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose lookup information." },
3497 { 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." },
3498 // clang-format on
3499};
3500
Kate Stoneb9c1b512016-09-06 20:57:50 +00003501class CommandObjectTargetModulesLookup : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00003502public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003503 enum {
3504 eLookupTypeInvalid = -1,
3505 eLookupTypeAddress = 0,
3506 eLookupTypeSymbol,
3507 eLookupTypeFileLine, // Line is optional
3508 eLookupTypeFunction,
3509 eLookupTypeFunctionOrSymbol,
3510 eLookupTypeType,
3511 kNumLookupTypes
3512 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003513
Kate Stoneb9c1b512016-09-06 20:57:50 +00003514 class CommandOptions : public Options {
3515 public:
3516 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003517
Kate Stoneb9c1b512016-09-06 20:57:50 +00003518 ~CommandOptions() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003519
Zachary Turnerfe114832016-11-12 16:56:47 +00003520 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
Kate Stoneb9c1b512016-09-06 20:57:50 +00003521 ExecutionContext *execution_context) override {
3522 Error error;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003523
Kate Stoneb9c1b512016-09-06 20:57:50 +00003524 const int short_option = m_getopt_table[option_idx].val;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003525
Kate Stoneb9c1b512016-09-06 20:57:50 +00003526 switch (short_option) {
3527 case 'a': {
3528 m_type = eLookupTypeAddress;
3529 m_addr = Args::StringToAddress(execution_context, option_arg,
3530 LLDB_INVALID_ADDRESS, &error);
3531 } break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003532
Kate Stoneb9c1b512016-09-06 20:57:50 +00003533 case 'o':
Zachary Turnerfe114832016-11-12 16:56:47 +00003534 if (option_arg.getAsInteger(0, m_offset))
Kate Stoneb9c1b512016-09-06 20:57:50 +00003535 error.SetErrorStringWithFormat("invalid offset string '%s'",
Zachary Turnerfe114832016-11-12 16:56:47 +00003536 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003537 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003538
Kate Stoneb9c1b512016-09-06 20:57:50 +00003539 case 's':
3540 m_str = option_arg;
3541 m_type = eLookupTypeSymbol;
3542 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003543
Kate Stoneb9c1b512016-09-06 20:57:50 +00003544 case 'f':
3545 m_file.SetFile(option_arg, false);
3546 m_type = eLookupTypeFileLine;
3547 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003548
Kate Stoneb9c1b512016-09-06 20:57:50 +00003549 case 'i':
3550 m_include_inlines = false;
3551 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003552
Kate Stoneb9c1b512016-09-06 20:57:50 +00003553 case 'l':
Zachary Turnerfe114832016-11-12 16:56:47 +00003554 if (option_arg.getAsInteger(0, m_line_number))
Kate Stoneb9c1b512016-09-06 20:57:50 +00003555 error.SetErrorStringWithFormat("invalid line number string '%s'",
Zachary Turnerfe114832016-11-12 16:56:47 +00003556 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003557 else if (m_line_number == 0)
3558 error.SetErrorString("zero is an invalid line number");
3559 m_type = eLookupTypeFileLine;
3560 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003561
Kate Stoneb9c1b512016-09-06 20:57:50 +00003562 case 'F':
3563 m_str = option_arg;
3564 m_type = eLookupTypeFunction;
3565 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003566
Kate Stoneb9c1b512016-09-06 20:57:50 +00003567 case 'n':
3568 m_str = option_arg;
3569 m_type = eLookupTypeFunctionOrSymbol;
3570 break;
Greg Claytonc4a8a762012-05-15 18:43:44 +00003571
Kate Stoneb9c1b512016-09-06 20:57:50 +00003572 case 't':
3573 m_str = option_arg;
3574 m_type = eLookupTypeType;
3575 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003576
Kate Stoneb9c1b512016-09-06 20:57:50 +00003577 case 'v':
3578 m_verbose = 1;
3579 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003580
Kate Stoneb9c1b512016-09-06 20:57:50 +00003581 case 'A':
3582 m_print_all = true;
3583 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003584
Kate Stoneb9c1b512016-09-06 20:57:50 +00003585 case 'r':
3586 m_use_regex = true;
3587 break;
3588 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003589
Kate Stoneb9c1b512016-09-06 20:57:50 +00003590 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003591 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003592
Kate Stoneb9c1b512016-09-06 20:57:50 +00003593 void OptionParsingStarting(ExecutionContext *execution_context) override {
3594 m_type = eLookupTypeInvalid;
3595 m_str.clear();
3596 m_file.Clear();
3597 m_addr = LLDB_INVALID_ADDRESS;
3598 m_offset = 0;
3599 m_line_number = 0;
3600 m_use_regex = false;
3601 m_include_inlines = true;
3602 m_verbose = false;
3603 m_print_all = false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003604 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003605
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003606 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00003607 return llvm::makeArrayRef(g_target_modules_lookup_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003608 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003609
Kate Stoneb9c1b512016-09-06 20:57:50 +00003610 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3611 std::string m_str; // Holds name lookup
3612 FileSpec m_file; // Files for file lookups
3613 lldb::addr_t m_addr; // Holds the address to lookup
3614 lldb::addr_t
3615 m_offset; // Subtract this offset from m_addr before doing lookups.
3616 uint32_t m_line_number; // Line number for file+line lookups
3617 bool m_use_regex; // Name lookups in m_str are regular expressions.
3618 bool m_include_inlines; // Check for inline entries when looking up by
3619 // file/line.
3620 bool m_verbose; // Enable verbose lookup info
3621 bool m_print_all; // Print all matches, even in cases where there's a best
3622 // match.
3623 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003624
Kate Stoneb9c1b512016-09-06 20:57:50 +00003625 CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3626 : CommandObjectParsed(interpreter, "target modules lookup",
3627 "Look up information within executable and "
3628 "dependent shared library images.",
3629 nullptr, eCommandRequiresTarget),
3630 m_options() {
3631 CommandArgumentEntry arg;
3632 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003633
Kate Stoneb9c1b512016-09-06 20:57:50 +00003634 // Define the first (and only) variant of this arg.
3635 file_arg.arg_type = eArgTypeFilename;
3636 file_arg.arg_repetition = eArgRepeatStar;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003637
Kate Stoneb9c1b512016-09-06 20:57:50 +00003638 // There is only one variant this argument could be; put it into the
3639 // argument entry.
3640 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003641
Kate Stoneb9c1b512016-09-06 20:57:50 +00003642 // Push the data for the first argument into the m_arguments vector.
3643 m_arguments.push_back(arg);
3644 }
3645
3646 ~CommandObjectTargetModulesLookup() override = default;
3647
3648 Options *GetOptions() override { return &m_options; }
3649
3650 bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3651 bool &syntax_error) {
3652 switch (m_options.m_type) {
3653 case eLookupTypeAddress:
3654 case eLookupTypeFileLine:
3655 case eLookupTypeFunction:
3656 case eLookupTypeFunctionOrSymbol:
3657 case eLookupTypeSymbol:
3658 default:
3659 return false;
3660 case eLookupTypeType:
3661 break;
Sean Callanand38b4a92012-06-06 20:49:55 +00003662 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003663
Kate Stoneb9c1b512016-09-06 20:57:50 +00003664 StackFrameSP frame = m_exe_ctx.GetFrameSP();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003665
Kate Stoneb9c1b512016-09-06 20:57:50 +00003666 if (!frame)
3667 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003668
Kate Stoneb9c1b512016-09-06 20:57:50 +00003669 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
Greg Claytonc4a8a762012-05-15 18:43:44 +00003670
Kate Stoneb9c1b512016-09-06 20:57:50 +00003671 if (!sym_ctx.module_sp)
3672 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003673
Kate Stoneb9c1b512016-09-06 20:57:50 +00003674 switch (m_options.m_type) {
3675 default:
3676 return false;
3677 case eLookupTypeType:
3678 if (!m_options.m_str.empty()) {
3679 if (LookupTypeHere(m_interpreter, result.GetOutputStream(), sym_ctx,
3680 m_options.m_str.c_str(), m_options.m_use_regex)) {
3681 result.SetStatus(eReturnStatusSuccessFinishResult);
3682 return true;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003683 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003684 }
3685 break;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003686 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003687
Kate Stoneb9c1b512016-09-06 20:57:50 +00003688 return true;
3689 }
3690
3691 bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3692 CommandReturnObject &result, bool &syntax_error) {
3693 switch (m_options.m_type) {
3694 case eLookupTypeAddress:
3695 if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3696 if (LookupAddressInModule(
3697 m_interpreter, result.GetOutputStream(), module,
3698 eSymbolContextEverything |
3699 (m_options.m_verbose
3700 ? static_cast<int>(eSymbolContextVariable)
3701 : 0),
3702 m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
3703 result.SetStatus(eReturnStatusSuccessFinishResult);
3704 return true;
3705 }
3706 }
3707 break;
3708
3709 case eLookupTypeSymbol:
3710 if (!m_options.m_str.empty()) {
3711 if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3712 module, m_options.m_str.c_str(),
3713 m_options.m_use_regex, m_options.m_verbose)) {
3714 result.SetStatus(eReturnStatusSuccessFinishResult);
3715 return true;
3716 }
3717 }
3718 break;
3719
3720 case eLookupTypeFileLine:
3721 if (m_options.m_file) {
3722 if (LookupFileAndLineInModule(
3723 m_interpreter, result.GetOutputStream(), module,
3724 m_options.m_file, m_options.m_line_number,
3725 m_options.m_include_inlines, m_options.m_verbose)) {
3726 result.SetStatus(eReturnStatusSuccessFinishResult);
3727 return true;
3728 }
3729 }
3730 break;
3731
3732 case eLookupTypeFunctionOrSymbol:
3733 case eLookupTypeFunction:
3734 if (!m_options.m_str.empty()) {
3735 if (LookupFunctionInModule(
3736 m_interpreter, result.GetOutputStream(), module,
3737 m_options.m_str.c_str(), m_options.m_use_regex,
3738 m_options.m_include_inlines,
3739 m_options.m_type ==
3740 eLookupTypeFunctionOrSymbol, // include symbols
3741 m_options.m_verbose)) {
3742 result.SetStatus(eReturnStatusSuccessFinishResult);
3743 return true;
3744 }
3745 }
3746 break;
3747
3748 case eLookupTypeType:
3749 if (!m_options.m_str.empty()) {
3750 if (LookupTypeInModule(m_interpreter, result.GetOutputStream(), module,
3751 m_options.m_str.c_str(),
3752 m_options.m_use_regex)) {
3753 result.SetStatus(eReturnStatusSuccessFinishResult);
3754 return true;
3755 }
3756 }
3757 break;
3758
3759 default:
3760 m_options.GenerateOptionUsage(
3761 result.GetErrorStream(), this,
3762 GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3763 syntax_error = true;
3764 break;
3765 }
3766
3767 result.SetStatus(eReturnStatusFailed);
3768 return false;
3769 }
3770
Jim Ingham5a988412012-06-08 21:56:10 +00003771protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003772 bool DoExecute(Args &command, CommandReturnObject &result) override {
3773 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3774 if (target == nullptr) {
3775 result.AppendError("invalid target, create a debug target using the "
3776 "'target create' command");
3777 result.SetStatus(eReturnStatusFailed);
3778 return false;
3779 } else {
3780 bool syntax_error = false;
3781 uint32_t i;
3782 uint32_t num_successful_lookups = 0;
3783 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3784 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3785 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3786 // Dump all sections for all modules images
3787
3788 if (command.GetArgumentCount() == 0) {
3789 ModuleSP current_module;
3790
3791 // Where it is possible to look in the current symbol context
3792 // first, try that. If this search was successful and --all
3793 // was not passed, don't print anything else.
3794 if (LookupHere(m_interpreter, result, syntax_error)) {
3795 result.GetOutputStream().EOL();
3796 num_successful_lookups++;
3797 if (!m_options.m_print_all) {
3798 result.SetStatus(eReturnStatusSuccessFinishResult);
3799 return result.Succeeded();
3800 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00003801 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003802
Kate Stoneb9c1b512016-09-06 20:57:50 +00003803 // Dump all sections for all other modules
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003804
Kate Stoneb9c1b512016-09-06 20:57:50 +00003805 const ModuleList &target_modules = target->GetImages();
3806 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3807 const size_t num_modules = target_modules.GetSize();
3808 if (num_modules > 0) {
3809 for (i = 0; i < num_modules && !syntax_error; ++i) {
3810 Module *module_pointer =
3811 target_modules.GetModulePointerAtIndexUnlocked(i);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003812
Kate Stoneb9c1b512016-09-06 20:57:50 +00003813 if (module_pointer != current_module.get() &&
3814 LookupInModule(
3815 m_interpreter,
3816 target_modules.GetModulePointerAtIndexUnlocked(i), result,
3817 syntax_error)) {
3818 result.GetOutputStream().EOL();
3819 num_successful_lookups++;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003820 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003821 }
3822 } else {
3823 result.AppendError("the target has no associated executable images");
3824 result.SetStatus(eReturnStatusFailed);
3825 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003826 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003827 } else {
3828 // Dump specified images (by basename or fullpath)
3829 const char *arg_cstr;
3830 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3831 !syntax_error;
3832 ++i) {
3833 ModuleList module_list;
3834 const size_t num_matches =
3835 FindModulesByName(target, arg_cstr, module_list, false);
3836 if (num_matches > 0) {
3837 for (size_t j = 0; j < num_matches; ++j) {
3838 Module *module = module_list.GetModulePointerAtIndex(j);
3839 if (module) {
3840 if (LookupInModule(m_interpreter, module, result,
3841 syntax_error)) {
3842 result.GetOutputStream().EOL();
3843 num_successful_lookups++;
3844 }
3845 }
3846 }
3847 } else
3848 result.AppendWarningWithFormat(
3849 "Unable to find an image that matches '%s'.\n", arg_cstr);
3850 }
3851 }
3852
3853 if (num_successful_lookups > 0)
3854 result.SetStatus(eReturnStatusSuccessFinishResult);
3855 else
3856 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00003857 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003858 return result.Succeeded();
3859 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003860
Kate Stoneb9c1b512016-09-06 20:57:50 +00003861 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003862};
3863
Jim Ingham9575d842011-03-11 03:53:59 +00003864#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003865
3866//-------------------------------------------------------------------------
3867// CommandObjectMultiwordImageSearchPaths
3868//-------------------------------------------------------------------------
3869
Kate Stoneb9c1b512016-09-06 20:57:50 +00003870class CommandObjectTargetModulesImageSearchPaths
3871 : public CommandObjectMultiword {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003872public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003873 CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
3874 : CommandObjectMultiword(
3875 interpreter, "target modules search-paths",
3876 "Commands for managing module search paths for a target.",
3877 "target modules search-paths <subcommand> [<subcommand-options>]") {
3878 LoadSubCommand(
3879 "add", CommandObjectSP(
3880 new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
3881 LoadSubCommand(
3882 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
3883 interpreter)));
3884 LoadSubCommand(
3885 "insert",
3886 CommandObjectSP(
3887 new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
3888 LoadSubCommand(
3889 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
3890 interpreter)));
3891 LoadSubCommand(
3892 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
3893 interpreter)));
3894 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003895
Kate Stoneb9c1b512016-09-06 20:57:50 +00003896 ~CommandObjectTargetModulesImageSearchPaths() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003897};
3898
Greg Claytoneffe5c92011-05-03 22:09:39 +00003899#pragma mark CommandObjectTargetModules
3900
3901//-------------------------------------------------------------------------
3902// CommandObjectTargetModules
3903//-------------------------------------------------------------------------
3904
Kate Stoneb9c1b512016-09-06 20:57:50 +00003905class CommandObjectTargetModules : public CommandObjectMultiword {
Greg Claytoneffe5c92011-05-03 22:09:39 +00003906public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003907 //------------------------------------------------------------------
3908 // Constructors and Destructors
3909 //------------------------------------------------------------------
3910 CommandObjectTargetModules(CommandInterpreter &interpreter)
3911 : CommandObjectMultiword(interpreter, "target modules",
3912 "Commands for accessing information for one or "
3913 "more target modules.",
3914 "target modules <sub-command> ...") {
3915 LoadSubCommand(
3916 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
3917 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
3918 interpreter)));
3919 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
3920 interpreter)));
3921 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
3922 interpreter)));
3923 LoadSubCommand(
3924 "lookup",
3925 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
3926 LoadSubCommand(
3927 "search-paths",
3928 CommandObjectSP(
3929 new CommandObjectTargetModulesImageSearchPaths(interpreter)));
3930 LoadSubCommand(
3931 "show-unwind",
3932 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
3933 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00003934
Kate Stoneb9c1b512016-09-06 20:57:50 +00003935 ~CommandObjectTargetModules() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003936
Greg Claytoneffe5c92011-05-03 22:09:39 +00003937private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003938 //------------------------------------------------------------------
3939 // For CommandObjectTargetModules only
3940 //------------------------------------------------------------------
3941 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules);
Greg Claytoneffe5c92011-05-03 22:09:39 +00003942};
3943
Kate Stoneb9c1b512016-09-06 20:57:50 +00003944class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
Greg Claytone72dfb32012-02-24 01:59:29 +00003945public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003946 CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
3947 : CommandObjectParsed(
3948 interpreter, "target symbols add",
3949 "Add a debug symbol file to one of the target's current modules by "
3950 "specifying a path to a debug symbols file, or using the options "
3951 "to specify a module to download symbols for.",
3952 "target symbols add [<symfile>]", eCommandRequiresTarget),
Todd Fialae1cfbc72016-08-11 23:51:28 +00003953 m_option_group(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00003954 m_file_option(
3955 LLDB_OPT_SET_1, false, "shlib", 's',
3956 CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3957 "Fullpath or basename for module to find debug symbols for."),
3958 m_current_frame_option(
3959 LLDB_OPT_SET_2, false, "frame", 'F',
3960 "Locate the debug symbols the currently selected frame.", false,
3961 true)
Greg Claytonb5f0fea2012-09-27 22:26:11 +00003962
Kate Stoneb9c1b512016-09-06 20:57:50 +00003963 {
3964 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
3965 LLDB_OPT_SET_1);
3966 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
3967 m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
3968 LLDB_OPT_SET_2);
3969 m_option_group.Finalize();
3970 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003971
Kate Stoneb9c1b512016-09-06 20:57:50 +00003972 ~CommandObjectTargetSymbolsAdd() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003973
Kate Stoneb9c1b512016-09-06 20:57:50 +00003974 int HandleArgumentCompletion(Args &input, int &cursor_index,
3975 int &cursor_char_position,
3976 OptionElementVector &opt_element_vector,
3977 int match_start_point, int max_return_elements,
3978 bool &word_complete,
3979 StringList &matches) override {
3980 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
3981 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003982
Kate Stoneb9c1b512016-09-06 20:57:50 +00003983 CommandCompletions::InvokeCommonCompletionCallbacks(
3984 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
3985 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
3986 word_complete, matches);
3987 return matches.GetSize();
3988 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003989
Kate Stoneb9c1b512016-09-06 20:57:50 +00003990 Options *GetOptions() override { return &m_option_group; }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00003991
Jim Ingham5a988412012-06-08 21:56:10 +00003992protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003993 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
3994 CommandReturnObject &result) {
3995 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
3996 if (symbol_fspec) {
3997 char symfile_path[PATH_MAX];
3998 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003999
Kate Stoneb9c1b512016-09-06 20:57:50 +00004000 if (!module_spec.GetUUID().IsValid()) {
4001 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4002 module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4003 }
4004 // We now have a module that represents a symbol file
4005 // that can be used for a module that might exist in the
4006 // current target, so we need to find that module in the
4007 // target
4008 ModuleList matching_module_list;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004009
Kate Stoneb9c1b512016-09-06 20:57:50 +00004010 size_t num_matches = 0;
4011 // First extract all module specs from the symbol file
4012 lldb_private::ModuleSpecList symfile_module_specs;
4013 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
4014 0, 0, symfile_module_specs)) {
4015 // Now extract the module spec that matches the target architecture
4016 ModuleSpec target_arch_module_spec;
4017 ModuleSpec symfile_module_spec;
4018 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4019 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4020 symfile_module_spec)) {
4021 // See if it has a UUID?
4022 if (symfile_module_spec.GetUUID().IsValid()) {
4023 // It has a UUID, look for this UUID in the target modules
4024 ModuleSpec symfile_uuid_module_spec;
4025 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4026 num_matches = target->GetImages().FindModules(
4027 symfile_uuid_module_spec, matching_module_list);
4028 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00004029 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004030
4031 if (num_matches == 0) {
4032 // No matches yet, iterate through the module specs to find a UUID
4033 // value that
4034 // we can match up to an image in our target
4035 const size_t num_symfile_module_specs =
4036 symfile_module_specs.GetSize();
4037 for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0;
4038 ++i) {
4039 if (symfile_module_specs.GetModuleSpecAtIndex(
4040 i, symfile_module_spec)) {
4041 if (symfile_module_spec.GetUUID().IsValid()) {
4042 // It has a UUID, look for this UUID in the target modules
4043 ModuleSpec symfile_uuid_module_spec;
4044 symfile_uuid_module_spec.GetUUID() =
4045 symfile_module_spec.GetUUID();
4046 num_matches = target->GetImages().FindModules(
4047 symfile_uuid_module_spec, matching_module_list);
4048 }
4049 }
4050 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00004051 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004052 }
4053
4054 // Just try to match up the file by basename if we have no matches at this
4055 // point
4056 if (num_matches == 0)
4057 num_matches =
4058 target->GetImages().FindModules(module_spec, matching_module_list);
4059
4060 while (num_matches == 0) {
4061 ConstString filename_no_extension(
4062 module_spec.GetFileSpec().GetFileNameStrippingExtension());
4063 // Empty string returned, lets bail
4064 if (!filename_no_extension)
4065 break;
4066
4067 // Check if there was no extension to strip and the basename is the same
4068 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4069 break;
4070
4071 // Replace basename with one less extension
4072 module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4073
4074 num_matches =
4075 target->GetImages().FindModules(module_spec, matching_module_list);
4076 }
4077
4078 if (num_matches > 1) {
4079 result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4080 "use the --uuid option to resolve the "
4081 "ambiguity.\n",
4082 symfile_path);
4083 } else if (num_matches == 1) {
4084 ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0));
4085
4086 // The module has not yet created its symbol vendor, we can just
4087 // give the existing target module the symfile path to use for
4088 // when it decides to create it!
4089 module_sp->SetSymbolFileFileSpec(symbol_fspec);
4090
4091 SymbolVendor *symbol_vendor =
4092 module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4093 if (symbol_vendor) {
4094 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4095
4096 if (symbol_file) {
4097 ObjectFile *object_file = symbol_file->GetObjectFile();
4098
4099 if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4100 // Provide feedback that the symfile has been successfully added.
4101 const FileSpec &module_fs = module_sp->GetFileSpec();
4102 result.AppendMessageWithFormat(
4103 "symbol file '%s' has been added to '%s'\n", symfile_path,
4104 module_fs.GetPath().c_str());
4105
4106 // Let clients know something changed in the module
4107 // if it is currently loaded
4108 ModuleList module_list;
4109 module_list.Append(module_sp);
4110 target->SymbolsDidLoad(module_list);
4111
4112 // Make sure we load any scripting resources that may be embedded
4113 // in the debug info files in case the platform supports that.
4114 Error error;
4115 StreamString feedback_stream;
4116 module_sp->LoadScriptingResourceInTarget(target, error,
4117 &feedback_stream);
4118 if (error.Fail() && error.AsCString())
4119 result.AppendWarningWithFormat(
4120 "unable to load scripting data for module %s - error "
4121 "reported was %s",
4122 module_sp->GetFileSpec()
4123 .GetFileNameStrippingExtension()
4124 .GetCString(),
4125 error.AsCString());
4126 else if (feedback_stream.GetSize())
4127 result.AppendWarningWithFormat("%s", feedback_stream.GetData());
4128
4129 flush = true;
4130 result.SetStatus(eReturnStatusSuccessFinishResult);
4131 return true;
4132 }
4133 }
4134 }
4135 // Clear the symbol file spec if anything went wrong
4136 module_sp->SetSymbolFileFileSpec(FileSpec());
4137 }
4138
4139 if (module_spec.GetUUID().IsValid()) {
4140 StreamString ss_symfile_uuid;
4141 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4142 result.AppendErrorWithFormat(
4143 "symbol file '%s' (%s) does not match any existing module%s\n",
4144 symfile_path, ss_symfile_uuid.GetData(),
Pavel Labath30e6cbf2017-03-07 13:19:15 +00004145 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
Kate Stoneb9c1b512016-09-06 20:57:50 +00004146 ? "\n please specify the full path to the symbol file"
4147 : "");
4148 } else {
4149 result.AppendErrorWithFormat(
4150 "symbol file '%s' does not match any existing module%s\n",
4151 symfile_path,
Pavel Labath30e6cbf2017-03-07 13:19:15 +00004152 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
Kate Stoneb9c1b512016-09-06 20:57:50 +00004153 ? "\n please specify the full path to the symbol file"
4154 : "");
4155 }
4156 } else {
4157 result.AppendError(
4158 "one or more executable image paths must be specified");
4159 }
4160 result.SetStatus(eReturnStatusFailed);
4161 return false;
4162 }
4163
4164 bool DoExecute(Args &args, CommandReturnObject &result) override {
4165 Target *target = m_exe_ctx.GetTargetPtr();
4166 result.SetStatus(eReturnStatusFailed);
4167 bool flush = false;
4168 ModuleSpec module_spec;
4169 const bool uuid_option_set =
4170 m_uuid_option_group.GetOptionValue().OptionWasSet();
4171 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4172 const bool frame_option_set =
4173 m_current_frame_option.GetOptionValue().OptionWasSet();
4174 const size_t argc = args.GetArgumentCount();
4175
4176 if (argc == 0) {
4177 if (uuid_option_set || file_option_set || frame_option_set) {
4178 bool success = false;
4179 bool error_set = false;
4180 if (frame_option_set) {
4181 Process *process = m_exe_ctx.GetProcessPtr();
4182 if (process) {
4183 const StateType process_state = process->GetState();
4184 if (StateIsStoppedState(process_state, true)) {
4185 StackFrame *frame = m_exe_ctx.GetFramePtr();
4186 if (frame) {
4187 ModuleSP frame_module_sp(
4188 frame->GetSymbolContext(eSymbolContextModule).module_sp);
4189 if (frame_module_sp) {
4190 if (frame_module_sp->GetPlatformFileSpec().Exists()) {
4191 module_spec.GetArchitecture() =
4192 frame_module_sp->GetArchitecture();
4193 module_spec.GetFileSpec() =
4194 frame_module_sp->GetPlatformFileSpec();
4195 }
4196 module_spec.GetUUID() = frame_module_sp->GetUUID();
4197 success = module_spec.GetUUID().IsValid() ||
4198 module_spec.GetFileSpec();
4199 } else {
4200 result.AppendError("frame has no module");
4201 error_set = true;
4202 }
4203 } else {
4204 result.AppendError("invalid current frame");
4205 error_set = true;
4206 }
4207 } else {
4208 result.AppendErrorWithFormat("process is not stopped: %s",
4209 StateAsCString(process_state));
4210 error_set = true;
4211 }
4212 } else {
4213 result.AppendError(
4214 "a process must exist in order to use the --frame option");
4215 error_set = true;
4216 }
4217 } else {
4218 if (uuid_option_set) {
4219 module_spec.GetUUID() =
4220 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4221 success |= module_spec.GetUUID().IsValid();
4222 } else if (file_option_set) {
4223 module_spec.GetFileSpec() =
4224 m_file_option.GetOptionValue().GetCurrentValue();
4225 ModuleSP module_sp(
4226 target->GetImages().FindFirstModule(module_spec));
4227 if (module_sp) {
4228 module_spec.GetFileSpec() = module_sp->GetFileSpec();
4229 module_spec.GetPlatformFileSpec() =
4230 module_sp->GetPlatformFileSpec();
4231 module_spec.GetUUID() = module_sp->GetUUID();
4232 module_spec.GetArchitecture() = module_sp->GetArchitecture();
4233 } else {
4234 module_spec.GetArchitecture() = target->GetArchitecture();
4235 }
4236 success |= module_spec.GetUUID().IsValid() ||
4237 module_spec.GetFileSpec().Exists();
4238 }
4239 }
4240
4241 if (success) {
4242 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4243 if (module_spec.GetSymbolFileSpec())
4244 success = AddModuleSymbols(target, module_spec, flush, result);
4245 }
4246 }
4247
4248 if (!success && !error_set) {
4249 StreamString error_strm;
4250 if (uuid_option_set) {
4251 error_strm.PutCString("unable to find debug symbols for UUID ");
4252 module_spec.GetUUID().Dump(&error_strm);
4253 } else if (file_option_set) {
4254 error_strm.PutCString(
4255 "unable to find debug symbols for the executable file ");
4256 error_strm << module_spec.GetFileSpec();
4257 } else if (frame_option_set) {
4258 error_strm.PutCString(
4259 "unable to find debug symbols for the current frame");
4260 }
Zachary Turnerc1564272016-11-16 21:15:24 +00004261 result.AppendError(error_strm.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004262 }
4263 } else {
4264 result.AppendError("one or more symbol file paths must be specified, "
4265 "or options must be specified");
4266 }
4267 } else {
4268 if (uuid_option_set) {
4269 result.AppendError("specify either one or more paths to symbol files "
4270 "or use the --uuid option without arguments");
4271 } else if (file_option_set) {
4272 result.AppendError("specify either one or more paths to symbol files "
4273 "or use the --file option without arguments");
4274 } else if (frame_option_set) {
4275 result.AppendError("specify either one or more paths to symbol files "
4276 "or use the --frame option without arguments");
4277 } else {
4278 PlatformSP platform_sp(target->GetPlatform());
4279
Zachary Turner97d2c402016-10-05 23:40:23 +00004280 for (auto &entry : args.entries()) {
4281 if (!entry.ref.empty()) {
4282 module_spec.GetSymbolFileSpec().SetFile(entry.ref, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004283 if (platform_sp) {
4284 FileSpec symfile_spec;
4285 if (platform_sp
4286 ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4287 .Success())
4288 module_spec.GetSymbolFileSpec() = symfile_spec;
4289 }
4290
4291 ArchSpec arch;
4292 bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
4293
4294 if (symfile_exists) {
4295 if (!AddModuleSymbols(target, module_spec, flush, result))
4296 break;
4297 } else {
Zachary Turner97d2c402016-10-05 23:40:23 +00004298 std::string resolved_symfile_path =
4299 module_spec.GetSymbolFileSpec().GetPath();
4300 if (resolved_symfile_path != entry.ref) {
4301 result.AppendErrorWithFormat(
4302 "invalid module path '%s' with resolved path '%s'\n",
4303 entry.c_str(), resolved_symfile_path.c_str());
4304 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004305 }
4306 result.AppendErrorWithFormat("invalid module path '%s'\n",
Zachary Turner97d2c402016-10-05 23:40:23 +00004307 entry.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004308 break;
4309 }
4310 }
4311 }
4312 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00004313 }
4314
Kate Stoneb9c1b512016-09-06 20:57:50 +00004315 if (flush) {
4316 Process *process = m_exe_ctx.GetProcessPtr();
4317 if (process)
4318 process->Flush();
Greg Claytone72dfb32012-02-24 01:59:29 +00004319 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004320 return result.Succeeded();
4321 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004322
Kate Stoneb9c1b512016-09-06 20:57:50 +00004323 OptionGroupOptions m_option_group;
4324 OptionGroupUUID m_uuid_option_group;
4325 OptionGroupFile m_file_option;
4326 OptionGroupBoolean m_current_frame_option;
Greg Claytone72dfb32012-02-24 01:59:29 +00004327};
4328
Greg Claytone72dfb32012-02-24 01:59:29 +00004329#pragma mark CommandObjectTargetSymbols
4330
4331//-------------------------------------------------------------------------
4332// CommandObjectTargetSymbols
4333//-------------------------------------------------------------------------
4334
Kate Stoneb9c1b512016-09-06 20:57:50 +00004335class CommandObjectTargetSymbols : public CommandObjectMultiword {
Greg Claytone72dfb32012-02-24 01:59:29 +00004336public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004337 //------------------------------------------------------------------
4338 // Constructors and Destructors
4339 //------------------------------------------------------------------
4340 CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4341 : CommandObjectMultiword(
4342 interpreter, "target symbols",
4343 "Commands for adding and managing debug symbol files.",
4344 "target symbols <sub-command> ...") {
4345 LoadSubCommand(
4346 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4347 }
Bruce Mitchener13d21e92015-10-07 16:56:17 +00004348
Kate Stoneb9c1b512016-09-06 20:57:50 +00004349 ~CommandObjectTargetSymbols() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004350
Greg Claytone72dfb32012-02-24 01:59:29 +00004351private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004352 //------------------------------------------------------------------
4353 // For CommandObjectTargetModules only
4354 //------------------------------------------------------------------
4355 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols);
Greg Claytone72dfb32012-02-24 01:59:29 +00004356};
4357
Jim Ingham9575d842011-03-11 03:53:59 +00004358#pragma mark CommandObjectTargetStopHookAdd
4359
4360//-------------------------------------------------------------------------
4361// CommandObjectTargetStopHookAdd
4362//-------------------------------------------------------------------------
4363
Zachary Turner1f0f5b52016-09-22 20:22:55 +00004364static OptionDefinition g_target_stop_hook_add_options[] = {
4365 // clang-format off
4366 { 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." },
4367 { 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." },
4368 { 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." },
4369 { 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." },
4370 { 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." },
4371 { 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." },
4372 { 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." },
4373 { 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." },
4374 { 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." },
4375 { 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." },
4376 { 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." },
4377 // clang-format on
4378};
4379
Kate Stoneb9c1b512016-09-06 20:57:50 +00004380class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4381 public IOHandlerDelegateMultiline {
Jim Ingham9575d842011-03-11 03:53:59 +00004382public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004383 class CommandOptions : public Options {
4384 public:
4385 CommandOptions()
4386 : Options(), m_line_start(0), m_line_end(UINT_MAX),
4387 m_func_name_type_mask(eFunctionNameTypeAuto),
4388 m_sym_ctx_specified(false), m_thread_specified(false),
4389 m_use_one_liner(false), m_one_liner() {}
4390
4391 ~CommandOptions() override = default;
4392
Zachary Turner1f0f5b52016-09-22 20:22:55 +00004393 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00004394 return llvm::makeArrayRef(g_target_stop_hook_add_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00004395 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004396
Zachary Turnerfe114832016-11-12 16:56:47 +00004397 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
Kate Stoneb9c1b512016-09-06 20:57:50 +00004398 ExecutionContext *execution_context) override {
4399 Error error;
4400 const int short_option = m_getopt_table[option_idx].val;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004401
4402 switch (short_option) {
4403 case 'c':
4404 m_class_name = option_arg;
4405 m_sym_ctx_specified = true;
4406 break;
4407
4408 case 'e':
Zachary Turnerfe114832016-11-12 16:56:47 +00004409 if (option_arg.getAsInteger(0, m_line_end)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00004410 error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
Zachary Turnerfe114832016-11-12 16:56:47 +00004411 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004412 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004413 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004414 m_sym_ctx_specified = true;
4415 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004416
Kate Stoneb9c1b512016-09-06 20:57:50 +00004417 case 'l':
Zachary Turnerfe114832016-11-12 16:56:47 +00004418 if (option_arg.getAsInteger(0, m_line_start)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00004419 error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
Zachary Turnerfe114832016-11-12 16:56:47 +00004420 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004421 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004422 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004423 m_sym_ctx_specified = true;
4424 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004425
Kate Stoneb9c1b512016-09-06 20:57:50 +00004426 case 'i':
4427 m_no_inlines = true;
4428 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004429
Kate Stoneb9c1b512016-09-06 20:57:50 +00004430 case 'n':
4431 m_function_name = option_arg;
4432 m_func_name_type_mask |= eFunctionNameTypeAuto;
4433 m_sym_ctx_specified = true;
4434 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004435
Kate Stoneb9c1b512016-09-06 20:57:50 +00004436 case 'f':
4437 m_file_name = option_arg;
4438 m_sym_ctx_specified = true;
4439 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004440
Kate Stoneb9c1b512016-09-06 20:57:50 +00004441 case 's':
4442 m_module_name = option_arg;
4443 m_sym_ctx_specified = true;
4444 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004445
Kate Stoneb9c1b512016-09-06 20:57:50 +00004446 case 't':
Zachary Turnerfe114832016-11-12 16:56:47 +00004447 if (option_arg.getAsInteger(0, m_thread_id))
Kate Stoneb9c1b512016-09-06 20:57:50 +00004448 error.SetErrorStringWithFormat("invalid thread id string '%s'",
Zachary Turnerfe114832016-11-12 16:56:47 +00004449 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004450 m_thread_specified = true;
4451 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004452
Kate Stoneb9c1b512016-09-06 20:57:50 +00004453 case 'T':
4454 m_thread_name = option_arg;
4455 m_thread_specified = true;
4456 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004457
Kate Stoneb9c1b512016-09-06 20:57:50 +00004458 case 'q':
4459 m_queue_name = option_arg;
4460 m_thread_specified = true;
4461 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004462
Kate Stoneb9c1b512016-09-06 20:57:50 +00004463 case 'x':
Zachary Turnerfe114832016-11-12 16:56:47 +00004464 if (option_arg.getAsInteger(0, m_thread_index))
Kate Stoneb9c1b512016-09-06 20:57:50 +00004465 error.SetErrorStringWithFormat("invalid thread index string '%s'",
Zachary Turnerfe114832016-11-12 16:56:47 +00004466 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004467 m_thread_specified = true;
4468 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004469
Kate Stoneb9c1b512016-09-06 20:57:50 +00004470 case 'o':
4471 m_use_one_liner = true;
4472 m_one_liner = option_arg;
4473 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004474
Kate Stoneb9c1b512016-09-06 20:57:50 +00004475 default:
4476 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
4477 break;
4478 }
4479 return error;
Jim Ingham9575d842011-03-11 03:53:59 +00004480 }
4481
Kate Stoneb9c1b512016-09-06 20:57:50 +00004482 void OptionParsingStarting(ExecutionContext *execution_context) override {
4483 m_class_name.clear();
4484 m_function_name.clear();
4485 m_line_start = 0;
4486 m_line_end = UINT_MAX;
4487 m_file_name.clear();
4488 m_module_name.clear();
4489 m_func_name_type_mask = eFunctionNameTypeAuto;
4490 m_thread_id = LLDB_INVALID_THREAD_ID;
4491 m_thread_index = UINT32_MAX;
4492 m_thread_name.clear();
4493 m_queue_name.clear();
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004494
Kate Stoneb9c1b512016-09-06 20:57:50 +00004495 m_no_inlines = false;
4496 m_sym_ctx_specified = false;
4497 m_thread_specified = false;
4498
4499 m_use_one_liner = false;
4500 m_one_liner.clear();
Jim Ingham9575d842011-03-11 03:53:59 +00004501 }
4502
Kate Stoneb9c1b512016-09-06 20:57:50 +00004503 std::string m_class_name;
4504 std::string m_function_name;
4505 uint32_t m_line_start;
4506 uint32_t m_line_end;
4507 std::string m_file_name;
4508 std::string m_module_name;
4509 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
4510 lldb::tid_t m_thread_id;
4511 uint32_t m_thread_index;
4512 std::string m_thread_name;
4513 std::string m_queue_name;
4514 bool m_sym_ctx_specified;
4515 bool m_no_inlines;
4516 bool m_thread_specified;
4517 // Instance variables to hold the values for one_liner options.
4518 bool m_use_one_liner;
4519 std::string m_one_liner;
4520 };
4521
4522 CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4523 : CommandObjectParsed(interpreter, "target stop-hook add",
4524 "Add a hook to be executed when the target stops.",
4525 "target stop-hook add"),
4526 IOHandlerDelegateMultiline("DONE",
4527 IOHandlerDelegate::Completion::LLDBCommand),
4528 m_options() {}
4529
4530 ~CommandObjectTargetStopHookAdd() override = default;
4531
4532 Options *GetOptions() override { return &m_options; }
4533
Jim Ingham5a988412012-06-08 21:56:10 +00004534protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004535 void IOHandlerActivated(IOHandler &io_handler) override {
4536 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4537 if (output_sp) {
4538 output_sp->PutCString(
4539 "Enter your stop hook command(s). Type 'DONE' to end.\n");
4540 output_sp->Flush();
Greg Clayton44d93782014-01-27 23:43:24 +00004541 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004542 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004543
Kate Stoneb9c1b512016-09-06 20:57:50 +00004544 void IOHandlerInputComplete(IOHandler &io_handler,
4545 std::string &line) override {
4546 if (m_stop_hook_sp) {
4547 if (line.empty()) {
4548 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
4549 if (error_sp) {
4550 error_sp->Printf("error: stop hook #%" PRIu64
4551 " aborted, no commands.\n",
4552 m_stop_hook_sp->GetID());
4553 error_sp->Flush();
Greg Clayton44d93782014-01-27 23:43:24 +00004554 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004555 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Jim Ingham9575d842011-03-11 03:53:59 +00004556 if (target)
Kate Stoneb9c1b512016-09-06 20:57:50 +00004557 target->RemoveStopHookByID(m_stop_hook_sp->GetID());
4558 } else {
4559 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
4560 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4561 if (output_sp) {
4562 output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4563 m_stop_hook_sp->GetID());
4564 output_sp->Flush();
Jim Ingham9575d842011-03-11 03:53:59 +00004565 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004566 }
4567 m_stop_hook_sp.reset();
Jim Ingham9575d842011-03-11 03:53:59 +00004568 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004569 io_handler.SetIsDone(true);
4570 }
4571
4572 bool DoExecute(Args &command, CommandReturnObject &result) override {
4573 m_stop_hook_sp.reset();
4574
4575 Target *target = GetSelectedOrDummyTarget();
4576 if (target) {
4577 Target::StopHookSP new_hook_sp = target->CreateStopHook();
4578
4579 // First step, make the specifier.
4580 std::unique_ptr<SymbolContextSpecifier> specifier_ap;
4581 if (m_options.m_sym_ctx_specified) {
4582 specifier_ap.reset(new SymbolContextSpecifier(
4583 m_interpreter.GetDebugger().GetSelectedTarget()));
4584
4585 if (!m_options.m_module_name.empty()) {
4586 specifier_ap->AddSpecification(
4587 m_options.m_module_name.c_str(),
4588 SymbolContextSpecifier::eModuleSpecified);
4589 }
4590
4591 if (!m_options.m_class_name.empty()) {
4592 specifier_ap->AddSpecification(
4593 m_options.m_class_name.c_str(),
4594 SymbolContextSpecifier::eClassOrNamespaceSpecified);
4595 }
4596
4597 if (!m_options.m_file_name.empty()) {
4598 specifier_ap->AddSpecification(
4599 m_options.m_file_name.c_str(),
4600 SymbolContextSpecifier::eFileSpecified);
4601 }
4602
4603 if (m_options.m_line_start != 0) {
4604 specifier_ap->AddLineSpecification(
4605 m_options.m_line_start,
4606 SymbolContextSpecifier::eLineStartSpecified);
4607 }
4608
4609 if (m_options.m_line_end != UINT_MAX) {
4610 specifier_ap->AddLineSpecification(
4611 m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4612 }
4613
4614 if (!m_options.m_function_name.empty()) {
4615 specifier_ap->AddSpecification(
4616 m_options.m_function_name.c_str(),
4617 SymbolContextSpecifier::eFunctionSpecified);
4618 }
4619 }
4620
4621 if (specifier_ap)
4622 new_hook_sp->SetSpecifier(specifier_ap.release());
4623
4624 // Next see if any of the thread options have been entered:
4625
4626 if (m_options.m_thread_specified) {
4627 ThreadSpec *thread_spec = new ThreadSpec();
4628
4629 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4630 thread_spec->SetTID(m_options.m_thread_id);
4631 }
4632
4633 if (m_options.m_thread_index != UINT32_MAX)
4634 thread_spec->SetIndex(m_options.m_thread_index);
4635
4636 if (!m_options.m_thread_name.empty())
4637 thread_spec->SetName(m_options.m_thread_name.c_str());
4638
4639 if (!m_options.m_queue_name.empty())
4640 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4641
4642 new_hook_sp->SetThreadSpecifier(thread_spec);
4643 }
4644 if (m_options.m_use_one_liner) {
4645 // Use one-liner.
4646 new_hook_sp->GetCommandPointer()->AppendString(
4647 m_options.m_one_liner.c_str());
4648 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4649 new_hook_sp->GetID());
4650 } else {
4651 m_stop_hook_sp = new_hook_sp;
4652 m_interpreter.GetLLDBCommandsFromIOHandler(
4653 "> ", // Prompt
4654 *this, // IOHandlerDelegate
4655 true, // Run IOHandler in async mode
4656 nullptr); // Baton for the "io_handler" that will be passed back
4657 // into our IOHandlerDelegate functions
4658 }
4659 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4660 } else {
4661 result.AppendError("invalid target\n");
4662 result.SetStatus(eReturnStatusFailed);
4663 }
4664
4665 return result.Succeeded();
4666 }
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004667
Jim Ingham9575d842011-03-11 03:53:59 +00004668private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004669 CommandOptions m_options;
4670 Target::StopHookSP m_stop_hook_sp;
Jim Ingham9575d842011-03-11 03:53:59 +00004671};
4672
Jim Ingham9575d842011-03-11 03:53:59 +00004673#pragma mark CommandObjectTargetStopHookDelete
4674
4675//-------------------------------------------------------------------------
4676// CommandObjectTargetStopHookDelete
4677//-------------------------------------------------------------------------
4678
Kate Stoneb9c1b512016-09-06 20:57:50 +00004679class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004680public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004681 CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4682 : CommandObjectParsed(interpreter, "target stop-hook delete",
4683 "Delete a stop-hook.",
4684 "target stop-hook delete [<idx>]") {}
Jim Ingham9575d842011-03-11 03:53:59 +00004685
Kate Stoneb9c1b512016-09-06 20:57:50 +00004686 ~CommandObjectTargetStopHookDelete() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004687
Jim Ingham5a988412012-06-08 21:56:10 +00004688protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004689 bool DoExecute(Args &command, CommandReturnObject &result) override {
4690 Target *target = GetSelectedOrDummyTarget();
4691 if (target) {
4692 // FIXME: see if we can use the breakpoint id style parser?
4693 size_t num_args = command.GetArgumentCount();
4694 if (num_args == 0) {
4695 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4696 result.SetStatus(eReturnStatusFailed);
4697 return false;
4698 } else {
4699 target->RemoveAllStopHooks();
Jim Ingham9575d842011-03-11 03:53:59 +00004700 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004701 } else {
4702 bool success;
4703 for (size_t i = 0; i < num_args; i++) {
4704 lldb::user_id_t user_id = StringConvert::ToUInt32(
4705 command.GetArgumentAtIndex(i), 0, 0, &success);
4706 if (!success) {
4707 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4708 command.GetArgumentAtIndex(i));
4709 result.SetStatus(eReturnStatusFailed);
4710 return false;
4711 }
4712 success = target->RemoveStopHookByID(user_id);
4713 if (!success) {
4714 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4715 command.GetArgumentAtIndex(i));
4716 result.SetStatus(eReturnStatusFailed);
4717 return false;
4718 }
Jim Ingham9575d842011-03-11 03:53:59 +00004719 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004720 }
4721 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4722 } else {
4723 result.AppendError("invalid target\n");
4724 result.SetStatus(eReturnStatusFailed);
Jim Ingham9575d842011-03-11 03:53:59 +00004725 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004726
4727 return result.Succeeded();
4728 }
Jim Ingham9575d842011-03-11 03:53:59 +00004729};
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004730
Jim Ingham9575d842011-03-11 03:53:59 +00004731#pragma mark CommandObjectTargetStopHookEnableDisable
4732
4733//-------------------------------------------------------------------------
4734// CommandObjectTargetStopHookEnableDisable
4735//-------------------------------------------------------------------------
4736
Kate Stoneb9c1b512016-09-06 20:57:50 +00004737class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004738public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004739 CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4740 bool enable, const char *name,
4741 const char *help, const char *syntax)
4742 : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4743 }
Jim Ingham9575d842011-03-11 03:53:59 +00004744
Kate Stoneb9c1b512016-09-06 20:57:50 +00004745 ~CommandObjectTargetStopHookEnableDisable() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004746
Jim Ingham5a988412012-06-08 21:56:10 +00004747protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004748 bool DoExecute(Args &command, CommandReturnObject &result) override {
4749 Target *target = GetSelectedOrDummyTarget();
4750 if (target) {
4751 // FIXME: see if we can use the breakpoint id style parser?
4752 size_t num_args = command.GetArgumentCount();
4753 bool success;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004754
Kate Stoneb9c1b512016-09-06 20:57:50 +00004755 if (num_args == 0) {
4756 target->SetAllStopHooksActiveState(m_enable);
4757 } else {
4758 for (size_t i = 0; i < num_args; i++) {
4759 lldb::user_id_t user_id = StringConvert::ToUInt32(
4760 command.GetArgumentAtIndex(i), 0, 0, &success);
4761 if (!success) {
4762 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4763 command.GetArgumentAtIndex(i));
4764 result.SetStatus(eReturnStatusFailed);
4765 return false;
4766 }
4767 success = target->SetStopHookActiveStateByID(user_id, m_enable);
4768 if (!success) {
4769 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4770 command.GetArgumentAtIndex(i));
4771 result.SetStatus(eReturnStatusFailed);
4772 return false;
4773 }
Jim Ingham9575d842011-03-11 03:53:59 +00004774 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004775 }
4776 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4777 } else {
4778 result.AppendError("invalid target\n");
4779 result.SetStatus(eReturnStatusFailed);
Jim Ingham9575d842011-03-11 03:53:59 +00004780 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004781 return result.Succeeded();
4782 }
4783
Jim Ingham9575d842011-03-11 03:53:59 +00004784private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004785 bool m_enable;
Jim Ingham9575d842011-03-11 03:53:59 +00004786};
4787
4788#pragma mark CommandObjectTargetStopHookList
4789
4790//-------------------------------------------------------------------------
4791// CommandObjectTargetStopHookList
4792//-------------------------------------------------------------------------
4793
Kate Stoneb9c1b512016-09-06 20:57:50 +00004794class CommandObjectTargetStopHookList : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004795public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004796 CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4797 : CommandObjectParsed(interpreter, "target stop-hook list",
4798 "List all stop-hooks.",
4799 "target stop-hook list [<type>]") {}
Jim Ingham9575d842011-03-11 03:53:59 +00004800
Kate Stoneb9c1b512016-09-06 20:57:50 +00004801 ~CommandObjectTargetStopHookList() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004802
Jim Ingham5a988412012-06-08 21:56:10 +00004803protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004804 bool DoExecute(Args &command, CommandReturnObject &result) override {
4805 Target *target = GetSelectedOrDummyTarget();
4806 if (!target) {
4807 result.AppendError("invalid target\n");
4808 result.SetStatus(eReturnStatusFailed);
4809 return result.Succeeded();
Jim Ingham9575d842011-03-11 03:53:59 +00004810 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004811
4812 size_t num_hooks = target->GetNumStopHooks();
4813 if (num_hooks == 0) {
4814 result.GetOutputStream().PutCString("No stop hooks.\n");
4815 } else {
4816 for (size_t i = 0; i < num_hooks; i++) {
4817 Target::StopHookSP this_hook = target->GetStopHookAtIndex(i);
4818 if (i > 0)
4819 result.GetOutputStream().PutCString("\n");
4820 this_hook->GetDescription(&(result.GetOutputStream()),
4821 eDescriptionLevelFull);
4822 }
4823 }
4824 result.SetStatus(eReturnStatusSuccessFinishResult);
4825 return result.Succeeded();
4826 }
Jim Ingham9575d842011-03-11 03:53:59 +00004827};
4828
4829#pragma mark CommandObjectMultiwordTargetStopHooks
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004830
Jim Ingham9575d842011-03-11 03:53:59 +00004831//-------------------------------------------------------------------------
4832// CommandObjectMultiwordTargetStopHooks
4833//-------------------------------------------------------------------------
4834
Kate Stoneb9c1b512016-09-06 20:57:50 +00004835class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
Jim Ingham9575d842011-03-11 03:53:59 +00004836public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004837 CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4838 : CommandObjectMultiword(
4839 interpreter, "target stop-hook",
4840 "Commands for operating on debugger target stop-hooks.",
4841 "target stop-hook <subcommand> [<subcommand-options>]") {
4842 LoadSubCommand("add", CommandObjectSP(
4843 new CommandObjectTargetStopHookAdd(interpreter)));
4844 LoadSubCommand(
4845 "delete",
4846 CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
4847 LoadSubCommand("disable",
4848 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4849 interpreter, false, "target stop-hook disable [<id>]",
4850 "Disable a stop-hook.", "target stop-hook disable")));
4851 LoadSubCommand("enable",
4852 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4853 interpreter, true, "target stop-hook enable [<id>]",
4854 "Enable a stop-hook.", "target stop-hook enable")));
4855 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
4856 interpreter)));
4857 }
Jim Ingham9575d842011-03-11 03:53:59 +00004858
Kate Stoneb9c1b512016-09-06 20:57:50 +00004859 ~CommandObjectMultiwordTargetStopHooks() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004860};
4861
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004862#pragma mark CommandObjectMultiwordTarget
4863
4864//-------------------------------------------------------------------------
4865// CommandObjectMultiwordTarget
4866//-------------------------------------------------------------------------
4867
Kate Stoneb9c1b512016-09-06 20:57:50 +00004868CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
4869 CommandInterpreter &interpreter)
4870 : CommandObjectMultiword(interpreter, "target",
4871 "Commands for operating on debugger targets.",
4872 "target <subcommand> [<subcommand-options>]") {
4873 LoadSubCommand("create",
4874 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
4875 LoadSubCommand("delete",
4876 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
4877 LoadSubCommand("list",
4878 CommandObjectSP(new CommandObjectTargetList(interpreter)));
4879 LoadSubCommand("select",
4880 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
4881 LoadSubCommand(
4882 "stop-hook",
4883 CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
4884 LoadSubCommand("modules",
4885 CommandObjectSP(new CommandObjectTargetModules(interpreter)));
4886 LoadSubCommand("symbols",
4887 CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
4888 LoadSubCommand("variable",
4889 CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004890}
4891
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004892CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;