blob: c8871c8de6e0fc39c4293bbe7c3c673379536f42 [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectTarget.h"
11
Chris Lattner30fdc8d2010-06-08 16:52:24 +000012// Project includes
Chris Lattner30fdc8d2010-06-08 16:52:24 +000013#include "lldb/Core/Debugger.h"
Greg Clayton44d93782014-01-27 23:43:24 +000014#include "lldb/Core/IOHandler.h"
Greg Clayton1f746072012-08-29 21:13:06 +000015#include "lldb/Core/Module.h"
16#include "lldb/Core/ModuleSpec.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000017#include "lldb/Core/Section.h"
Greg Clayton7260f622011-04-18 08:33:37 +000018#include "lldb/Core/State.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000019#include "lldb/Core/Timer.h"
Greg Clayton644247c2011-07-07 01:59:51 +000020#include "lldb/Core/ValueObjectVariable.h"
Enrico Granata4d93b8c2013-09-30 19:11:51 +000021#include "lldb/DataFormatters/ValueObjectPrinter.h"
Vince Harron5275aaa2015-01-15 20:08:35 +000022#include "lldb/Host/StringConvert.h"
Greg Claytonc8f814d2012-09-27 03:13:55 +000023#include "lldb/Host/Symbols.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000024#include "lldb/Interpreter/Args.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000025#include "lldb/Interpreter/CommandInterpreter.h"
26#include "lldb/Interpreter/CommandReturnObject.h"
Greg Clayton7260f622011-04-18 08:33:37 +000027#include "lldb/Interpreter/OptionGroupArchitecture.h"
Greg Claytonaa149cb2011-08-11 02:48:45 +000028#include "lldb/Interpreter/OptionGroupBoolean.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000029#include "lldb/Interpreter/OptionGroupFile.h"
Greg Clayton1deb7962011-10-25 06:44:01 +000030#include "lldb/Interpreter/OptionGroupFormat.h"
Greg Clayton7260f622011-04-18 08:33:37 +000031#include "lldb/Interpreter/OptionGroupPlatform.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000032#include "lldb/Interpreter/OptionGroupString.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000033#include "lldb/Interpreter/OptionGroupUInt64.h"
34#include "lldb/Interpreter/OptionGroupUUID.h"
Greg Clayton644247c2011-07-07 01:59:51 +000035#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000036#include "lldb/Interpreter/OptionGroupVariable.h"
37#include "lldb/Interpreter/Options.h"
Greg Clayton1f746072012-08-29 21:13:06 +000038#include "lldb/Symbol/CompileUnit.h"
Jason Molenda380241a2012-07-12 00:20:07 +000039#include "lldb/Symbol/FuncUnwinders.h"
Greg Claytoneffe5c92011-05-03 22:09:39 +000040#include "lldb/Symbol/LineTable.h"
41#include "lldb/Symbol/ObjectFile.h"
42#include "lldb/Symbol/SymbolFile.h"
43#include "lldb/Symbol/SymbolVendor.h"
Jason Molenda380241a2012-07-12 00:20:07 +000044#include "lldb/Symbol/UnwindPlan.h"
Greg Clayton644247c2011-07-07 01:59:51 +000045#include "lldb/Symbol/VariableList.h"
Zachary Turner32abc6e2015-03-03 19:23:09 +000046#include "lldb/Target/ABI.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000047#include "lldb/Target/Process.h"
Greg Claytond5944cd2013-12-06 01:12:00 +000048#include "lldb/Target/SectionLoadList.h"
Jason Molendab57e4a12013-11-04 09:33:30 +000049#include "lldb/Target/StackFrame.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000050#include "lldb/Target/Thread.h"
Jim Ingham9575d842011-03-11 03:53:59 +000051#include "lldb/Target/ThreadSpec.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000052
Zachary Turner7d86ee52017-03-08 17:56:08 +000053#include "llvm/Support/FileSystem.h"
54
Pavel Labath7e2cfbf2016-11-09 09:59:18 +000055// C Includes
56// C++ Includes
57#include <cerrno>
58
Chris Lattner30fdc8d2010-06-08 16:52:24 +000059using namespace lldb;
60using namespace lldb_private;
61
Kate Stoneb9c1b512016-09-06 20:57:50 +000062static void DumpTargetInfo(uint32_t target_idx, Target *target,
63 const char *prefix_cstr,
64 bool show_stopped_process_status, Stream &strm) {
65 const ArchSpec &target_arch = target->GetArchitecture();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000066
Kate Stoneb9c1b512016-09-06 20:57:50 +000067 Module *exe_module = target->GetExecutableModulePointer();
68 char exe_path[PATH_MAX];
69 bool exe_valid = false;
70 if (exe_module)
71 exe_valid = exe_module->GetFileSpec().GetPath(exe_path, sizeof(exe_path));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000072
Kate Stoneb9c1b512016-09-06 20:57:50 +000073 if (!exe_valid)
74 ::strcpy(exe_path, "<none>");
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000075
Kate Stoneb9c1b512016-09-06 20:57:50 +000076 strm.Printf("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx,
77 exe_path);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000078
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 uint32_t properties = 0;
80 if (target_arch.IsValid()) {
81 strm.Printf("%sarch=", properties++ > 0 ? ", " : " ( ");
82 target_arch.DumpTriple(strm);
83 properties++;
84 }
85 PlatformSP platform_sp(target->GetPlatform());
86 if (platform_sp)
87 strm.Printf("%splatform=%s", properties++ > 0 ? ", " : " ( ",
88 platform_sp->GetName().GetCString());
Saleem Abdulrasool324a1032014-04-04 04:06:10 +000089
Kate Stoneb9c1b512016-09-06 20:57:50 +000090 ProcessSP process_sp(target->GetProcessSP());
91 bool show_process_status = false;
92 if (process_sp) {
93 lldb::pid_t pid = process_sp->GetID();
94 StateType state = process_sp->GetState();
95 if (show_stopped_process_status)
96 show_process_status = StateIsStoppedState(state, true);
97 const char *state_cstr = StateAsCString(state);
98 if (pid != LLDB_INVALID_PROCESS_ID)
99 strm.Printf("%spid=%" PRIu64, properties++ > 0 ? ", " : " ( ", pid);
100 strm.Printf("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
101 }
102 if (properties > 0)
103 strm.PutCString(" )\n");
104 else
105 strm.EOL();
106 if (show_process_status) {
107 const bool only_threads_with_stop_reason = true;
108 const uint32_t start_frame = 0;
109 const uint32_t num_frames = 1;
110 const uint32_t num_frames_with_source = 1;
Jim Ingham6a9767c2016-11-08 20:36:40 +0000111 const bool stop_format = false;
Kate Stoneb9c1b512016-09-06 20:57:50 +0000112 process_sp->GetStatus(strm);
113 process_sp->GetThreadStatus(strm, only_threads_with_stop_reason,
114 start_frame, num_frames,
Jim Ingham6a9767c2016-11-08 20:36:40 +0000115 num_frames_with_source, stop_format);
Kate Stoneb9c1b512016-09-06 20:57:50 +0000116 }
Greg Clayton7260f622011-04-18 08:33:37 +0000117}
118
Kate Stoneb9c1b512016-09-06 20:57:50 +0000119static uint32_t DumpTargetList(TargetList &target_list,
120 bool show_stopped_process_status, Stream &strm) {
121 const uint32_t num_targets = target_list.GetNumTargets();
122 if (num_targets) {
123 TargetSP selected_target_sp(target_list.GetSelectedTarget());
124 strm.PutCString("Current targets:\n");
125 for (uint32_t i = 0; i < num_targets; ++i) {
126 TargetSP target_sp(target_list.GetTargetAtIndex(i));
127 if (target_sp) {
128 bool is_selected = target_sp.get() == selected_target_sp.get();
129 DumpTargetInfo(i, target_sp.get(), is_selected ? "* " : " ",
130 show_stopped_process_status, strm);
131 }
Greg Clayton7260f622011-04-18 08:33:37 +0000132 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000133 }
134 return num_targets;
Greg Clayton7260f622011-04-18 08:33:37 +0000135}
Eugene Zelenkof13e6522016-02-25 19:02:39 +0000136
Pavel Labath8cb1cd92016-11-16 10:54:22 +0000137// TODO: Remove this once llvm can pretty-print time points
138static void DumpTimePoint(llvm::sys::TimePoint<> tp, Stream &s, uint32_t width) {
139#ifndef LLDB_DISABLE_POSIX
140 char time_buf[32];
141 time_t time = llvm::sys::toTimeT(tp);
142 char *time_cstr = ::ctime_r(&time, time_buf);
143 if (time_cstr) {
144 char *newline = ::strpbrk(time_cstr, "\n\r");
145 if (newline)
146 *newline = '\0';
147 if (width > 0)
148 s.Printf("%-*s", width, time_cstr);
149 else
150 s.PutCString(time_cstr);
151 } else if (width > 0)
152 s.Printf("%-*s", width, "");
153#endif
154}
155
Greg Clayton7260f622011-04-18 08:33:37 +0000156#pragma mark CommandObjectTargetCreate
157
158//-------------------------------------------------------------------------
159// "target create"
160//-------------------------------------------------------------------------
161
Kate Stoneb9c1b512016-09-06 20:57:50 +0000162class CommandObjectTargetCreate : public CommandObjectParsed {
Greg Clayton7260f622011-04-18 08:33:37 +0000163public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000164 CommandObjectTargetCreate(CommandInterpreter &interpreter)
165 : CommandObjectParsed(
166 interpreter, "target create",
167 "Create a target using the argument as the main executable.",
168 nullptr),
169 m_option_group(), m_arch_option(),
170 m_core_file(LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypeFilename,
171 "Fullpath to a core file to use for this target."),
172 m_platform_path(LLDB_OPT_SET_1, false, "platform-path", 'P', 0,
173 eArgTypePath,
174 "Path to the remote file to use for this target."),
175 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
176 eArgTypeFilename, "Fullpath to a stand alone debug "
177 "symbols file for when debug symbols "
178 "are not in the executable."),
179 m_remote_file(
180 LLDB_OPT_SET_1, false, "remote-file", 'r', 0, eArgTypeFilename,
181 "Fullpath to the file on the remote host if debugging remotely."),
182 m_add_dependents(LLDB_OPT_SET_1, false, "no-dependents", 'd',
183 "Don't load dependent files when creating the target, "
184 "just add the specified executable.",
185 true, true) {
186 CommandArgumentEntry arg;
187 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000188
Kate Stoneb9c1b512016-09-06 20:57:50 +0000189 // Define the first (and only) variant of this arg.
190 file_arg.arg_type = eArgTypeFilename;
191 file_arg.arg_repetition = eArgRepeatPlain;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000192
Kate Stoneb9c1b512016-09-06 20:57:50 +0000193 // There is only one variant this argument could be; put it into the
194 // argument entry.
195 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000196
Kate Stoneb9c1b512016-09-06 20:57:50 +0000197 // Push the data for the first argument into the m_arguments vector.
198 m_arguments.push_back(arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000199
Kate Stoneb9c1b512016-09-06 20:57:50 +0000200 m_option_group.Append(&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
201 m_option_group.Append(&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
202 m_option_group.Append(&m_platform_path, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
203 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
204 m_option_group.Append(&m_remote_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
205 m_option_group.Append(&m_add_dependents, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
206 m_option_group.Finalize();
207 }
Greg Clayton7260f622011-04-18 08:33:37 +0000208
Kate Stoneb9c1b512016-09-06 20:57:50 +0000209 ~CommandObjectTargetCreate() override = default;
Greg Clayton7260f622011-04-18 08:33:37 +0000210
Kate Stoneb9c1b512016-09-06 20:57:50 +0000211 Options *GetOptions() override { return &m_option_group; }
Greg Clayton7260f622011-04-18 08:33:37 +0000212
Kate Stoneb9c1b512016-09-06 20:57:50 +0000213 int HandleArgumentCompletion(Args &input, int &cursor_index,
214 int &cursor_char_position,
215 OptionElementVector &opt_element_vector,
216 int match_start_point, int max_return_elements,
217 bool &word_complete,
218 StringList &matches) override {
219 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
220 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000221
Kate Stoneb9c1b512016-09-06 20:57:50 +0000222 CommandCompletions::InvokeCommonCompletionCallbacks(
223 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
224 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
225 word_complete, matches);
226 return matches.GetSize();
227 }
Jim Ingham5a988412012-06-08 21:56:10 +0000228
229protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000230 bool DoExecute(Args &command, CommandReturnObject &result) override {
231 const size_t argc = command.GetArgumentCount();
232 FileSpec core_file(m_core_file.GetOptionValue().GetCurrentValue());
233 FileSpec remote_file(m_remote_file.GetOptionValue().GetCurrentValue());
Greg Claytonc3776bf2012-02-09 06:16:32 +0000234
Kate Stoneb9c1b512016-09-06 20:57:50 +0000235 if (core_file) {
236 if (!core_file.Exists()) {
237 result.AppendErrorWithFormat("core file '%s' doesn't exist",
238 core_file.GetPath().c_str());
239 result.SetStatus(eReturnStatusFailed);
240 return false;
241 }
242 if (!core_file.Readable()) {
243 result.AppendErrorWithFormat("core file '%s' is not readable",
244 core_file.GetPath().c_str());
245 result.SetStatus(eReturnStatusFailed);
246 return false;
247 }
Greg Clayton7260f622011-04-18 08:33:37 +0000248 }
249
Kate Stoneb9c1b512016-09-06 20:57:50 +0000250 if (argc == 1 || core_file || remote_file) {
251 FileSpec symfile(m_symbol_file.GetOptionValue().GetCurrentValue());
252 if (symfile) {
253 if (symfile.Exists()) {
254 if (!symfile.Readable()) {
255 result.AppendErrorWithFormat("symbol file '%s' is not readable",
256 symfile.GetPath().c_str());
257 result.SetStatus(eReturnStatusFailed);
258 return false;
259 }
260 } else {
261 char symfile_path[PATH_MAX];
262 symfile.GetPath(symfile_path, sizeof(symfile_path));
263 result.AppendErrorWithFormat("invalid symbol file path '%s'",
264 symfile_path);
265 result.SetStatus(eReturnStatusFailed);
266 return false;
267 }
268 }
269
270 const char *file_path = command.GetArgumentAtIndex(0);
271 Timer scoped_timer(LLVM_PRETTY_FUNCTION, "(lldb) target create '%s'",
272 file_path);
273 FileSpec file_spec;
274
275 if (file_path)
276 file_spec.SetFile(file_path, true);
277
278 bool must_set_platform_path = false;
279
280 Debugger &debugger = m_interpreter.GetDebugger();
281
282 TargetSP target_sp;
Zachary Turnera47464b2016-11-18 20:44:46 +0000283 llvm::StringRef arch_cstr = m_arch_option.GetArchitectureName();
Kate Stoneb9c1b512016-09-06 20:57:50 +0000284 const bool get_dependent_files =
285 m_add_dependents.GetOptionValue().GetCurrentValue();
286 Error error(debugger.GetTargetList().CreateTarget(
287 debugger, file_path, arch_cstr, get_dependent_files, nullptr,
288 target_sp));
289
290 if (target_sp) {
291 // Only get the platform after we create the target because we might
292 // have
293 // switched platforms depending on what the arguments were to
294 // CreateTarget()
295 // we can't rely on the selected platform.
296
297 PlatformSP platform_sp = target_sp->GetPlatform();
298
299 if (remote_file) {
300 if (platform_sp) {
301 // I have a remote file.. two possible cases
302 if (file_spec && file_spec.Exists()) {
303 // if the remote file does not exist, push it there
304 if (!platform_sp->GetFileExists(remote_file)) {
305 Error err = platform_sp->PutFile(file_spec, remote_file);
306 if (err.Fail()) {
307 result.AppendError(err.AsCString());
308 result.SetStatus(eReturnStatusFailed);
309 return false;
310 }
311 }
312 } else {
313 // there is no local file and we need one
314 // in order to make the remote ---> local transfer we need a
315 // platform
316 // TODO: if the user has passed in a --platform argument, use it
317 // to fetch the right platform
318 if (!platform_sp) {
319 result.AppendError(
320 "unable to perform remote debugging without a platform");
321 result.SetStatus(eReturnStatusFailed);
322 return false;
323 }
324 if (file_path) {
325 // copy the remote file to the local file
326 Error err = platform_sp->GetFile(remote_file, file_spec);
327 if (err.Fail()) {
328 result.AppendError(err.AsCString());
329 result.SetStatus(eReturnStatusFailed);
330 return false;
331 }
332 } else {
333 // make up a local file
334 result.AppendError("remote --> local transfer without local "
335 "path is not implemented yet");
336 result.SetStatus(eReturnStatusFailed);
337 return false;
338 }
339 }
340 } else {
341 result.AppendError("no platform found for target");
342 result.SetStatus(eReturnStatusFailed);
343 return false;
344 }
345 }
346
347 if (symfile || remote_file) {
348 ModuleSP module_sp(target_sp->GetExecutableModule());
349 if (module_sp) {
350 if (symfile)
351 module_sp->SetSymbolFileFileSpec(symfile);
352 if (remote_file) {
353 std::string remote_path = remote_file.GetPath();
354 target_sp->SetArg0(remote_path.c_str());
355 module_sp->SetPlatformFileSpec(remote_file);
356 }
357 }
358 }
359
360 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
361 if (must_set_platform_path) {
362 ModuleSpec main_module_spec(file_spec);
363 ModuleSP module_sp = target_sp->GetSharedModule(main_module_spec);
364 if (module_sp)
365 module_sp->SetPlatformFileSpec(remote_file);
366 }
367 if (core_file) {
368 char core_path[PATH_MAX];
369 core_file.GetPath(core_path, sizeof(core_path));
370 if (core_file.Exists()) {
371 if (!core_file.Readable()) {
372 result.AppendMessageWithFormat(
373 "Core file '%s' is not readable.\n", core_path);
374 result.SetStatus(eReturnStatusFailed);
375 return false;
376 }
377 FileSpec core_file_dir;
378 core_file_dir.GetDirectory() = core_file.GetDirectory();
379 target_sp->GetExecutableSearchPaths().Append(core_file_dir);
380
381 ProcessSP process_sp(target_sp->CreateProcess(
Zachary Turner31659452016-11-17 21:15:14 +0000382 m_interpreter.GetDebugger().GetListener(), llvm::StringRef(),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000383 &core_file));
384
385 if (process_sp) {
386 // Seems weird that we Launch a core file, but that is
387 // what we do!
388 error = process_sp->LoadCore();
389
390 if (error.Fail()) {
391 result.AppendError(
392 error.AsCString("can't find plug-in for core file"));
393 result.SetStatus(eReturnStatusFailed);
394 return false;
395 } else {
396 result.AppendMessageWithFormat(
397 "Core file '%s' (%s) was loaded.\n", core_path,
398 target_sp->GetArchitecture().GetArchitectureName());
399 result.SetStatus(eReturnStatusSuccessFinishNoResult);
400 }
401 } else {
402 result.AppendErrorWithFormat(
403 "Unable to find process plug-in for core file '%s'\n",
404 core_path);
405 result.SetStatus(eReturnStatusFailed);
406 }
407 } else {
408 result.AppendErrorWithFormat("Core file '%s' does not exist\n",
409 core_path);
410 result.SetStatus(eReturnStatusFailed);
411 }
412 } else {
413 result.AppendMessageWithFormat(
414 "Current executable set to '%s' (%s).\n", file_path,
415 target_sp->GetArchitecture().GetArchitectureName());
416 result.SetStatus(eReturnStatusSuccessFinishNoResult);
417 }
418 } else {
419 result.AppendError(error.AsCString());
420 result.SetStatus(eReturnStatusFailed);
421 }
422 } else {
423 result.AppendErrorWithFormat("'%s' takes exactly one executable path "
424 "argument, or use the --core option.\n",
425 m_cmd_name.c_str());
426 result.SetStatus(eReturnStatusFailed);
427 }
428 return result.Succeeded();
429 }
430
Greg Clayton7260f622011-04-18 08:33:37 +0000431private:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000432 OptionGroupOptions m_option_group;
433 OptionGroupArchitecture m_arch_option;
434 OptionGroupFile m_core_file;
435 OptionGroupFile m_platform_path;
436 OptionGroupFile m_symbol_file;
437 OptionGroupFile m_remote_file;
438 OptionGroupBoolean m_add_dependents;
Greg Clayton7260f622011-04-18 08:33:37 +0000439};
440
441#pragma mark CommandObjectTargetList
442
443//----------------------------------------------------------------------
444// "target list"
445//----------------------------------------------------------------------
446
Kate Stoneb9c1b512016-09-06 20:57:50 +0000447class CommandObjectTargetList : public CommandObjectParsed {
Greg Clayton7260f622011-04-18 08:33:37 +0000448public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000449 CommandObjectTargetList(CommandInterpreter &interpreter)
450 : CommandObjectParsed(
451 interpreter, "target list",
452 "List all current targets in the current debug session.", nullptr) {
453 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000454
Kate Stoneb9c1b512016-09-06 20:57:50 +0000455 ~CommandObjectTargetList() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000456
Jim Ingham5a988412012-06-08 21:56:10 +0000457protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000458 bool DoExecute(Args &args, CommandReturnObject &result) override {
459 if (args.GetArgumentCount() == 0) {
460 Stream &strm = result.GetOutputStream();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000461
Kate Stoneb9c1b512016-09-06 20:57:50 +0000462 bool show_stopped_process_status = false;
463 if (DumpTargetList(m_interpreter.GetDebugger().GetTargetList(),
464 show_stopped_process_status, strm) == 0) {
465 strm.PutCString("No targets.\n");
466 }
467 result.SetStatus(eReturnStatusSuccessFinishResult);
468 } else {
469 result.AppendError("the 'target list' command takes no arguments\n");
470 result.SetStatus(eReturnStatusFailed);
Greg Clayton7260f622011-04-18 08:33:37 +0000471 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000472 return result.Succeeded();
473 }
Greg Clayton7260f622011-04-18 08:33:37 +0000474};
475
Greg Clayton7260f622011-04-18 08:33:37 +0000476#pragma mark CommandObjectTargetSelect
477
478//----------------------------------------------------------------------
479// "target select"
480//----------------------------------------------------------------------
481
Kate Stoneb9c1b512016-09-06 20:57:50 +0000482class CommandObjectTargetSelect : public CommandObjectParsed {
Greg Clayton7260f622011-04-18 08:33:37 +0000483public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000484 CommandObjectTargetSelect(CommandInterpreter &interpreter)
485 : CommandObjectParsed(
486 interpreter, "target select",
487 "Select a target as the current target by target index.", nullptr) {
488 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000489
Kate Stoneb9c1b512016-09-06 20:57:50 +0000490 ~CommandObjectTargetSelect() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000491
Jim Ingham5a988412012-06-08 21:56:10 +0000492protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000493 bool DoExecute(Args &args, CommandReturnObject &result) override {
494 if (args.GetArgumentCount() == 1) {
495 bool success = false;
496 const char *target_idx_arg = args.GetArgumentAtIndex(0);
497 uint32_t target_idx =
498 StringConvert::ToUInt32(target_idx_arg, UINT32_MAX, 0, &success);
499 if (success) {
500 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
501 const uint32_t num_targets = target_list.GetNumTargets();
502 if (target_idx < num_targets) {
503 TargetSP target_sp(target_list.GetTargetAtIndex(target_idx));
504 if (target_sp) {
505 Stream &strm = result.GetOutputStream();
506 target_list.SetSelectedTarget(target_sp.get());
507 bool show_stopped_process_status = false;
508 DumpTargetList(target_list, show_stopped_process_status, strm);
509 result.SetStatus(eReturnStatusSuccessFinishResult);
510 } else {
511 result.AppendErrorWithFormat("target #%u is NULL in target list\n",
512 target_idx);
513 result.SetStatus(eReturnStatusFailed);
514 }
515 } else {
516 if (num_targets > 0) {
517 result.AppendErrorWithFormat(
518 "index %u is out of range, valid target indexes are 0 - %u\n",
519 target_idx, num_targets - 1);
520 } else {
521 result.AppendErrorWithFormat(
522 "index %u is out of range since there are no active targets\n",
523 target_idx);
524 }
525 result.SetStatus(eReturnStatusFailed);
Greg Clayton7260f622011-04-18 08:33:37 +0000526 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000527 } else {
528 result.AppendErrorWithFormat("invalid index string value '%s'\n",
529 target_idx_arg);
530 result.SetStatus(eReturnStatusFailed);
531 }
532 } else {
533 result.AppendError(
534 "'target select' takes a single argument: a target index\n");
535 result.SetStatus(eReturnStatusFailed);
Greg Clayton7260f622011-04-18 08:33:37 +0000536 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000537 return result.Succeeded();
538 }
Greg Clayton7260f622011-04-18 08:33:37 +0000539};
540
Greg Clayton3418c852011-08-10 02:10:13 +0000541#pragma mark CommandObjectTargetSelect
542
543//----------------------------------------------------------------------
544// "target delete"
545//----------------------------------------------------------------------
546
Kate Stoneb9c1b512016-09-06 20:57:50 +0000547class CommandObjectTargetDelete : public CommandObjectParsed {
Greg Clayton3418c852011-08-10 02:10:13 +0000548public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000549 CommandObjectTargetDelete(CommandInterpreter &interpreter)
550 : CommandObjectParsed(interpreter, "target delete",
Eugene Zelenkof13e6522016-02-25 19:02:39 +0000551 "Delete one or more targets by target index.",
552 nullptr),
Kate Stoneb9c1b512016-09-06 20:57:50 +0000553 m_option_group(), m_all_option(LLDB_OPT_SET_1, false, "all", 'a',
554 "Delete all targets.", false, true),
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000555 m_cleanup_option(
Kate Stoneb9c1b512016-09-06 20:57:50 +0000556 LLDB_OPT_SET_1, false, "clean", 'c',
557 "Perform extra cleanup to minimize memory consumption after "
558 "deleting the target. "
559 "By default, LLDB will keep in memory any modules previously "
560 "loaded by the target as well "
561 "as all of its debug info. Specifying --clean will unload all of "
562 "these shared modules and "
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000563 "cause them to be reparsed again the next time the target is run",
Kate Stoneb9c1b512016-09-06 20:57:50 +0000564 false, true) {
565 m_option_group.Append(&m_all_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
566 m_option_group.Append(&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
567 m_option_group.Finalize();
568 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000569
Kate Stoneb9c1b512016-09-06 20:57:50 +0000570 ~CommandObjectTargetDelete() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000571
Kate Stoneb9c1b512016-09-06 20:57:50 +0000572 Options *GetOptions() override { return &m_option_group; }
Jim Ingham5a988412012-06-08 21:56:10 +0000573
574protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000575 bool DoExecute(Args &args, CommandReturnObject &result) override {
576 const size_t argc = args.GetArgumentCount();
577 std::vector<TargetSP> delete_target_list;
578 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
579 TargetSP target_sp;
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000580
Kate Stoneb9c1b512016-09-06 20:57:50 +0000581 if (m_all_option.GetOptionValue()) {
582 for (int i = 0; i < target_list.GetNumTargets(); ++i)
583 delete_target_list.push_back(target_list.GetTargetAtIndex(i));
584 } else if (argc > 0) {
585 const uint32_t num_targets = target_list.GetNumTargets();
586 // Bail out if don't have any targets.
587 if (num_targets == 0) {
588 result.AppendError("no targets to delete");
589 result.SetStatus(eReturnStatusFailed);
590 return false;
591 }
592
Zachary Turner97d2c402016-10-05 23:40:23 +0000593 for (auto &entry : args.entries()) {
594 uint32_t target_idx;
595 if (entry.ref.getAsInteger(0, target_idx)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +0000596 result.AppendErrorWithFormat("invalid target index '%s'\n",
Zachary Turner97d2c402016-10-05 23:40:23 +0000597 entry.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +0000598 result.SetStatus(eReturnStatusFailed);
599 return false;
Zachary Turneraa4dabf2015-03-26 16:43:13 +0000600 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000601 if (target_idx < num_targets) {
602 target_sp = target_list.GetTargetAtIndex(target_idx);
603 if (target_sp) {
604 delete_target_list.push_back(target_sp);
605 continue;
606 }
Greg Clayton3418c852011-08-10 02:10:13 +0000607 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000608 if (num_targets > 1)
609 result.AppendErrorWithFormat("target index %u is out of range, valid "
610 "target indexes are 0 - %u\n",
611 target_idx, num_targets - 1);
Greg Clayton3418c852011-08-10 02:10:13 +0000612 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000613 result.AppendErrorWithFormat(
614 "target index %u is out of range, the only valid index is 0\n",
615 target_idx);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000616
Kate Stoneb9c1b512016-09-06 20:57:50 +0000617 result.SetStatus(eReturnStatusFailed);
618 return false;
619 }
620 } else {
621 target_sp = target_list.GetSelectedTarget();
622 if (!target_sp) {
623 result.AppendErrorWithFormat("no target is currently selected\n");
624 result.SetStatus(eReturnStatusFailed);
625 return false;
626 }
627 delete_target_list.push_back(target_sp);
Greg Clayton3418c852011-08-10 02:10:13 +0000628 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000629
Kate Stoneb9c1b512016-09-06 20:57:50 +0000630 const size_t num_targets_to_delete = delete_target_list.size();
631 for (size_t idx = 0; idx < num_targets_to_delete; ++idx) {
632 target_sp = delete_target_list[idx];
633 target_list.DeleteTarget(target_sp);
634 target_sp->Destroy();
635 }
636 // If "--clean" was specified, prune any orphaned shared modules from
637 // the global shared module list
638 if (m_cleanup_option.GetOptionValue()) {
639 const bool mandatory = true;
640 ModuleList::RemoveOrphanSharedModules(mandatory);
641 }
642 result.GetOutputStream().Printf("%u targets deleted.\n",
643 (uint32_t)num_targets_to_delete);
644 result.SetStatus(eReturnStatusSuccessFinishResult);
645
646 return true;
647 }
648
649 OptionGroupOptions m_option_group;
650 OptionGroupBoolean m_all_option;
651 OptionGroupBoolean m_cleanup_option;
Greg Clayton3418c852011-08-10 02:10:13 +0000652};
653
Greg Clayton644247c2011-07-07 01:59:51 +0000654#pragma mark CommandObjectTargetVariable
655
656//----------------------------------------------------------------------
657// "target variable"
658//----------------------------------------------------------------------
659
Kate Stoneb9c1b512016-09-06 20:57:50 +0000660class CommandObjectTargetVariable : public CommandObjectParsed {
661 static const uint32_t SHORT_OPTION_FILE = 0x66696c65; // 'file'
662 static const uint32_t SHORT_OPTION_SHLB = 0x73686c62; // 'shlb'
Saleem Abdulrasool44edda02014-03-18 04:43:47 +0000663
Greg Clayton644247c2011-07-07 01:59:51 +0000664public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000665 CommandObjectTargetVariable(CommandInterpreter &interpreter)
666 : CommandObjectParsed(interpreter, "target variable",
667 "Read global variables for the current target, "
668 "before or while running a process.",
669 nullptr, eCommandRequiresTarget),
670 m_option_group(),
671 m_option_variable(false), // Don't include frame options
672 m_option_format(eFormatDefault),
673 m_option_compile_units(LLDB_OPT_SET_1, false, "file", SHORT_OPTION_FILE,
674 0, eArgTypeFilename,
675 "A basename or fullpath to a file that contains "
676 "global variables. This option can be "
677 "specified multiple times."),
678 m_option_shared_libraries(
679 LLDB_OPT_SET_1, false, "shlib", SHORT_OPTION_SHLB, 0,
680 eArgTypeFilename,
681 "A basename or fullpath to a shared library to use in the search "
682 "for global "
683 "variables. This option can be specified multiple times."),
684 m_varobj_options() {
685 CommandArgumentEntry arg;
686 CommandArgumentData var_name_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000687
Kate Stoneb9c1b512016-09-06 20:57:50 +0000688 // Define the first (and only) variant of this arg.
689 var_name_arg.arg_type = eArgTypeVarName;
690 var_name_arg.arg_repetition = eArgRepeatPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000691
Kate Stoneb9c1b512016-09-06 20:57:50 +0000692 // There is only one variant this argument could be; put it into the
693 // argument entry.
694 arg.push_back(var_name_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000695
Kate Stoneb9c1b512016-09-06 20:57:50 +0000696 // Push the data for the first argument into the m_arguments vector.
697 m_arguments.push_back(arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000698
Kate Stoneb9c1b512016-09-06 20:57:50 +0000699 m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
700 m_option_group.Append(&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
701 m_option_group.Append(&m_option_format,
702 OptionGroupFormat::OPTION_GROUP_FORMAT |
703 OptionGroupFormat::OPTION_GROUP_GDB_FMT,
704 LLDB_OPT_SET_1);
705 m_option_group.Append(&m_option_compile_units, LLDB_OPT_SET_ALL,
706 LLDB_OPT_SET_1);
707 m_option_group.Append(&m_option_shared_libraries, LLDB_OPT_SET_ALL,
708 LLDB_OPT_SET_1);
709 m_option_group.Finalize();
710 }
711
712 ~CommandObjectTargetVariable() override = default;
713
714 void DumpValueObject(Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp,
715 const char *root_name) {
716 DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions());
717
718 if (!valobj_sp->GetTargetSP()->GetDisplayRuntimeSupportValues() &&
719 valobj_sp->IsRuntimeSupportValue())
720 return;
721
722 switch (var_sp->GetScope()) {
723 case eValueTypeVariableGlobal:
724 if (m_option_variable.show_scope)
725 s.PutCString("GLOBAL: ");
726 break;
727
728 case eValueTypeVariableStatic:
729 if (m_option_variable.show_scope)
730 s.PutCString("STATIC: ");
731 break;
732
733 case eValueTypeVariableArgument:
734 if (m_option_variable.show_scope)
735 s.PutCString(" ARG: ");
736 break;
737
738 case eValueTypeVariableLocal:
739 if (m_option_variable.show_scope)
740 s.PutCString(" LOCAL: ");
741 break;
742
743 case eValueTypeVariableThreadLocal:
744 if (m_option_variable.show_scope)
745 s.PutCString("THREAD: ");
746 break;
747
748 default:
749 break;
Greg Clayton644247c2011-07-07 01:59:51 +0000750 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000751
Kate Stoneb9c1b512016-09-06 20:57:50 +0000752 if (m_option_variable.show_decl) {
753 bool show_fullpaths = false;
754 bool show_module = true;
755 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
756 s.PutCString(": ");
Greg Clayton884fb692011-07-08 21:46:14 +0000757 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000758
Kate Stoneb9c1b512016-09-06 20:57:50 +0000759 const Format format = m_option_format.GetFormat();
760 if (format != eFormatDefault)
761 options.SetFormat(format);
Greg Clayton884fb692011-07-08 21:46:14 +0000762
Kate Stoneb9c1b512016-09-06 20:57:50 +0000763 options.SetRootValueObjectName(root_name);
764
765 valobj_sp->Dump(s, options);
766 }
767
768 static size_t GetVariableCallback(void *baton, const char *name,
769 VariableList &variable_list) {
770 Target *target = static_cast<Target *>(baton);
771 if (target) {
772 return target->GetImages().FindGlobalVariables(ConstString(name), true,
773 UINT32_MAX, variable_list);
Jim Ingham5a988412012-06-08 21:56:10 +0000774 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000775 return 0;
776 }
777
778 Options *GetOptions() override { return &m_option_group; }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000779
Jim Ingham5a988412012-06-08 21:56:10 +0000780protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000781 void DumpGlobalVariableList(const ExecutionContext &exe_ctx,
782 const SymbolContext &sc,
783 const VariableList &variable_list, Stream &s) {
784 size_t count = variable_list.GetSize();
785 if (count > 0) {
786 if (sc.module_sp) {
787 if (sc.comp_unit) {
788 s.Printf("Global variables for %s in %s:\n",
789 sc.comp_unit->GetPath().c_str(),
790 sc.module_sp->GetFileSpec().GetPath().c_str());
791 } else {
792 s.Printf("Global variables for %s\n",
793 sc.module_sp->GetFileSpec().GetPath().c_str());
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000794 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000795 } else if (sc.comp_unit) {
796 s.Printf("Global variables for %s\n", sc.comp_unit->GetPath().c_str());
797 }
798
799 for (uint32_t i = 0; i < count; ++i) {
800 VariableSP var_sp(variable_list.GetVariableAtIndex(i));
801 if (var_sp) {
802 ValueObjectSP valobj_sp(ValueObjectVariable::Create(
803 exe_ctx.GetBestExecutionContextScope(), var_sp));
804
805 if (valobj_sp)
806 DumpValueObject(s, var_sp, valobj_sp,
807 var_sp->GetName().GetCString());
808 }
809 }
Greg Clayton3bcdfc02012-12-04 00:32:51 +0000810 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000811 }
Eugene Zelenkof13e6522016-02-25 19:02:39 +0000812
Kate Stoneb9c1b512016-09-06 20:57:50 +0000813 bool DoExecute(Args &args, CommandReturnObject &result) override {
814 Target *target = m_exe_ctx.GetTargetPtr();
815 const size_t argc = args.GetArgumentCount();
816 Stream &s = result.GetOutputStream();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000817
Kate Stoneb9c1b512016-09-06 20:57:50 +0000818 if (argc > 0) {
Greg Claytonf9fc6092013-01-09 19:44:40 +0000819
Zachary Turner97d2c402016-10-05 23:40:23 +0000820 // TODO: Convert to entry-based iteration. Requires converting
821 // DumpValueObject.
Kate Stoneb9c1b512016-09-06 20:57:50 +0000822 for (size_t idx = 0; idx < argc; ++idx) {
823 VariableList variable_list;
824 ValueObjectList valobj_list;
Greg Clayton884fb692011-07-08 21:46:14 +0000825
Kate Stoneb9c1b512016-09-06 20:57:50 +0000826 const char *arg = args.GetArgumentAtIndex(idx);
827 size_t matches = 0;
828 bool use_var_name = false;
829 if (m_option_variable.use_regex) {
Zachary Turner95eae422016-09-21 16:01:28 +0000830 RegularExpression regex(llvm::StringRef::withNullAsEmpty(arg));
Kate Stoneb9c1b512016-09-06 20:57:50 +0000831 if (!regex.IsValid()) {
832 result.GetErrorStream().Printf(
833 "error: invalid regular expression: '%s'\n", arg);
834 result.SetStatus(eReturnStatusFailed);
835 return false;
836 }
837 use_var_name = true;
838 matches = target->GetImages().FindGlobalVariables(
839 regex, true, UINT32_MAX, variable_list);
840 } else {
841 Error error(Variable::GetValuesForVariableExpressionPath(
842 arg, m_exe_ctx.GetBestExecutionContextScope(),
843 GetVariableCallback, target, variable_list, valobj_list));
844 matches = variable_list.GetSize();
Greg Clayton644247c2011-07-07 01:59:51 +0000845 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000846
847 if (matches == 0) {
848 result.GetErrorStream().Printf(
849 "error: can't find global variable '%s'\n", arg);
850 result.SetStatus(eReturnStatusFailed);
851 return false;
852 } else {
853 for (uint32_t global_idx = 0; global_idx < matches; ++global_idx) {
854 VariableSP var_sp(variable_list.GetVariableAtIndex(global_idx));
855 if (var_sp) {
856 ValueObjectSP valobj_sp(
857 valobj_list.GetValueObjectAtIndex(global_idx));
858 if (!valobj_sp)
859 valobj_sp = ValueObjectVariable::Create(
860 m_exe_ctx.GetBestExecutionContextScope(), var_sp);
861
862 if (valobj_sp)
863 DumpValueObject(s, var_sp, valobj_sp,
864 use_var_name ? var_sp->GetName().GetCString()
865 : arg);
Greg Claytonf9fc6092013-01-09 19:44:40 +0000866 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000867 }
868 }
869 }
870 } else {
871 const FileSpecList &compile_units =
872 m_option_compile_units.GetOptionValue().GetCurrentValue();
873 const FileSpecList &shlibs =
874 m_option_shared_libraries.GetOptionValue().GetCurrentValue();
875 SymbolContextList sc_list;
876 const size_t num_compile_units = compile_units.GetSize();
877 const size_t num_shlibs = shlibs.GetSize();
878 if (num_compile_units == 0 && num_shlibs == 0) {
879 bool success = false;
880 StackFrame *frame = m_exe_ctx.GetFramePtr();
881 CompileUnit *comp_unit = nullptr;
882 if (frame) {
883 SymbolContext sc = frame->GetSymbolContext(eSymbolContextCompUnit);
884 if (sc.comp_unit) {
885 const bool can_create = true;
886 VariableListSP comp_unit_varlist_sp(
887 sc.comp_unit->GetVariableList(can_create));
888 if (comp_unit_varlist_sp) {
889 size_t count = comp_unit_varlist_sp->GetSize();
890 if (count > 0) {
891 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp, s);
892 success = true;
893 }
894 }
895 }
896 }
897 if (!success) {
898 if (frame) {
899 if (comp_unit)
900 result.AppendErrorWithFormat(
901 "no global variables in current compile unit: %s\n",
902 comp_unit->GetPath().c_str());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000903 else
Kate Stoneb9c1b512016-09-06 20:57:50 +0000904 result.AppendErrorWithFormat(
905 "no debug information for frame %u\n",
906 frame->GetFrameIndex());
907 } else
908 result.AppendError("'target variable' takes one or more global "
909 "variable names as arguments\n");
910 result.SetStatus(eReturnStatusFailed);
911 }
912 } else {
913 SymbolContextList sc_list;
914 const bool append = true;
915 // We have one or more compile unit or shlib
916 if (num_shlibs > 0) {
917 for (size_t shlib_idx = 0; shlib_idx < num_shlibs; ++shlib_idx) {
918 const FileSpec module_file(shlibs.GetFileSpecAtIndex(shlib_idx));
919 ModuleSpec module_spec(module_file);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000920
Kate Stoneb9c1b512016-09-06 20:57:50 +0000921 ModuleSP module_sp(
922 target->GetImages().FindFirstModule(module_spec));
923 if (module_sp) {
924 if (num_compile_units > 0) {
925 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
926 module_sp->FindCompileUnits(
927 compile_units.GetFileSpecAtIndex(cu_idx), append,
928 sc_list);
929 } else {
930 SymbolContext sc;
931 sc.module_sp = module_sp;
932 sc_list.Append(sc);
933 }
934 } else {
935 // Didn't find matching shlib/module in target...
936 result.AppendErrorWithFormat(
937 "target doesn't contain the specified shared library: %s\n",
938 module_file.GetPath().c_str());
Greg Claytonf9fc6092013-01-09 19:44:40 +0000939 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000940 }
941 } else {
942 // No shared libraries, we just want to find globals for the compile
943 // units files that were specified
944 for (size_t cu_idx = 0; cu_idx < num_compile_units; ++cu_idx)
945 target->GetImages().FindCompileUnits(
946 compile_units.GetFileSpecAtIndex(cu_idx), append, sc_list);
Greg Clayton644247c2011-07-07 01:59:51 +0000947 }
Greg Claytonf9fc6092013-01-09 19:44:40 +0000948
Kate Stoneb9c1b512016-09-06 20:57:50 +0000949 const uint32_t num_scs = sc_list.GetSize();
950 if (num_scs > 0) {
951 SymbolContext sc;
952 for (uint32_t sc_idx = 0; sc_idx < num_scs; ++sc_idx) {
953 if (sc_list.GetContextAtIndex(sc_idx, sc)) {
954 if (sc.comp_unit) {
955 const bool can_create = true;
956 VariableListSP comp_unit_varlist_sp(
957 sc.comp_unit->GetVariableList(can_create));
958 if (comp_unit_varlist_sp)
959 DumpGlobalVariableList(m_exe_ctx, sc, *comp_unit_varlist_sp,
960 s);
961 } else if (sc.module_sp) {
962 // Get all global variables for this module
963 lldb_private::RegularExpression all_globals_regex(
Zachary Turner95eae422016-09-21 16:01:28 +0000964 llvm::StringRef(
965 ".")); // Any global with at least one character
Kate Stoneb9c1b512016-09-06 20:57:50 +0000966 VariableList variable_list;
967 sc.module_sp->FindGlobalVariables(all_globals_regex, append,
968 UINT32_MAX, variable_list);
969 DumpGlobalVariableList(m_exe_ctx, sc, variable_list, s);
970 }
971 }
972 }
Enrico Granata61a80ba2011-08-12 16:42:31 +0000973 }
Kate Stoneb9c1b512016-09-06 20:57:50 +0000974 }
Greg Clayton644247c2011-07-07 01:59:51 +0000975 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +0000976
Kate Stoneb9c1b512016-09-06 20:57:50 +0000977 if (m_interpreter.TruncationWarningNecessary()) {
978 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
979 m_cmd_name.c_str());
980 m_interpreter.TruncationWarningGiven();
981 }
982
983 return result.Succeeded();
984 }
985
986 OptionGroupOptions m_option_group;
987 OptionGroupVariable m_option_variable;
988 OptionGroupFormat m_option_format;
989 OptionGroupFileList m_option_compile_units;
990 OptionGroupFileList m_option_shared_libraries;
991 OptionGroupValueObjectDisplay m_varobj_options;
Greg Clayton644247c2011-07-07 01:59:51 +0000992};
993
Greg Claytoneffe5c92011-05-03 22:09:39 +0000994#pragma mark CommandObjectTargetModulesSearchPathsAdd
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000995
Kate Stoneb9c1b512016-09-06 20:57:50 +0000996class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000997public:
Kate Stoneb9c1b512016-09-06 20:57:50 +0000998 CommandObjectTargetModulesSearchPathsAdd(CommandInterpreter &interpreter)
999 : CommandObjectParsed(interpreter, "target modules search-paths add",
1000 "Add new image search paths substitution pairs to "
1001 "the current target.",
1002 nullptr) {
1003 CommandArgumentEntry arg;
1004 CommandArgumentData old_prefix_arg;
1005 CommandArgumentData new_prefix_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001006
Kate Stoneb9c1b512016-09-06 20:57:50 +00001007 // Define the first variant of this arg pair.
1008 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1009 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001010
Kate Stoneb9c1b512016-09-06 20:57:50 +00001011 // Define the first variant of this arg pair.
1012 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1013 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001014
Kate Stoneb9c1b512016-09-06 20:57:50 +00001015 // There are two required arguments that must always occur together, i.e. an
1016 // argument "pair". Because they
1017 // must always occur together, they are treated as two variants of one
1018 // argument rather than two independent
1019 // arguments. Push them both into the first argument position for
1020 // m_arguments...
Caroline Tice405fe672010-10-04 22:28:36 +00001021
Kate Stoneb9c1b512016-09-06 20:57:50 +00001022 arg.push_back(old_prefix_arg);
1023 arg.push_back(new_prefix_arg);
Caroline Tice405fe672010-10-04 22:28:36 +00001024
Kate Stoneb9c1b512016-09-06 20:57:50 +00001025 m_arguments.push_back(arg);
1026 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001027
Kate Stoneb9c1b512016-09-06 20:57:50 +00001028 ~CommandObjectTargetModulesSearchPathsAdd() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001029
Jim Ingham5a988412012-06-08 21:56:10 +00001030protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001031 bool DoExecute(Args &command, CommandReturnObject &result) override {
1032 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1033 if (target) {
1034 const size_t argc = command.GetArgumentCount();
1035 if (argc & 1) {
1036 result.AppendError("add requires an even number of arguments\n");
1037 result.SetStatus(eReturnStatusFailed);
1038 } else {
1039 for (size_t i = 0; i < argc; i += 2) {
1040 const char *from = command.GetArgumentAtIndex(i);
1041 const char *to = command.GetArgumentAtIndex(i + 1);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001042
Kate Stoneb9c1b512016-09-06 20:57:50 +00001043 if (from[0] && to[0]) {
1044 Log *log = lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_HOST);
1045 if (log) {
1046 log->Printf("target modules search path adding ImageSearchPath "
1047 "pair: '%s' -> '%s'",
1048 from, to);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001049 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001050 bool last_pair = ((argc - i) == 2);
1051 target->GetImageSearchPathList().Append(
1052 ConstString(from), ConstString(to),
1053 last_pair); // Notify if this is the last pair
1054 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1055 } else {
1056 if (from[0])
1057 result.AppendError("<path-prefix> can't be empty\n");
1058 else
1059 result.AppendError("<new-path-prefix> can't be empty\n");
1060 result.SetStatus(eReturnStatusFailed);
1061 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001062 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001063 }
1064 } else {
1065 result.AppendError("invalid target\n");
1066 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001067 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001068 return result.Succeeded();
1069 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001070};
1071
Greg Claytoneffe5c92011-05-03 22:09:39 +00001072#pragma mark CommandObjectTargetModulesSearchPathsClear
1073
Kate Stoneb9c1b512016-09-06 20:57:50 +00001074class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001075public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001076 CommandObjectTargetModulesSearchPathsClear(CommandInterpreter &interpreter)
1077 : CommandObjectParsed(interpreter, "target modules search-paths clear",
1078 "Clear all current image search path substitution "
1079 "pairs from the current target.",
1080 "target modules search-paths clear") {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001081
Kate Stoneb9c1b512016-09-06 20:57:50 +00001082 ~CommandObjectTargetModulesSearchPathsClear() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001083
Jim Ingham5a988412012-06-08 21:56:10 +00001084protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001085 bool DoExecute(Args &command, CommandReturnObject &result) override {
1086 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1087 if (target) {
1088 bool notify = true;
1089 target->GetImageSearchPathList().Clear(notify);
1090 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1091 } else {
1092 result.AppendError("invalid target\n");
1093 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001094 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001095 return result.Succeeded();
1096 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001097};
1098
Greg Claytoneffe5c92011-05-03 22:09:39 +00001099#pragma mark CommandObjectTargetModulesSearchPathsInsert
1100
Kate Stoneb9c1b512016-09-06 20:57:50 +00001101class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001102public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001103 CommandObjectTargetModulesSearchPathsInsert(CommandInterpreter &interpreter)
1104 : CommandObjectParsed(interpreter, "target modules search-paths insert",
1105 "Insert a new image search path substitution pair "
1106 "into the current target at the specified index.",
1107 nullptr) {
1108 CommandArgumentEntry arg1;
1109 CommandArgumentEntry arg2;
1110 CommandArgumentData index_arg;
1111 CommandArgumentData old_prefix_arg;
1112 CommandArgumentData new_prefix_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001113
Kate Stoneb9c1b512016-09-06 20:57:50 +00001114 // Define the first and only variant of this arg.
1115 index_arg.arg_type = eArgTypeIndex;
1116 index_arg.arg_repetition = eArgRepeatPlain;
Caroline Tice405fe672010-10-04 22:28:36 +00001117
Kate Stoneb9c1b512016-09-06 20:57:50 +00001118 // Put the one and only variant into the first arg for m_arguments:
1119 arg1.push_back(index_arg);
Caroline Tice405fe672010-10-04 22:28:36 +00001120
Kate Stoneb9c1b512016-09-06 20:57:50 +00001121 // Define the first variant of this arg pair.
1122 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1123 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001124
Kate Stoneb9c1b512016-09-06 20:57:50 +00001125 // Define the first variant of this arg pair.
1126 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1127 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001128
Kate Stoneb9c1b512016-09-06 20:57:50 +00001129 // There are two required arguments that must always occur together, i.e. an
1130 // argument "pair". Because they
1131 // must always occur together, they are treated as two variants of one
1132 // argument rather than two independent
1133 // arguments. Push them both into the same argument position for
1134 // m_arguments...
Caroline Tice405fe672010-10-04 22:28:36 +00001135
Kate Stoneb9c1b512016-09-06 20:57:50 +00001136 arg2.push_back(old_prefix_arg);
1137 arg2.push_back(new_prefix_arg);
Caroline Tice405fe672010-10-04 22:28:36 +00001138
Kate Stoneb9c1b512016-09-06 20:57:50 +00001139 // Add arguments to m_arguments.
1140 m_arguments.push_back(arg1);
1141 m_arguments.push_back(arg2);
1142 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001143
Kate Stoneb9c1b512016-09-06 20:57:50 +00001144 ~CommandObjectTargetModulesSearchPathsInsert() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001145
Jim Ingham5a988412012-06-08 21:56:10 +00001146protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001147 bool DoExecute(Args &command, CommandReturnObject &result) override {
1148 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1149 if (target) {
1150 size_t argc = command.GetArgumentCount();
1151 // check for at least 3 arguments and an odd number of parameters
1152 if (argc >= 3 && argc & 1) {
1153 bool success = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001154
Kate Stoneb9c1b512016-09-06 20:57:50 +00001155 uint32_t insert_idx = StringConvert::ToUInt32(
1156 command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001157
Kate Stoneb9c1b512016-09-06 20:57:50 +00001158 if (!success) {
1159 result.AppendErrorWithFormat(
1160 "<index> parameter is not an integer: '%s'.\n",
1161 command.GetArgumentAtIndex(0));
1162 result.SetStatus(eReturnStatusFailed);
1163 return result.Succeeded();
1164 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001165
Kate Stoneb9c1b512016-09-06 20:57:50 +00001166 // shift off the index
1167 command.Shift();
1168 argc = command.GetArgumentCount();
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001169
Kate Stoneb9c1b512016-09-06 20:57:50 +00001170 for (uint32_t i = 0; i < argc; i += 2, ++insert_idx) {
1171 const char *from = command.GetArgumentAtIndex(i);
1172 const char *to = command.GetArgumentAtIndex(i + 1);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001173
Kate Stoneb9c1b512016-09-06 20:57:50 +00001174 if (from[0] && to[0]) {
1175 bool last_pair = ((argc - i) == 2);
1176 target->GetImageSearchPathList().Insert(
1177 ConstString(from), ConstString(to), insert_idx, last_pair);
1178 result.SetStatus(eReturnStatusSuccessFinishNoResult);
1179 } else {
1180 if (from[0])
1181 result.AppendError("<path-prefix> can't be empty\n");
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001182 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001183 result.AppendError("<new-path-prefix> can't be empty\n");
1184 result.SetStatus(eReturnStatusFailed);
1185 return false;
1186 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001187 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001188 } else {
1189 result.AppendError("insert requires at least three arguments\n");
1190 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001191 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001192 }
1193
1194 } else {
1195 result.AppendError("invalid target\n");
1196 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001197 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001198 return result.Succeeded();
1199 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001200};
1201
Greg Claytoneffe5c92011-05-03 22:09:39 +00001202#pragma mark CommandObjectTargetModulesSearchPathsList
1203
Kate Stoneb9c1b512016-09-06 20:57:50 +00001204class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001205public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001206 CommandObjectTargetModulesSearchPathsList(CommandInterpreter &interpreter)
1207 : CommandObjectParsed(interpreter, "target modules search-paths list",
1208 "List all current image search path substitution "
1209 "pairs in the current target.",
1210 "target modules search-paths list") {}
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001211
Kate Stoneb9c1b512016-09-06 20:57:50 +00001212 ~CommandObjectTargetModulesSearchPathsList() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001213
Jim Ingham5a988412012-06-08 21:56:10 +00001214protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001215 bool DoExecute(Args &command, CommandReturnObject &result) override {
1216 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1217 if (target) {
1218 if (command.GetArgumentCount() != 0) {
1219 result.AppendError("list takes no arguments\n");
1220 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001221 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001222 }
1223
1224 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
1225 result.SetStatus(eReturnStatusSuccessFinishResult);
1226 } else {
1227 result.AppendError("invalid target\n");
1228 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001229 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001230 return result.Succeeded();
1231 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001232};
1233
Greg Claytoneffe5c92011-05-03 22:09:39 +00001234#pragma mark CommandObjectTargetModulesSearchPathsQuery
1235
Kate Stoneb9c1b512016-09-06 20:57:50 +00001236class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001237public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001238 CommandObjectTargetModulesSearchPathsQuery(CommandInterpreter &interpreter)
1239 : CommandObjectParsed(
1240 interpreter, "target modules search-paths query",
1241 "Transform a path using the first applicable image search path.",
1242 nullptr) {
1243 CommandArgumentEntry arg;
1244 CommandArgumentData path_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001245
Kate Stoneb9c1b512016-09-06 20:57:50 +00001246 // Define the first (and only) variant of this arg.
1247 path_arg.arg_type = eArgTypeDirectoryName;
1248 path_arg.arg_repetition = eArgRepeatPlain;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001249
Kate Stoneb9c1b512016-09-06 20:57:50 +00001250 // There is only one variant this argument could be; put it into the
1251 // argument entry.
1252 arg.push_back(path_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001253
Kate Stoneb9c1b512016-09-06 20:57:50 +00001254 // Push the data for the first argument into the m_arguments vector.
1255 m_arguments.push_back(arg);
1256 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001257
Kate Stoneb9c1b512016-09-06 20:57:50 +00001258 ~CommandObjectTargetModulesSearchPathsQuery() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001259
Jim Ingham5a988412012-06-08 21:56:10 +00001260protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001261 bool DoExecute(Args &command, CommandReturnObject &result) override {
1262 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1263 if (target) {
1264 if (command.GetArgumentCount() != 1) {
1265 result.AppendError("query requires one argument\n");
1266 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001267 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001268 }
1269
1270 ConstString orig(command.GetArgumentAtIndex(0));
1271 ConstString transformed;
1272 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1273 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1274 else
1275 result.GetOutputStream().Printf("%s\n", orig.GetCString());
1276
1277 result.SetStatus(eReturnStatusSuccessFinishResult);
1278 } else {
1279 result.AppendError("invalid target\n");
1280 result.SetStatus(eReturnStatusFailed);
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001281 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001282 return result.Succeeded();
1283 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001284};
1285
Greg Claytoneffe5c92011-05-03 22:09:39 +00001286//----------------------------------------------------------------------
1287// Static Helper functions
1288//----------------------------------------------------------------------
Kate Stoneb9c1b512016-09-06 20:57:50 +00001289static void DumpModuleArchitecture(Stream &strm, Module *module,
1290 bool full_triple, uint32_t width) {
1291 if (module) {
1292 StreamString arch_strm;
Todd Fiala7df337f2015-10-13 23:41:19 +00001293
Kate Stoneb9c1b512016-09-06 20:57:50 +00001294 if (full_triple)
1295 module->GetArchitecture().DumpTriple(arch_strm);
Greg Clayton3418c852011-08-10 02:10:13 +00001296 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001297 arch_strm.PutCString(module->GetArchitecture().GetArchitectureName());
1298 std::string arch_str = arch_strm.GetString();
1299
1300 if (width)
1301 strm.Printf("%-*s", width, arch_str.c_str());
1302 else
Malcolm Parsons771ef6d2016-11-02 20:34:10 +00001303 strm.PutCString(arch_str);
Kate Stoneb9c1b512016-09-06 20:57:50 +00001304 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001305}
1306
Kate Stoneb9c1b512016-09-06 20:57:50 +00001307static void DumpModuleUUID(Stream &strm, Module *module) {
1308 if (module && module->GetUUID().IsValid())
1309 module->GetUUID().Dump(&strm);
1310 else
1311 strm.PutCString(" ");
Greg Claytoneffe5c92011-05-03 22:09:39 +00001312}
1313
Kate Stoneb9c1b512016-09-06 20:57:50 +00001314static uint32_t DumpCompileUnitLineTable(CommandInterpreter &interpreter,
1315 Stream &strm, Module *module,
1316 const FileSpec &file_spec,
1317 bool load_addresses) {
1318 uint32_t num_matches = 0;
1319 if (module) {
1320 SymbolContextList sc_list;
1321 num_matches = module->ResolveSymbolContextsForFileSpec(
1322 file_spec, 0, false, eSymbolContextCompUnit, sc_list);
1323
1324 for (uint32_t i = 0; i < num_matches; ++i) {
1325 SymbolContext sc;
1326 if (sc_list.GetContextAtIndex(i, sc)) {
1327 if (i > 0)
1328 strm << "\n\n";
1329
1330 strm << "Line table for " << *static_cast<FileSpec *>(sc.comp_unit)
1331 << " in `" << module->GetFileSpec().GetFilename() << "\n";
1332 LineTable *line_table = sc.comp_unit->GetLineTable();
1333 if (line_table)
1334 line_table->GetDescription(
1335 &strm, interpreter.GetExecutionContext().GetTargetPtr(),
1336 lldb::eDescriptionLevelBrief);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001337 else
Kate Stoneb9c1b512016-09-06 20:57:50 +00001338 strm << "No line table";
1339 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001340 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001341 }
1342 return num_matches;
1343}
1344
1345static void DumpFullpath(Stream &strm, const FileSpec *file_spec_ptr,
1346 uint32_t width) {
1347 if (file_spec_ptr) {
1348 if (width > 0) {
1349 std::string fullpath = file_spec_ptr->GetPath();
1350 strm.Printf("%-*s", width, fullpath.c_str());
1351 return;
1352 } else {
1353 file_spec_ptr->Dump(&strm);
1354 return;
1355 }
1356 }
1357 // Keep the width spacing correct if things go wrong...
1358 if (width > 0)
1359 strm.Printf("%-*s", width, "");
1360}
1361
1362static void DumpDirectory(Stream &strm, const FileSpec *file_spec_ptr,
1363 uint32_t width) {
1364 if (file_spec_ptr) {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001365 if (width > 0)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001366 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1367 else
1368 file_spec_ptr->GetDirectory().Dump(&strm);
1369 return;
1370 }
1371 // Keep the width spacing correct if things go wrong...
1372 if (width > 0)
1373 strm.Printf("%-*s", width, "");
Greg Claytoneffe5c92011-05-03 22:09:39 +00001374}
1375
Kate Stoneb9c1b512016-09-06 20:57:50 +00001376static void DumpBasename(Stream &strm, const FileSpec *file_spec_ptr,
1377 uint32_t width) {
1378 if (file_spec_ptr) {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001379 if (width > 0)
Kate Stoneb9c1b512016-09-06 20:57:50 +00001380 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1381 else
1382 file_spec_ptr->GetFilename().Dump(&strm);
1383 return;
1384 }
1385 // Keep the width spacing correct if things go wrong...
1386 if (width > 0)
1387 strm.Printf("%-*s", width, "");
Greg Claytoneffe5c92011-05-03 22:09:39 +00001388}
1389
Kate Stoneb9c1b512016-09-06 20:57:50 +00001390static size_t DumpModuleObjfileHeaders(Stream &strm, ModuleList &module_list) {
1391 size_t num_dumped = 0;
1392 std::lock_guard<std::recursive_mutex> guard(module_list.GetMutex());
1393 const size_t num_modules = module_list.GetSize();
1394 if (num_modules > 0) {
1395 strm.Printf("Dumping headers for %" PRIu64 " module(s).\n",
1396 static_cast<uint64_t>(num_modules));
Greg Claytonc4a8a762012-05-15 18:43:44 +00001397 strm.IndentMore();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001398 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1399 Module *module = module_list.GetModulePointerAtIndexUnlocked(image_idx);
1400 if (module) {
1401 if (num_dumped++ > 0) {
1402 strm.EOL();
1403 strm.EOL();
1404 }
1405 ObjectFile *objfile = module->GetObjectFile();
1406 objfile->Dump(&strm);
1407 }
Greg Claytonc4a8a762012-05-15 18:43:44 +00001408 }
1409 strm.IndentLess();
Kate Stoneb9c1b512016-09-06 20:57:50 +00001410 }
1411 return num_dumped;
Greg Claytonc4a8a762012-05-15 18:43:44 +00001412}
1413
Kate Stoneb9c1b512016-09-06 20:57:50 +00001414static void DumpModuleSymtab(CommandInterpreter &interpreter, Stream &strm,
1415 Module *module, SortOrder sort_order) {
1416 if (module) {
1417 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1418 if (sym_vendor) {
1419 Symtab *symtab = sym_vendor->GetSymtab();
1420 if (symtab)
1421 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(),
1422 sort_order);
1423 }
1424 }
1425}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001426
Kate Stoneb9c1b512016-09-06 20:57:50 +00001427static void DumpModuleSections(CommandInterpreter &interpreter, Stream &strm,
1428 Module *module) {
1429 if (module) {
1430 SectionList *section_list = module->GetSectionList();
1431 if (section_list) {
1432 strm.Printf("Sections for '%s' (%s):\n",
1433 module->GetSpecificationDescription().c_str(),
1434 module->GetArchitecture().GetArchitectureName());
1435 strm.IndentMore();
1436 section_list->Dump(&strm,
1437 interpreter.GetExecutionContext().GetTargetPtr(), true,
1438 UINT32_MAX);
1439 strm.IndentLess();
1440 }
1441 }
1442}
1443
1444static bool DumpModuleSymbolVendor(Stream &strm, Module *module) {
1445 if (module) {
1446 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1447 if (symbol_vendor) {
1448 symbol_vendor->Dump(&strm);
1449 return true;
1450 }
1451 }
1452 return false;
1453}
1454
1455static void DumpAddress(ExecutionContextScope *exe_scope,
1456 const Address &so_addr, bool verbose, Stream &strm) {
1457 strm.IndentMore();
1458 strm.Indent(" Address: ");
1459 so_addr.Dump(&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1460 strm.PutCString(" (");
1461 so_addr.Dump(&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1462 strm.PutCString(")\n");
1463 strm.Indent(" Summary: ");
1464 const uint32_t save_indent = strm.GetIndentLevel();
1465 strm.SetIndentLevel(save_indent + 13);
1466 so_addr.Dump(&strm, exe_scope, Address::DumpStyleResolvedDescription);
1467 strm.SetIndentLevel(save_indent);
1468 // Print out detailed address information when verbose is enabled
1469 if (verbose) {
1470 strm.EOL();
1471 so_addr.Dump(&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1472 }
1473 strm.IndentLess();
1474}
1475
1476static bool LookupAddressInModule(CommandInterpreter &interpreter, Stream &strm,
1477 Module *module, uint32_t resolve_mask,
1478 lldb::addr_t raw_addr, lldb::addr_t offset,
1479 bool verbose) {
1480 if (module) {
1481 lldb::addr_t addr = raw_addr - offset;
1482 Address so_addr;
1483 SymbolContext sc;
1484 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
1485 if (target && !target->GetSectionLoadList().IsEmpty()) {
1486 if (!target->GetSectionLoadList().ResolveLoadAddress(addr, so_addr))
1487 return false;
1488 else if (so_addr.GetModule().get() != module)
1489 return false;
1490 } else {
1491 if (!module->ResolveFileAddress(addr, so_addr))
1492 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001493 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001494
Kate Stoneb9c1b512016-09-06 20:57:50 +00001495 ExecutionContextScope *exe_scope =
1496 interpreter.GetExecutionContext().GetBestExecutionContextScope();
1497 DumpAddress(exe_scope, so_addr, verbose, strm);
1498 // strm.IndentMore();
1499 // strm.Indent (" Address: ");
1500 // so_addr.Dump (&strm, exe_scope,
1501 // Address::DumpStyleModuleWithFileAddress);
1502 // strm.PutCString (" (");
1503 // so_addr.Dump (&strm, exe_scope,
1504 // Address::DumpStyleSectionNameOffset);
1505 // strm.PutCString (")\n");
1506 // strm.Indent (" Summary: ");
1507 // const uint32_t save_indent = strm.GetIndentLevel ();
1508 // strm.SetIndentLevel (save_indent + 13);
1509 // so_addr.Dump (&strm, exe_scope,
1510 // Address::DumpStyleResolvedDescription);
1511 // strm.SetIndentLevel (save_indent);
1512 // // Print out detailed address information when verbose is enabled
1513 // if (verbose)
1514 // {
1515 // strm.EOL();
1516 // so_addr.Dump (&strm, exe_scope,
1517 // Address::DumpStyleDetailedSymbolContext);
1518 // }
1519 // strm.IndentLess();
1520 return true;
1521 }
1522
1523 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001524}
1525
Kate Stoneb9c1b512016-09-06 20:57:50 +00001526static uint32_t LookupSymbolInModule(CommandInterpreter &interpreter,
1527 Stream &strm, Module *module,
1528 const char *name, bool name_is_regex,
1529 bool verbose) {
1530 if (module) {
1531 SymbolContext sc;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001532
Kate Stoneb9c1b512016-09-06 20:57:50 +00001533 SymbolVendor *sym_vendor = module->GetSymbolVendor();
1534 if (sym_vendor) {
1535 Symtab *symtab = sym_vendor->GetSymtab();
1536 if (symtab) {
1537 std::vector<uint32_t> match_indexes;
1538 ConstString symbol_name(name);
1539 uint32_t num_matches = 0;
1540 if (name_is_regex) {
Zachary Turner95eae422016-09-21 16:01:28 +00001541 RegularExpression name_regexp(symbol_name.GetStringRef());
Kate Stoneb9c1b512016-09-06 20:57:50 +00001542 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType(
1543 name_regexp, eSymbolTypeAny, match_indexes);
1544 } else {
1545 num_matches =
1546 symtab->AppendSymbolIndexesWithName(symbol_name, match_indexes);
1547 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001548
Kate Stoneb9c1b512016-09-06 20:57:50 +00001549 if (num_matches > 0) {
1550 strm.Indent();
1551 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1552 name_is_regex ? "the regular expression " : "", name);
1553 DumpFullpath(strm, &module->GetFileSpec(), 0);
1554 strm.PutCString(":\n");
1555 strm.IndentMore();
1556 for (uint32_t i = 0; i < num_matches; ++i) {
1557 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1558 if (symbol && symbol->ValueIsAddress()) {
1559 DumpAddress(interpreter.GetExecutionContext()
1560 .GetBestExecutionContextScope(),
1561 symbol->GetAddressRef(), verbose, strm);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001562 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001563 }
1564 strm.IndentLess();
1565 return num_matches;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001566 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001567 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001568 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001569 }
1570 return 0;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001571}
1572
Kate Stoneb9c1b512016-09-06 20:57:50 +00001573static void DumpSymbolContextList(ExecutionContextScope *exe_scope,
1574 Stream &strm, SymbolContextList &sc_list,
1575 bool verbose) {
1576 strm.IndentMore();
Eugene Zelenkof13e6522016-02-25 19:02:39 +00001577
Kate Stoneb9c1b512016-09-06 20:57:50 +00001578 const uint32_t num_matches = sc_list.GetSize();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001579
Kate Stoneb9c1b512016-09-06 20:57:50 +00001580 for (uint32_t i = 0; i < num_matches; ++i) {
1581 SymbolContext sc;
1582 if (sc_list.GetContextAtIndex(i, sc)) {
1583 AddressRange range;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001584
Kate Stoneb9c1b512016-09-06 20:57:50 +00001585 sc.GetAddressRange(eSymbolContextEverything, 0, true, range);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001586
Kate Stoneb9c1b512016-09-06 20:57:50 +00001587 DumpAddress(exe_scope, range.GetBaseAddress(), verbose, strm);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001588 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001589 }
1590 strm.IndentLess();
Greg Claytoneffe5c92011-05-03 22:09:39 +00001591}
1592
Kate Stoneb9c1b512016-09-06 20:57:50 +00001593static size_t LookupFunctionInModule(CommandInterpreter &interpreter,
1594 Stream &strm, Module *module,
1595 const char *name, bool name_is_regex,
1596 bool include_inlines, bool include_symbols,
1597 bool verbose) {
1598 if (module && name && name[0]) {
1599 SymbolContextList sc_list;
1600 const bool append = true;
1601 size_t num_matches = 0;
1602 if (name_is_regex) {
Zachary Turner95eae422016-09-21 16:01:28 +00001603 RegularExpression function_name_regex((llvm::StringRef(name)));
Kate Stoneb9c1b512016-09-06 20:57:50 +00001604 num_matches = module->FindFunctions(function_name_regex, include_symbols,
1605 include_inlines, append, sc_list);
1606 } else {
1607 ConstString function_name(name);
1608 num_matches = module->FindFunctions(
1609 function_name, nullptr, eFunctionNameTypeAuto, include_symbols,
1610 include_inlines, append, sc_list);
Greg Claytoneffe5c92011-05-03 22:09:39 +00001611 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001612
Kate Stoneb9c1b512016-09-06 20:57:50 +00001613 if (num_matches) {
1614 strm.Indent();
1615 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1616 num_matches > 1 ? "es" : "");
1617 DumpFullpath(strm, &module->GetFileSpec(), 0);
1618 strm.PutCString(":\n");
1619 DumpSymbolContextList(
1620 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1621 strm, sc_list, verbose);
Sean Callanand38b4a92012-06-06 20:49:55 +00001622 }
1623 return num_matches;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001624 }
1625 return 0;
Sean Callanand38b4a92012-06-06 20:49:55 +00001626}
1627
Kate Stoneb9c1b512016-09-06 20:57:50 +00001628static size_t LookupTypeInModule(CommandInterpreter &interpreter, Stream &strm,
1629 Module *module, const char *name_cstr,
1630 bool name_is_regex) {
1631 if (module && name_cstr && name_cstr[0]) {
1632 TypeList type_list;
1633 const uint32_t max_num_matches = UINT32_MAX;
1634 size_t num_matches = 0;
1635 bool name_is_fully_qualified = false;
1636 SymbolContext sc;
1637
1638 ConstString name(name_cstr);
1639 llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
1640 num_matches =
1641 module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches,
1642 searched_symbol_files, type_list);
1643
1644 if (num_matches) {
1645 strm.Indent();
1646 strm.Printf("%" PRIu64 " match%s found in ", (uint64_t)num_matches,
1647 num_matches > 1 ? "es" : "");
1648 DumpFullpath(strm, &module->GetFileSpec(), 0);
1649 strm.PutCString(":\n");
1650 for (TypeSP type_sp : type_list.Types()) {
1651 if (type_sp) {
1652 // Resolve the clang type so that any forward references
1653 // to types that haven't yet been parsed will get parsed.
1654 type_sp->GetFullCompilerType();
1655 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1656 // Print all typedef chains
1657 TypeSP typedef_type_sp(type_sp);
1658 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1659 while (typedefed_type_sp) {
1660 strm.EOL();
1661 strm.Printf(" typedef '%s': ",
1662 typedef_type_sp->GetName().GetCString());
1663 typedefed_type_sp->GetFullCompilerType();
1664 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull,
1665 true);
1666 typedef_type_sp = typedefed_type_sp;
1667 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1668 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001669 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001670 strm.EOL();
1671 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001672 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001673 return num_matches;
1674 }
1675 return 0;
1676}
1677
1678static size_t LookupTypeHere(CommandInterpreter &interpreter, Stream &strm,
1679 const SymbolContext &sym_ctx,
1680 const char *name_cstr, bool name_is_regex) {
1681 if (!sym_ctx.module_sp)
Greg Claytoneffe5c92011-05-03 22:09:39 +00001682 return 0;
Kate Stoneb9c1b512016-09-06 20:57:50 +00001683
1684 TypeList type_list;
1685 const uint32_t max_num_matches = UINT32_MAX;
1686 size_t num_matches = 1;
1687 bool name_is_fully_qualified = false;
1688
1689 ConstString name(name_cstr);
1690 llvm::DenseSet<SymbolFile *> searched_symbol_files;
1691 num_matches = sym_ctx.module_sp->FindTypes(
1692 sym_ctx, name, name_is_fully_qualified, max_num_matches,
1693 searched_symbol_files, type_list);
1694
1695 if (num_matches) {
1696 strm.Indent();
1697 strm.PutCString("Best match found in ");
1698 DumpFullpath(strm, &sym_ctx.module_sp->GetFileSpec(), 0);
1699 strm.PutCString(":\n");
1700
1701 TypeSP type_sp(type_list.GetTypeAtIndex(0));
1702 if (type_sp) {
1703 // Resolve the clang type so that any forward references
1704 // to types that haven't yet been parsed will get parsed.
1705 type_sp->GetFullCompilerType();
1706 type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1707 // Print all typedef chains
1708 TypeSP typedef_type_sp(type_sp);
1709 TypeSP typedefed_type_sp(typedef_type_sp->GetTypedefType());
1710 while (typedefed_type_sp) {
1711 strm.EOL();
1712 strm.Printf(" typedef '%s': ",
1713 typedef_type_sp->GetName().GetCString());
1714 typedefed_type_sp->GetFullCompilerType();
1715 typedefed_type_sp->GetDescription(&strm, eDescriptionLevelFull, true);
1716 typedef_type_sp = typedefed_type_sp;
1717 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1718 }
1719 }
1720 strm.EOL();
1721 }
1722 return num_matches;
Greg Claytoneffe5c92011-05-03 22:09:39 +00001723}
1724
Kate Stoneb9c1b512016-09-06 20:57:50 +00001725static uint32_t LookupFileAndLineInModule(CommandInterpreter &interpreter,
1726 Stream &strm, Module *module,
1727 const FileSpec &file_spec,
1728 uint32_t line, bool check_inlines,
1729 bool verbose) {
1730 if (module && file_spec) {
1731 SymbolContextList sc_list;
1732 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(
1733 file_spec, line, check_inlines, eSymbolContextEverything, sc_list);
1734 if (num_matches > 0) {
1735 strm.Indent();
1736 strm.Printf("%u match%s found in ", num_matches,
1737 num_matches > 1 ? "es" : "");
1738 strm << file_spec;
1739 if (line > 0)
1740 strm.Printf(":%u", line);
1741 strm << " in ";
1742 DumpFullpath(strm, &module->GetFileSpec(), 0);
1743 strm.PutCString(":\n");
1744 DumpSymbolContextList(
1745 interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1746 strm, sc_list, verbose);
1747 return num_matches;
Greg Clayton8ee64382011-11-10 01:18:58 +00001748 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001749 }
1750 return 0;
1751}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001752
Kate Stoneb9c1b512016-09-06 20:57:50 +00001753static size_t FindModulesByName(Target *target, const char *module_name,
1754 ModuleList &module_list,
1755 bool check_global_list) {
1756 FileSpec module_file_spec(module_name, false);
1757 ModuleSpec module_spec(module_file_spec);
1758
1759 const size_t initial_size = module_list.GetSize();
1760
1761 if (check_global_list) {
1762 // Check the global list
1763 std::lock_guard<std::recursive_mutex> guard(
1764 Module::GetAllocationModuleCollectionMutex());
1765 const size_t num_modules = Module::GetNumberAllocatedModules();
1766 ModuleSP module_sp;
1767 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
1768 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1769
1770 if (module) {
1771 if (module->MatchesModuleSpec(module_spec)) {
1772 module_sp = module->shared_from_this();
1773 module_list.AppendIfNeeded(module_sp);
Greg Claytonf3156262012-07-11 20:46:47 +00001774 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001775 }
Greg Claytonf3156262012-07-11 20:46:47 +00001776 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001777 } else {
1778 if (target) {
1779 const size_t num_matches =
1780 target->GetImages().FindModules(module_spec, module_list);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001781
Kate Stoneb9c1b512016-09-06 20:57:50 +00001782 // Not found in our module list for our target, check the main
1783 // shared module list in case it is a extra file used somewhere
1784 // else
1785 if (num_matches == 0) {
1786 module_spec.GetArchitecture() = target->GetArchitecture();
1787 ModuleList::FindSharedModules(module_spec, module_list);
1788 }
1789 } else {
1790 ModuleList::FindSharedModules(module_spec, module_list);
1791 }
1792 }
1793
1794 return module_list.GetSize() - initial_size;
Greg Clayton8ee64382011-11-10 01:18:58 +00001795}
1796
Greg Claytoneffe5c92011-05-03 22:09:39 +00001797#pragma mark CommandObjectTargetModulesModuleAutoComplete
1798
1799//----------------------------------------------------------------------
1800// A base command object class that can auto complete with module file
1801// paths
1802//----------------------------------------------------------------------
1803
Kate Stoneb9c1b512016-09-06 20:57:50 +00001804class CommandObjectTargetModulesModuleAutoComplete
1805 : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001806public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001807 CommandObjectTargetModulesModuleAutoComplete(CommandInterpreter &interpreter,
1808 const char *name,
1809 const char *help,
1810 const char *syntax)
1811 : CommandObjectParsed(interpreter, name, help, syntax) {
1812 CommandArgumentEntry arg;
1813 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001814
Kate Stoneb9c1b512016-09-06 20:57:50 +00001815 // Define the first (and only) variant of this arg.
1816 file_arg.arg_type = eArgTypeFilename;
1817 file_arg.arg_repetition = eArgRepeatStar;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001818
Kate Stoneb9c1b512016-09-06 20:57:50 +00001819 // There is only one variant this argument could be; put it into the
1820 // argument entry.
1821 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001822
Kate Stoneb9c1b512016-09-06 20:57:50 +00001823 // Push the data for the first argument into the m_arguments vector.
1824 m_arguments.push_back(arg);
1825 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001826
Kate Stoneb9c1b512016-09-06 20:57:50 +00001827 ~CommandObjectTargetModulesModuleAutoComplete() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001828
Kate Stoneb9c1b512016-09-06 20:57:50 +00001829 int HandleArgumentCompletion(Args &input, int &cursor_index,
1830 int &cursor_char_position,
1831 OptionElementVector &opt_element_vector,
1832 int match_start_point, int max_return_elements,
1833 bool &word_complete,
1834 StringList &matches) override {
1835 // Arguments are the standard module completer.
1836 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
1837 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001838
Kate Stoneb9c1b512016-09-06 20:57:50 +00001839 CommandCompletions::InvokeCommonCompletionCallbacks(
1840 GetCommandInterpreter(), CommandCompletions::eModuleCompletion,
1841 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
1842 word_complete, matches);
1843 return matches.GetSize();
1844 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001845};
1846
1847#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1848
1849//----------------------------------------------------------------------
1850// A base command object class that can auto complete with module source
1851// file paths
1852//----------------------------------------------------------------------
1853
Kate Stoneb9c1b512016-09-06 20:57:50 +00001854class CommandObjectTargetModulesSourceFileAutoComplete
1855 : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001856public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001857 CommandObjectTargetModulesSourceFileAutoComplete(
1858 CommandInterpreter &interpreter, const char *name, const char *help,
1859 const char *syntax, uint32_t flags)
1860 : CommandObjectParsed(interpreter, name, help, syntax, flags) {
1861 CommandArgumentEntry arg;
1862 CommandArgumentData source_file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001863
Kate Stoneb9c1b512016-09-06 20:57:50 +00001864 // Define the first (and only) variant of this arg.
1865 source_file_arg.arg_type = eArgTypeSourceFile;
1866 source_file_arg.arg_repetition = eArgRepeatPlus;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001867
Kate Stoneb9c1b512016-09-06 20:57:50 +00001868 // There is only one variant this argument could be; put it into the
1869 // argument entry.
1870 arg.push_back(source_file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001871
Kate Stoneb9c1b512016-09-06 20:57:50 +00001872 // Push the data for the first argument into the m_arguments vector.
1873 m_arguments.push_back(arg);
1874 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001875
Kate Stoneb9c1b512016-09-06 20:57:50 +00001876 ~CommandObjectTargetModulesSourceFileAutoComplete() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001877
Kate Stoneb9c1b512016-09-06 20:57:50 +00001878 int HandleArgumentCompletion(Args &input, int &cursor_index,
1879 int &cursor_char_position,
1880 OptionElementVector &opt_element_vector,
1881 int match_start_point, int max_return_elements,
1882 bool &word_complete,
1883 StringList &matches) override {
1884 // Arguments are the standard source file completer.
1885 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
1886 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00001887
Kate Stoneb9c1b512016-09-06 20:57:50 +00001888 CommandCompletions::InvokeCommonCompletionCallbacks(
1889 GetCommandInterpreter(), CommandCompletions::eSourceFileCompletion,
1890 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
1891 word_complete, matches);
1892 return matches.GetSize();
1893 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00001894};
1895
Adrian McCarthy543725c2016-04-04 21:21:49 +00001896#pragma mark CommandObjectTargetModulesDumpObjfile
1897
Kate Stoneb9c1b512016-09-06 20:57:50 +00001898class CommandObjectTargetModulesDumpObjfile
1899 : public CommandObjectTargetModulesModuleAutoComplete {
Adrian McCarthy543725c2016-04-04 21:21:49 +00001900public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001901 CommandObjectTargetModulesDumpObjfile(CommandInterpreter &interpreter)
1902 : CommandObjectTargetModulesModuleAutoComplete(
1903 interpreter, "target modules dump objfile",
1904 "Dump the object file headers from one or more target modules.",
1905 nullptr) {}
Adrian McCarthy543725c2016-04-04 21:21:49 +00001906
Kate Stoneb9c1b512016-09-06 20:57:50 +00001907 ~CommandObjectTargetModulesDumpObjfile() override = default;
Adrian McCarthy543725c2016-04-04 21:21:49 +00001908
1909protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001910 bool DoExecute(Args &command, CommandReturnObject &result) override {
1911 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1912 if (target == nullptr) {
1913 result.AppendError("invalid target, create a debug target using the "
1914 "'target create' command");
1915 result.SetStatus(eReturnStatusFailed);
1916 return false;
Adrian McCarthy543725c2016-04-04 21:21:49 +00001917 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00001918
1919 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1920 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1921 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1922
1923 size_t num_dumped = 0;
1924 if (command.GetArgumentCount() == 0) {
1925 // Dump all headers for all modules images
1926 num_dumped = DumpModuleObjfileHeaders(result.GetOutputStream(),
1927 target->GetImages());
1928 if (num_dumped == 0) {
1929 result.AppendError("the target has no associated executable images");
1930 result.SetStatus(eReturnStatusFailed);
1931 }
1932 } else {
1933 // Find the modules that match the basename or full path.
1934 ModuleList module_list;
1935 const char *arg_cstr;
1936 for (int arg_idx = 0;
1937 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
1938 ++arg_idx) {
1939 size_t num_matched =
1940 FindModulesByName(target, arg_cstr, module_list, true);
1941 if (num_matched == 0) {
1942 result.AppendWarningWithFormat(
1943 "Unable to find an image that matches '%s'.\n", arg_cstr);
1944 }
1945 }
1946 // Dump all the modules we found.
1947 num_dumped =
1948 DumpModuleObjfileHeaders(result.GetOutputStream(), module_list);
1949 }
1950
1951 if (num_dumped > 0) {
1952 result.SetStatus(eReturnStatusSuccessFinishResult);
1953 } else {
1954 result.AppendError("no matching executable images found");
1955 result.SetStatus(eReturnStatusFailed);
1956 }
1957 return result.Succeeded();
1958 }
Adrian McCarthy543725c2016-04-04 21:21:49 +00001959};
1960
Greg Claytoneffe5c92011-05-03 22:09:39 +00001961#pragma mark CommandObjectTargetModulesDumpSymtab
1962
Zachary Turner1f0f5b52016-09-22 20:22:55 +00001963static OptionEnumValueElement g_sort_option_enumeration[4] = {
1964 {eSortOrderNone, "none",
1965 "No sorting, use the original symbol table order."},
1966 {eSortOrderByAddress, "address", "Sort output by symbol address."},
1967 {eSortOrderByName, "name", "Sort output by symbol name."},
1968 {0, nullptr, nullptr}};
1969
1970static OptionDefinition g_target_modules_dump_symtab_options[] = {
1971 // clang-format off
1972 { 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." }
1973 // clang-format on
1974};
1975
Kate Stoneb9c1b512016-09-06 20:57:50 +00001976class CommandObjectTargetModulesDumpSymtab
1977 : public CommandObjectTargetModulesModuleAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00001978public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00001979 CommandObjectTargetModulesDumpSymtab(CommandInterpreter &interpreter)
1980 : CommandObjectTargetModulesModuleAutoComplete(
1981 interpreter, "target modules dump symtab",
1982 "Dump the symbol table from one or more target modules.", nullptr),
1983 m_options() {}
1984
1985 ~CommandObjectTargetModulesDumpSymtab() override = default;
1986
1987 Options *GetOptions() override { return &m_options; }
1988
1989 class CommandOptions : public Options {
1990 public:
1991 CommandOptions() : Options(), m_sort_order(eSortOrderNone) {}
1992
1993 ~CommandOptions() override = default;
1994
Zachary Turnerfe114832016-11-12 16:56:47 +00001995 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
Kate Stoneb9c1b512016-09-06 20:57:50 +00001996 ExecutionContext *execution_context) override {
1997 Error error;
1998 const int short_option = m_getopt_table[option_idx].val;
1999
2000 switch (short_option) {
2001 case 's':
2002 m_sort_order = (SortOrder)Args::StringToOptionEnum(
Zachary Turnerfe114832016-11-12 16:56:47 +00002003 option_arg, GetDefinitions()[option_idx].enum_values,
2004 eSortOrderNone, error);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002005 break;
2006
2007 default:
2008 error.SetErrorStringWithFormat("invalid short option character '%c'",
2009 short_option);
2010 break;
2011 }
2012 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002013 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002014
Kate Stoneb9c1b512016-09-06 20:57:50 +00002015 void OptionParsingStarting(ExecutionContext *execution_context) override {
2016 m_sort_order = eSortOrderNone;
Jim Ingham5a988412012-06-08 21:56:10 +00002017 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002018
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002019 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00002020 return llvm::makeArrayRef(g_target_modules_dump_symtab_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002021 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002022
Kate Stoneb9c1b512016-09-06 20:57:50 +00002023 SortOrder m_sort_order;
2024 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002025
Jim Ingham5a988412012-06-08 21:56:10 +00002026protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002027 bool DoExecute(Args &command, CommandReturnObject &result) override {
2028 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2029 if (target == nullptr) {
2030 result.AppendError("invalid target, create a debug target using the "
2031 "'target create' command");
2032 result.SetStatus(eReturnStatusFailed);
2033 return false;
2034 } else {
2035 uint32_t num_dumped = 0;
2036
2037 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2038 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2039 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2040
2041 if (command.GetArgumentCount() == 0) {
2042 // Dump all sections for all modules images
2043 std::lock_guard<std::recursive_mutex> guard(
2044 target->GetImages().GetMutex());
2045 const size_t num_modules = target->GetImages().GetSize();
2046 if (num_modules > 0) {
2047 result.GetOutputStream().Printf("Dumping symbol table for %" PRIu64
2048 " modules.\n",
2049 (uint64_t)num_modules);
2050 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2051 if (num_dumped > 0) {
2052 result.GetOutputStream().EOL();
2053 result.GetOutputStream().EOL();
2054 }
2055 num_dumped++;
2056 DumpModuleSymtab(
2057 m_interpreter, result.GetOutputStream(),
2058 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2059 m_options.m_sort_order);
2060 }
2061 } else {
2062 result.AppendError("the target has no associated executable images");
2063 result.SetStatus(eReturnStatusFailed);
2064 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002065 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002066 } else {
2067 // Dump specified images (by basename or fullpath)
2068 const char *arg_cstr;
2069 for (int arg_idx = 0;
2070 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2071 ++arg_idx) {
2072 ModuleList module_list;
2073 const size_t num_matches =
2074 FindModulesByName(target, arg_cstr, module_list, true);
2075 if (num_matches > 0) {
2076 for (size_t i = 0; i < num_matches; ++i) {
2077 Module *module = module_list.GetModulePointerAtIndex(i);
2078 if (module) {
2079 if (num_dumped > 0) {
2080 result.GetOutputStream().EOL();
2081 result.GetOutputStream().EOL();
Greg Claytoneffe5c92011-05-03 22:09:39 +00002082 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002083 num_dumped++;
2084 DumpModuleSymtab(m_interpreter, result.GetOutputStream(),
2085 module, m_options.m_sort_order);
2086 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002087 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002088 } else
2089 result.AppendWarningWithFormat(
2090 "Unable to find an image that matches '%s'.\n", arg_cstr);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002091 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002092 }
2093
2094 if (num_dumped > 0)
2095 result.SetStatus(eReturnStatusSuccessFinishResult);
2096 else {
2097 result.AppendError("no matching executable images found");
2098 result.SetStatus(eReturnStatusFailed);
2099 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002100 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002101 return result.Succeeded();
2102 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002103
Kate Stoneb9c1b512016-09-06 20:57:50 +00002104 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002105};
2106
Greg Claytoneffe5c92011-05-03 22:09:39 +00002107#pragma mark CommandObjectTargetModulesDumpSections
2108
2109//----------------------------------------------------------------------
2110// Image section dumping command
2111//----------------------------------------------------------------------
2112
Kate Stoneb9c1b512016-09-06 20:57:50 +00002113class CommandObjectTargetModulesDumpSections
2114 : public CommandObjectTargetModulesModuleAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002115public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002116 CommandObjectTargetModulesDumpSections(CommandInterpreter &interpreter)
2117 : CommandObjectTargetModulesModuleAutoComplete(
2118 interpreter, "target modules dump sections",
2119 "Dump the sections from one or more target modules.",
2120 //"target modules dump sections [<file1> ...]")
2121 nullptr) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002122
Kate Stoneb9c1b512016-09-06 20:57:50 +00002123 ~CommandObjectTargetModulesDumpSections() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002124
Jim Ingham5a988412012-06-08 21:56:10 +00002125protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002126 bool DoExecute(Args &command, CommandReturnObject &result) override {
2127 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2128 if (target == nullptr) {
2129 result.AppendError("invalid target, create a debug target using the "
2130 "'target create' command");
2131 result.SetStatus(eReturnStatusFailed);
2132 return false;
2133 } else {
2134 uint32_t num_dumped = 0;
2135
2136 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2137 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2138 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2139
2140 if (command.GetArgumentCount() == 0) {
2141 // Dump all sections for all modules images
2142 const size_t num_modules = target->GetImages().GetSize();
2143 if (num_modules > 0) {
2144 result.GetOutputStream().Printf("Dumping sections for %" PRIu64
2145 " modules.\n",
2146 (uint64_t)num_modules);
2147 for (size_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2148 num_dumped++;
2149 DumpModuleSections(
2150 m_interpreter, result.GetOutputStream(),
2151 target->GetImages().GetModulePointerAtIndex(image_idx));
2152 }
2153 } else {
2154 result.AppendError("the target has no associated executable images");
2155 result.SetStatus(eReturnStatusFailed);
2156 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002157 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002158 } else {
2159 // Dump specified images (by basename or fullpath)
2160 const char *arg_cstr;
2161 for (int arg_idx = 0;
2162 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2163 ++arg_idx) {
2164 ModuleList module_list;
2165 const size_t num_matches =
2166 FindModulesByName(target, arg_cstr, module_list, true);
2167 if (num_matches > 0) {
2168 for (size_t i = 0; i < num_matches; ++i) {
2169 Module *module = module_list.GetModulePointerAtIndex(i);
2170 if (module) {
2171 num_dumped++;
2172 DumpModuleSections(m_interpreter, result.GetOutputStream(),
2173 module);
2174 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002175 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002176 } else {
2177 // Check the global list
2178 std::lock_guard<std::recursive_mutex> guard(
2179 Module::GetAllocationModuleCollectionMutex());
Greg Clayton8ee64382011-11-10 01:18:58 +00002180
Kate Stoneb9c1b512016-09-06 20:57:50 +00002181 result.AppendWarningWithFormat(
2182 "Unable to find an image that matches '%s'.\n", arg_cstr);
2183 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002184 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002185 }
2186
2187 if (num_dumped > 0)
2188 result.SetStatus(eReturnStatusSuccessFinishResult);
2189 else {
2190 result.AppendError("no matching executable images found");
2191 result.SetStatus(eReturnStatusFailed);
2192 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002193 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002194 return result.Succeeded();
2195 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002196};
2197
Greg Claytoneffe5c92011-05-03 22:09:39 +00002198#pragma mark CommandObjectTargetModulesDumpSymfile
2199
2200//----------------------------------------------------------------------
2201// Image debug symbol dumping command
2202//----------------------------------------------------------------------
2203
Kate Stoneb9c1b512016-09-06 20:57:50 +00002204class CommandObjectTargetModulesDumpSymfile
2205 : public CommandObjectTargetModulesModuleAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002206public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002207 CommandObjectTargetModulesDumpSymfile(CommandInterpreter &interpreter)
2208 : CommandObjectTargetModulesModuleAutoComplete(
2209 interpreter, "target modules dump symfile",
2210 "Dump the debug symbol file for one or more target modules.",
2211 //"target modules dump symfile [<file1> ...]")
2212 nullptr) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002213
Kate Stoneb9c1b512016-09-06 20:57:50 +00002214 ~CommandObjectTargetModulesDumpSymfile() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002215
Jim Ingham5a988412012-06-08 21:56:10 +00002216protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002217 bool DoExecute(Args &command, CommandReturnObject &result) override {
2218 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2219 if (target == nullptr) {
2220 result.AppendError("invalid target, create a debug target using the "
2221 "'target create' command");
2222 result.SetStatus(eReturnStatusFailed);
2223 return false;
2224 } else {
2225 uint32_t num_dumped = 0;
2226
2227 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2228 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2229 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2230
2231 if (command.GetArgumentCount() == 0) {
2232 // Dump all sections for all modules images
2233 const ModuleList &target_modules = target->GetImages();
2234 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2235 const size_t num_modules = target_modules.GetSize();
2236 if (num_modules > 0) {
2237 result.GetOutputStream().Printf("Dumping debug symbols for %" PRIu64
2238 " modules.\n",
2239 (uint64_t)num_modules);
2240 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
2241 if (DumpModuleSymbolVendor(
2242 result.GetOutputStream(),
2243 target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
2244 num_dumped++;
2245 }
2246 } else {
2247 result.AppendError("the target has no associated executable images");
2248 result.SetStatus(eReturnStatusFailed);
2249 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002250 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002251 } else {
2252 // Dump specified images (by basename or fullpath)
2253 const char *arg_cstr;
2254 for (int arg_idx = 0;
2255 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2256 ++arg_idx) {
2257 ModuleList module_list;
2258 const size_t num_matches =
2259 FindModulesByName(target, arg_cstr, module_list, true);
2260 if (num_matches > 0) {
2261 for (size_t i = 0; i < num_matches; ++i) {
2262 Module *module = module_list.GetModulePointerAtIndex(i);
2263 if (module) {
2264 if (DumpModuleSymbolVendor(result.GetOutputStream(), module))
2265 num_dumped++;
2266 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002267 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002268 } else
2269 result.AppendWarningWithFormat(
2270 "Unable to find an image that matches '%s'.\n", arg_cstr);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002271 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002272 }
2273
2274 if (num_dumped > 0)
2275 result.SetStatus(eReturnStatusSuccessFinishResult);
2276 else {
2277 result.AppendError("no matching executable images found");
2278 result.SetStatus(eReturnStatusFailed);
2279 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002280 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002281 return result.Succeeded();
2282 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002283};
2284
Greg Claytoneffe5c92011-05-03 22:09:39 +00002285#pragma mark CommandObjectTargetModulesDumpLineTable
2286
2287//----------------------------------------------------------------------
2288// Image debug line table dumping command
2289//----------------------------------------------------------------------
2290
Kate Stoneb9c1b512016-09-06 20:57:50 +00002291class CommandObjectTargetModulesDumpLineTable
2292 : public CommandObjectTargetModulesSourceFileAutoComplete {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002293public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002294 CommandObjectTargetModulesDumpLineTable(CommandInterpreter &interpreter)
2295 : CommandObjectTargetModulesSourceFileAutoComplete(
2296 interpreter, "target modules dump line-table",
2297 "Dump the line table for one or more compilation units.", nullptr,
2298 eCommandRequiresTarget) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002299
Kate Stoneb9c1b512016-09-06 20:57:50 +00002300 ~CommandObjectTargetModulesDumpLineTable() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002301
Jim Ingham5a988412012-06-08 21:56:10 +00002302protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002303 bool DoExecute(Args &command, CommandReturnObject &result) override {
2304 Target *target = m_exe_ctx.GetTargetPtr();
2305 uint32_t total_num_dumped = 0;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002306
Kate Stoneb9c1b512016-09-06 20:57:50 +00002307 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2308 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2309 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002310
Kate Stoneb9c1b512016-09-06 20:57:50 +00002311 if (command.GetArgumentCount() == 0) {
2312 result.AppendError("file option must be specified.");
2313 result.SetStatus(eReturnStatusFailed);
2314 return result.Succeeded();
2315 } else {
2316 // Dump specified images (by basename or fullpath)
2317 const char *arg_cstr;
2318 for (int arg_idx = 0;
2319 (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != nullptr;
2320 ++arg_idx) {
2321 FileSpec file_spec(arg_cstr, false);
2322
2323 const ModuleList &target_modules = target->GetImages();
2324 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
2325 const size_t num_modules = target_modules.GetSize();
2326 if (num_modules > 0) {
2327 uint32_t num_dumped = 0;
2328 for (uint32_t i = 0; i < num_modules; ++i) {
2329 if (DumpCompileUnitLineTable(
2330 m_interpreter, result.GetOutputStream(),
2331 target_modules.GetModulePointerAtIndexUnlocked(i),
2332 file_spec, m_exe_ctx.GetProcessPtr() &&
2333 m_exe_ctx.GetProcessRef().IsAlive()))
2334 num_dumped++;
2335 }
2336 if (num_dumped == 0)
2337 result.AppendWarningWithFormat(
2338 "No source filenames matched '%s'.\n", arg_cstr);
2339 else
2340 total_num_dumped += num_dumped;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002341 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002342 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002343 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002344
2345 if (total_num_dumped > 0)
2346 result.SetStatus(eReturnStatusSuccessFinishResult);
2347 else {
2348 result.AppendError("no source filenames matched any command arguments");
2349 result.SetStatus(eReturnStatusFailed);
2350 }
2351 return result.Succeeded();
2352 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002353};
2354
Greg Claytoneffe5c92011-05-03 22:09:39 +00002355#pragma mark CommandObjectTargetModulesDump
2356
2357//----------------------------------------------------------------------
2358// Dump multi-word command for target modules
2359//----------------------------------------------------------------------
2360
Kate Stoneb9c1b512016-09-06 20:57:50 +00002361class CommandObjectTargetModulesDump : public CommandObjectMultiword {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002362public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002363 //------------------------------------------------------------------
2364 // Constructors and Destructors
2365 //------------------------------------------------------------------
2366 CommandObjectTargetModulesDump(CommandInterpreter &interpreter)
2367 : CommandObjectMultiword(interpreter, "target modules dump",
2368 "Commands for dumping information about one or "
2369 "more target modules.",
2370 "target modules dump "
2371 "[headers|symtab|sections|symfile|line-table] "
2372 "[<file1> <file2> ...]") {
2373 LoadSubCommand("objfile",
2374 CommandObjectSP(
2375 new CommandObjectTargetModulesDumpObjfile(interpreter)));
2376 LoadSubCommand(
2377 "symtab",
2378 CommandObjectSP(new CommandObjectTargetModulesDumpSymtab(interpreter)));
2379 LoadSubCommand("sections",
2380 CommandObjectSP(new CommandObjectTargetModulesDumpSections(
2381 interpreter)));
2382 LoadSubCommand("symfile",
2383 CommandObjectSP(
2384 new CommandObjectTargetModulesDumpSymfile(interpreter)));
2385 LoadSubCommand("line-table",
2386 CommandObjectSP(new CommandObjectTargetModulesDumpLineTable(
2387 interpreter)));
2388 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002389
Kate Stoneb9c1b512016-09-06 20:57:50 +00002390 ~CommandObjectTargetModulesDump() override = default;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002391};
2392
Kate Stoneb9c1b512016-09-06 20:57:50 +00002393class CommandObjectTargetModulesAdd : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002394public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002395 CommandObjectTargetModulesAdd(CommandInterpreter &interpreter)
2396 : CommandObjectParsed(interpreter, "target modules add",
2397 "Add a new module to the current target's modules.",
2398 "target modules add [<module>]"),
Todd Fialae1cfbc72016-08-11 23:51:28 +00002399 m_option_group(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00002400 m_symbol_file(LLDB_OPT_SET_1, false, "symfile", 's', 0,
2401 eArgTypeFilename, "Fullpath to a stand alone debug "
2402 "symbols file for when debug symbols "
2403 "are not in the executable.") {
2404 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2405 LLDB_OPT_SET_1);
2406 m_option_group.Append(&m_symbol_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2407 m_option_group.Finalize();
2408 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002409
Kate Stoneb9c1b512016-09-06 20:57:50 +00002410 ~CommandObjectTargetModulesAdd() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002411
Kate Stoneb9c1b512016-09-06 20:57:50 +00002412 Options *GetOptions() override { return &m_option_group; }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002413
Kate Stoneb9c1b512016-09-06 20:57:50 +00002414 int HandleArgumentCompletion(Args &input, int &cursor_index,
2415 int &cursor_char_position,
2416 OptionElementVector &opt_element_vector,
2417 int match_start_point, int max_return_elements,
2418 bool &word_complete,
2419 StringList &matches) override {
2420 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
2421 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002422
Kate Stoneb9c1b512016-09-06 20:57:50 +00002423 CommandCompletions::InvokeCommonCompletionCallbacks(
2424 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
2425 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
2426 word_complete, matches);
2427 return matches.GetSize();
2428 }
Jim Ingham5a988412012-06-08 21:56:10 +00002429
2430protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002431 OptionGroupOptions m_option_group;
2432 OptionGroupUUID m_uuid_option_group;
2433 OptionGroupFile m_symbol_file;
Greg Clayton50a24bd2012-11-29 22:16:27 +00002434
Kate Stoneb9c1b512016-09-06 20:57:50 +00002435 bool DoExecute(Args &args, CommandReturnObject &result) override {
2436 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2437 if (target == nullptr) {
2438 result.AppendError("invalid target, create a debug target using the "
2439 "'target create' command");
2440 result.SetStatus(eReturnStatusFailed);
2441 return false;
2442 } else {
2443 bool flush = false;
2444
2445 const size_t argc = args.GetArgumentCount();
2446 if (argc == 0) {
2447 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2448 // We are given a UUID only, go locate the file
2449 ModuleSpec module_spec;
2450 module_spec.GetUUID() =
2451 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2452 if (m_symbol_file.GetOptionValue().OptionWasSet())
2453 module_spec.GetSymbolFileSpec() =
2454 m_symbol_file.GetOptionValue().GetCurrentValue();
2455 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
2456 ModuleSP module_sp(target->GetSharedModule(module_spec));
2457 if (module_sp) {
2458 result.SetStatus(eReturnStatusSuccessFinishResult);
2459 return true;
2460 } else {
2461 StreamString strm;
2462 module_spec.GetUUID().Dump(&strm);
2463 if (module_spec.GetFileSpec()) {
2464 if (module_spec.GetSymbolFileSpec()) {
2465 result.AppendErrorWithFormat(
2466 "Unable to create the executable or symbol file with "
2467 "UUID %s with path %s and symbol file %s",
Zachary Turnerc1564272016-11-16 21:15:24 +00002468 strm.GetData(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00002469 module_spec.GetFileSpec().GetPath().c_str(),
2470 module_spec.GetSymbolFileSpec().GetPath().c_str());
2471 } else {
2472 result.AppendErrorWithFormat(
2473 "Unable to create the executable or symbol file with "
2474 "UUID %s with path %s",
Zachary Turnerc1564272016-11-16 21:15:24 +00002475 strm.GetData(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00002476 module_spec.GetFileSpec().GetPath().c_str());
2477 }
2478 } else {
2479 result.AppendErrorWithFormat("Unable to create the executable "
2480 "or symbol file with UUID %s",
Zachary Turnerc1564272016-11-16 21:15:24 +00002481 strm.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002482 }
2483 result.SetStatus(eReturnStatusFailed);
2484 return false;
2485 }
2486 } else {
2487 StreamString strm;
2488 module_spec.GetUUID().Dump(&strm);
2489 result.AppendErrorWithFormat(
2490 "Unable to locate the executable or symbol file with UUID %s",
Zachary Turnerc1564272016-11-16 21:15:24 +00002491 strm.GetData());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002492 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002493 return false;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002494 }
2495 } else {
2496 result.AppendError(
2497 "one or more executable image paths must be specified");
2498 result.SetStatus(eReturnStatusFailed);
2499 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002500 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002501 } else {
Zachary Turner97d2c402016-10-05 23:40:23 +00002502 for (auto &entry : args.entries()) {
2503 if (entry.ref.empty())
2504 continue;
2505
2506 FileSpec file_spec(entry.ref, true);
2507 if (file_spec.Exists()) {
2508 ModuleSpec module_spec(file_spec);
2509 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2510 module_spec.GetUUID() =
2511 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2512 if (m_symbol_file.GetOptionValue().OptionWasSet())
2513 module_spec.GetSymbolFileSpec() =
2514 m_symbol_file.GetOptionValue().GetCurrentValue();
2515 if (!module_spec.GetArchitecture().IsValid())
2516 module_spec.GetArchitecture() = target->GetArchitecture();
2517 Error error;
2518 ModuleSP module_sp(target->GetSharedModule(module_spec, &error));
2519 if (!module_sp) {
2520 const char *error_cstr = error.AsCString();
2521 if (error_cstr)
2522 result.AppendError(error_cstr);
2523 else
2524 result.AppendErrorWithFormat("unsupported module: %s",
2525 entry.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002526 result.SetStatus(eReturnStatusFailed);
Zachary Turner97d2c402016-10-05 23:40:23 +00002527 return false;
2528 } else {
2529 flush = true;
2530 }
2531 result.SetStatus(eReturnStatusSuccessFinishResult);
2532 } else {
2533 std::string resolved_path = file_spec.GetPath();
2534 result.SetStatus(eReturnStatusFailed);
2535 if (resolved_path != entry.ref) {
2536 result.AppendErrorWithFormat(
2537 "invalid module path '%s' with resolved path '%s'\n",
2538 entry.ref.str().c_str(), resolved_path.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00002539 break;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002540 }
Zachary Turner97d2c402016-10-05 23:40:23 +00002541 result.AppendErrorWithFormat("invalid module path '%s'\n",
2542 entry.c_str());
2543 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002544 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00002545 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002546 }
2547
2548 if (flush) {
2549 ProcessSP process = target->GetProcessSP();
2550 if (process)
2551 process->Flush();
2552 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002553 }
2554
Kate Stoneb9c1b512016-09-06 20:57:50 +00002555 return result.Succeeded();
2556 }
2557};
2558
2559class CommandObjectTargetModulesLoad
2560 : public CommandObjectTargetModulesModuleAutoComplete {
2561public:
2562 CommandObjectTargetModulesLoad(CommandInterpreter &interpreter)
2563 : CommandObjectTargetModulesModuleAutoComplete(
2564 interpreter, "target modules load", "Set the load addresses for "
2565 "one or more sections in a "
2566 "target module.",
2567 "target modules load [--file <module> --uuid <uuid>] <sect-name> "
2568 "<address> [<sect-name> <address> ....]"),
2569 m_option_group(),
2570 m_file_option(LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypeName,
2571 "Fullpath or basename for module to load.", ""),
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002572 m_load_option(LLDB_OPT_SET_1, false, "load", 'l',
Hafiz Abid Qadeerb10fb962017-01-24 23:07:27 +00002573 "Write file contents to the memory.", false, true),
2574 m_pc_option(LLDB_OPT_SET_1, false, "--set-pc-to-entry", 'p',
2575 "Set PC to the entry point."
2576 " Only applicable with '--load' option.",
2577 false, true),
Kate Stoneb9c1b512016-09-06 20:57:50 +00002578 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset,
2579 "Set the load address for all sections to be the "
2580 "virtual address in the file plus the offset.",
2581 0) {
2582 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
2583 LLDB_OPT_SET_1);
2584 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002585 m_option_group.Append(&m_load_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Hafiz Abid Qadeerb10fb962017-01-24 23:07:27 +00002586 m_option_group.Append(&m_pc_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002587 m_option_group.Append(&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2588 m_option_group.Finalize();
2589 }
2590
2591 ~CommandObjectTargetModulesLoad() override = default;
2592
2593 Options *GetOptions() override { return &m_option_group; }
2594
2595protected:
2596 bool DoExecute(Args &args, CommandReturnObject &result) override {
2597 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002598 const bool load = m_load_option.GetOptionValue().GetCurrentValue();
Hafiz Abid Qadeerb10fb962017-01-24 23:07:27 +00002599 const bool set_pc = m_pc_option.GetOptionValue().GetCurrentValue();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002600 if (target == nullptr) {
2601 result.AppendError("invalid target, create a debug target using the "
2602 "'target create' command");
2603 result.SetStatus(eReturnStatusFailed);
2604 return false;
2605 } else {
2606 const size_t argc = args.GetArgumentCount();
2607 ModuleSpec module_spec;
2608 bool search_using_module_spec = false;
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002609
2610 // Allow "load" option to work without --file or --uuid
2611 // option.
2612 if (load) {
2613 if (!m_file_option.GetOptionValue().OptionWasSet() &&
2614 !m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2615 ModuleList &module_list = target->GetImages();
2616 if (module_list.GetSize() == 1) {
2617 search_using_module_spec = true;
2618 module_spec.GetFileSpec() =
2619 module_list.GetModuleAtIndex(0)->GetFileSpec();
2620 }
2621 }
2622 }
2623
Kate Stoneb9c1b512016-09-06 20:57:50 +00002624 if (m_file_option.GetOptionValue().OptionWasSet()) {
2625 search_using_module_spec = true;
2626 const char *arg_cstr = m_file_option.GetOptionValue().GetCurrentValue();
2627 const bool use_global_module_list = true;
2628 ModuleList module_list;
2629 const size_t num_matches = FindModulesByName(
2630 target, arg_cstr, module_list, use_global_module_list);
2631 if (num_matches == 1) {
2632 module_spec.GetFileSpec() =
2633 module_list.GetModuleAtIndex(0)->GetFileSpec();
2634 } else if (num_matches > 1) {
2635 search_using_module_spec = false;
2636 result.AppendErrorWithFormat(
2637 "more than 1 module matched by name '%s'\n", arg_cstr);
2638 result.SetStatus(eReturnStatusFailed);
2639 } else {
2640 search_using_module_spec = false;
2641 result.AppendErrorWithFormat("no object file for module '%s'\n",
2642 arg_cstr);
2643 result.SetStatus(eReturnStatusFailed);
2644 }
2645 }
2646
2647 if (m_uuid_option_group.GetOptionValue().OptionWasSet()) {
2648 search_using_module_spec = true;
2649 module_spec.GetUUID() =
2650 m_uuid_option_group.GetOptionValue().GetCurrentValue();
2651 }
2652
2653 if (search_using_module_spec) {
2654 ModuleList matching_modules;
2655 const size_t num_matches =
2656 target->GetImages().FindModules(module_spec, matching_modules);
2657
2658 char path[PATH_MAX];
2659 if (num_matches == 1) {
2660 Module *module = matching_modules.GetModulePointerAtIndex(0);
2661 if (module) {
2662 ObjectFile *objfile = module->GetObjectFile();
2663 if (objfile) {
2664 SectionList *section_list = module->GetSectionList();
2665 if (section_list) {
2666 bool changed = false;
2667 if (argc == 0) {
2668 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2669 const addr_t slide =
2670 m_slide_option.GetOptionValue().GetCurrentValue();
2671 const bool slide_is_offset = true;
2672 module->SetLoadAddress(*target, slide, slide_is_offset,
2673 changed);
2674 } else {
2675 result.AppendError("one or more section name + load "
2676 "address pair must be specified");
2677 result.SetStatus(eReturnStatusFailed);
2678 return false;
2679 }
2680 } else {
2681 if (m_slide_option.GetOptionValue().OptionWasSet()) {
2682 result.AppendError("The \"--slide <offset>\" option can't "
2683 "be used in conjunction with setting "
2684 "section load addresses.\n");
2685 result.SetStatus(eReturnStatusFailed);
2686 return false;
2687 }
2688
2689 for (size_t i = 0; i < argc; i += 2) {
2690 const char *sect_name = args.GetArgumentAtIndex(i);
2691 const char *load_addr_cstr = args.GetArgumentAtIndex(i + 1);
2692 if (sect_name && load_addr_cstr) {
2693 ConstString const_sect_name(sect_name);
2694 bool success = false;
2695 addr_t load_addr = StringConvert::ToUInt64(
2696 load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2697 if (success) {
2698 SectionSP section_sp(
2699 section_list->FindSectionByName(const_sect_name));
2700 if (section_sp) {
2701 if (section_sp->IsThreadSpecific()) {
2702 result.AppendErrorWithFormat(
2703 "thread specific sections are not yet "
2704 "supported (section '%s')\n",
2705 sect_name);
2706 result.SetStatus(eReturnStatusFailed);
2707 break;
2708 } else {
2709 if (target->GetSectionLoadList()
2710 .SetSectionLoadAddress(section_sp,
2711 load_addr))
2712 changed = true;
2713 result.AppendMessageWithFormat(
2714 "section '%s' loaded at 0x%" PRIx64 "\n",
2715 sect_name, load_addr);
2716 }
2717 } else {
2718 result.AppendErrorWithFormat("no section found that "
2719 "matches the section "
2720 "name '%s'\n",
2721 sect_name);
2722 result.SetStatus(eReturnStatusFailed);
2723 break;
2724 }
2725 } else {
2726 result.AppendErrorWithFormat(
2727 "invalid load address string '%s'\n",
2728 load_addr_cstr);
2729 result.SetStatus(eReturnStatusFailed);
2730 break;
2731 }
2732 } else {
2733 if (sect_name)
2734 result.AppendError("section names must be followed by "
2735 "a load address.\n");
2736 else
2737 result.AppendError("one or more section name + load "
2738 "address pair must be specified.\n");
2739 result.SetStatus(eReturnStatusFailed);
2740 break;
2741 }
2742 }
2743 }
2744
2745 if (changed) {
2746 target->ModulesDidLoad(matching_modules);
2747 Process *process = m_exe_ctx.GetProcessPtr();
2748 if (process)
2749 process->Flush();
2750 }
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002751 if (load) {
Hafiz Abid Qadeerb10fb962017-01-24 23:07:27 +00002752 Error error = module->LoadInMemory(*target, set_pc);
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002753 if (error.Fail()) {
2754 result.AppendError(error.AsCString());
2755 return false;
2756 }
2757 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002758 } else {
2759 module->GetFileSpec().GetPath(path, sizeof(path));
2760 result.AppendErrorWithFormat(
2761 "no sections in object file '%s'\n", path);
2762 result.SetStatus(eReturnStatusFailed);
2763 }
2764 } else {
2765 module->GetFileSpec().GetPath(path, sizeof(path));
2766 result.AppendErrorWithFormat("no object file for module '%s'\n",
2767 path);
2768 result.SetStatus(eReturnStatusFailed);
2769 }
2770 } else {
2771 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2772 if (module_spec_file) {
2773 module_spec_file->GetPath(path, sizeof(path));
2774 result.AppendErrorWithFormat("invalid module '%s'.\n", path);
2775 } else
2776 result.AppendError("no module spec");
2777 result.SetStatus(eReturnStatusFailed);
2778 }
2779 } else {
2780 std::string uuid_str;
2781
2782 if (module_spec.GetFileSpec())
2783 module_spec.GetFileSpec().GetPath(path, sizeof(path));
2784 else
2785 path[0] = '\0';
2786
2787 if (module_spec.GetUUIDPtr())
2788 uuid_str = module_spec.GetUUID().GetAsString();
2789 if (num_matches > 1) {
2790 result.AppendErrorWithFormat(
2791 "multiple modules match%s%s%s%s:\n", path[0] ? " file=" : "",
2792 path, !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2793 for (size_t i = 0; i < num_matches; ++i) {
2794 if (matching_modules.GetModulePointerAtIndex(i)
2795 ->GetFileSpec()
2796 .GetPath(path, sizeof(path)))
2797 result.AppendMessageWithFormat("%s\n", path);
2798 }
2799 } else {
2800 result.AppendErrorWithFormat(
2801 "no modules were found that match%s%s%s%s.\n",
2802 path[0] ? " file=" : "", path,
2803 !uuid_str.empty() ? " uuid=" : "", uuid_str.c_str());
2804 }
2805 result.SetStatus(eReturnStatusFailed);
2806 }
2807 } else {
2808 result.AppendError("either the \"--file <module>\" or the \"--uuid "
2809 "<uuid>\" option must be specified.\n");
2810 result.SetStatus(eReturnStatusFailed);
2811 return false;
2812 }
2813 }
2814 return result.Succeeded();
2815 }
2816
2817 OptionGroupOptions m_option_group;
2818 OptionGroupUUID m_uuid_option_group;
2819 OptionGroupString m_file_option;
Hafiz Abid Qadeer4687db02017-01-19 17:32:50 +00002820 OptionGroupBoolean m_load_option;
Hafiz Abid Qadeerb10fb962017-01-24 23:07:27 +00002821 OptionGroupBoolean m_pc_option;
Kate Stoneb9c1b512016-09-06 20:57:50 +00002822 OptionGroupUInt64 m_slide_option;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002823};
2824
2825//----------------------------------------------------------------------
2826// List images with associated information
2827//----------------------------------------------------------------------
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002828
2829static OptionDefinition g_target_modules_list_options[] = {
2830 // clang-format off
2831 { LLDB_OPT_SET_1, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Display the image at this address." },
2832 { LLDB_OPT_SET_1, false, "arch", 'A', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the architecture when listing images." },
2833 { LLDB_OPT_SET_1, false, "triple", 't', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the triple when listing images." },
2834 { 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." },
2835 { 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)." },
2836 { LLDB_OPT_SET_1, false, "uuid", 'u', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the UUID when listing images." },
2837 { LLDB_OPT_SET_1, false, "fullpath", 'f', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image object file." },
2838 { LLDB_OPT_SET_1, false, "directory", 'd', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the directory with optional width for the image object file." },
2839 { LLDB_OPT_SET_1, false, "basename", 'b', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the basename with optional width for the image object file." },
2840 { LLDB_OPT_SET_1, false, "symfile", 's', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width." },
2841 { 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." },
2842 { LLDB_OPT_SET_1, false, "mod-time", 'm', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeWidth, "Display the modification time with optional width of the module." },
2843 { 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." },
2844 { LLDB_OPT_SET_1, false, "pointer", 'p', OptionParser::eOptionalArgument, nullptr, nullptr, 0, eArgTypeNone, "Display the module pointer." },
2845 { 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." }
2846 // clang-format on
2847};
2848
Kate Stoneb9c1b512016-09-06 20:57:50 +00002849class CommandObjectTargetModulesList : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00002850public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002851 class CommandOptions : public Options {
2852 public:
2853 CommandOptions()
2854 : Options(), m_format_array(), m_use_global_module_list(false),
2855 m_module_addr(LLDB_INVALID_ADDRESS) {}
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002856
Kate Stoneb9c1b512016-09-06 20:57:50 +00002857 ~CommandOptions() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002858
Zachary Turnerfe114832016-11-12 16:56:47 +00002859 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
Kate Stoneb9c1b512016-09-06 20:57:50 +00002860 ExecutionContext *execution_context) override {
2861 Error error;
Greg Claytonb9d5df52012-12-06 22:49:16 +00002862
Kate Stoneb9c1b512016-09-06 20:57:50 +00002863 const int short_option = m_getopt_table[option_idx].val;
2864 if (short_option == 'g') {
2865 m_use_global_module_list = true;
2866 } else if (short_option == 'a') {
2867 m_module_addr = Args::StringToAddress(execution_context, option_arg,
2868 LLDB_INVALID_ADDRESS, &error);
2869 } else {
2870 unsigned long width = 0;
Zachary Turnerfe114832016-11-12 16:56:47 +00002871 option_arg.getAsInteger(0, width);
Kate Stoneb9c1b512016-09-06 20:57:50 +00002872 m_format_array.push_back(std::make_pair(short_option, width));
2873 }
2874 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002875 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002876
Kate Stoneb9c1b512016-09-06 20:57:50 +00002877 void OptionParsingStarting(ExecutionContext *execution_context) override {
2878 m_format_array.clear();
2879 m_use_global_module_list = false;
2880 m_module_addr = LLDB_INVALID_ADDRESS;
Greg Claytoneffe5c92011-05-03 22:09:39 +00002881 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00002882
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002883 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00002884 return llvm::makeArrayRef(g_target_modules_list_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00002885 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002886
2887 // Instance variables to hold the values for command options.
2888 typedef std::vector<std::pair<char, uint32_t>> FormatWidthCollection;
2889 FormatWidthCollection m_format_array;
2890 bool m_use_global_module_list;
2891 lldb::addr_t m_module_addr;
2892 };
2893
2894 CommandObjectTargetModulesList(CommandInterpreter &interpreter)
2895 : CommandObjectParsed(
2896 interpreter, "target modules list",
2897 "List current executable and dependent shared library images.",
2898 "target modules list [<cmd-options>]"),
2899 m_options() {}
2900
2901 ~CommandObjectTargetModulesList() override = default;
2902
2903 Options *GetOptions() override { return &m_options; }
2904
Jim Ingham5a988412012-06-08 21:56:10 +00002905protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00002906 bool DoExecute(Args &command, CommandReturnObject &result) override {
2907 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2908 const bool use_global_module_list = m_options.m_use_global_module_list;
2909 // Define a local module list here to ensure it lives longer than any
2910 // "locker"
2911 // object which might lock its contents below (through the "module_list_ptr"
2912 // variable).
2913 ModuleList module_list;
2914 if (target == nullptr && !use_global_module_list) {
2915 result.AppendError("invalid target, create a debug target using the "
2916 "'target create' command");
2917 result.SetStatus(eReturnStatusFailed);
2918 return false;
2919 } else {
2920 if (target) {
2921 uint32_t addr_byte_size =
2922 target->GetArchitecture().GetAddressByteSize();
2923 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2924 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2925 }
2926 // Dump all sections for all modules images
2927 Stream &strm = result.GetOutputStream();
2928
2929 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS) {
2930 if (target) {
2931 Address module_address;
2932 if (module_address.SetLoadAddress(m_options.m_module_addr, target)) {
2933 ModuleSP module_sp(module_address.GetModule());
2934 if (module_sp) {
2935 PrintModule(target, module_sp.get(), 0, strm);
2936 result.SetStatus(eReturnStatusSuccessFinishResult);
2937 } else {
2938 result.AppendErrorWithFormat(
2939 "Couldn't find module matching address: 0x%" PRIx64 ".",
2940 m_options.m_module_addr);
2941 result.SetStatus(eReturnStatusFailed);
Greg Clayton3418c852011-08-10 02:10:13 +00002942 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002943 } else {
2944 result.AppendErrorWithFormat(
2945 "Couldn't find module containing address: 0x%" PRIx64 ".",
2946 m_options.m_module_addr);
2947 result.SetStatus(eReturnStatusFailed);
2948 }
2949 } else {
2950 result.AppendError(
2951 "Can only look up modules by address with a valid target.");
2952 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00002953 }
2954 return result.Succeeded();
Kate Stoneb9c1b512016-09-06 20:57:50 +00002955 }
Jim Inghamc10312c2011-10-24 18:36:33 +00002956
Kate Stoneb9c1b512016-09-06 20:57:50 +00002957 size_t num_modules = 0;
2958
2959 // This locker will be locked on the mutex in module_list_ptr if it is
2960 // non-nullptr.
2961 // Otherwise it will lock the AllocationModuleCollectionMutex when
2962 // accessing
2963 // the global module list directly.
2964 std::unique_lock<std::recursive_mutex> guard(
2965 Module::GetAllocationModuleCollectionMutex(), std::defer_lock);
2966
2967 const ModuleList *module_list_ptr = nullptr;
2968 const size_t argc = command.GetArgumentCount();
2969 if (argc == 0) {
2970 if (use_global_module_list) {
2971 guard.lock();
2972 num_modules = Module::GetNumberAllocatedModules();
2973 } else {
2974 module_list_ptr = &target->GetImages();
Jim Ingham28eb5712012-10-12 17:34:26 +00002975 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002976 } else {
Zachary Turner97d2c402016-10-05 23:40:23 +00002977 // TODO: Convert to entry based iteration. Requires converting
2978 // FindModulesByName.
Kate Stoneb9c1b512016-09-06 20:57:50 +00002979 for (size_t i = 0; i < argc; ++i) {
2980 // Dump specified images (by basename or fullpath)
2981 const char *arg_cstr = command.GetArgumentAtIndex(i);
2982 const size_t num_matches = FindModulesByName(
2983 target, arg_cstr, module_list, use_global_module_list);
2984 if (num_matches == 0) {
2985 if (argc == 1) {
2986 result.AppendErrorWithFormat("no modules found that match '%s'",
2987 arg_cstr);
2988 result.SetStatus(eReturnStatusFailed);
2989 return false;
Jim Inghamc10312c2011-10-24 18:36:33 +00002990 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002991 }
Greg Claytonc9660542012-02-05 02:38:54 +00002992 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00002993
2994 module_list_ptr = &module_list;
2995 }
2996
2997 std::unique_lock<std::recursive_mutex> lock;
2998 if (module_list_ptr != nullptr) {
2999 lock =
3000 std::unique_lock<std::recursive_mutex>(module_list_ptr->GetMutex());
3001
3002 num_modules = module_list_ptr->GetSize();
3003 }
3004
3005 if (num_modules > 0) {
3006 for (uint32_t image_idx = 0; image_idx < num_modules; ++image_idx) {
3007 ModuleSP module_sp;
3008 Module *module;
3009 if (module_list_ptr) {
3010 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
3011 module = module_sp.get();
3012 } else {
3013 module = Module::GetAllocatedModuleAtIndex(image_idx);
3014 module_sp = module->shared_from_this();
3015 }
3016
3017 const size_t indent = strm.Printf("[%3u] ", image_idx);
3018 PrintModule(target, module, indent, strm);
Jim Inghamc10312c2011-10-24 18:36:33 +00003019 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003020 result.SetStatus(eReturnStatusSuccessFinishResult);
3021 } else {
3022 if (argc) {
3023 if (use_global_module_list)
3024 result.AppendError(
3025 "the global module list has no matching modules");
3026 else
3027 result.AppendError("the target has no matching modules");
3028 } else {
3029 if (use_global_module_list)
3030 result.AppendError("the global module list is empty");
3031 else
3032 result.AppendError(
3033 "the target has no associated executable images");
3034 }
3035 result.SetStatus(eReturnStatusFailed);
3036 return false;
3037 }
3038 }
3039 return result.Succeeded();
3040 }
3041
3042 void PrintModule(Target *target, Module *module, int indent, Stream &strm) {
3043 if (module == nullptr) {
3044 strm.PutCString("Null module");
3045 return;
Jim Inghamc10312c2011-10-24 18:36:33 +00003046 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003047
Kate Stoneb9c1b512016-09-06 20:57:50 +00003048 bool dump_object_name = false;
3049 if (m_options.m_format_array.empty()) {
3050 m_options.m_format_array.push_back(std::make_pair('u', 0));
3051 m_options.m_format_array.push_back(std::make_pair('h', 0));
3052 m_options.m_format_array.push_back(std::make_pair('f', 0));
3053 m_options.m_format_array.push_back(std::make_pair('S', 0));
3054 }
3055 const size_t num_entries = m_options.m_format_array.size();
3056 bool print_space = false;
3057 for (size_t i = 0; i < num_entries; ++i) {
3058 if (print_space)
3059 strm.PutChar(' ');
3060 print_space = true;
3061 const char format_char = m_options.m_format_array[i].first;
3062 uint32_t width = m_options.m_format_array[i].second;
3063 switch (format_char) {
3064 case 'A':
3065 DumpModuleArchitecture(strm, module, false, width);
3066 break;
3067
3068 case 't':
3069 DumpModuleArchitecture(strm, module, true, width);
3070 break;
3071
3072 case 'f':
3073 DumpFullpath(strm, &module->GetFileSpec(), width);
3074 dump_object_name = true;
3075 break;
3076
3077 case 'd':
3078 DumpDirectory(strm, &module->GetFileSpec(), width);
3079 break;
3080
3081 case 'b':
3082 DumpBasename(strm, &module->GetFileSpec(), width);
3083 dump_object_name = true;
3084 break;
3085
3086 case 'h':
3087 case 'o':
3088 // Image header address
3089 {
3090 uint32_t addr_nibble_width =
3091 target ? (target->GetArchitecture().GetAddressByteSize() * 2)
3092 : 16;
3093
3094 ObjectFile *objfile = module->GetObjectFile();
3095 if (objfile) {
3096 Address header_addr(objfile->GetHeaderAddress());
3097 if (header_addr.IsValid()) {
3098 if (target && !target->GetSectionLoadList().IsEmpty()) {
3099 lldb::addr_t header_load_addr =
3100 header_addr.GetLoadAddress(target);
3101 if (header_load_addr == LLDB_INVALID_ADDRESS) {
3102 header_addr.Dump(&strm, target,
3103 Address::DumpStyleModuleWithFileAddress,
3104 Address::DumpStyleFileAddress);
3105 } else {
3106 if (format_char == 'o') {
3107 // Show the offset of slide for the image
3108 strm.Printf(
3109 "0x%*.*" PRIx64, addr_nibble_width, addr_nibble_width,
3110 header_load_addr - header_addr.GetFileAddress());
3111 } else {
3112 // Show the load address of the image
3113 strm.Printf("0x%*.*" PRIx64, addr_nibble_width,
3114 addr_nibble_width, header_load_addr);
3115 }
3116 }
3117 break;
3118 }
3119 // The address was valid, but the image isn't loaded, output the
3120 // address in an appropriate format
3121 header_addr.Dump(&strm, target, Address::DumpStyleFileAddress);
3122 break;
3123 }
3124 }
3125 strm.Printf("%*s", addr_nibble_width + 2, "");
3126 }
3127 break;
3128
3129 case 'r': {
3130 size_t ref_count = 0;
3131 ModuleSP module_sp(module->shared_from_this());
3132 if (module_sp) {
3133 // Take one away to make sure we don't count our local "module_sp"
3134 ref_count = module_sp.use_count() - 1;
3135 }
3136 if (width)
3137 strm.Printf("{%*" PRIu64 "}", width, (uint64_t)ref_count);
3138 else
3139 strm.Printf("{%" PRIu64 "}", (uint64_t)ref_count);
3140 } break;
3141
3142 case 's':
3143 case 'S': {
3144 const SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3145 if (symbol_vendor) {
3146 const FileSpec symfile_spec = symbol_vendor->GetMainFileSpec();
3147 if (format_char == 'S') {
3148 // Dump symbol file only if different from module file
3149 if (!symfile_spec || symfile_spec == module->GetFileSpec()) {
3150 print_space = false;
3151 break;
3152 }
3153 // Add a newline and indent past the index
3154 strm.Printf("\n%*s", indent, "");
3155 }
3156 DumpFullpath(strm, &symfile_spec, width);
3157 dump_object_name = true;
3158 break;
3159 }
3160 strm.Printf("%.*s", width, "<NONE>");
3161 } break;
3162
3163 case 'm':
Pavel Labath7e2cfbf2016-11-09 09:59:18 +00003164 DumpTimePoint(module->GetModificationTime(), strm, width);
Kate Stoneb9c1b512016-09-06 20:57:50 +00003165 break;
3166
3167 case 'p':
3168 strm.Printf("%p", static_cast<void *>(module));
3169 break;
3170
3171 case 'u':
3172 DumpModuleUUID(strm, module);
3173 break;
3174
3175 default:
3176 break;
3177 }
3178 }
3179 if (dump_object_name) {
3180 const char *object_name = module->GetObjectName().GetCString();
3181 if (object_name)
3182 strm.Printf("(%s)", object_name);
3183 }
3184 strm.EOL();
3185 }
3186
3187 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003188};
3189
Jason Molenda380241a2012-07-12 00:20:07 +00003190#pragma mark CommandObjectTargetModulesShowUnwind
Greg Claytoneffe5c92011-05-03 22:09:39 +00003191
Jason Molenda380241a2012-07-12 00:20:07 +00003192//----------------------------------------------------------------------
3193// Lookup unwind information in images
3194//----------------------------------------------------------------------
3195
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003196static OptionDefinition g_target_modules_show_unwind_options[] = {
3197 // clang-format off
3198 { LLDB_OPT_SET_1, false, "name", 'n', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeFunctionName, "Show unwind instructions for a function or symbol name." },
3199 { LLDB_OPT_SET_2, false, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Show unwind instructions for a function or symbol containing an address" }
3200 // clang-format on
3201};
3202
Kate Stoneb9c1b512016-09-06 20:57:50 +00003203class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed {
Jason Molenda380241a2012-07-12 00:20:07 +00003204public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003205 enum {
3206 eLookupTypeInvalid = -1,
3207 eLookupTypeAddress = 0,
3208 eLookupTypeSymbol,
3209 eLookupTypeFunction,
3210 eLookupTypeFunctionOrSymbol,
3211 kNumLookupTypes
3212 };
Jason Molenda380241a2012-07-12 00:20:07 +00003213
Kate Stoneb9c1b512016-09-06 20:57:50 +00003214 class CommandOptions : public Options {
3215 public:
3216 CommandOptions()
3217 : Options(), m_type(eLookupTypeInvalid), m_str(),
3218 m_addr(LLDB_INVALID_ADDRESS) {}
Jason Molenda380241a2012-07-12 00:20:07 +00003219
Kate Stoneb9c1b512016-09-06 20:57:50 +00003220 ~CommandOptions() override = default;
Jason Molenda380241a2012-07-12 00:20:07 +00003221
Zachary Turnerfe114832016-11-12 16:56:47 +00003222 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
Kate Stoneb9c1b512016-09-06 20:57:50 +00003223 ExecutionContext *execution_context) override {
3224 Error error;
Jason Molenda380241a2012-07-12 00:20:07 +00003225
Kate Stoneb9c1b512016-09-06 20:57:50 +00003226 const int short_option = m_getopt_table[option_idx].val;
Jason Molenda380241a2012-07-12 00:20:07 +00003227
Kate Stoneb9c1b512016-09-06 20:57:50 +00003228 switch (short_option) {
3229 case 'a': {
3230 m_str = option_arg;
3231 m_type = eLookupTypeAddress;
3232 m_addr = Args::StringToAddress(execution_context, option_arg,
3233 LLDB_INVALID_ADDRESS, &error);
3234 if (m_addr == LLDB_INVALID_ADDRESS)
3235 error.SetErrorStringWithFormat("invalid address string '%s'",
Zachary Turnerfe114832016-11-12 16:56:47 +00003236 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003237 break;
3238 }
Jason Molenda380241a2012-07-12 00:20:07 +00003239
Kate Stoneb9c1b512016-09-06 20:57:50 +00003240 case 'n':
3241 m_str = option_arg;
3242 m_type = eLookupTypeFunctionOrSymbol;
3243 break;
Michael Sartainb1e15922013-08-22 20:42:30 +00003244
Kate Stoneb9c1b512016-09-06 20:57:50 +00003245 default:
3246 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
3247 break;
3248 }
Jason Molenda380241a2012-07-12 00:20:07 +00003249
Kate Stoneb9c1b512016-09-06 20:57:50 +00003250 return error;
Jason Molenda380241a2012-07-12 00:20:07 +00003251 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003252
Kate Stoneb9c1b512016-09-06 20:57:50 +00003253 void OptionParsingStarting(ExecutionContext *execution_context) override {
3254 m_type = eLookupTypeInvalid;
3255 m_str.clear();
3256 m_addr = LLDB_INVALID_ADDRESS;
Jason Molenda380241a2012-07-12 00:20:07 +00003257 }
3258
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003259 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00003260 return llvm::makeArrayRef(g_target_modules_show_unwind_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003261 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003262
3263 // Instance variables to hold the values for command options.
3264
3265 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3266 std::string m_str; // Holds name lookup
3267 lldb::addr_t m_addr; // Holds the address to lookup
3268 };
3269
3270 CommandObjectTargetModulesShowUnwind(CommandInterpreter &interpreter)
3271 : CommandObjectParsed(
3272 interpreter, "target modules show-unwind",
3273 "Show synthesized unwind instructions for a function.", nullptr,
3274 eCommandRequiresTarget | eCommandRequiresProcess |
3275 eCommandProcessMustBeLaunched | eCommandProcessMustBePaused),
3276 m_options() {}
3277
3278 ~CommandObjectTargetModulesShowUnwind() override = default;
3279
3280 Options *GetOptions() override { return &m_options; }
3281
Jason Molenda380241a2012-07-12 00:20:07 +00003282protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003283 bool DoExecute(Args &command, CommandReturnObject &result) override {
3284 Target *target = m_exe_ctx.GetTargetPtr();
3285 Process *process = m_exe_ctx.GetProcessPtr();
3286 ABI *abi = nullptr;
3287 if (process)
3288 abi = process->GetABI().get();
Jason Molenda380241a2012-07-12 00:20:07 +00003289
Kate Stoneb9c1b512016-09-06 20:57:50 +00003290 if (process == nullptr) {
3291 result.AppendError(
3292 "You must have a process running to use this command.");
3293 result.SetStatus(eReturnStatusFailed);
3294 return false;
Jason Molenda380241a2012-07-12 00:20:07 +00003295 }
3296
Kate Stoneb9c1b512016-09-06 20:57:50 +00003297 ThreadList threads(process->GetThreadList());
3298 if (threads.GetSize() == 0) {
3299 result.AppendError("The process must be paused to use this command.");
3300 result.SetStatus(eReturnStatusFailed);
3301 return false;
3302 }
3303
3304 ThreadSP thread(threads.GetThreadAtIndex(0));
3305 if (!thread) {
3306 result.AppendError("The process must be paused to use this command.");
3307 result.SetStatus(eReturnStatusFailed);
3308 return false;
3309 }
3310
3311 SymbolContextList sc_list;
3312
3313 if (m_options.m_type == eLookupTypeFunctionOrSymbol) {
3314 ConstString function_name(m_options.m_str.c_str());
3315 target->GetImages().FindFunctions(function_name, eFunctionNameTypeAuto,
3316 true, false, true, sc_list);
3317 } else if (m_options.m_type == eLookupTypeAddress && target) {
3318 Address addr;
3319 if (target->GetSectionLoadList().ResolveLoadAddress(m_options.m_addr,
3320 addr)) {
3321 SymbolContext sc;
3322 ModuleSP module_sp(addr.GetModule());
3323 module_sp->ResolveSymbolContextForAddress(addr,
3324 eSymbolContextEverything, sc);
3325 if (sc.function || sc.symbol) {
3326 sc_list.Append(sc);
3327 }
3328 }
3329 } else {
3330 result.AppendError(
3331 "address-expression or function name option must be specified.");
3332 result.SetStatus(eReturnStatusFailed);
3333 return false;
3334 }
3335
3336 size_t num_matches = sc_list.GetSize();
3337 if (num_matches == 0) {
3338 result.AppendErrorWithFormat("no unwind data found that matches '%s'.",
3339 m_options.m_str.c_str());
3340 result.SetStatus(eReturnStatusFailed);
3341 return false;
3342 }
3343
3344 for (uint32_t idx = 0; idx < num_matches; idx++) {
3345 SymbolContext sc;
3346 sc_list.GetContextAtIndex(idx, sc);
3347 if (sc.symbol == nullptr && sc.function == nullptr)
3348 continue;
3349 if (!sc.module_sp || sc.module_sp->GetObjectFile() == nullptr)
3350 continue;
3351 AddressRange range;
3352 if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
3353 false, range))
3354 continue;
3355 if (!range.GetBaseAddress().IsValid())
3356 continue;
3357 ConstString funcname(sc.GetFunctionName());
3358 if (funcname.IsEmpty())
3359 continue;
3360 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3361 if (abi)
3362 start_addr = abi->FixCodeAddress(start_addr);
3363
3364 FuncUnwindersSP func_unwinders_sp(
3365 sc.module_sp->GetObjectFile()
3366 ->GetUnwindTable()
3367 .GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3368 if (!func_unwinders_sp)
3369 continue;
3370
3371 result.GetOutputStream().Printf(
3372 "UNWIND PLANS for %s`%s (start addr 0x%" PRIx64 ")\n\n",
3373 sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(),
3374 funcname.AsCString(), start_addr);
3375
3376 UnwindPlanSP non_callsite_unwind_plan =
3377 func_unwinders_sp->GetUnwindPlanAtNonCallSite(*target, *thread, -1);
3378 if (non_callsite_unwind_plan) {
3379 result.GetOutputStream().Printf(
3380 "Asynchronous (not restricted to call-sites) UnwindPlan is '%s'\n",
3381 non_callsite_unwind_plan->GetSourceName().AsCString());
3382 }
3383 UnwindPlanSP callsite_unwind_plan =
3384 func_unwinders_sp->GetUnwindPlanAtCallSite(*target, -1);
3385 if (callsite_unwind_plan) {
3386 result.GetOutputStream().Printf(
3387 "Synchronous (restricted to call-sites) UnwindPlan is '%s'\n",
3388 callsite_unwind_plan->GetSourceName().AsCString());
3389 }
3390 UnwindPlanSP fast_unwind_plan =
3391 func_unwinders_sp->GetUnwindPlanFastUnwind(*target, *thread);
3392 if (fast_unwind_plan) {
3393 result.GetOutputStream().Printf(
3394 "Fast UnwindPlan is '%s'\n",
3395 fast_unwind_plan->GetSourceName().AsCString());
3396 }
3397
3398 result.GetOutputStream().Printf("\n");
3399
3400 UnwindPlanSP assembly_sp =
3401 func_unwinders_sp->GetAssemblyUnwindPlan(*target, *thread, 0);
3402 if (assembly_sp) {
3403 result.GetOutputStream().Printf(
3404 "Assembly language inspection UnwindPlan:\n");
3405 assembly_sp->Dump(result.GetOutputStream(), thread.get(),
3406 LLDB_INVALID_ADDRESS);
3407 result.GetOutputStream().Printf("\n");
3408 }
3409
3410 UnwindPlanSP ehframe_sp =
3411 func_unwinders_sp->GetEHFrameUnwindPlan(*target, 0);
3412 if (ehframe_sp) {
3413 result.GetOutputStream().Printf("eh_frame UnwindPlan:\n");
3414 ehframe_sp->Dump(result.GetOutputStream(), thread.get(),
3415 LLDB_INVALID_ADDRESS);
3416 result.GetOutputStream().Printf("\n");
3417 }
3418
3419 UnwindPlanSP ehframe_augmented_sp =
3420 func_unwinders_sp->GetEHFrameAugmentedUnwindPlan(*target, *thread, 0);
3421 if (ehframe_augmented_sp) {
3422 result.GetOutputStream().Printf("eh_frame augmented UnwindPlan:\n");
3423 ehframe_augmented_sp->Dump(result.GetOutputStream(), thread.get(),
3424 LLDB_INVALID_ADDRESS);
3425 result.GetOutputStream().Printf("\n");
3426 }
3427
3428 UnwindPlanSP arm_unwind_sp =
3429 func_unwinders_sp->GetArmUnwindUnwindPlan(*target, 0);
3430 if (arm_unwind_sp) {
3431 result.GetOutputStream().Printf("ARM.exidx unwind UnwindPlan:\n");
3432 arm_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3433 LLDB_INVALID_ADDRESS);
3434 result.GetOutputStream().Printf("\n");
3435 }
3436
3437 UnwindPlanSP compact_unwind_sp =
3438 func_unwinders_sp->GetCompactUnwindUnwindPlan(*target, 0);
3439 if (compact_unwind_sp) {
3440 result.GetOutputStream().Printf("Compact unwind UnwindPlan:\n");
3441 compact_unwind_sp->Dump(result.GetOutputStream(), thread.get(),
3442 LLDB_INVALID_ADDRESS);
3443 result.GetOutputStream().Printf("\n");
3444 }
3445
3446 if (fast_unwind_plan) {
3447 result.GetOutputStream().Printf("Fast UnwindPlan:\n");
3448 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(),
3449 LLDB_INVALID_ADDRESS);
3450 result.GetOutputStream().Printf("\n");
3451 }
3452
3453 ABISP abi_sp = process->GetABI();
3454 if (abi_sp) {
3455 UnwindPlan arch_default(lldb::eRegisterKindGeneric);
3456 if (abi_sp->CreateDefaultUnwindPlan(arch_default)) {
3457 result.GetOutputStream().Printf("Arch default UnwindPlan:\n");
3458 arch_default.Dump(result.GetOutputStream(), thread.get(),
3459 LLDB_INVALID_ADDRESS);
3460 result.GetOutputStream().Printf("\n");
3461 }
3462
3463 UnwindPlan arch_entry(lldb::eRegisterKindGeneric);
3464 if (abi_sp->CreateFunctionEntryUnwindPlan(arch_entry)) {
3465 result.GetOutputStream().Printf(
3466 "Arch default at entry point UnwindPlan:\n");
3467 arch_entry.Dump(result.GetOutputStream(), thread.get(),
3468 LLDB_INVALID_ADDRESS);
3469 result.GetOutputStream().Printf("\n");
3470 }
3471 }
3472
3473 result.GetOutputStream().Printf("\n");
3474 }
3475 return result.Succeeded();
3476 }
3477
3478 CommandOptions m_options;
Jason Molenda380241a2012-07-12 00:20:07 +00003479};
3480
Greg Claytoneffe5c92011-05-03 22:09:39 +00003481//----------------------------------------------------------------------
3482// Lookup information in images
3483//----------------------------------------------------------------------
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003484
3485static OptionDefinition g_target_modules_lookup_options[] = {
3486 // clang-format off
3487 { LLDB_OPT_SET_1, true, "address", 'a', OptionParser::eRequiredArgument, nullptr, nullptr, 0, eArgTypeAddressOrExpression, "Lookup an address in one or more target modules." },
3488 { 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." },
3489 /* FIXME: re-enable regex for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */
3490 { 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." },
3491 { 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." },
3492 { 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." },
3493 { 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)." },
3494 { 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)." },
3495 { 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." },
3496 { 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." },
3497 { 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." },
3498 { LLDB_OPT_SET_ALL, false, "verbose", 'v', OptionParser::eNoArgument, nullptr, nullptr, 0, eArgTypeNone, "Enable verbose lookup information." },
3499 { 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." },
3500 // clang-format on
3501};
3502
Kate Stoneb9c1b512016-09-06 20:57:50 +00003503class CommandObjectTargetModulesLookup : public CommandObjectParsed {
Greg Claytoneffe5c92011-05-03 22:09:39 +00003504public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003505 enum {
3506 eLookupTypeInvalid = -1,
3507 eLookupTypeAddress = 0,
3508 eLookupTypeSymbol,
3509 eLookupTypeFileLine, // Line is optional
3510 eLookupTypeFunction,
3511 eLookupTypeFunctionOrSymbol,
3512 eLookupTypeType,
3513 kNumLookupTypes
3514 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003515
Kate Stoneb9c1b512016-09-06 20:57:50 +00003516 class CommandOptions : public Options {
3517 public:
3518 CommandOptions() : Options() { OptionParsingStarting(nullptr); }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003519
Kate Stoneb9c1b512016-09-06 20:57:50 +00003520 ~CommandOptions() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003521
Zachary Turnerfe114832016-11-12 16:56:47 +00003522 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
Kate Stoneb9c1b512016-09-06 20:57:50 +00003523 ExecutionContext *execution_context) override {
3524 Error error;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003525
Kate Stoneb9c1b512016-09-06 20:57:50 +00003526 const int short_option = m_getopt_table[option_idx].val;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003527
Kate Stoneb9c1b512016-09-06 20:57:50 +00003528 switch (short_option) {
3529 case 'a': {
3530 m_type = eLookupTypeAddress;
3531 m_addr = Args::StringToAddress(execution_context, option_arg,
3532 LLDB_INVALID_ADDRESS, &error);
3533 } break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003534
Kate Stoneb9c1b512016-09-06 20:57:50 +00003535 case 'o':
Zachary Turnerfe114832016-11-12 16:56:47 +00003536 if (option_arg.getAsInteger(0, m_offset))
Kate Stoneb9c1b512016-09-06 20:57:50 +00003537 error.SetErrorStringWithFormat("invalid offset string '%s'",
Zachary Turnerfe114832016-11-12 16:56:47 +00003538 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003539 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003540
Kate Stoneb9c1b512016-09-06 20:57:50 +00003541 case 's':
3542 m_str = option_arg;
3543 m_type = eLookupTypeSymbol;
3544 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003545
Kate Stoneb9c1b512016-09-06 20:57:50 +00003546 case 'f':
3547 m_file.SetFile(option_arg, false);
3548 m_type = eLookupTypeFileLine;
3549 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003550
Kate Stoneb9c1b512016-09-06 20:57:50 +00003551 case 'i':
3552 m_include_inlines = false;
3553 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003554
Kate Stoneb9c1b512016-09-06 20:57:50 +00003555 case 'l':
Zachary Turnerfe114832016-11-12 16:56:47 +00003556 if (option_arg.getAsInteger(0, m_line_number))
Kate Stoneb9c1b512016-09-06 20:57:50 +00003557 error.SetErrorStringWithFormat("invalid line number string '%s'",
Zachary Turnerfe114832016-11-12 16:56:47 +00003558 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00003559 else if (m_line_number == 0)
3560 error.SetErrorString("zero is an invalid line number");
3561 m_type = eLookupTypeFileLine;
3562 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003563
Kate Stoneb9c1b512016-09-06 20:57:50 +00003564 case 'F':
3565 m_str = option_arg;
3566 m_type = eLookupTypeFunction;
3567 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003568
Kate Stoneb9c1b512016-09-06 20:57:50 +00003569 case 'n':
3570 m_str = option_arg;
3571 m_type = eLookupTypeFunctionOrSymbol;
3572 break;
Greg Claytonc4a8a762012-05-15 18:43:44 +00003573
Kate Stoneb9c1b512016-09-06 20:57:50 +00003574 case 't':
3575 m_str = option_arg;
3576 m_type = eLookupTypeType;
3577 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003578
Kate Stoneb9c1b512016-09-06 20:57:50 +00003579 case 'v':
3580 m_verbose = 1;
3581 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003582
Kate Stoneb9c1b512016-09-06 20:57:50 +00003583 case 'A':
3584 m_print_all = true;
3585 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003586
Kate Stoneb9c1b512016-09-06 20:57:50 +00003587 case 'r':
3588 m_use_regex = true;
3589 break;
3590 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003591
Kate Stoneb9c1b512016-09-06 20:57:50 +00003592 return error;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003593 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003594
Kate Stoneb9c1b512016-09-06 20:57:50 +00003595 void OptionParsingStarting(ExecutionContext *execution_context) override {
3596 m_type = eLookupTypeInvalid;
3597 m_str.clear();
3598 m_file.Clear();
3599 m_addr = LLDB_INVALID_ADDRESS;
3600 m_offset = 0;
3601 m_line_number = 0;
3602 m_use_regex = false;
3603 m_include_inlines = true;
3604 m_verbose = false;
3605 m_print_all = false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003606 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003607
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003608 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00003609 return llvm::makeArrayRef(g_target_modules_lookup_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00003610 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003611
Kate Stoneb9c1b512016-09-06 20:57:50 +00003612 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3613 std::string m_str; // Holds name lookup
3614 FileSpec m_file; // Files for file lookups
3615 lldb::addr_t m_addr; // Holds the address to lookup
3616 lldb::addr_t
3617 m_offset; // Subtract this offset from m_addr before doing lookups.
3618 uint32_t m_line_number; // Line number for file+line lookups
3619 bool m_use_regex; // Name lookups in m_str are regular expressions.
3620 bool m_include_inlines; // Check for inline entries when looking up by
3621 // file/line.
3622 bool m_verbose; // Enable verbose lookup info
3623 bool m_print_all; // Print all matches, even in cases where there's a best
3624 // match.
3625 };
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003626
Kate Stoneb9c1b512016-09-06 20:57:50 +00003627 CommandObjectTargetModulesLookup(CommandInterpreter &interpreter)
3628 : CommandObjectParsed(interpreter, "target modules lookup",
3629 "Look up information within executable and "
3630 "dependent shared library images.",
3631 nullptr, eCommandRequiresTarget),
3632 m_options() {
3633 CommandArgumentEntry arg;
3634 CommandArgumentData file_arg;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003635
Kate Stoneb9c1b512016-09-06 20:57:50 +00003636 // Define the first (and only) variant of this arg.
3637 file_arg.arg_type = eArgTypeFilename;
3638 file_arg.arg_repetition = eArgRepeatStar;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003639
Kate Stoneb9c1b512016-09-06 20:57:50 +00003640 // There is only one variant this argument could be; put it into the
3641 // argument entry.
3642 arg.push_back(file_arg);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003643
Kate Stoneb9c1b512016-09-06 20:57:50 +00003644 // Push the data for the first argument into the m_arguments vector.
3645 m_arguments.push_back(arg);
3646 }
3647
3648 ~CommandObjectTargetModulesLookup() override = default;
3649
3650 Options *GetOptions() override { return &m_options; }
3651
3652 bool LookupHere(CommandInterpreter &interpreter, CommandReturnObject &result,
3653 bool &syntax_error) {
3654 switch (m_options.m_type) {
3655 case eLookupTypeAddress:
3656 case eLookupTypeFileLine:
3657 case eLookupTypeFunction:
3658 case eLookupTypeFunctionOrSymbol:
3659 case eLookupTypeSymbol:
3660 default:
3661 return false;
3662 case eLookupTypeType:
3663 break;
Sean Callanand38b4a92012-06-06 20:49:55 +00003664 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003665
Kate Stoneb9c1b512016-09-06 20:57:50 +00003666 StackFrameSP frame = m_exe_ctx.GetFrameSP();
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003667
Kate Stoneb9c1b512016-09-06 20:57:50 +00003668 if (!frame)
3669 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003670
Kate Stoneb9c1b512016-09-06 20:57:50 +00003671 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
Greg Claytonc4a8a762012-05-15 18:43:44 +00003672
Kate Stoneb9c1b512016-09-06 20:57:50 +00003673 if (!sym_ctx.module_sp)
3674 return false;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003675
Kate Stoneb9c1b512016-09-06 20:57:50 +00003676 switch (m_options.m_type) {
3677 default:
3678 return false;
3679 case eLookupTypeType:
3680 if (!m_options.m_str.empty()) {
3681 if (LookupTypeHere(m_interpreter, result.GetOutputStream(), sym_ctx,
3682 m_options.m_str.c_str(), m_options.m_use_regex)) {
3683 result.SetStatus(eReturnStatusSuccessFinishResult);
3684 return true;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003685 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003686 }
3687 break;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003688 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003689
Kate Stoneb9c1b512016-09-06 20:57:50 +00003690 return true;
3691 }
3692
3693 bool LookupInModule(CommandInterpreter &interpreter, Module *module,
3694 CommandReturnObject &result, bool &syntax_error) {
3695 switch (m_options.m_type) {
3696 case eLookupTypeAddress:
3697 if (m_options.m_addr != LLDB_INVALID_ADDRESS) {
3698 if (LookupAddressInModule(
3699 m_interpreter, result.GetOutputStream(), module,
3700 eSymbolContextEverything |
3701 (m_options.m_verbose
3702 ? static_cast<int>(eSymbolContextVariable)
3703 : 0),
3704 m_options.m_addr, m_options.m_offset, m_options.m_verbose)) {
3705 result.SetStatus(eReturnStatusSuccessFinishResult);
3706 return true;
3707 }
3708 }
3709 break;
3710
3711 case eLookupTypeSymbol:
3712 if (!m_options.m_str.empty()) {
3713 if (LookupSymbolInModule(m_interpreter, result.GetOutputStream(),
3714 module, m_options.m_str.c_str(),
3715 m_options.m_use_regex, m_options.m_verbose)) {
3716 result.SetStatus(eReturnStatusSuccessFinishResult);
3717 return true;
3718 }
3719 }
3720 break;
3721
3722 case eLookupTypeFileLine:
3723 if (m_options.m_file) {
3724 if (LookupFileAndLineInModule(
3725 m_interpreter, result.GetOutputStream(), module,
3726 m_options.m_file, m_options.m_line_number,
3727 m_options.m_include_inlines, m_options.m_verbose)) {
3728 result.SetStatus(eReturnStatusSuccessFinishResult);
3729 return true;
3730 }
3731 }
3732 break;
3733
3734 case eLookupTypeFunctionOrSymbol:
3735 case eLookupTypeFunction:
3736 if (!m_options.m_str.empty()) {
3737 if (LookupFunctionInModule(
3738 m_interpreter, result.GetOutputStream(), module,
3739 m_options.m_str.c_str(), m_options.m_use_regex,
3740 m_options.m_include_inlines,
3741 m_options.m_type ==
3742 eLookupTypeFunctionOrSymbol, // include symbols
3743 m_options.m_verbose)) {
3744 result.SetStatus(eReturnStatusSuccessFinishResult);
3745 return true;
3746 }
3747 }
3748 break;
3749
3750 case eLookupTypeType:
3751 if (!m_options.m_str.empty()) {
3752 if (LookupTypeInModule(m_interpreter, result.GetOutputStream(), module,
3753 m_options.m_str.c_str(),
3754 m_options.m_use_regex)) {
3755 result.SetStatus(eReturnStatusSuccessFinishResult);
3756 return true;
3757 }
3758 }
3759 break;
3760
3761 default:
3762 m_options.GenerateOptionUsage(
3763 result.GetErrorStream(), this,
3764 GetCommandInterpreter().GetDebugger().GetTerminalWidth());
3765 syntax_error = true;
3766 break;
3767 }
3768
3769 result.SetStatus(eReturnStatusFailed);
3770 return false;
3771 }
3772
Jim Ingham5a988412012-06-08 21:56:10 +00003773protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003774 bool DoExecute(Args &command, CommandReturnObject &result) override {
3775 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3776 if (target == nullptr) {
3777 result.AppendError("invalid target, create a debug target using the "
3778 "'target create' command");
3779 result.SetStatus(eReturnStatusFailed);
3780 return false;
3781 } else {
3782 bool syntax_error = false;
3783 uint32_t i;
3784 uint32_t num_successful_lookups = 0;
3785 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3786 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3787 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3788 // Dump all sections for all modules images
3789
3790 if (command.GetArgumentCount() == 0) {
3791 ModuleSP current_module;
3792
3793 // Where it is possible to look in the current symbol context
3794 // first, try that. If this search was successful and --all
3795 // was not passed, don't print anything else.
3796 if (LookupHere(m_interpreter, result, syntax_error)) {
3797 result.GetOutputStream().EOL();
3798 num_successful_lookups++;
3799 if (!m_options.m_print_all) {
3800 result.SetStatus(eReturnStatusSuccessFinishResult);
3801 return result.Succeeded();
3802 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00003803 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003804
Kate Stoneb9c1b512016-09-06 20:57:50 +00003805 // Dump all sections for all other modules
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003806
Kate Stoneb9c1b512016-09-06 20:57:50 +00003807 const ModuleList &target_modules = target->GetImages();
3808 std::lock_guard<std::recursive_mutex> guard(target_modules.GetMutex());
3809 const size_t num_modules = target_modules.GetSize();
3810 if (num_modules > 0) {
3811 for (i = 0; i < num_modules && !syntax_error; ++i) {
3812 Module *module_pointer =
3813 target_modules.GetModulePointerAtIndexUnlocked(i);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003814
Kate Stoneb9c1b512016-09-06 20:57:50 +00003815 if (module_pointer != current_module.get() &&
3816 LookupInModule(
3817 m_interpreter,
3818 target_modules.GetModulePointerAtIndexUnlocked(i), result,
3819 syntax_error)) {
3820 result.GetOutputStream().EOL();
3821 num_successful_lookups++;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003822 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003823 }
3824 } else {
3825 result.AppendError("the target has no associated executable images");
3826 result.SetStatus(eReturnStatusFailed);
3827 return false;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003828 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003829 } else {
3830 // Dump specified images (by basename or fullpath)
3831 const char *arg_cstr;
3832 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != nullptr &&
3833 !syntax_error;
3834 ++i) {
3835 ModuleList module_list;
3836 const size_t num_matches =
3837 FindModulesByName(target, arg_cstr, module_list, false);
3838 if (num_matches > 0) {
3839 for (size_t j = 0; j < num_matches; ++j) {
3840 Module *module = module_list.GetModulePointerAtIndex(j);
3841 if (module) {
3842 if (LookupInModule(m_interpreter, module, result,
3843 syntax_error)) {
3844 result.GetOutputStream().EOL();
3845 num_successful_lookups++;
3846 }
3847 }
3848 }
3849 } else
3850 result.AppendWarningWithFormat(
3851 "Unable to find an image that matches '%s'.\n", arg_cstr);
3852 }
3853 }
3854
3855 if (num_successful_lookups > 0)
3856 result.SetStatus(eReturnStatusSuccessFinishResult);
3857 else
3858 result.SetStatus(eReturnStatusFailed);
Greg Claytoneffe5c92011-05-03 22:09:39 +00003859 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00003860 return result.Succeeded();
3861 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003862
Kate Stoneb9c1b512016-09-06 20:57:50 +00003863 CommandOptions m_options;
Greg Claytoneffe5c92011-05-03 22:09:39 +00003864};
3865
Jim Ingham9575d842011-03-11 03:53:59 +00003866#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003867
3868//-------------------------------------------------------------------------
3869// CommandObjectMultiwordImageSearchPaths
3870//-------------------------------------------------------------------------
3871
Kate Stoneb9c1b512016-09-06 20:57:50 +00003872class CommandObjectTargetModulesImageSearchPaths
3873 : public CommandObjectMultiword {
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003874public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003875 CommandObjectTargetModulesImageSearchPaths(CommandInterpreter &interpreter)
3876 : CommandObjectMultiword(
3877 interpreter, "target modules search-paths",
3878 "Commands for managing module search paths for a target.",
3879 "target modules search-paths <subcommand> [<subcommand-options>]") {
3880 LoadSubCommand(
3881 "add", CommandObjectSP(
3882 new CommandObjectTargetModulesSearchPathsAdd(interpreter)));
3883 LoadSubCommand(
3884 "clear", CommandObjectSP(new CommandObjectTargetModulesSearchPathsClear(
3885 interpreter)));
3886 LoadSubCommand(
3887 "insert",
3888 CommandObjectSP(
3889 new CommandObjectTargetModulesSearchPathsInsert(interpreter)));
3890 LoadSubCommand(
3891 "list", CommandObjectSP(new CommandObjectTargetModulesSearchPathsList(
3892 interpreter)));
3893 LoadSubCommand(
3894 "query", CommandObjectSP(new CommandObjectTargetModulesSearchPathsQuery(
3895 interpreter)));
3896 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003897
Kate Stoneb9c1b512016-09-06 20:57:50 +00003898 ~CommandObjectTargetModulesImageSearchPaths() override = default;
Chris Lattner30fdc8d2010-06-08 16:52:24 +00003899};
3900
Greg Claytoneffe5c92011-05-03 22:09:39 +00003901#pragma mark CommandObjectTargetModules
3902
3903//-------------------------------------------------------------------------
3904// CommandObjectTargetModules
3905//-------------------------------------------------------------------------
3906
Kate Stoneb9c1b512016-09-06 20:57:50 +00003907class CommandObjectTargetModules : public CommandObjectMultiword {
Greg Claytoneffe5c92011-05-03 22:09:39 +00003908public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003909 //------------------------------------------------------------------
3910 // Constructors and Destructors
3911 //------------------------------------------------------------------
3912 CommandObjectTargetModules(CommandInterpreter &interpreter)
3913 : CommandObjectMultiword(interpreter, "target modules",
3914 "Commands for accessing information for one or "
3915 "more target modules.",
3916 "target modules <sub-command> ...") {
3917 LoadSubCommand(
3918 "add", CommandObjectSP(new CommandObjectTargetModulesAdd(interpreter)));
3919 LoadSubCommand("load", CommandObjectSP(new CommandObjectTargetModulesLoad(
3920 interpreter)));
3921 LoadSubCommand("dump", CommandObjectSP(new CommandObjectTargetModulesDump(
3922 interpreter)));
3923 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetModulesList(
3924 interpreter)));
3925 LoadSubCommand(
3926 "lookup",
3927 CommandObjectSP(new CommandObjectTargetModulesLookup(interpreter)));
3928 LoadSubCommand(
3929 "search-paths",
3930 CommandObjectSP(
3931 new CommandObjectTargetModulesImageSearchPaths(interpreter)));
3932 LoadSubCommand(
3933 "show-unwind",
3934 CommandObjectSP(new CommandObjectTargetModulesShowUnwind(interpreter)));
3935 }
Greg Claytoneffe5c92011-05-03 22:09:39 +00003936
Kate Stoneb9c1b512016-09-06 20:57:50 +00003937 ~CommandObjectTargetModules() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003938
Greg Claytoneffe5c92011-05-03 22:09:39 +00003939private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003940 //------------------------------------------------------------------
3941 // For CommandObjectTargetModules only
3942 //------------------------------------------------------------------
3943 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetModules);
Greg Claytoneffe5c92011-05-03 22:09:39 +00003944};
3945
Kate Stoneb9c1b512016-09-06 20:57:50 +00003946class CommandObjectTargetSymbolsAdd : public CommandObjectParsed {
Greg Claytone72dfb32012-02-24 01:59:29 +00003947public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003948 CommandObjectTargetSymbolsAdd(CommandInterpreter &interpreter)
3949 : CommandObjectParsed(
3950 interpreter, "target symbols add",
3951 "Add a debug symbol file to one of the target's current modules by "
3952 "specifying a path to a debug symbols file, or using the options "
3953 "to specify a module to download symbols for.",
3954 "target symbols add [<symfile>]", eCommandRequiresTarget),
Todd Fialae1cfbc72016-08-11 23:51:28 +00003955 m_option_group(),
Kate Stoneb9c1b512016-09-06 20:57:50 +00003956 m_file_option(
3957 LLDB_OPT_SET_1, false, "shlib", 's',
3958 CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3959 "Fullpath or basename for module to find debug symbols for."),
3960 m_current_frame_option(
3961 LLDB_OPT_SET_2, false, "frame", 'F',
3962 "Locate the debug symbols the currently selected frame.", false,
3963 true)
Greg Claytonb5f0fea2012-09-27 22:26:11 +00003964
Kate Stoneb9c1b512016-09-06 20:57:50 +00003965 {
3966 m_option_group.Append(&m_uuid_option_group, LLDB_OPT_SET_ALL,
3967 LLDB_OPT_SET_1);
3968 m_option_group.Append(&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
3969 m_option_group.Append(&m_current_frame_option, LLDB_OPT_SET_2,
3970 LLDB_OPT_SET_2);
3971 m_option_group.Finalize();
3972 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003973
Kate Stoneb9c1b512016-09-06 20:57:50 +00003974 ~CommandObjectTargetSymbolsAdd() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003975
Kate Stoneb9c1b512016-09-06 20:57:50 +00003976 int HandleArgumentCompletion(Args &input, int &cursor_index,
3977 int &cursor_char_position,
3978 OptionElementVector &opt_element_vector,
3979 int match_start_point, int max_return_elements,
3980 bool &word_complete,
3981 StringList &matches) override {
3982 std::string completion_str(input.GetArgumentAtIndex(cursor_index));
3983 completion_str.erase(cursor_char_position);
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003984
Kate Stoneb9c1b512016-09-06 20:57:50 +00003985 CommandCompletions::InvokeCommonCompletionCallbacks(
3986 GetCommandInterpreter(), CommandCompletions::eDiskFileCompletion,
3987 completion_str.c_str(), match_start_point, max_return_elements, nullptr,
3988 word_complete, matches);
3989 return matches.GetSize();
3990 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00003991
Kate Stoneb9c1b512016-09-06 20:57:50 +00003992 Options *GetOptions() override { return &m_option_group; }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00003993
Jim Ingham5a988412012-06-08 21:56:10 +00003994protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00003995 bool AddModuleSymbols(Target *target, ModuleSpec &module_spec, bool &flush,
3996 CommandReturnObject &result) {
3997 const FileSpec &symbol_fspec = module_spec.GetSymbolFileSpec();
3998 if (symbol_fspec) {
3999 char symfile_path[PATH_MAX];
4000 symbol_fspec.GetPath(symfile_path, sizeof(symfile_path));
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004001
Kate Stoneb9c1b512016-09-06 20:57:50 +00004002 if (!module_spec.GetUUID().IsValid()) {
4003 if (!module_spec.GetFileSpec() && !module_spec.GetPlatformFileSpec())
4004 module_spec.GetFileSpec().GetFilename() = symbol_fspec.GetFilename();
4005 }
4006 // We now have a module that represents a symbol file
4007 // that can be used for a module that might exist in the
4008 // current target, so we need to find that module in the
4009 // target
4010 ModuleList matching_module_list;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004011
Kate Stoneb9c1b512016-09-06 20:57:50 +00004012 size_t num_matches = 0;
4013 // First extract all module specs from the symbol file
4014 lldb_private::ModuleSpecList symfile_module_specs;
4015 if (ObjectFile::GetModuleSpecifications(module_spec.GetSymbolFileSpec(),
4016 0, 0, symfile_module_specs)) {
4017 // Now extract the module spec that matches the target architecture
4018 ModuleSpec target_arch_module_spec;
4019 ModuleSpec symfile_module_spec;
4020 target_arch_module_spec.GetArchitecture() = target->GetArchitecture();
4021 if (symfile_module_specs.FindMatchingModuleSpec(target_arch_module_spec,
4022 symfile_module_spec)) {
4023 // See if it has a UUID?
4024 if (symfile_module_spec.GetUUID().IsValid()) {
4025 // It has a UUID, look for this UUID in the target modules
4026 ModuleSpec symfile_uuid_module_spec;
4027 symfile_uuid_module_spec.GetUUID() = symfile_module_spec.GetUUID();
4028 num_matches = target->GetImages().FindModules(
4029 symfile_uuid_module_spec, matching_module_list);
4030 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00004031 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004032
4033 if (num_matches == 0) {
4034 // No matches yet, iterate through the module specs to find a UUID
4035 // value that
4036 // we can match up to an image in our target
4037 const size_t num_symfile_module_specs =
4038 symfile_module_specs.GetSize();
4039 for (size_t i = 0; i < num_symfile_module_specs && num_matches == 0;
4040 ++i) {
4041 if (symfile_module_specs.GetModuleSpecAtIndex(
4042 i, symfile_module_spec)) {
4043 if (symfile_module_spec.GetUUID().IsValid()) {
4044 // It has a UUID, look for this UUID in the target modules
4045 ModuleSpec symfile_uuid_module_spec;
4046 symfile_uuid_module_spec.GetUUID() =
4047 symfile_module_spec.GetUUID();
4048 num_matches = target->GetImages().FindModules(
4049 symfile_uuid_module_spec, matching_module_list);
4050 }
4051 }
4052 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00004053 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004054 }
4055
4056 // Just try to match up the file by basename if we have no matches at this
4057 // point
4058 if (num_matches == 0)
4059 num_matches =
4060 target->GetImages().FindModules(module_spec, matching_module_list);
4061
4062 while (num_matches == 0) {
4063 ConstString filename_no_extension(
4064 module_spec.GetFileSpec().GetFileNameStrippingExtension());
4065 // Empty string returned, lets bail
4066 if (!filename_no_extension)
4067 break;
4068
4069 // Check if there was no extension to strip and the basename is the same
4070 if (filename_no_extension == module_spec.GetFileSpec().GetFilename())
4071 break;
4072
4073 // Replace basename with one less extension
4074 module_spec.GetFileSpec().GetFilename() = filename_no_extension;
4075
4076 num_matches =
4077 target->GetImages().FindModules(module_spec, matching_module_list);
4078 }
4079
4080 if (num_matches > 1) {
4081 result.AppendErrorWithFormat("multiple modules match symbol file '%s', "
4082 "use the --uuid option to resolve the "
4083 "ambiguity.\n",
4084 symfile_path);
4085 } else if (num_matches == 1) {
4086 ModuleSP module_sp(matching_module_list.GetModuleAtIndex(0));
4087
4088 // The module has not yet created its symbol vendor, we can just
4089 // give the existing target module the symfile path to use for
4090 // when it decides to create it!
4091 module_sp->SetSymbolFileFileSpec(symbol_fspec);
4092
4093 SymbolVendor *symbol_vendor =
4094 module_sp->GetSymbolVendor(true, &result.GetErrorStream());
4095 if (symbol_vendor) {
4096 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
4097
4098 if (symbol_file) {
4099 ObjectFile *object_file = symbol_file->GetObjectFile();
4100
4101 if (object_file && object_file->GetFileSpec() == symbol_fspec) {
4102 // Provide feedback that the symfile has been successfully added.
4103 const FileSpec &module_fs = module_sp->GetFileSpec();
4104 result.AppendMessageWithFormat(
4105 "symbol file '%s' has been added to '%s'\n", symfile_path,
4106 module_fs.GetPath().c_str());
4107
4108 // Let clients know something changed in the module
4109 // if it is currently loaded
4110 ModuleList module_list;
4111 module_list.Append(module_sp);
4112 target->SymbolsDidLoad(module_list);
4113
4114 // Make sure we load any scripting resources that may be embedded
4115 // in the debug info files in case the platform supports that.
4116 Error error;
4117 StreamString feedback_stream;
4118 module_sp->LoadScriptingResourceInTarget(target, error,
4119 &feedback_stream);
4120 if (error.Fail() && error.AsCString())
4121 result.AppendWarningWithFormat(
4122 "unable to load scripting data for module %s - error "
4123 "reported was %s",
4124 module_sp->GetFileSpec()
4125 .GetFileNameStrippingExtension()
4126 .GetCString(),
4127 error.AsCString());
4128 else if (feedback_stream.GetSize())
4129 result.AppendWarningWithFormat("%s", feedback_stream.GetData());
4130
4131 flush = true;
4132 result.SetStatus(eReturnStatusSuccessFinishResult);
4133 return true;
4134 }
4135 }
4136 }
4137 // Clear the symbol file spec if anything went wrong
4138 module_sp->SetSymbolFileFileSpec(FileSpec());
4139 }
4140
Zachary Turner7d86ee52017-03-08 17:56:08 +00004141 namespace fs = llvm::sys::fs;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004142 if (module_spec.GetUUID().IsValid()) {
4143 StreamString ss_symfile_uuid;
4144 module_spec.GetUUID().Dump(&ss_symfile_uuid);
4145 result.AppendErrorWithFormat(
4146 "symbol file '%s' (%s) does not match any existing module%s\n",
4147 symfile_path, ss_symfile_uuid.GetData(),
Zachary Turner7d86ee52017-03-08 17:56:08 +00004148 !fs::is_regular_file(symbol_fspec.GetPath())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004149 ? "\n please specify the full path to the symbol file"
4150 : "");
4151 } else {
4152 result.AppendErrorWithFormat(
4153 "symbol file '%s' does not match any existing module%s\n",
4154 symfile_path,
Zachary Turner7d86ee52017-03-08 17:56:08 +00004155 !fs::is_regular_file(symbol_fspec.GetPath())
Kate Stoneb9c1b512016-09-06 20:57:50 +00004156 ? "\n please specify the full path to the symbol file"
4157 : "");
4158 }
4159 } else {
4160 result.AppendError(
4161 "one or more executable image paths must be specified");
4162 }
4163 result.SetStatus(eReturnStatusFailed);
4164 return false;
4165 }
4166
4167 bool DoExecute(Args &args, CommandReturnObject &result) override {
4168 Target *target = m_exe_ctx.GetTargetPtr();
4169 result.SetStatus(eReturnStatusFailed);
4170 bool flush = false;
4171 ModuleSpec module_spec;
4172 const bool uuid_option_set =
4173 m_uuid_option_group.GetOptionValue().OptionWasSet();
4174 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4175 const bool frame_option_set =
4176 m_current_frame_option.GetOptionValue().OptionWasSet();
4177 const size_t argc = args.GetArgumentCount();
4178
4179 if (argc == 0) {
4180 if (uuid_option_set || file_option_set || frame_option_set) {
4181 bool success = false;
4182 bool error_set = false;
4183 if (frame_option_set) {
4184 Process *process = m_exe_ctx.GetProcessPtr();
4185 if (process) {
4186 const StateType process_state = process->GetState();
4187 if (StateIsStoppedState(process_state, true)) {
4188 StackFrame *frame = m_exe_ctx.GetFramePtr();
4189 if (frame) {
4190 ModuleSP frame_module_sp(
4191 frame->GetSymbolContext(eSymbolContextModule).module_sp);
4192 if (frame_module_sp) {
4193 if (frame_module_sp->GetPlatformFileSpec().Exists()) {
4194 module_spec.GetArchitecture() =
4195 frame_module_sp->GetArchitecture();
4196 module_spec.GetFileSpec() =
4197 frame_module_sp->GetPlatformFileSpec();
4198 }
4199 module_spec.GetUUID() = frame_module_sp->GetUUID();
4200 success = module_spec.GetUUID().IsValid() ||
4201 module_spec.GetFileSpec();
4202 } else {
4203 result.AppendError("frame has no module");
4204 error_set = true;
4205 }
4206 } else {
4207 result.AppendError("invalid current frame");
4208 error_set = true;
4209 }
4210 } else {
4211 result.AppendErrorWithFormat("process is not stopped: %s",
4212 StateAsCString(process_state));
4213 error_set = true;
4214 }
4215 } else {
4216 result.AppendError(
4217 "a process must exist in order to use the --frame option");
4218 error_set = true;
4219 }
4220 } else {
4221 if (uuid_option_set) {
4222 module_spec.GetUUID() =
4223 m_uuid_option_group.GetOptionValue().GetCurrentValue();
4224 success |= module_spec.GetUUID().IsValid();
4225 } else if (file_option_set) {
4226 module_spec.GetFileSpec() =
4227 m_file_option.GetOptionValue().GetCurrentValue();
4228 ModuleSP module_sp(
4229 target->GetImages().FindFirstModule(module_spec));
4230 if (module_sp) {
4231 module_spec.GetFileSpec() = module_sp->GetFileSpec();
4232 module_spec.GetPlatformFileSpec() =
4233 module_sp->GetPlatformFileSpec();
4234 module_spec.GetUUID() = module_sp->GetUUID();
4235 module_spec.GetArchitecture() = module_sp->GetArchitecture();
4236 } else {
4237 module_spec.GetArchitecture() = target->GetArchitecture();
4238 }
4239 success |= module_spec.GetUUID().IsValid() ||
4240 module_spec.GetFileSpec().Exists();
4241 }
4242 }
4243
4244 if (success) {
4245 if (Symbols::DownloadObjectAndSymbolFile(module_spec)) {
4246 if (module_spec.GetSymbolFileSpec())
4247 success = AddModuleSymbols(target, module_spec, flush, result);
4248 }
4249 }
4250
4251 if (!success && !error_set) {
4252 StreamString error_strm;
4253 if (uuid_option_set) {
4254 error_strm.PutCString("unable to find debug symbols for UUID ");
4255 module_spec.GetUUID().Dump(&error_strm);
4256 } else if (file_option_set) {
4257 error_strm.PutCString(
4258 "unable to find debug symbols for the executable file ");
4259 error_strm << module_spec.GetFileSpec();
4260 } else if (frame_option_set) {
4261 error_strm.PutCString(
4262 "unable to find debug symbols for the current frame");
4263 }
Zachary Turnerc1564272016-11-16 21:15:24 +00004264 result.AppendError(error_strm.GetString());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004265 }
4266 } else {
4267 result.AppendError("one or more symbol file paths must be specified, "
4268 "or options must be specified");
4269 }
4270 } else {
4271 if (uuid_option_set) {
4272 result.AppendError("specify either one or more paths to symbol files "
4273 "or use the --uuid option without arguments");
4274 } else if (file_option_set) {
4275 result.AppendError("specify either one or more paths to symbol files "
4276 "or use the --file option without arguments");
4277 } else if (frame_option_set) {
4278 result.AppendError("specify either one or more paths to symbol files "
4279 "or use the --frame option without arguments");
4280 } else {
4281 PlatformSP platform_sp(target->GetPlatform());
4282
Zachary Turner97d2c402016-10-05 23:40:23 +00004283 for (auto &entry : args.entries()) {
4284 if (!entry.ref.empty()) {
4285 module_spec.GetSymbolFileSpec().SetFile(entry.ref, true);
Kate Stoneb9c1b512016-09-06 20:57:50 +00004286 if (platform_sp) {
4287 FileSpec symfile_spec;
4288 if (platform_sp
4289 ->ResolveSymbolFile(*target, module_spec, symfile_spec)
4290 .Success())
4291 module_spec.GetSymbolFileSpec() = symfile_spec;
4292 }
4293
4294 ArchSpec arch;
4295 bool symfile_exists = module_spec.GetSymbolFileSpec().Exists();
4296
4297 if (symfile_exists) {
4298 if (!AddModuleSymbols(target, module_spec, flush, result))
4299 break;
4300 } else {
Zachary Turner97d2c402016-10-05 23:40:23 +00004301 std::string resolved_symfile_path =
4302 module_spec.GetSymbolFileSpec().GetPath();
4303 if (resolved_symfile_path != entry.ref) {
4304 result.AppendErrorWithFormat(
4305 "invalid module path '%s' with resolved path '%s'\n",
4306 entry.c_str(), resolved_symfile_path.c_str());
4307 break;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004308 }
4309 result.AppendErrorWithFormat("invalid module path '%s'\n",
Zachary Turner97d2c402016-10-05 23:40:23 +00004310 entry.c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004311 break;
4312 }
4313 }
4314 }
4315 }
Greg Claytonb5f0fea2012-09-27 22:26:11 +00004316 }
4317
Kate Stoneb9c1b512016-09-06 20:57:50 +00004318 if (flush) {
4319 Process *process = m_exe_ctx.GetProcessPtr();
4320 if (process)
4321 process->Flush();
Greg Claytone72dfb32012-02-24 01:59:29 +00004322 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004323 return result.Succeeded();
4324 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004325
Kate Stoneb9c1b512016-09-06 20:57:50 +00004326 OptionGroupOptions m_option_group;
4327 OptionGroupUUID m_uuid_option_group;
4328 OptionGroupFile m_file_option;
4329 OptionGroupBoolean m_current_frame_option;
Greg Claytone72dfb32012-02-24 01:59:29 +00004330};
4331
Greg Claytone72dfb32012-02-24 01:59:29 +00004332#pragma mark CommandObjectTargetSymbols
4333
4334//-------------------------------------------------------------------------
4335// CommandObjectTargetSymbols
4336//-------------------------------------------------------------------------
4337
Kate Stoneb9c1b512016-09-06 20:57:50 +00004338class CommandObjectTargetSymbols : public CommandObjectMultiword {
Greg Claytone72dfb32012-02-24 01:59:29 +00004339public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004340 //------------------------------------------------------------------
4341 // Constructors and Destructors
4342 //------------------------------------------------------------------
4343 CommandObjectTargetSymbols(CommandInterpreter &interpreter)
4344 : CommandObjectMultiword(
4345 interpreter, "target symbols",
4346 "Commands for adding and managing debug symbol files.",
4347 "target symbols <sub-command> ...") {
4348 LoadSubCommand(
4349 "add", CommandObjectSP(new CommandObjectTargetSymbolsAdd(interpreter)));
4350 }
Bruce Mitchener13d21e92015-10-07 16:56:17 +00004351
Kate Stoneb9c1b512016-09-06 20:57:50 +00004352 ~CommandObjectTargetSymbols() override = default;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004353
Greg Claytone72dfb32012-02-24 01:59:29 +00004354private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004355 //------------------------------------------------------------------
4356 // For CommandObjectTargetModules only
4357 //------------------------------------------------------------------
4358 DISALLOW_COPY_AND_ASSIGN(CommandObjectTargetSymbols);
Greg Claytone72dfb32012-02-24 01:59:29 +00004359};
4360
Jim Ingham9575d842011-03-11 03:53:59 +00004361#pragma mark CommandObjectTargetStopHookAdd
4362
4363//-------------------------------------------------------------------------
4364// CommandObjectTargetStopHookAdd
4365//-------------------------------------------------------------------------
4366
Zachary Turner1f0f5b52016-09-22 20:22:55 +00004367static OptionDefinition g_target_stop_hook_add_options[] = {
4368 // clang-format off
4369 { 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." },
4370 { 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." },
4371 { 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." },
4372 { 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." },
4373 { 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." },
4374 { 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." },
4375 { 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." },
4376 { 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." },
4377 { 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." },
4378 { 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." },
4379 { 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." },
4380 // clang-format on
4381};
4382
Kate Stoneb9c1b512016-09-06 20:57:50 +00004383class CommandObjectTargetStopHookAdd : public CommandObjectParsed,
4384 public IOHandlerDelegateMultiline {
Jim Ingham9575d842011-03-11 03:53:59 +00004385public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004386 class CommandOptions : public Options {
4387 public:
4388 CommandOptions()
4389 : Options(), m_line_start(0), m_line_end(UINT_MAX),
4390 m_func_name_type_mask(eFunctionNameTypeAuto),
4391 m_sym_ctx_specified(false), m_thread_specified(false),
4392 m_use_one_liner(false), m_one_liner() {}
4393
4394 ~CommandOptions() override = default;
4395
Zachary Turner1f0f5b52016-09-22 20:22:55 +00004396 llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
Zachary Turner70602432016-09-22 21:06:13 +00004397 return llvm::makeArrayRef(g_target_stop_hook_add_options);
Zachary Turner1f0f5b52016-09-22 20:22:55 +00004398 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004399
Zachary Turnerfe114832016-11-12 16:56:47 +00004400 Error SetOptionValue(uint32_t option_idx, llvm::StringRef option_arg,
Kate Stoneb9c1b512016-09-06 20:57:50 +00004401 ExecutionContext *execution_context) override {
4402 Error error;
4403 const int short_option = m_getopt_table[option_idx].val;
Kate Stoneb9c1b512016-09-06 20:57:50 +00004404
4405 switch (short_option) {
4406 case 'c':
4407 m_class_name = option_arg;
4408 m_sym_ctx_specified = true;
4409 break;
4410
4411 case 'e':
Zachary Turnerfe114832016-11-12 16:56:47 +00004412 if (option_arg.getAsInteger(0, m_line_end)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00004413 error.SetErrorStringWithFormat("invalid end line number: \"%s\"",
Zachary Turnerfe114832016-11-12 16:56:47 +00004414 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004415 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004416 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004417 m_sym_ctx_specified = true;
4418 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004419
Kate Stoneb9c1b512016-09-06 20:57:50 +00004420 case 'l':
Zachary Turnerfe114832016-11-12 16:56:47 +00004421 if (option_arg.getAsInteger(0, m_line_start)) {
Kate Stoneb9c1b512016-09-06 20:57:50 +00004422 error.SetErrorStringWithFormat("invalid start line number: \"%s\"",
Zachary Turnerfe114832016-11-12 16:56:47 +00004423 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004424 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004425 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004426 m_sym_ctx_specified = true;
4427 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004428
Kate Stoneb9c1b512016-09-06 20:57:50 +00004429 case 'i':
4430 m_no_inlines = true;
4431 break;
Jim Ingham9575d842011-03-11 03:53:59 +00004432
Kate Stoneb9c1b512016-09-06 20:57:50 +00004433 case 'n':
4434 m_function_name = option_arg;
4435 m_func_name_type_mask |= eFunctionNameTypeAuto;
4436 m_sym_ctx_specified = true;
4437 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004438
Kate Stoneb9c1b512016-09-06 20:57:50 +00004439 case 'f':
4440 m_file_name = option_arg;
4441 m_sym_ctx_specified = true;
4442 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004443
Kate Stoneb9c1b512016-09-06 20:57:50 +00004444 case 's':
4445 m_module_name = option_arg;
4446 m_sym_ctx_specified = true;
4447 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004448
Kate Stoneb9c1b512016-09-06 20:57:50 +00004449 case 't':
Zachary Turnerfe114832016-11-12 16:56:47 +00004450 if (option_arg.getAsInteger(0, m_thread_id))
Kate Stoneb9c1b512016-09-06 20:57:50 +00004451 error.SetErrorStringWithFormat("invalid thread id string '%s'",
Zachary Turnerfe114832016-11-12 16:56:47 +00004452 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004453 m_thread_specified = true;
4454 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004455
Kate Stoneb9c1b512016-09-06 20:57:50 +00004456 case 'T':
4457 m_thread_name = option_arg;
4458 m_thread_specified = true;
4459 break;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004460
Kate Stoneb9c1b512016-09-06 20:57:50 +00004461 case 'q':
4462 m_queue_name = option_arg;
4463 m_thread_specified = true;
4464 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004465
Kate Stoneb9c1b512016-09-06 20:57:50 +00004466 case 'x':
Zachary Turnerfe114832016-11-12 16:56:47 +00004467 if (option_arg.getAsInteger(0, m_thread_index))
Kate Stoneb9c1b512016-09-06 20:57:50 +00004468 error.SetErrorStringWithFormat("invalid thread index string '%s'",
Zachary Turnerfe114832016-11-12 16:56:47 +00004469 option_arg.str().c_str());
Kate Stoneb9c1b512016-09-06 20:57:50 +00004470 m_thread_specified = true;
4471 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004472
Kate Stoneb9c1b512016-09-06 20:57:50 +00004473 case 'o':
4474 m_use_one_liner = true;
4475 m_one_liner = option_arg;
4476 break;
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004477
Kate Stoneb9c1b512016-09-06 20:57:50 +00004478 default:
4479 error.SetErrorStringWithFormat("unrecognized option %c.", short_option);
4480 break;
4481 }
4482 return error;
Jim Ingham9575d842011-03-11 03:53:59 +00004483 }
4484
Kate Stoneb9c1b512016-09-06 20:57:50 +00004485 void OptionParsingStarting(ExecutionContext *execution_context) override {
4486 m_class_name.clear();
4487 m_function_name.clear();
4488 m_line_start = 0;
4489 m_line_end = UINT_MAX;
4490 m_file_name.clear();
4491 m_module_name.clear();
4492 m_func_name_type_mask = eFunctionNameTypeAuto;
4493 m_thread_id = LLDB_INVALID_THREAD_ID;
4494 m_thread_index = UINT32_MAX;
4495 m_thread_name.clear();
4496 m_queue_name.clear();
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004497
Kate Stoneb9c1b512016-09-06 20:57:50 +00004498 m_no_inlines = false;
4499 m_sym_ctx_specified = false;
4500 m_thread_specified = false;
4501
4502 m_use_one_liner = false;
4503 m_one_liner.clear();
Jim Ingham9575d842011-03-11 03:53:59 +00004504 }
4505
Kate Stoneb9c1b512016-09-06 20:57:50 +00004506 std::string m_class_name;
4507 std::string m_function_name;
4508 uint32_t m_line_start;
4509 uint32_t m_line_end;
4510 std::string m_file_name;
4511 std::string m_module_name;
4512 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
4513 lldb::tid_t m_thread_id;
4514 uint32_t m_thread_index;
4515 std::string m_thread_name;
4516 std::string m_queue_name;
4517 bool m_sym_ctx_specified;
4518 bool m_no_inlines;
4519 bool m_thread_specified;
4520 // Instance variables to hold the values for one_liner options.
4521 bool m_use_one_liner;
4522 std::string m_one_liner;
4523 };
4524
4525 CommandObjectTargetStopHookAdd(CommandInterpreter &interpreter)
4526 : CommandObjectParsed(interpreter, "target stop-hook add",
4527 "Add a hook to be executed when the target stops.",
4528 "target stop-hook add"),
4529 IOHandlerDelegateMultiline("DONE",
4530 IOHandlerDelegate::Completion::LLDBCommand),
4531 m_options() {}
4532
4533 ~CommandObjectTargetStopHookAdd() override = default;
4534
4535 Options *GetOptions() override { return &m_options; }
4536
Jim Ingham5a988412012-06-08 21:56:10 +00004537protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004538 void IOHandlerActivated(IOHandler &io_handler) override {
4539 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4540 if (output_sp) {
4541 output_sp->PutCString(
4542 "Enter your stop hook command(s). Type 'DONE' to end.\n");
4543 output_sp->Flush();
Greg Clayton44d93782014-01-27 23:43:24 +00004544 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004545 }
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004546
Kate Stoneb9c1b512016-09-06 20:57:50 +00004547 void IOHandlerInputComplete(IOHandler &io_handler,
4548 std::string &line) override {
4549 if (m_stop_hook_sp) {
4550 if (line.empty()) {
4551 StreamFileSP error_sp(io_handler.GetErrorStreamFile());
4552 if (error_sp) {
4553 error_sp->Printf("error: stop hook #%" PRIu64
4554 " aborted, no commands.\n",
4555 m_stop_hook_sp->GetID());
4556 error_sp->Flush();
Greg Clayton44d93782014-01-27 23:43:24 +00004557 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004558 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Jim Ingham9575d842011-03-11 03:53:59 +00004559 if (target)
Kate Stoneb9c1b512016-09-06 20:57:50 +00004560 target->RemoveStopHookByID(m_stop_hook_sp->GetID());
4561 } else {
4562 m_stop_hook_sp->GetCommandPointer()->SplitIntoLines(line);
4563 StreamFileSP output_sp(io_handler.GetOutputStreamFile());
4564 if (output_sp) {
4565 output_sp->Printf("Stop hook #%" PRIu64 " added.\n",
4566 m_stop_hook_sp->GetID());
4567 output_sp->Flush();
Jim Ingham9575d842011-03-11 03:53:59 +00004568 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004569 }
4570 m_stop_hook_sp.reset();
Jim Ingham9575d842011-03-11 03:53:59 +00004571 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004572 io_handler.SetIsDone(true);
4573 }
4574
4575 bool DoExecute(Args &command, CommandReturnObject &result) override {
4576 m_stop_hook_sp.reset();
4577
4578 Target *target = GetSelectedOrDummyTarget();
4579 if (target) {
4580 Target::StopHookSP new_hook_sp = target->CreateStopHook();
4581
4582 // First step, make the specifier.
4583 std::unique_ptr<SymbolContextSpecifier> specifier_ap;
4584 if (m_options.m_sym_ctx_specified) {
4585 specifier_ap.reset(new SymbolContextSpecifier(
4586 m_interpreter.GetDebugger().GetSelectedTarget()));
4587
4588 if (!m_options.m_module_name.empty()) {
4589 specifier_ap->AddSpecification(
4590 m_options.m_module_name.c_str(),
4591 SymbolContextSpecifier::eModuleSpecified);
4592 }
4593
4594 if (!m_options.m_class_name.empty()) {
4595 specifier_ap->AddSpecification(
4596 m_options.m_class_name.c_str(),
4597 SymbolContextSpecifier::eClassOrNamespaceSpecified);
4598 }
4599
4600 if (!m_options.m_file_name.empty()) {
4601 specifier_ap->AddSpecification(
4602 m_options.m_file_name.c_str(),
4603 SymbolContextSpecifier::eFileSpecified);
4604 }
4605
4606 if (m_options.m_line_start != 0) {
4607 specifier_ap->AddLineSpecification(
4608 m_options.m_line_start,
4609 SymbolContextSpecifier::eLineStartSpecified);
4610 }
4611
4612 if (m_options.m_line_end != UINT_MAX) {
4613 specifier_ap->AddLineSpecification(
4614 m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4615 }
4616
4617 if (!m_options.m_function_name.empty()) {
4618 specifier_ap->AddSpecification(
4619 m_options.m_function_name.c_str(),
4620 SymbolContextSpecifier::eFunctionSpecified);
4621 }
4622 }
4623
4624 if (specifier_ap)
4625 new_hook_sp->SetSpecifier(specifier_ap.release());
4626
4627 // Next see if any of the thread options have been entered:
4628
4629 if (m_options.m_thread_specified) {
4630 ThreadSpec *thread_spec = new ThreadSpec();
4631
4632 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID) {
4633 thread_spec->SetTID(m_options.m_thread_id);
4634 }
4635
4636 if (m_options.m_thread_index != UINT32_MAX)
4637 thread_spec->SetIndex(m_options.m_thread_index);
4638
4639 if (!m_options.m_thread_name.empty())
4640 thread_spec->SetName(m_options.m_thread_name.c_str());
4641
4642 if (!m_options.m_queue_name.empty())
4643 thread_spec->SetQueueName(m_options.m_queue_name.c_str());
4644
4645 new_hook_sp->SetThreadSpecifier(thread_spec);
4646 }
4647 if (m_options.m_use_one_liner) {
4648 // Use one-liner.
4649 new_hook_sp->GetCommandPointer()->AppendString(
4650 m_options.m_one_liner.c_str());
4651 result.AppendMessageWithFormat("Stop hook #%" PRIu64 " added.\n",
4652 new_hook_sp->GetID());
4653 } else {
4654 m_stop_hook_sp = new_hook_sp;
4655 m_interpreter.GetLLDBCommandsFromIOHandler(
4656 "> ", // Prompt
4657 *this, // IOHandlerDelegate
4658 true, // Run IOHandler in async mode
4659 nullptr); // Baton for the "io_handler" that will be passed back
4660 // into our IOHandlerDelegate functions
4661 }
4662 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4663 } else {
4664 result.AppendError("invalid target\n");
4665 result.SetStatus(eReturnStatusFailed);
4666 }
4667
4668 return result.Succeeded();
4669 }
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004670
Jim Ingham9575d842011-03-11 03:53:59 +00004671private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004672 CommandOptions m_options;
4673 Target::StopHookSP m_stop_hook_sp;
Jim Ingham9575d842011-03-11 03:53:59 +00004674};
4675
Jim Ingham9575d842011-03-11 03:53:59 +00004676#pragma mark CommandObjectTargetStopHookDelete
4677
4678//-------------------------------------------------------------------------
4679// CommandObjectTargetStopHookDelete
4680//-------------------------------------------------------------------------
4681
Kate Stoneb9c1b512016-09-06 20:57:50 +00004682class CommandObjectTargetStopHookDelete : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004683public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004684 CommandObjectTargetStopHookDelete(CommandInterpreter &interpreter)
4685 : CommandObjectParsed(interpreter, "target stop-hook delete",
4686 "Delete a stop-hook.",
4687 "target stop-hook delete [<idx>]") {}
Jim Ingham9575d842011-03-11 03:53:59 +00004688
Kate Stoneb9c1b512016-09-06 20:57:50 +00004689 ~CommandObjectTargetStopHookDelete() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004690
Jim Ingham5a988412012-06-08 21:56:10 +00004691protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004692 bool DoExecute(Args &command, CommandReturnObject &result) override {
4693 Target *target = GetSelectedOrDummyTarget();
4694 if (target) {
4695 // FIXME: see if we can use the breakpoint id style parser?
4696 size_t num_args = command.GetArgumentCount();
4697 if (num_args == 0) {
4698 if (!m_interpreter.Confirm("Delete all stop hooks?", true)) {
4699 result.SetStatus(eReturnStatusFailed);
4700 return false;
4701 } else {
4702 target->RemoveAllStopHooks();
Jim Ingham9575d842011-03-11 03:53:59 +00004703 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004704 } else {
4705 bool success;
4706 for (size_t i = 0; i < num_args; i++) {
4707 lldb::user_id_t user_id = StringConvert::ToUInt32(
4708 command.GetArgumentAtIndex(i), 0, 0, &success);
4709 if (!success) {
4710 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4711 command.GetArgumentAtIndex(i));
4712 result.SetStatus(eReturnStatusFailed);
4713 return false;
4714 }
4715 success = target->RemoveStopHookByID(user_id);
4716 if (!success) {
4717 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4718 command.GetArgumentAtIndex(i));
4719 result.SetStatus(eReturnStatusFailed);
4720 return false;
4721 }
Jim Ingham9575d842011-03-11 03:53:59 +00004722 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004723 }
4724 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4725 } else {
4726 result.AppendError("invalid target\n");
4727 result.SetStatus(eReturnStatusFailed);
Jim Ingham9575d842011-03-11 03:53:59 +00004728 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004729
4730 return result.Succeeded();
4731 }
Jim Ingham9575d842011-03-11 03:53:59 +00004732};
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004733
Jim Ingham9575d842011-03-11 03:53:59 +00004734#pragma mark CommandObjectTargetStopHookEnableDisable
4735
4736//-------------------------------------------------------------------------
4737// CommandObjectTargetStopHookEnableDisable
4738//-------------------------------------------------------------------------
4739
Kate Stoneb9c1b512016-09-06 20:57:50 +00004740class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004741public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004742 CommandObjectTargetStopHookEnableDisable(CommandInterpreter &interpreter,
4743 bool enable, const char *name,
4744 const char *help, const char *syntax)
4745 : CommandObjectParsed(interpreter, name, help, syntax), m_enable(enable) {
4746 }
Jim Ingham9575d842011-03-11 03:53:59 +00004747
Kate Stoneb9c1b512016-09-06 20:57:50 +00004748 ~CommandObjectTargetStopHookEnableDisable() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004749
Jim Ingham5a988412012-06-08 21:56:10 +00004750protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004751 bool DoExecute(Args &command, CommandReturnObject &result) override {
4752 Target *target = GetSelectedOrDummyTarget();
4753 if (target) {
4754 // FIXME: see if we can use the breakpoint id style parser?
4755 size_t num_args = command.GetArgumentCount();
4756 bool success;
Saleem Abdulrasool324a1032014-04-04 04:06:10 +00004757
Kate Stoneb9c1b512016-09-06 20:57:50 +00004758 if (num_args == 0) {
4759 target->SetAllStopHooksActiveState(m_enable);
4760 } else {
4761 for (size_t i = 0; i < num_args; i++) {
4762 lldb::user_id_t user_id = StringConvert::ToUInt32(
4763 command.GetArgumentAtIndex(i), 0, 0, &success);
4764 if (!success) {
4765 result.AppendErrorWithFormat("invalid stop hook id: \"%s\".\n",
4766 command.GetArgumentAtIndex(i));
4767 result.SetStatus(eReturnStatusFailed);
4768 return false;
4769 }
4770 success = target->SetStopHookActiveStateByID(user_id, m_enable);
4771 if (!success) {
4772 result.AppendErrorWithFormat("unknown stop hook id: \"%s\".\n",
4773 command.GetArgumentAtIndex(i));
4774 result.SetStatus(eReturnStatusFailed);
4775 return false;
4776 }
Jim Ingham9575d842011-03-11 03:53:59 +00004777 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004778 }
4779 result.SetStatus(eReturnStatusSuccessFinishNoResult);
4780 } else {
4781 result.AppendError("invalid target\n");
4782 result.SetStatus(eReturnStatusFailed);
Jim Ingham9575d842011-03-11 03:53:59 +00004783 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004784 return result.Succeeded();
4785 }
4786
Jim Ingham9575d842011-03-11 03:53:59 +00004787private:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004788 bool m_enable;
Jim Ingham9575d842011-03-11 03:53:59 +00004789};
4790
4791#pragma mark CommandObjectTargetStopHookList
4792
4793//-------------------------------------------------------------------------
4794// CommandObjectTargetStopHookList
4795//-------------------------------------------------------------------------
4796
Kate Stoneb9c1b512016-09-06 20:57:50 +00004797class CommandObjectTargetStopHookList : public CommandObjectParsed {
Jim Ingham9575d842011-03-11 03:53:59 +00004798public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004799 CommandObjectTargetStopHookList(CommandInterpreter &interpreter)
4800 : CommandObjectParsed(interpreter, "target stop-hook list",
4801 "List all stop-hooks.",
4802 "target stop-hook list [<type>]") {}
Jim Ingham9575d842011-03-11 03:53:59 +00004803
Kate Stoneb9c1b512016-09-06 20:57:50 +00004804 ~CommandObjectTargetStopHookList() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004805
Jim Ingham5a988412012-06-08 21:56:10 +00004806protected:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004807 bool DoExecute(Args &command, CommandReturnObject &result) override {
4808 Target *target = GetSelectedOrDummyTarget();
4809 if (!target) {
4810 result.AppendError("invalid target\n");
4811 result.SetStatus(eReturnStatusFailed);
4812 return result.Succeeded();
Jim Ingham9575d842011-03-11 03:53:59 +00004813 }
Kate Stoneb9c1b512016-09-06 20:57:50 +00004814
4815 size_t num_hooks = target->GetNumStopHooks();
4816 if (num_hooks == 0) {
4817 result.GetOutputStream().PutCString("No stop hooks.\n");
4818 } else {
4819 for (size_t i = 0; i < num_hooks; i++) {
4820 Target::StopHookSP this_hook = target->GetStopHookAtIndex(i);
4821 if (i > 0)
4822 result.GetOutputStream().PutCString("\n");
4823 this_hook->GetDescription(&(result.GetOutputStream()),
4824 eDescriptionLevelFull);
4825 }
4826 }
4827 result.SetStatus(eReturnStatusSuccessFinishResult);
4828 return result.Succeeded();
4829 }
Jim Ingham9575d842011-03-11 03:53:59 +00004830};
4831
4832#pragma mark CommandObjectMultiwordTargetStopHooks
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004833
Jim Ingham9575d842011-03-11 03:53:59 +00004834//-------------------------------------------------------------------------
4835// CommandObjectMultiwordTargetStopHooks
4836//-------------------------------------------------------------------------
4837
Kate Stoneb9c1b512016-09-06 20:57:50 +00004838class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword {
Jim Ingham9575d842011-03-11 03:53:59 +00004839public:
Kate Stoneb9c1b512016-09-06 20:57:50 +00004840 CommandObjectMultiwordTargetStopHooks(CommandInterpreter &interpreter)
4841 : CommandObjectMultiword(
4842 interpreter, "target stop-hook",
4843 "Commands for operating on debugger target stop-hooks.",
4844 "target stop-hook <subcommand> [<subcommand-options>]") {
4845 LoadSubCommand("add", CommandObjectSP(
4846 new CommandObjectTargetStopHookAdd(interpreter)));
4847 LoadSubCommand(
4848 "delete",
4849 CommandObjectSP(new CommandObjectTargetStopHookDelete(interpreter)));
4850 LoadSubCommand("disable",
4851 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4852 interpreter, false, "target stop-hook disable [<id>]",
4853 "Disable a stop-hook.", "target stop-hook disable")));
4854 LoadSubCommand("enable",
4855 CommandObjectSP(new CommandObjectTargetStopHookEnableDisable(
4856 interpreter, true, "target stop-hook enable [<id>]",
4857 "Enable a stop-hook.", "target stop-hook enable")));
4858 LoadSubCommand("list", CommandObjectSP(new CommandObjectTargetStopHookList(
4859 interpreter)));
4860 }
Jim Ingham9575d842011-03-11 03:53:59 +00004861
Kate Stoneb9c1b512016-09-06 20:57:50 +00004862 ~CommandObjectMultiwordTargetStopHooks() override = default;
Jim Ingham9575d842011-03-11 03:53:59 +00004863};
4864
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004865#pragma mark CommandObjectMultiwordTarget
4866
4867//-------------------------------------------------------------------------
4868// CommandObjectMultiwordTarget
4869//-------------------------------------------------------------------------
4870
Kate Stoneb9c1b512016-09-06 20:57:50 +00004871CommandObjectMultiwordTarget::CommandObjectMultiwordTarget(
4872 CommandInterpreter &interpreter)
4873 : CommandObjectMultiword(interpreter, "target",
4874 "Commands for operating on debugger targets.",
4875 "target <subcommand> [<subcommand-options>]") {
4876 LoadSubCommand("create",
4877 CommandObjectSP(new CommandObjectTargetCreate(interpreter)));
4878 LoadSubCommand("delete",
4879 CommandObjectSP(new CommandObjectTargetDelete(interpreter)));
4880 LoadSubCommand("list",
4881 CommandObjectSP(new CommandObjectTargetList(interpreter)));
4882 LoadSubCommand("select",
4883 CommandObjectSP(new CommandObjectTargetSelect(interpreter)));
4884 LoadSubCommand(
4885 "stop-hook",
4886 CommandObjectSP(new CommandObjectMultiwordTargetStopHooks(interpreter)));
4887 LoadSubCommand("modules",
4888 CommandObjectSP(new CommandObjectTargetModules(interpreter)));
4889 LoadSubCommand("symbols",
4890 CommandObjectSP(new CommandObjectTargetSymbols(interpreter)));
4891 LoadSubCommand("variable",
4892 CommandObjectSP(new CommandObjectTargetVariable(interpreter)));
Chris Lattner30fdc8d2010-06-08 16:52:24 +00004893}
4894
Eugene Zelenkof13e6522016-02-25 19:02:39 +00004895CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget() = default;