blob: 6f77106a6f786a73dcd08bfc69a256bfabfd29bf [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectTarget.h"
11
12// C Includes
13#include <errno.h>
Greg Clayton81040f42011-02-01 01:13:32 +000014
Chris Lattner24943d22010-06-08 16:52:24 +000015// C++ Includes
16// Other libraries and framework includes
17// Project includes
Jim Ingham84cdc152010-06-15 19:49:27 +000018#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Core/Debugger.h"
Jim Inghamd60d94a2011-03-11 03:53:59 +000020#include "lldb/Core/InputReader.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000021#include "lldb/Core/Module.h"
22#include "lldb/Core/ModuleSpec.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000023#include "lldb/Core/Section.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000024#include "lldb/Core/State.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Core/Timer.h"
Greg Clayton801417e2011-07-07 01:59:51 +000026#include "lldb/Core/ValueObjectVariable.h"
Greg Claytonb924eb62012-09-27 03:13:55 +000027#include "lldb/Host/Symbols.h"
Chris Lattner24943d22010-06-08 16:52:24 +000028#include "lldb/Interpreter/CommandInterpreter.h"
29#include "lldb/Interpreter/CommandReturnObject.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000030#include "lldb/Interpreter/Options.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000031#include "lldb/Interpreter/OptionGroupArchitecture.h"
Greg Clayton5beb99d2011-08-11 02:48:45 +000032#include "lldb/Interpreter/OptionGroupBoolean.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000033#include "lldb/Interpreter/OptionGroupFile.h"
Greg Claytona42880a2011-10-25 06:44:01 +000034#include "lldb/Interpreter/OptionGroupFormat.h"
Greg Clayton368f8222011-07-07 04:38:25 +000035#include "lldb/Interpreter/OptionGroupVariable.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000036#include "lldb/Interpreter/OptionGroupPlatform.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000037#include "lldb/Interpreter/OptionGroupUInt64.h"
38#include "lldb/Interpreter/OptionGroupUUID.h"
Greg Clayton801417e2011-07-07 01:59:51 +000039#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
Greg Clayton49ce8962012-08-29 21:13:06 +000040#include "lldb/Symbol/CompileUnit.h"
Jason Molenda5b0afcc2012-07-12 00:20:07 +000041#include "lldb/Symbol/FuncUnwinders.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000042#include "lldb/Symbol/LineTable.h"
43#include "lldb/Symbol/ObjectFile.h"
44#include "lldb/Symbol/SymbolFile.h"
45#include "lldb/Symbol/SymbolVendor.h"
Jason Molenda5b0afcc2012-07-12 00:20:07 +000046#include "lldb/Symbol/UnwindPlan.h"
Greg Clayton801417e2011-07-07 01:59:51 +000047#include "lldb/Symbol/VariableList.h"
Chris Lattner24943d22010-06-08 16:52:24 +000048#include "lldb/Target/Process.h"
49#include "lldb/Target/StackFrame.h"
50#include "lldb/Target/Thread.h"
Jim Inghamd60d94a2011-03-11 03:53:59 +000051#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000052
53using namespace lldb;
54using namespace lldb_private;
55
Greg Claytonabe0fed2011-04-18 08:33:37 +000056
57
58static void
59DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
60{
Greg Clayton52c8b6e2011-04-19 04:19:37 +000061 const ArchSpec &target_arch = target->GetArchitecture();
Greg Claytonabe0fed2011-04-18 08:33:37 +000062
Greg Clayton5beb99d2011-08-11 02:48:45 +000063 Module *exe_module = target->GetExecutableModulePointer();
Greg Claytonabe0fed2011-04-18 08:33:37 +000064 char exe_path[PATH_MAX];
65 bool exe_valid = false;
Greg Clayton5beb99d2011-08-11 02:48:45 +000066 if (exe_module)
67 exe_valid = exe_module->GetFileSpec().GetPath (exe_path, sizeof(exe_path));
Greg Claytonabe0fed2011-04-18 08:33:37 +000068
69 if (!exe_valid)
70 ::strcpy (exe_path, "<none>");
71
72 strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path);
73
74 uint32_t properties = 0;
75 if (target_arch.IsValid())
76 {
77 strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str());
78 properties++;
79 }
80 PlatformSP platform_sp (target->GetPlatform());
81 if (platform_sp)
82 strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName());
83
84 ProcessSP process_sp (target->GetProcessSP());
85 bool show_process_status = false;
86 if (process_sp)
87 {
88 lldb::pid_t pid = process_sp->GetID();
89 StateType state = process_sp->GetState();
90 if (show_stopped_process_status)
Greg Clayton20206082011-11-17 01:23:07 +000091 show_process_status = StateIsStoppedState(state, true);
Greg Claytonabe0fed2011-04-18 08:33:37 +000092 const char *state_cstr = StateAsCString (state);
93 if (pid != LLDB_INVALID_PROCESS_ID)
Greg Claytond9919d32011-12-01 23:28:38 +000094 strm.Printf ("%spid=%llu", properties++ > 0 ? ", " : " ( ", pid);
Greg Claytonabe0fed2011-04-18 08:33:37 +000095 strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
96 }
97 if (properties > 0)
98 strm.PutCString (" )\n");
99 else
100 strm.EOL();
101 if (show_process_status)
102 {
103 const bool only_threads_with_stop_reason = true;
104 const uint32_t start_frame = 0;
105 const uint32_t num_frames = 1;
106 const uint32_t num_frames_with_source = 1;
107 process_sp->GetStatus (strm);
108 process_sp->GetThreadStatus (strm,
109 only_threads_with_stop_reason,
110 start_frame,
111 num_frames,
112 num_frames_with_source);
113
114 }
115}
116
117static uint32_t
118DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm)
119{
120 const uint32_t num_targets = target_list.GetNumTargets();
121 if (num_targets)
122 {
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 {
127 TargetSP target_sp (target_list.GetTargetAtIndex (i));
128 if (target_sp)
129 {
130 bool is_selected = target_sp.get() == selected_target_sp.get();
131 DumpTargetInfo (i,
132 target_sp.get(),
133 is_selected ? "* " : " ",
134 show_stopped_process_status,
135 strm);
136 }
137 }
138 }
139 return num_targets;
140}
141#pragma mark CommandObjectTargetCreate
142
143//-------------------------------------------------------------------------
144// "target create"
145//-------------------------------------------------------------------------
146
Jim Inghamda26bd22012-06-08 21:56:10 +0000147class CommandObjectTargetCreate : public CommandObjectParsed
Greg Claytonabe0fed2011-04-18 08:33:37 +0000148{
149public:
150 CommandObjectTargetCreate(CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000151 CommandObjectParsed (interpreter,
152 "target create",
153 "Create a target using the argument as the main executable.",
154 NULL),
Greg Claytonabe0fed2011-04-18 08:33:37 +0000155 m_option_group (interpreter),
Greg Clayton801417e2011-07-07 01:59:51 +0000156 m_arch_option (),
Greg Clayton46c9a352012-02-09 06:16:32 +0000157 m_platform_options(true), // Do include the "--platform" option in the platform settings by passing true
Johnny Chen6c061be2012-08-15 22:10:42 +0000158 m_core_file (LLDB_OPT_SET_1, false, "core", 'c', 0, eArgTypePath, "Fullpath to a core file to use for this target.")
Greg Claytonabe0fed2011-04-18 08:33:37 +0000159 {
160 CommandArgumentEntry arg;
161 CommandArgumentData file_arg;
162
163 // Define the first (and only) variant of this arg.
164 file_arg.arg_type = eArgTypeFilename;
165 file_arg.arg_repetition = eArgRepeatPlain;
166
167 // There is only one variant this argument could be; put it into the argument entry.
168 arg.push_back (file_arg);
169
170 // Push the data for the first argument into the m_arguments vector.
171 m_arguments.push_back (arg);
172
Greg Clayton801417e2011-07-07 01:59:51 +0000173 m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000174 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Clayton46c9a352012-02-09 06:16:32 +0000175 m_option_group.Append (&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000176 m_option_group.Finalize();
177 }
178
179 ~CommandObjectTargetCreate ()
180 {
181 }
182
183 Options *
184 GetOptions ()
185 {
186 return &m_option_group;
187 }
188
Jim Inghamda26bd22012-06-08 21:56:10 +0000189 int
190 HandleArgumentCompletion (Args &input,
191 int &cursor_index,
192 int &cursor_char_position,
193 OptionElementVector &opt_element_vector,
194 int match_start_point,
195 int max_return_elements,
196 bool &word_complete,
197 StringList &matches)
198 {
199 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
200 completion_str.erase (cursor_char_position);
201
202 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
203 CommandCompletions::eDiskFileCompletion,
204 completion_str.c_str(),
205 match_start_point,
206 max_return_elements,
207 NULL,
208 word_complete,
209 matches);
210 return matches.GetSize();
211 }
212
213protected:
Greg Claytonabe0fed2011-04-18 08:33:37 +0000214 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000215 DoExecute (Args& command, CommandReturnObject &result)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000216 {
217 const int argc = command.GetArgumentCount();
Greg Clayton46c9a352012-02-09 06:16:32 +0000218 FileSpec core_file (m_core_file.GetOptionValue().GetCurrentValue());
219
220 if (argc == 1 || core_file)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000221 {
222 const char *file_path = command.GetArgumentAtIndex(0);
223 Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path);
Greg Clayton46c9a352012-02-09 06:16:32 +0000224 FileSpec file_spec;
225
226 if (file_path)
227 file_spec.SetFile (file_path, true);
Greg Clayton3e8c25f2011-09-24 00:52:29 +0000228
Greg Claytonabe0fed2011-04-18 08:33:37 +0000229 TargetSP target_sp;
230 Debugger &debugger = m_interpreter.GetDebugger();
Greg Clayton3e8c25f2011-09-24 00:52:29 +0000231 const char *arch_cstr = m_arch_option.GetArchitectureName();
232 const bool get_dependent_files = true;
233 Error error (debugger.GetTargetList().CreateTarget (debugger,
234 file_spec,
235 arch_cstr,
236 get_dependent_files,
237 &m_platform_options,
238 target_sp));
239
Greg Claytonabe0fed2011-04-18 08:33:37 +0000240 if (target_sp)
241 {
242 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
Greg Clayton46c9a352012-02-09 06:16:32 +0000243 if (core_file)
244 {
Greg Clayton46c9a352012-02-09 06:16:32 +0000245 char core_path[PATH_MAX];
246 core_file.GetPath(core_path, sizeof(core_path));
Greg Clayton9ce95382012-02-13 23:10:39 +0000247 if (core_file.Exists())
Greg Clayton46c9a352012-02-09 06:16:32 +0000248 {
Greg Clayton9ce95382012-02-13 23:10:39 +0000249 FileSpec core_file_dir;
250 core_file_dir.GetDirectory() = core_file.GetDirectory();
251 target_sp->GetExecutableSearchPaths ().Append (core_file_dir);
Greg Clayton46c9a352012-02-09 06:16:32 +0000252
Greg Clayton9ce95382012-02-13 23:10:39 +0000253 ProcessSP process_sp (target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), NULL, &core_file));
254
255 if (process_sp)
Greg Clayton46c9a352012-02-09 06:16:32 +0000256 {
Greg Clayton9ce95382012-02-13 23:10:39 +0000257 // Seems wierd that we Launch a core file, but that is
258 // what we do!
259 error = process_sp->LoadCore();
260
261 if (error.Fail())
262 {
263 result.AppendError(error.AsCString("can't find plug-in for core file"));
264 result.SetStatus (eReturnStatusFailed);
265 return false;
266 }
267 else
268 {
269 result.AppendMessageWithFormat ("Core file '%s' (%s) was loaded.\n", core_path, target_sp->GetArchitecture().GetArchitectureName());
270 result.SetStatus (eReturnStatusSuccessFinishNoResult);
271 }
Greg Clayton46c9a352012-02-09 06:16:32 +0000272 }
273 else
274 {
Greg Clayton9ce95382012-02-13 23:10:39 +0000275 result.AppendErrorWithFormat ("Unable to find process plug-in for core file '%s'\n", core_path);
276 result.SetStatus (eReturnStatusFailed);
Greg Clayton46c9a352012-02-09 06:16:32 +0000277 }
278 }
279 else
280 {
Greg Clayton9ce95382012-02-13 23:10:39 +0000281 result.AppendErrorWithFormat ("Core file '%s' does not exist\n", core_path);
Greg Clayton46c9a352012-02-09 06:16:32 +0000282 result.SetStatus (eReturnStatusFailed);
283 }
284 }
285 else
286 {
287 result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName());
288 result.SetStatus (eReturnStatusSuccessFinishNoResult);
289 }
Greg Claytonabe0fed2011-04-18 08:33:37 +0000290 }
291 else
292 {
293 result.AppendError(error.AsCString());
294 result.SetStatus (eReturnStatusFailed);
295 }
296 }
297 else
298 {
Greg Clayton46c9a352012-02-09 06:16:32 +0000299 result.AppendErrorWithFormat("'%s' takes exactly one executable path argument, or use the --core-file option.\n", m_cmd_name.c_str());
Greg Claytonabe0fed2011-04-18 08:33:37 +0000300 result.SetStatus (eReturnStatusFailed);
301 }
302 return result.Succeeded();
303
304 }
305
Greg Claytonabe0fed2011-04-18 08:33:37 +0000306private:
307 OptionGroupOptions m_option_group;
Greg Clayton801417e2011-07-07 01:59:51 +0000308 OptionGroupArchitecture m_arch_option;
Greg Claytonabe0fed2011-04-18 08:33:37 +0000309 OptionGroupPlatform m_platform_options;
Greg Clayton46c9a352012-02-09 06:16:32 +0000310 OptionGroupFile m_core_file;
Greg Claytonabe0fed2011-04-18 08:33:37 +0000311
312};
313
314#pragma mark CommandObjectTargetList
315
316//----------------------------------------------------------------------
317// "target list"
318//----------------------------------------------------------------------
319
Jim Inghamda26bd22012-06-08 21:56:10 +0000320class CommandObjectTargetList : public CommandObjectParsed
Greg Claytonabe0fed2011-04-18 08:33:37 +0000321{
322public:
323 CommandObjectTargetList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000324 CommandObjectParsed (interpreter,
325 "target list",
326 "List all current targets in the current debug session.",
327 NULL,
328 0)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000329 {
330 }
331
332 virtual
333 ~CommandObjectTargetList ()
334 {
335 }
336
Jim Inghamda26bd22012-06-08 21:56:10 +0000337protected:
Greg Claytonabe0fed2011-04-18 08:33:37 +0000338 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000339 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000340 {
341 if (args.GetArgumentCount() == 0)
342 {
343 Stream &strm = result.GetOutputStream();
344
345 bool show_stopped_process_status = false;
346 if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0)
347 {
348 strm.PutCString ("No targets.\n");
349 }
Johnny Chen44dc9d32011-04-18 21:08:05 +0000350 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000351 }
352 else
353 {
354 result.AppendError ("the 'target list' command takes no arguments\n");
355 result.SetStatus (eReturnStatusFailed);
356 }
357 return result.Succeeded();
358 }
359};
360
361
362#pragma mark CommandObjectTargetSelect
363
364//----------------------------------------------------------------------
365// "target select"
366//----------------------------------------------------------------------
367
Jim Inghamda26bd22012-06-08 21:56:10 +0000368class CommandObjectTargetSelect : public CommandObjectParsed
Greg Claytonabe0fed2011-04-18 08:33:37 +0000369{
370public:
371 CommandObjectTargetSelect (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000372 CommandObjectParsed (interpreter,
373 "target select",
374 "Select a target as the current target by target index.",
375 NULL,
376 0)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000377 {
378 }
379
380 virtual
381 ~CommandObjectTargetSelect ()
382 {
383 }
384
Jim Inghamda26bd22012-06-08 21:56:10 +0000385protected:
Greg Claytonabe0fed2011-04-18 08:33:37 +0000386 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000387 DoExecute (Args& args, CommandReturnObject &result)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000388 {
389 if (args.GetArgumentCount() == 1)
390 {
391 bool success = false;
392 const char *target_idx_arg = args.GetArgumentAtIndex(0);
393 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
394 if (success)
395 {
396 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
397 const uint32_t num_targets = target_list.GetNumTargets();
398 if (target_idx < num_targets)
399 {
400 TargetSP target_sp (target_list.GetTargetAtIndex (target_idx));
401 if (target_sp)
402 {
403 Stream &strm = result.GetOutputStream();
404 target_list.SetSelectedTarget (target_sp.get());
405 bool show_stopped_process_status = false;
406 DumpTargetList (target_list, show_stopped_process_status, strm);
Johnny Chen44dc9d32011-04-18 21:08:05 +0000407 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000408 }
409 else
410 {
411 result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx);
412 result.SetStatus (eReturnStatusFailed);
413 }
414 }
415 else
416 {
417 result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n",
418 target_idx,
419 num_targets - 1);
420 result.SetStatus (eReturnStatusFailed);
421 }
422 }
423 else
424 {
425 result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg);
426 result.SetStatus (eReturnStatusFailed);
427 }
428 }
429 else
430 {
431 result.AppendError ("'target select' takes a single argument: a target index\n");
432 result.SetStatus (eReturnStatusFailed);
433 }
434 return result.Succeeded();
435 }
436};
437
Greg Clayton153ccd72011-08-10 02:10:13 +0000438#pragma mark CommandObjectTargetSelect
439
440//----------------------------------------------------------------------
441// "target delete"
442//----------------------------------------------------------------------
443
Jim Inghamda26bd22012-06-08 21:56:10 +0000444class CommandObjectTargetDelete : public CommandObjectParsed
Greg Clayton153ccd72011-08-10 02:10:13 +0000445{
446public:
447 CommandObjectTargetDelete (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000448 CommandObjectParsed (interpreter,
449 "target delete",
450 "Delete one or more targets by target index.",
451 NULL,
452 0),
Greg Clayton5beb99d2011-08-11 02:48:45 +0000453 m_option_group (interpreter),
Greg Clayton437b5bc2012-09-27 22:26:11 +0000454 m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', "Perform extra cleanup to minimize memory consumption after deleting the target.", false, false)
Greg Clayton153ccd72011-08-10 02:10:13 +0000455 {
Greg Clayton5beb99d2011-08-11 02:48:45 +0000456 m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
457 m_option_group.Finalize();
Greg Clayton153ccd72011-08-10 02:10:13 +0000458 }
459
460 virtual
461 ~CommandObjectTargetDelete ()
462 {
463 }
464
Jim Inghamda26bd22012-06-08 21:56:10 +0000465 Options *
466 GetOptions ()
467 {
468 return &m_option_group;
469 }
470
471protected:
Greg Clayton153ccd72011-08-10 02:10:13 +0000472 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000473 DoExecute (Args& args, CommandReturnObject &result)
Greg Clayton153ccd72011-08-10 02:10:13 +0000474 {
475 const size_t argc = args.GetArgumentCount();
476 std::vector<TargetSP> delete_target_list;
477 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
478 bool success = true;
479 TargetSP target_sp;
480 if (argc > 0)
481 {
482 const uint32_t num_targets = target_list.GetNumTargets();
Filipe Cabecinhasaa3d89e2012-07-09 13:02:17 +0000483 // Bail out if don't have any targets.
484 if (num_targets == 0) {
485 result.AppendError("no targets to delete");
486 result.SetStatus(eReturnStatusFailed);
487 success = false;
488 }
489
Greg Clayton153ccd72011-08-10 02:10:13 +0000490 for (uint32_t arg_idx = 0; success && arg_idx < argc; ++arg_idx)
491 {
492 const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx);
493 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
494 if (success)
495 {
496 if (target_idx < num_targets)
497 {
498 target_sp = target_list.GetTargetAtIndex (target_idx);
499 if (target_sp)
500 {
501 delete_target_list.push_back (target_sp);
502 continue;
503 }
504 }
Filipe Cabecinhasaa3d89e2012-07-09 13:02:17 +0000505 if (num_targets > 1)
506 result.AppendErrorWithFormat ("target index %u is out of range, valid target indexes are 0 - %u\n",
507 target_idx,
508 num_targets - 1);
509 else
510 result.AppendErrorWithFormat("target index %u is out of range, the only valid index is 0\n",
511 target_idx);
512
Greg Clayton153ccd72011-08-10 02:10:13 +0000513 result.SetStatus (eReturnStatusFailed);
514 success = false;
515 }
516 else
517 {
518 result.AppendErrorWithFormat("invalid target index '%s'\n", target_idx_arg);
519 result.SetStatus (eReturnStatusFailed);
520 success = false;
521 }
522 }
523
524 }
525 else
526 {
527 target_sp = target_list.GetSelectedTarget();
528 if (target_sp)
529 {
530 delete_target_list.push_back (target_sp);
531 }
532 else
533 {
534 result.AppendErrorWithFormat("no target is currently selected\n");
535 result.SetStatus (eReturnStatusFailed);
536 success = false;
537 }
538 }
539 if (success)
540 {
541 const size_t num_targets_to_delete = delete_target_list.size();
542 for (size_t idx = 0; idx < num_targets_to_delete; ++idx)
543 {
544 target_sp = delete_target_list[idx];
545 target_list.DeleteTarget(target_sp);
546 target_sp->Destroy();
547 }
Greg Clayton5beb99d2011-08-11 02:48:45 +0000548 // If "--clean" was specified, prune any orphaned shared modules from
549 // the global shared module list
550 if (m_cleanup_option.GetOptionValue ())
551 {
Greg Clayton860b9ea2012-04-09 20:22:01 +0000552 const bool mandatory = true;
553 ModuleList::RemoveOrphanSharedModules(mandatory);
Greg Clayton5beb99d2011-08-11 02:48:45 +0000554 }
Greg Clayton153ccd72011-08-10 02:10:13 +0000555 result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete);
556 result.SetStatus(eReturnStatusSuccessFinishResult);
557 }
558
559 return result.Succeeded();
560 }
Greg Clayton5beb99d2011-08-11 02:48:45 +0000561
Greg Clayton5beb99d2011-08-11 02:48:45 +0000562 OptionGroupOptions m_option_group;
563 OptionGroupBoolean m_cleanup_option;
Greg Clayton153ccd72011-08-10 02:10:13 +0000564};
565
Greg Claytonabe0fed2011-04-18 08:33:37 +0000566
Greg Clayton801417e2011-07-07 01:59:51 +0000567#pragma mark CommandObjectTargetVariable
568
569//----------------------------------------------------------------------
570// "target variable"
571//----------------------------------------------------------------------
572
Jim Inghamda26bd22012-06-08 21:56:10 +0000573class CommandObjectTargetVariable : public CommandObjectParsed
Greg Clayton801417e2011-07-07 01:59:51 +0000574{
575public:
576 CommandObjectTargetVariable (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000577 CommandObjectParsed (interpreter,
578 "target variable",
579 "Read global variable(s) prior to running your binary.",
580 NULL,
581 0),
Greg Clayton801417e2011-07-07 01:59:51 +0000582 m_option_group (interpreter),
Greg Clayton368f8222011-07-07 04:38:25 +0000583 m_option_variable (false), // Don't include frame options
Greg Claytona42880a2011-10-25 06:44:01 +0000584 m_option_format (eFormatDefault),
Greg Clayton801417e2011-07-07 01:59:51 +0000585 m_option_compile_units (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "A basename or fullpath to a file that contains global variables. This option can be specified multiple times."),
586 m_option_shared_libraries (LLDB_OPT_SET_1, false, "shlib",'s', 0, eArgTypePath, "A basename or fullpath to a shared library to use in the search for global variables. This option can be specified multiple times."),
587 m_varobj_options()
588 {
Johnny Chen24b81e32011-08-22 22:22:00 +0000589 CommandArgumentEntry arg;
590 CommandArgumentData var_name_arg;
591
592 // Define the first (and only) variant of this arg.
593 var_name_arg.arg_type = eArgTypeVarName;
594 var_name_arg.arg_repetition = eArgRepeatPlus;
595
596 // There is only one variant this argument could be; put it into the argument entry.
597 arg.push_back (var_name_arg);
598
599 // Push the data for the first argument into the m_arguments vector.
600 m_arguments.push_back (arg);
601
Greg Clayton801417e2011-07-07 01:59:51 +0000602 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Clayton368f8222011-07-07 04:38:25 +0000603 m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Clayton24a6bd92011-10-27 17:55:14 +0000604 m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
Greg Clayton801417e2011-07-07 01:59:51 +0000605 m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
606 m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
607 m_option_group.Finalize();
608 }
609
610 virtual
611 ~CommandObjectTargetVariable ()
612 {
613 }
Greg Clayton5d81f492011-07-08 21:46:14 +0000614
615 void
616 DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name)
617 {
Enrico Granata19030d82011-08-15 18:01:31 +0000618 ValueObject::DumpValueObjectOptions options;
619
Enrico Granata3069c622012-03-01 04:24:26 +0000620 options.SetMaximumPointerDepth(m_varobj_options.ptr_depth)
Enrico Granata19030d82011-08-15 18:01:31 +0000621 .SetMaximumDepth(m_varobj_options.max_depth)
622 .SetShowTypes(m_varobj_options.show_types)
623 .SetShowLocation(m_varobj_options.show_location)
624 .SetUseObjectiveC(m_varobj_options.use_objc)
625 .SetUseDynamicType(m_varobj_options.use_dynamic)
Enrico Granatacf09f882012-03-19 22:58:49 +0000626 .SetUseSyntheticValue(m_varobj_options.use_synth)
Enrico Granata19030d82011-08-15 18:01:31 +0000627 .SetFlatOutput(m_varobj_options.flat_output)
628 .SetOmitSummaryDepth(m_varobj_options.no_summary_depth)
629 .SetIgnoreCap(m_varobj_options.ignore_cap);
630
Greg Clayton5d81f492011-07-08 21:46:14 +0000631 switch (var_sp->GetScope())
632 {
633 case eValueTypeVariableGlobal:
634 if (m_option_variable.show_scope)
635 s.PutCString("GLOBAL: ");
636 break;
637
638 case eValueTypeVariableStatic:
639 if (m_option_variable.show_scope)
640 s.PutCString("STATIC: ");
641 break;
642
643 case eValueTypeVariableArgument:
644 if (m_option_variable.show_scope)
645 s.PutCString(" ARG: ");
646 break;
647
648 case eValueTypeVariableLocal:
649 if (m_option_variable.show_scope)
650 s.PutCString(" LOCAL: ");
651 break;
652
653 default:
654 break;
655 }
656
Greg Claytonfb816422011-07-10 19:21:23 +0000657 if (m_option_variable.show_decl)
Greg Clayton5d81f492011-07-08 21:46:14 +0000658 {
Greg Claytonfb816422011-07-10 19:21:23 +0000659 bool show_fullpaths = false;
660 bool show_module = true;
661 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
662 s.PutCString (": ");
Greg Clayton5d81f492011-07-08 21:46:14 +0000663 }
664
Greg Claytona42880a2011-10-25 06:44:01 +0000665 const Format format = m_option_format.GetFormat();
Greg Clayton5d81f492011-07-08 21:46:14 +0000666 if (format != eFormatDefault)
Enrico Granata3069c622012-03-01 04:24:26 +0000667 options.SetFormat(format);
668
669 options.SetRootValueObjectName(root_name);
Greg Clayton5d81f492011-07-08 21:46:14 +0000670
671 ValueObject::DumpValueObject (s,
672 valobj_sp.get(),
Enrico Granata3069c622012-03-01 04:24:26 +0000673 options);
Greg Clayton5d81f492011-07-08 21:46:14 +0000674
675 }
Greg Clayton801417e2011-07-07 01:59:51 +0000676
Greg Clayton5d81f492011-07-08 21:46:14 +0000677
678 static uint32_t GetVariableCallback (void *baton,
679 const char *name,
680 VariableList &variable_list)
681 {
682 Target *target = static_cast<Target *>(baton);
683 if (target)
684 {
685 return target->GetImages().FindGlobalVariables (ConstString(name),
686 true,
687 UINT32_MAX,
688 variable_list);
689 }
690 return 0;
691 }
692
693
694
Jim Inghamda26bd22012-06-08 21:56:10 +0000695 Options *
696 GetOptions ()
697 {
698 return &m_option_group;
699 }
700
701protected:
Greg Clayton801417e2011-07-07 01:59:51 +0000702 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000703 DoExecute (Args& args, CommandReturnObject &result)
Greg Clayton801417e2011-07-07 01:59:51 +0000704 {
705 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +0000706 Target *target = exe_ctx.GetTargetPtr();
707 if (target)
Greg Clayton801417e2011-07-07 01:59:51 +0000708 {
709 const size_t argc = args.GetArgumentCount();
Greg Claytonfac93882011-10-05 22:17:32 +0000710 Stream &s = result.GetOutputStream();
Greg Clayton801417e2011-07-07 01:59:51 +0000711 if (argc > 0)
712 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000713
Greg Clayton801417e2011-07-07 01:59:51 +0000714 for (size_t idx = 0; idx < argc; ++idx)
715 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000716 VariableList variable_list;
717 ValueObjectList valobj_list;
718
Greg Clayton368f8222011-07-07 04:38:25 +0000719 const char *arg = args.GetArgumentAtIndex(idx);
720 uint32_t matches = 0;
Greg Claytonfb816422011-07-10 19:21:23 +0000721 bool use_var_name = false;
Greg Clayton368f8222011-07-07 04:38:25 +0000722 if (m_option_variable.use_regex)
Greg Clayton801417e2011-07-07 01:59:51 +0000723 {
Greg Clayton368f8222011-07-07 04:38:25 +0000724 RegularExpression regex(arg);
725 if (!regex.IsValid ())
726 {
727 result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg);
728 result.SetStatus (eReturnStatusFailed);
729 return false;
730 }
Greg Claytonfb816422011-07-10 19:21:23 +0000731 use_var_name = true;
Greg Clayton567e7f32011-09-22 04:58:26 +0000732 matches = target->GetImages().FindGlobalVariables (regex,
733 true,
734 UINT32_MAX,
735 variable_list);
Greg Clayton801417e2011-07-07 01:59:51 +0000736 }
737 else
738 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000739 Error error (Variable::GetValuesForVariableExpressionPath (arg,
Greg Clayton24b03102011-07-09 20:12:33 +0000740 exe_ctx.GetBestExecutionContextScope(),
Greg Clayton5d81f492011-07-08 21:46:14 +0000741 GetVariableCallback,
Greg Clayton567e7f32011-09-22 04:58:26 +0000742 target,
Greg Clayton5d81f492011-07-08 21:46:14 +0000743 variable_list,
744 valobj_list));
Greg Clayton5d81f492011-07-08 21:46:14 +0000745 matches = variable_list.GetSize();
Greg Clayton368f8222011-07-07 04:38:25 +0000746 }
747
748 if (matches == 0)
749 {
750 result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg);
751 result.SetStatus (eReturnStatusFailed);
752 return false;
753 }
754 else
755 {
Greg Clayton801417e2011-07-07 01:59:51 +0000756 for (uint32_t global_idx=0; global_idx<matches; ++global_idx)
757 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000758 VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx));
Greg Clayton801417e2011-07-07 01:59:51 +0000759 if (var_sp)
760 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000761 ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx));
762 if (!valobj_sp)
Greg Claytonfb816422011-07-10 19:21:23 +0000763 valobj_sp = ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp);
Greg Clayton801417e2011-07-07 01:59:51 +0000764
765 if (valobj_sp)
Greg Claytonb304a742011-10-13 18:31:02 +0000766 DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg);
Greg Clayton801417e2011-07-07 01:59:51 +0000767 }
768 }
769 }
770 }
771 }
772 else
773 {
Greg Claytonfac93882011-10-05 22:17:32 +0000774 bool success = false;
775 StackFrame *frame = exe_ctx.GetFramePtr();
776 CompileUnit *comp_unit = NULL;
777 if (frame)
778 {
779 comp_unit = frame->GetSymbolContext (eSymbolContextCompUnit).comp_unit;
780 if (comp_unit)
781 {
782 const bool can_create = true;
783 VariableListSP comp_unit_varlist_sp (comp_unit->GetVariableList(can_create));
784 if (comp_unit_varlist_sp)
785 {
786 size_t count = comp_unit_varlist_sp->GetSize();
787 if (count > 0)
788 {
Greg Claytona1b9a902011-11-13 04:15:56 +0000789 s.Printf ("Global variables for %s/%s:\n",
Greg Claytonfac93882011-10-05 22:17:32 +0000790 comp_unit->GetDirectory().GetCString(),
791 comp_unit->GetFilename().GetCString());
792
793 success = true;
794 for (uint32_t i=0; i<count; ++i)
795 {
796 VariableSP var_sp (comp_unit_varlist_sp->GetVariableAtIndex(i));
797 if (var_sp)
798 {
799 ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp));
800
801 if (valobj_sp)
802 DumpValueObject (s, var_sp, valobj_sp, var_sp->GetName().GetCString());
803 }
804 }
805 }
806 }
807 }
808 }
809 if (!success)
810 {
811 if (frame)
812 {
813 if (comp_unit)
814 result.AppendErrorWithFormat ("no global variables in current compile unit: %s/%s\n",
815 comp_unit->GetDirectory().GetCString(),
816 comp_unit->GetFilename().GetCString());
817 else
818 result.AppendError ("no debug information for frame %u\n", frame->GetFrameIndex());
819 }
820 else
821 result.AppendError ("'target variable' takes one or more global variable names as arguments\n");
822 result.SetStatus (eReturnStatusFailed);
823 }
Greg Clayton801417e2011-07-07 01:59:51 +0000824 }
825 }
826 else
827 {
828 result.AppendError ("invalid target, create a debug target using the 'target create' command");
829 result.SetStatus (eReturnStatusFailed);
830 return false;
831 }
Enrico Granatadb64d952011-08-12 16:42:31 +0000832
833 if (m_interpreter.TruncationWarningNecessary())
834 {
835 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
836 m_cmd_name.c_str());
837 m_interpreter.TruncationWarningGiven();
838 }
839
Greg Clayton801417e2011-07-07 01:59:51 +0000840 return result.Succeeded();
841 }
842
Greg Clayton801417e2011-07-07 01:59:51 +0000843 OptionGroupOptions m_option_group;
Greg Clayton368f8222011-07-07 04:38:25 +0000844 OptionGroupVariable m_option_variable;
Greg Claytona42880a2011-10-25 06:44:01 +0000845 OptionGroupFormat m_option_format;
Greg Clayton801417e2011-07-07 01:59:51 +0000846 OptionGroupFileList m_option_compile_units;
847 OptionGroupFileList m_option_shared_libraries;
848 OptionGroupValueObjectDisplay m_varobj_options;
849
850};
851
852
Greg Claytone1f50b92011-05-03 22:09:39 +0000853#pragma mark CommandObjectTargetModulesSearchPathsAdd
Chris Lattner24943d22010-06-08 16:52:24 +0000854
Jim Inghamda26bd22012-06-08 21:56:10 +0000855class CommandObjectTargetModulesSearchPathsAdd : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000856{
857public:
858
Greg Claytone1f50b92011-05-03 22:09:39 +0000859 CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000860 CommandObjectParsed (interpreter,
861 "target modules search-paths add",
862 "Add new image search paths substitution pairs to the current target.",
863 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000864 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000865 CommandArgumentEntry arg;
866 CommandArgumentData old_prefix_arg;
867 CommandArgumentData new_prefix_arg;
868
869 // Define the first variant of this arg pair.
870 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
871 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
872
873 // Define the first variant of this arg pair.
874 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
875 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
876
877 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
878 // must always occur together, they are treated as two variants of one argument rather than two independent
879 // arguments. Push them both into the first argument position for m_arguments...
880
881 arg.push_back (old_prefix_arg);
882 arg.push_back (new_prefix_arg);
883
884 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000885 }
886
Greg Claytone1f50b92011-05-03 22:09:39 +0000887 ~CommandObjectTargetModulesSearchPathsAdd ()
Chris Lattner24943d22010-06-08 16:52:24 +0000888 {
889 }
890
Jim Inghamda26bd22012-06-08 21:56:10 +0000891protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000892 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000893 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000894 CommandReturnObject &result)
895 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000896 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000897 if (target)
898 {
899 uint32_t argc = command.GetArgumentCount();
900 if (argc & 1)
901 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000902 result.AppendError ("add requires an even number of arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000903 result.SetStatus (eReturnStatusFailed);
904 }
905 else
906 {
907 for (uint32_t i=0; i<argc; i+=2)
908 {
909 const char *from = command.GetArgumentAtIndex(i);
910 const char *to = command.GetArgumentAtIndex(i+1);
911
912 if (from[0] && to[0])
913 {
914 bool last_pair = ((argc - i) == 2);
Greg Clayton63094e02010-06-23 01:19:29 +0000915 target->GetImageSearchPathList().Append (ConstString(from),
916 ConstString(to),
917 last_pair); // Notify if this is the last pair
Johnny Chen4d661352011-02-03 00:30:19 +0000918 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000919 }
920 else
921 {
922 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +0000923 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000924 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000925 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000926 result.SetStatus (eReturnStatusFailed);
927 }
928 }
929 }
930 }
931 else
932 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000933 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000934 result.SetStatus (eReturnStatusFailed);
935 }
936 return result.Succeeded();
937 }
938};
939
Greg Claytone1f50b92011-05-03 22:09:39 +0000940#pragma mark CommandObjectTargetModulesSearchPathsClear
941
Jim Inghamda26bd22012-06-08 21:56:10 +0000942class CommandObjectTargetModulesSearchPathsClear : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000943{
944public:
945
Greg Claytone1f50b92011-05-03 22:09:39 +0000946 CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000947 CommandObjectParsed (interpreter,
948 "target modules search-paths clear",
949 "Clear all current image search path substitution pairs from the current target.",
950 "target modules search-paths clear")
Chris Lattner24943d22010-06-08 16:52:24 +0000951 {
952 }
953
Greg Claytone1f50b92011-05-03 22:09:39 +0000954 ~CommandObjectTargetModulesSearchPathsClear ()
Chris Lattner24943d22010-06-08 16:52:24 +0000955 {
956 }
957
Jim Inghamda26bd22012-06-08 21:56:10 +0000958protected:
Chris Lattner24943d22010-06-08 16:52:24 +0000959 bool
Jim Inghamda26bd22012-06-08 21:56:10 +0000960 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000961 CommandReturnObject &result)
962 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000963 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000964 if (target)
965 {
966 bool notify = true;
967 target->GetImageSearchPathList().Clear(notify);
Johnny Chen4d661352011-02-03 00:30:19 +0000968 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000969 }
970 else
971 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000972 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000973 result.SetStatus (eReturnStatusFailed);
974 }
975 return result.Succeeded();
976 }
977};
978
Greg Claytone1f50b92011-05-03 22:09:39 +0000979#pragma mark CommandObjectTargetModulesSearchPathsInsert
980
Jim Inghamda26bd22012-06-08 21:56:10 +0000981class CommandObjectTargetModulesSearchPathsInsert : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +0000982{
983public:
984
Greg Claytone1f50b92011-05-03 22:09:39 +0000985 CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +0000986 CommandObjectParsed (interpreter,
987 "target modules search-paths insert",
988 "Insert a new image search path substitution pair into the current target at the specified index.",
989 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000990 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000991 CommandArgumentEntry arg1;
992 CommandArgumentEntry arg2;
993 CommandArgumentData index_arg;
994 CommandArgumentData old_prefix_arg;
995 CommandArgumentData new_prefix_arg;
996
997 // Define the first and only variant of this arg.
998 index_arg.arg_type = eArgTypeIndex;
999 index_arg.arg_repetition = eArgRepeatPlain;
1000
1001 // Put the one and only variant into the first arg for m_arguments:
1002 arg1.push_back (index_arg);
1003
1004 // Define the first variant of this arg pair.
1005 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
1006 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1007
1008 // Define the first variant of this arg pair.
1009 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
1010 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
1011
1012 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
1013 // must always occur together, they are treated as two variants of one argument rather than two independent
1014 // arguments. Push them both into the same argument position for m_arguments...
1015
1016 arg2.push_back (old_prefix_arg);
1017 arg2.push_back (new_prefix_arg);
1018
1019 // Add arguments to m_arguments.
1020 m_arguments.push_back (arg1);
1021 m_arguments.push_back (arg2);
Chris Lattner24943d22010-06-08 16:52:24 +00001022 }
1023
Greg Claytone1f50b92011-05-03 22:09:39 +00001024 ~CommandObjectTargetModulesSearchPathsInsert ()
Chris Lattner24943d22010-06-08 16:52:24 +00001025 {
1026 }
1027
Jim Inghamda26bd22012-06-08 21:56:10 +00001028protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001029 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001030 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001031 CommandReturnObject &result)
1032 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001033 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001034 if (target)
1035 {
1036 uint32_t argc = command.GetArgumentCount();
1037 // check for at least 3 arguments and an odd nubmer of parameters
1038 if (argc >= 3 && argc & 1)
1039 {
1040 bool success = false;
1041
1042 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
1043
1044 if (!success)
1045 {
1046 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
1047 result.SetStatus (eReturnStatusFailed);
1048 return result.Succeeded();
1049 }
1050
1051 // shift off the index
1052 command.Shift();
1053 argc = command.GetArgumentCount();
1054
1055 for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
1056 {
1057 const char *from = command.GetArgumentAtIndex(i);
1058 const char *to = command.GetArgumentAtIndex(i+1);
1059
1060 if (from[0] && to[0])
1061 {
1062 bool last_pair = ((argc - i) == 2);
1063 target->GetImageSearchPathList().Insert (ConstString(from),
1064 ConstString(to),
1065 insert_idx,
1066 last_pair);
Johnny Chen4d661352011-02-03 00:30:19 +00001067 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001068 }
1069 else
1070 {
1071 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +00001072 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001073 else
Greg Claytonabe0fed2011-04-18 08:33:37 +00001074 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001075 result.SetStatus (eReturnStatusFailed);
1076 return false;
1077 }
1078 }
1079 }
1080 else
1081 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001082 result.AppendError ("insert requires at least three arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001083 result.SetStatus (eReturnStatusFailed);
1084 return result.Succeeded();
1085 }
1086
1087 }
1088 else
1089 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001090 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001091 result.SetStatus (eReturnStatusFailed);
1092 }
1093 return result.Succeeded();
1094 }
1095};
1096
Greg Claytone1f50b92011-05-03 22:09:39 +00001097
1098#pragma mark CommandObjectTargetModulesSearchPathsList
1099
1100
Jim Inghamda26bd22012-06-08 21:56:10 +00001101class CommandObjectTargetModulesSearchPathsList : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001102{
1103public:
1104
Greg Claytone1f50b92011-05-03 22:09:39 +00001105 CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001106 CommandObjectParsed (interpreter,
1107 "target modules search-paths list",
1108 "List all current image search path substitution pairs in the current target.",
1109 "target modules search-paths list")
Chris Lattner24943d22010-06-08 16:52:24 +00001110 {
1111 }
1112
Greg Claytone1f50b92011-05-03 22:09:39 +00001113 ~CommandObjectTargetModulesSearchPathsList ()
Chris Lattner24943d22010-06-08 16:52:24 +00001114 {
1115 }
1116
Jim Inghamda26bd22012-06-08 21:56:10 +00001117protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001118 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001119 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001120 CommandReturnObject &result)
1121 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001122 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001123 if (target)
1124 {
1125 if (command.GetArgumentCount() != 0)
1126 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001127 result.AppendError ("list takes no arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001128 result.SetStatus (eReturnStatusFailed);
1129 return result.Succeeded();
1130 }
1131
1132 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
Johnny Chen4d661352011-02-03 00:30:19 +00001133 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001134 }
1135 else
1136 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001137 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001138 result.SetStatus (eReturnStatusFailed);
1139 }
1140 return result.Succeeded();
1141 }
1142};
1143
Greg Claytone1f50b92011-05-03 22:09:39 +00001144#pragma mark CommandObjectTargetModulesSearchPathsQuery
1145
Jim Inghamda26bd22012-06-08 21:56:10 +00001146class CommandObjectTargetModulesSearchPathsQuery : public CommandObjectParsed
Chris Lattner24943d22010-06-08 16:52:24 +00001147{
1148public:
1149
Greg Claytone1f50b92011-05-03 22:09:39 +00001150 CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001151 CommandObjectParsed (interpreter,
1152 "target modules search-paths query",
1153 "Transform a path using the first applicable image search path.",
1154 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001155 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001156 CommandArgumentEntry arg;
1157 CommandArgumentData path_arg;
1158
1159 // Define the first (and only) variant of this arg.
1160 path_arg.arg_type = eArgTypePath;
1161 path_arg.arg_repetition = eArgRepeatPlain;
1162
1163 // There is only one variant this argument could be; put it into the argument entry.
1164 arg.push_back (path_arg);
1165
1166 // Push the data for the first argument into the m_arguments vector.
1167 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001168 }
1169
Greg Claytone1f50b92011-05-03 22:09:39 +00001170 ~CommandObjectTargetModulesSearchPathsQuery ()
Chris Lattner24943d22010-06-08 16:52:24 +00001171 {
1172 }
1173
Jim Inghamda26bd22012-06-08 21:56:10 +00001174protected:
Chris Lattner24943d22010-06-08 16:52:24 +00001175 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00001176 DoExecute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001177 CommandReturnObject &result)
1178 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001179 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001180 if (target)
1181 {
1182 if (command.GetArgumentCount() != 1)
1183 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001184 result.AppendError ("query requires one argument\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001185 result.SetStatus (eReturnStatusFailed);
1186 return result.Succeeded();
1187 }
1188
1189 ConstString orig(command.GetArgumentAtIndex(0));
1190 ConstString transformed;
1191 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1192 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1193 else
1194 result.GetOutputStream().Printf("%s\n", orig.GetCString());
Johnny Chen4d661352011-02-03 00:30:19 +00001195
1196 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001197 }
1198 else
1199 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001200 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001201 result.SetStatus (eReturnStatusFailed);
1202 }
1203 return result.Succeeded();
1204 }
1205};
1206
Greg Claytone1f50b92011-05-03 22:09:39 +00001207//----------------------------------------------------------------------
1208// Static Helper functions
1209//----------------------------------------------------------------------
1210static void
1211DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width)
1212{
1213 if (module)
1214 {
1215 const char *arch_cstr;
1216 if (full_triple)
1217 arch_cstr = module->GetArchitecture().GetTriple().str().c_str();
1218 else
1219 arch_cstr = module->GetArchitecture().GetArchitectureName();
1220 if (width)
1221 strm.Printf("%-*s", width, arch_cstr);
1222 else
1223 strm.PutCString(arch_cstr);
1224 }
1225}
1226
1227static void
1228DumpModuleUUID (Stream &strm, Module *module)
1229{
Jim Ingham6f01c932012-10-12 17:34:26 +00001230 if (module && module->GetUUID().IsValid())
Greg Clayton153ccd72011-08-10 02:10:13 +00001231 module->GetUUID().Dump (&strm);
1232 else
1233 strm.PutCString(" ");
Greg Claytone1f50b92011-05-03 22:09:39 +00001234}
1235
1236static uint32_t
1237DumpCompileUnitLineTable
1238(
1239 CommandInterpreter &interpreter,
1240 Stream &strm,
1241 Module *module,
1242 const FileSpec &file_spec,
1243 bool load_addresses
1244 )
1245{
1246 uint32_t num_matches = 0;
1247 if (module)
1248 {
1249 SymbolContextList sc_list;
1250 num_matches = module->ResolveSymbolContextsForFileSpec (file_spec,
1251 0,
1252 false,
1253 eSymbolContextCompUnit,
1254 sc_list);
1255
1256 for (uint32_t i=0; i<num_matches; ++i)
1257 {
1258 SymbolContext sc;
1259 if (sc_list.GetContextAtIndex(i, sc))
1260 {
1261 if (i > 0)
1262 strm << "\n\n";
1263
1264 strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `"
1265 << module->GetFileSpec().GetFilename() << "\n";
1266 LineTable *line_table = sc.comp_unit->GetLineTable();
1267 if (line_table)
1268 line_table->GetDescription (&strm,
Greg Clayton567e7f32011-09-22 04:58:26 +00001269 interpreter.GetExecutionContext().GetTargetPtr(),
Greg Claytone1f50b92011-05-03 22:09:39 +00001270 lldb::eDescriptionLevelBrief);
1271 else
1272 strm << "No line table";
1273 }
1274 }
1275 }
1276 return num_matches;
1277}
1278
1279static void
1280DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1281{
1282 if (file_spec_ptr)
1283 {
1284 if (width > 0)
1285 {
1286 char fullpath[PATH_MAX];
1287 if (file_spec_ptr->GetPath(fullpath, sizeof(fullpath)))
1288 {
1289 strm.Printf("%-*s", width, fullpath);
1290 return;
1291 }
1292 }
1293 else
1294 {
1295 file_spec_ptr->Dump(&strm);
1296 return;
1297 }
1298 }
1299 // Keep the width spacing correct if things go wrong...
1300 if (width > 0)
1301 strm.Printf("%-*s", width, "");
1302}
1303
1304static void
1305DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1306{
1307 if (file_spec_ptr)
1308 {
1309 if (width > 0)
1310 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1311 else
1312 file_spec_ptr->GetDirectory().Dump(&strm);
1313 return;
1314 }
1315 // Keep the width spacing correct if things go wrong...
1316 if (width > 0)
1317 strm.Printf("%-*s", width, "");
1318}
1319
1320static void
1321DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1322{
1323 if (file_spec_ptr)
1324 {
1325 if (width > 0)
1326 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1327 else
1328 file_spec_ptr->GetFilename().Dump(&strm);
1329 return;
1330 }
1331 // Keep the width spacing correct if things go wrong...
1332 if (width > 0)
1333 strm.Printf("%-*s", width, "");
1334}
1335
1336
1337static void
1338DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order)
1339{
1340 if (module)
1341 {
1342 ObjectFile *objfile = module->GetObjectFile ();
1343 if (objfile)
1344 {
1345 Symtab *symtab = objfile->GetSymtab();
1346 if (symtab)
Greg Clayton567e7f32011-09-22 04:58:26 +00001347 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), sort_order);
Greg Claytone1f50b92011-05-03 22:09:39 +00001348 }
1349 }
1350}
1351
1352static void
1353DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module)
1354{
1355 if (module)
1356 {
1357 ObjectFile *objfile = module->GetObjectFile ();
1358 if (objfile)
1359 {
1360 SectionList *section_list = objfile->GetSectionList();
1361 if (section_list)
1362 {
1363 strm.PutCString ("Sections for '");
1364 strm << module->GetFileSpec();
1365 if (module->GetObjectName())
1366 strm << '(' << module->GetObjectName() << ')';
1367 strm.Printf ("' (%s):\n", module->GetArchitecture().GetArchitectureName());
1368 strm.IndentMore();
Greg Clayton567e7f32011-09-22 04:58:26 +00001369 section_list->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX);
Greg Claytone1f50b92011-05-03 22:09:39 +00001370 strm.IndentLess();
1371 }
1372 }
1373 }
1374}
1375
1376static bool
1377DumpModuleSymbolVendor (Stream &strm, Module *module)
1378{
1379 if (module)
1380 {
1381 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1382 if (symbol_vendor)
1383 {
1384 symbol_vendor->Dump(&strm);
1385 return true;
1386 }
1387 }
1388 return false;
1389}
1390
Greg Clayton2ad894b2012-05-15 18:43:44 +00001391static void
1392DumpAddress (ExecutionContextScope *exe_scope, const Address &so_addr, bool verbose, Stream &strm)
1393{
1394 strm.IndentMore();
1395 strm.Indent (" Address: ");
1396 so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1397 strm.PutCString (" (");
1398 so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1399 strm.PutCString (")\n");
1400 strm.Indent (" Summary: ");
1401 const uint32_t save_indent = strm.GetIndentLevel ();
1402 strm.SetIndentLevel (save_indent + 13);
1403 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
1404 strm.SetIndentLevel (save_indent);
1405 // Print out detailed address information when verbose is enabled
1406 if (verbose)
1407 {
1408 strm.EOL();
1409 so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1410 }
1411 strm.IndentLess();
1412}
1413
Greg Claytone1f50b92011-05-03 22:09:39 +00001414static bool
Greg Clayton3508c382012-02-24 01:59:29 +00001415LookupAddressInModule (CommandInterpreter &interpreter,
1416 Stream &strm,
1417 Module *module,
1418 uint32_t resolve_mask,
1419 lldb::addr_t raw_addr,
1420 lldb::addr_t offset,
1421 bool verbose)
Greg Claytone1f50b92011-05-03 22:09:39 +00001422{
1423 if (module)
1424 {
1425 lldb::addr_t addr = raw_addr - offset;
1426 Address so_addr;
1427 SymbolContext sc;
Greg Clayton567e7f32011-09-22 04:58:26 +00001428 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
Greg Claytone1f50b92011-05-03 22:09:39 +00001429 if (target && !target->GetSectionLoadList().IsEmpty())
1430 {
1431 if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr))
1432 return false;
Greg Clayton3508c382012-02-24 01:59:29 +00001433 else if (so_addr.GetModule().get() != module)
Greg Claytone1f50b92011-05-03 22:09:39 +00001434 return false;
1435 }
1436 else
1437 {
1438 if (!module->ResolveFileAddress (addr, so_addr))
1439 return false;
1440 }
1441
Greg Claytone1f50b92011-05-03 22:09:39 +00001442 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope();
Greg Clayton2ad894b2012-05-15 18:43:44 +00001443 DumpAddress (exe_scope, so_addr, verbose, strm);
1444// strm.IndentMore();
1445// strm.Indent (" Address: ");
1446// so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1447// strm.PutCString (" (");
1448// so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1449// strm.PutCString (")\n");
1450// strm.Indent (" Summary: ");
1451// const uint32_t save_indent = strm.GetIndentLevel ();
1452// strm.SetIndentLevel (save_indent + 13);
1453// so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
1454// strm.SetIndentLevel (save_indent);
1455// // Print out detailed address information when verbose is enabled
1456// if (verbose)
1457// {
1458// strm.EOL();
1459// so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
1460// }
1461// strm.IndentLess();
Greg Claytone1f50b92011-05-03 22:09:39 +00001462 return true;
1463 }
1464
1465 return false;
1466}
1467
1468static uint32_t
Greg Clayton2ad894b2012-05-15 18:43:44 +00001469LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose)
Greg Claytone1f50b92011-05-03 22:09:39 +00001470{
1471 if (module)
1472 {
1473 SymbolContext sc;
1474
1475 ObjectFile *objfile = module->GetObjectFile ();
1476 if (objfile)
1477 {
1478 Symtab *symtab = objfile->GetSymtab();
1479 if (symtab)
1480 {
1481 uint32_t i;
1482 std::vector<uint32_t> match_indexes;
1483 ConstString symbol_name (name);
1484 uint32_t num_matches = 0;
1485 if (name_is_regex)
1486 {
1487 RegularExpression name_regexp(name);
1488 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp,
1489 eSymbolTypeAny,
1490 match_indexes);
1491 }
1492 else
1493 {
1494 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
1495 }
1496
1497
1498 if (num_matches > 0)
1499 {
1500 strm.Indent ();
1501 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1502 name_is_regex ? "the regular expression " : "", name);
1503 DumpFullpath (strm, &module->GetFileSpec(), 0);
1504 strm.PutCString(":\n");
1505 strm.IndentMore ();
Greg Clayton2ad894b2012-05-15 18:43:44 +00001506 //Symtab::DumpSymbolHeader (&strm);
Greg Claytone1f50b92011-05-03 22:09:39 +00001507 for (i=0; i < num_matches; ++i)
1508 {
1509 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
Greg Clayton2ad894b2012-05-15 18:43:44 +00001510 DumpAddress (interpreter.GetExecutionContext().GetBestExecutionContextScope(),
1511 symbol->GetAddress(),
1512 verbose,
1513 strm);
1514
1515// strm.Indent ();
1516// symbol->Dump (&strm, interpreter.GetExecutionContext().GetTargetPtr(), i);
Greg Claytone1f50b92011-05-03 22:09:39 +00001517 }
1518 strm.IndentLess ();
1519 return num_matches;
1520 }
1521 }
1522 }
1523 }
1524 return 0;
1525}
1526
1527
1528static void
Greg Clayton2ad894b2012-05-15 18:43:44 +00001529DumpSymbolContextList (ExecutionContextScope *exe_scope, Stream &strm, SymbolContextList &sc_list, bool verbose)
Greg Claytone1f50b92011-05-03 22:09:39 +00001530{
1531 strm.IndentMore ();
1532 uint32_t i;
1533 const uint32_t num_matches = sc_list.GetSize();
1534
1535 for (i=0; i<num_matches; ++i)
1536 {
1537 SymbolContext sc;
1538 if (sc_list.GetContextAtIndex(i, sc))
1539 {
Sean Callanand7793d22012-02-11 00:24:04 +00001540 AddressRange range;
1541
1542 sc.GetAddressRange(eSymbolContextEverything,
1543 0,
1544 true,
1545 range);
1546
Greg Clayton2ad894b2012-05-15 18:43:44 +00001547 DumpAddress (exe_scope, range.GetBaseAddress(), verbose, strm);
Greg Claytone1f50b92011-05-03 22:09:39 +00001548 }
1549 }
1550 strm.IndentLess ();
1551}
1552
1553static uint32_t
Greg Clayton2ad894b2012-05-15 18:43:44 +00001554LookupFunctionInModule (CommandInterpreter &interpreter,
1555 Stream &strm,
1556 Module *module,
1557 const char *name,
1558 bool name_is_regex,
1559 bool include_inlines,
1560 bool include_symbols,
1561 bool verbose)
Greg Claytone1f50b92011-05-03 22:09:39 +00001562{
1563 if (module && name && name[0])
1564 {
1565 SymbolContextList sc_list;
Greg Claytone1f50b92011-05-03 22:09:39 +00001566 const bool append = true;
1567 uint32_t num_matches = 0;
1568 if (name_is_regex)
1569 {
1570 RegularExpression function_name_regex (name);
1571 num_matches = module->FindFunctions (function_name_regex,
1572 include_symbols,
Sean Callanan302d78c2012-02-10 22:52:19 +00001573 include_inlines,
Greg Claytone1f50b92011-05-03 22:09:39 +00001574 append,
1575 sc_list);
1576 }
1577 else
1578 {
1579 ConstString function_name (name);
Sean Callanan3e80cd92011-10-12 02:08:07 +00001580 num_matches = module->FindFunctions (function_name,
1581 NULL,
Greg Claytone1f50b92011-05-03 22:09:39 +00001582 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
1583 include_symbols,
Sean Callanan302d78c2012-02-10 22:52:19 +00001584 include_inlines,
Greg Claytone1f50b92011-05-03 22:09:39 +00001585 append,
1586 sc_list);
1587 }
1588
1589 if (num_matches)
1590 {
1591 strm.Indent ();
1592 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1593 DumpFullpath (strm, &module->GetFileSpec(), 0);
1594 strm.PutCString(":\n");
Greg Clayton2ad894b2012-05-15 18:43:44 +00001595 DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
Greg Claytone1f50b92011-05-03 22:09:39 +00001596 }
1597 return num_matches;
1598 }
1599 return 0;
1600}
1601
1602static uint32_t
Greg Clayton0cbaacd2012-05-15 19:26:12 +00001603LookupTypeInModule (CommandInterpreter &interpreter,
Greg Clayton801417e2011-07-07 01:59:51 +00001604 Stream &strm,
1605 Module *module,
1606 const char *name_cstr,
1607 bool name_is_regex)
Greg Claytone1f50b92011-05-03 22:09:39 +00001608{
1609 if (module && name_cstr && name_cstr[0])
1610 {
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001611 TypeList type_list;
Greg Claytondc0a38c2012-03-26 23:03:23 +00001612 const uint32_t max_num_matches = UINT32_MAX;
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001613 uint32_t num_matches = 0;
Greg Claytondc0a38c2012-03-26 23:03:23 +00001614 bool name_is_fully_qualified = false;
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001615 SymbolContext sc;
1616
1617 ConstString name(name_cstr);
Greg Claytondc0a38c2012-03-26 23:03:23 +00001618 num_matches = module->FindTypes(sc, name, name_is_fully_qualified, max_num_matches, type_list);
Greg Claytone1f50b92011-05-03 22:09:39 +00001619
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001620 if (num_matches)
1621 {
1622 strm.Indent ();
1623 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1624 DumpFullpath (strm, &module->GetFileSpec(), 0);
1625 strm.PutCString(":\n");
1626 const uint32_t num_types = type_list.GetSize();
1627 for (uint32_t i=0; i<num_types; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00001628 {
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001629 TypeSP type_sp (type_list.GetTypeAtIndex(i));
1630 if (type_sp)
Greg Claytone1f50b92011-05-03 22:09:39 +00001631 {
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001632 // Resolve the clang type so that any forward references
1633 // to types that haven't yet been parsed will get parsed.
1634 type_sp->GetClangFullType ();
1635 type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
Greg Clayton0cbaacd2012-05-15 19:26:12 +00001636 // Print all typedef chains
1637 TypeSP typedef_type_sp (type_sp);
1638 TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
1639 while (typedefed_type_sp)
1640 {
1641 strm.EOL();
1642 strm.Printf(" typedef '%s': ", typedef_type_sp->GetName().GetCString());
1643 typedefed_type_sp->GetClangFullType ();
1644 typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1645 typedef_type_sp = typedefed_type_sp;
1646 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1647 }
Greg Claytone1f50b92011-05-03 22:09:39 +00001648 }
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001649 strm.EOL();
Greg Claytone1f50b92011-05-03 22:09:39 +00001650 }
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001651 }
1652 return num_matches;
Greg Claytone1f50b92011-05-03 22:09:39 +00001653 }
1654 return 0;
1655}
1656
1657static uint32_t
Sean Callanan56d31ec2012-06-06 20:49:55 +00001658LookupTypeHere (CommandInterpreter &interpreter,
1659 Stream &strm,
1660 const SymbolContext &sym_ctx,
1661 const char *name_cstr,
1662 bool name_is_regex)
1663{
1664 if (!sym_ctx.module_sp)
1665 return 0;
1666
1667 TypeList type_list;
1668 const uint32_t max_num_matches = UINT32_MAX;
1669 uint32_t num_matches = 1;
1670 bool name_is_fully_qualified = false;
1671
1672 ConstString name(name_cstr);
1673 num_matches = sym_ctx.module_sp->FindTypes(sym_ctx, name, name_is_fully_qualified, max_num_matches, type_list);
1674
1675 if (num_matches)
1676 {
1677 strm.Indent ();
1678 strm.PutCString("Best match found in ");
1679 DumpFullpath (strm, &sym_ctx.module_sp->GetFileSpec(), 0);
1680 strm.PutCString(":\n");
1681
1682 TypeSP type_sp (type_list.GetTypeAtIndex(0));
1683 if (type_sp)
1684 {
1685 // Resolve the clang type so that any forward references
1686 // to types that haven't yet been parsed will get parsed.
1687 type_sp->GetClangFullType ();
1688 type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1689 // Print all typedef chains
1690 TypeSP typedef_type_sp (type_sp);
1691 TypeSP typedefed_type_sp (typedef_type_sp->GetTypedefType());
1692 while (typedefed_type_sp)
1693 {
1694 strm.EOL();
1695 strm.Printf(" typedef '%s': ", typedef_type_sp->GetName().GetCString());
1696 typedefed_type_sp->GetClangFullType ();
1697 typedefed_type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1698 typedef_type_sp = typedefed_type_sp;
1699 typedefed_type_sp = typedef_type_sp->GetTypedefType();
1700 }
1701 }
1702 strm.EOL();
1703 }
1704 return num_matches;
1705}
1706
1707static uint32_t
Greg Claytone1f50b92011-05-03 22:09:39 +00001708LookupFileAndLineInModule (CommandInterpreter &interpreter,
Sean Callanan56d31ec2012-06-06 20:49:55 +00001709 Stream &strm,
Greg Claytone1f50b92011-05-03 22:09:39 +00001710 Module *module,
1711 const FileSpec &file_spec,
1712 uint32_t line,
1713 bool check_inlines,
1714 bool verbose)
1715{
1716 if (module && file_spec)
1717 {
1718 SymbolContextList sc_list;
1719 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
1720 eSymbolContextEverything, sc_list);
1721 if (num_matches > 0)
1722 {
1723 strm.Indent ();
1724 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1725 strm << file_spec;
1726 if (line > 0)
1727 strm.Printf (":%u", line);
1728 strm << " in ";
1729 DumpFullpath (strm, &module->GetFileSpec(), 0);
1730 strm.PutCString(":\n");
Greg Clayton2ad894b2012-05-15 18:43:44 +00001731 DumpSymbolContextList (interpreter.GetExecutionContext().GetBestExecutionContextScope(), strm, sc_list, verbose);
Greg Claytone1f50b92011-05-03 22:09:39 +00001732 return num_matches;
1733 }
1734 }
1735 return 0;
1736
1737}
1738
Greg Clayton91048ef2011-11-10 01:18:58 +00001739
1740static size_t
1741FindModulesByName (Target *target,
1742 const char *module_name,
1743 ModuleList &module_list,
1744 bool check_global_list)
1745{
1746// Dump specified images (by basename or fullpath)
1747 FileSpec module_file_spec(module_name, false);
Greg Clayton444fe992012-02-26 05:51:37 +00001748 ModuleSpec module_spec (module_file_spec);
Greg Clayton91048ef2011-11-10 01:18:58 +00001749
1750 const size_t initial_size = module_list.GetSize ();
1751
Greg Clayton316f57f2012-07-11 20:46:47 +00001752 if (check_global_list)
Greg Clayton91048ef2011-11-10 01:18:58 +00001753 {
1754 // Check the global list
Greg Claytonc149c8b2012-01-27 18:08:35 +00001755 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
Greg Clayton91048ef2011-11-10 01:18:58 +00001756 const uint32_t num_modules = Module::GetNumberAllocatedModules();
1757 ModuleSP module_sp;
1758 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1759 {
1760 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1761
1762 if (module)
1763 {
Greg Clayton444fe992012-02-26 05:51:37 +00001764 if (module->MatchesModuleSpec (module_spec))
Greg Clayton91048ef2011-11-10 01:18:58 +00001765 {
Greg Clayton13d24fb2012-01-29 20:56:30 +00001766 module_sp = module->shared_from_this();
Greg Clayton91048ef2011-11-10 01:18:58 +00001767 module_list.AppendIfNeeded(module_sp);
1768 }
1769 }
1770 }
1771 }
Greg Clayton316f57f2012-07-11 20:46:47 +00001772 else
1773 {
1774 if (target)
1775 {
1776 const size_t num_matches = target->GetImages().FindModules (module_spec, module_list);
1777
1778 // Not found in our module list for our target, check the main
1779 // shared module list in case it is a extra file used somewhere
1780 // else
1781 if (num_matches == 0)
1782 {
1783 module_spec.GetArchitecture() = target->GetArchitecture();
1784 ModuleList::FindSharedModules (module_spec, module_list);
1785 }
1786 }
1787 else
1788 {
1789 ModuleList::FindSharedModules (module_spec,module_list);
1790 }
1791 }
1792
Greg Clayton91048ef2011-11-10 01:18:58 +00001793 return module_list.GetSize () - initial_size;
1794}
1795
Greg Claytone1f50b92011-05-03 22:09:39 +00001796#pragma mark CommandObjectTargetModulesModuleAutoComplete
1797
1798//----------------------------------------------------------------------
1799// A base command object class that can auto complete with module file
1800// paths
1801//----------------------------------------------------------------------
1802
Jim Inghamda26bd22012-06-08 21:56:10 +00001803class CommandObjectTargetModulesModuleAutoComplete : public CommandObjectParsed
Greg Claytone1f50b92011-05-03 22:09:39 +00001804{
1805public:
1806
1807 CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter,
1808 const char *name,
1809 const char *help,
1810 const char *syntax) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001811 CommandObjectParsed (interpreter, name, help, syntax)
Greg Claytone1f50b92011-05-03 22:09:39 +00001812 {
1813 CommandArgumentEntry arg;
1814 CommandArgumentData file_arg;
1815
1816 // Define the first (and only) variant of this arg.
1817 file_arg.arg_type = eArgTypeFilename;
1818 file_arg.arg_repetition = eArgRepeatStar;
1819
1820 // There is only one variant this argument could be; put it into the argument entry.
1821 arg.push_back (file_arg);
1822
1823 // Push the data for the first argument into the m_arguments vector.
1824 m_arguments.push_back (arg);
1825 }
1826
1827 virtual
1828 ~CommandObjectTargetModulesModuleAutoComplete ()
1829 {
1830 }
1831
1832 virtual int
1833 HandleArgumentCompletion (Args &input,
1834 int &cursor_index,
1835 int &cursor_char_position,
1836 OptionElementVector &opt_element_vector,
1837 int match_start_point,
1838 int max_return_elements,
1839 bool &word_complete,
1840 StringList &matches)
1841 {
1842 // Arguments are the standard module completer.
1843 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1844 completion_str.erase (cursor_char_position);
1845
1846 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1847 CommandCompletions::eModuleCompletion,
1848 completion_str.c_str(),
1849 match_start_point,
1850 max_return_elements,
1851 NULL,
1852 word_complete,
1853 matches);
1854 return matches.GetSize();
1855 }
1856};
1857
1858#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1859
1860//----------------------------------------------------------------------
1861// A base command object class that can auto complete with module source
1862// file paths
1863//----------------------------------------------------------------------
1864
Jim Inghamda26bd22012-06-08 21:56:10 +00001865class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObjectParsed
Greg Claytone1f50b92011-05-03 22:09:39 +00001866{
1867public:
1868
1869 CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
1870 const char *name,
1871 const char *help,
1872 const char *syntax) :
Jim Inghamda26bd22012-06-08 21:56:10 +00001873 CommandObjectParsed (interpreter, name, help, syntax)
Greg Claytone1f50b92011-05-03 22:09:39 +00001874 {
1875 CommandArgumentEntry arg;
1876 CommandArgumentData source_file_arg;
1877
1878 // Define the first (and only) variant of this arg.
1879 source_file_arg.arg_type = eArgTypeSourceFile;
1880 source_file_arg.arg_repetition = eArgRepeatPlus;
1881
1882 // There is only one variant this argument could be; put it into the argument entry.
1883 arg.push_back (source_file_arg);
1884
1885 // Push the data for the first argument into the m_arguments vector.
1886 m_arguments.push_back (arg);
1887 }
1888
1889 virtual
1890 ~CommandObjectTargetModulesSourceFileAutoComplete ()
1891 {
1892 }
1893
1894 virtual int
1895 HandleArgumentCompletion (Args &input,
1896 int &cursor_index,
1897 int &cursor_char_position,
1898 OptionElementVector &opt_element_vector,
1899 int match_start_point,
1900 int max_return_elements,
1901 bool &word_complete,
1902 StringList &matches)
1903 {
1904 // Arguments are the standard source file completer.
1905 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1906 completion_str.erase (cursor_char_position);
1907
1908 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1909 CommandCompletions::eSourceFileCompletion,
1910 completion_str.c_str(),
1911 match_start_point,
1912 max_return_elements,
1913 NULL,
1914 word_complete,
1915 matches);
1916 return matches.GetSize();
1917 }
1918};
1919
1920
1921#pragma mark CommandObjectTargetModulesDumpSymtab
1922
1923
1924class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
1925{
1926public:
1927 CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
1928 CommandObjectTargetModulesModuleAutoComplete (interpreter,
1929 "target modules dump symtab",
1930 "Dump the symbol table from one or more target modules.",
1931 NULL),
1932 m_options (interpreter)
1933 {
1934 }
1935
1936 virtual
1937 ~CommandObjectTargetModulesDumpSymtab ()
1938 {
1939 }
1940
Jim Inghamda26bd22012-06-08 21:56:10 +00001941 virtual Options *
1942 GetOptions ()
1943 {
1944 return &m_options;
1945 }
1946
1947 class CommandOptions : public Options
1948 {
1949 public:
1950
1951 CommandOptions (CommandInterpreter &interpreter) :
1952 Options(interpreter),
1953 m_sort_order (eSortOrderNone)
1954 {
1955 }
1956
1957 virtual
1958 ~CommandOptions ()
1959 {
1960 }
1961
1962 virtual Error
1963 SetOptionValue (uint32_t option_idx, const char *option_arg)
1964 {
1965 Error error;
1966 char short_option = (char) m_getopt_table[option_idx].val;
1967
1968 switch (short_option)
1969 {
1970 case 's':
1971 m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
1972 g_option_table[option_idx].enum_values,
1973 eSortOrderNone,
1974 error);
1975 break;
1976
1977 default:
1978 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
1979 break;
1980
1981 }
1982 return error;
1983 }
1984
1985 void
1986 OptionParsingStarting ()
1987 {
1988 m_sort_order = eSortOrderNone;
1989 }
1990
1991 const OptionDefinition*
1992 GetDefinitions ()
1993 {
1994 return g_option_table;
1995 }
1996
1997 // Options table: Required for subclasses of Options.
1998 static OptionDefinition g_option_table[];
1999
2000 SortOrder m_sort_order;
2001 };
2002
2003protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00002004 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00002005 DoExecute (Args& command,
Greg Claytone1f50b92011-05-03 22:09:39 +00002006 CommandReturnObject &result)
2007 {
2008 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2009 if (target == NULL)
2010 {
2011 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2012 result.SetStatus (eReturnStatusFailed);
2013 return false;
2014 }
2015 else
2016 {
2017 uint32_t num_dumped = 0;
2018
2019 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2020 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2021 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2022
2023 if (command.GetArgumentCount() == 0)
2024 {
2025 // Dump all sections for all modules images
Jim Ingham93367902012-05-30 02:19:25 +00002026 Mutex::Locker modules_locker(target->GetImages().GetMutex());
Greg Claytone1f50b92011-05-03 22:09:39 +00002027 const uint32_t num_modules = target->GetImages().GetSize();
2028 if (num_modules > 0)
2029 {
2030 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
2031 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2032 {
2033 if (num_dumped > 0)
2034 {
2035 result.GetOutputStream().EOL();
2036 result.GetOutputStream().EOL();
2037 }
2038 num_dumped++;
Jim Ingham93367902012-05-30 02:19:25 +00002039 DumpModuleSymtab (m_interpreter,
2040 result.GetOutputStream(),
2041 target->GetImages().GetModulePointerAtIndexUnlocked(image_idx),
2042 m_options.m_sort_order);
Greg Claytone1f50b92011-05-03 22:09:39 +00002043 }
2044 }
2045 else
2046 {
2047 result.AppendError ("the target has no associated executable images");
2048 result.SetStatus (eReturnStatusFailed);
2049 return false;
2050 }
2051 }
2052 else
2053 {
2054 // Dump specified images (by basename or fullpath)
2055 const char *arg_cstr;
2056 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2057 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002058 ModuleList module_list;
2059 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2060 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00002061 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002062 for (size_t i=0; i<num_matches; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00002063 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002064 Module *module = module_list.GetModulePointerAtIndex(i);
2065 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00002066 {
2067 if (num_dumped > 0)
2068 {
2069 result.GetOutputStream().EOL();
2070 result.GetOutputStream().EOL();
2071 }
2072 num_dumped++;
Greg Clayton91048ef2011-11-10 01:18:58 +00002073 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order);
Greg Claytone1f50b92011-05-03 22:09:39 +00002074 }
2075 }
2076 }
2077 else
2078 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2079 }
2080 }
2081
2082 if (num_dumped > 0)
2083 result.SetStatus (eReturnStatusSuccessFinishResult);
2084 else
2085 {
2086 result.AppendError ("no matching executable images found");
2087 result.SetStatus (eReturnStatusFailed);
2088 }
2089 }
2090 return result.Succeeded();
2091 }
2092
Greg Claytone1f50b92011-05-03 22:09:39 +00002093
2094 CommandOptions m_options;
2095};
2096
2097static OptionEnumValueElement
2098g_sort_option_enumeration[4] =
2099{
2100 { eSortOrderNone, "none", "No sorting, use the original symbol table order."},
2101 { eSortOrderByAddress, "address", "Sort output by symbol address."},
2102 { eSortOrderByName, "name", "Sort output by symbol name."},
2103 { 0, NULL, NULL }
2104};
2105
2106
2107OptionDefinition
2108CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
2109{
2110 { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
2111 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
2112};
2113
2114#pragma mark CommandObjectTargetModulesDumpSections
2115
2116//----------------------------------------------------------------------
2117// Image section dumping command
2118//----------------------------------------------------------------------
2119
2120class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
2121{
2122public:
2123 CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
2124 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2125 "target modules dump sections",
2126 "Dump the sections from one or more target modules.",
2127 //"target modules dump sections [<file1> ...]")
2128 NULL)
2129 {
2130 }
2131
2132 virtual
2133 ~CommandObjectTargetModulesDumpSections ()
2134 {
2135 }
2136
Jim Inghamda26bd22012-06-08 21:56:10 +00002137protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00002138 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00002139 DoExecute (Args& command,
Greg Claytone1f50b92011-05-03 22:09:39 +00002140 CommandReturnObject &result)
2141 {
2142 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2143 if (target == NULL)
2144 {
2145 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2146 result.SetStatus (eReturnStatusFailed);
2147 return false;
2148 }
2149 else
2150 {
2151 uint32_t num_dumped = 0;
2152
2153 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2154 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2155 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2156
2157 if (command.GetArgumentCount() == 0)
2158 {
2159 // Dump all sections for all modules images
2160 const uint32_t num_modules = target->GetImages().GetSize();
2161 if (num_modules > 0)
2162 {
2163 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
2164 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2165 {
2166 num_dumped++;
2167 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
2168 }
2169 }
2170 else
2171 {
2172 result.AppendError ("the target has no associated executable images");
2173 result.SetStatus (eReturnStatusFailed);
2174 return false;
2175 }
2176 }
2177 else
2178 {
2179 // Dump specified images (by basename or fullpath)
2180 const char *arg_cstr;
2181 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2182 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002183 ModuleList module_list;
2184 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2185 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00002186 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002187 for (size_t i=0; i<num_matches; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00002188 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002189 Module *module = module_list.GetModulePointerAtIndex(i);
2190 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00002191 {
2192 num_dumped++;
Greg Clayton91048ef2011-11-10 01:18:58 +00002193 DumpModuleSections (m_interpreter, result.GetOutputStream(), module);
Greg Claytone1f50b92011-05-03 22:09:39 +00002194 }
2195 }
2196 }
2197 else
Greg Clayton91048ef2011-11-10 01:18:58 +00002198 {
2199 // Check the global list
Greg Claytonc149c8b2012-01-27 18:08:35 +00002200 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
Greg Clayton91048ef2011-11-10 01:18:58 +00002201
Greg Claytone1f50b92011-05-03 22:09:39 +00002202 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
Greg Clayton91048ef2011-11-10 01:18:58 +00002203 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002204 }
2205 }
2206
2207 if (num_dumped > 0)
2208 result.SetStatus (eReturnStatusSuccessFinishResult);
2209 else
2210 {
2211 result.AppendError ("no matching executable images found");
2212 result.SetStatus (eReturnStatusFailed);
2213 }
2214 }
2215 return result.Succeeded();
2216 }
2217};
2218
2219
2220#pragma mark CommandObjectTargetModulesDumpSymfile
2221
2222//----------------------------------------------------------------------
2223// Image debug symbol dumping command
2224//----------------------------------------------------------------------
2225
2226class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
2227{
2228public:
2229 CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
2230 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2231 "target modules dump symfile",
2232 "Dump the debug symbol file for one or more target modules.",
2233 //"target modules dump symfile [<file1> ...]")
2234 NULL)
2235 {
2236 }
2237
2238 virtual
2239 ~CommandObjectTargetModulesDumpSymfile ()
2240 {
2241 }
2242
Jim Inghamda26bd22012-06-08 21:56:10 +00002243protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00002244 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00002245 DoExecute (Args& command,
Greg Claytone1f50b92011-05-03 22:09:39 +00002246 CommandReturnObject &result)
2247 {
2248 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2249 if (target == NULL)
2250 {
2251 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2252 result.SetStatus (eReturnStatusFailed);
2253 return false;
2254 }
2255 else
2256 {
2257 uint32_t num_dumped = 0;
2258
2259 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2260 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2261 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2262
2263 if (command.GetArgumentCount() == 0)
2264 {
2265 // Dump all sections for all modules images
Jim Ingham93367902012-05-30 02:19:25 +00002266 ModuleList &target_modules = target->GetImages();
2267 Mutex::Locker modules_locker (target_modules.GetMutex());
2268 const uint32_t num_modules = target_modules.GetSize();
Greg Claytone1f50b92011-05-03 22:09:39 +00002269 if (num_modules > 0)
2270 {
2271 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
2272 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2273 {
Jim Ingham93367902012-05-30 02:19:25 +00002274 if (DumpModuleSymbolVendor (result.GetOutputStream(), target_modules.GetModulePointerAtIndexUnlocked(image_idx)))
Greg Claytone1f50b92011-05-03 22:09:39 +00002275 num_dumped++;
2276 }
2277 }
2278 else
2279 {
2280 result.AppendError ("the target has no associated executable images");
2281 result.SetStatus (eReturnStatusFailed);
2282 return false;
2283 }
2284 }
2285 else
2286 {
2287 // Dump specified images (by basename or fullpath)
2288 const char *arg_cstr;
2289 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2290 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002291 ModuleList module_list;
2292 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2293 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00002294 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002295 for (size_t i=0; i<num_matches; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00002296 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002297 Module *module = module_list.GetModulePointerAtIndex(i);
2298 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00002299 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002300 if (DumpModuleSymbolVendor (result.GetOutputStream(), module))
Greg Claytone1f50b92011-05-03 22:09:39 +00002301 num_dumped++;
2302 }
2303 }
2304 }
2305 else
2306 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2307 }
2308 }
2309
2310 if (num_dumped > 0)
2311 result.SetStatus (eReturnStatusSuccessFinishResult);
2312 else
2313 {
2314 result.AppendError ("no matching executable images found");
2315 result.SetStatus (eReturnStatusFailed);
2316 }
2317 }
2318 return result.Succeeded();
2319 }
2320};
2321
2322
2323#pragma mark CommandObjectTargetModulesDumpLineTable
2324
2325//----------------------------------------------------------------------
2326// Image debug line table dumping command
2327//----------------------------------------------------------------------
2328
2329class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
2330{
2331public:
2332 CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
2333 CommandObjectTargetModulesSourceFileAutoComplete (interpreter,
2334 "target modules dump line-table",
2335 "Dump the debug symbol file for one or more target modules.",
2336 NULL)
2337 {
2338 }
2339
2340 virtual
2341 ~CommandObjectTargetModulesDumpLineTable ()
2342 {
2343 }
2344
Jim Inghamda26bd22012-06-08 21:56:10 +00002345protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00002346 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00002347 DoExecute (Args& command,
Greg Claytone1f50b92011-05-03 22:09:39 +00002348 CommandReturnObject &result)
2349 {
2350 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2351 if (target == NULL)
2352 {
2353 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2354 result.SetStatus (eReturnStatusFailed);
2355 return false;
2356 }
2357 else
2358 {
2359 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
2360 uint32_t total_num_dumped = 0;
2361
2362 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2363 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2364 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2365
2366 if (command.GetArgumentCount() == 0)
2367 {
2368 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
2369 result.SetStatus (eReturnStatusFailed);
2370 }
2371 else
2372 {
2373 // Dump specified images (by basename or fullpath)
2374 const char *arg_cstr;
2375 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2376 {
2377 FileSpec file_spec(arg_cstr, false);
Jim Ingham93367902012-05-30 02:19:25 +00002378
2379 ModuleList &target_modules = target->GetImages();
2380 Mutex::Locker modules_locker(target_modules.GetMutex());
2381 const uint32_t num_modules = target_modules.GetSize();
Greg Claytone1f50b92011-05-03 22:09:39 +00002382 if (num_modules > 0)
2383 {
2384 uint32_t num_dumped = 0;
2385 for (uint32_t i = 0; i<num_modules; ++i)
2386 {
2387 if (DumpCompileUnitLineTable (m_interpreter,
2388 result.GetOutputStream(),
Jim Ingham93367902012-05-30 02:19:25 +00002389 target_modules.GetModulePointerAtIndexUnlocked(i),
Greg Claytone1f50b92011-05-03 22:09:39 +00002390 file_spec,
Greg Clayton567e7f32011-09-22 04:58:26 +00002391 exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive()))
Greg Claytone1f50b92011-05-03 22:09:39 +00002392 num_dumped++;
2393 }
2394 if (num_dumped == 0)
2395 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
2396 else
2397 total_num_dumped += num_dumped;
2398 }
2399 }
2400 }
2401
2402 if (total_num_dumped > 0)
2403 result.SetStatus (eReturnStatusSuccessFinishResult);
2404 else
2405 {
2406 result.AppendError ("no source filenames matched any command arguments");
2407 result.SetStatus (eReturnStatusFailed);
2408 }
2409 }
2410 return result.Succeeded();
2411 }
2412};
2413
2414
2415#pragma mark CommandObjectTargetModulesDump
2416
2417//----------------------------------------------------------------------
2418// Dump multi-word command for target modules
2419//----------------------------------------------------------------------
2420
2421class CommandObjectTargetModulesDump : public CommandObjectMultiword
2422{
2423public:
2424
2425 //------------------------------------------------------------------
2426 // Constructors and Destructors
2427 //------------------------------------------------------------------
2428 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) :
2429 CommandObjectMultiword (interpreter,
2430 "target modules dump",
2431 "A set of commands for dumping information about one or more target modules.",
2432 "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
2433 {
2434 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
2435 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
2436 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
2437 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
2438 }
2439
2440 virtual
2441 ~CommandObjectTargetModulesDump()
2442 {
2443 }
2444};
2445
Jim Inghamda26bd22012-06-08 21:56:10 +00002446class CommandObjectTargetModulesAdd : public CommandObjectParsed
Greg Claytone1f50b92011-05-03 22:09:39 +00002447{
2448public:
2449 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00002450 CommandObjectParsed (interpreter,
2451 "target modules add",
2452 "Add a new module to the current target's modules.",
2453 "target modules add [<module>]")
Greg Claytone1f50b92011-05-03 22:09:39 +00002454 {
2455 }
2456
2457 virtual
2458 ~CommandObjectTargetModulesAdd ()
2459 {
2460 }
2461
Jim Inghamda26bd22012-06-08 21:56:10 +00002462 int
2463 HandleArgumentCompletion (Args &input,
2464 int &cursor_index,
2465 int &cursor_char_position,
2466 OptionElementVector &opt_element_vector,
2467 int match_start_point,
2468 int max_return_elements,
2469 bool &word_complete,
2470 StringList &matches)
2471 {
2472 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2473 completion_str.erase (cursor_char_position);
2474
2475 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2476 CommandCompletions::eDiskFileCompletion,
2477 completion_str.c_str(),
2478 match_start_point,
2479 max_return_elements,
2480 NULL,
2481 word_complete,
2482 matches);
2483 return matches.GetSize();
2484 }
2485
2486protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00002487 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00002488 DoExecute (Args& args,
Greg Claytone1f50b92011-05-03 22:09:39 +00002489 CommandReturnObject &result)
2490 {
2491 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2492 if (target == NULL)
2493 {
2494 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2495 result.SetStatus (eReturnStatusFailed);
2496 return false;
2497 }
2498 else
2499 {
2500 const size_t argc = args.GetArgumentCount();
2501 if (argc == 0)
2502 {
2503 result.AppendError ("one or more executable image paths must be specified");
2504 result.SetStatus (eReturnStatusFailed);
2505 return false;
2506 }
2507 else
2508 {
2509 for (size_t i=0; i<argc; ++i)
2510 {
2511 const char *path = args.GetArgumentAtIndex(i);
2512 if (path)
2513 {
2514 FileSpec file_spec(path, true);
Greg Claytone1f50b92011-05-03 22:09:39 +00002515 if (file_spec.Exists())
2516 {
Greg Clayton444fe992012-02-26 05:51:37 +00002517 ModuleSpec module_spec (file_spec);
2518 ModuleSP module_sp (target->GetSharedModule (module_spec));
Greg Claytone1f50b92011-05-03 22:09:39 +00002519 if (!module_sp)
2520 {
2521 result.AppendError ("one or more executable image paths must be specified");
2522 result.SetStatus (eReturnStatusFailed);
2523 return false;
2524 }
Jason Molenda36f6fb92011-08-02 23:28:55 +00002525 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytone1f50b92011-05-03 22:09:39 +00002526 }
2527 else
2528 {
2529 char resolved_path[PATH_MAX];
2530 result.SetStatus (eReturnStatusFailed);
2531 if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
2532 {
2533 if (strcmp (resolved_path, path) != 0)
2534 {
2535 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
2536 break;
2537 }
2538 }
2539 result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
2540 break;
2541 }
2542 }
2543 }
2544 }
2545 }
2546 return result.Succeeded();
2547 }
2548
Greg Claytone1f50b92011-05-03 22:09:39 +00002549};
2550
2551class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
2552{
2553public:
2554 CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) :
2555 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2556 "target modules load",
2557 "Set the load addresses for one or more sections in a target module.",
2558 "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
2559 m_option_group (interpreter),
2560 m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "Fullpath or basename for module to load."),
2561 m_slide_option(LLDB_OPT_SET_1, false, "slide", 's', 0, eArgTypeOffset, "Set the load address for all sections to be the virtual address in the file plus the offset.", 0)
2562 {
2563 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2564 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2565 m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2566 m_option_group.Finalize();
2567 }
2568
2569 virtual
2570 ~CommandObjectTargetModulesLoad ()
2571 {
2572 }
2573
Jim Inghamda26bd22012-06-08 21:56:10 +00002574 virtual Options *
2575 GetOptions ()
2576 {
2577 return &m_option_group;
2578 }
2579
2580protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00002581 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00002582 DoExecute (Args& args,
Greg Claytone1f50b92011-05-03 22:09:39 +00002583 CommandReturnObject &result)
2584 {
2585 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2586 if (target == NULL)
2587 {
2588 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2589 result.SetStatus (eReturnStatusFailed);
2590 return false;
2591 }
2592 else
2593 {
2594 const size_t argc = args.GetArgumentCount();
Greg Clayton444fe992012-02-26 05:51:37 +00002595 ModuleSpec module_spec;
2596 bool search_using_module_spec = false;
Greg Claytone1f50b92011-05-03 22:09:39 +00002597 if (m_file_option.GetOptionValue().OptionWasSet())
Greg Clayton444fe992012-02-26 05:51:37 +00002598 {
2599 search_using_module_spec = true;
2600 module_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
2601 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002602
2603 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
Greg Clayton444fe992012-02-26 05:51:37 +00002604 {
2605 search_using_module_spec = true;
2606 module_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
2607 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002608
Greg Clayton444fe992012-02-26 05:51:37 +00002609 if (search_using_module_spec)
Greg Claytone1f50b92011-05-03 22:09:39 +00002610 {
2611
2612 ModuleList matching_modules;
Greg Clayton444fe992012-02-26 05:51:37 +00002613 const size_t num_matches = target->GetImages().FindModules (module_spec, matching_modules);
Greg Claytone1f50b92011-05-03 22:09:39 +00002614
2615 char path[PATH_MAX];
2616 if (num_matches == 1)
2617 {
2618 Module *module = matching_modules.GetModulePointerAtIndex(0);
2619 if (module)
2620 {
2621 ObjectFile *objfile = module->GetObjectFile();
2622 if (objfile)
2623 {
2624 SectionList *section_list = objfile->GetSectionList();
2625 if (section_list)
2626 {
Greg Clayton9ab696e2012-03-27 21:10:07 +00002627 bool changed = false;
Greg Claytone1f50b92011-05-03 22:09:39 +00002628 if (argc == 0)
2629 {
2630 if (m_slide_option.GetOptionValue().OptionWasSet())
2631 {
Greg Clayton9ab696e2012-03-27 21:10:07 +00002632 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
2633 module->SetLoadAddress (*target, slide, changed);
Greg Claytone1f50b92011-05-03 22:09:39 +00002634 }
2635 else
2636 {
2637 result.AppendError ("one or more section name + load address pair must be specified");
2638 result.SetStatus (eReturnStatusFailed);
2639 return false;
2640 }
2641 }
2642 else
2643 {
2644 if (m_slide_option.GetOptionValue().OptionWasSet())
2645 {
2646 result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
2647 result.SetStatus (eReturnStatusFailed);
2648 return false;
2649 }
2650
2651 for (size_t i=0; i<argc; i += 2)
2652 {
2653 const char *sect_name = args.GetArgumentAtIndex(i);
2654 const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
2655 if (sect_name && load_addr_cstr)
2656 {
2657 ConstString const_sect_name(sect_name);
2658 bool success = false;
2659 addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2660 if (success)
2661 {
2662 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
2663 if (section_sp)
2664 {
Greg Clayton9ab696e2012-03-27 21:10:07 +00002665 if (section_sp->IsThreadSpecific())
2666 {
2667 result.AppendErrorWithFormat ("thread specific sections are not yet supported (section '%s')\n", sect_name);
2668 result.SetStatus (eReturnStatusFailed);
2669 break;
2670 }
2671 else
2672 {
Greg Clayton545762f2012-07-07 01:24:12 +00002673 if (target->GetSectionLoadList().SetSectionLoadAddress (section_sp, load_addr))
Greg Clayton9ab696e2012-03-27 21:10:07 +00002674 changed = true;
2675 result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr);
2676 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002677 }
2678 else
2679 {
2680 result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
2681 result.SetStatus (eReturnStatusFailed);
2682 break;
2683 }
2684 }
2685 else
2686 {
2687 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
2688 result.SetStatus (eReturnStatusFailed);
2689 break;
2690 }
2691 }
2692 else
2693 {
2694 if (sect_name)
2695 result.AppendError ("section names must be followed by a load address.\n");
2696 else
2697 result.AppendError ("one or more section name + load address pair must be specified.\n");
2698 result.SetStatus (eReturnStatusFailed);
2699 break;
2700 }
2701 }
2702 }
Greg Clayton9ab696e2012-03-27 21:10:07 +00002703
2704 if (changed)
2705 target->ModulesDidLoad (matching_modules);
Greg Claytone1f50b92011-05-03 22:09:39 +00002706 }
2707 else
2708 {
2709 module->GetFileSpec().GetPath (path, sizeof(path));
2710 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
2711 result.SetStatus (eReturnStatusFailed);
2712 }
2713 }
2714 else
2715 {
2716 module->GetFileSpec().GetPath (path, sizeof(path));
2717 result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
2718 result.SetStatus (eReturnStatusFailed);
2719 }
2720 }
2721 else
2722 {
Jim Ingham6f01c932012-10-12 17:34:26 +00002723 FileSpec *module_spec_file = module_spec.GetFileSpecPtr();
2724 if (module_spec_file)
2725 {
2726 module_spec_file->GetPath (path, sizeof(path));
2727 result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
2728 }
2729 else
2730 result.AppendError ("no module spec");
Greg Claytone1f50b92011-05-03 22:09:39 +00002731 result.SetStatus (eReturnStatusFailed);
2732 }
2733 }
2734 else
2735 {
2736 char uuid_cstr[64];
Greg Clayton444fe992012-02-26 05:51:37 +00002737
2738 if (module_spec.GetFileSpec())
2739 module_spec.GetFileSpec().GetPath (path, sizeof(path));
Greg Claytone1f50b92011-05-03 22:09:39 +00002740 else
2741 path[0] = '\0';
2742
Greg Clayton444fe992012-02-26 05:51:37 +00002743 if (module_spec.GetUUIDPtr())
2744 module_spec.GetUUID().GetAsCString(uuid_cstr, sizeof(uuid_cstr));
Greg Claytone1f50b92011-05-03 22:09:39 +00002745 else
2746 uuid_cstr[0] = '\0';
2747 if (num_matches > 1)
2748 {
2749 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
2750 path[0] ? " file=" : "",
2751 path,
2752 uuid_cstr[0] ? " uuid=" : "",
2753 uuid_cstr);
2754 for (size_t i=0; i<num_matches; ++i)
2755 {
2756 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
2757 result.AppendMessageWithFormat("%s\n", path);
2758 }
2759 }
2760 else
2761 {
2762 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n",
2763 path[0] ? " file=" : "",
2764 path,
2765 uuid_cstr[0] ? " uuid=" : "",
2766 uuid_cstr);
2767 }
2768 result.SetStatus (eReturnStatusFailed);
2769 }
2770 }
2771 else
2772 {
2773 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
2774 result.SetStatus (eReturnStatusFailed);
2775 return false;
2776 }
2777 }
2778 return result.Succeeded();
2779 }
2780
Greg Claytone1f50b92011-05-03 22:09:39 +00002781 OptionGroupOptions m_option_group;
2782 OptionGroupUUID m_uuid_option_group;
2783 OptionGroupFile m_file_option;
2784 OptionGroupUInt64 m_slide_option;
2785};
2786
2787//----------------------------------------------------------------------
2788// List images with associated information
2789//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +00002790class CommandObjectTargetModulesList : public CommandObjectParsed
Greg Claytone1f50b92011-05-03 22:09:39 +00002791{
2792public:
2793
2794 class CommandOptions : public Options
2795 {
2796 public:
2797
2798 CommandOptions (CommandInterpreter &interpreter) :
Greg Clayton899025f2011-08-09 00:01:09 +00002799 Options(interpreter),
Jim Ingham6bdea822011-10-24 18:36:33 +00002800 m_format_array(),
Daniel Dunbar97c89572011-10-31 22:50:49 +00002801 m_use_global_module_list (false),
Jim Ingham6bdea822011-10-24 18:36:33 +00002802 m_module_addr (LLDB_INVALID_ADDRESS)
Greg Claytone1f50b92011-05-03 22:09:39 +00002803 {
2804 }
2805
2806 virtual
2807 ~CommandOptions ()
2808 {
2809 }
2810
2811 virtual Error
2812 SetOptionValue (uint32_t option_idx, const char *option_arg)
2813 {
2814 char short_option = (char) m_getopt_table[option_idx].val;
Greg Clayton899025f2011-08-09 00:01:09 +00002815 if (short_option == 'g')
2816 {
2817 m_use_global_module_list = true;
2818 }
Jim Ingham6bdea822011-10-24 18:36:33 +00002819 else if (short_option == 'a')
2820 {
2821 bool success;
2822 m_module_addr = Args::StringToAddress(option_arg, LLDB_INVALID_ADDRESS, &success);
2823 if (!success)
2824 {
2825 Error error;
Greg Clayton9c236732011-10-26 00:56:27 +00002826 error.SetErrorStringWithFormat("invalid address: \"%s\"", option_arg);
Jim Ingham6bdea822011-10-24 18:36:33 +00002827 }
2828 }
Greg Clayton899025f2011-08-09 00:01:09 +00002829 else
2830 {
2831 uint32_t width = 0;
2832 if (option_arg)
2833 width = strtoul (option_arg, NULL, 0);
2834 m_format_array.push_back(std::make_pair(short_option, width));
2835 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002836 Error error;
2837 return error;
2838 }
2839
2840 void
2841 OptionParsingStarting ()
2842 {
2843 m_format_array.clear();
Greg Clayton899025f2011-08-09 00:01:09 +00002844 m_use_global_module_list = false;
Jim Ingham6bdea822011-10-24 18:36:33 +00002845 m_module_addr = LLDB_INVALID_ADDRESS;
Greg Claytone1f50b92011-05-03 22:09:39 +00002846 }
2847
2848 const OptionDefinition*
2849 GetDefinitions ()
2850 {
2851 return g_option_table;
2852 }
2853
2854 // Options table: Required for subclasses of Options.
2855
2856 static OptionDefinition g_option_table[];
2857
2858 // Instance variables to hold the values for command options.
2859 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
2860 FormatWidthCollection m_format_array;
Greg Clayton899025f2011-08-09 00:01:09 +00002861 bool m_use_global_module_list;
Jim Ingham6bdea822011-10-24 18:36:33 +00002862 lldb::addr_t m_module_addr;
Greg Claytone1f50b92011-05-03 22:09:39 +00002863 };
2864
2865 CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00002866 CommandObjectParsed (interpreter,
2867 "target modules list",
2868 "List current executable and dependent shared library images.",
2869 "target modules list [<cmd-options>]"),
Greg Claytone1f50b92011-05-03 22:09:39 +00002870 m_options (interpreter)
2871 {
2872 }
2873
2874 virtual
2875 ~CommandObjectTargetModulesList ()
2876 {
2877 }
2878
2879 virtual
2880 Options *
2881 GetOptions ()
2882 {
2883 return &m_options;
2884 }
2885
Jim Inghamda26bd22012-06-08 21:56:10 +00002886protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00002887 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00002888 DoExecute (Args& command,
Greg Claytone1f50b92011-05-03 22:09:39 +00002889 CommandReturnObject &result)
2890 {
2891 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Clayton153ccd72011-08-10 02:10:13 +00002892 const bool use_global_module_list = m_options.m_use_global_module_list;
Greg Clayton11fb9212012-06-27 20:26:19 +00002893 // Define a local module list here to ensure it lives longer than any "locker"
2894 // object which might lock its contents below (through the "module_list_ptr"
2895 // variable).
2896 ModuleList module_list;
Greg Clayton153ccd72011-08-10 02:10:13 +00002897 if (target == NULL && use_global_module_list == false)
Greg Claytone1f50b92011-05-03 22:09:39 +00002898 {
2899 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2900 result.SetStatus (eReturnStatusFailed);
2901 return false;
2902 }
2903 else
2904 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002905 if (target)
2906 {
2907 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2908 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2909 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2910 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002911 // Dump all sections for all modules images
Jim Ingham6bdea822011-10-24 18:36:33 +00002912 Stream &strm = result.GetOutputStream();
2913
2914 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS)
2915 {
2916 if (target)
2917 {
2918 Address module_address;
2919 if (module_address.SetLoadAddress(m_options.m_module_addr, target))
2920 {
Greg Clayton3508c382012-02-24 01:59:29 +00002921 ModuleSP module_sp (module_address.GetModule());
2922 if (module_sp)
Jim Ingham6bdea822011-10-24 18:36:33 +00002923 {
Greg Clayton3508c382012-02-24 01:59:29 +00002924 PrintModule (target, module_sp.get(), UINT32_MAX, 0, strm);
Jim Ingham6bdea822011-10-24 18:36:33 +00002925 result.SetStatus (eReturnStatusSuccessFinishResult);
2926 }
2927 else
2928 {
2929 result.AppendError ("Couldn't find module matching address: 0x%llx.", m_options.m_module_addr);
2930 result.SetStatus (eReturnStatusFailed);
2931 }
2932 }
2933 else
2934 {
2935 result.AppendError ("Couldn't find module containing address: 0x%llx.", m_options.m_module_addr);
2936 result.SetStatus (eReturnStatusFailed);
2937 }
2938 }
2939 else
2940 {
2941 result.AppendError ("Can only look up modules by address with a valid target.");
2942 result.SetStatus (eReturnStatusFailed);
2943 }
2944 return result.Succeeded();
2945 }
2946
Jim Ingham93367902012-05-30 02:19:25 +00002947 uint32_t num_modules = 0;
2948 Mutex::Locker locker; // This locker will be locked on the mutex in module_list_ptr if it is non-NULL.
2949 // Otherwise it will lock the AllocationModuleCollectionMutex when accessing
2950 // the global module list directly.
Greg Clayton2ad894b2012-05-15 18:43:44 +00002951 ModuleList *module_list_ptr = NULL;
2952 const size_t argc = command.GetArgumentCount();
2953 if (argc == 0)
Greg Clayton899025f2011-08-09 00:01:09 +00002954 {
Greg Clayton2ad894b2012-05-15 18:43:44 +00002955 if (use_global_module_list)
2956 {
2957 locker.Lock (Module::GetAllocationModuleCollectionMutex());
2958 num_modules = Module::GetNumberAllocatedModules();
2959 }
2960 else
2961 {
2962 module_list_ptr = &target->GetImages();
Greg Clayton2ad894b2012-05-15 18:43:44 +00002963 }
Greg Clayton899025f2011-08-09 00:01:09 +00002964 }
2965 else
Greg Clayton2ad894b2012-05-15 18:43:44 +00002966 {
2967 for (size_t i=0; i<argc; ++i)
2968 {
2969 // Dump specified images (by basename or fullpath)
2970 const char *arg_cstr = command.GetArgumentAtIndex(i);
2971 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, use_global_module_list);
2972 if (num_matches == 0)
2973 {
2974 if (argc == 1)
2975 {
2976 result.AppendErrorWithFormat ("no modules found that match '%s'", arg_cstr);
2977 result.SetStatus (eReturnStatusFailed);
2978 return false;
2979 }
2980 }
2981 }
2982
Greg Clayton2ad894b2012-05-15 18:43:44 +00002983 module_list_ptr = &module_list;
2984 }
Jim Ingham93367902012-05-30 02:19:25 +00002985
2986 if (module_list_ptr != NULL)
2987 {
2988 locker.Lock(module_list_ptr->GetMutex());
2989 num_modules = module_list_ptr->GetSize();
2990 }
Greg Clayton899025f2011-08-09 00:01:09 +00002991
Greg Claytone1f50b92011-05-03 22:09:39 +00002992 if (num_modules > 0)
Jim Ingham6bdea822011-10-24 18:36:33 +00002993 {
Greg Claytone1f50b92011-05-03 22:09:39 +00002994 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2995 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002996 ModuleSP module_sp;
Greg Clayton899025f2011-08-09 00:01:09 +00002997 Module *module;
Greg Clayton2ad894b2012-05-15 18:43:44 +00002998 if (module_list_ptr)
Greg Clayton899025f2011-08-09 00:01:09 +00002999 {
Jim Ingham93367902012-05-30 02:19:25 +00003000 module_sp = module_list_ptr->GetModuleAtIndexUnlocked(image_idx);
Greg Clayton2ad894b2012-05-15 18:43:44 +00003001 module = module_sp.get();
Greg Clayton899025f2011-08-09 00:01:09 +00003002 }
3003 else
3004 {
Greg Clayton2ad894b2012-05-15 18:43:44 +00003005 module = Module::GetAllocatedModuleAtIndex(image_idx);
3006 module_sp = module->shared_from_this();
Greg Clayton899025f2011-08-09 00:01:09 +00003007 }
Jim Ingham6bdea822011-10-24 18:36:33 +00003008
Greg Claytonb5a8f142012-02-05 02:38:54 +00003009 int indent = strm.Printf("[%3u] ", image_idx);
3010 PrintModule (target, module, image_idx, indent, strm);
Greg Clayton153ccd72011-08-10 02:10:13 +00003011
Greg Claytone1f50b92011-05-03 22:09:39 +00003012 }
3013 result.SetStatus (eReturnStatusSuccessFinishResult);
3014 }
3015 else
3016 {
Greg Clayton2ad894b2012-05-15 18:43:44 +00003017 if (argc)
3018 {
3019 if (use_global_module_list)
3020 result.AppendError ("the global module list has no matching modules");
3021 else
3022 result.AppendError ("the target has no matching modules");
3023 }
Greg Clayton153ccd72011-08-10 02:10:13 +00003024 else
Greg Clayton2ad894b2012-05-15 18:43:44 +00003025 {
3026 if (use_global_module_list)
3027 result.AppendError ("the global module list is empty");
3028 else
3029 result.AppendError ("the target has no associated executable images");
3030 }
Greg Claytone1f50b92011-05-03 22:09:39 +00003031 result.SetStatus (eReturnStatusFailed);
3032 return false;
3033 }
3034 }
3035 return result.Succeeded();
3036 }
Jim Ingham6bdea822011-10-24 18:36:33 +00003037
3038 void
Greg Claytonb5a8f142012-02-05 02:38:54 +00003039 PrintModule (Target *target, Module *module, uint32_t idx, int indent, Stream &strm)
Jim Ingham6bdea822011-10-24 18:36:33 +00003040 {
3041
Jim Ingham6f01c932012-10-12 17:34:26 +00003042 if (module == NULL)
3043 {
3044 strm.PutCString("Null module");
3045 return;
3046 }
3047
Jim Ingham6bdea822011-10-24 18:36:33 +00003048 bool dump_object_name = false;
3049 if (m_options.m_format_array.empty())
3050 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00003051 m_options.m_format_array.push_back(std::make_pair('u', 0));
3052 m_options.m_format_array.push_back(std::make_pair('h', 0));
3053 m_options.m_format_array.push_back(std::make_pair('f', 0));
3054 m_options.m_format_array.push_back(std::make_pair('S', 0));
Jim Ingham6bdea822011-10-24 18:36:33 +00003055 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00003056 const size_t num_entries = m_options.m_format_array.size();
3057 bool print_space = false;
3058 for (size_t i=0; i<num_entries; ++i)
Jim Ingham6bdea822011-10-24 18:36:33 +00003059 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00003060 if (print_space)
3061 strm.PutChar(' ');
3062 print_space = true;
3063 const char format_char = m_options.m_format_array[i].first;
3064 uint32_t width = m_options.m_format_array[i].second;
3065 switch (format_char)
Jim Ingham6bdea822011-10-24 18:36:33 +00003066 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00003067 case 'A':
3068 DumpModuleArchitecture (strm, module, false, width);
3069 break;
3070
3071 case 't':
3072 DumpModuleArchitecture (strm, module, true, width);
3073 break;
3074
3075 case 'f':
3076 DumpFullpath (strm, &module->GetFileSpec(), width);
3077 dump_object_name = true;
3078 break;
3079
3080 case 'd':
3081 DumpDirectory (strm, &module->GetFileSpec(), width);
3082 break;
3083
3084 case 'b':
3085 DumpBasename (strm, &module->GetFileSpec(), width);
3086 dump_object_name = true;
3087 break;
3088
3089 case 'h':
3090 case 'o':
3091 // Image header address
3092 {
3093 uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16;
Jim Ingham6bdea822011-10-24 18:36:33 +00003094
Greg Claytonb5a8f142012-02-05 02:38:54 +00003095 ObjectFile *objfile = module->GetObjectFile ();
3096 if (objfile)
Jim Ingham6bdea822011-10-24 18:36:33 +00003097 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00003098 Address header_addr(objfile->GetHeaderAddress());
3099 if (header_addr.IsValid())
Jim Ingham6bdea822011-10-24 18:36:33 +00003100 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00003101 if (target && !target->GetSectionLoadList().IsEmpty())
Jim Ingham6bdea822011-10-24 18:36:33 +00003102 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00003103 lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target);
3104 if (header_load_addr == LLDB_INVALID_ADDRESS)
3105 {
3106 header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress);
3107 }
Jim Ingham6bdea822011-10-24 18:36:33 +00003108 else
Greg Claytonb5a8f142012-02-05 02:38:54 +00003109 {
3110 if (format_char == 'o')
3111 {
3112 // Show the offset of slide for the image
3113 strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
3114 }
3115 else
3116 {
3117 // Show the load address of the image
3118 strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr);
3119 }
3120 }
Jim Ingham6bdea822011-10-24 18:36:33 +00003121 break;
3122 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00003123 // The address was valid, but the image isn't loaded, output the address in an appropriate format
3124 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress);
3125 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00003126 }
Jim Ingham6bdea822011-10-24 18:36:33 +00003127 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00003128 strm.Printf ("%*s", addr_nibble_width + 2, "");
3129 }
3130 break;
3131 case 'r':
3132 {
3133 uint32_t ref_count = 0;
3134 ModuleSP module_sp (module->shared_from_this());
3135 if (module_sp)
3136 {
3137 // Take one away to make sure we don't count our local "module_sp"
3138 ref_count = module_sp.use_count() - 1;
3139 }
3140 if (width)
3141 strm.Printf("{%*u}", width, ref_count);
3142 else
3143 strm.Printf("{%u}", ref_count);
3144 }
3145 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00003146
Greg Claytonb5a8f142012-02-05 02:38:54 +00003147 case 's':
3148 case 'S':
3149 {
3150 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
3151 if (symbol_vendor)
3152 {
3153 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
3154 if (symbol_file)
3155 {
3156 if (format_char == 'S')
3157 {
3158 FileSpec &symfile_spec = symbol_file->GetObjectFile()->GetFileSpec();
3159 // Dump symbol file only if different from module file
3160 if (!symfile_spec || symfile_spec == module->GetFileSpec())
3161 {
3162 print_space = false;
3163 break;
3164 }
3165 // Add a newline and indent past the index
3166 strm.Printf ("\n%*s", indent, "");
3167 }
3168 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
3169 dump_object_name = true;
3170 break;
3171 }
3172 }
3173 strm.Printf("%.*s", width, "<NONE>");
3174 }
3175 break;
3176
3177 case 'm':
3178 module->GetModificationTime().Dump(&strm, width);
3179 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00003180
Greg Claytonb5a8f142012-02-05 02:38:54 +00003181 case 'p':
3182 strm.Printf("%p", module);
3183 break;
3184
3185 case 'u':
3186 DumpModuleUUID(strm, module);
3187 break;
3188
3189 default:
3190 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00003191 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00003192
3193 }
3194 if (dump_object_name)
3195 {
3196 const char *object_name = module->GetObjectName().GetCString();
3197 if (object_name)
3198 strm.Printf ("(%s)", object_name);
Jim Ingham6bdea822011-10-24 18:36:33 +00003199 }
3200 strm.EOL();
3201 }
3202
Greg Claytone1f50b92011-05-03 22:09:39 +00003203 CommandOptions m_options;
3204};
3205
3206OptionDefinition
3207CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
3208{
Jim Ingham6bdea822011-10-24 18:36:33 +00003209 { LLDB_OPT_SET_1, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Display the image at this address."},
3210 { LLDB_OPT_SET_1, false, "arch", 'A', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."},
Greg Claytone1f50b92011-05-03 22:09:39 +00003211 { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."},
Greg Claytonb5a8f142012-02-05 02:38:54 +00003212 { LLDB_OPT_SET_1, false, "header", 'h', no_argument, NULL, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise."},
3213 { LLDB_OPT_SET_1, false, "offset", 'o', no_argument, NULL, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)."},
Greg Claytone1f50b92011-05-03 22:09:39 +00003214 { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."},
3215 { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
3216 { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
3217 { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
3218 { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
Greg Claytonb5a8f142012-02-05 02:38:54 +00003219 { LLDB_OPT_SET_1, false, "symfile-unique", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file."},
Greg Clayton153ccd72011-08-10 02:10:13 +00003220 { LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."},
3221 { LLDB_OPT_SET_1, false, "ref-count", 'r', optional_argument, NULL, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache."},
3222 { LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."},
Greg Clayton899025f2011-08-09 00:01:09 +00003223 { LLDB_OPT_SET_1, false, "global", 'g', no_argument, NULL, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target."},
Greg Claytone1f50b92011-05-03 22:09:39 +00003224 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3225};
3226
Jason Molenda5b0afcc2012-07-12 00:20:07 +00003227#pragma mark CommandObjectTargetModulesShowUnwind
Greg Claytone1f50b92011-05-03 22:09:39 +00003228
Jason Molenda5b0afcc2012-07-12 00:20:07 +00003229//----------------------------------------------------------------------
3230// Lookup unwind information in images
3231//----------------------------------------------------------------------
3232
3233class CommandObjectTargetModulesShowUnwind : public CommandObjectParsed
3234{
3235public:
3236
3237 enum
3238 {
3239 eLookupTypeInvalid = -1,
3240 eLookupTypeAddress = 0,
3241 eLookupTypeSymbol,
3242 eLookupTypeFunction,
3243 eLookupTypeFunctionOrSymbol,
3244 kNumLookupTypes
3245 };
3246
3247 class CommandOptions : public Options
3248 {
3249 public:
3250
3251 CommandOptions (CommandInterpreter &interpreter) :
3252 Options(interpreter),
3253 m_type(eLookupTypeInvalid),
3254 m_str(),
3255 m_addr(LLDB_INVALID_ADDRESS)
3256 {
3257 }
3258
3259 virtual
3260 ~CommandOptions ()
3261 {
3262 }
3263
3264 virtual Error
3265 SetOptionValue (uint32_t option_idx, const char *option_arg)
3266 {
3267 Error error;
3268
3269 char short_option = (char) m_getopt_table[option_idx].val;
3270
3271 switch (short_option)
3272 {
3273 case 'a':
3274 m_type = eLookupTypeAddress;
3275 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3276 if (m_addr == LLDB_INVALID_ADDRESS)
3277 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
3278 break;
3279
3280 case 'n':
3281 m_str = option_arg;
3282 m_type = eLookupTypeFunctionOrSymbol;
3283 break;
3284 }
3285
3286 return error;
3287 }
3288
3289 void
3290 OptionParsingStarting ()
3291 {
3292 m_type = eLookupTypeInvalid;
3293 m_str.clear();
3294 m_addr = LLDB_INVALID_ADDRESS;
3295 }
3296
3297 const OptionDefinition*
3298 GetDefinitions ()
3299 {
3300 return g_option_table;
3301 }
3302
3303 // Options table: Required for subclasses of Options.
3304
3305 static OptionDefinition g_option_table[];
3306
3307 // Instance variables to hold the values for command options.
3308
3309 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3310 std::string m_str; // Holds name lookup
3311 lldb::addr_t m_addr; // Holds the address to lookup
3312 };
3313
3314 CommandObjectTargetModulesShowUnwind (CommandInterpreter &interpreter) :
3315 CommandObjectParsed (interpreter,
3316 "target modules show-unwind",
3317 "Show synthesized unwind instructions for a function.",
3318 NULL),
3319 m_options (interpreter)
3320 {
3321 }
3322
3323 virtual
3324 ~CommandObjectTargetModulesShowUnwind ()
3325 {
3326 }
3327
3328 virtual
3329 Options *
3330 GetOptions ()
3331 {
3332 return &m_options;
3333 }
3334
3335protected:
3336 bool
3337 DoExecute (Args& command,
3338 CommandReturnObject &result)
3339 {
3340 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3341 if (!target)
3342 {
3343 result.AppendError ("invalid target, create a debug target using the 'target create' command");
3344 result.SetStatus (eReturnStatusFailed);
3345 return false;
3346 }
3347
3348 ExecutionContext exe_ctx = m_interpreter.GetDebugger().GetSelectedExecutionContext();
3349 Process *process = exe_ctx.GetProcessPtr();
3350 ABI *abi = NULL;
3351 if (process)
3352 abi = process->GetABI().get();
3353
3354 if (process == NULL)
3355 {
3356 result.AppendError ("You must have a process running to use this command.");
3357 result.SetStatus (eReturnStatusFailed);
3358 return false;
3359 }
3360
3361 ThreadList threads(process->GetThreadList());
3362 if (threads.GetSize() == 0)
3363 {
3364 result.AppendError ("The process must be paused to use this command.");
3365 result.SetStatus (eReturnStatusFailed);
3366 return false;
3367 }
3368
3369 ThreadSP thread(threads.GetThreadAtIndex(0));
3370 if (thread.get() == NULL)
3371 {
3372 result.AppendError ("The process must be paused to use this command.");
3373 result.SetStatus (eReturnStatusFailed);
3374 return false;
3375 }
3376
3377 if (m_options.m_type == eLookupTypeFunctionOrSymbol)
3378 {
3379 SymbolContextList sc_list;
3380 uint32_t num_matches;
3381 ConstString function_name (m_options.m_str.c_str());
3382 num_matches = target->GetImages().FindFunctions (function_name, eFunctionNameTypeAuto, true, false, true, sc_list);
3383 for (uint32_t idx = 0; idx < num_matches; idx++)
3384 {
3385 SymbolContext sc;
3386 sc_list.GetContextAtIndex(idx, sc);
3387 if (sc.symbol == NULL && sc.function == NULL)
3388 continue;
3389 if (sc.module_sp.get() == NULL || sc.module_sp->GetObjectFile() == NULL)
3390 continue;
3391 AddressRange range;
3392 if (!sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range))
3393 continue;
3394 if (!range.GetBaseAddress().IsValid())
3395 continue;
3396 ConstString funcname(sc.GetFunctionName());
3397 if (funcname.IsEmpty())
3398 continue;
3399 addr_t start_addr = range.GetBaseAddress().GetLoadAddress(target);
3400 if (abi)
3401 start_addr = abi->FixCodeAddress(start_addr);
3402
3403 FuncUnwindersSP func_unwinders_sp (sc.module_sp->GetObjectFile()->GetUnwindTable().GetUncachedFuncUnwindersContainingAddress(start_addr, sc));
3404 if (func_unwinders_sp.get() == NULL)
3405 continue;
3406
3407 Address first_non_prologue_insn (func_unwinders_sp->GetFirstNonPrologueInsn(*target));
3408 if (first_non_prologue_insn.IsValid())
3409 {
3410 result.GetOutputStream().Printf("First non-prologue instruction is at address 0x%llx or offset %lld into the function.\n", first_non_prologue_insn.GetLoadAddress(target), first_non_prologue_insn.GetLoadAddress(target) - start_addr);
3411 result.GetOutputStream().Printf ("\n");
3412 }
3413
3414 UnwindPlanSP non_callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtNonCallSite(*thread.get());
3415 if (non_callsite_unwind_plan.get())
3416 {
3417 result.GetOutputStream().Printf("Asynchronous (not restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3418 non_callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3419 result.GetOutputStream().Printf ("\n");
3420 }
3421
3422 UnwindPlanSP callsite_unwind_plan = func_unwinders_sp->GetUnwindPlanAtCallSite(-1);
3423 if (callsite_unwind_plan.get())
3424 {
3425 result.GetOutputStream().Printf("Synchronous (restricted to call-sites) UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3426 callsite_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3427 result.GetOutputStream().Printf ("\n");
3428 }
3429
3430 UnwindPlanSP arch_default_unwind_plan = func_unwinders_sp->GetUnwindPlanArchitectureDefault(*thread.get());
3431 if (arch_default_unwind_plan.get())
3432 {
3433 result.GetOutputStream().Printf("Architecture default UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3434 arch_default_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3435 result.GetOutputStream().Printf ("\n");
3436 }
3437
3438 UnwindPlanSP fast_unwind_plan = func_unwinders_sp->GetUnwindPlanFastUnwind(*thread.get());
3439 if (fast_unwind_plan.get())
3440 {
3441 result.GetOutputStream().Printf("Fast UnwindPlan for %s`%s (start addr 0x%llx):\n", sc.module_sp->GetPlatformFileSpec().GetFilename().AsCString(), funcname.AsCString(), start_addr);
3442 fast_unwind_plan->Dump(result.GetOutputStream(), thread.get(), LLDB_INVALID_ADDRESS);
3443 result.GetOutputStream().Printf ("\n");
3444 }
3445
3446
3447 result.GetOutputStream().Printf ("\n");
3448 }
3449 }
3450 return result.Succeeded();
3451 }
3452
3453 CommandOptions m_options;
3454};
3455
3456OptionDefinition
3457CommandObjectTargetModulesShowUnwind::CommandOptions::g_option_table[] =
3458{
3459 { LLDB_OPT_SET_1, true, "name", 'n', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function or symbol by name in one or more target modules."},
3460 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3461};
Greg Claytone1f50b92011-05-03 22:09:39 +00003462
3463//----------------------------------------------------------------------
3464// Lookup information in images
3465//----------------------------------------------------------------------
Jim Inghamda26bd22012-06-08 21:56:10 +00003466class CommandObjectTargetModulesLookup : public CommandObjectParsed
Greg Claytone1f50b92011-05-03 22:09:39 +00003467{
3468public:
3469
3470 enum
3471 {
3472 eLookupTypeInvalid = -1,
3473 eLookupTypeAddress = 0,
3474 eLookupTypeSymbol,
3475 eLookupTypeFileLine, // Line is optional
3476 eLookupTypeFunction,
Greg Clayton2ad894b2012-05-15 18:43:44 +00003477 eLookupTypeFunctionOrSymbol,
Greg Claytone1f50b92011-05-03 22:09:39 +00003478 eLookupTypeType,
3479 kNumLookupTypes
3480 };
3481
3482 class CommandOptions : public Options
3483 {
3484 public:
3485
3486 CommandOptions (CommandInterpreter &interpreter) :
3487 Options(interpreter)
3488 {
3489 OptionParsingStarting();
3490 }
3491
3492 virtual
3493 ~CommandOptions ()
3494 {
3495 }
3496
3497 virtual Error
3498 SetOptionValue (uint32_t option_idx, const char *option_arg)
3499 {
3500 Error error;
3501
3502 char short_option = (char) m_getopt_table[option_idx].val;
3503
3504 switch (short_option)
3505 {
3506 case 'a':
3507 m_type = eLookupTypeAddress;
3508 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3509 if (m_addr == LLDB_INVALID_ADDRESS)
Greg Clayton9c236732011-10-26 00:56:27 +00003510 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
Greg Claytone1f50b92011-05-03 22:09:39 +00003511 break;
3512
3513 case 'o':
3514 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3515 if (m_offset == LLDB_INVALID_ADDRESS)
Greg Clayton9c236732011-10-26 00:56:27 +00003516 error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
Greg Claytone1f50b92011-05-03 22:09:39 +00003517 break;
3518
3519 case 's':
3520 m_str = option_arg;
3521 m_type = eLookupTypeSymbol;
3522 break;
3523
3524 case 'f':
3525 m_file.SetFile (option_arg, false);
3526 m_type = eLookupTypeFileLine;
3527 break;
3528
3529 case 'i':
Sean Callanan9ad19532012-02-11 01:22:21 +00003530 m_include_inlines = false;
Greg Claytone1f50b92011-05-03 22:09:39 +00003531 break;
3532
3533 case 'l':
3534 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
3535 if (m_line_number == UINT32_MAX)
Greg Clayton9c236732011-10-26 00:56:27 +00003536 error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
Greg Claytone1f50b92011-05-03 22:09:39 +00003537 else if (m_line_number == 0)
Greg Clayton9c236732011-10-26 00:56:27 +00003538 error.SetErrorString ("zero is an invalid line number");
Greg Claytone1f50b92011-05-03 22:09:39 +00003539 m_type = eLookupTypeFileLine;
3540 break;
3541
Greg Clayton2ad894b2012-05-15 18:43:44 +00003542 case 'F':
Greg Claytone1f50b92011-05-03 22:09:39 +00003543 m_str = option_arg;
3544 m_type = eLookupTypeFunction;
3545 break;
Greg Clayton2ad894b2012-05-15 18:43:44 +00003546
3547 case 'n':
3548 m_str = option_arg;
3549 m_type = eLookupTypeFunctionOrSymbol;
3550 break;
3551
Greg Claytone1f50b92011-05-03 22:09:39 +00003552 case 't':
3553 m_str = option_arg;
3554 m_type = eLookupTypeType;
3555 break;
3556
3557 case 'v':
3558 m_verbose = 1;
3559 break;
Sean Callanan56d31ec2012-06-06 20:49:55 +00003560
3561 case 'A':
3562 m_print_all = true;
3563 break;
Greg Claytone1f50b92011-05-03 22:09:39 +00003564
3565 case 'r':
3566 m_use_regex = true;
3567 break;
3568 }
3569
3570 return error;
3571 }
3572
3573 void
3574 OptionParsingStarting ()
3575 {
3576 m_type = eLookupTypeInvalid;
3577 m_str.clear();
3578 m_file.Clear();
3579 m_addr = LLDB_INVALID_ADDRESS;
3580 m_offset = 0;
3581 m_line_number = 0;
3582 m_use_regex = false;
Sean Callanan9ad19532012-02-11 01:22:21 +00003583 m_include_inlines = true;
Greg Claytone1f50b92011-05-03 22:09:39 +00003584 m_verbose = false;
Sean Callanan56d31ec2012-06-06 20:49:55 +00003585 m_print_all = false;
Greg Claytone1f50b92011-05-03 22:09:39 +00003586 }
3587
3588 const OptionDefinition*
3589 GetDefinitions ()
3590 {
3591 return g_option_table;
3592 }
3593
3594 // Options table: Required for subclasses of Options.
3595
3596 static OptionDefinition g_option_table[];
3597 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3598 std::string m_str; // Holds name lookup
3599 FileSpec m_file; // Files for file lookups
3600 lldb::addr_t m_addr; // Holds the address to lookup
3601 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
3602 uint32_t m_line_number; // Line number for file+line lookups
3603 bool m_use_regex; // Name lookups in m_str are regular expressions.
Sean Callanan9ad19532012-02-11 01:22:21 +00003604 bool m_include_inlines;// Check for inline entries when looking up by file/line.
Greg Claytone1f50b92011-05-03 22:09:39 +00003605 bool m_verbose; // Enable verbose lookup info
Sean Callanan56d31ec2012-06-06 20:49:55 +00003606 bool m_print_all; // Print all matches, even in cases where there's a best match.
Greg Claytone1f50b92011-05-03 22:09:39 +00003607
3608 };
3609
3610 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00003611 CommandObjectParsed (interpreter,
3612 "target modules lookup",
3613 "Look up information within executable and dependent shared library images.",
3614 NULL),
3615 m_options (interpreter)
Greg Claytone1f50b92011-05-03 22:09:39 +00003616 {
3617 CommandArgumentEntry arg;
3618 CommandArgumentData file_arg;
3619
3620 // Define the first (and only) variant of this arg.
3621 file_arg.arg_type = eArgTypeFilename;
3622 file_arg.arg_repetition = eArgRepeatStar;
3623
3624 // There is only one variant this argument could be; put it into the argument entry.
3625 arg.push_back (file_arg);
3626
3627 // Push the data for the first argument into the m_arguments vector.
3628 m_arguments.push_back (arg);
3629 }
3630
3631 virtual
3632 ~CommandObjectTargetModulesLookup ()
3633 {
3634 }
3635
3636 virtual Options *
3637 GetOptions ()
3638 {
3639 return &m_options;
3640 }
3641
Sean Callanan56d31ec2012-06-06 20:49:55 +00003642 bool
3643 LookupHere (CommandInterpreter &interpreter, CommandReturnObject &result, bool &syntax_error)
3644 {
3645 switch (m_options.m_type)
3646 {
3647 case eLookupTypeAddress:
3648 case eLookupTypeFileLine:
3649 case eLookupTypeFunction:
3650 case eLookupTypeFunctionOrSymbol:
3651 case eLookupTypeSymbol:
3652 default:
3653 return false;
3654 case eLookupTypeType:
3655 break;
3656 }
3657
3658 ExecutionContext exe_ctx = interpreter.GetDebugger().GetSelectedExecutionContext();
3659
3660 StackFrameSP frame = exe_ctx.GetFrameSP();
3661
3662 if (!frame)
3663 return false;
3664
3665 const SymbolContext &sym_ctx(frame->GetSymbolContext(eSymbolContextModule));
3666
3667 if (!sym_ctx.module_sp)
3668 return false;
3669
3670 switch (m_options.m_type)
3671 {
3672 default:
3673 return false;
3674 case eLookupTypeType:
3675 if (!m_options.m_str.empty())
3676 {
3677 if (LookupTypeHere (m_interpreter,
3678 result.GetOutputStream(),
3679 sym_ctx,
3680 m_options.m_str.c_str(),
3681 m_options.m_use_regex))
3682 {
3683 result.SetStatus(eReturnStatusSuccessFinishResult);
3684 return true;
3685 }
3686 }
3687 break;
3688 }
3689
3690 return true;
3691 }
Greg Claytone1f50b92011-05-03 22:09:39 +00003692
3693 bool
3694 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
3695 {
3696 switch (m_options.m_type)
3697 {
3698 case eLookupTypeAddress:
3699 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
3700 {
3701 if (LookupAddressInModule (m_interpreter,
3702 result.GetOutputStream(),
3703 module,
3704 eSymbolContextEverything,
3705 m_options.m_addr,
3706 m_options.m_offset,
3707 m_options.m_verbose))
3708 {
3709 result.SetStatus(eReturnStatusSuccessFinishResult);
3710 return true;
3711 }
3712 }
3713 break;
3714
3715 case eLookupTypeSymbol:
3716 if (!m_options.m_str.empty())
3717 {
Greg Clayton2ad894b2012-05-15 18:43:44 +00003718 if (LookupSymbolInModule (m_interpreter,
3719 result.GetOutputStream(),
3720 module,
3721 m_options.m_str.c_str(),
3722 m_options.m_use_regex,
3723 m_options.m_verbose))
Greg Claytone1f50b92011-05-03 22:09:39 +00003724 {
3725 result.SetStatus(eReturnStatusSuccessFinishResult);
3726 return true;
3727 }
3728 }
3729 break;
3730
3731 case eLookupTypeFileLine:
3732 if (m_options.m_file)
3733 {
3734
3735 if (LookupFileAndLineInModule (m_interpreter,
3736 result.GetOutputStream(),
3737 module,
3738 m_options.m_file,
3739 m_options.m_line_number,
Sean Callanan9ad19532012-02-11 01:22:21 +00003740 m_options.m_include_inlines,
Greg Claytone1f50b92011-05-03 22:09:39 +00003741 m_options.m_verbose))
3742 {
3743 result.SetStatus(eReturnStatusSuccessFinishResult);
3744 return true;
3745 }
3746 }
3747 break;
Greg Clayton2ad894b2012-05-15 18:43:44 +00003748
3749 case eLookupTypeFunctionOrSymbol:
Greg Claytone1f50b92011-05-03 22:09:39 +00003750 case eLookupTypeFunction:
3751 if (!m_options.m_str.empty())
3752 {
3753 if (LookupFunctionInModule (m_interpreter,
3754 result.GetOutputStream(),
3755 module,
3756 m_options.m_str.c_str(),
3757 m_options.m_use_regex,
Sean Callanan9ad19532012-02-11 01:22:21 +00003758 m_options.m_include_inlines,
Greg Clayton2ad894b2012-05-15 18:43:44 +00003759 m_options.m_type == eLookupTypeFunctionOrSymbol, // include symbols
Greg Claytone1f50b92011-05-03 22:09:39 +00003760 m_options.m_verbose))
3761 {
3762 result.SetStatus(eReturnStatusSuccessFinishResult);
3763 return true;
3764 }
3765 }
3766 break;
3767
Greg Clayton2ad894b2012-05-15 18:43:44 +00003768
Greg Claytone1f50b92011-05-03 22:09:39 +00003769 case eLookupTypeType:
3770 if (!m_options.m_str.empty())
3771 {
3772 if (LookupTypeInModule (m_interpreter,
3773 result.GetOutputStream(),
3774 module,
3775 m_options.m_str.c_str(),
3776 m_options.m_use_regex))
3777 {
3778 result.SetStatus(eReturnStatusSuccessFinishResult);
3779 return true;
3780 }
3781 }
3782 break;
3783
3784 default:
3785 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
3786 syntax_error = true;
3787 break;
3788 }
3789
3790 result.SetStatus (eReturnStatusFailed);
3791 return false;
3792 }
3793
Jim Inghamda26bd22012-06-08 21:56:10 +00003794protected:
Greg Claytone1f50b92011-05-03 22:09:39 +00003795 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00003796 DoExecute (Args& command,
Greg Claytone1f50b92011-05-03 22:09:39 +00003797 CommandReturnObject &result)
3798 {
3799 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3800 if (target == NULL)
3801 {
3802 result.AppendError ("invalid target, create a debug target using the 'target create' command");
3803 result.SetStatus (eReturnStatusFailed);
3804 return false;
3805 }
3806 else
3807 {
3808 bool syntax_error = false;
3809 uint32_t i;
3810 uint32_t num_successful_lookups = 0;
3811 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3812 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3813 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3814 // Dump all sections for all modules images
3815
3816 if (command.GetArgumentCount() == 0)
3817 {
Sean Callanan56d31ec2012-06-06 20:49:55 +00003818 ModuleSP current_module;
3819
3820 // Where it is possible to look in the current symbol context
3821 // first, try that. If this search was successful and --all
3822 // was not passed, don't print anything else.
3823 if (LookupHere (m_interpreter, result, syntax_error))
3824 {
3825 result.GetOutputStream().EOL();
3826 num_successful_lookups++;
3827 if (!m_options.m_print_all)
3828 {
3829 result.SetStatus (eReturnStatusSuccessFinishResult);
3830 return result.Succeeded();
3831 }
3832 }
3833
3834 // Dump all sections for all other modules
3835
Jim Ingham93367902012-05-30 02:19:25 +00003836 ModuleList &target_modules = target->GetImages();
3837 Mutex::Locker modules_locker(target_modules.GetMutex());
3838 const uint32_t num_modules = target_modules.GetSize();
Greg Claytone1f50b92011-05-03 22:09:39 +00003839 if (num_modules > 0)
3840 {
3841 for (i = 0; i<num_modules && syntax_error == false; ++i)
3842 {
Sean Callanan56d31ec2012-06-06 20:49:55 +00003843 Module *module_pointer = target_modules.GetModulePointerAtIndexUnlocked(i);
3844
3845 if (module_pointer != current_module.get() &&
3846 LookupInModule (m_interpreter, target_modules.GetModulePointerAtIndexUnlocked(i), result, syntax_error))
Greg Claytone1f50b92011-05-03 22:09:39 +00003847 {
3848 result.GetOutputStream().EOL();
3849 num_successful_lookups++;
3850 }
3851 }
3852 }
3853 else
3854 {
3855 result.AppendError ("the target has no associated executable images");
3856 result.SetStatus (eReturnStatusFailed);
3857 return false;
3858 }
3859 }
3860 else
3861 {
3862 // Dump specified images (by basename or fullpath)
3863 const char *arg_cstr;
3864 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
3865 {
Greg Clayton91048ef2011-11-10 01:18:58 +00003866 ModuleList module_list;
3867 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
3868 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00003869 {
Jason Molendabf41e192012-10-04 22:47:07 +00003870 for (size_t j=0; j<num_matches; ++j)
Greg Claytone1f50b92011-05-03 22:09:39 +00003871 {
Jason Molendabf41e192012-10-04 22:47:07 +00003872 Module *module = module_list.GetModulePointerAtIndex(j);
Greg Clayton91048ef2011-11-10 01:18:58 +00003873 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00003874 {
Greg Clayton91048ef2011-11-10 01:18:58 +00003875 if (LookupInModule (m_interpreter, module, result, syntax_error))
Greg Claytone1f50b92011-05-03 22:09:39 +00003876 {
3877 result.GetOutputStream().EOL();
3878 num_successful_lookups++;
3879 }
3880 }
3881 }
3882 }
3883 else
3884 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
3885 }
3886 }
3887
3888 if (num_successful_lookups > 0)
3889 result.SetStatus (eReturnStatusSuccessFinishResult);
3890 else
3891 result.SetStatus (eReturnStatusFailed);
3892 }
3893 return result.Succeeded();
3894 }
Greg Claytone1f50b92011-05-03 22:09:39 +00003895
3896 CommandOptions m_options;
3897};
3898
3899OptionDefinition
3900CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
3901{
Sean Callanan3bfaad62012-09-13 21:11:40 +00003902 { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more target modules."},
3903 { LLDB_OPT_SET_1, false, "offset", 'o', required_argument, NULL, 0, eArgTypeOffset, "When looking up an address subtract <offset> from any addresses before doing the lookup."},
Greg Clayton2ad894b2012-05-15 18:43:44 +00003904 { LLDB_OPT_SET_2| LLDB_OPT_SET_4 | LLDB_OPT_SET_5
3905 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_6 */ ,
Sean Callanan3bfaad62012-09-13 21:11:40 +00003906 false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."},
3907 { LLDB_OPT_SET_2, true, "symbol", 's', required_argument, NULL, 0, eArgTypeSymbol, "Lookup a symbol by name in the symbol tables in one or more target modules."},
3908 { LLDB_OPT_SET_3, true, "file", 'f', required_argument, NULL, 0, eArgTypeFilename, "Lookup a file by fullpath or basename in one or more target modules."},
3909 { LLDB_OPT_SET_3, false, "line", 'l', required_argument, NULL, 0, eArgTypeLineNum, "Lookup a line number in a file (must be used in conjunction with --file)."},
Jim Inghamf081dab2012-06-04 22:47:34 +00003910 { LLDB_OPT_SET_FROM_TO(3,5),
Sean Callanan3bfaad62012-09-13 21:11:40 +00003911 false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."},
3912 { LLDB_OPT_SET_4, true, "function", 'F', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules."},
3913 { LLDB_OPT_SET_5, true, "name", 'n', required_argument, NULL, 0, eArgTypeFunctionOrSymbol, "Lookup a function or symbol by name in one or more target modules."},
3914 { LLDB_OPT_SET_6, true, "type", 't', required_argument, NULL, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules."},
3915 { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."},
3916 { LLDB_OPT_SET_ALL, false, "all", 'A', no_argument, NULL, 0, eArgTypeNone, "Print all matches, not just the best match, if a best match is available."},
3917 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
Greg Claytone1f50b92011-05-03 22:09:39 +00003918};
Chris Lattner24943d22010-06-08 16:52:24 +00003919
3920
Jim Inghamd60d94a2011-03-11 03:53:59 +00003921#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner24943d22010-06-08 16:52:24 +00003922
3923//-------------------------------------------------------------------------
3924// CommandObjectMultiwordImageSearchPaths
3925//-------------------------------------------------------------------------
3926
Greg Claytone1f50b92011-05-03 22:09:39 +00003927class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
Chris Lattner24943d22010-06-08 16:52:24 +00003928{
3929public:
Greg Claytone1f50b92011-05-03 22:09:39 +00003930
3931 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
3932 CommandObjectMultiword (interpreter,
3933 "target modules search-paths",
3934 "A set of commands for operating on debugger target image search paths.",
3935 "target modules search-paths <subcommand> [<subcommand-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +00003936 {
Greg Claytone1f50b92011-05-03 22:09:39 +00003937 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
3938 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
3939 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
3940 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
3941 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00003942 }
Greg Claytone1f50b92011-05-03 22:09:39 +00003943
3944 ~CommandObjectTargetModulesImageSearchPaths()
Chris Lattner24943d22010-06-08 16:52:24 +00003945 {
3946 }
3947};
3948
Greg Claytone1f50b92011-05-03 22:09:39 +00003949
3950
3951#pragma mark CommandObjectTargetModules
3952
3953//-------------------------------------------------------------------------
3954// CommandObjectTargetModules
3955//-------------------------------------------------------------------------
3956
3957class CommandObjectTargetModules : public CommandObjectMultiword
3958{
3959public:
3960 //------------------------------------------------------------------
3961 // Constructors and Destructors
3962 //------------------------------------------------------------------
3963 CommandObjectTargetModules(CommandInterpreter &interpreter) :
3964 CommandObjectMultiword (interpreter,
3965 "target modules",
3966 "A set of commands for accessing information for one or more target modules.",
3967 "target modules <sub-command> ...")
3968 {
3969 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
3970 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
3971 //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter)));
3972 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
3973 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
3974 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
3975 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
Jason Molenda5b0afcc2012-07-12 00:20:07 +00003976 LoadSubCommand ("show-unwind", CommandObjectSP (new CommandObjectTargetModulesShowUnwind (interpreter)));
Greg Claytone1f50b92011-05-03 22:09:39 +00003977
3978 }
3979 virtual
3980 ~CommandObjectTargetModules()
3981 {
3982 }
3983
3984private:
3985 //------------------------------------------------------------------
3986 // For CommandObjectTargetModules only
3987 //------------------------------------------------------------------
3988 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
3989};
3990
3991
Greg Clayton3508c382012-02-24 01:59:29 +00003992
Jim Inghamda26bd22012-06-08 21:56:10 +00003993class CommandObjectTargetSymbolsAdd : public CommandObjectParsed
Greg Clayton3508c382012-02-24 01:59:29 +00003994{
3995public:
3996 CommandObjectTargetSymbolsAdd (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00003997 CommandObjectParsed (interpreter,
3998 "target symbols add",
Greg Clayton437b5bc2012-09-27 22:26:11 +00003999 "Add a debug symbol file to one of the target's current modules by specifying a path to a debug symbols file, or using the options to specify a module to download symbols for.",
4000 "target symbols add [<symfile>]"),
4001 m_option_group (interpreter),
4002 m_file_option (LLDB_OPT_SET_1, false, "shlib", 's', CommandCompletions::eModuleCompletion, eArgTypeShlibName, "Fullpath or basename for module to find debug symbols for."),
4003 m_current_frame_option (LLDB_OPT_SET_2, false, "frame", 'F', "Locate the debug symbols the currently selected frame.", false, true)
4004
Greg Clayton3508c382012-02-24 01:59:29 +00004005 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004006 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4007 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
4008 m_option_group.Append (&m_current_frame_option, LLDB_OPT_SET_2, LLDB_OPT_SET_2);
4009 m_option_group.Finalize();
Greg Clayton3508c382012-02-24 01:59:29 +00004010 }
4011
4012 virtual
4013 ~CommandObjectTargetSymbolsAdd ()
4014 {
4015 }
4016
Jim Inghamda26bd22012-06-08 21:56:10 +00004017 int
4018 HandleArgumentCompletion (Args &input,
4019 int &cursor_index,
4020 int &cursor_char_position,
4021 OptionElementVector &opt_element_vector,
4022 int match_start_point,
4023 int max_return_elements,
4024 bool &word_complete,
4025 StringList &matches)
4026 {
4027 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
4028 completion_str.erase (cursor_char_position);
4029
4030 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
4031 CommandCompletions::eDiskFileCompletion,
4032 completion_str.c_str(),
4033 match_start_point,
4034 max_return_elements,
4035 NULL,
4036 word_complete,
4037 matches);
4038 return matches.GetSize();
4039 }
4040
Greg Clayton437b5bc2012-09-27 22:26:11 +00004041 virtual Options *
4042 GetOptions ()
4043 {
4044 return &m_option_group;
4045 }
4046
4047
Jim Inghamda26bd22012-06-08 21:56:10 +00004048protected:
Greg Clayton437b5bc2012-09-27 22:26:11 +00004049
4050 bool
4051 AddModuleSymbols (Target *target,
4052 const FileSpec &symfile_spec,
4053 bool &flush,
4054 CommandReturnObject &result)
4055 {
4056 ModuleSP symfile_module_sp (new Module (symfile_spec, target->GetArchitecture()));
4057 const UUID &symfile_uuid = symfile_module_sp->GetUUID();
4058 StreamString ss_symfile_uuid;
4059 symfile_uuid.Dump(&ss_symfile_uuid);
4060
4061 if (symfile_module_sp)
4062 {
4063 char symfile_path[PATH_MAX];
4064 symfile_spec.GetPath (symfile_path, sizeof(symfile_path));
4065 // We now have a module that represents a symbol file
4066 // that can be used for a module that might exist in the
4067 // current target, so we need to find that module in the
4068 // target
4069
4070 ModuleSP old_module_sp (target->GetImages().FindModule (symfile_uuid));
4071 if (old_module_sp)
4072 {
4073 // The module has not yet created its symbol vendor, we can just
4074 // give the existing target module the symfile path to use for
4075 // when it decides to create it!
4076 old_module_sp->SetSymbolFileFileSpec (symfile_module_sp->GetFileSpec());
4077
4078 // Provide feedback that the symfile has been successfully added.
4079 const FileSpec &module_fs = old_module_sp->GetFileSpec();
4080 result.AppendMessageWithFormat("symbol file '%s' with UUID %s has been successfully added to the '%s/%s' module\n",
4081 symfile_path, ss_symfile_uuid.GetData(),
4082 module_fs.GetDirectory().AsCString(), module_fs.GetFilename().AsCString());
4083
4084 // Let clients know something changed in the module
4085 // if it is currently loaded
4086 ModuleList module_list;
4087 module_list.Append (old_module_sp);
4088 target->ModulesDidLoad (module_list);
4089 flush = true;
4090 }
4091 else
4092 {
4093 result.AppendErrorWithFormat ("symbol file '%s' with UUID %s does not match any existing module%s\n",
4094 symfile_path, ss_symfile_uuid.GetData(),
4095 (symfile_spec.GetFileType() != FileSpec::eFileTypeRegular)
4096 ? "\n please specify the full path to the symbol file"
4097 : "");
4098 return false;
4099 }
4100 }
4101 else
4102 {
4103 result.AppendError ("one or more executable image paths must be specified");
4104 result.SetStatus (eReturnStatusFailed);
4105 return false;
4106 }
4107 result.SetStatus (eReturnStatusSuccessFinishResult);
4108 return true;
4109 }
4110
Greg Clayton3508c382012-02-24 01:59:29 +00004111 virtual bool
Jim Inghamda26bd22012-06-08 21:56:10 +00004112 DoExecute (Args& args,
Greg Clayton3508c382012-02-24 01:59:29 +00004113 CommandReturnObject &result)
4114 {
Greg Claytoncf5927e2012-05-18 02:38:05 +00004115 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
4116 Target *target = exe_ctx.GetTargetPtr();
Greg Clayton437b5bc2012-09-27 22:26:11 +00004117 result.SetStatus (eReturnStatusFailed);
Greg Clayton3508c382012-02-24 01:59:29 +00004118 if (target == NULL)
4119 {
4120 result.AppendError ("invalid target, create a debug target using the 'target create' command");
Greg Clayton3508c382012-02-24 01:59:29 +00004121 }
4122 else
4123 {
Greg Claytoncf5927e2012-05-18 02:38:05 +00004124 bool flush = false;
Greg Clayton437b5bc2012-09-27 22:26:11 +00004125 ModuleSpec sym_spec;
4126 const bool uuid_option_set = m_uuid_option_group.GetOptionValue().OptionWasSet();
4127 const bool file_option_set = m_file_option.GetOptionValue().OptionWasSet();
4128 const bool frame_option_set = m_current_frame_option.GetOptionValue().OptionWasSet();
4129
Greg Clayton3508c382012-02-24 01:59:29 +00004130 const size_t argc = args.GetArgumentCount();
4131 if (argc == 0)
4132 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004133 if (uuid_option_set || file_option_set || frame_option_set)
Greg Clayton3508c382012-02-24 01:59:29 +00004134 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004135 bool success = false;
4136 bool error_set = false;
4137 if (frame_option_set)
Greg Clayton3508c382012-02-24 01:59:29 +00004138 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004139 Process *process = exe_ctx.GetProcessPtr();
4140 if (process)
Greg Clayton3508c382012-02-24 01:59:29 +00004141 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004142 const StateType process_state = process->GetState();
4143 if (StateIsStoppedState (process_state, true))
Greg Clayton3508c382012-02-24 01:59:29 +00004144 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004145 StackFrame *frame = exe_ctx.GetFramePtr();
4146 if (frame)
Greg Clayton3508c382012-02-24 01:59:29 +00004147 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004148 ModuleSP frame_module_sp (frame->GetSymbolContext(eSymbolContextModule).module_sp);
4149 if (frame_module_sp)
4150 {
4151 if (frame_module_sp->GetPlatformFileSpec().Exists())
4152 {
4153 sym_spec.GetArchitecture() = frame_module_sp->GetArchitecture();
4154 sym_spec.GetFileSpec() = frame_module_sp->GetPlatformFileSpec();
4155 }
4156 sym_spec.GetUUID() = frame_module_sp->GetUUID();
4157 success = sym_spec.GetUUID().IsValid() || sym_spec.GetFileSpec();
4158 }
4159 else
4160 {
4161 result.AppendError ("frame has no module");
4162 error_set = true;
4163 }
Greg Clayton3508c382012-02-24 01:59:29 +00004164 }
Johnny Chen9262cd52012-08-22 00:18:43 +00004165 else
4166 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004167 result.AppendError ("invalid current frame");
4168 error_set = true;
Johnny Chen9262cd52012-08-22 00:18:43 +00004169 }
Greg Clayton3508c382012-02-24 01:59:29 +00004170 }
4171 else
4172 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004173 result.AppendErrorWithFormat ("process is not stopped: %s", StateAsCString(process_state));
4174 error_set = true;
Greg Clayton3508c382012-02-24 01:59:29 +00004175 }
Greg Clayton3508c382012-02-24 01:59:29 +00004176 }
4177 else
4178 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004179 result.AppendError ("a process must exist in order to use the --frame option");
4180 error_set = true;
4181 }
4182 }
4183 else
4184 {
4185 if (uuid_option_set)
4186 {
4187 sym_spec.GetUUID() = m_uuid_option_group.GetOptionValue().GetCurrentValue();
4188 success |= sym_spec.GetUUID().IsValid();
4189 }
4190 else if (file_option_set)
4191 {
4192 sym_spec.GetFileSpec() = m_file_option.GetOptionValue().GetCurrentValue();
4193 ModuleSP module_sp (target->GetImages().FindFirstModule(sym_spec));
4194 if (module_sp)
Greg Clayton3508c382012-02-24 01:59:29 +00004195 {
Greg Clayton437b5bc2012-09-27 22:26:11 +00004196 sym_spec.GetFileSpec() = module_sp->GetFileSpec();
4197 sym_spec.GetPlatformFileSpec() = module_sp->GetPlatformFileSpec();
4198 sym_spec.GetUUID() = module_sp->GetUUID();
4199 sym_spec.GetArchitecture() = module_sp->GetArchitecture();
Greg Clayton3508c382012-02-24 01:59:29 +00004200 }
Greg Clayton437b5bc2012-09-27 22:26:11 +00004201 else
4202 {
4203 sym_spec.GetArchitecture() = target->GetArchitecture();
4204 }
4205 success |= sym_spec.GetFileSpec().Exists();
4206 }
4207 }
4208
4209 if (success)
4210 {
4211 if (Symbols::DownloadObjectAndSymbolFile (sym_spec))
4212 {
4213 if (sym_spec.GetSymbolFileSpec())
4214 success = AddModuleSymbols (target, sym_spec.GetSymbolFileSpec(), flush, result);
4215 }
4216 }
4217
4218 if (!success && !error_set)
4219 {
4220 StreamString error_strm;
4221 if (uuid_option_set)
4222 {
4223 error_strm.PutCString("unable to find debug symbols for UUID ");
4224 sym_spec.GetUUID().Dump (&error_strm);
4225 }
4226 else if (file_option_set)
4227 {
4228 error_strm.PutCString("unable to find debug symbols for the executable file ");
4229 error_strm << sym_spec.GetFileSpec();
4230 }
4231 else if (frame_option_set)
4232 {
4233 error_strm.PutCString("unable to find debug symbols for the current frame");
4234 }
4235 result.AppendError (error_strm.GetData());
4236 }
4237 }
4238 else
4239 {
4240 result.AppendError ("one or more symbol file paths must be specified, or options must be specified");
4241 }
4242 }
4243 else
4244 {
4245 if (uuid_option_set)
4246 {
4247 result.AppendError ("specify either one or more paths to symbol files or use the --uuid option without arguments");
4248 }
4249 else if (file_option_set)
4250 {
4251 result.AppendError ("specify either one or more paths to symbol files or use the --file option without arguments");
4252 }
4253 else if (frame_option_set)
4254 {
4255 result.AppendError ("specify either one or more paths to symbol files or use the --frame option without arguments");
4256 }
4257 else
4258 {
4259 PlatformSP platform_sp (target->GetPlatform());
4260
4261 for (size_t i=0; i<argc; ++i)
4262 {
4263 const char *symfile_path = args.GetArgumentAtIndex(i);
4264 if (symfile_path)
4265 {
4266 FileSpec symfile_spec;
4267 sym_spec.GetSymbolFileSpec().SetFile(symfile_path, true);
4268 if (platform_sp)
4269 platform_sp->ResolveSymbolFile(*target, sym_spec, symfile_spec);
4270 else
4271 symfile_spec.SetFile(symfile_path, true);
4272
4273 ArchSpec arch;
4274 bool symfile_exists = symfile_spec.Exists();
4275
4276 if (symfile_exists)
4277 {
4278 if (!AddModuleSymbols (target, symfile_spec, flush, result))
4279 break;
4280 }
4281 else
4282 {
4283 char resolved_symfile_path[PATH_MAX];
4284 if (symfile_spec.GetPath (resolved_symfile_path, sizeof(resolved_symfile_path)))
4285 {
4286 if (strcmp (resolved_symfile_path, symfile_path) != 0)
4287 {
4288 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", symfile_path, resolved_symfile_path);
4289 break;
4290 }
4291 }
4292 result.AppendErrorWithFormat ("invalid module path '%s'\n", symfile_path);
4293 break;
4294 }
Greg Clayton3508c382012-02-24 01:59:29 +00004295 }
4296 }
4297 }
4298 }
Greg Claytoncf5927e2012-05-18 02:38:05 +00004299
4300 if (flush)
4301 {
4302 Process *process = exe_ctx.GetProcessPtr();
4303 if (process)
4304 process->Flush();
4305 }
Greg Clayton3508c382012-02-24 01:59:29 +00004306 }
4307 return result.Succeeded();
4308 }
4309
Greg Clayton437b5bc2012-09-27 22:26:11 +00004310 OptionGroupOptions m_option_group;
4311 OptionGroupUUID m_uuid_option_group;
4312 OptionGroupFile m_file_option;
4313 OptionGroupBoolean m_current_frame_option;
4314
4315
Greg Clayton3508c382012-02-24 01:59:29 +00004316};
4317
4318
4319#pragma mark CommandObjectTargetSymbols
4320
4321//-------------------------------------------------------------------------
4322// CommandObjectTargetSymbols
4323//-------------------------------------------------------------------------
4324
4325class CommandObjectTargetSymbols : public CommandObjectMultiword
4326{
4327public:
4328 //------------------------------------------------------------------
4329 // Constructors and Destructors
4330 //------------------------------------------------------------------
4331 CommandObjectTargetSymbols(CommandInterpreter &interpreter) :
4332 CommandObjectMultiword (interpreter,
4333 "target symbols",
4334 "A set of commands for adding and managing debug symbol files.",
4335 "target symbols <sub-command> ...")
4336 {
4337 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetSymbolsAdd (interpreter)));
4338
4339 }
4340 virtual
4341 ~CommandObjectTargetSymbols()
4342 {
4343 }
4344
4345private:
4346 //------------------------------------------------------------------
4347 // For CommandObjectTargetModules only
4348 //------------------------------------------------------------------
4349 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetSymbols);
4350};
4351
4352
Jim Inghamd60d94a2011-03-11 03:53:59 +00004353#pragma mark CommandObjectTargetStopHookAdd
4354
4355//-------------------------------------------------------------------------
4356// CommandObjectTargetStopHookAdd
4357//-------------------------------------------------------------------------
4358
Jim Inghamda26bd22012-06-08 21:56:10 +00004359class CommandObjectTargetStopHookAdd : public CommandObjectParsed
Jim Inghamd60d94a2011-03-11 03:53:59 +00004360{
4361public:
4362
4363 class CommandOptions : public Options
4364 {
4365 public:
Greg Claytonf15996e2011-04-07 22:46:35 +00004366 CommandOptions (CommandInterpreter &interpreter) :
4367 Options(interpreter),
Jim Inghamd60d94a2011-03-11 03:53:59 +00004368 m_line_start(0),
4369 m_line_end (UINT_MAX),
4370 m_func_name_type_mask (eFunctionNameTypeAuto),
4371 m_sym_ctx_specified (false),
Johnny Chen60fe60e2011-05-02 23:47:55 +00004372 m_thread_specified (false),
4373 m_use_one_liner (false),
4374 m_one_liner()
Jim Inghamd60d94a2011-03-11 03:53:59 +00004375 {
4376 }
4377
4378 ~CommandOptions () {}
4379
Greg Claytonb3448432011-03-24 21:19:54 +00004380 const OptionDefinition*
Jim Inghamd60d94a2011-03-11 03:53:59 +00004381 GetDefinitions ()
4382 {
4383 return g_option_table;
4384 }
4385
4386 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +00004387 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004388 {
4389 Error error;
4390 char short_option = (char) m_getopt_table[option_idx].val;
4391 bool success;
4392
4393 switch (short_option)
4394 {
4395 case 'c':
4396 m_class_name = option_arg;
4397 m_sym_ctx_specified = true;
4398 break;
4399
4400 case 'e':
4401 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
4402 if (!success)
4403 {
Greg Clayton9c236732011-10-26 00:56:27 +00004404 error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004405 break;
4406 }
4407 m_sym_ctx_specified = true;
4408 break;
4409
4410 case 'l':
4411 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
4412 if (!success)
4413 {
Greg Clayton9c236732011-10-26 00:56:27 +00004414 error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004415 break;
4416 }
4417 m_sym_ctx_specified = true;
4418 break;
Sean Callanan9ad19532012-02-11 01:22:21 +00004419
4420 case 'i':
4421 m_no_inlines = true;
4422 break;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004423
4424 case 'n':
4425 m_function_name = option_arg;
4426 m_func_name_type_mask |= eFunctionNameTypeAuto;
4427 m_sym_ctx_specified = true;
4428 break;
4429
4430 case 'f':
4431 m_file_name = option_arg;
4432 m_sym_ctx_specified = true;
4433 break;
4434 case 's':
4435 m_module_name = option_arg;
4436 m_sym_ctx_specified = true;
4437 break;
4438 case 't' :
4439 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00004440 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004441 if (m_thread_id == LLDB_INVALID_THREAD_ID)
Greg Clayton9c236732011-10-26 00:56:27 +00004442 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004443 m_thread_specified = true;
4444 }
4445 break;
4446 case 'T':
4447 m_thread_name = option_arg;
4448 m_thread_specified = true;
4449 break;
4450 case 'q':
4451 m_queue_name = option_arg;
4452 m_thread_specified = true;
4453 break;
4454 case 'x':
4455 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00004456 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004457 if (m_thread_id == UINT32_MAX)
Greg Clayton9c236732011-10-26 00:56:27 +00004458 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004459 m_thread_specified = true;
4460 }
4461 break;
Johnny Chen60fe60e2011-05-02 23:47:55 +00004462 case 'o':
4463 m_use_one_liner = true;
4464 m_one_liner = option_arg;
4465 break;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004466 default:
Greg Clayton9c236732011-10-26 00:56:27 +00004467 error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004468 break;
4469 }
4470 return error;
4471 }
4472
4473 void
Greg Clayton143fcc32011-04-13 00:18:08 +00004474 OptionParsingStarting ()
Jim Inghamd60d94a2011-03-11 03:53:59 +00004475 {
4476 m_class_name.clear();
4477 m_function_name.clear();
4478 m_line_start = 0;
4479 m_line_end = UINT_MAX;
4480 m_file_name.clear();
4481 m_module_name.clear();
4482 m_func_name_type_mask = eFunctionNameTypeAuto;
4483 m_thread_id = LLDB_INVALID_THREAD_ID;
4484 m_thread_index = UINT32_MAX;
4485 m_thread_name.clear();
4486 m_queue_name.clear();
Sean Callanan9ad19532012-02-11 01:22:21 +00004487
4488 m_no_inlines = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004489 m_sym_ctx_specified = false;
4490 m_thread_specified = false;
Johnny Chen60fe60e2011-05-02 23:47:55 +00004491
4492 m_use_one_liner = false;
4493 m_one_liner.clear();
Jim Inghamd60d94a2011-03-11 03:53:59 +00004494 }
4495
4496
Greg Claytonb3448432011-03-24 21:19:54 +00004497 static OptionDefinition g_option_table[];
Jim Inghamd60d94a2011-03-11 03:53:59 +00004498
4499 std::string m_class_name;
4500 std::string m_function_name;
4501 uint32_t m_line_start;
4502 uint32_t m_line_end;
4503 std::string m_file_name;
4504 std::string m_module_name;
4505 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
4506 lldb::tid_t m_thread_id;
4507 uint32_t m_thread_index;
4508 std::string m_thread_name;
4509 std::string m_queue_name;
4510 bool m_sym_ctx_specified;
Sean Callanan9ad19532012-02-11 01:22:21 +00004511 bool m_no_inlines;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004512 bool m_thread_specified;
Johnny Chen60fe60e2011-05-02 23:47:55 +00004513 // Instance variables to hold the values for one_liner options.
4514 bool m_use_one_liner;
4515 std::string m_one_liner;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004516 };
4517
4518 Options *
4519 GetOptions ()
4520 {
4521 return &m_options;
4522 }
4523
4524 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00004525 CommandObjectParsed (interpreter,
4526 "target stop-hook add ",
4527 "Add a hook to be executed when the target stops.",
4528 "target stop-hook add"),
Greg Claytonf15996e2011-04-07 22:46:35 +00004529 m_options (interpreter)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004530 {
4531 }
4532
4533 ~CommandObjectTargetStopHookAdd ()
4534 {
4535 }
4536
4537 static size_t
4538 ReadCommandsCallbackFunction (void *baton,
4539 InputReader &reader,
4540 lldb::InputReaderAction notification,
4541 const char *bytes,
4542 size_t bytes_len)
4543 {
Caroline Tice892fadd2011-06-16 16:27:19 +00004544 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
Jim Inghamd60d94a2011-03-11 03:53:59 +00004545 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
Jim Inghame15511a2011-05-05 01:03:36 +00004546 static bool got_interrupted;
Caroline Tice892fadd2011-06-16 16:27:19 +00004547 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
Jim Inghamd60d94a2011-03-11 03:53:59 +00004548
4549 switch (notification)
4550 {
4551 case eInputReaderActivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00004552 if (!batch_mode)
4553 {
4554 out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end.");
4555 if (reader.GetPrompt())
4556 out_stream->Printf ("%s", reader.GetPrompt());
4557 out_stream->Flush();
4558 }
Jim Inghame15511a2011-05-05 01:03:36 +00004559 got_interrupted = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004560 break;
4561
4562 case eInputReaderDeactivate:
4563 break;
4564
4565 case eInputReaderReactivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00004566 if (reader.GetPrompt() && !batch_mode)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004567 {
Caroline Tice892fadd2011-06-16 16:27:19 +00004568 out_stream->Printf ("%s", reader.GetPrompt());
4569 out_stream->Flush();
Jim Inghamd60d94a2011-03-11 03:53:59 +00004570 }
Jim Inghame15511a2011-05-05 01:03:36 +00004571 got_interrupted = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004572 break;
4573
Caroline Tice4a348082011-05-02 20:41:46 +00004574 case eInputReaderAsynchronousOutputWritten:
4575 break;
4576
Jim Inghamd60d94a2011-03-11 03:53:59 +00004577 case eInputReaderGotToken:
4578 if (bytes && bytes_len && baton)
4579 {
4580 StringList *commands = new_stop_hook->GetCommandPointer();
4581 if (commands)
4582 {
4583 commands->AppendString (bytes, bytes_len);
4584 }
4585 }
Caroline Tice892fadd2011-06-16 16:27:19 +00004586 if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004587 {
Caroline Tice892fadd2011-06-16 16:27:19 +00004588 out_stream->Printf ("%s", reader.GetPrompt());
4589 out_stream->Flush();
Jim Inghamd60d94a2011-03-11 03:53:59 +00004590 }
4591 break;
4592
4593 case eInputReaderInterrupt:
4594 {
4595 // Finish, and cancel the stop hook.
4596 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
Caroline Tice892fadd2011-06-16 16:27:19 +00004597 if (!batch_mode)
4598 {
4599 out_stream->Printf ("Stop hook cancelled.\n");
4600 out_stream->Flush();
4601 }
4602
Jim Inghamd60d94a2011-03-11 03:53:59 +00004603 reader.SetIsDone (true);
4604 }
Jim Inghame15511a2011-05-05 01:03:36 +00004605 got_interrupted = true;
Jim Inghamd60d94a2011-03-11 03:53:59 +00004606 break;
4607
4608 case eInputReaderEndOfFile:
4609 reader.SetIsDone (true);
4610 break;
4611
4612 case eInputReaderDone:
Caroline Tice892fadd2011-06-16 16:27:19 +00004613 if (!got_interrupted && !batch_mode)
4614 {
Greg Clayton444e35b2011-10-19 18:09:39 +00004615 out_stream->Printf ("Stop hook #%llu added.\n", new_stop_hook->GetID());
Caroline Tice892fadd2011-06-16 16:27:19 +00004616 out_stream->Flush();
4617 }
Jim Inghamd60d94a2011-03-11 03:53:59 +00004618 break;
4619 }
4620
4621 return bytes_len;
4622 }
4623
Jim Inghamda26bd22012-06-08 21:56:10 +00004624protected:
Jim Inghamd60d94a2011-03-11 03:53:59 +00004625 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00004626 DoExecute (Args& command, CommandReturnObject &result)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004627 {
4628 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4629 if (target)
4630 {
4631 Target::StopHookSP new_hook_sp;
4632 target->AddStopHook (new_hook_sp);
4633
4634 // First step, make the specifier.
4635 std::auto_ptr<SymbolContextSpecifier> specifier_ap;
4636 if (m_options.m_sym_ctx_specified)
4637 {
4638 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
4639
4640 if (!m_options.m_module_name.empty())
4641 {
4642 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
4643 }
4644
4645 if (!m_options.m_class_name.empty())
4646 {
4647 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
4648 }
4649
4650 if (!m_options.m_file_name.empty())
4651 {
4652 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
4653 }
4654
4655 if (m_options.m_line_start != 0)
4656 {
4657 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
4658 }
4659
4660 if (m_options.m_line_end != UINT_MAX)
4661 {
4662 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
4663 }
4664
4665 if (!m_options.m_function_name.empty())
4666 {
4667 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
4668 }
4669 }
4670
4671 if (specifier_ap.get())
4672 new_hook_sp->SetSpecifier (specifier_ap.release());
4673
4674 // Next see if any of the thread options have been entered:
4675
4676 if (m_options.m_thread_specified)
4677 {
4678 ThreadSpec *thread_spec = new ThreadSpec();
4679
4680 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
4681 {
4682 thread_spec->SetTID (m_options.m_thread_id);
4683 }
4684
4685 if (m_options.m_thread_index != UINT32_MAX)
4686 thread_spec->SetIndex (m_options.m_thread_index);
4687
4688 if (!m_options.m_thread_name.empty())
4689 thread_spec->SetName (m_options.m_thread_name.c_str());
4690
4691 if (!m_options.m_queue_name.empty())
4692 thread_spec->SetQueueName (m_options.m_queue_name.c_str());
4693
4694 new_hook_sp->SetThreadSpecifier (thread_spec);
4695
4696 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00004697 if (m_options.m_use_one_liner)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004698 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00004699 // Use one-liner.
4700 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
Greg Clayton444e35b2011-10-19 18:09:39 +00004701 result.AppendMessageWithFormat("Stop hook #%llu added.\n", new_hook_sp->GetID());
Jim Inghamd60d94a2011-03-11 03:53:59 +00004702 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00004703 else
Jim Inghamd60d94a2011-03-11 03:53:59 +00004704 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00004705 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into
4706 // the new stop hook's command string.
4707 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
4708 if (!reader_sp)
4709 {
4710 result.AppendError("out of memory\n");
4711 result.SetStatus (eReturnStatusFailed);
4712 target->RemoveStopHookByID (new_hook_sp->GetID());
4713 return false;
4714 }
4715
4716 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
4717 new_hook_sp.get(), // baton
4718 eInputReaderGranularityLine, // token size, to pass to callback function
4719 "DONE", // end token
4720 "> ", // prompt
4721 true)); // echo input
4722 if (!err.Success())
4723 {
4724 result.AppendError (err.AsCString());
4725 result.SetStatus (eReturnStatusFailed);
4726 target->RemoveStopHookByID (new_hook_sp->GetID());
4727 return false;
4728 }
4729 m_interpreter.GetDebugger().PushInputReader (reader_sp);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004730 }
Jim Inghamd60d94a2011-03-11 03:53:59 +00004731 result.SetStatus (eReturnStatusSuccessFinishNoResult);
4732 }
4733 else
4734 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004735 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00004736 result.SetStatus (eReturnStatusFailed);
4737 }
4738
4739 return result.Succeeded();
4740 }
4741private:
4742 CommandOptions m_options;
4743};
4744
Greg Claytonb3448432011-03-24 21:19:54 +00004745OptionDefinition
Jim Inghamd60d94a2011-03-11 03:53:59 +00004746CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
4747{
Filipe Cabecinhas560c5142012-09-11 16:09:27 +00004748 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, 0, eArgTypeOneLiner,
Johnny Chen60fe60e2011-05-02 23:47:55 +00004749 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
Jim Inghamd60d94a2011-03-11 03:53:59 +00004750 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
4751 "Set the module within which the stop-hook is to be run."},
Filipe Cabecinhas560c5142012-09-11 16:09:27 +00004752 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, 0, eArgTypeThreadIndex,
Jim Inghamd60d94a2011-03-11 03:53:59 +00004753 "The stop hook is run only for the thread whose index matches this argument."},
Filipe Cabecinhas560c5142012-09-11 16:09:27 +00004754 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, 0, eArgTypeThreadID,
Jim Inghamd60d94a2011-03-11 03:53:59 +00004755 "The stop hook is run only for the thread whose TID matches this argument."},
Filipe Cabecinhas560c5142012-09-11 16:09:27 +00004756 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, 0, eArgTypeThreadName,
Jim Inghamd60d94a2011-03-11 03:53:59 +00004757 "The stop hook is run only for the thread whose thread name matches this argument."},
Filipe Cabecinhas560c5142012-09-11 16:09:27 +00004758 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, 0, eArgTypeQueueName,
Jim Inghamd60d94a2011-03-11 03:53:59 +00004759 "The stop hook is run only for threads in the queue whose name is given by this argument."},
4760 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
4761 "Specify the source file within which the stop-hook is to be run." },
4762 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
4763 "Set the start of the line range for which the stop-hook is to be run."},
4764 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum,
4765 "Set the end of the line range for which the stop-hook is to be run."},
Filipe Cabecinhas560c5142012-09-11 16:09:27 +00004766 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, 0, eArgTypeClassName,
Jim Inghamd60d94a2011-03-11 03:53:59 +00004767 "Specify the class within which the stop-hook is to be run." },
4768 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
4769 "Set the function name within which the stop hook will be run." },
4770 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
4771};
4772
4773#pragma mark CommandObjectTargetStopHookDelete
4774
4775//-------------------------------------------------------------------------
4776// CommandObjectTargetStopHookDelete
4777//-------------------------------------------------------------------------
4778
Jim Inghamda26bd22012-06-08 21:56:10 +00004779class CommandObjectTargetStopHookDelete : public CommandObjectParsed
Jim Inghamd60d94a2011-03-11 03:53:59 +00004780{
4781public:
4782
4783 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00004784 CommandObjectParsed (interpreter,
4785 "target stop-hook delete",
4786 "Delete a stop-hook.",
4787 "target stop-hook delete [<idx>]")
Jim Inghamd60d94a2011-03-11 03:53:59 +00004788 {
4789 }
4790
4791 ~CommandObjectTargetStopHookDelete ()
4792 {
4793 }
4794
Jim Inghamda26bd22012-06-08 21:56:10 +00004795protected:
Jim Inghamd60d94a2011-03-11 03:53:59 +00004796 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00004797 DoExecute (Args& command, CommandReturnObject &result)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004798 {
4799 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4800 if (target)
4801 {
4802 // FIXME: see if we can use the breakpoint id style parser?
4803 size_t num_args = command.GetArgumentCount();
4804 if (num_args == 0)
4805 {
4806 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
4807 {
4808 result.SetStatus (eReturnStatusFailed);
4809 return false;
4810 }
4811 else
4812 {
4813 target->RemoveAllStopHooks();
4814 }
4815 }
4816 else
4817 {
4818 bool success;
4819 for (size_t i = 0; i < num_args; i++)
4820 {
4821 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
4822 if (!success)
4823 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004824 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00004825 result.SetStatus(eReturnStatusFailed);
4826 return false;
4827 }
4828 success = target->RemoveStopHookByID (user_id);
4829 if (!success)
4830 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004831 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00004832 result.SetStatus(eReturnStatusFailed);
4833 return false;
4834 }
4835 }
4836 }
4837 result.SetStatus (eReturnStatusSuccessFinishNoResult);
4838 }
4839 else
4840 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004841 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00004842 result.SetStatus (eReturnStatusFailed);
4843 }
4844
4845 return result.Succeeded();
4846 }
4847};
4848#pragma mark CommandObjectTargetStopHookEnableDisable
4849
4850//-------------------------------------------------------------------------
4851// CommandObjectTargetStopHookEnableDisable
4852//-------------------------------------------------------------------------
4853
Jim Inghamda26bd22012-06-08 21:56:10 +00004854class CommandObjectTargetStopHookEnableDisable : public CommandObjectParsed
Jim Inghamd60d94a2011-03-11 03:53:59 +00004855{
4856public:
4857
4858 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
Jim Inghamda26bd22012-06-08 21:56:10 +00004859 CommandObjectParsed (interpreter,
4860 name,
4861 help,
4862 syntax),
Jim Inghamd60d94a2011-03-11 03:53:59 +00004863 m_enable (enable)
4864 {
4865 }
4866
4867 ~CommandObjectTargetStopHookEnableDisable ()
4868 {
4869 }
4870
Jim Inghamda26bd22012-06-08 21:56:10 +00004871protected:
Jim Inghamd60d94a2011-03-11 03:53:59 +00004872 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00004873 DoExecute (Args& command, CommandReturnObject &result)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004874 {
4875 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4876 if (target)
4877 {
4878 // FIXME: see if we can use the breakpoint id style parser?
4879 size_t num_args = command.GetArgumentCount();
4880 bool success;
4881
4882 if (num_args == 0)
4883 {
4884 target->SetAllStopHooksActiveState (m_enable);
4885 }
4886 else
4887 {
4888 for (size_t i = 0; i < num_args; i++)
4889 {
4890 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
4891 if (!success)
4892 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004893 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00004894 result.SetStatus(eReturnStatusFailed);
4895 return false;
4896 }
4897 success = target->SetStopHookActiveStateByID (user_id, m_enable);
4898 if (!success)
4899 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004900 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00004901 result.SetStatus(eReturnStatusFailed);
4902 return false;
4903 }
4904 }
4905 }
4906 result.SetStatus (eReturnStatusSuccessFinishNoResult);
4907 }
4908 else
4909 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004910 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00004911 result.SetStatus (eReturnStatusFailed);
4912 }
4913 return result.Succeeded();
4914 }
4915private:
4916 bool m_enable;
4917};
4918
4919#pragma mark CommandObjectTargetStopHookList
4920
4921//-------------------------------------------------------------------------
4922// CommandObjectTargetStopHookList
4923//-------------------------------------------------------------------------
4924
Jim Inghamda26bd22012-06-08 21:56:10 +00004925class CommandObjectTargetStopHookList : public CommandObjectParsed
Jim Inghamd60d94a2011-03-11 03:53:59 +00004926{
4927public:
4928
4929 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
Jim Inghamda26bd22012-06-08 21:56:10 +00004930 CommandObjectParsed (interpreter,
4931 "target stop-hook list",
4932 "List all stop-hooks.",
4933 "target stop-hook list [<type>]")
Jim Inghamd60d94a2011-03-11 03:53:59 +00004934 {
4935 }
4936
4937 ~CommandObjectTargetStopHookList ()
4938 {
4939 }
4940
Jim Inghamda26bd22012-06-08 21:56:10 +00004941protected:
Jim Inghamd60d94a2011-03-11 03:53:59 +00004942 bool
Jim Inghamda26bd22012-06-08 21:56:10 +00004943 DoExecute (Args& command, CommandReturnObject &result)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004944 {
4945 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Johnny Chen9fc16922011-11-29 23:56:14 +00004946 if (!target)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004947 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004948 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00004949 result.SetStatus (eReturnStatusFailed);
Jason Molenda6e3a2412011-09-23 21:15:42 +00004950 return result.Succeeded();
Jim Inghamd60d94a2011-03-11 03:53:59 +00004951 }
4952
4953 size_t num_hooks = target->GetNumStopHooks ();
4954 if (num_hooks == 0)
4955 {
4956 result.GetOutputStream().PutCString ("No stop hooks.\n");
4957 }
4958 else
4959 {
4960 for (size_t i = 0; i < num_hooks; i++)
4961 {
4962 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
4963 if (i > 0)
4964 result.GetOutputStream().PutCString ("\n");
4965 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
4966 }
4967 }
Johnny Chen6c7c3902011-11-30 19:09:20 +00004968 result.SetStatus (eReturnStatusSuccessFinishResult);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004969 return result.Succeeded();
4970 }
4971};
4972
4973#pragma mark CommandObjectMultiwordTargetStopHooks
4974//-------------------------------------------------------------------------
4975// CommandObjectMultiwordTargetStopHooks
4976//-------------------------------------------------------------------------
4977
4978class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
4979{
4980public:
4981
4982 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
4983 CommandObjectMultiword (interpreter,
4984 "target stop-hook",
4985 "A set of commands for operating on debugger target stop-hooks.",
4986 "target stop-hook <subcommand> [<subcommand-options>]")
4987 {
4988 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
4989 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
4990 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
4991 false,
4992 "target stop-hook disable [<id>]",
4993 "Disable a stop-hook.",
4994 "target stop-hook disable")));
4995 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
4996 true,
4997 "target stop-hook enable [<id>]",
4998 "Enable a stop-hook.",
4999 "target stop-hook enable")));
5000 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
5001 }
5002
5003 ~CommandObjectMultiwordTargetStopHooks()
5004 {
5005 }
5006};
5007
5008
Chris Lattner24943d22010-06-08 16:52:24 +00005009
5010#pragma mark CommandObjectMultiwordTarget
5011
5012//-------------------------------------------------------------------------
5013// CommandObjectMultiwordTarget
5014//-------------------------------------------------------------------------
5015
Greg Clayton63094e02010-06-23 01:19:29 +00005016CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00005017 CommandObjectMultiword (interpreter,
5018 "target",
Chris Lattner24943d22010-06-08 16:52:24 +00005019 "A set of commands for operating on debugger targets.",
5020 "target <subcommand> [<subcommand-options>]")
5021{
Greg Claytonabe0fed2011-04-18 08:33:37 +00005022
5023 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
Greg Clayton153ccd72011-08-10 02:10:13 +00005024 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
Greg Claytonabe0fed2011-04-18 08:33:37 +00005025 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter)));
5026 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
Jim Inghamd60d94a2011-03-11 03:53:59 +00005027 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
Greg Claytone1f50b92011-05-03 22:09:39 +00005028 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter)));
Greg Clayton3508c382012-02-24 01:59:29 +00005029 LoadSubCommand ("symbols", CommandObjectSP (new CommandObjectTargetSymbols (interpreter)));
Greg Clayton801417e2011-07-07 01:59:51 +00005030 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00005031}
5032
5033CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
5034{
5035}
5036
Greg Claytonabe0fed2011-04-18 08:33:37 +00005037