blob: 321341cd861cf44387547c966b33ebc95f5c7381 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectTarget.h"
11
12// C Includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000013// C++ Includes
Eugene Zelenkof13e6522016-02-25 19:02:39 +000014#include <cerrno>
15
Chris Lattner30fdc8d2010-06-08 16:52:24 +000016// Other libraries and framework includes
17// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000018#include "lldb/Core/Debugger.h"
Greg Clayton44d93782014-01-27 23:43:24 +000019#include "lldb/Core/IOHandler.h"
Greg Clayton1f746072012-08-29 21:13:06 +000020#include "lldb/Core/Module.h"
21#include "lldb/Core/ModuleSpec.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000022#include "lldb/Core/Section.h"
Greg Clayton7260f622011-04-18 08:33:37 +000023#include "lldb/Core/State.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000024#include "lldb/Core/Timer.h"
Greg Clayton644247c2011-07-07 01:59:51 +000025#include "lldb/Core/ValueObjectVariable.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000026#include "lldb/DataFormatters/ValueObjectPrinter.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000027#include "lldb/Host/StringConvert.h"
Greg Claytonc8f814d2012-09-27 03:13:55 +000028#include "lldb/Host/Symbols.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000029#include "lldb/Interpreter/Args.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000030#include "lldb/Interpreter/CommandInterpreter.h"
31#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton7260f622011-04-18 08:33:37 +000032#include "lldb/Interpreter/OptionGroupArchitecture.h"
Greg Claytonaa149cb2011-08-11 02:48:45 +000033#include "lldb/Interpreter/OptionGroupBoolean.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000034#include "lldb/Interpreter/OptionGroupFile.h"
Greg Clayton1deb7962011-10-25 06:44:01 +000035#include "lldb/Interpreter/OptionGroupFormat.h"
Greg Clayton7260f622011-04-18 08:33:37 +000036#include "lldb/Interpreter/OptionGroupPlatform.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000037#include "lldb/Interpreter/OptionGroupString.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000038#include "lldb/Interpreter/OptionGroupUInt64.h"
39#include "lldb/Interpreter/OptionGroupUUID.h"
Greg Clayton644247c2011-07-07 01:59:51 +000040#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000041#include "lldb/Interpreter/OptionGroupVariable.h"
42#include "lldb/Interpreter/Options.h"
Greg Clayton1f746072012-08-29 21:13:06 +000043#include "lldb/Symbol/CompileUnit.h"
Jason Molenda380241a2012-07-12 00:20:07 +000044#include "lldb/Symbol/FuncUnwinders.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000045#include "lldb/Symbol/LineTable.h"
46#include "lldb/Symbol/ObjectFile.h"
47#include "lldb/Symbol/SymbolFile.h"
48#include "lldb/Symbol/SymbolVendor.h"
Jason Molenda380241a2012-07-12 00:20:07 +000049#include "lldb/Symbol/UnwindPlan.h"
Greg Clayton644247c2011-07-07 01:59:51 +000050#include "lldb/Symbol/VariableList.h"
Zachary Turner32abc6e2015-03-03 19:23:09 +000051#include "lldb/Target/ABI.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052#include "lldb/Target/Process.h"
Greg Claytond5944cd2013-12-06 01:12:00 +000053#include "lldb/Target/SectionLoadList.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000054#include "lldb/Target/StackFrame.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000055#include "lldb/Target/Thread.h"
Jim Ingham9575d842011-03-11 03:53:59 +000056#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000057
58using namespace lldb;
59using namespace lldb_private;
60
Kate Stoneb9c1b512016-09-06 20:57:50 +000061static void DumpTargetInfo(uint32_t target_idx, Target *target,
62 const char *prefix_cstr,
63 bool show_stopped_process_status, Stream &strm) {
64 const ArchSpec &target_arch = target->GetArchitecture();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000065
Kate Stoneb9c1b512016-09-06 20:57:50 +000066 Module *exe_module = target->GetExecutableModulePointer();
67 char exe_path[PATH_MAX];
68 bool exe_valid = false;
69 if (exe_module)
70 exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000071
Kate Stoneb9c1b512016-09-06 20:57:50 +000072 if (!exe_valid)
73 ::strcpy(exe_path, "<none>");
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000074
Kate Stoneb9c1b512016-09-06 20:57:50 +000075 strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
76 exe_path);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000077
Kate Stoneb9c1b512016-09-06 20:57:50 +000078 uint32_t properties = 0;
79 if (target_arch.IsValid()) {
80 strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
81 target_arch.DumpTriple(strm);
82 properties++;
83 }
84 PlatformSP platform_sp(target->GetPlatform());
85 if (platform_sp)
86 strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ",
87 platform_sp->GetName().GetCString());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000088
Kate Stoneb9c1b512016-09-06 20:57:50 +000089 ProcessSP process_sp(target->GetProcessSP());
90 bool show_process_status = false;
91 if (process_sp) {
92 lldb::pid_t pid = process_sp->GetID();
93 StateType state = process_sp->GetState();
94 if (show_stopped_process_status)
95 show_process_status = StateIsStoppedState(state, true);
96 const char *state_cstr = StateAsCString(state);
97 if (pid != LLDB_INVALID_PROCESS_ID)
98 strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
99 strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
100 }
101 if (properties > 0)
102 strm.PutCString(" )\n");
103 else
104 strm.EOL();
105 if (show_process_status) {
106 const bool only_threads_with_stop_reason = true;
107 const uint32_t start_frame = 0;
108 const uint32_t num_frames = 1;
109 const uint32_t num_frames_with_source = 1;
110 process_sp->GetStatus(strm);
111 process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
112 start_frame, num_frames,
113 num_frames_with_source);
114 }
Greg Clayton7260f622011-04-18 08:33:37 +0000115}
116
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117static uint32_t DumpTargetList(TargetList &target_list,
118 bool show_stopped_process_status, Stream &strm) {
119 const uint32_t num_targets = target_list.GetNumTargets();
120 if (num_targets) {
121 TargetSP selected_target_sp(target_list.GetSelectedTarget());
122 strm.PutCString("Current targets:\n");
123 for (uint32_t i = 0; i < num_targets; ++i) {
124 TargetSP target_sp(target_list.GetTargetAtIndex(i));
125 if (target_sp) {
126 bool is_selected = target_sp.get() == selected_target_sp.get();
127 DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
128 show_stopped_process_status, strm);
129 }
Greg Clayton7260f622011-04-18 08:33:37 +0000130 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000131 }
132 return num_targets;
Greg Clayton7260f622011-04-18 08:33:37 +0000133}
Eugene Zelenkof13e6522016-02-25 19:02:39 +0000134
Greg Clayton7260f622011-04-18 08:33:37 +0000135#pragma mark CommandObjectTargetCreate
136
137//-------------------------------------------------------------------------
138// "target create"
139//-------------------------------------------------------------------------
140
Kate Stoneb9c1b512016-09-06 20:57:50 +0000141class CommandObjectTargetCreate : public CommandObjectParsed {
Greg Clayton7260f622011-04-18 08:33:37 +0000142public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000143 CommandObjectTargetCreate(CommandInterpreter &interpreter)
144 : CommandObjectParsed(
145 interpreter, "target create",
146 "Create a target using the argument as the main executable.",
147 nullptr),
148 m_option_group(), m_arch_option(),
149 m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
150 "Fullpath to a core file to use for this target."),
151 m_platform_path(LLDB_OPT_SET_1, false, "platform-path", 'P', 0,
152 eArgTypePath,
153 "Path to the remote file to use for this target."),
154 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
155 eArgTypeFilename, "Fullpath to a stand alone debug "
156 "symbols file for when debug symbols "
157 "are not in the executable."),
158 m_remote_file(
159 LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
160 "Fullpath to the file on the remote host if debugging remotely."),
161 m_add_dependents(LLDB_OPT_SET_1, false, "no-dependents", 'd',
162 "Don't load dependent files when creating the target, "
163 "just add the specified executable.",
164 true, true) {
165 CommandArgumentEntry arg;
166 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000167
Kate Stoneb9c1b512016-09-06 20:57:50 +0000168 // Define the first (and only) variant of this arg.
169 file_arg.arg_type = eArgTypeFilename;
170 file_arg.arg_repetition = eArgRepeatPlain;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000171
Kate Stoneb9c1b512016-09-06 20:57:50 +0000172 // There is only one variant this argument could be; put it into the
173 // argument entry.
174 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000175
Kate Stoneb9c1b512016-09-06 20:57:50 +0000176 // Push the data for the first argument into the m_arguments vector.
177 m_arguments.push_back(arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000178
Kate Stoneb9c1b512016-09-06 20:57:50 +0000179 m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
180 m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
181 m_option_group.Append(&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
182 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
183 m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
184 m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
185 m_option_group.Finalize();
186 }
Greg Clayton7260f622011-04-18 08:33:37 +0000187
Kate Stoneb9c1b512016-09-06 20:57:50 +0000188 ~CommandObjectTargetCreate() override = default;
Greg Clayton7260f622011-04-18 08:33:37 +0000189
Kate Stoneb9c1b512016-09-06 20:57:50 +0000190 Options *GetOptions() override { return &m_option_group; }
Greg Clayton7260f622011-04-18 08:33:37 +0000191
Kate Stoneb9c1b512016-09-06 20:57:50 +0000192 int HandleArgumentCompletion(Args &input, int &cursor_index,
193 int &cursor_char_position,
194 OptionElementVector &opt_element_vector,
195 int match_start_point, int max_return_elements,
196 bool &word_complete,
197 StringList &matches) override {
198 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
199 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000200
Kate Stoneb9c1b512016-09-06 20:57:50 +0000201 CommandCompletions::InvokeCommonCompletionCallbacks(
202 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
203 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
204 word_complete, matches);
205 return matches.GetSize();
206 }
Jim Ingham5a988412012-06-08 21:56:10 +0000207
208protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209 bool DoExecute(Args &command, CommandReturnObject &result) override {
210 const size_t argc = command.GetArgumentCount();
211 FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
212 FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
Greg Claytonc3776bf2012-02-09 06:16:32 +0000213
Kate Stoneb9c1b512016-09-06 20:57:50 +0000214 if (core_file) {
215 if (!core_file.Exists()) {
216 result.AppendErrorWithFormat("core file '%s' doesn't exist",
217 core_file.GetPath().c_str());
218 result.SetStatus(eReturnStatusFailed);
219 return false;
220 }
221 if (!core_file.Readable()) {
222 result.AppendErrorWithFormat("core file '%s' is not readable",
223 core_file.GetPath().c_str());
224 result.SetStatus(eReturnStatusFailed);
225 return false;
226 }
Greg Clayton7260f622011-04-18 08:33:37 +0000227 }
228
Kate Stoneb9c1b512016-09-06 20:57:50 +0000229 if (argc == 1 || core_file || remote_file) {
230 FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
231 if (symfile) {
232 if (symfile.Exists()) {
233 if (!symfile.Readable()) {
234 result.AppendErrorWithFormat("symbol file '%s' is not readable",
235 symfile.GetPath().c_str());
236 result.SetStatus(eReturnStatusFailed);
237 return false;
238 }
239 } else {
240 char symfile_path[PATH_MAX];
241 symfile.GetPath(symfile_path, sizeof(symfile_path));
242 result.AppendErrorWithFormat("invalid symbol file path '%s'",
243 symfile_path);
244 result.SetStatus(eReturnStatusFailed);
245 return false;
246 }
247 }
248
249 const char *file_path = command.GetArgumentAtIndex(0);
250 Timer scoped_timer(LLVM_PRETTY_FUNCTION, "(lldb) target create '%s'",
251 file_path);
252 FileSpec file_spec;
253
254 if (file_path)
255 file_spec.SetFile(file_path, true);
256
257 bool must_set_platform_path = false;
258
259 Debugger &debugger = m_interpreter.GetDebugger();
260
261 TargetSP target_sp;
262 const char *arch_cstr = m_arch_option.GetArchitectureName();
263 const bool get_dependent_files =
264 m_add_dependents.GetOptionValue().GetCurrentValue();
265 Error error(debugger.GetTargetList().CreateTarget(
266 debugger, file_path, arch_cstr, get_dependent_files, nullptr,
267 target_sp));
268
269 if (target_sp) {
270 // Only get the platform after we create the target because we might
271 // have
272 // switched platforms depending on what the arguments were to
273 // CreateTarget()
274 // we can't rely on the selected platform.
275
276 PlatformSP platform_sp = target_sp->GetPlatform();
277
278 if (remote_file) {
279 if (platform_sp) {
280 // I have a remote file.. two possible cases
281 if (file_spec && file_spec.Exists()) {
282 // if the remote file does not exist, push it there
283 if (!platform_sp->GetFileExists(remote_file)) {
284 Error err = platform_sp->PutFile(file_spec, remote_file);
285 if (err.Fail()) {
286 result.AppendError(err.AsCString());
287 result.SetStatus(eReturnStatusFailed);
288 return false;
289 }
290 }
291 } else {
292 // there is no local file and we need one
293 // in order to make the remote ---> local transfer we need a
294 // platform
295 // TODO: if the user has passed in a --platform argument, use it
296 // to fetch the right platform
297 if (!platform_sp) {
298 result.AppendError(
299 "unable to perform remote debugging without a platform");
300 result.SetStatus(eReturnStatusFailed);
301 return false;
302 }
303 if (file_path) {
304 // copy the remote file to the local file
305 Error err = platform_sp->GetFile(remote_file, file_spec);
306 if (err.Fail()) {
307 result.AppendError(err.AsCString());
308 result.SetStatus(eReturnStatusFailed);
309 return false;
310 }
311 } else {
312 // make up a local file
313 result.AppendError("remote --> local transfer without local "
314 "path is not implemented yet");
315 result.SetStatus(eReturnStatusFailed);
316 return false;
317 }
318 }
319 } else {
320 result.AppendError("no platform found for target");
321 result.SetStatus(eReturnStatusFailed);
322 return false;
323 }
324 }
325
326 if (symfile || remote_file) {
327 ModuleSP module_sp(target_sp->GetExecutableModule());
328 if (module_sp) {
329 if (symfile)
330 module_sp->SetSymbolFileFileSpec(symfile);
331 if (remote_file) {
332 std::string remote_path = remote_file.GetPath();
333 target_sp->SetArg0(remote_path.c_str());
334 module_sp->SetPlatformFileSpec(remote_file);
335 }
336 }
337 }
338
339 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
340 if (must_set_platform_path) {
341 ModuleSpec main_module_spec(file_spec);
342 ModuleSP module_sp = target_sp->GetSharedModule(main_module_spec);
343 if (module_sp)
344 module_sp->SetPlatformFileSpec(remote_file);
345 }
346 if (core_file) {
347 char core_path[PATH_MAX];
348 core_file.GetPath(core_path, sizeof(core_path));
349 if (core_file.Exists()) {
350 if (!core_file.Readable()) {
351 result.AppendMessageWithFormat(
352 "Core file '%s' is not readable.\n", core_path);
353 result.SetStatus(eReturnStatusFailed);
354 return false;
355 }
356 FileSpec core_file_dir;
357 core_file_dir.GetDirectory() = core_file.GetDirectory();
358 target_sp->GetExecutableSearchPaths().Append(core_file_dir);
359
360 ProcessSP process_sp(target_sp->CreateProcess(
361 m_interpreter.GetDebugger().GetListener(), nullptr,
362 &core_file));
363
364 if (process_sp) {
365 // Seems weird that we Launch a core file, but that is
366 // what we do!
367 error = process_sp->LoadCore();
368
369 if (error.Fail()) {
370 result.AppendError(
371 error.AsCString("can't find plug-in for core file"));
372 result.SetStatus(eReturnStatusFailed);
373 return false;
374 } else {
375 result.AppendMessageWithFormat(
376 "Core file '%s' (%s) was loaded.\n", core_path,
377 target_sp->GetArchitecture().GetArchitectureName());
378 result.SetStatus(eReturnStatusSuccessFinishNoResult);
379 }
380 } else {
381 result.AppendErrorWithFormat(
382 "Unable to find process plug-in for core file '%s'\n",
383 core_path);
384 result.SetStatus(eReturnStatusFailed);
385 }
386 } else {
387 result.AppendErrorWithFormat("Core file '%s' does not exist\n",
388 core_path);
389 result.SetStatus(eReturnStatusFailed);
390 }
391 } else {
392 result.AppendMessageWithFormat(
393 "Current executable set to '%s' (%s).\n", file_path,
394 target_sp->GetArchitecture().GetArchitectureName());
395 result.SetStatus(eReturnStatusSuccessFinishNoResult);
396 }
397 } else {
398 result.AppendError(error.AsCString());
399 result.SetStatus(eReturnStatusFailed);
400 }
401 } else {
402 result.AppendErrorWithFormat("'%s' takes exactly one executable path "
403 "argument, or use the --core option.\n",
404 m_cmd_name.c_str());
405 result.SetStatus(eReturnStatusFailed);
406 }
407 return result.Succeeded();
408 }
409
Greg Clayton7260f622011-04-18 08:33:37 +0000410private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000411 OptionGroupOptions m_option_group;
412 OptionGroupArchitecture m_arch_option;
413 OptionGroupFile m_core_file;
414 OptionGroupFile m_platform_path;
415 OptionGroupFile m_symbol_file;
416 OptionGroupFile m_remote_file;
417 OptionGroupBoolean m_add_dependents;
Greg Clayton7260f622011-04-18 08:33:37 +0000418};
419
420#pragma mark CommandObjectTargetList
421
422//----------------------------------------------------------------------
423// "target list"
424//----------------------------------------------------------------------
425
Kate Stoneb9c1b512016-09-06 20:57:50 +0000426class CommandObjectTargetList : public CommandObjectParsed {
Greg Clayton7260f622011-04-18 08:33:37 +0000427public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000428 CommandObjectTargetList(CommandInterpreter &interpreter)
429 : CommandObjectParsed(
430 interpreter, "target list",
431 "List all current targets in the current debug session.", nullptr) {
432 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000433
Kate Stoneb9c1b512016-09-06 20:57:50 +0000434 ~CommandObjectTargetList() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000435
Jim Ingham5a988412012-06-08 21:56:10 +0000436protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000437 bool DoExecute(Args &args, CommandReturnObject &result) override {
438 if (args.GetArgumentCount() == 0) {
439 Stream &strm = result.GetOutputStream();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000440
Kate Stoneb9c1b512016-09-06 20:57:50 +0000441 bool show_stopped_process_status = false;
442 if (DumpTargetList(m_interpreter.GetDebugger().GetTargetList(),
443 show_stopped_process_status, strm) == 0) {
444 strm.PutCString("No targets.\n");
445 }
446 result.SetStatus(eReturnStatusSuccessFinishResult);
447 } else {
448 result.AppendError("the 'target list' command takes no arguments\n");
449 result.SetStatus(eReturnStatusFailed);
Greg Clayton7260f622011-04-18 08:33:37 +0000450 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000451 return result.Succeeded();
452 }
Greg Clayton7260f622011-04-18 08:33:37 +0000453};
454
Greg Clayton7260f622011-04-18 08:33:37 +0000455#pragma mark CommandObjectTargetSelect
456
457//----------------------------------------------------------------------
458// "target select"
459//----------------------------------------------------------------------
460
Kate Stoneb9c1b512016-09-06 20:57:50 +0000461class CommandObjectTargetSelect : public CommandObjectParsed {
Greg Clayton7260f622011-04-18 08:33:37 +0000462public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000463 CommandObjectTargetSelect(CommandInterpreter &interpreter)
464 : CommandObjectParsed(
465 interpreter, "target select",
466 "Select a target as the current target by target index.", nullptr) {
467 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000468
Kate Stoneb9c1b512016-09-06 20:57:50 +0000469 ~CommandObjectTargetSelect() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000470
Jim Ingham5a988412012-06-08 21:56:10 +0000471protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000472 bool DoExecute(Args &args, CommandReturnObject &result) override {
473 if (args.GetArgumentCount() == 1) {
474 bool success = false;
475 const char *target_idx_arg = args.GetArgumentAtIndex(0);
476 uint32_t target_idx =
477 StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success);
478 if (success) {
479 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
480 const uint32_t num_targets = target_list.GetNumTargets();
481 if (target_idx < num_targets) {
482 TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
483 if (target_sp) {
484 Stream &strm = result.GetOutputStream();
485 target_list.SetSelectedTarget(target_sp.get());
486 bool show_stopped_process_status = false;
487 DumpTargetList(target_list, show_stopped_process_status, strm);
488 result.SetStatus(eReturnStatusSuccessFinishResult);
489 } else {
490 result.AppendErrorWithFormat("target #%u is NULL in target list\n",
491 target_idx);
492 result.SetStatus(eReturnStatusFailed);
493 }
494 } else {
495 if (num_targets > 0) {
496 result.AppendErrorWithFormat(
497 "index %u is out of range, valid target indexes are 0 - %u\n",
498 target_idx, num_targets - 1);
499 } else {
500 result.AppendErrorWithFormat(
501 "index %u is out of range since there are no active targets\n",
502 target_idx);
503 }
504 result.SetStatus(eReturnStatusFailed);
Greg Clayton7260f622011-04-18 08:33:37 +0000505 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000506 } else {
507 result.AppendErrorWithFormat("invalid index string value '%s'\n",
508 target_idx_arg);
509 result.SetStatus(eReturnStatusFailed);
510 }
511 } else {
512 result.AppendError(
513 "'target select' takes a single argument: a target index\n");
514 result.SetStatus(eReturnStatusFailed);
Greg Clayton7260f622011-04-18 08:33:37 +0000515 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000516 return result.Succeeded();
517 }
Greg Clayton7260f622011-04-18 08:33:37 +0000518};
519
Greg Clayton3418c852011-08-10 02:10:13 +0000520#pragma mark CommandObjectTargetSelect
521
522//----------------------------------------------------------------------
523// "target delete"
524//----------------------------------------------------------------------
525
Kate Stoneb9c1b512016-09-06 20:57:50 +0000526class CommandObjectTargetDelete : public CommandObjectParsed {
Greg Clayton3418c852011-08-10 02:10:13 +0000527public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000528 CommandObjectTargetDelete(CommandInterpreter &interpreter)
529 : CommandObjectParsed(interpreter, "target delete",
Eugene Zelenkof13e6522016-02-25 19:02:39 +0000530 "Delete one or more targets by target index.",
531 nullptr),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000532 m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
533 "Delete all targets.", false, true),
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000534 m_cleanup_option(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000535 LLDB_OPT_SET_1, false, "clean", 'c',
536 "Perform extra cleanup to minimize memory consumption after "
537 "deleting the target. "
538 "By default, LLDB will keep in memory any modules previously "
539 "loaded by the target as well "
540 "as all of its debug info. Specifying --clean will unload all of "
541 "these shared modules and "
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000542 "cause them to be reparsed again the next time the target is run",
Kate Stoneb9c1b512016-09-06 20:57:50 +0000543 false, true) {
544 m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
545 m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
546 m_option_group.Finalize();
547 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000548
Kate Stoneb9c1b512016-09-06 20:57:50 +0000549 ~CommandObjectTargetDelete() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000550
Kate Stoneb9c1b512016-09-06 20:57:50 +0000551 Options *GetOptions() override { return &m_option_group; }
Jim Ingham5a988412012-06-08 21:56:10 +0000552
553protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000554 bool DoExecute(Args &args, CommandReturnObject &result) override {
555 const size_t argc = args.GetArgumentCount();
556 std::vector<TargetSP> delete_target_list;
557 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
558 TargetSP target_sp;
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000559
Kate Stoneb9c1b512016-09-06 20:57:50 +0000560 if (m_all_option.GetOptionValue()) {
561 for (int i = 0; i < target_list.GetNumTargets(); ++i)
562 delete_target_list.push_back(target_list.GetTargetAtIndex(i));
563 } else if (argc > 0) {
564 const uint32_t num_targets = target_list.GetNumTargets();
565 // Bail out if don't have any targets.
566 if (num_targets == 0) {
567 result.AppendError("no targets to delete");
568 result.SetStatus(eReturnStatusFailed);
569 return false;
570 }
571
572 for (uint32_t arg_idx = 0; arg_idx < argc; ++arg_idx) {
573 const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx);
574 bool success = false;
575 uint32_t target_idx =
576 StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success);
577 if (!success) {
578 result.AppendErrorWithFormat("invalid target index '%s'\n",
579 target_idx_arg);
580 result.SetStatus(eReturnStatusFailed);
581 return false;
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000582 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000583 if (target_idx < num_targets) {
584 target_sp = target_list.GetTargetAtIndex(target_idx);
585 if (target_sp) {
586 delete_target_list.push_back(target_sp);
587 continue;
588 }
Greg Clayton3418c852011-08-10 02:10:13 +0000589 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000590 if (num_targets > 1)
591 result.AppendErrorWithFormat("target index %u is out of range, valid "
592 "target indexes are 0 - %u\n",
593 target_idx, num_targets - 1);
Greg Clayton3418c852011-08-10 02:10:13 +0000594 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000595 result.AppendErrorWithFormat(
596 "target index %u is out of range, the only valid index is 0\n",
597 target_idx);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000598
Kate Stoneb9c1b512016-09-06 20:57:50 +0000599 result.SetStatus(eReturnStatusFailed);
600 return false;
601 }
602 } else {
603 target_sp = target_list.GetSelectedTarget();
604 if (!target_sp) {
605 result.AppendErrorWithFormat("no target is currently selected\n");
606 result.SetStatus(eReturnStatusFailed);
607 return false;
608 }
609 delete_target_list.push_back(target_sp);
Greg Clayton3418c852011-08-10 02:10:13 +0000610 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000611
Kate Stoneb9c1b512016-09-06 20:57:50 +0000612 const size_t num_targets_to_delete = delete_target_list.size();
613 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
614 target_sp = delete_target_list[idx];
615 target_list.DeleteTarget(target_sp);
616 target_sp->Destroy();
617 }
618 // If "--clean" was specified, prune any orphaned shared modules from
619 // the global shared module list
620 if (m_cleanup_option.GetOptionValue()) {
621 const bool mandatory = true;
622 ModuleList::RemoveOrphanSharedModules(mandatory);
623 }
624 result.GetOutputStream().Printf("%u targets deleted.\n",
625 (uint32_t)num_targets_to_delete);
626 result.SetStatus(eReturnStatusSuccessFinishResult);
627
628 return true;
629 }
630
631 OptionGroupOptions m_option_group;
632 OptionGroupBoolean m_all_option;
633 OptionGroupBoolean m_cleanup_option;
Greg Clayton3418c852011-08-10 02:10:13 +0000634};
635
Greg Clayton644247c2011-07-07 01:59:51 +0000636#pragma mark CommandObjectTargetVariable
637
638//----------------------------------------------------------------------
639// "target variable"
640//----------------------------------------------------------------------
641
Kate Stoneb9c1b512016-09-06 20:57:50 +0000642class CommandObjectTargetVariable : public CommandObjectParsed {
643 static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
644 static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
Saleem Abdulrasool44edda02014-03-18 04:43:47 +0000645
Greg Clayton644247c2011-07-07 01:59:51 +0000646public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000647 CommandObjectTargetVariable(CommandInterpreter &interpreter)
648 : CommandObjectParsed(interpreter, "target variable",
649 "Read global variables for the current target, "
650 "before or while running a process.",
651 nullptr, eCommandRequiresTarget),
652 m_option_group(),
653 m_option_variable(false), // Don't include frame options
654 m_option_format(eFormatDefault),
655 m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
656 0, eArgTypeFilename,
657 "A basename or fullpath to a file that contains "
658 "global variables. This option can be "
659 "specified multiple times."),
660 m_option_shared_libraries(
661 LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
662 eArgTypeFilename,
663 "A basename or fullpath to a shared library to use in the search "
664 "for global "
665 "variables. This option can be specified multiple times."),
666 m_varobj_options() {
667 CommandArgumentEntry arg;
668 CommandArgumentData var_name_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000669
Kate Stoneb9c1b512016-09-06 20:57:50 +0000670 // Define the first (and only) variant of this arg.
671 var_name_arg.arg_type = eArgTypeVarName;
672 var_name_arg.arg_repetition = eArgRepeatPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000673
Kate Stoneb9c1b512016-09-06 20:57:50 +0000674 // There is only one variant this argument could be; put it into the
675 // argument entry.
676 arg.push_back(var_name_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000677
Kate Stoneb9c1b512016-09-06 20:57:50 +0000678 // Push the data for the first argument into the m_arguments vector.
679 m_arguments.push_back(arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000680
Kate Stoneb9c1b512016-09-06 20:57:50 +0000681 m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
682 m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
683 m_option_group.Append(&m_option_format,
684 OptionGroupFormat::OPTION_GROUP_FORMAT |
685 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
686 LLDB_OPT_SET_1);
687 m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
688 LLDB_OPT_SET_1);
689 m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
690 LLDB_OPT_SET_1);
691 m_option_group.Finalize();
692 }
693
694 ~CommandObjectTargetVariable() override = default;
695
696 void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
697 const char *root_name) {
698 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
699
700 if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
701 valobj_sp->IsRuntimeSupportValue())
702 return;
703
704 switch (var_sp->GetScope()) {
705 case eValueTypeVariableGlobal:
706 if (m_option_variable.show_scope)
707 s.PutCString("GLOBAL: ");
708 break;
709
710 case eValueTypeVariableStatic:
711 if (m_option_variable.show_scope)
712 s.PutCString("STATIC: ");
713 break;
714
715 case eValueTypeVariableArgument:
716 if (m_option_variable.show_scope)
717 s.PutCString(" ARG: ");
718 break;
719
720 case eValueTypeVariableLocal:
721 if (m_option_variable.show_scope)
722 s.PutCString(" LOCAL: ");
723 break;
724
725 case eValueTypeVariableThreadLocal:
726 if (m_option_variable.show_scope)
727 s.PutCString("THREAD: ");
728 break;
729
730 default:
731 break;
Greg Clayton644247c2011-07-07 01:59:51 +0000732 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000733
Kate Stoneb9c1b512016-09-06 20:57:50 +0000734 if (m_option_variable.show_decl) {
735 bool show_fullpaths = false;
736 bool show_module = true;
737 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
738 s.PutCString(": ");
Greg Clayton884fb692011-07-08 21:46:14 +0000739 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000740
Kate Stoneb9c1b512016-09-06 20:57:50 +0000741 const Format format = m_option_format.GetFormat();
742 if (format != eFormatDefault)
743 options.SetFormat(format);
Greg Clayton884fb692011-07-08 21:46:14 +0000744
Kate Stoneb9c1b512016-09-06 20:57:50 +0000745 options.SetRootValueObjectName(root_name);
746
747 valobj_sp->Dump(s, options);
748 }
749
750 static size_t GetVariableCallback(void *baton, const char *name,
751 VariableList &variable_list) {
752 Target *target = static_cast<Target *>(baton);
753 if (target) {
754 return target->GetImages().FindGlobalVariables(ConstString(name), true,
755 UINT32_MAX, variable_list);
Jim Ingham5a988412012-06-08 21:56:10 +0000756 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000757 return 0;
758 }
759
760 Options *GetOptions() override { return &m_option_group; }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000761
Jim Ingham5a988412012-06-08 21:56:10 +0000762protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000763 void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
764 const SymbolContext &sc,
765 const VariableList &variable_list, Stream &s) {
766 size_t count = variable_list.GetSize();
767 if (count > 0) {
768 if (sc.module_sp) {
769 if (sc.comp_unit) {
770 s.Printf("Global variables for %s in %s:\n",
771 sc.comp_unit->GetPath().c_str(),
772 sc.module_sp->GetFileSpec().GetPath().c_str());
773 } else {
774 s.Printf("Global variables for %s\n",
775 sc.module_sp->GetFileSpec().GetPath().c_str());
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000776 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000777 } else if (sc.comp_unit) {
778 s.Printf("Global variables for %s\n", sc.comp_unit->GetPath().c_str());
779 }
780
781 for (uint32_t i = 0; i < count; ++i) {
782 VariableSP var_sp(variable_list.GetVariableAtIndex(i));
783 if (var_sp) {
784 ValueObjectSP valobj_sp(ValueObjectVariable::Create(
785 exe_ctx.GetBestExecutionContextScope(), var_sp));
786
787 if (valobj_sp)
788 DumpValueObject(s, var_sp, valobj_sp,
789 var_sp->GetName().GetCString());
790 }
791 }
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000792 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000793 }
Eugene Zelenkof13e6522016-02-25 19:02:39 +0000794
Kate Stoneb9c1b512016-09-06 20:57:50 +0000795 bool DoExecute(Args &args, CommandReturnObject &result) override {
796 Target *target = m_exe_ctx.GetTargetPtr();
797 const size_t argc = args.GetArgumentCount();
798 Stream &s = result.GetOutputStream();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000799
Kate Stoneb9c1b512016-09-06 20:57:50 +0000800 if (argc > 0) {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000801
Kate Stoneb9c1b512016-09-06 20:57:50 +0000802 for (size_t idx = 0; idx < argc; ++idx) {
803 VariableList variable_list;
804 ValueObjectList valobj_list;
Greg Clayton884fb692011-07-08 21:46:14 +0000805
Kate Stoneb9c1b512016-09-06 20:57:50 +0000806 const char *arg = args.GetArgumentAtIndex(idx);
807 size_t matches = 0;
808 bool use_var_name = false;
809 if (m_option_variable.use_regex) {
Zachary Turner95eae422016-09-21 16:01:28 +0000810 RegularExpression regex(llvm::StringRef::withNullAsEmpty(arg));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000811 if (!regex.IsValid()) {
812 result.GetErrorStream().Printf(
813 "error: invalid regular expression: '%s'\n", arg);
814 result.SetStatus(eReturnStatusFailed);
815 return false;
816 }
817 use_var_name = true;
818 matches = target->GetImages().FindGlobalVariables(
819 regex, true, UINT32_MAX, variable_list);
820 } else {
821 Error error(Variable::GetValuesForVariableExpressionPath(
822 arg, m_exe_ctx.GetBestExecutionContextScope(),
823 GetVariableCallback, target, variable_list, valobj_list));
824 matches = variable_list.GetSize();
Greg Clayton644247c2011-07-07 01:59:51 +0000825 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000826
827 if (matches == 0) {
828 result.GetErrorStream().Printf(
829 "error: can't find global variable '%s'\n", arg);
830 result.SetStatus(eReturnStatusFailed);
831 return false;
832 } else {
833 for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
834 VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
835 if (var_sp) {
836 ValueObjectSP valobj_sp(
837 valobj_list.GetValueObjectAtIndex(global_idx));
838 if (!valobj_sp)
839 valobj_sp = ValueObjectVariable::Create(
840 m_exe_ctx.GetBestExecutionContextScope(), var_sp);
841
842 if (valobj_sp)
843 DumpValueObject(s, var_sp, valobj_sp,
844 use_var_name ? var_sp->GetName().GetCString()
845 : arg);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000846 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000847 }
848 }
849 }
850 } else {
851 const FileSpecList &compile_units =
852 m_option_compile_units.GetOptionValue().GetCurrentValue();
853 const FileSpecList &shlibs =
854 m_option_shared_libraries.GetOptionValue().GetCurrentValue();
855 SymbolContextList sc_list;
856 const size_t num_compile_units = compile_units.GetSize();
857 const size_t num_shlibs = shlibs.GetSize();
858 if (num_compile_units == 0 && num_shlibs == 0) {
859 bool success = false;
860 StackFrame *frame = m_exe_ctx.GetFramePtr();
861 CompileUnit *comp_unit = nullptr;
862 if (frame) {
863 SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
864 if (sc.comp_unit) {
865 const bool can_create = true;
866 VariableListSP comp_unit_varlist_sp(
867 sc.comp_unit->GetVariableList(can_create));
868 if (comp_unit_varlist_sp) {
869 size_t count = comp_unit_varlist_sp->GetSize();
870 if (count > 0) {
871 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
872 success = true;
873 }
874 }
875 }
876 }
877 if (!success) {
878 if (frame) {
879 if (comp_unit)
880 result.AppendErrorWithFormat(
881 "no global variables in current compile unit: %s\n",
882 comp_unit->GetPath().c_str());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000883 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000884 result.AppendErrorWithFormat(
885 "no debug information for frame %u\n",
886 frame->GetFrameIndex());
887 } else
888 result.AppendError("'target variable' takes one or more global "
889 "variable names as arguments\n");
890 result.SetStatus(eReturnStatusFailed);
891 }
892 } else {
893 SymbolContextList sc_list;
894 const bool append = true;
895 // We have one or more compile unit or shlib
896 if (num_shlibs > 0) {
897 for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
898 const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
899 ModuleSpec module_spec(module_file);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000900
Kate Stoneb9c1b512016-09-06 20:57:50 +0000901 ModuleSP module_sp(
902 target->GetImages().FindFirstModule(module_spec));
903 if (module_sp) {
904 if (num_compile_units > 0) {
905 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
906 module_sp->FindCompileUnits(
907 compile_units.GetFileSpecAtIndex(cu_idx), append,
908 sc_list);
909 } else {
910 SymbolContext sc;
911 sc.module_sp = module_sp;
912 sc_list.Append(sc);
913 }
914 } else {
915 // Didn't find matching shlib/module in target...
916 result.AppendErrorWithFormat(
917 "target doesn't contain the specified shared library: %s\n",
918 module_file.GetPath().c_str());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000919 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000920 }
921 } else {
922 // No shared libraries, we just want to find globals for the compile
923 // units files that were specified
924 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
925 target->GetImages().FindCompileUnits(
926 compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
Greg Clayton644247c2011-07-07 01:59:51 +0000927 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000928
Kate Stoneb9c1b512016-09-06 20:57:50 +0000929 const uint32_t num_scs = sc_list.GetSize();
930 if (num_scs > 0) {
931 SymbolContext sc;
932 for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
933 if (sc_list.GetContextAtIndex(sc_idx, sc)) {
934 if (sc.comp_unit) {
935 const bool can_create = true;
936 VariableListSP comp_unit_varlist_sp(
937 sc.comp_unit->GetVariableList(can_create));
938 if (comp_unit_varlist_sp)
939 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
940 s);
941 } else if (sc.module_sp) {
942 // Get all global variables for this module
943 lldb_private::RegularExpression all_globals_regex(
Zachary Turner95eae422016-09-21 16:01:28 +0000944 llvm::StringRef(
945 ".")); // Any global with at least one character
Kate Stoneb9c1b512016-09-06 20:57:50 +0000946 VariableList variable_list;
947 sc.module_sp->FindGlobalVariables(all_globals_regex, append,
948 UINT32_MAX, variable_list);
949 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
950 }
951 }
952 }
Enrico Granata61a80ba2011-08-12 16:42:31 +0000953 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000954 }
Greg Clayton644247c2011-07-07 01:59:51 +0000955 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000956
Kate Stoneb9c1b512016-09-06 20:57:50 +0000957 if (m_interpreter.TruncationWarningNecessary()) {
958 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
959 m_cmd_name.c_str());
960 m_interpreter.TruncationWarningGiven();
961 }
962
963 return result.Succeeded();
964 }
965
966 OptionGroupOptions m_option_group;
967 OptionGroupVariable m_option_variable;
968 OptionGroupFormat m_option_format;
969 OptionGroupFileList m_option_compile_units;
970 OptionGroupFileList m_option_shared_libraries;
971 OptionGroupValueObjectDisplay m_varobj_options;
Greg Clayton644247c2011-07-07 01:59:51 +0000972};
973
Greg Claytoneffe5c92011-05-03 22:09:39 +0000974#pragma mark CommandObjectTargetModulesSearchPathsAdd
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000975
Kate Stoneb9c1b512016-09-06 20:57:50 +0000976class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000977public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000978 CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
979 : CommandObjectParsed(interpreter, "target modules search-paths add",
980 "Add new image search paths substitution pairs to "
981 "the current target.",
982 nullptr) {
983 CommandArgumentEntry arg;
984 CommandArgumentData old_prefix_arg;
985 CommandArgumentData new_prefix_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000986
Kate Stoneb9c1b512016-09-06 20:57:50 +0000987 // Define the first variant of this arg pair.
988 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
989 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000990
Kate Stoneb9c1b512016-09-06 20:57:50 +0000991 // Define the first variant of this arg pair.
992 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
993 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000994
Kate Stoneb9c1b512016-09-06 20:57:50 +0000995 // There are two required arguments that must always occur together, i.e. an
996 // argument "pair". Because they
997 // must always occur together, they are treated as two variants of one
998 // argument rather than two independent
999 // arguments. Push them both into the first argument position for
1000 // m_arguments...
Caroline Tice405fe672010-10-04 22:28:36 +00001001
Kate Stoneb9c1b512016-09-06 20:57:50 +00001002 arg.push_back(old_prefix_arg);
1003 arg.push_back(new_prefix_arg);
Caroline Tice405fe672010-10-04 22:28:36 +00001004
Kate Stoneb9c1b512016-09-06 20:57:50 +00001005 m_arguments.push_back(arg);
1006 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001007
Kate Stoneb9c1b512016-09-06 20:57:50 +00001008 ~CommandObjectTargetModulesSearchPathsAdd() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001009
Jim Ingham5a988412012-06-08 21:56:10 +00001010protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001011 bool DoExecute(Args &command, CommandReturnObject &result) override {
1012 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1013 if (target) {
1014 const size_t argc = command.GetArgumentCount();
1015 if (argc & 1) {
1016 result.AppendError("add requires an even number of arguments\n");
1017 result.SetStatus(eReturnStatusFailed);
1018 } else {
1019 for (size_t i = 0; i < argc; i += 2) {
1020 const char *from = command.GetArgumentAtIndex(i);
1021 const char *to = command.GetArgumentAtIndex(i + 1);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001022
Kate Stoneb9c1b512016-09-06 20:57:50 +00001023 if (from[0] && to[0]) {
1024 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
1025 if (log) {
1026 log->Printf("target modules search path adding ImageSearchPath "
1027 "pair: '%s' -> '%s'",
1028 from, to);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001029 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001030 bool last_pair = ((argc - i) == 2);
1031 target->GetImageSearchPathList().Append(
1032 ConstString(from), ConstString(to),
1033 last_pair); // Notify if this is the last pair
1034 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1035 } else {
1036 if (from[0])
1037 result.AppendError("<path-prefix> can't be empty\n");
1038 else
1039 result.AppendError("<new-path-prefix> can't be empty\n");
1040 result.SetStatus(eReturnStatusFailed);
1041 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001042 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001043 }
1044 } else {
1045 result.AppendError("invalid target\n");
1046 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001047 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001048 return result.Succeeded();
1049 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001050};
1051
Greg Claytoneffe5c92011-05-03 22:09:39 +00001052#pragma mark CommandObjectTargetModulesSearchPathsClear
1053
Kate Stoneb9c1b512016-09-06 20:57:50 +00001054class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001055public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001056 CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
1057 : CommandObjectParsed(interpreter, "target modules search-paths clear",
1058 "Clear all current image search path substitution "
1059 "pairs from the current target.",
1060 "target modules search-paths clear") {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001061
Kate Stoneb9c1b512016-09-06 20:57:50 +00001062 ~CommandObjectTargetModulesSearchPathsClear() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001063
Jim Ingham5a988412012-06-08 21:56:10 +00001064protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001065 bool DoExecute(Args &command, CommandReturnObject &result) override {
1066 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1067 if (target) {
1068 bool notify = true;
1069 target->GetImageSearchPathList().Clear(notify);
1070 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1071 } else {
1072 result.AppendError("invalid target\n");
1073 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001074 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001075 return result.Succeeded();
1076 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001077};
1078
Greg Claytoneffe5c92011-05-03 22:09:39 +00001079#pragma mark CommandObjectTargetModulesSearchPathsInsert
1080
Kate Stoneb9c1b512016-09-06 20:57:50 +00001081class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001082public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001083 CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
1084 : CommandObjectParsed(interpreter, "target modules search-paths insert",
1085 "Insert a new image search path substitution pair "
1086 "into the current target at the specified index.",
1087 nullptr) {
1088 CommandArgumentEntry arg1;
1089 CommandArgumentEntry arg2;
1090 CommandArgumentData index_arg;
1091 CommandArgumentData old_prefix_arg;
1092 CommandArgumentData new_prefix_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001093
Kate Stoneb9c1b512016-09-06 20:57:50 +00001094 // Define the first and only variant of this arg.
1095 index_arg.arg_type = eArgTypeIndex;
1096 index_arg.arg_repetition = eArgRepeatPlain;
Caroline Tice405fe672010-10-04 22:28:36 +00001097
Kate Stoneb9c1b512016-09-06 20:57:50 +00001098 // Put the one and only variant into the first arg for m_arguments:
1099 arg1.push_back(index_arg);
Caroline Tice405fe672010-10-04 22:28:36 +00001100
Kate Stoneb9c1b512016-09-06 20:57:50 +00001101 // Define the first variant of this arg pair.
1102 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1103 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001104
Kate Stoneb9c1b512016-09-06 20:57:50 +00001105 // Define the first variant of this arg pair.
1106 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1107 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001108
Kate Stoneb9c1b512016-09-06 20:57:50 +00001109 // There are two required arguments that must always occur together, i.e. an
1110 // argument "pair". Because they
1111 // must always occur together, they are treated as two variants of one
1112 // argument rather than two independent
1113 // arguments. Push them both into the same argument position for
1114 // m_arguments...
Caroline Tice405fe672010-10-04 22:28:36 +00001115
Kate Stoneb9c1b512016-09-06 20:57:50 +00001116 arg2.push_back(old_prefix_arg);
1117 arg2.push_back(new_prefix_arg);
Caroline Tice405fe672010-10-04 22:28:36 +00001118
Kate Stoneb9c1b512016-09-06 20:57:50 +00001119 // Add arguments to m_arguments.
1120 m_arguments.push_back(arg1);
1121 m_arguments.push_back(arg2);
1122 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001123
Kate Stoneb9c1b512016-09-06 20:57:50 +00001124 ~CommandObjectTargetModulesSearchPathsInsert() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001125
Jim Ingham5a988412012-06-08 21:56:10 +00001126protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001127 bool DoExecute(Args &command, CommandReturnObject &result) override {
1128 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1129 if (target) {
1130 size_t argc = command.GetArgumentCount();
1131 // check for at least 3 arguments and an odd number of parameters
1132 if (argc >= 3 && argc & 1) {
1133 bool success = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001134
Kate Stoneb9c1b512016-09-06 20:57:50 +00001135 uint32_t insert_idx = StringConvert::ToUInt32(
1136 command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001137
Kate Stoneb9c1b512016-09-06 20:57:50 +00001138 if (!success) {
1139 result.AppendErrorWithFormat(
1140 "<index> parameter is not an integer: '%s'.\n",
1141 command.GetArgumentAtIndex(0));
1142 result.SetStatus(eReturnStatusFailed);
1143 return result.Succeeded();
1144 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001145
Kate Stoneb9c1b512016-09-06 20:57:50 +00001146 // shift off the index
1147 command.Shift();
1148 argc = command.GetArgumentCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001149
Kate Stoneb9c1b512016-09-06 20:57:50 +00001150 for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1151 const char *from = command.GetArgumentAtIndex(i);
1152 const char *to = command.GetArgumentAtIndex(i + 1);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001153
Kate Stoneb9c1b512016-09-06 20:57:50 +00001154 if (from[0] && to[0]) {
1155 bool last_pair = ((argc - i) == 2);
1156 target->GetImageSearchPathList().Insert(
1157 ConstString(from), ConstString(to), insert_idx, last_pair);
1158 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1159 } else {
1160 if (from[0])
1161 result.AppendError("<path-prefix> can't be empty\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001162 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001163 result.AppendError("<new-path-prefix> can't be empty\n");
1164 result.SetStatus(eReturnStatusFailed);
1165 return false;
1166 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001167 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001168 } else {
1169 result.AppendError("insert requires at least three arguments\n");
1170 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001171 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001172 }
1173
1174 } else {
1175 result.AppendError("invalid target\n");
1176 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001177 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001178 return result.Succeeded();
1179 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001180};
1181
Greg Claytoneffe5c92011-05-03 22:09:39 +00001182#pragma mark CommandObjectTargetModulesSearchPathsList
1183
Kate Stoneb9c1b512016-09-06 20:57:50 +00001184class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001185public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001186 CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
1187 : CommandObjectParsed(interpreter, "target modules search-paths list",
1188 "List all current image search path substitution "
1189 "pairs in the current target.",
1190 "target modules search-paths list") {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001191
Kate Stoneb9c1b512016-09-06 20:57:50 +00001192 ~CommandObjectTargetModulesSearchPathsList() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001193
Jim Ingham5a988412012-06-08 21:56:10 +00001194protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001195 bool DoExecute(Args &command, CommandReturnObject &result) override {
1196 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1197 if (target) {
1198 if (command.GetArgumentCount() != 0) {
1199 result.AppendError("list takes no arguments\n");
1200 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001201 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001202 }
1203
1204 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1205 result.SetStatus(eReturnStatusSuccessFinishResult);
1206 } else {
1207 result.AppendError("invalid target\n");
1208 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001209 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001210 return result.Succeeded();
1211 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001212};
1213
Greg Claytoneffe5c92011-05-03 22:09:39 +00001214#pragma mark CommandObjectTargetModulesSearchPathsQuery
1215
Kate Stoneb9c1b512016-09-06 20:57:50 +00001216class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001217public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001218 CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
1219 : CommandObjectParsed(
1220 interpreter, "target modules search-paths query",
1221 "Transform a path using the first applicable image search path.",
1222 nullptr) {
1223 CommandArgumentEntry arg;
1224 CommandArgumentData path_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001225
Kate Stoneb9c1b512016-09-06 20:57:50 +00001226 // Define the first (and only) variant of this arg.
1227 path_arg.arg_type = eArgTypeDirectoryName;
1228 path_arg.arg_repetition = eArgRepeatPlain;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001229
Kate Stoneb9c1b512016-09-06 20:57:50 +00001230 // There is only one variant this argument could be; put it into the
1231 // argument entry.
1232 arg.push_back(path_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001233
Kate Stoneb9c1b512016-09-06 20:57:50 +00001234 // Push the data for the first argument into the m_arguments vector.
1235 m_arguments.push_back(arg);
1236 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001237
Kate Stoneb9c1b512016-09-06 20:57:50 +00001238 ~CommandObjectTargetModulesSearchPathsQuery() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001239
Jim Ingham5a988412012-06-08 21:56:10 +00001240protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001241 bool DoExecute(Args &command, CommandReturnObject &result) override {
1242 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1243 if (target) {
1244 if (command.GetArgumentCount() != 1) {
1245 result.AppendError("query requires one argument\n");
1246 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001247 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001248 }
1249
1250 ConstString orig(command.GetArgumentAtIndex(0));
1251 ConstString transformed;
1252 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1253 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1254 else
1255 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1256
1257 result.SetStatus(eReturnStatusSuccessFinishResult);
1258 } else {
1259 result.AppendError("invalid target\n");
1260 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001261 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001262 return result.Succeeded();
1263 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001264};
1265
Greg Claytoneffe5c92011-05-03 22:09:39 +00001266//----------------------------------------------------------------------
1267// Static Helper functions
1268//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001269static void DumpModuleArchitecture(Stream &strm, Module *module,
1270 bool full_triple, uint32_t width) {
1271 if (module) {
1272 StreamString arch_strm;
Todd Fiala7df337f2015-10-13 23:41:19 +00001273
Kate Stoneb9c1b512016-09-06 20:57:50 +00001274 if (full_triple)
1275 module->GetArchitecture().DumpTriple(arch_strm);
Greg Clayton3418c852011-08-10 02:10:13 +00001276 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001277 arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1278 std::string arch_str = arch_strm.GetString();
1279
1280 if (width)
1281 strm.Printf("%-*s", width, arch_str.c_str());
1282 else
1283 strm.PutCString(arch_str.c_str());
1284 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001285}
1286
Kate Stoneb9c1b512016-09-06 20:57:50 +00001287static void DumpModuleUUID(Stream &strm, Module *module) {
1288 if (module && module->GetUUID().IsValid())
1289 module->GetUUID().Dump(&strm);
1290 else
1291 strm.PutCString(" ");
Greg Claytoneffe5c92011-05-03 22:09:39 +00001292}
1293
Kate Stoneb9c1b512016-09-06 20:57:50 +00001294static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
1295 Stream &strm, Module *module,
1296 const FileSpec &file_spec,
1297 bool load_addresses) {
1298 uint32_t num_matches = 0;
1299 if (module) {
1300 SymbolContextList sc_list;
1301 num_matches = module->ResolveSymbolContextsForFileSpec(
1302 file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1303
1304 for (uint32_t i = 0; i < num_matches; ++i) {
1305 SymbolContext sc;
1306 if (sc_list.GetContextAtIndex(i, sc)) {
1307 if (i > 0)
1308 strm << "\n\n";
1309
1310 strm << "Line table for " << *static_cast<FileSpec *>(sc.comp_unit)
1311 << " in `" << module->GetFileSpec().GetFilename() << "\n";
1312 LineTable *line_table = sc.comp_unit->GetLineTable();
1313 if (line_table)
1314 line_table->GetDescription(
1315 &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1316 lldb::eDescriptionLevelBrief);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001317 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001318 strm << "No line table";
1319 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001320 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001321 }
1322 return num_matches;
1323}
1324
1325static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1326 uint32_t width) {
1327 if (file_spec_ptr) {
1328 if (width > 0) {
1329 std::string fullpath = file_spec_ptr->GetPath();
1330 strm.Printf("%-*s", width, fullpath.c_str());
1331 return;
1332 } else {
1333 file_spec_ptr->Dump(&strm);
1334 return;
1335 }
1336 }
1337 // Keep the width spacing correct if things go wrong...
1338 if (width > 0)
1339 strm.Printf("%-*s", width, "");
1340}
1341
1342static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1343 uint32_t width) {
1344 if (file_spec_ptr) {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001345 if (width > 0)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001346 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1347 else
1348 file_spec_ptr->GetDirectory().Dump(&strm);
1349 return;
1350 }
1351 // Keep the width spacing correct if things go wrong...
1352 if (width > 0)
1353 strm.Printf("%-*s", width, "");
Greg Claytoneffe5c92011-05-03 22:09:39 +00001354}
1355
Kate Stoneb9c1b512016-09-06 20:57:50 +00001356static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1357 uint32_t width) {
1358 if (file_spec_ptr) {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001359 if (width > 0)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001360 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1361 else
1362 file_spec_ptr->GetFilename().Dump(&strm);
1363 return;
1364 }
1365 // Keep the width spacing correct if things go wrong...
1366 if (width > 0)
1367 strm.Printf("%-*s", width, "");
Greg Claytoneffe5c92011-05-03 22:09:39 +00001368}
1369
Kate Stoneb9c1b512016-09-06 20:57:50 +00001370static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1371 size_t num_dumped = 0;
1372 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1373 const size_t num_modules = module_list.GetSize();
1374 if (num_modules > 0) {
1375 strm.Printf("Dumping headers for %" PRIu64 " module(s).\n",
1376 static_cast<uint64_t>(num_modules));
Greg Claytonc4a8a762012-05-15 18:43:44 +00001377 strm.IndentMore();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001378 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1379 Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
1380 if (module) {
1381 if (num_dumped++ > 0) {
1382 strm.EOL();
1383 strm.EOL();
1384 }
1385 ObjectFile *objfile = module->GetObjectFile();
1386 objfile->Dump(&strm);
1387 }
Greg Claytonc4a8a762012-05-15 18:43:44 +00001388 }
1389 strm.IndentLess();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001390 }
1391 return num_dumped;
Greg Claytonc4a8a762012-05-15 18:43:44 +00001392}
1393
Kate Stoneb9c1b512016-09-06 20:57:50 +00001394static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1395 Module *module, SortOrder sort_order) {
1396 if (module) {
1397 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1398 if (sym_vendor) {
1399 Symtab *symtab = sym_vendor->GetSymtab();
1400 if (symtab)
1401 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1402 sort_order);
1403 }
1404 }
1405}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001406
Kate Stoneb9c1b512016-09-06 20:57:50 +00001407static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1408 Module *module) {
1409 if (module) {
1410 SectionList *section_list = module->GetSectionList();
1411 if (section_list) {
1412 strm.Printf("Sections for '%s' (%s):\n",
1413 module->GetSpecificationDescription().c_str(),
1414 module->GetArchitecture().GetArchitectureName());
1415 strm.IndentMore();
1416 section_list->Dump(&strm,
1417 interpreter.GetExecutionContext().GetTargetPtr(), true,
1418 UINT32_MAX);
1419 strm.IndentLess();
1420 }
1421 }
1422}
1423
1424static bool DumpModuleSymbolVendor(Stream &strm, Module *module) {
1425 if (module) {
1426 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1427 if (symbol_vendor) {
1428 symbol_vendor->Dump(&strm);
1429 return true;
1430 }
1431 }
1432 return false;
1433}
1434
1435static void DumpAddress(ExecutionContextScope *exe_scope,
1436 const Address &so_addr, bool verbose, Stream &strm) {
1437 strm.IndentMore();
1438 strm.Indent(" Address: ");
1439 so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1440 strm.PutCString(" (");
1441 so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1442 strm.PutCString(")\n");
1443 strm.Indent(" Summary: ");
1444 const uint32_t save_indent = strm.GetIndentLevel();
1445 strm.SetIndentLevel(save_indent + 13);
1446 so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
1447 strm.SetIndentLevel(save_indent);
1448 // Print out detailed address information when verbose is enabled
1449 if (verbose) {
1450 strm.EOL();
1451 so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1452 }
1453 strm.IndentLess();
1454}
1455
1456static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1457 Module *module, uint32_t resolve_mask,
1458 lldb::addr_t raw_addr, lldb::addr_t offset,
1459 bool verbose) {
1460 if (module) {
1461 lldb::addr_t addr = raw_addr - offset;
1462 Address so_addr;
1463 SymbolContext sc;
1464 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1465 if (target && !target->GetSectionLoadList().IsEmpty()) {
1466 if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
1467 return false;
1468 else if (so_addr.GetModule().get() != module)
1469 return false;
1470 } else {
1471 if (!module->ResolveFileAddress(addr, so_addr))
1472 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001473 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001474
Kate Stoneb9c1b512016-09-06 20:57:50 +00001475 ExecutionContextScope *exe_scope =
1476 interpreter.GetExecutionContext().GetBestExecutionContextScope();
1477 DumpAddress(exe_scope, so_addr, verbose, strm);
1478 // strm.IndentMore();
1479 // strm.Indent (" Address: ");
1480 // so_addr.Dump (&strm, exe_scope,
1481 // Address::DumpStyleModuleWithFileAddress);
1482 // strm.PutCString (" (");
1483 // so_addr.Dump (&strm, exe_scope,
1484 // Address::DumpStyleSectionNameOffset);
1485 // strm.PutCString (")\n");
1486 // strm.Indent (" Summary: ");
1487 // const uint32_t save_indent = strm.GetIndentLevel ();
1488 // strm.SetIndentLevel (save_indent + 13);
1489 // so_addr.Dump (&strm, exe_scope,
1490 // Address::DumpStyleResolvedDescription);
1491 // strm.SetIndentLevel (save_indent);
1492 // // Print out detailed address information when verbose is enabled
1493 // if (verbose)
1494 // {
1495 // strm.EOL();
1496 // so_addr.Dump (&strm, exe_scope,
1497 // Address::DumpStyleDetailedSymbolContext);
1498 // }
1499 // strm.IndentLess();
1500 return true;
1501 }
1502
1503 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001504}
1505
Kate Stoneb9c1b512016-09-06 20:57:50 +00001506static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1507 Stream &strm, Module *module,
1508 const char *name, bool name_is_regex,
1509 bool verbose) {
1510 if (module) {
1511 SymbolContext sc;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001512
Kate Stoneb9c1b512016-09-06 20:57:50 +00001513 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1514 if (sym_vendor) {
1515 Symtab *symtab = sym_vendor->GetSymtab();
1516 if (symtab) {
1517 std::vector<uint32_t> match_indexes;
1518 ConstString symbol_name(name);
1519 uint32_t num_matches = 0;
1520 if (name_is_regex) {
Zachary Turner95eae422016-09-21 16:01:28 +00001521 RegularExpression name_regexp(symbol_name.GetStringRef());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001522 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1523 name_regexp, eSymbolTypeAny, match_indexes);
1524 } else {
1525 num_matches =
1526 symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1527 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001528
Kate Stoneb9c1b512016-09-06 20:57:50 +00001529 if (num_matches > 0) {
1530 strm.Indent();
1531 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1532 name_is_regex ? "the regular expression " : "", name);
1533 DumpFullpath(strm, &module->GetFileSpec(), 0);
1534 strm.PutCString(":\n");
1535 strm.IndentMore();
1536 for (uint32_t i = 0; i < num_matches; ++i) {
1537 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1538 if (symbol && symbol->ValueIsAddress()) {
1539 DumpAddress(interpreter.GetExecutionContext()
1540 .GetBestExecutionContextScope(),
1541 symbol->GetAddressRef(), verbose, strm);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001542 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001543 }
1544 strm.IndentLess();
1545 return num_matches;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001546 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001547 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001548 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001549 }
1550 return 0;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001551}
1552
Kate Stoneb9c1b512016-09-06 20:57:50 +00001553static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
1554 Stream &strm, SymbolContextList &sc_list,
1555 bool verbose) {
1556 strm.IndentMore();
Eugene Zelenkof13e6522016-02-25 19:02:39 +00001557
Kate Stoneb9c1b512016-09-06 20:57:50 +00001558 const uint32_t num_matches = sc_list.GetSize();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001559
Kate Stoneb9c1b512016-09-06 20:57:50 +00001560 for (uint32_t i = 0; i < num_matches; ++i) {
1561 SymbolContext sc;
1562 if (sc_list.GetContextAtIndex(i, sc)) {
1563 AddressRange range;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001564
Kate Stoneb9c1b512016-09-06 20:57:50 +00001565 sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001566
Kate Stoneb9c1b512016-09-06 20:57:50 +00001567 DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001568 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001569 }
1570 strm.IndentLess();
Greg Claytoneffe5c92011-05-03 22:09:39 +00001571}
1572
Kate Stoneb9c1b512016-09-06 20:57:50 +00001573static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
1574 Stream &strm, Module *module,
1575 const char *name, bool name_is_regex,
1576 bool include_inlines, bool include_symbols,
1577 bool verbose) {
1578 if (module && name && name[0]) {
1579 SymbolContextList sc_list;
1580 const bool append = true;
1581 size_t num_matches = 0;
1582 if (name_is_regex) {
Zachary Turner95eae422016-09-21 16:01:28 +00001583 RegularExpression function_name_regex((llvm::StringRef(name)));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001584 num_matches = module->FindFunctions(function_name_regex, include_symbols,
1585 include_inlines, append, sc_list);
1586 } else {
1587 ConstString function_name(name);
1588 num_matches = module->FindFunctions(
1589 function_name, nullptr, eFunctionNameTypeAuto, include_symbols,
1590 include_inlines, append, sc_list);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001591 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001592
Kate Stoneb9c1b512016-09-06 20:57:50 +00001593 if (num_matches) {
1594 strm.Indent();
1595 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1596 num_matches > 1 ? "es" : "");
1597 DumpFullpath(strm, &module->GetFileSpec(), 0);
1598 strm.PutCString(":\n");
1599 DumpSymbolContextList(
1600 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1601 strm, sc_list, verbose);
Sean Callanand38b4a92012-06-06 20:49:55 +00001602 }
1603 return num_matches;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001604 }
1605 return 0;
Sean Callanand38b4a92012-06-06 20:49:55 +00001606}
1607
Kate Stoneb9c1b512016-09-06 20:57:50 +00001608static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
1609 Module *module, const char *name_cstr,
1610 bool name_is_regex) {
1611 if (module && name_cstr && name_cstr[0]) {
1612 TypeList type_list;
1613 const uint32_t max_num_matches = UINT32_MAX;
1614 size_t num_matches = 0;
1615 bool name_is_fully_qualified = false;
1616 SymbolContext sc;
1617
1618 ConstString name(name_cstr);
1619 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1620 num_matches =
1621 module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches,
1622 searched_symbol_files, type_list);
1623
1624 if (num_matches) {
1625 strm.Indent();
1626 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1627 num_matches > 1 ? "es" : "");
1628 DumpFullpath(strm, &module->GetFileSpec(), 0);
1629 strm.PutCString(":\n");
1630 for (TypeSP type_sp : type_list.Types()) {
1631 if (type_sp) {
1632 // Resolve the clang type so that any forward references
1633 // to types that haven't yet been parsed will get parsed.
1634 type_sp->GetFullCompilerType();
1635 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1636 // Print all typedef chains
1637 TypeSP typedef_type_sp(type_sp);
1638 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1639 while (typedefed_type_sp) {
1640 strm.EOL();
1641 strm.Printf(" typedef '%s': ",
1642 typedef_type_sp->GetName().GetCString());
1643 typedefed_type_sp->GetFullCompilerType();
1644 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull,
1645 true);
1646 typedef_type_sp = typedefed_type_sp;
1647 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1648 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001649 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001650 strm.EOL();
1651 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001652 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001653 return num_matches;
1654 }
1655 return 0;
1656}
1657
1658static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
1659 const SymbolContext &sym_ctx,
1660 const char *name_cstr, bool name_is_regex) {
1661 if (!sym_ctx.module_sp)
Greg Claytoneffe5c92011-05-03 22:09:39 +00001662 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001663
1664 TypeList type_list;
1665 const uint32_t max_num_matches = UINT32_MAX;
1666 size_t num_matches = 1;
1667 bool name_is_fully_qualified = false;
1668
1669 ConstString name(name_cstr);
1670 llvm::DenseSet<SymbolFile *> searched_symbol_files;
1671 num_matches = sym_ctx.module_sp->FindTypes(
1672 sym_ctx, name, name_is_fully_qualified, max_num_matches,
1673 searched_symbol_files, type_list);
1674
1675 if (num_matches) {
1676 strm.Indent();
1677 strm.PutCString("Best match found in ");
1678 DumpFullpath(strm, &sym_ctx.module_sp->GetFileSpec(), 0);
1679 strm.PutCString(":\n");
1680
1681 TypeSP type_sp(type_list.GetTypeAtIndex(0));
1682 if (type_sp) {
1683 // Resolve the clang type so that any forward references
1684 // to types that haven't yet been parsed will get parsed.
1685 type_sp->GetFullCompilerType();
1686 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1687 // Print all typedef chains
1688 TypeSP typedef_type_sp(type_sp);
1689 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1690 while (typedefed_type_sp) {
1691 strm.EOL();
1692 strm.Printf(" typedef '%s': ",
1693 typedef_type_sp->GetName().GetCString());
1694 typedefed_type_sp->GetFullCompilerType();
1695 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1696 typedef_type_sp = typedefed_type_sp;
1697 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1698 }
1699 }
1700 strm.EOL();
1701 }
1702 return num_matches;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001703}
1704
Kate Stoneb9c1b512016-09-06 20:57:50 +00001705static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
1706 Stream &strm, Module *module,
1707 const FileSpec &file_spec,
1708 uint32_t line, bool check_inlines,
1709 bool verbose) {
1710 if (module && file_spec) {
1711 SymbolContextList sc_list;
1712 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1713 file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1714 if (num_matches > 0) {
1715 strm.Indent();
1716 strm.Printf("%u match%s found in ", num_matches,
1717 num_matches > 1 ? "es" : "");
1718 strm << file_spec;
1719 if (line > 0)
1720 strm.Printf(":%u", line);
1721 strm << " in ";
1722 DumpFullpath(strm, &module->GetFileSpec(), 0);
1723 strm.PutCString(":\n");
1724 DumpSymbolContextList(
1725 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1726 strm, sc_list, verbose);
1727 return num_matches;
Greg Clayton8ee64382011-11-10 01:18:58 +00001728 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001729 }
1730 return 0;
1731}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001732
Kate Stoneb9c1b512016-09-06 20:57:50 +00001733static size_t FindModulesByName(Target *target, const char *module_name,
1734 ModuleList &module_list,
1735 bool check_global_list) {
1736 FileSpec module_file_spec(module_name, false);
1737 ModuleSpec module_spec(module_file_spec);
1738
1739 const size_t initial_size = module_list.GetSize();
1740
1741 if (check_global_list) {
1742 // Check the global list
1743 std::lock_guard<std::recursive_mutex> guard(
1744 Module::GetAllocationModuleCollectionMutex());
1745 const size_t num_modules = Module::GetNumberAllocatedModules();
1746 ModuleSP module_sp;
1747 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1748 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1749
1750 if (module) {
1751 if (module->MatchesModuleSpec(module_spec)) {
1752 module_sp = module->shared_from_this();
1753 module_list.AppendIfNeeded(module_sp);
Greg Claytonf3156262012-07-11 20:46:47 +00001754 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001755 }
Greg Claytonf3156262012-07-11 20:46:47 +00001756 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001757 } else {
1758 if (target) {
1759 const size_t num_matches =
1760 target->GetImages().FindModules(module_spec, module_list);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001761
Kate Stoneb9c1b512016-09-06 20:57:50 +00001762 // Not found in our module list for our target, check the main
1763 // shared module list in case it is a extra file used somewhere
1764 // else
1765 if (num_matches == 0) {
1766 module_spec.GetArchitecture() = target->GetArchitecture();
1767 ModuleList::FindSharedModules(module_spec, module_list);
1768 }
1769 } else {
1770 ModuleList::FindSharedModules(module_spec, module_list);
1771 }
1772 }
1773
1774 return module_list.GetSize() - initial_size;
Greg Clayton8ee64382011-11-10 01:18:58 +00001775}
1776
Greg Claytoneffe5c92011-05-03 22:09:39 +00001777#pragma mark CommandObjectTargetModulesModuleAutoComplete
1778
1779//----------------------------------------------------------------------
1780// A base command object class that can auto complete with module file
1781// paths
1782//----------------------------------------------------------------------
1783
Kate Stoneb9c1b512016-09-06 20:57:50 +00001784class CommandObjectTargetModulesModuleAutoComplete
1785 : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001786public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001787 CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1788 const char *name,
1789 const char *help,
1790 const char *syntax)
1791 : CommandObjectParsed(interpreter, name, help, syntax) {
1792 CommandArgumentEntry arg;
1793 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001794
Kate Stoneb9c1b512016-09-06 20:57:50 +00001795 // Define the first (and only) variant of this arg.
1796 file_arg.arg_type = eArgTypeFilename;
1797 file_arg.arg_repetition = eArgRepeatStar;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001798
Kate Stoneb9c1b512016-09-06 20:57:50 +00001799 // There is only one variant this argument could be; put it into the
1800 // argument entry.
1801 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001802
Kate Stoneb9c1b512016-09-06 20:57:50 +00001803 // Push the data for the first argument into the m_arguments vector.
1804 m_arguments.push_back(arg);
1805 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001806
Kate Stoneb9c1b512016-09-06 20:57:50 +00001807 ~CommandObjectTargetModulesModuleAutoComplete() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001808
Kate Stoneb9c1b512016-09-06 20:57:50 +00001809 int HandleArgumentCompletion(Args &input, int &cursor_index,
1810 int &cursor_char_position,
1811 OptionElementVector &opt_element_vector,
1812 int match_start_point, int max_return_elements,
1813 bool &word_complete,
1814 StringList &matches) override {
1815 // Arguments are the standard module completer.
1816 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
1817 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001818
Kate Stoneb9c1b512016-09-06 20:57:50 +00001819 CommandCompletions::InvokeCommonCompletionCallbacks(
1820 GetCommandInterpreter(), CommandCompletions::eModuleCompletion,
1821 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
1822 word_complete, matches);
1823 return matches.GetSize();
1824 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001825};
1826
1827#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1828
1829//----------------------------------------------------------------------
1830// A base command object class that can auto complete with module source
1831// file paths
1832//----------------------------------------------------------------------
1833
Kate Stoneb9c1b512016-09-06 20:57:50 +00001834class CommandObjectTargetModulesSourceFileAutoComplete
1835 : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001836public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001837 CommandObjectTargetModulesSourceFileAutoComplete(
1838 CommandInterpreter &interpreter, const char *name, const char *help,
1839 const char *syntax, uint32_t flags)
1840 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1841 CommandArgumentEntry arg;
1842 CommandArgumentData source_file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001843
Kate Stoneb9c1b512016-09-06 20:57:50 +00001844 // Define the first (and only) variant of this arg.
1845 source_file_arg.arg_type = eArgTypeSourceFile;
1846 source_file_arg.arg_repetition = eArgRepeatPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001847
Kate Stoneb9c1b512016-09-06 20:57:50 +00001848 // There is only one variant this argument could be; put it into the
1849 // argument entry.
1850 arg.push_back(source_file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001851
Kate Stoneb9c1b512016-09-06 20:57:50 +00001852 // Push the data for the first argument into the m_arguments vector.
1853 m_arguments.push_back(arg);
1854 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001855
Kate Stoneb9c1b512016-09-06 20:57:50 +00001856 ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001857
Kate Stoneb9c1b512016-09-06 20:57:50 +00001858 int HandleArgumentCompletion(Args &input, int &cursor_index,
1859 int &cursor_char_position,
1860 OptionElementVector &opt_element_vector,
1861 int match_start_point, int max_return_elements,
1862 bool &word_complete,
1863 StringList &matches) override {
1864 // Arguments are the standard source file completer.
1865 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
1866 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001867
Kate Stoneb9c1b512016-09-06 20:57:50 +00001868 CommandCompletions::InvokeCommonCompletionCallbacks(
1869 GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
1870 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
1871 word_complete, matches);
1872 return matches.GetSize();
1873 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001874};
1875
Adrian McCarthy543725c2016-04-04 21:21:49 +00001876#pragma mark CommandObjectTargetModulesDumpObjfile
1877
Kate Stoneb9c1b512016-09-06 20:57:50 +00001878class CommandObjectTargetModulesDumpObjfile
1879 : public CommandObjectTargetModulesModuleAutoComplete {
Adrian McCarthy543725c2016-04-04 21:21:49 +00001880public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001881 CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
1882 : CommandObjectTargetModulesModuleAutoComplete(
1883 interpreter, "target modules dump objfile",
1884 "Dump the object file headers from one or more target modules.",
1885 nullptr) {}
Adrian McCarthy543725c2016-04-04 21:21:49 +00001886
Kate Stoneb9c1b512016-09-06 20:57:50 +00001887 ~CommandObjectTargetModulesDumpObjfile() override = default;
Adrian McCarthy543725c2016-04-04 21:21:49 +00001888
1889protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001890 bool DoExecute(Args &command, CommandReturnObject &result) override {
1891 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1892 if (target == nullptr) {
1893 result.AppendError("invalid target, create a debug target using the "
1894 "'target create' command");
1895 result.SetStatus(eReturnStatusFailed);
1896 return false;
Adrian McCarthy543725c2016-04-04 21:21:49 +00001897 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001898
1899 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1900 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1901 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1902
1903 size_t num_dumped = 0;
1904 if (command.GetArgumentCount() == 0) {
1905 // Dump all headers for all modules images
1906 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1907 target->GetImages());
1908 if (num_dumped == 0) {
1909 result.AppendError("the target has no associated executable images");
1910 result.SetStatus(eReturnStatusFailed);
1911 }
1912 } else {
1913 // Find the modules that match the basename or full path.
1914 ModuleList module_list;
1915 const char *arg_cstr;
1916 for (int arg_idx = 0;
1917 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1918 ++arg_idx) {
1919 size_t num_matched =
1920 FindModulesByName(target, arg_cstr, module_list, true);
1921 if (num_matched == 0) {
1922 result.AppendWarningWithFormat(
1923 "Unable to find an image that matches '%s'.\n", arg_cstr);
1924 }
1925 }
1926 // Dump all the modules we found.
1927 num_dumped =
1928 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1929 }
1930
1931 if (num_dumped > 0) {
1932 result.SetStatus(eReturnStatusSuccessFinishResult);
1933 } else {
1934 result.AppendError("no matching executable images found");
1935 result.SetStatus(eReturnStatusFailed);
1936 }
1937 return result.Succeeded();
1938 }
Adrian McCarthy543725c2016-04-04 21:21:49 +00001939};
1940
Greg Claytoneffe5c92011-05-03 22:09:39 +00001941#pragma mark CommandObjectTargetModulesDumpSymtab
1942
Kate Stoneb9c1b512016-09-06 20:57:50 +00001943class CommandObjectTargetModulesDumpSymtab
1944 : public CommandObjectTargetModulesModuleAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001945public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001946 CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
1947 : CommandObjectTargetModulesModuleAutoComplete(
1948 interpreter, "target modules dump symtab",
1949 "Dump the symbol table from one or more target modules.", nullptr),
1950 m_options() {}
1951
1952 ~CommandObjectTargetModulesDumpSymtab() override = default;
1953
1954 Options *GetOptions() override { return &m_options; }
1955
1956 class CommandOptions : public Options {
1957 public:
1958 CommandOptions() : Options(), m_sort_order(eSortOrderNone) {}
1959
1960 ~CommandOptions() override = default;
1961
1962 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
1963 ExecutionContext *execution_context) override {
1964 Error error;
1965 const int short_option = m_getopt_table[option_idx].val;
1966
1967 switch (short_option) {
1968 case 's':
1969 m_sort_order = (SortOrder)Args::StringToOptionEnum(
1970 option_arg, g_option_table[option_idx].enum_values, eSortOrderNone,
1971 error);
1972 break;
1973
1974 default:
1975 error.SetErrorStringWithFormat("invalid short option character '%c'",
1976 short_option);
1977 break;
1978 }
1979 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001980 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001981
Kate Stoneb9c1b512016-09-06 20:57:50 +00001982 void OptionParsingStarting(ExecutionContext *execution_context) override {
1983 m_sort_order = eSortOrderNone;
Jim Ingham5a988412012-06-08 21:56:10 +00001984 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001985
Kate Stoneb9c1b512016-09-06 20:57:50 +00001986 const OptionDefinition *GetDefinitions() override { return g_option_table; }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001987
Kate Stoneb9c1b512016-09-06 20:57:50 +00001988 // Options table: Required for subclasses of Options.
1989 static OptionDefinition g_option_table[];
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001990
Kate Stoneb9c1b512016-09-06 20:57:50 +00001991 SortOrder m_sort_order;
1992 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001993
Jim Ingham5a988412012-06-08 21:56:10 +00001994protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001995 bool DoExecute(Args &command, CommandReturnObject &result) override {
1996 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1997 if (target == nullptr) {
1998 result.AppendError("invalid target, create a debug target using the "
1999 "'target create' command");
2000 result.SetStatus(eReturnStatusFailed);
2001 return false;
2002 } else {
2003 uint32_t num_dumped = 0;
2004
2005 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2006 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2007 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2008
2009 if (command.GetArgumentCount() == 0) {
2010 // Dump all sections for all modules images
2011 std::lock_guard<std::recursive_mutex> guard(
2012 target->GetImages().GetMutex());
2013 const size_t num_modules = target->GetImages().GetSize();
2014 if (num_modules > 0) {
2015 result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
2016 " modules.\n",
2017 (uint64_t)num_modules);
2018 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2019 if (num_dumped > 0) {
2020 result.GetOutputStream().EOL();
2021 result.GetOutputStream().EOL();
2022 }
2023 num_dumped++;
2024 DumpModuleSymtab(
2025 m_interpreter, result.GetOutputStream(),
2026 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2027 m_options.m_sort_order);
2028 }
2029 } else {
2030 result.AppendError("the target has no associated executable images");
2031 result.SetStatus(eReturnStatusFailed);
2032 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002033 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002034 } else {
2035 // Dump specified images (by basename or fullpath)
2036 const char *arg_cstr;
2037 for (int arg_idx = 0;
2038 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2039 ++arg_idx) {
2040 ModuleList module_list;
2041 const size_t num_matches =
2042 FindModulesByName(target, arg_cstr, module_list, true);
2043 if (num_matches > 0) {
2044 for (size_t i = 0; i < num_matches; ++i) {
2045 Module *module = module_list.GetModulePointerAtIndex(i);
2046 if (module) {
2047 if (num_dumped > 0) {
2048 result.GetOutputStream().EOL();
2049 result.GetOutputStream().EOL();
Greg Claytoneffe5c92011-05-03 22:09:39 +00002050 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002051 num_dumped++;
2052 DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2053 module, m_options.m_sort_order);
2054 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002055 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002056 } else
2057 result.AppendWarningWithFormat(
2058 "Unable to find an image that matches '%s'.\n", arg_cstr);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002059 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002060 }
2061
2062 if (num_dumped > 0)
2063 result.SetStatus(eReturnStatusSuccessFinishResult);
2064 else {
2065 result.AppendError("no matching executable images found");
2066 result.SetStatus(eReturnStatusFailed);
2067 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002068 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002069 return result.Succeeded();
2070 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002071
Kate Stoneb9c1b512016-09-06 20:57:50 +00002072 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002073};
2074
Kate Stoneb9c1b512016-09-06 20:57:50 +00002075static OptionEnumValueElement g_sort_option_enumeration[4] = {
2076 {eSortOrderNone, "none",
2077 "No sorting, use the original symbol table order."},
2078 {eSortOrderByAddress, "address", "Sort output by symbol address."},
2079 {eSortOrderByName, "name", "Sort output by symbol name."},
2080 {0, nullptr, nullptr}};
Greg Claytoneffe5c92011-05-03 22:09:39 +00002081
Greg Claytoneffe5c92011-05-03 22:09:39 +00002082OptionDefinition
Kate Stoneb9c1b512016-09-06 20:57:50 +00002083 CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] = {
2084 // clang-format off
Kate Stoneac9c3a62016-08-26 23:28:47 +00002085 {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."},
2086 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
Kate Stoneb9c1b512016-09-06 20:57:50 +00002087 // clang-format on
Greg Claytoneffe5c92011-05-03 22:09:39 +00002088};
2089
2090#pragma mark CommandObjectTargetModulesDumpSections
2091
2092//----------------------------------------------------------------------
2093// Image section dumping command
2094//----------------------------------------------------------------------
2095
Kate Stoneb9c1b512016-09-06 20:57:50 +00002096class CommandObjectTargetModulesDumpSections
2097 : public CommandObjectTargetModulesModuleAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002098public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002099 CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
2100 : CommandObjectTargetModulesModuleAutoComplete(
2101 interpreter, "target modules dump sections",
2102 "Dump the sections from one or more target modules.",
2103 //"target modules dump sections [<file1> ...]")
2104 nullptr) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002105
Kate Stoneb9c1b512016-09-06 20:57:50 +00002106 ~CommandObjectTargetModulesDumpSections() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002107
Jim Ingham5a988412012-06-08 21:56:10 +00002108protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002109 bool DoExecute(Args &command, CommandReturnObject &result) override {
2110 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2111 if (target == nullptr) {
2112 result.AppendError("invalid target, create a debug target using the "
2113 "'target create' command");
2114 result.SetStatus(eReturnStatusFailed);
2115 return false;
2116 } else {
2117 uint32_t num_dumped = 0;
2118
2119 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2120 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2121 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2122
2123 if (command.GetArgumentCount() == 0) {
2124 // Dump all sections for all modules images
2125 const size_t num_modules = target->GetImages().GetSize();
2126 if (num_modules > 0) {
2127 result.GetOutputStream().Printf("Dumping sections for %" PRIu64
2128 " modules.\n",
2129 (uint64_t)num_modules);
2130 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2131 num_dumped++;
2132 DumpModuleSections(
2133 m_interpreter, result.GetOutputStream(),
2134 target->GetImages().GetModulePointerAtIndex(image_idx));
2135 }
2136 } else {
2137 result.AppendError("the target has no associated executable images");
2138 result.SetStatus(eReturnStatusFailed);
2139 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002140 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002141 } else {
2142 // Dump specified images (by basename or fullpath)
2143 const char *arg_cstr;
2144 for (int arg_idx = 0;
2145 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2146 ++arg_idx) {
2147 ModuleList module_list;
2148 const size_t num_matches =
2149 FindModulesByName(target, arg_cstr, module_list, true);
2150 if (num_matches > 0) {
2151 for (size_t i = 0; i < num_matches; ++i) {
2152 Module *module = module_list.GetModulePointerAtIndex(i);
2153 if (module) {
2154 num_dumped++;
2155 DumpModuleSections(m_interpreter, result.GetOutputStream(),
2156 module);
2157 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002158 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002159 } else {
2160 // Check the global list
2161 std::lock_guard<std::recursive_mutex> guard(
2162 Module::GetAllocationModuleCollectionMutex());
Greg Clayton8ee64382011-11-10 01:18:58 +00002163
Kate Stoneb9c1b512016-09-06 20:57:50 +00002164 result.AppendWarningWithFormat(
2165 "Unable to find an image that matches '%s'.\n", arg_cstr);
2166 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002167 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002168 }
2169
2170 if (num_dumped > 0)
2171 result.SetStatus(eReturnStatusSuccessFinishResult);
2172 else {
2173 result.AppendError("no matching executable images found");
2174 result.SetStatus(eReturnStatusFailed);
2175 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002176 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002177 return result.Succeeded();
2178 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002179};
2180
Greg Claytoneffe5c92011-05-03 22:09:39 +00002181#pragma mark CommandObjectTargetModulesDumpSymfile
2182
2183//----------------------------------------------------------------------
2184// Image debug symbol dumping command
2185//----------------------------------------------------------------------
2186
Kate Stoneb9c1b512016-09-06 20:57:50 +00002187class CommandObjectTargetModulesDumpSymfile
2188 : public CommandObjectTargetModulesModuleAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002189public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002190 CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
2191 : CommandObjectTargetModulesModuleAutoComplete(
2192 interpreter, "target modules dump symfile",
2193 "Dump the debug symbol file for one or more target modules.",
2194 //"target modules dump symfile [<file1> ...]")
2195 nullptr) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002196
Kate Stoneb9c1b512016-09-06 20:57:50 +00002197 ~CommandObjectTargetModulesDumpSymfile() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002198
Jim Ingham5a988412012-06-08 21:56:10 +00002199protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002200 bool DoExecute(Args &command, CommandReturnObject &result) override {
2201 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2202 if (target == nullptr) {
2203 result.AppendError("invalid target, create a debug target using the "
2204 "'target create' command");
2205 result.SetStatus(eReturnStatusFailed);
2206 return false;
2207 } else {
2208 uint32_t num_dumped = 0;
2209
2210 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2211 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2212 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2213
2214 if (command.GetArgumentCount() == 0) {
2215 // Dump all sections for all modules images
2216 const ModuleList &target_modules = target->GetImages();
2217 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2218 const size_t num_modules = target_modules.GetSize();
2219 if (num_modules > 0) {
2220 result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
2221 " modules.\n",
2222 (uint64_t)num_modules);
2223 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2224 if (DumpModuleSymbolVendor(
2225 result.GetOutputStream(),
2226 target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2227 num_dumped++;
2228 }
2229 } else {
2230 result.AppendError("the target has no associated executable images");
2231 result.SetStatus(eReturnStatusFailed);
2232 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002233 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002234 } else {
2235 // Dump specified images (by basename or fullpath)
2236 const char *arg_cstr;
2237 for (int arg_idx = 0;
2238 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2239 ++arg_idx) {
2240 ModuleList module_list;
2241 const size_t num_matches =
2242 FindModulesByName(target, arg_cstr, module_list, true);
2243 if (num_matches > 0) {
2244 for (size_t i = 0; i < num_matches; ++i) {
2245 Module *module = module_list.GetModulePointerAtIndex(i);
2246 if (module) {
2247 if (DumpModuleSymbolVendor(result.GetOutputStream(), module))
2248 num_dumped++;
2249 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002250 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002251 } else
2252 result.AppendWarningWithFormat(
2253 "Unable to find an image that matches '%s'.\n", arg_cstr);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002254 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002255 }
2256
2257 if (num_dumped > 0)
2258 result.SetStatus(eReturnStatusSuccessFinishResult);
2259 else {
2260 result.AppendError("no matching executable images found");
2261 result.SetStatus(eReturnStatusFailed);
2262 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002263 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002264 return result.Succeeded();
2265 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002266};
2267
Greg Claytoneffe5c92011-05-03 22:09:39 +00002268#pragma mark CommandObjectTargetModulesDumpLineTable
2269
2270//----------------------------------------------------------------------
2271// Image debug line table dumping command
2272//----------------------------------------------------------------------
2273
Kate Stoneb9c1b512016-09-06 20:57:50 +00002274class CommandObjectTargetModulesDumpLineTable
2275 : public CommandObjectTargetModulesSourceFileAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002276public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002277 CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
2278 : CommandObjectTargetModulesSourceFileAutoComplete(
2279 interpreter, "target modules dump line-table",
2280 "Dump the line table for one or more compilation units.", nullptr,
2281 eCommandRequiresTarget) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002282
Kate Stoneb9c1b512016-09-06 20:57:50 +00002283 ~CommandObjectTargetModulesDumpLineTable() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002284
Jim Ingham5a988412012-06-08 21:56:10 +00002285protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002286 bool DoExecute(Args &command, CommandReturnObject &result) override {
2287 Target *target = m_exe_ctx.GetTargetPtr();
2288 uint32_t total_num_dumped = 0;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002289
Kate Stoneb9c1b512016-09-06 20:57:50 +00002290 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2291 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2292 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002293
Kate Stoneb9c1b512016-09-06 20:57:50 +00002294 if (command.GetArgumentCount() == 0) {
2295 result.AppendError("file option must be specified.");
2296 result.SetStatus(eReturnStatusFailed);
2297 return result.Succeeded();
2298 } else {
2299 // Dump specified images (by basename or fullpath)
2300 const char *arg_cstr;
2301 for (int arg_idx = 0;
2302 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2303 ++arg_idx) {
2304 FileSpec file_spec(arg_cstr, false);
2305
2306 const ModuleList &target_modules = target->GetImages();
2307 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2308 const size_t num_modules = target_modules.GetSize();
2309 if (num_modules > 0) {
2310 uint32_t num_dumped = 0;
2311 for (uint32_t i = 0; i < num_modules; ++i) {
2312 if (DumpCompileUnitLineTable(
2313 m_interpreter, result.GetOutputStream(),
2314 target_modules.GetModulePointerAtIndexUnlocked(i),
2315 file_spec, m_exe_ctx.GetProcessPtr() &&
2316 m_exe_ctx.GetProcessRef().IsAlive()))
2317 num_dumped++;
2318 }
2319 if (num_dumped == 0)
2320 result.AppendWarningWithFormat(
2321 "No source filenames matched '%s'.\n", arg_cstr);
2322 else
2323 total_num_dumped += num_dumped;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002324 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002325 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002326 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002327
2328 if (total_num_dumped > 0)
2329 result.SetStatus(eReturnStatusSuccessFinishResult);
2330 else {
2331 result.AppendError("no source filenames matched any command arguments");
2332 result.SetStatus(eReturnStatusFailed);
2333 }
2334 return result.Succeeded();
2335 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002336};
2337
Greg Claytoneffe5c92011-05-03 22:09:39 +00002338#pragma mark CommandObjectTargetModulesDump
2339
2340//----------------------------------------------------------------------
2341// Dump multi-word command for target modules
2342//----------------------------------------------------------------------
2343
Kate Stoneb9c1b512016-09-06 20:57:50 +00002344class CommandObjectTargetModulesDump : public CommandObjectMultiword {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002345public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002346 //------------------------------------------------------------------
2347 // Constructors and Destructors
2348 //------------------------------------------------------------------
2349 CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2350 : CommandObjectMultiword(interpreter, "target modules dump",
2351 "Commands for dumping information about one or "
2352 "more target modules.",
2353 "target modules dump "
2354 "[headers|symtab|sections|symfile|line-table] "
2355 "[<file1> <file2> ...]") {
2356 LoadSubCommand("objfile",
2357 CommandObjectSP(
2358 new CommandObjectTargetModulesDumpObjfile(interpreter)));
2359 LoadSubCommand(
2360 "symtab",
2361 CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
2362 LoadSubCommand("sections",
2363 CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2364 interpreter)));
2365 LoadSubCommand("symfile",
2366 CommandObjectSP(
2367 new CommandObjectTargetModulesDumpSymfile(interpreter)));
2368 LoadSubCommand("line-table",
2369 CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2370 interpreter)));
2371 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002372
Kate Stoneb9c1b512016-09-06 20:57:50 +00002373 ~CommandObjectTargetModulesDump() override = default;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002374};
2375
Kate Stoneb9c1b512016-09-06 20:57:50 +00002376class CommandObjectTargetModulesAdd : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002377public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002378 CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
2379 : CommandObjectParsed(interpreter, "target modules add",
2380 "Add a new module to the current target's modules.",
2381 "target modules add [<module>]"),
Todd Fialae1cfbc72016-08-11 23:51:28 +00002382 m_option_group(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00002383 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2384 eArgTypeFilename, "Fullpath to a stand alone debug "
2385 "symbols file for when debug symbols "
2386 "are not in the executable.") {
2387 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2388 LLDB_OPT_SET_1);
2389 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2390 m_option_group.Finalize();
2391 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002392
Kate Stoneb9c1b512016-09-06 20:57:50 +00002393 ~CommandObjectTargetModulesAdd() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002394
Kate Stoneb9c1b512016-09-06 20:57:50 +00002395 Options *GetOptions() override { return &m_option_group; }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002396
Kate Stoneb9c1b512016-09-06 20:57:50 +00002397 int HandleArgumentCompletion(Args &input, int &cursor_index,
2398 int &cursor_char_position,
2399 OptionElementVector &opt_element_vector,
2400 int match_start_point, int max_return_elements,
2401 bool &word_complete,
2402 StringList &matches) override {
2403 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
2404 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002405
Kate Stoneb9c1b512016-09-06 20:57:50 +00002406 CommandCompletions::InvokeCommonCompletionCallbacks(
2407 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2408 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
2409 word_complete, matches);
2410 return matches.GetSize();
2411 }
Jim Ingham5a988412012-06-08 21:56:10 +00002412
2413protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002414 OptionGroupOptions m_option_group;
2415 OptionGroupUUID m_uuid_option_group;
2416 OptionGroupFile m_symbol_file;
Greg Clayton50a24bd2012-11-29 22:16:27 +00002417
Kate Stoneb9c1b512016-09-06 20:57:50 +00002418 bool DoExecute(Args &args, CommandReturnObject &result) override {
2419 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2420 if (target == nullptr) {
2421 result.AppendError("invalid target, create a debug target using the "
2422 "'target create' command");
2423 result.SetStatus(eReturnStatusFailed);
2424 return false;
2425 } else {
2426 bool flush = false;
2427
2428 const size_t argc = args.GetArgumentCount();
2429 if (argc == 0) {
2430 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2431 // We are given a UUID only, go locate the file
2432 ModuleSpec module_spec;
2433 module_spec.GetUUID() =
2434 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2435 if (m_symbol_file.GetOptionValue().OptionWasSet())
2436 module_spec.GetSymbolFileSpec() =
2437 m_symbol_file.GetOptionValue().GetCurrentValue();
2438 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
2439 ModuleSP module_sp(target->GetSharedModule(module_spec));
2440 if (module_sp) {
2441 result.SetStatus(eReturnStatusSuccessFinishResult);
2442 return true;
2443 } else {
2444 StreamString strm;
2445 module_spec.GetUUID().Dump(&strm);
2446 if (module_spec.GetFileSpec()) {
2447 if (module_spec.GetSymbolFileSpec()) {
2448 result.AppendErrorWithFormat(
2449 "Unable to create the executable or symbol file with "
2450 "UUID %s with path %s and symbol file %s",
2451 strm.GetString().c_str(),
2452 module_spec.GetFileSpec().GetPath().c_str(),
2453 module_spec.GetSymbolFileSpec().GetPath().c_str());
2454 } else {
2455 result.AppendErrorWithFormat(
2456 "Unable to create the executable or symbol file with "
2457 "UUID %s with path %s",
2458 strm.GetString().c_str(),
2459 module_spec.GetFileSpec().GetPath().c_str());
2460 }
2461 } else {
2462 result.AppendErrorWithFormat("Unable to create the executable "
2463 "or symbol file with UUID %s",
2464 strm.GetString().c_str());
2465 }
2466 result.SetStatus(eReturnStatusFailed);
2467 return false;
2468 }
2469 } else {
2470 StreamString strm;
2471 module_spec.GetUUID().Dump(&strm);
2472 result.AppendErrorWithFormat(
2473 "Unable to locate the executable or symbol file with UUID %s",
2474 strm.GetString().c_str());
2475 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002476 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002477 }
2478 } else {
2479 result.AppendError(
2480 "one or more executable image paths must be specified");
2481 result.SetStatus(eReturnStatusFailed);
2482 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002483 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002484 } else {
2485 for (size_t i = 0; i < argc; ++i) {
2486 const char *path = args.GetArgumentAtIndex(i);
2487 if (path) {
2488 FileSpec file_spec(path, true);
2489 if (file_spec.Exists()) {
2490 ModuleSpec module_spec(file_spec);
2491 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2492 module_spec.GetUUID() =
2493 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2494 if (m_symbol_file.GetOptionValue().OptionWasSet())
2495 module_spec.GetSymbolFileSpec() =
2496 m_symbol_file.GetOptionValue().GetCurrentValue();
2497 if (!module_spec.GetArchitecture().IsValid())
2498 module_spec.GetArchitecture() = target->GetArchitecture();
2499 Error error;
2500 ModuleSP module_sp(target->GetSharedModule(module_spec, &error));
2501 if (!module_sp) {
2502 const char *error_cstr = error.AsCString();
2503 if (error_cstr)
2504 result.AppendError(error_cstr);
Greg Clayton50a24bd2012-11-29 22:16:27 +00002505 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00002506 result.AppendErrorWithFormat("unsupported module: %s", path);
2507 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002508 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002509 } else {
2510 flush = true;
2511 }
2512 result.SetStatus(eReturnStatusSuccessFinishResult);
2513 } else {
2514 char resolved_path[PATH_MAX];
2515 result.SetStatus(eReturnStatusFailed);
2516 if (file_spec.GetPath(resolved_path, sizeof(resolved_path))) {
2517 if (strcmp(resolved_path, path) != 0) {
2518 result.AppendErrorWithFormat(
2519 "invalid module path '%s' with resolved path '%s'\n",
2520 path, resolved_path);
2521 break;
2522 }
2523 }
2524 result.AppendErrorWithFormat("invalid module path '%s'\n", path);
2525 break;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002526 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002527 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002528 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002529 }
2530
2531 if (flush) {
2532 ProcessSP process = target->GetProcessSP();
2533 if (process)
2534 process->Flush();
2535 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002536 }
2537
Kate Stoneb9c1b512016-09-06 20:57:50 +00002538 return result.Succeeded();
2539 }
2540};
2541
2542class CommandObjectTargetModulesLoad
2543 : public CommandObjectTargetModulesModuleAutoComplete {
2544public:
2545 CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
2546 : CommandObjectTargetModulesModuleAutoComplete(
2547 interpreter, "target modules load", "Set the load addresses for "
2548 "one or more sections in a "
2549 "target module.",
2550 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2551 "<address> [<sect-name> <address> ....]"),
2552 m_option_group(),
2553 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2554 "Fullpath or basename for module to load.", ""),
2555 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2556 "Set the load address for all sections to be the "
2557 "virtual address in the file plus the offset.",
2558 0) {
2559 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2560 LLDB_OPT_SET_1);
2561 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2562 m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2563 m_option_group.Finalize();
2564 }
2565
2566 ~CommandObjectTargetModulesLoad() override = default;
2567
2568 Options *GetOptions() override { return &m_option_group; }
2569
2570protected:
2571 bool DoExecute(Args &args, CommandReturnObject &result) override {
2572 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2573 if (target == nullptr) {
2574 result.AppendError("invalid target, create a debug target using the "
2575 "'target create' command");
2576 result.SetStatus(eReturnStatusFailed);
2577 return false;
2578 } else {
2579 const size_t argc = args.GetArgumentCount();
2580 ModuleSpec module_spec;
2581 bool search_using_module_spec = false;
2582 if (m_file_option.GetOptionValue().OptionWasSet()) {
2583 search_using_module_spec = true;
2584 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2585 const bool use_global_module_list = true;
2586 ModuleList module_list;
2587 const size_t num_matches = FindModulesByName(
2588 target, arg_cstr, module_list, use_global_module_list);
2589 if (num_matches == 1) {
2590 module_spec.GetFileSpec() =
2591 module_list.GetModuleAtIndex(0)->GetFileSpec();
2592 } else if (num_matches > 1) {
2593 search_using_module_spec = false;
2594 result.AppendErrorWithFormat(
2595 "more than 1 module matched by name '%s'\n", arg_cstr);
2596 result.SetStatus(eReturnStatusFailed);
2597 } else {
2598 search_using_module_spec = false;
2599 result.AppendErrorWithFormat("no object file for module '%s'\n",
2600 arg_cstr);
2601 result.SetStatus(eReturnStatusFailed);
2602 }
2603 }
2604
2605 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2606 search_using_module_spec = true;
2607 module_spec.GetUUID() =
2608 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2609 }
2610
2611 if (search_using_module_spec) {
2612 ModuleList matching_modules;
2613 const size_t num_matches =
2614 target->GetImages().FindModules(module_spec, matching_modules);
2615
2616 char path[PATH_MAX];
2617 if (num_matches == 1) {
2618 Module *module = matching_modules.GetModulePointerAtIndex(0);
2619 if (module) {
2620 ObjectFile *objfile = module->GetObjectFile();
2621 if (objfile) {
2622 SectionList *section_list = module->GetSectionList();
2623 if (section_list) {
2624 bool changed = false;
2625 if (argc == 0) {
2626 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2627 const addr_t slide =
2628 m_slide_option.GetOptionValue().GetCurrentValue();
2629 const bool slide_is_offset = true;
2630 module->SetLoadAddress(*target, slide, slide_is_offset,
2631 changed);
2632 } else {
2633 result.AppendError("one or more section name + load "
2634 "address pair must be specified");
2635 result.SetStatus(eReturnStatusFailed);
2636 return false;
2637 }
2638 } else {
2639 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2640 result.AppendError("The \"--slide <offset>\" option can't "
2641 "be used in conjunction with setting "
2642 "section load addresses.\n");
2643 result.SetStatus(eReturnStatusFailed);
2644 return false;
2645 }
2646
2647 for (size_t i = 0; i < argc; i += 2) {
2648 const char *sect_name = args.GetArgumentAtIndex(i);
2649 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2650 if (sect_name && load_addr_cstr) {
2651 ConstString const_sect_name(sect_name);
2652 bool success = false;
2653 addr_t load_addr = StringConvert::ToUInt64(
2654 load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2655 if (success) {
2656 SectionSP section_sp(
2657 section_list->FindSectionByName(const_sect_name));
2658 if (section_sp) {
2659 if (section_sp->IsThreadSpecific()) {
2660 result.AppendErrorWithFormat(
2661 "thread specific sections are not yet "
2662 "supported (section '%s')\n",
2663 sect_name);
2664 result.SetStatus(eReturnStatusFailed);
2665 break;
2666 } else {
2667 if (target->GetSectionLoadList()
2668 .SetSectionLoadAddress(section_sp,
2669 load_addr))
2670 changed = true;
2671 result.AppendMessageWithFormat(
2672 "section '%s' loaded at 0x%" PRIx64 "\n",
2673 sect_name, load_addr);
2674 }
2675 } else {
2676 result.AppendErrorWithFormat("no section found that "
2677 "matches the section "
2678 "name '%s'\n",
2679 sect_name);
2680 result.SetStatus(eReturnStatusFailed);
2681 break;
2682 }
2683 } else {
2684 result.AppendErrorWithFormat(
2685 "invalid load address string '%s'\n",
2686 load_addr_cstr);
2687 result.SetStatus(eReturnStatusFailed);
2688 break;
2689 }
2690 } else {
2691 if (sect_name)
2692 result.AppendError("section names must be followed by "
2693 "a load address.\n");
2694 else
2695 result.AppendError("one or more section name + load "
2696 "address pair must be specified.\n");
2697 result.SetStatus(eReturnStatusFailed);
2698 break;
2699 }
2700 }
2701 }
2702
2703 if (changed) {
2704 target->ModulesDidLoad(matching_modules);
2705 Process *process = m_exe_ctx.GetProcessPtr();
2706 if (process)
2707 process->Flush();
2708 }
2709 } else {
2710 module->GetFileSpec().GetPath(path, sizeof(path));
2711 result.AppendErrorWithFormat(
2712 "no sections in object file '%s'\n", path);
2713 result.SetStatus(eReturnStatusFailed);
2714 }
2715 } else {
2716 module->GetFileSpec().GetPath(path, sizeof(path));
2717 result.AppendErrorWithFormat("no object file for module '%s'\n",
2718 path);
2719 result.SetStatus(eReturnStatusFailed);
2720 }
2721 } else {
2722 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2723 if (module_spec_file) {
2724 module_spec_file->GetPath(path, sizeof(path));
2725 result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2726 } else
2727 result.AppendError("no module spec");
2728 result.SetStatus(eReturnStatusFailed);
2729 }
2730 } else {
2731 std::string uuid_str;
2732
2733 if (module_spec.GetFileSpec())
2734 module_spec.GetFileSpec().GetPath(path, sizeof(path));
2735 else
2736 path[0] = '\0';
2737
2738 if (module_spec.GetUUIDPtr())
2739 uuid_str = module_spec.GetUUID().GetAsString();
2740 if (num_matches > 1) {
2741 result.AppendErrorWithFormat(
2742 "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2743 path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2744 for (size_t i = 0; i < num_matches; ++i) {
2745 if (matching_modules.GetModulePointerAtIndex(i)
2746 ->GetFileSpec()
2747 .GetPath(path, sizeof(path)))
2748 result.AppendMessageWithFormat("%s\n", path);
2749 }
2750 } else {
2751 result.AppendErrorWithFormat(
2752 "no modules were found that match%s%s%s%s.\n",
2753 path[0] ? " file=" : "", path,
2754 !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2755 }
2756 result.SetStatus(eReturnStatusFailed);
2757 }
2758 } else {
2759 result.AppendError("either the \"--file <module>\" or the \"--uuid "
2760 "<uuid>\" option must be specified.\n");
2761 result.SetStatus(eReturnStatusFailed);
2762 return false;
2763 }
2764 }
2765 return result.Succeeded();
2766 }
2767
2768 OptionGroupOptions m_option_group;
2769 OptionGroupUUID m_uuid_option_group;
2770 OptionGroupString m_file_option;
2771 OptionGroupUInt64 m_slide_option;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002772};
2773
2774//----------------------------------------------------------------------
2775// List images with associated information
2776//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00002777class CommandObjectTargetModulesList : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002778public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002779 class CommandOptions : public Options {
2780 public:
2781 CommandOptions()
2782 : Options(), m_format_array(), m_use_global_module_list(false),
2783 m_module_addr(LLDB_INVALID_ADDRESS) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002784
Kate Stoneb9c1b512016-09-06 20:57:50 +00002785 ~CommandOptions() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002786
Kate Stoneb9c1b512016-09-06 20:57:50 +00002787 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
2788 ExecutionContext *execution_context) override {
2789 Error error;
Greg Claytonb9d5df52012-12-06 22:49:16 +00002790
Kate Stoneb9c1b512016-09-06 20:57:50 +00002791 const int short_option = m_getopt_table[option_idx].val;
2792 if (short_option == 'g') {
2793 m_use_global_module_list = true;
2794 } else if (short_option == 'a') {
2795 m_module_addr = Args::StringToAddress(execution_context, option_arg,
2796 LLDB_INVALID_ADDRESS, &error);
2797 } else {
2798 unsigned long width = 0;
2799 if (option_arg)
2800 width = strtoul(option_arg, nullptr, 0);
2801 m_format_array.push_back(std::make_pair(short_option, width));
2802 }
2803 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002804 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002805
Kate Stoneb9c1b512016-09-06 20:57:50 +00002806 void OptionParsingStarting(ExecutionContext *execution_context) override {
2807 m_format_array.clear();
2808 m_use_global_module_list = false;
2809 m_module_addr = LLDB_INVALID_ADDRESS;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002810 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002811
Kate Stoneb9c1b512016-09-06 20:57:50 +00002812 const OptionDefinition *GetDefinitions() override { return g_option_table; }
2813
2814 // Options table: Required for subclasses of Options.
2815
2816 static OptionDefinition g_option_table[];
2817
2818 // Instance variables to hold the values for command options.
2819 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
2820 FormatWidthCollection m_format_array;
2821 bool m_use_global_module_list;
2822 lldb::addr_t m_module_addr;
2823 };
2824
2825 CommandObjectTargetModulesList(CommandInterpreter &interpreter)
2826 : CommandObjectParsed(
2827 interpreter, "target modules list",
2828 "List current executable and dependent shared library images.",
2829 "target modules list [<cmd-options>]"),
2830 m_options() {}
2831
2832 ~CommandObjectTargetModulesList() override = default;
2833
2834 Options *GetOptions() override { return &m_options; }
2835
Jim Ingham5a988412012-06-08 21:56:10 +00002836protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002837 bool DoExecute(Args &command, CommandReturnObject &result) override {
2838 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2839 const bool use_global_module_list = m_options.m_use_global_module_list;
2840 // Define a local module list here to ensure it lives longer than any
2841 // "locker"
2842 // object which might lock its contents below (through the "module_list_ptr"
2843 // variable).
2844 ModuleList module_list;
2845 if (target == nullptr && !use_global_module_list) {
2846 result.AppendError("invalid target, create a debug target using the "
2847 "'target create' command");
2848 result.SetStatus(eReturnStatusFailed);
2849 return false;
2850 } else {
2851 if (target) {
2852 uint32_t addr_byte_size =
2853 target->GetArchitecture().GetAddressByteSize();
2854 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2855 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2856 }
2857 // Dump all sections for all modules images
2858 Stream &strm = result.GetOutputStream();
2859
2860 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
2861 if (target) {
2862 Address module_address;
2863 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
2864 ModuleSP module_sp(module_address.GetModule());
2865 if (module_sp) {
2866 PrintModule(target, module_sp.get(), 0, strm);
2867 result.SetStatus(eReturnStatusSuccessFinishResult);
2868 } else {
2869 result.AppendErrorWithFormat(
2870 "Couldn't find module matching address: 0x%" PRIx64 ".",
2871 m_options.m_module_addr);
2872 result.SetStatus(eReturnStatusFailed);
Greg Clayton3418c852011-08-10 02:10:13 +00002873 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002874 } else {
2875 result.AppendErrorWithFormat(
2876 "Couldn't find module containing address: 0x%" PRIx64 ".",
2877 m_options.m_module_addr);
2878 result.SetStatus(eReturnStatusFailed);
2879 }
2880 } else {
2881 result.AppendError(
2882 "Can only look up modules by address with a valid target.");
2883 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002884 }
2885 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002886 }
Jim Inghamc10312c2011-10-24 18:36:33 +00002887
Kate Stoneb9c1b512016-09-06 20:57:50 +00002888 size_t num_modules = 0;
2889
2890 // This locker will be locked on the mutex in module_list_ptr if it is
2891 // non-nullptr.
2892 // Otherwise it will lock the AllocationModuleCollectionMutex when
2893 // accessing
2894 // the global module list directly.
2895 std::unique_lock<std::recursive_mutex> guard(
2896 Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
2897
2898 const ModuleList *module_list_ptr = nullptr;
2899 const size_t argc = command.GetArgumentCount();
2900 if (argc == 0) {
2901 if (use_global_module_list) {
2902 guard.lock();
2903 num_modules = Module::GetNumberAllocatedModules();
2904 } else {
2905 module_list_ptr = &target->GetImages();
Jim Ingham28eb5712012-10-12 17:34:26 +00002906 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002907 } else {
2908 for (size_t i = 0; i < argc; ++i) {
2909 // Dump specified images (by basename or fullpath)
2910 const char *arg_cstr = command.GetArgumentAtIndex(i);
2911 const size_t num_matches = FindModulesByName(
2912 target, arg_cstr, module_list, use_global_module_list);
2913 if (num_matches == 0) {
2914 if (argc == 1) {
2915 result.AppendErrorWithFormat("no modules found that match '%s'",
2916 arg_cstr);
2917 result.SetStatus(eReturnStatusFailed);
2918 return false;
Jim Inghamc10312c2011-10-24 18:36:33 +00002919 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002920 }
Greg Claytonc9660542012-02-05 02:38:54 +00002921 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002922
2923 module_list_ptr = &module_list;
2924 }
2925
2926 std::unique_lock<std::recursive_mutex> lock;
2927 if (module_list_ptr != nullptr) {
2928 lock =
2929 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
2930
2931 num_modules = module_list_ptr->GetSize();
2932 }
2933
2934 if (num_modules > 0) {
2935 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2936 ModuleSP module_sp;
2937 Module *module;
2938 if (module_list_ptr) {
2939 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
2940 module = module_sp.get();
2941 } else {
2942 module = Module::GetAllocatedModuleAtIndex(image_idx);
2943 module_sp = module->shared_from_this();
2944 }
2945
2946 const size_t indent = strm.Printf("[%3u] ", image_idx);
2947 PrintModule(target, module, indent, strm);
Jim Inghamc10312c2011-10-24 18:36:33 +00002948 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002949 result.SetStatus(eReturnStatusSuccessFinishResult);
2950 } else {
2951 if (argc) {
2952 if (use_global_module_list)
2953 result.AppendError(
2954 "the global module list has no matching modules");
2955 else
2956 result.AppendError("the target has no matching modules");
2957 } else {
2958 if (use_global_module_list)
2959 result.AppendError("the global module list is empty");
2960 else
2961 result.AppendError(
2962 "the target has no associated executable images");
2963 }
2964 result.SetStatus(eReturnStatusFailed);
2965 return false;
2966 }
2967 }
2968 return result.Succeeded();
2969 }
2970
2971 void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
2972 if (module == nullptr) {
2973 strm.PutCString("Null module");
2974 return;
Jim Inghamc10312c2011-10-24 18:36:33 +00002975 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002976
Kate Stoneb9c1b512016-09-06 20:57:50 +00002977 bool dump_object_name = false;
2978 if (m_options.m_format_array.empty()) {
2979 m_options.m_format_array.push_back(std::make_pair('u', 0));
2980 m_options.m_format_array.push_back(std::make_pair('h', 0));
2981 m_options.m_format_array.push_back(std::make_pair('f', 0));
2982 m_options.m_format_array.push_back(std::make_pair('S', 0));
2983 }
2984 const size_t num_entries = m_options.m_format_array.size();
2985 bool print_space = false;
2986 for (size_t i = 0; i < num_entries; ++i) {
2987 if (print_space)
2988 strm.PutChar(' ');
2989 print_space = true;
2990 const char format_char = m_options.m_format_array[i].first;
2991 uint32_t width = m_options.m_format_array[i].second;
2992 switch (format_char) {
2993 case 'A':
2994 DumpModuleArchitecture(strm, module, false, width);
2995 break;
2996
2997 case 't':
2998 DumpModuleArchitecture(strm, module, true, width);
2999 break;
3000
3001 case 'f':
3002 DumpFullpath(strm, &module->GetFileSpec(), width);
3003 dump_object_name = true;
3004 break;
3005
3006 case 'd':
3007 DumpDirectory(strm, &module->GetFileSpec(), width);
3008 break;
3009
3010 case 'b':
3011 DumpBasename(strm, &module->GetFileSpec(), width);
3012 dump_object_name = true;
3013 break;
3014
3015 case 'h':
3016 case 'o':
3017 // Image header address
3018 {
3019 uint32_t addr_nibble_width =
3020 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3021 : 16;
3022
3023 ObjectFile *objfile = module->GetObjectFile();
3024 if (objfile) {
3025 Address header_addr(objfile->GetHeaderAddress());
3026 if (header_addr.IsValid()) {
3027 if (target && !target->GetSectionLoadList().IsEmpty()) {
3028 lldb::addr_t header_load_addr =
3029 header_addr.GetLoadAddress(target);
3030 if (header_load_addr == LLDB_INVALID_ADDRESS) {
3031 header_addr.Dump(&strm, target,
3032 Address::DumpStyleModuleWithFileAddress,
3033 Address::DumpStyleFileAddress);
3034 } else {
3035 if (format_char == 'o') {
3036 // Show the offset of slide for the image
3037 strm.Printf(
3038 "0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width,
3039 header_load_addr - header_addr.GetFileAddress());
3040 } else {
3041 // Show the load address of the image
3042 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3043 addr_nibble_width, header_load_addr);
3044 }
3045 }
3046 break;
3047 }
3048 // The address was valid, but the image isn't loaded, output the
3049 // address in an appropriate format
3050 header_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3051 break;
3052 }
3053 }
3054 strm.Printf("%*s", addr_nibble_width + 2, "");
3055 }
3056 break;
3057
3058 case 'r': {
3059 size_t ref_count = 0;
3060 ModuleSP module_sp(module->shared_from_this());
3061 if (module_sp) {
3062 // Take one away to make sure we don't count our local "module_sp"
3063 ref_count = module_sp.use_count() - 1;
3064 }
3065 if (width)
3066 strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3067 else
3068 strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3069 } break;
3070
3071 case 's':
3072 case 'S': {
3073 const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3074 if (symbol_vendor) {
3075 const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3076 if (format_char == 'S') {
3077 // Dump symbol file only if different from module file
3078 if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3079 print_space = false;
3080 break;
3081 }
3082 // Add a newline and indent past the index
3083 strm.Printf("\n%*s", indent, "");
3084 }
3085 DumpFullpath(strm, &symfile_spec, width);
3086 dump_object_name = true;
3087 break;
3088 }
3089 strm.Printf("%.*s", width, "<NONE>");
3090 } break;
3091
3092 case 'm':
3093 module->GetModificationTime().Dump(&strm, width);
3094 break;
3095
3096 case 'p':
3097 strm.Printf("%p", static_cast<void *>(module));
3098 break;
3099
3100 case 'u':
3101 DumpModuleUUID(strm, module);
3102 break;
3103
3104 default:
3105 break;
3106 }
3107 }
3108 if (dump_object_name) {
3109 const char *object_name = module->GetObjectName().GetCString();
3110 if (object_name)
3111 strm.Printf("(%s)", object_name);
3112 }
3113 strm.EOL();
3114 }
3115
3116 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003117};
3118
3119OptionDefinition
Kate Stoneb9c1b512016-09-06 20:57:50 +00003120 CommandObjectTargetModulesList::CommandOptions::g_option_table[] = {
3121 // clang-format off
Kate Stoneac9c3a62016-08-26 23:28:47 +00003122 {LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Display the image at this address."},
3123 {LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the architecture when listing images."},
3124 {LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the triple when listing images."},
3125 {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."},
3126 {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)."},
3127 {LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the UUID when listing images."},
3128 {LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
3129 {LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
3130 {LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
3131 {LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
3132 {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."},
3133 {LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the modification time with optional width of the module."},
3134 {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."},
3135 {LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the module pointer."},
3136 {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."},
3137 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
Kate Stoneb9c1b512016-09-06 20:57:50 +00003138 // clang-format on
Greg Claytoneffe5c92011-05-03 22:09:39 +00003139};
3140
Jason Molenda380241a2012-07-12 00:20:07 +00003141#pragma mark CommandObjectTargetModulesShowUnwind
Greg Claytoneffe5c92011-05-03 22:09:39 +00003142
Jason Molenda380241a2012-07-12 00:20:07 +00003143//----------------------------------------------------------------------
3144// Lookup unwind information in images
3145//----------------------------------------------------------------------
3146
Kate Stoneb9c1b512016-09-06 20:57:50 +00003147class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
Jason Molenda380241a2012-07-12 00:20:07 +00003148public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003149 enum {
3150 eLookupTypeInvalid = -1,
3151 eLookupTypeAddress = 0,
3152 eLookupTypeSymbol,
3153 eLookupTypeFunction,
3154 eLookupTypeFunctionOrSymbol,
3155 kNumLookupTypes
3156 };
Jason Molenda380241a2012-07-12 00:20:07 +00003157
Kate Stoneb9c1b512016-09-06 20:57:50 +00003158 class CommandOptions : public Options {
3159 public:
3160 CommandOptions()
3161 : Options(), m_type(eLookupTypeInvalid), m_str(),
3162 m_addr(LLDB_INVALID_ADDRESS) {}
Jason Molenda380241a2012-07-12 00:20:07 +00003163
Kate Stoneb9c1b512016-09-06 20:57:50 +00003164 ~CommandOptions() override = default;
Jason Molenda380241a2012-07-12 00:20:07 +00003165
Kate Stoneb9c1b512016-09-06 20:57:50 +00003166 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
3167 ExecutionContext *execution_context) override {
3168 Error error;
Jason Molenda380241a2012-07-12 00:20:07 +00003169
Kate Stoneb9c1b512016-09-06 20:57:50 +00003170 const int short_option = m_getopt_table[option_idx].val;
Jason Molenda380241a2012-07-12 00:20:07 +00003171
Kate Stoneb9c1b512016-09-06 20:57:50 +00003172 switch (short_option) {
3173 case 'a': {
3174 m_str = option_arg;
3175 m_type = eLookupTypeAddress;
3176 m_addr = Args::StringToAddress(execution_context, option_arg,
3177 LLDB_INVALID_ADDRESS, &error);
3178 if (m_addr == LLDB_INVALID_ADDRESS)
3179 error.SetErrorStringWithFormat("invalid address string '%s'",
3180 option_arg);
3181 break;
3182 }
Jason Molenda380241a2012-07-12 00:20:07 +00003183
Kate Stoneb9c1b512016-09-06 20:57:50 +00003184 case 'n':
3185 m_str = option_arg;
3186 m_type = eLookupTypeFunctionOrSymbol;
3187 break;
Michael Sartainb1e15922013-08-22 20:42:30 +00003188
Kate Stoneb9c1b512016-09-06 20:57:50 +00003189 default:
3190 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
3191 break;
3192 }
Jason Molenda380241a2012-07-12 00:20:07 +00003193
Kate Stoneb9c1b512016-09-06 20:57:50 +00003194 return error;
Jason Molenda380241a2012-07-12 00:20:07 +00003195 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003196
Kate Stoneb9c1b512016-09-06 20:57:50 +00003197 void OptionParsingStarting(ExecutionContext *execution_context) override {
3198 m_type = eLookupTypeInvalid;
3199 m_str.clear();
3200 m_addr = LLDB_INVALID_ADDRESS;
Jason Molenda380241a2012-07-12 00:20:07 +00003201 }
3202
Kate Stoneb9c1b512016-09-06 20:57:50 +00003203 const OptionDefinition *GetDefinitions() override { return g_option_table; }
3204
3205 // Options table: Required for subclasses of Options.
3206
3207 static OptionDefinition g_option_table[];
3208
3209 // Instance variables to hold the values for command options.
3210
3211 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3212 std::string m_str; // Holds name lookup
3213 lldb::addr_t m_addr; // Holds the address to lookup
3214 };
3215
3216 CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3217 : CommandObjectParsed(
3218 interpreter, "target modules show-unwind",
3219 "Show synthesized unwind instructions for a function.", nullptr,
3220 eCommandRequiresTarget | eCommandRequiresProcess |
3221 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
3222 m_options() {}
3223
3224 ~CommandObjectTargetModulesShowUnwind() override = default;
3225
3226 Options *GetOptions() override { return &m_options; }
3227
Jason Molenda380241a2012-07-12 00:20:07 +00003228protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003229 bool DoExecute(Args &command, CommandReturnObject &result) override {
3230 Target *target = m_exe_ctx.GetTargetPtr();
3231 Process *process = m_exe_ctx.GetProcessPtr();
3232 ABI *abi = nullptr;
3233 if (process)
3234 abi = process->GetABI().get();
Jason Molenda380241a2012-07-12 00:20:07 +00003235
Kate Stoneb9c1b512016-09-06 20:57:50 +00003236 if (process == nullptr) {
3237 result.AppendError(
3238 "You must have a process running to use this command.");
3239 result.SetStatus(eReturnStatusFailed);
3240 return false;
Jason Molenda380241a2012-07-12 00:20:07 +00003241 }
3242
Kate Stoneb9c1b512016-09-06 20:57:50 +00003243 ThreadList threads(process->GetThreadList());
3244 if (threads.GetSize() == 0) {
3245 result.AppendError("The process must be paused to use this command.");
3246 result.SetStatus(eReturnStatusFailed);
3247 return false;
3248 }
3249
3250 ThreadSP thread(threads.GetThreadAtIndex(0));
3251 if (!thread) {
3252 result.AppendError("The process must be paused to use this command.");
3253 result.SetStatus(eReturnStatusFailed);
3254 return false;
3255 }
3256
3257 SymbolContextList sc_list;
3258
3259 if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3260 ConstString function_name(m_options.m_str.c_str());
3261 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3262 true, false, true, sc_list);
3263 } else if (m_options.m_type == eLookupTypeAddress && target) {
3264 Address addr;
3265 if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3266 addr)) {
3267 SymbolContext sc;
3268 ModuleSP module_sp(addr.GetModule());
3269 module_sp->ResolveSymbolContextForAddress(addr,
3270 eSymbolContextEverything, sc);
3271 if (sc.function || sc.symbol) {
3272 sc_list.Append(sc);
3273 }
3274 }
3275 } else {
3276 result.AppendError(
3277 "address-expression or function name option must be specified.");
3278 result.SetStatus(eReturnStatusFailed);
3279 return false;
3280 }
3281
3282 size_t num_matches = sc_list.GetSize();
3283 if (num_matches == 0) {
3284 result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3285 m_options.m_str.c_str());
3286 result.SetStatus(eReturnStatusFailed);
3287 return false;
3288 }
3289
3290 for (uint32_t idx = 0; idx < num_matches; idx++) {
3291 SymbolContext sc;
3292 sc_list.GetContextAtIndex(idx, sc);
3293 if (sc.symbol == nullptr && sc.function == nullptr)
3294 continue;
3295 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3296 continue;
3297 AddressRange range;
3298 if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3299 false, range))
3300 continue;
3301 if (!range.GetBaseAddress().IsValid())
3302 continue;
3303 ConstString funcname(sc.GetFunctionName());
3304 if (funcname.IsEmpty())
3305 continue;
3306 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3307 if (abi)
3308 start_addr = abi->FixCodeAddress(start_addr);
3309
3310 FuncUnwindersSP func_unwinders_sp(
3311 sc.module_sp->GetObjectFile()
3312 ->GetUnwindTable()
3313 .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3314 if (!func_unwinders_sp)
3315 continue;
3316
3317 result.GetOutputStream().Printf(
3318 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
3319 sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3320 funcname.AsCString(), start_addr);
3321
3322 UnwindPlanSP non_callsite_unwind_plan =
3323 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
3324 if (non_callsite_unwind_plan) {
3325 result.GetOutputStream().Printf(
3326 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3327 non_callsite_unwind_plan->GetSourceName().AsCString());
3328 }
3329 UnwindPlanSP callsite_unwind_plan =
3330 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3331 if (callsite_unwind_plan) {
3332 result.GetOutputStream().Printf(
3333 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3334 callsite_unwind_plan->GetSourceName().AsCString());
3335 }
3336 UnwindPlanSP fast_unwind_plan =
3337 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3338 if (fast_unwind_plan) {
3339 result.GetOutputStream().Printf(
3340 "Fast UnwindPlan is '%s'\n",
3341 fast_unwind_plan->GetSourceName().AsCString());
3342 }
3343
3344 result.GetOutputStream().Printf("\n");
3345
3346 UnwindPlanSP assembly_sp =
3347 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
3348 if (assembly_sp) {
3349 result.GetOutputStream().Printf(
3350 "Assembly language inspection UnwindPlan:\n");
3351 assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3352 LLDB_INVALID_ADDRESS);
3353 result.GetOutputStream().Printf("\n");
3354 }
3355
3356 UnwindPlanSP ehframe_sp =
3357 func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3358 if (ehframe_sp) {
3359 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3360 ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3361 LLDB_INVALID_ADDRESS);
3362 result.GetOutputStream().Printf("\n");
3363 }
3364
3365 UnwindPlanSP ehframe_augmented_sp =
3366 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
3367 if (ehframe_augmented_sp) {
3368 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3369 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3370 LLDB_INVALID_ADDRESS);
3371 result.GetOutputStream().Printf("\n");
3372 }
3373
3374 UnwindPlanSP arm_unwind_sp =
3375 func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
3376 if (arm_unwind_sp) {
3377 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3378 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3379 LLDB_INVALID_ADDRESS);
3380 result.GetOutputStream().Printf("\n");
3381 }
3382
3383 UnwindPlanSP compact_unwind_sp =
3384 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3385 if (compact_unwind_sp) {
3386 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3387 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3388 LLDB_INVALID_ADDRESS);
3389 result.GetOutputStream().Printf("\n");
3390 }
3391
3392 if (fast_unwind_plan) {
3393 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3394 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3395 LLDB_INVALID_ADDRESS);
3396 result.GetOutputStream().Printf("\n");
3397 }
3398
3399 ABISP abi_sp = process->GetABI();
3400 if (abi_sp) {
3401 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3402 if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3403 result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3404 arch_default.Dump(result.GetOutputStream(), thread.get(),
3405 LLDB_INVALID_ADDRESS);
3406 result.GetOutputStream().Printf("\n");
3407 }
3408
3409 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3410 if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3411 result.GetOutputStream().Printf(
3412 "Arch default at entry point UnwindPlan:\n");
3413 arch_entry.Dump(result.GetOutputStream(), thread.get(),
3414 LLDB_INVALID_ADDRESS);
3415 result.GetOutputStream().Printf("\n");
3416 }
3417 }
3418
3419 result.GetOutputStream().Printf("\n");
3420 }
3421 return result.Succeeded();
3422 }
3423
3424 CommandOptions m_options;
Jason Molenda380241a2012-07-12 00:20:07 +00003425};
3426
3427OptionDefinition
Kate Stoneb9c1b512016-09-06 20:57:50 +00003428 CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] = {
3429 // clang-format off
Kate Stoneac9c3a62016-08-26 23:28:47 +00003430 {LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name."},
3431 {LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address"},
3432 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
Kate Stoneb9c1b512016-09-06 20:57:50 +00003433 // clang-format on
Jason Molenda380241a2012-07-12 00:20:07 +00003434};
Greg Claytoneffe5c92011-05-03 22:09:39 +00003435
3436//----------------------------------------------------------------------
3437// Lookup information in images
3438//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00003439class CommandObjectTargetModulesLookup : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00003440public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003441 enum {
3442 eLookupTypeInvalid = -1,
3443 eLookupTypeAddress = 0,
3444 eLookupTypeSymbol,
3445 eLookupTypeFileLine, // Line is optional
3446 eLookupTypeFunction,
3447 eLookupTypeFunctionOrSymbol,
3448 eLookupTypeType,
3449 kNumLookupTypes
3450 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003451
Kate Stoneb9c1b512016-09-06 20:57:50 +00003452 class CommandOptions : public Options {
3453 public:
3454 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003455
Kate Stoneb9c1b512016-09-06 20:57:50 +00003456 ~CommandOptions() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003457
Kate Stoneb9c1b512016-09-06 20:57:50 +00003458 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
3459 ExecutionContext *execution_context) override {
3460 Error error;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003461
Kate Stoneb9c1b512016-09-06 20:57:50 +00003462 const int short_option = m_getopt_table[option_idx].val;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003463
Kate Stoneb9c1b512016-09-06 20:57:50 +00003464 switch (short_option) {
3465 case 'a': {
3466 m_type = eLookupTypeAddress;
3467 m_addr = Args::StringToAddress(execution_context, option_arg,
3468 LLDB_INVALID_ADDRESS, &error);
3469 } break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003470
Kate Stoneb9c1b512016-09-06 20:57:50 +00003471 case 'o':
3472 m_offset = StringConvert::ToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3473 if (m_offset == LLDB_INVALID_ADDRESS)
3474 error.SetErrorStringWithFormat("invalid offset string '%s'",
3475 option_arg);
3476 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003477
Kate Stoneb9c1b512016-09-06 20:57:50 +00003478 case 's':
3479 m_str = option_arg;
3480 m_type = eLookupTypeSymbol;
3481 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003482
Kate Stoneb9c1b512016-09-06 20:57:50 +00003483 case 'f':
3484 m_file.SetFile(option_arg, false);
3485 m_type = eLookupTypeFileLine;
3486 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003487
Kate Stoneb9c1b512016-09-06 20:57:50 +00003488 case 'i':
3489 m_include_inlines = false;
3490 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003491
Kate Stoneb9c1b512016-09-06 20:57:50 +00003492 case 'l':
3493 m_line_number = StringConvert::ToUInt32(option_arg, UINT32_MAX);
3494 if (m_line_number == UINT32_MAX)
3495 error.SetErrorStringWithFormat("invalid line number string '%s'",
3496 option_arg);
3497 else if (m_line_number == 0)
3498 error.SetErrorString("zero is an invalid line number");
3499 m_type = eLookupTypeFileLine;
3500 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003501
Kate Stoneb9c1b512016-09-06 20:57:50 +00003502 case 'F':
3503 m_str = option_arg;
3504 m_type = eLookupTypeFunction;
3505 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003506
Kate Stoneb9c1b512016-09-06 20:57:50 +00003507 case 'n':
3508 m_str = option_arg;
3509 m_type = eLookupTypeFunctionOrSymbol;
3510 break;
Greg Claytonc4a8a762012-05-15 18:43:44 +00003511
Kate Stoneb9c1b512016-09-06 20:57:50 +00003512 case 't':
3513 m_str = option_arg;
3514 m_type = eLookupTypeType;
3515 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003516
Kate Stoneb9c1b512016-09-06 20:57:50 +00003517 case 'v':
3518 m_verbose = 1;
3519 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003520
Kate Stoneb9c1b512016-09-06 20:57:50 +00003521 case 'A':
3522 m_print_all = true;
3523 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003524
Kate Stoneb9c1b512016-09-06 20:57:50 +00003525 case 'r':
3526 m_use_regex = true;
3527 break;
3528 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003529
Kate Stoneb9c1b512016-09-06 20:57:50 +00003530 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003531 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003532
Kate Stoneb9c1b512016-09-06 20:57:50 +00003533 void OptionParsingStarting(ExecutionContext *execution_context) override {
3534 m_type = eLookupTypeInvalid;
3535 m_str.clear();
3536 m_file.Clear();
3537 m_addr = LLDB_INVALID_ADDRESS;
3538 m_offset = 0;
3539 m_line_number = 0;
3540 m_use_regex = false;
3541 m_include_inlines = true;
3542 m_verbose = false;
3543 m_print_all = false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003544 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003545
Kate Stoneb9c1b512016-09-06 20:57:50 +00003546 const OptionDefinition *GetDefinitions() override { return g_option_table; }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003547
Kate Stoneb9c1b512016-09-06 20:57:50 +00003548 // Options table: Required for subclasses of Options.
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003549
Kate Stoneb9c1b512016-09-06 20:57:50 +00003550 static OptionDefinition g_option_table[];
3551 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3552 std::string m_str; // Holds name lookup
3553 FileSpec m_file; // Files for file lookups
3554 lldb::addr_t m_addr; // Holds the address to lookup
3555 lldb::addr_t
3556 m_offset; // Subtract this offset from m_addr before doing lookups.
3557 uint32_t m_line_number; // Line number for file+line lookups
3558 bool m_use_regex; // Name lookups in m_str are regular expressions.
3559 bool m_include_inlines; // Check for inline entries when looking up by
3560 // file/line.
3561 bool m_verbose; // Enable verbose lookup info
3562 bool m_print_all; // Print all matches, even in cases where there's a best
3563 // match.
3564 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003565
Kate Stoneb9c1b512016-09-06 20:57:50 +00003566 CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3567 : CommandObjectParsed(interpreter, "target modules lookup",
3568 "Look up information within executable and "
3569 "dependent shared library images.",
3570 nullptr, eCommandRequiresTarget),
3571 m_options() {
3572 CommandArgumentEntry arg;
3573 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003574
Kate Stoneb9c1b512016-09-06 20:57:50 +00003575 // Define the first (and only) variant of this arg.
3576 file_arg.arg_type = eArgTypeFilename;
3577 file_arg.arg_repetition = eArgRepeatStar;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003578
Kate Stoneb9c1b512016-09-06 20:57:50 +00003579 // There is only one variant this argument could be; put it into the
3580 // argument entry.
3581 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003582
Kate Stoneb9c1b512016-09-06 20:57:50 +00003583 // Push the data for the first argument into the m_arguments vector.
3584 m_arguments.push_back(arg);
3585 }
3586
3587 ~CommandObjectTargetModulesLookup() override = default;
3588
3589 Options *GetOptions() override { return &m_options; }
3590
3591 bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3592 bool &syntax_error) {
3593 switch (m_options.m_type) {
3594 case eLookupTypeAddress:
3595 case eLookupTypeFileLine:
3596 case eLookupTypeFunction:
3597 case eLookupTypeFunctionOrSymbol:
3598 case eLookupTypeSymbol:
3599 default:
3600 return false;
3601 case eLookupTypeType:
3602 break;
Sean Callanand38b4a92012-06-06 20:49:55 +00003603 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003604
Kate Stoneb9c1b512016-09-06 20:57:50 +00003605 StackFrameSP frame = m_exe_ctx.GetFrameSP();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003606
Kate Stoneb9c1b512016-09-06 20:57:50 +00003607 if (!frame)
3608 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003609
Kate Stoneb9c1b512016-09-06 20:57:50 +00003610 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
Greg Claytonc4a8a762012-05-15 18:43:44 +00003611
Kate Stoneb9c1b512016-09-06 20:57:50 +00003612 if (!sym_ctx.module_sp)
3613 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003614
Kate Stoneb9c1b512016-09-06 20:57:50 +00003615 switch (m_options.m_type) {
3616 default:
3617 return false;
3618 case eLookupTypeType:
3619 if (!m_options.m_str.empty()) {
3620 if (LookupTypeHere(m_interpreter, result.GetOutputStream(), sym_ctx,
3621 m_options.m_str.c_str(), m_options.m_use_regex)) {
3622 result.SetStatus(eReturnStatusSuccessFinishResult);
3623 return true;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003624 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003625 }
3626 break;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003627 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003628
Kate Stoneb9c1b512016-09-06 20:57:50 +00003629 return true;
3630 }
3631
3632 bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3633 CommandReturnObject &result, bool &syntax_error) {
3634 switch (m_options.m_type) {
3635 case eLookupTypeAddress:
3636 if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3637 if (LookupAddressInModule(
3638 m_interpreter, result.GetOutputStream(), module,
3639 eSymbolContextEverything |
3640 (m_options.m_verbose
3641 ? static_cast<int>(eSymbolContextVariable)
3642 : 0),
3643 m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
3644 result.SetStatus(eReturnStatusSuccessFinishResult);
3645 return true;
3646 }
3647 }
3648 break;
3649
3650 case eLookupTypeSymbol:
3651 if (!m_options.m_str.empty()) {
3652 if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3653 module, m_options.m_str.c_str(),
3654 m_options.m_use_regex, m_options.m_verbose)) {
3655 result.SetStatus(eReturnStatusSuccessFinishResult);
3656 return true;
3657 }
3658 }
3659 break;
3660
3661 case eLookupTypeFileLine:
3662 if (m_options.m_file) {
3663 if (LookupFileAndLineInModule(
3664 m_interpreter, result.GetOutputStream(), module,
3665 m_options.m_file, m_options.m_line_number,
3666 m_options.m_include_inlines, m_options.m_verbose)) {
3667 result.SetStatus(eReturnStatusSuccessFinishResult);
3668 return true;
3669 }
3670 }
3671 break;
3672
3673 case eLookupTypeFunctionOrSymbol:
3674 case eLookupTypeFunction:
3675 if (!m_options.m_str.empty()) {
3676 if (LookupFunctionInModule(
3677 m_interpreter, result.GetOutputStream(), module,
3678 m_options.m_str.c_str(), m_options.m_use_regex,
3679 m_options.m_include_inlines,
3680 m_options.m_type ==
3681 eLookupTypeFunctionOrSymbol, // include symbols
3682 m_options.m_verbose)) {
3683 result.SetStatus(eReturnStatusSuccessFinishResult);
3684 return true;
3685 }
3686 }
3687 break;
3688
3689 case eLookupTypeType:
3690 if (!m_options.m_str.empty()) {
3691 if (LookupTypeInModule(m_interpreter, result.GetOutputStream(), module,
3692 m_options.m_str.c_str(),
3693 m_options.m_use_regex)) {
3694 result.SetStatus(eReturnStatusSuccessFinishResult);
3695 return true;
3696 }
3697 }
3698 break;
3699
3700 default:
3701 m_options.GenerateOptionUsage(
3702 result.GetErrorStream(), this,
3703 GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3704 syntax_error = true;
3705 break;
3706 }
3707
3708 result.SetStatus(eReturnStatusFailed);
3709 return false;
3710 }
3711
Jim Ingham5a988412012-06-08 21:56:10 +00003712protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003713 bool DoExecute(Args &command, CommandReturnObject &result) override {
3714 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3715 if (target == nullptr) {
3716 result.AppendError("invalid target, create a debug target using the "
3717 "'target create' command");
3718 result.SetStatus(eReturnStatusFailed);
3719 return false;
3720 } else {
3721 bool syntax_error = false;
3722 uint32_t i;
3723 uint32_t num_successful_lookups = 0;
3724 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3725 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3726 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3727 // Dump all sections for all modules images
3728
3729 if (command.GetArgumentCount() == 0) {
3730 ModuleSP current_module;
3731
3732 // Where it is possible to look in the current symbol context
3733 // first, try that. If this search was successful and --all
3734 // was not passed, don't print anything else.
3735 if (LookupHere(m_interpreter, result, syntax_error)) {
3736 result.GetOutputStream().EOL();
3737 num_successful_lookups++;
3738 if (!m_options.m_print_all) {
3739 result.SetStatus(eReturnStatusSuccessFinishResult);
3740 return result.Succeeded();
3741 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00003742 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003743
Kate Stoneb9c1b512016-09-06 20:57:50 +00003744 // Dump all sections for all other modules
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003745
Kate Stoneb9c1b512016-09-06 20:57:50 +00003746 const ModuleList &target_modules = target->GetImages();
3747 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3748 const size_t num_modules = target_modules.GetSize();
3749 if (num_modules > 0) {
3750 for (i = 0; i < num_modules && !syntax_error; ++i) {
3751 Module *module_pointer =
3752 target_modules.GetModulePointerAtIndexUnlocked(i);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003753
Kate Stoneb9c1b512016-09-06 20:57:50 +00003754 if (module_pointer != current_module.get() &&
3755 LookupInModule(
3756 m_interpreter,
3757 target_modules.GetModulePointerAtIndexUnlocked(i), result,
3758 syntax_error)) {
3759 result.GetOutputStream().EOL();
3760 num_successful_lookups++;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003761 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003762 }
3763 } else {
3764 result.AppendError("the target has no associated executable images");
3765 result.SetStatus(eReturnStatusFailed);
3766 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003767 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003768 } else {
3769 // Dump specified images (by basename or fullpath)
3770 const char *arg_cstr;
3771 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3772 !syntax_error;
3773 ++i) {
3774 ModuleList module_list;
3775 const size_t num_matches =
3776 FindModulesByName(target, arg_cstr, module_list, false);
3777 if (num_matches > 0) {
3778 for (size_t j = 0; j < num_matches; ++j) {
3779 Module *module = module_list.GetModulePointerAtIndex(j);
3780 if (module) {
3781 if (LookupInModule(m_interpreter, module, result,
3782 syntax_error)) {
3783 result.GetOutputStream().EOL();
3784 num_successful_lookups++;
3785 }
3786 }
3787 }
3788 } else
3789 result.AppendWarningWithFormat(
3790 "Unable to find an image that matches '%s'.\n", arg_cstr);
3791 }
3792 }
3793
3794 if (num_successful_lookups > 0)
3795 result.SetStatus(eReturnStatusSuccessFinishResult);
3796 else
3797 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00003798 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003799 return result.Succeeded();
3800 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003801
Kate Stoneb9c1b512016-09-06 20:57:50 +00003802 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003803};
3804
3805OptionDefinition
Kate Stoneb9c1b512016-09-06 20:57:50 +00003806 CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
3807 {
3808 // clang-format off
Kate Stoneac9c3a62016-08-26 23:28:47 +00003809 {LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules."},
3810 {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."},
3811 /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */
3812 {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."},
3813 {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."},
3814 {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."},
3815 {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)."},
3816 {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)."},
3817 {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."},
3818 {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."},
3819 {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."},
3820 {LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose lookup information."},
3821 {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."},
3822 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr}
Kate Stoneb9c1b512016-09-06 20:57:50 +00003823 // clang-format on
Greg Claytoneffe5c92011-05-03 22:09:39 +00003824};
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003825
Jim Ingham9575d842011-03-11 03:53:59 +00003826#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003827
3828//-------------------------------------------------------------------------
3829// CommandObjectMultiwordImageSearchPaths
3830//-------------------------------------------------------------------------
3831
Kate Stoneb9c1b512016-09-06 20:57:50 +00003832class CommandObjectTargetModulesImageSearchPaths
3833 : public CommandObjectMultiword {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003834public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003835 CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
3836 : CommandObjectMultiword(
3837 interpreter, "target modules search-paths",
3838 "Commands for managing module search paths for a target.",
3839 "target modules search-paths <subcommand> [<subcommand-options>]") {
3840 LoadSubCommand(
3841 "add", CommandObjectSP(
3842 new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
3843 LoadSubCommand(
3844 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
3845 interpreter)));
3846 LoadSubCommand(
3847 "insert",
3848 CommandObjectSP(
3849 new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
3850 LoadSubCommand(
3851 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
3852 interpreter)));
3853 LoadSubCommand(
3854 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
3855 interpreter)));
3856 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003857
Kate Stoneb9c1b512016-09-06 20:57:50 +00003858 ~CommandObjectTargetModulesImageSearchPaths() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003859};
3860
Greg Claytoneffe5c92011-05-03 22:09:39 +00003861#pragma mark CommandObjectTargetModules
3862
3863//-------------------------------------------------------------------------
3864// CommandObjectTargetModules
3865//-------------------------------------------------------------------------
3866
Kate Stoneb9c1b512016-09-06 20:57:50 +00003867class CommandObjectTargetModules : public CommandObjectMultiword {
Greg Claytoneffe5c92011-05-03 22:09:39 +00003868public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003869 //------------------------------------------------------------------
3870 // Constructors and Destructors
3871 //------------------------------------------------------------------
3872 CommandObjectTargetModules(CommandInterpreter &interpreter)
3873 : CommandObjectMultiword(interpreter, "target modules",
3874 "Commands for accessing information for one or "
3875 "more target modules.",
3876 "target modules <sub-command> ...") {
3877 LoadSubCommand(
3878 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
3879 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
3880 interpreter)));
3881 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
3882 interpreter)));
3883 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
3884 interpreter)));
3885 LoadSubCommand(
3886 "lookup",
3887 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
3888 LoadSubCommand(
3889 "search-paths",
3890 CommandObjectSP(
3891 new CommandObjectTargetModulesImageSearchPaths(interpreter)));
3892 LoadSubCommand(
3893 "show-unwind",
3894 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
3895 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00003896
Kate Stoneb9c1b512016-09-06 20:57:50 +00003897 ~CommandObjectTargetModules() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003898
Greg Claytoneffe5c92011-05-03 22:09:39 +00003899private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003900 //------------------------------------------------------------------
3901 // For CommandObjectTargetModules only
3902 //------------------------------------------------------------------
3903 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules);
Greg Claytoneffe5c92011-05-03 22:09:39 +00003904};
3905
Kate Stoneb9c1b512016-09-06 20:57:50 +00003906class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
Greg Claytone72dfb32012-02-24 01:59:29 +00003907public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003908 CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
3909 : CommandObjectParsed(
3910 interpreter, "target symbols add",
3911 "Add a debug symbol file to one of the target's current modules by "
3912 "specifying a path to a debug symbols file, or using the options "
3913 "to specify a module to download symbols for.",
3914 "target symbols add [<symfile>]", eCommandRequiresTarget),
Todd Fialae1cfbc72016-08-11 23:51:28 +00003915 m_option_group(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00003916 m_file_option(
3917 LLDB_OPT_SET_1, false, "shlib", 's',
3918 CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3919 "Fullpath or basename for module to find debug symbols for."),
3920 m_current_frame_option(
3921 LLDB_OPT_SET_2, false, "frame", 'F',
3922 "Locate the debug symbols the currently selected frame.", false,
3923 true)
Greg Claytonb5f0fea2012-09-27 22:26:11 +00003924
Kate Stoneb9c1b512016-09-06 20:57:50 +00003925 {
3926 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
3927 LLDB_OPT_SET_1);
3928 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
3929 m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
3930 LLDB_OPT_SET_2);
3931 m_option_group.Finalize();
3932 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003933
Kate Stoneb9c1b512016-09-06 20:57:50 +00003934 ~CommandObjectTargetSymbolsAdd() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003935
Kate Stoneb9c1b512016-09-06 20:57:50 +00003936 int HandleArgumentCompletion(Args &input, int &cursor_index,
3937 int &cursor_char_position,
3938 OptionElementVector &opt_element_vector,
3939 int match_start_point, int max_return_elements,
3940 bool &word_complete,
3941 StringList &matches) override {
3942 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
3943 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003944
Kate Stoneb9c1b512016-09-06 20:57:50 +00003945 CommandCompletions::InvokeCommonCompletionCallbacks(
3946 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
3947 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
3948 word_complete, matches);
3949 return matches.GetSize();
3950 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003951
Kate Stoneb9c1b512016-09-06 20:57:50 +00003952 Options *GetOptions() override { return &m_option_group; }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00003953
Jim Ingham5a988412012-06-08 21:56:10 +00003954protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003955 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
3956 CommandReturnObject &result) {
3957 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
3958 if (symbol_fspec) {
3959 char symfile_path[PATH_MAX];
3960 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003961
Kate Stoneb9c1b512016-09-06 20:57:50 +00003962 if (!module_spec.GetUUID().IsValid()) {
3963 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
3964 module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
3965 }
3966 // We now have a module that represents a symbol file
3967 // that can be used for a module that might exist in the
3968 // current target, so we need to find that module in the
3969 // target
3970 ModuleList matching_module_list;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003971
Kate Stoneb9c1b512016-09-06 20:57:50 +00003972 size_t num_matches = 0;
3973 // First extract all module specs from the symbol file
3974 lldb_private::ModuleSpecList symfile_module_specs;
3975 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
3976 0, 0, symfile_module_specs)) {
3977 // Now extract the module spec that matches the target architecture
3978 ModuleSpec target_arch_module_spec;
3979 ModuleSpec symfile_module_spec;
3980 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
3981 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
3982 symfile_module_spec)) {
3983 // See if it has a UUID?
3984 if (symfile_module_spec.GetUUID().IsValid()) {
3985 // It has a UUID, look for this UUID in the target modules
3986 ModuleSpec symfile_uuid_module_spec;
3987 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
3988 num_matches = target->GetImages().FindModules(
3989 symfile_uuid_module_spec, matching_module_list);
3990 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00003991 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003992
3993 if (num_matches == 0) {
3994 // No matches yet, iterate through the module specs to find a UUID
3995 // value that
3996 // we can match up to an image in our target
3997 const size_t num_symfile_module_specs =
3998 symfile_module_specs.GetSize();
3999 for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0;
4000 ++i) {
4001 if (symfile_module_specs.GetModuleSpecAtIndex(
4002 i, symfile_module_spec)) {
4003 if (symfile_module_spec.GetUUID().IsValid()) {
4004 // It has a UUID, look for this UUID in the target modules
4005 ModuleSpec symfile_uuid_module_spec;
4006 symfile_uuid_module_spec.GetUUID() =
4007 symfile_module_spec.GetUUID();
4008 num_matches = target->GetImages().FindModules(
4009 symfile_uuid_module_spec, matching_module_list);
4010 }
4011 }
4012 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00004013 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004014 }
4015
4016 // Just try to match up the file by basename if we have no matches at this
4017 // point
4018 if (num_matches == 0)
4019 num_matches =
4020 target->GetImages().FindModules(module_spec, matching_module_list);
4021
4022 while (num_matches == 0) {
4023 ConstString filename_no_extension(
4024 module_spec.GetFileSpec().GetFileNameStrippingExtension());
4025 // Empty string returned, lets bail
4026 if (!filename_no_extension)
4027 break;
4028
4029 // Check if there was no extension to strip and the basename is the same
4030 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4031 break;
4032
4033 // Replace basename with one less extension
4034 module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4035
4036 num_matches =
4037 target->GetImages().FindModules(module_spec, matching_module_list);
4038 }
4039
4040 if (num_matches > 1) {
4041 result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4042 "use the --uuid option to resolve the "
4043 "ambiguity.\n",
4044 symfile_path);
4045 } else if (num_matches == 1) {
4046 ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0));
4047
4048 // The module has not yet created its symbol vendor, we can just
4049 // give the existing target module the symfile path to use for
4050 // when it decides to create it!
4051 module_sp->SetSymbolFileFileSpec(symbol_fspec);
4052
4053 SymbolVendor *symbol_vendor =
4054 module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4055 if (symbol_vendor) {
4056 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4057
4058 if (symbol_file) {
4059 ObjectFile *object_file = symbol_file->GetObjectFile();
4060
4061 if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4062 // Provide feedback that the symfile has been successfully added.
4063 const FileSpec &module_fs = module_sp->GetFileSpec();
4064 result.AppendMessageWithFormat(
4065 "symbol file '%s' has been added to '%s'\n", symfile_path,
4066 module_fs.GetPath().c_str());
4067
4068 // Let clients know something changed in the module
4069 // if it is currently loaded
4070 ModuleList module_list;
4071 module_list.Append(module_sp);
4072 target->SymbolsDidLoad(module_list);
4073
4074 // Make sure we load any scripting resources that may be embedded
4075 // in the debug info files in case the platform supports that.
4076 Error error;
4077 StreamString feedback_stream;
4078 module_sp->LoadScriptingResourceInTarget(target, error,
4079 &feedback_stream);
4080 if (error.Fail() && error.AsCString())
4081 result.AppendWarningWithFormat(
4082 "unable to load scripting data for module %s - error "
4083 "reported was %s",
4084 module_sp->GetFileSpec()
4085 .GetFileNameStrippingExtension()
4086 .GetCString(),
4087 error.AsCString());
4088 else if (feedback_stream.GetSize())
4089 result.AppendWarningWithFormat("%s", feedback_stream.GetData());
4090
4091 flush = true;
4092 result.SetStatus(eReturnStatusSuccessFinishResult);
4093 return true;
4094 }
4095 }
4096 }
4097 // Clear the symbol file spec if anything went wrong
4098 module_sp->SetSymbolFileFileSpec(FileSpec());
4099 }
4100
4101 if (module_spec.GetUUID().IsValid()) {
4102 StreamString ss_symfile_uuid;
4103 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4104 result.AppendErrorWithFormat(
4105 "symbol file '%s' (%s) does not match any existing module%s\n",
4106 symfile_path, ss_symfile_uuid.GetData(),
4107 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4108 ? "\n please specify the full path to the symbol file"
4109 : "");
4110 } else {
4111 result.AppendErrorWithFormat(
4112 "symbol file '%s' does not match any existing module%s\n",
4113 symfile_path,
4114 (symbol_fspec.GetFileType() != FileSpec::eFileTypeRegular)
4115 ? "\n please specify the full path to the symbol file"
4116 : "");
4117 }
4118 } else {
4119 result.AppendError(
4120 "one or more executable image paths must be specified");
4121 }
4122 result.SetStatus(eReturnStatusFailed);
4123 return false;
4124 }
4125
4126 bool DoExecute(Args &args, CommandReturnObject &result) override {
4127 Target *target = m_exe_ctx.GetTargetPtr();
4128 result.SetStatus(eReturnStatusFailed);
4129 bool flush = false;
4130 ModuleSpec module_spec;
4131 const bool uuid_option_set =
4132 m_uuid_option_group.GetOptionValue().OptionWasSet();
4133 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4134 const bool frame_option_set =
4135 m_current_frame_option.GetOptionValue().OptionWasSet();
4136 const size_t argc = args.GetArgumentCount();
4137
4138 if (argc == 0) {
4139 if (uuid_option_set || file_option_set || frame_option_set) {
4140 bool success = false;
4141 bool error_set = false;
4142 if (frame_option_set) {
4143 Process *process = m_exe_ctx.GetProcessPtr();
4144 if (process) {
4145 const StateType process_state = process->GetState();
4146 if (StateIsStoppedState(process_state, true)) {
4147 StackFrame *frame = m_exe_ctx.GetFramePtr();
4148 if (frame) {
4149 ModuleSP frame_module_sp(
4150 frame->GetSymbolContext(eSymbolContextModule).module_sp);
4151 if (frame_module_sp) {
4152 if (frame_module_sp->GetPlatformFileSpec().Exists()) {
4153 module_spec.GetArchitecture() =
4154 frame_module_sp->GetArchitecture();
4155 module_spec.GetFileSpec() =
4156 frame_module_sp->GetPlatformFileSpec();
4157 }
4158 module_spec.GetUUID() = frame_module_sp->GetUUID();
4159 success = module_spec.GetUUID().IsValid() ||
4160 module_spec.GetFileSpec();
4161 } else {
4162 result.AppendError("frame has no module");
4163 error_set = true;
4164 }
4165 } else {
4166 result.AppendError("invalid current frame");
4167 error_set = true;
4168 }
4169 } else {
4170 result.AppendErrorWithFormat("process is not stopped: %s",
4171 StateAsCString(process_state));
4172 error_set = true;
4173 }
4174 } else {
4175 result.AppendError(
4176 "a process must exist in order to use the --frame option");
4177 error_set = true;
4178 }
4179 } else {
4180 if (uuid_option_set) {
4181 module_spec.GetUUID() =
4182 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4183 success |= module_spec.GetUUID().IsValid();
4184 } else if (file_option_set) {
4185 module_spec.GetFileSpec() =
4186 m_file_option.GetOptionValue().GetCurrentValue();
4187 ModuleSP module_sp(
4188 target->GetImages().FindFirstModule(module_spec));
4189 if (module_sp) {
4190 module_spec.GetFileSpec() = module_sp->GetFileSpec();
4191 module_spec.GetPlatformFileSpec() =
4192 module_sp->GetPlatformFileSpec();
4193 module_spec.GetUUID() = module_sp->GetUUID();
4194 module_spec.GetArchitecture() = module_sp->GetArchitecture();
4195 } else {
4196 module_spec.GetArchitecture() = target->GetArchitecture();
4197 }
4198 success |= module_spec.GetUUID().IsValid() ||
4199 module_spec.GetFileSpec().Exists();
4200 }
4201 }
4202
4203 if (success) {
4204 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4205 if (module_spec.GetSymbolFileSpec())
4206 success = AddModuleSymbols(target, module_spec, flush, result);
4207 }
4208 }
4209
4210 if (!success && !error_set) {
4211 StreamString error_strm;
4212 if (uuid_option_set) {
4213 error_strm.PutCString("unable to find debug symbols for UUID ");
4214 module_spec.GetUUID().Dump(&error_strm);
4215 } else if (file_option_set) {
4216 error_strm.PutCString(
4217 "unable to find debug symbols for the executable file ");
4218 error_strm << module_spec.GetFileSpec();
4219 } else if (frame_option_set) {
4220 error_strm.PutCString(
4221 "unable to find debug symbols for the current frame");
4222 }
4223 result.AppendError(error_strm.GetData());
4224 }
4225 } else {
4226 result.AppendError("one or more symbol file paths must be specified, "
4227 "or options must be specified");
4228 }
4229 } else {
4230 if (uuid_option_set) {
4231 result.AppendError("specify either one or more paths to symbol files "
4232 "or use the --uuid option without arguments");
4233 } else if (file_option_set) {
4234 result.AppendError("specify either one or more paths to symbol files "
4235 "or use the --file option without arguments");
4236 } else if (frame_option_set) {
4237 result.AppendError("specify either one or more paths to symbol files "
4238 "or use the --frame option without arguments");
4239 } else {
4240 PlatformSP platform_sp(target->GetPlatform());
4241
4242 for (size_t i = 0; i < argc; ++i) {
4243 const char *symfile_path = args.GetArgumentAtIndex(i);
4244 if (symfile_path) {
4245 module_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
4246 if (platform_sp) {
4247 FileSpec symfile_spec;
4248 if (platform_sp
4249 ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4250 .Success())
4251 module_spec.GetSymbolFileSpec() = symfile_spec;
4252 }
4253
4254 ArchSpec arch;
4255 bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
4256
4257 if (symfile_exists) {
4258 if (!AddModuleSymbols(target, module_spec, flush, result))
4259 break;
4260 } else {
4261 char resolved_symfile_path[PATH_MAX];
4262 if (module_spec.GetSymbolFileSpec().GetPath(
4263 resolved_symfile_path, sizeof(resolved_symfile_path))) {
4264 if (strcmp(resolved_symfile_path, symfile_path) != 0) {
4265 result.AppendErrorWithFormat(
4266 "invalid module path '%s' with resolved path '%s'\n",
4267 symfile_path, resolved_symfile_path);
4268 break;
4269 }
4270 }
4271 result.AppendErrorWithFormat("invalid module path '%s'\n",
4272 symfile_path);
4273 break;
4274 }
4275 }
4276 }
4277 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00004278 }
4279
Kate Stoneb9c1b512016-09-06 20:57:50 +00004280 if (flush) {
4281 Process *process = m_exe_ctx.GetProcessPtr();
4282 if (process)
4283 process->Flush();
Greg Claytone72dfb32012-02-24 01:59:29 +00004284 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004285 return result.Succeeded();
4286 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004287
Kate Stoneb9c1b512016-09-06 20:57:50 +00004288 OptionGroupOptions m_option_group;
4289 OptionGroupUUID m_uuid_option_group;
4290 OptionGroupFile m_file_option;
4291 OptionGroupBoolean m_current_frame_option;
Greg Claytone72dfb32012-02-24 01:59:29 +00004292};
4293
Greg Claytone72dfb32012-02-24 01:59:29 +00004294#pragma mark CommandObjectTargetSymbols
4295
4296//-------------------------------------------------------------------------
4297// CommandObjectTargetSymbols
4298//-------------------------------------------------------------------------
4299
Kate Stoneb9c1b512016-09-06 20:57:50 +00004300class CommandObjectTargetSymbols : public CommandObjectMultiword {
Greg Claytone72dfb32012-02-24 01:59:29 +00004301public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004302 //------------------------------------------------------------------
4303 // Constructors and Destructors
4304 //------------------------------------------------------------------
4305 CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4306 : CommandObjectMultiword(
4307 interpreter, "target symbols",
4308 "Commands for adding and managing debug symbol files.",
4309 "target symbols <sub-command> ...") {
4310 LoadSubCommand(
4311 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4312 }
Bruce Mitchener13d21e92015-10-07 16:56:17 +00004313
Kate Stoneb9c1b512016-09-06 20:57:50 +00004314 ~CommandObjectTargetSymbols() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004315
Greg Claytone72dfb32012-02-24 01:59:29 +00004316private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004317 //------------------------------------------------------------------
4318 // For CommandObjectTargetModules only
4319 //------------------------------------------------------------------
4320 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols);
Greg Claytone72dfb32012-02-24 01:59:29 +00004321};
4322
Jim Ingham9575d842011-03-11 03:53:59 +00004323#pragma mark CommandObjectTargetStopHookAdd
4324
4325//-------------------------------------------------------------------------
4326// CommandObjectTargetStopHookAdd
4327//-------------------------------------------------------------------------
4328
Kate Stoneb9c1b512016-09-06 20:57:50 +00004329class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4330 public IOHandlerDelegateMultiline {
Jim Ingham9575d842011-03-11 03:53:59 +00004331public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004332 class CommandOptions : public Options {
4333 public:
4334 CommandOptions()
4335 : Options(), m_line_start(0), m_line_end(UINT_MAX),
4336 m_func_name_type_mask(eFunctionNameTypeAuto),
4337 m_sym_ctx_specified(false), m_thread_specified(false),
4338 m_use_one_liner(false), m_one_liner() {}
4339
4340 ~CommandOptions() override = default;
4341
4342 const OptionDefinition *GetDefinitions() override { return g_option_table; }
4343
4344 Error SetOptionValue(uint32_t option_idx, const char *option_arg,
4345 ExecutionContext *execution_context) override {
4346 Error error;
4347 const int short_option = m_getopt_table[option_idx].val;
4348 bool success;
4349
4350 switch (short_option) {
4351 case 'c':
4352 m_class_name = option_arg;
4353 m_sym_ctx_specified = true;
4354 break;
4355
4356 case 'e':
4357 m_line_end = StringConvert::ToUInt32(option_arg, UINT_MAX, 0, &success);
4358 if (!success) {
4359 error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
4360 option_arg);
4361 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004362 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004363 m_sym_ctx_specified = true;
4364 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004365
Kate Stoneb9c1b512016-09-06 20:57:50 +00004366 case 'l':
4367 m_line_start = StringConvert::ToUInt32(option_arg, 0, 0, &success);
4368 if (!success) {
4369 error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
4370 option_arg);
4371 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004372 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004373 m_sym_ctx_specified = true;
4374 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004375
Kate Stoneb9c1b512016-09-06 20:57:50 +00004376 case 'i':
4377 m_no_inlines = true;
4378 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004379
Kate Stoneb9c1b512016-09-06 20:57:50 +00004380 case 'n':
4381 m_function_name = option_arg;
4382 m_func_name_type_mask |= eFunctionNameTypeAuto;
4383 m_sym_ctx_specified = true;
4384 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004385
Kate Stoneb9c1b512016-09-06 20:57:50 +00004386 case 'f':
4387 m_file_name = option_arg;
4388 m_sym_ctx_specified = true;
4389 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004390
Kate Stoneb9c1b512016-09-06 20:57:50 +00004391 case 's':
4392 m_module_name = option_arg;
4393 m_sym_ctx_specified = true;
4394 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004395
Kate Stoneb9c1b512016-09-06 20:57:50 +00004396 case 't':
4397 m_thread_id =
4398 StringConvert::ToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
4399 if (m_thread_id == LLDB_INVALID_THREAD_ID)
4400 error.SetErrorStringWithFormat("invalid thread id string '%s'",
4401 option_arg);
4402 m_thread_specified = true;
4403 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004404
Kate Stoneb9c1b512016-09-06 20:57:50 +00004405 case 'T':
4406 m_thread_name = option_arg;
4407 m_thread_specified = true;
4408 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004409
Kate Stoneb9c1b512016-09-06 20:57:50 +00004410 case 'q':
4411 m_queue_name = option_arg;
4412 m_thread_specified = true;
4413 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004414
Kate Stoneb9c1b512016-09-06 20:57:50 +00004415 case 'x':
4416 m_thread_index = StringConvert::ToUInt32(option_arg, UINT32_MAX, 0);
4417 if (m_thread_id == UINT32_MAX)
4418 error.SetErrorStringWithFormat("invalid thread index string '%s'",
4419 option_arg);
4420 m_thread_specified = true;
4421 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004422
Kate Stoneb9c1b512016-09-06 20:57:50 +00004423 case 'o':
4424 m_use_one_liner = true;
4425 m_one_liner = option_arg;
4426 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004427
Kate Stoneb9c1b512016-09-06 20:57:50 +00004428 default:
4429 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
4430 break;
4431 }
4432 return error;
Jim Ingham9575d842011-03-11 03:53:59 +00004433 }
4434
Kate Stoneb9c1b512016-09-06 20:57:50 +00004435 void OptionParsingStarting(ExecutionContext *execution_context) override {
4436 m_class_name.clear();
4437 m_function_name.clear();
4438 m_line_start = 0;
4439 m_line_end = UINT_MAX;
4440 m_file_name.clear();
4441 m_module_name.clear();
4442 m_func_name_type_mask = eFunctionNameTypeAuto;
4443 m_thread_id = LLDB_INVALID_THREAD_ID;
4444 m_thread_index = UINT32_MAX;
4445 m_thread_name.clear();
4446 m_queue_name.clear();
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004447
Kate Stoneb9c1b512016-09-06 20:57:50 +00004448 m_no_inlines = false;
4449 m_sym_ctx_specified = false;
4450 m_thread_specified = false;
4451
4452 m_use_one_liner = false;
4453 m_one_liner.clear();
Jim Ingham9575d842011-03-11 03:53:59 +00004454 }
4455
Kate Stoneb9c1b512016-09-06 20:57:50 +00004456 static OptionDefinition g_option_table[];
4457
4458 std::string m_class_name;
4459 std::string m_function_name;
4460 uint32_t m_line_start;
4461 uint32_t m_line_end;
4462 std::string m_file_name;
4463 std::string m_module_name;
4464 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
4465 lldb::tid_t m_thread_id;
4466 uint32_t m_thread_index;
4467 std::string m_thread_name;
4468 std::string m_queue_name;
4469 bool m_sym_ctx_specified;
4470 bool m_no_inlines;
4471 bool m_thread_specified;
4472 // Instance variables to hold the values for one_liner options.
4473 bool m_use_one_liner;
4474 std::string m_one_liner;
4475 };
4476
4477 CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4478 : CommandObjectParsed(interpreter, "target stop-hook add",
4479 "Add a hook to be executed when the target stops.",
4480 "target stop-hook add"),
4481 IOHandlerDelegateMultiline("DONE",
4482 IOHandlerDelegate::Completion::LLDBCommand),
4483 m_options() {}
4484
4485 ~CommandObjectTargetStopHookAdd() override = default;
4486
4487 Options *GetOptions() override { return &m_options; }
4488
Jim Ingham5a988412012-06-08 21:56:10 +00004489protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004490 void IOHandlerActivated(IOHandler &io_handler) override {
4491 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4492 if (output_sp) {
4493 output_sp->PutCString(
4494 "Enter your stop hook command(s). Type 'DONE' to end.\n");
4495 output_sp->Flush();
Greg Clayton44d93782014-01-27 23:43:24 +00004496 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004497 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004498
Kate Stoneb9c1b512016-09-06 20:57:50 +00004499 void IOHandlerInputComplete(IOHandler &io_handler,
4500 std::string &line) override {
4501 if (m_stop_hook_sp) {
4502 if (line.empty()) {
4503 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
4504 if (error_sp) {
4505 error_sp->Printf("error: stop hook #%" PRIu64
4506 " aborted, no commands.\n",
4507 m_stop_hook_sp->GetID());
4508 error_sp->Flush();
Greg Clayton44d93782014-01-27 23:43:24 +00004509 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004510 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Jim Ingham9575d842011-03-11 03:53:59 +00004511 if (target)
Kate Stoneb9c1b512016-09-06 20:57:50 +00004512 target->RemoveStopHookByID(m_stop_hook_sp->GetID());
4513 } else {
4514 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
4515 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4516 if (output_sp) {
4517 output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4518 m_stop_hook_sp->GetID());
4519 output_sp->Flush();
Jim Ingham9575d842011-03-11 03:53:59 +00004520 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004521 }
4522 m_stop_hook_sp.reset();
Jim Ingham9575d842011-03-11 03:53:59 +00004523 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004524 io_handler.SetIsDone(true);
4525 }
4526
4527 bool DoExecute(Args &command, CommandReturnObject &result) override {
4528 m_stop_hook_sp.reset();
4529
4530 Target *target = GetSelectedOrDummyTarget();
4531 if (target) {
4532 Target::StopHookSP new_hook_sp = target->CreateStopHook();
4533
4534 // First step, make the specifier.
4535 std::unique_ptr<SymbolContextSpecifier> specifier_ap;
4536 if (m_options.m_sym_ctx_specified) {
4537 specifier_ap.reset(new SymbolContextSpecifier(
4538 m_interpreter.GetDebugger().GetSelectedTarget()));
4539
4540 if (!m_options.m_module_name.empty()) {
4541 specifier_ap->AddSpecification(
4542 m_options.m_module_name.c_str(),
4543 SymbolContextSpecifier::eModuleSpecified);
4544 }
4545
4546 if (!m_options.m_class_name.empty()) {
4547 specifier_ap->AddSpecification(
4548 m_options.m_class_name.c_str(),
4549 SymbolContextSpecifier::eClassOrNamespaceSpecified);
4550 }
4551
4552 if (!m_options.m_file_name.empty()) {
4553 specifier_ap->AddSpecification(
4554 m_options.m_file_name.c_str(),
4555 SymbolContextSpecifier::eFileSpecified);
4556 }
4557
4558 if (m_options.m_line_start != 0) {
4559 specifier_ap->AddLineSpecification(
4560 m_options.m_line_start,
4561 SymbolContextSpecifier::eLineStartSpecified);
4562 }
4563
4564 if (m_options.m_line_end != UINT_MAX) {
4565 specifier_ap->AddLineSpecification(
4566 m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4567 }
4568
4569 if (!m_options.m_function_name.empty()) {
4570 specifier_ap->AddSpecification(
4571 m_options.m_function_name.c_str(),
4572 SymbolContextSpecifier::eFunctionSpecified);
4573 }
4574 }
4575
4576 if (specifier_ap)
4577 new_hook_sp->SetSpecifier(specifier_ap.release());
4578
4579 // Next see if any of the thread options have been entered:
4580
4581 if (m_options.m_thread_specified) {
4582 ThreadSpec *thread_spec = new ThreadSpec();
4583
4584 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4585 thread_spec->SetTID(m_options.m_thread_id);
4586 }
4587
4588 if (m_options.m_thread_index != UINT32_MAX)
4589 thread_spec->SetIndex(m_options.m_thread_index);
4590
4591 if (!m_options.m_thread_name.empty())
4592 thread_spec->SetName(m_options.m_thread_name.c_str());
4593
4594 if (!m_options.m_queue_name.empty())
4595 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4596
4597 new_hook_sp->SetThreadSpecifier(thread_spec);
4598 }
4599 if (m_options.m_use_one_liner) {
4600 // Use one-liner.
4601 new_hook_sp->GetCommandPointer()->AppendString(
4602 m_options.m_one_liner.c_str());
4603 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4604 new_hook_sp->GetID());
4605 } else {
4606 m_stop_hook_sp = new_hook_sp;
4607 m_interpreter.GetLLDBCommandsFromIOHandler(
4608 "> ", // Prompt
4609 *this, // IOHandlerDelegate
4610 true, // Run IOHandler in async mode
4611 nullptr); // Baton for the "io_handler" that will be passed back
4612 // into our IOHandlerDelegate functions
4613 }
4614 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4615 } else {
4616 result.AppendError("invalid target\n");
4617 result.SetStatus(eReturnStatusFailed);
4618 }
4619
4620 return result.Succeeded();
4621 }
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004622
Jim Ingham9575d842011-03-11 03:53:59 +00004623private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004624 CommandOptions m_options;
4625 Target::StopHookSP m_stop_hook_sp;
Jim Ingham9575d842011-03-11 03:53:59 +00004626};
4627
Greg Claytone0d378b2011-03-24 21:19:54 +00004628OptionDefinition
Kate Stoneb9c1b512016-09-06 20:57:50 +00004629 CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] = {
4630 // clang-format off
Kate Stoneac9c3a62016-08-26 23:28:47 +00004631 {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."},
4632 {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."},
4633 {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."},
4634 {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."},
4635 {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."},
4636 {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."},
4637 {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."},
4638 {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."},
4639 {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."},
4640 {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."},
4641 {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."},
4642 {0, false, nullptr, 0, 0, nullptr, nullptr, 0, eArgTypeNone, nullptr }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004643 // clang-format on
Jim Ingham9575d842011-03-11 03:53:59 +00004644};
4645
4646#pragma mark CommandObjectTargetStopHookDelete
4647
4648//-------------------------------------------------------------------------
4649// CommandObjectTargetStopHookDelete
4650//-------------------------------------------------------------------------
4651
Kate Stoneb9c1b512016-09-06 20:57:50 +00004652class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004653public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004654 CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4655 : CommandObjectParsed(interpreter, "target stop-hook delete",
4656 "Delete a stop-hook.",
4657 "target stop-hook delete [<idx>]") {}
Jim Ingham9575d842011-03-11 03:53:59 +00004658
Kate Stoneb9c1b512016-09-06 20:57:50 +00004659 ~CommandObjectTargetStopHookDelete() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004660
Jim Ingham5a988412012-06-08 21:56:10 +00004661protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004662 bool DoExecute(Args &command, CommandReturnObject &result) override {
4663 Target *target = GetSelectedOrDummyTarget();
4664 if (target) {
4665 // FIXME: see if we can use the breakpoint id style parser?
4666 size_t num_args = command.GetArgumentCount();
4667 if (num_args == 0) {
4668 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4669 result.SetStatus(eReturnStatusFailed);
4670 return false;
4671 } else {
4672 target->RemoveAllStopHooks();
Jim Ingham9575d842011-03-11 03:53:59 +00004673 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004674 } else {
4675 bool success;
4676 for (size_t i = 0; i < num_args; i++) {
4677 lldb::user_id_t user_id = StringConvert::ToUInt32(
4678 command.GetArgumentAtIndex(i), 0, 0, &success);
4679 if (!success) {
4680 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4681 command.GetArgumentAtIndex(i));
4682 result.SetStatus(eReturnStatusFailed);
4683 return false;
4684 }
4685 success = target->RemoveStopHookByID(user_id);
4686 if (!success) {
4687 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4688 command.GetArgumentAtIndex(i));
4689 result.SetStatus(eReturnStatusFailed);
4690 return false;
4691 }
Jim Ingham9575d842011-03-11 03:53:59 +00004692 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004693 }
4694 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4695 } else {
4696 result.AppendError("invalid target\n");
4697 result.SetStatus(eReturnStatusFailed);
Jim Ingham9575d842011-03-11 03:53:59 +00004698 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004699
4700 return result.Succeeded();
4701 }
Jim Ingham9575d842011-03-11 03:53:59 +00004702};
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004703
Jim Ingham9575d842011-03-11 03:53:59 +00004704#pragma mark CommandObjectTargetStopHookEnableDisable
4705
4706//-------------------------------------------------------------------------
4707// CommandObjectTargetStopHookEnableDisable
4708//-------------------------------------------------------------------------
4709
Kate Stoneb9c1b512016-09-06 20:57:50 +00004710class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004711public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004712 CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4713 bool enable, const char *name,
4714 const char *help, const char *syntax)
4715 : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4716 }
Jim Ingham9575d842011-03-11 03:53:59 +00004717
Kate Stoneb9c1b512016-09-06 20:57:50 +00004718 ~CommandObjectTargetStopHookEnableDisable() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004719
Jim Ingham5a988412012-06-08 21:56:10 +00004720protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004721 bool DoExecute(Args &command, CommandReturnObject &result) override {
4722 Target *target = GetSelectedOrDummyTarget();
4723 if (target) {
4724 // FIXME: see if we can use the breakpoint id style parser?
4725 size_t num_args = command.GetArgumentCount();
4726 bool success;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004727
Kate Stoneb9c1b512016-09-06 20:57:50 +00004728 if (num_args == 0) {
4729 target->SetAllStopHooksActiveState(m_enable);
4730 } else {
4731 for (size_t i = 0; i < num_args; i++) {
4732 lldb::user_id_t user_id = StringConvert::ToUInt32(
4733 command.GetArgumentAtIndex(i), 0, 0, &success);
4734 if (!success) {
4735 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4736 command.GetArgumentAtIndex(i));
4737 result.SetStatus(eReturnStatusFailed);
4738 return false;
4739 }
4740 success = target->SetStopHookActiveStateByID(user_id, m_enable);
4741 if (!success) {
4742 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4743 command.GetArgumentAtIndex(i));
4744 result.SetStatus(eReturnStatusFailed);
4745 return false;
4746 }
Jim Ingham9575d842011-03-11 03:53:59 +00004747 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004748 }
4749 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4750 } else {
4751 result.AppendError("invalid target\n");
4752 result.SetStatus(eReturnStatusFailed);
Jim Ingham9575d842011-03-11 03:53:59 +00004753 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004754 return result.Succeeded();
4755 }
4756
Jim Ingham9575d842011-03-11 03:53:59 +00004757private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004758 bool m_enable;
Jim Ingham9575d842011-03-11 03:53:59 +00004759};
4760
4761#pragma mark CommandObjectTargetStopHookList
4762
4763//-------------------------------------------------------------------------
4764// CommandObjectTargetStopHookList
4765//-------------------------------------------------------------------------
4766
Kate Stoneb9c1b512016-09-06 20:57:50 +00004767class CommandObjectTargetStopHookList : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004768public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004769 CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4770 : CommandObjectParsed(interpreter, "target stop-hook list",
4771 "List all stop-hooks.",
4772 "target stop-hook list [<type>]") {}
Jim Ingham9575d842011-03-11 03:53:59 +00004773
Kate Stoneb9c1b512016-09-06 20:57:50 +00004774 ~CommandObjectTargetStopHookList() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004775
Jim Ingham5a988412012-06-08 21:56:10 +00004776protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004777 bool DoExecute(Args &command, CommandReturnObject &result) override {
4778 Target *target = GetSelectedOrDummyTarget();
4779 if (!target) {
4780 result.AppendError("invalid target\n");
4781 result.SetStatus(eReturnStatusFailed);
4782 return result.Succeeded();
Jim Ingham9575d842011-03-11 03:53:59 +00004783 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004784
4785 size_t num_hooks = target->GetNumStopHooks();
4786 if (num_hooks == 0) {
4787 result.GetOutputStream().PutCString("No stop hooks.\n");
4788 } else {
4789 for (size_t i = 0; i < num_hooks; i++) {
4790 Target::StopHookSP this_hook = target->GetStopHookAtIndex(i);
4791 if (i > 0)
4792 result.GetOutputStream().PutCString("\n");
4793 this_hook->GetDescription(&(result.GetOutputStream()),
4794 eDescriptionLevelFull);
4795 }
4796 }
4797 result.SetStatus(eReturnStatusSuccessFinishResult);
4798 return result.Succeeded();
4799 }
Jim Ingham9575d842011-03-11 03:53:59 +00004800};
4801
4802#pragma mark CommandObjectMultiwordTargetStopHooks
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004803
Jim Ingham9575d842011-03-11 03:53:59 +00004804//-------------------------------------------------------------------------
4805// CommandObjectMultiwordTargetStopHooks
4806//-------------------------------------------------------------------------
4807
Kate Stoneb9c1b512016-09-06 20:57:50 +00004808class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
Jim Ingham9575d842011-03-11 03:53:59 +00004809public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004810 CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4811 : CommandObjectMultiword(
4812 interpreter, "target stop-hook",
4813 "Commands for operating on debugger target stop-hooks.",
4814 "target stop-hook <subcommand> [<subcommand-options>]") {
4815 LoadSubCommand("add", CommandObjectSP(
4816 new CommandObjectTargetStopHookAdd(interpreter)));
4817 LoadSubCommand(
4818 "delete",
4819 CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
4820 LoadSubCommand("disable",
4821 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4822 interpreter, false, "target stop-hook disable [<id>]",
4823 "Disable a stop-hook.", "target stop-hook disable")));
4824 LoadSubCommand("enable",
4825 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4826 interpreter, true, "target stop-hook enable [<id>]",
4827 "Enable a stop-hook.", "target stop-hook enable")));
4828 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
4829 interpreter)));
4830 }
Jim Ingham9575d842011-03-11 03:53:59 +00004831
Kate Stoneb9c1b512016-09-06 20:57:50 +00004832 ~CommandObjectMultiwordTargetStopHooks() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004833};
4834
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004835#pragma mark CommandObjectMultiwordTarget
4836
4837//-------------------------------------------------------------------------
4838// CommandObjectMultiwordTarget
4839//-------------------------------------------------------------------------
4840
Kate Stoneb9c1b512016-09-06 20:57:50 +00004841CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
4842 CommandInterpreter &interpreter)
4843 : CommandObjectMultiword(interpreter, "target",
4844 "Commands for operating on debugger targets.",
4845 "target <subcommand> [<subcommand-options>]") {
4846 LoadSubCommand("create",
4847 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
4848 LoadSubCommand("delete",
4849 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
4850 LoadSubCommand("list",
4851 CommandObjectSP(new CommandObjectTargetList(interpreter)));
4852 LoadSubCommand("select",
4853 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
4854 LoadSubCommand(
4855 "stop-hook",
4856 CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
4857 LoadSubCommand("modules",
4858 CommandObjectSP(new CommandObjectTargetModules(interpreter)));
4859 LoadSubCommand("symbols",
4860 CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
4861 LoadSubCommand("variable",
4862 CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004863}
4864
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004865CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;