blob: 1da39a5f4cc61a429ae69184d633256e84186e3c [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 Claytone1f50b92011-05-03 22:09:39 +000021#include "lldb/Core/Section.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000022#include "lldb/Core/State.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Core/Timer.h"
Greg Clayton801417e2011-07-07 01:59:51 +000024#include "lldb/Core/ValueObjectVariable.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Interpreter/CommandInterpreter.h"
26#include "lldb/Interpreter/CommandReturnObject.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000027#include "lldb/Interpreter/Options.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000028#include "lldb/Interpreter/OptionGroupArchitecture.h"
Greg Clayton5beb99d2011-08-11 02:48:45 +000029#include "lldb/Interpreter/OptionGroupBoolean.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000030#include "lldb/Interpreter/OptionGroupFile.h"
Greg Clayton368f8222011-07-07 04:38:25 +000031#include "lldb/Interpreter/OptionGroupVariable.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000032#include "lldb/Interpreter/OptionGroupPlatform.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000033#include "lldb/Interpreter/OptionGroupUInt64.h"
34#include "lldb/Interpreter/OptionGroupUUID.h"
Greg Clayton801417e2011-07-07 01:59:51 +000035#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000036#include "lldb/Symbol/LineTable.h"
37#include "lldb/Symbol/ObjectFile.h"
38#include "lldb/Symbol/SymbolFile.h"
39#include "lldb/Symbol/SymbolVendor.h"
Greg Clayton801417e2011-07-07 01:59:51 +000040#include "lldb/Symbol/VariableList.h"
Chris Lattner24943d22010-06-08 16:52:24 +000041#include "lldb/Target/Process.h"
42#include "lldb/Target/StackFrame.h"
43#include "lldb/Target/Thread.h"
Jim Inghamd60d94a2011-03-11 03:53:59 +000044#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000045
46using namespace lldb;
47using namespace lldb_private;
48
Greg Claytonabe0fed2011-04-18 08:33:37 +000049
50
51static void
52DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
53{
Greg Clayton52c8b6e2011-04-19 04:19:37 +000054 const ArchSpec &target_arch = target->GetArchitecture();
Greg Claytonabe0fed2011-04-18 08:33:37 +000055
Greg Clayton5beb99d2011-08-11 02:48:45 +000056 Module *exe_module = target->GetExecutableModulePointer();
Greg Claytonabe0fed2011-04-18 08:33:37 +000057 char exe_path[PATH_MAX];
58 bool exe_valid = false;
Greg Clayton5beb99d2011-08-11 02:48:45 +000059 if (exe_module)
60 exe_valid = exe_module->GetFileSpec().GetPath (exe_path, sizeof(exe_path));
Greg Claytonabe0fed2011-04-18 08:33:37 +000061
62 if (!exe_valid)
63 ::strcpy (exe_path, "<none>");
64
65 strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path);
66
67 uint32_t properties = 0;
68 if (target_arch.IsValid())
69 {
70 strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str());
71 properties++;
72 }
73 PlatformSP platform_sp (target->GetPlatform());
74 if (platform_sp)
75 strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName());
76
77 ProcessSP process_sp (target->GetProcessSP());
78 bool show_process_status = false;
79 if (process_sp)
80 {
81 lldb::pid_t pid = process_sp->GetID();
82 StateType state = process_sp->GetState();
83 if (show_stopped_process_status)
84 show_process_status = StateIsStoppedState(state);
85 const char *state_cstr = StateAsCString (state);
86 if (pid != LLDB_INVALID_PROCESS_ID)
87 strm.Printf ("%spid=%i", properties++ > 0 ? ", " : " ( ", pid);
88 strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
89 }
90 if (properties > 0)
91 strm.PutCString (" )\n");
92 else
93 strm.EOL();
94 if (show_process_status)
95 {
96 const bool only_threads_with_stop_reason = true;
97 const uint32_t start_frame = 0;
98 const uint32_t num_frames = 1;
99 const uint32_t num_frames_with_source = 1;
100 process_sp->GetStatus (strm);
101 process_sp->GetThreadStatus (strm,
102 only_threads_with_stop_reason,
103 start_frame,
104 num_frames,
105 num_frames_with_source);
106
107 }
108}
109
110static uint32_t
111DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm)
112{
113 const uint32_t num_targets = target_list.GetNumTargets();
114 if (num_targets)
115 {
116 TargetSP selected_target_sp (target_list.GetSelectedTarget());
117 strm.PutCString ("Current targets:\n");
118 for (uint32_t i=0; i<num_targets; ++i)
119 {
120 TargetSP target_sp (target_list.GetTargetAtIndex (i));
121 if (target_sp)
122 {
123 bool is_selected = target_sp.get() == selected_target_sp.get();
124 DumpTargetInfo (i,
125 target_sp.get(),
126 is_selected ? "* " : " ",
127 show_stopped_process_status,
128 strm);
129 }
130 }
131 }
132 return num_targets;
133}
134#pragma mark CommandObjectTargetCreate
135
136//-------------------------------------------------------------------------
137// "target create"
138//-------------------------------------------------------------------------
139
140class CommandObjectTargetCreate : public CommandObject
141{
142public:
143 CommandObjectTargetCreate(CommandInterpreter &interpreter) :
144 CommandObject (interpreter,
145 "target create",
146 "Create a target using the argument as the main executable.",
147 NULL),
148 m_option_group (interpreter),
Greg Clayton801417e2011-07-07 01:59:51 +0000149 m_arch_option (),
Greg Claytonabe0fed2011-04-18 08:33:37 +0000150 m_platform_options(true) // Do include the "--platform" option in the platform settings by passing true
151 {
152 CommandArgumentEntry arg;
153 CommandArgumentData file_arg;
154
155 // Define the first (and only) variant of this arg.
156 file_arg.arg_type = eArgTypeFilename;
157 file_arg.arg_repetition = eArgRepeatPlain;
158
159 // There is only one variant this argument could be; put it into the argument entry.
160 arg.push_back (file_arg);
161
162 // Push the data for the first argument into the m_arguments vector.
163 m_arguments.push_back (arg);
164
Greg Clayton801417e2011-07-07 01:59:51 +0000165 m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000166 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
167 m_option_group.Finalize();
168 }
169
170 ~CommandObjectTargetCreate ()
171 {
172 }
173
174 Options *
175 GetOptions ()
176 {
177 return &m_option_group;
178 }
179
180 bool
181 Execute (Args& command, CommandReturnObject &result)
182 {
183 const int argc = command.GetArgumentCount();
184 if (argc == 1)
185 {
186 const char *file_path = command.GetArgumentAtIndex(0);
187 Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path);
188 FileSpec file_spec (file_path, true);
189
190 bool select = true;
191 PlatformSP platform_sp;
192
193 Error error;
194
195 if (m_platform_options.PlatformWasSpecified ())
196 {
197 platform_sp = m_platform_options.CreatePlatformWithOptions(m_interpreter, select, error);
198 if (!platform_sp)
199 {
200 result.AppendError(error.AsCString());
201 result.SetStatus (eReturnStatusFailed);
202 return false;
203 }
204 }
205 ArchSpec file_arch;
206
Greg Clayton801417e2011-07-07 01:59:51 +0000207 const char *arch_cstr = m_arch_option.GetArchitectureName();
Greg Claytonabe0fed2011-04-18 08:33:37 +0000208 if (arch_cstr)
209 {
210 if (!platform_sp)
211 platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
Greg Clayton801417e2011-07-07 01:59:51 +0000212 if (!m_arch_option.GetArchitecture(platform_sp.get(), file_arch))
Greg Claytonabe0fed2011-04-18 08:33:37 +0000213 {
214 result.AppendErrorWithFormat("invalid architecture '%s'\n", arch_cstr);
215 result.SetStatus (eReturnStatusFailed);
216 return false;
217 }
218 }
219
220 if (! file_spec.Exists() && !file_spec.ResolveExecutableLocation())
221 {
222 result.AppendErrorWithFormat ("File '%s' does not exist.\n", file_path);
223 result.SetStatus (eReturnStatusFailed);
224 return false;
225 }
226
227 TargetSP target_sp;
228 Debugger &debugger = m_interpreter.GetDebugger();
229 error = debugger.GetTargetList().CreateTarget (debugger, file_spec, file_arch, true, target_sp);
230
231 if (target_sp)
232 {
233 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
234 result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName());
235 result.SetStatus (eReturnStatusSuccessFinishNoResult);
236 }
237 else
238 {
239 result.AppendError(error.AsCString());
240 result.SetStatus (eReturnStatusFailed);
241 }
242 }
243 else
244 {
245 result.AppendErrorWithFormat("'%s' takes exactly one executable path argument.\n", m_cmd_name.c_str());
246 result.SetStatus (eReturnStatusFailed);
247 }
248 return result.Succeeded();
249
250 }
251
252 int
253 HandleArgumentCompletion (Args &input,
254 int &cursor_index,
255 int &cursor_char_position,
256 OptionElementVector &opt_element_vector,
257 int match_start_point,
258 int max_return_elements,
259 bool &word_complete,
260 StringList &matches)
261 {
262 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
263 completion_str.erase (cursor_char_position);
264
265 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
266 CommandCompletions::eDiskFileCompletion,
267 completion_str.c_str(),
268 match_start_point,
269 max_return_elements,
270 NULL,
271 word_complete,
272 matches);
273 return matches.GetSize();
274 }
275private:
276 OptionGroupOptions m_option_group;
Greg Clayton801417e2011-07-07 01:59:51 +0000277 OptionGroupArchitecture m_arch_option;
Greg Claytonabe0fed2011-04-18 08:33:37 +0000278 OptionGroupPlatform m_platform_options;
279
280};
281
282#pragma mark CommandObjectTargetList
283
284//----------------------------------------------------------------------
285// "target list"
286//----------------------------------------------------------------------
287
288class CommandObjectTargetList : public CommandObject
289{
290public:
291 CommandObjectTargetList (CommandInterpreter &interpreter) :
292 CommandObject (interpreter,
293 "target list",
294 "List all current targets in the current debug session.",
295 NULL,
296 0)
297 {
298 }
299
300 virtual
301 ~CommandObjectTargetList ()
302 {
303 }
304
305 virtual bool
306 Execute (Args& args, CommandReturnObject &result)
307 {
308 if (args.GetArgumentCount() == 0)
309 {
310 Stream &strm = result.GetOutputStream();
311
312 bool show_stopped_process_status = false;
313 if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0)
314 {
315 strm.PutCString ("No targets.\n");
316 }
Johnny Chen44dc9d32011-04-18 21:08:05 +0000317 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000318 }
319 else
320 {
321 result.AppendError ("the 'target list' command takes no arguments\n");
322 result.SetStatus (eReturnStatusFailed);
323 }
324 return result.Succeeded();
325 }
326};
327
328
329#pragma mark CommandObjectTargetSelect
330
331//----------------------------------------------------------------------
332// "target select"
333//----------------------------------------------------------------------
334
335class CommandObjectTargetSelect : public CommandObject
336{
337public:
338 CommandObjectTargetSelect (CommandInterpreter &interpreter) :
339 CommandObject (interpreter,
340 "target select",
341 "Select a target as the current target by target index.",
342 NULL,
343 0)
344 {
345 }
346
347 virtual
348 ~CommandObjectTargetSelect ()
349 {
350 }
351
352 virtual bool
353 Execute (Args& args, CommandReturnObject &result)
354 {
355 if (args.GetArgumentCount() == 1)
356 {
357 bool success = false;
358 const char *target_idx_arg = args.GetArgumentAtIndex(0);
359 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
360 if (success)
361 {
362 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
363 const uint32_t num_targets = target_list.GetNumTargets();
364 if (target_idx < num_targets)
365 {
366 TargetSP target_sp (target_list.GetTargetAtIndex (target_idx));
367 if (target_sp)
368 {
369 Stream &strm = result.GetOutputStream();
370 target_list.SetSelectedTarget (target_sp.get());
371 bool show_stopped_process_status = false;
372 DumpTargetList (target_list, show_stopped_process_status, strm);
Johnny Chen44dc9d32011-04-18 21:08:05 +0000373 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000374 }
375 else
376 {
377 result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx);
378 result.SetStatus (eReturnStatusFailed);
379 }
380 }
381 else
382 {
383 result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n",
384 target_idx,
385 num_targets - 1);
386 result.SetStatus (eReturnStatusFailed);
387 }
388 }
389 else
390 {
391 result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg);
392 result.SetStatus (eReturnStatusFailed);
393 }
394 }
395 else
396 {
397 result.AppendError ("'target select' takes a single argument: a target index\n");
398 result.SetStatus (eReturnStatusFailed);
399 }
400 return result.Succeeded();
401 }
402};
403
Greg Clayton153ccd72011-08-10 02:10:13 +0000404#pragma mark CommandObjectTargetSelect
405
406//----------------------------------------------------------------------
407// "target delete"
408//----------------------------------------------------------------------
409
410class CommandObjectTargetDelete : public CommandObject
411{
412public:
413 CommandObjectTargetDelete (CommandInterpreter &interpreter) :
Greg Clayton5beb99d2011-08-11 02:48:45 +0000414 CommandObject (interpreter,
415 "target delete",
416 "Delete one or more targets by target index.",
417 NULL,
418 0),
419 m_option_group (interpreter),
420 m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', 0, eArgTypeNone, "Perform extra cleanup to minimize memory consumption after deleting the target.", false)
Greg Clayton153ccd72011-08-10 02:10:13 +0000421 {
Greg Clayton5beb99d2011-08-11 02:48:45 +0000422 m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
423 m_option_group.Finalize();
Greg Clayton153ccd72011-08-10 02:10:13 +0000424 }
425
426 virtual
427 ~CommandObjectTargetDelete ()
428 {
429 }
430
431 virtual bool
432 Execute (Args& args, CommandReturnObject &result)
433 {
434 const size_t argc = args.GetArgumentCount();
435 std::vector<TargetSP> delete_target_list;
436 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
437 bool success = true;
438 TargetSP target_sp;
439 if (argc > 0)
440 {
441 const uint32_t num_targets = target_list.GetNumTargets();
442 for (uint32_t arg_idx = 0; success && arg_idx < argc; ++arg_idx)
443 {
444 const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx);
445 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
446 if (success)
447 {
448 if (target_idx < num_targets)
449 {
450 target_sp = target_list.GetTargetAtIndex (target_idx);
451 if (target_sp)
452 {
453 delete_target_list.push_back (target_sp);
454 continue;
455 }
456 }
457 result.AppendErrorWithFormat ("target index %u is out of range, valid target indexes are 0 - %u\n",
458 target_idx,
459 num_targets - 1);
460 result.SetStatus (eReturnStatusFailed);
461 success = false;
462 }
463 else
464 {
465 result.AppendErrorWithFormat("invalid target index '%s'\n", target_idx_arg);
466 result.SetStatus (eReturnStatusFailed);
467 success = false;
468 }
469 }
470
471 }
472 else
473 {
474 target_sp = target_list.GetSelectedTarget();
475 if (target_sp)
476 {
477 delete_target_list.push_back (target_sp);
478 }
479 else
480 {
481 result.AppendErrorWithFormat("no target is currently selected\n");
482 result.SetStatus (eReturnStatusFailed);
483 success = false;
484 }
485 }
486 if (success)
487 {
488 const size_t num_targets_to_delete = delete_target_list.size();
489 for (size_t idx = 0; idx < num_targets_to_delete; ++idx)
490 {
491 target_sp = delete_target_list[idx];
492 target_list.DeleteTarget(target_sp);
493 target_sp->Destroy();
494 }
Greg Clayton5beb99d2011-08-11 02:48:45 +0000495 // If "--clean" was specified, prune any orphaned shared modules from
496 // the global shared module list
497 if (m_cleanup_option.GetOptionValue ())
498 {
499 ModuleList::RemoveOrphanSharedModules();
500 }
Greg Clayton153ccd72011-08-10 02:10:13 +0000501 result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete);
502 result.SetStatus(eReturnStatusSuccessFinishResult);
503 }
504
505 return result.Succeeded();
506 }
Greg Clayton5beb99d2011-08-11 02:48:45 +0000507
508 Options *
509 GetOptions ()
510 {
511 return &m_option_group;
512 }
513
514protected:
515 OptionGroupOptions m_option_group;
516 OptionGroupBoolean m_cleanup_option;
Greg Clayton153ccd72011-08-10 02:10:13 +0000517};
518
Greg Claytonabe0fed2011-04-18 08:33:37 +0000519
Greg Clayton801417e2011-07-07 01:59:51 +0000520#pragma mark CommandObjectTargetVariable
521
522//----------------------------------------------------------------------
523// "target variable"
524//----------------------------------------------------------------------
525
526class CommandObjectTargetVariable : public CommandObject
527{
528public:
529 CommandObjectTargetVariable (CommandInterpreter &interpreter) :
530 CommandObject (interpreter,
Johnny Chen34bfa4f2011-07-12 22:34:30 +0000531 "target variable",
532 "Read global variable(s) prior to running your binary.",
Greg Clayton801417e2011-07-07 01:59:51 +0000533 NULL,
534 0),
535 m_option_group (interpreter),
Greg Clayton368f8222011-07-07 04:38:25 +0000536 m_option_variable (false), // Don't include frame options
Greg Clayton801417e2011-07-07 01:59:51 +0000537 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."),
538 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."),
539 m_varobj_options()
540 {
541 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Clayton368f8222011-07-07 04:38:25 +0000542 m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Clayton801417e2011-07-07 01:59:51 +0000543 m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
544 m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
545 m_option_group.Finalize();
546 }
547
548 virtual
549 ~CommandObjectTargetVariable ()
550 {
551 }
Greg Clayton5d81f492011-07-08 21:46:14 +0000552
553 void
554 DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name)
555 {
556 if (m_option_variable.format != eFormatDefault)
557 valobj_sp->SetFormat (m_option_variable.format);
558
559 switch (var_sp->GetScope())
560 {
561 case eValueTypeVariableGlobal:
562 if (m_option_variable.show_scope)
563 s.PutCString("GLOBAL: ");
564 break;
565
566 case eValueTypeVariableStatic:
567 if (m_option_variable.show_scope)
568 s.PutCString("STATIC: ");
569 break;
570
571 case eValueTypeVariableArgument:
572 if (m_option_variable.show_scope)
573 s.PutCString(" ARG: ");
574 break;
575
576 case eValueTypeVariableLocal:
577 if (m_option_variable.show_scope)
578 s.PutCString(" LOCAL: ");
579 break;
580
581 default:
582 break;
583 }
584
Greg Claytonfb816422011-07-10 19:21:23 +0000585 if (m_option_variable.show_decl)
Greg Clayton5d81f492011-07-08 21:46:14 +0000586 {
Greg Claytonfb816422011-07-10 19:21:23 +0000587 bool show_fullpaths = false;
588 bool show_module = true;
589 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
590 s.PutCString (": ");
Greg Clayton5d81f492011-07-08 21:46:14 +0000591 }
592
593 const Format format = m_option_variable.format;
594 if (format != eFormatDefault)
595 valobj_sp->SetFormat (format);
596
597 ValueObject::DumpValueObject (s,
598 valobj_sp.get(),
599 root_name,
600 m_varobj_options.ptr_depth,
601 0,
602 m_varobj_options.max_depth,
603 m_varobj_options.show_types,
604 m_varobj_options.show_location,
605 m_varobj_options.use_objc,
606 m_varobj_options.use_dynamic,
Enrico Granata840eb262011-08-09 23:50:01 +0000607 m_varobj_options.be_raw ? false : m_varobj_options.use_synth,
Greg Clayton5d81f492011-07-08 21:46:14 +0000608 false,
Enrico Granata7f163b32011-07-16 01:22:04 +0000609 m_varobj_options.flat_output,
Enrico Granata018921d2011-08-12 02:00:06 +0000610 m_varobj_options.be_raw ? UINT32_MAX : m_varobj_options.no_summary_depth,
611 m_varobj_options.be_raw ? true : m_varobj_options.ignore_cap);
Greg Clayton5d81f492011-07-08 21:46:14 +0000612
613 }
Greg Clayton801417e2011-07-07 01:59:51 +0000614
Greg Clayton5d81f492011-07-08 21:46:14 +0000615
616 static uint32_t GetVariableCallback (void *baton,
617 const char *name,
618 VariableList &variable_list)
619 {
620 Target *target = static_cast<Target *>(baton);
621 if (target)
622 {
623 return target->GetImages().FindGlobalVariables (ConstString(name),
624 true,
625 UINT32_MAX,
626 variable_list);
627 }
628 return 0;
629 }
630
631
632
Greg Clayton801417e2011-07-07 01:59:51 +0000633 virtual bool
634 Execute (Args& args, CommandReturnObject &result)
635 {
636 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
637
638 if (exe_ctx.target)
639 {
640 const size_t argc = args.GetArgumentCount();
641 if (argc > 0)
642 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000643 Stream &s = result.GetOutputStream();
644
Greg Clayton801417e2011-07-07 01:59:51 +0000645 for (size_t idx = 0; idx < argc; ++idx)
646 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000647 VariableList variable_list;
648 ValueObjectList valobj_list;
649
Greg Clayton368f8222011-07-07 04:38:25 +0000650 const char *arg = args.GetArgumentAtIndex(idx);
651 uint32_t matches = 0;
Greg Claytonfb816422011-07-10 19:21:23 +0000652 bool use_var_name = false;
Greg Clayton368f8222011-07-07 04:38:25 +0000653 if (m_option_variable.use_regex)
Greg Clayton801417e2011-07-07 01:59:51 +0000654 {
Greg Clayton368f8222011-07-07 04:38:25 +0000655 RegularExpression regex(arg);
656 if (!regex.IsValid ())
657 {
658 result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg);
659 result.SetStatus (eReturnStatusFailed);
660 return false;
661 }
Greg Claytonfb816422011-07-10 19:21:23 +0000662 use_var_name = true;
Greg Clayton368f8222011-07-07 04:38:25 +0000663 matches = exe_ctx.target->GetImages().FindGlobalVariables (regex,
664 true,
665 UINT32_MAX,
Greg Clayton5d81f492011-07-08 21:46:14 +0000666 variable_list);
Greg Clayton801417e2011-07-07 01:59:51 +0000667 }
668 else
669 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000670 Error error (Variable::GetValuesForVariableExpressionPath (arg,
Greg Clayton24b03102011-07-09 20:12:33 +0000671 exe_ctx.GetBestExecutionContextScope(),
Greg Clayton5d81f492011-07-08 21:46:14 +0000672 GetVariableCallback,
673 exe_ctx.target,
674 variable_list,
675 valobj_list));
676
677// matches = exe_ctx.target->GetImages().FindGlobalVariables (ConstString(arg),
678// true,
679// UINT32_MAX,
680// variable_list);
681 matches = variable_list.GetSize();
Greg Clayton368f8222011-07-07 04:38:25 +0000682 }
683
684 if (matches == 0)
685 {
686 result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg);
687 result.SetStatus (eReturnStatusFailed);
688 return false;
689 }
690 else
691 {
Greg Clayton801417e2011-07-07 01:59:51 +0000692 for (uint32_t global_idx=0; global_idx<matches; ++global_idx)
693 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000694 VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx));
Greg Clayton801417e2011-07-07 01:59:51 +0000695 if (var_sp)
696 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000697 ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx));
698 if (!valobj_sp)
Greg Claytonfb816422011-07-10 19:21:23 +0000699 valobj_sp = ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp);
Greg Clayton801417e2011-07-07 01:59:51 +0000700
701 if (valobj_sp)
Greg Claytonfb816422011-07-10 19:21:23 +0000702 DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg);
Greg Clayton801417e2011-07-07 01:59:51 +0000703 }
704 }
705 }
706 }
707 }
708 else
709 {
710 result.AppendError ("'target variable' takes one or more global variable names as arguments\n");
711 result.SetStatus (eReturnStatusFailed);
712 }
713 }
714 else
715 {
716 result.AppendError ("invalid target, create a debug target using the 'target create' command");
717 result.SetStatus (eReturnStatusFailed);
718 return false;
719 }
720 return result.Succeeded();
721 }
722
723 Options *
724 GetOptions ()
725 {
726 return &m_option_group;
727 }
728
729protected:
730 OptionGroupOptions m_option_group;
Greg Clayton368f8222011-07-07 04:38:25 +0000731 OptionGroupVariable m_option_variable;
Greg Clayton801417e2011-07-07 01:59:51 +0000732 OptionGroupFileList m_option_compile_units;
733 OptionGroupFileList m_option_shared_libraries;
734 OptionGroupValueObjectDisplay m_varobj_options;
735
736};
737
738
Greg Claytone1f50b92011-05-03 22:09:39 +0000739#pragma mark CommandObjectTargetModulesSearchPathsAdd
Chris Lattner24943d22010-06-08 16:52:24 +0000740
Greg Claytone1f50b92011-05-03 22:09:39 +0000741class CommandObjectTargetModulesSearchPathsAdd : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000742{
743public:
744
Greg Claytone1f50b92011-05-03 22:09:39 +0000745 CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000746 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000747 "target modules search-paths add",
Chris Lattner24943d22010-06-08 16:52:24 +0000748 "Add new image search paths substitution pairs to the current target.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000749 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000750 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000751 CommandArgumentEntry arg;
752 CommandArgumentData old_prefix_arg;
753 CommandArgumentData new_prefix_arg;
754
755 // Define the first variant of this arg pair.
756 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
757 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
758
759 // Define the first variant of this arg pair.
760 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
761 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
762
763 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
764 // must always occur together, they are treated as two variants of one argument rather than two independent
765 // arguments. Push them both into the first argument position for m_arguments...
766
767 arg.push_back (old_prefix_arg);
768 arg.push_back (new_prefix_arg);
769
770 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000771 }
772
Greg Claytone1f50b92011-05-03 22:09:39 +0000773 ~CommandObjectTargetModulesSearchPathsAdd ()
Chris Lattner24943d22010-06-08 16:52:24 +0000774 {
775 }
776
777 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000778 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000779 CommandReturnObject &result)
780 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000781 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000782 if (target)
783 {
784 uint32_t argc = command.GetArgumentCount();
785 if (argc & 1)
786 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000787 result.AppendError ("add requires an even number of arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000788 result.SetStatus (eReturnStatusFailed);
789 }
790 else
791 {
792 for (uint32_t i=0; i<argc; i+=2)
793 {
794 const char *from = command.GetArgumentAtIndex(i);
795 const char *to = command.GetArgumentAtIndex(i+1);
796
797 if (from[0] && to[0])
798 {
799 bool last_pair = ((argc - i) == 2);
Greg Clayton63094e02010-06-23 01:19:29 +0000800 target->GetImageSearchPathList().Append (ConstString(from),
801 ConstString(to),
802 last_pair); // Notify if this is the last pair
Johnny Chen4d661352011-02-03 00:30:19 +0000803 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000804 }
805 else
806 {
807 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +0000808 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000809 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000810 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000811 result.SetStatus (eReturnStatusFailed);
812 }
813 }
814 }
815 }
816 else
817 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000818 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000819 result.SetStatus (eReturnStatusFailed);
820 }
821 return result.Succeeded();
822 }
823};
824
Greg Claytone1f50b92011-05-03 22:09:39 +0000825#pragma mark CommandObjectTargetModulesSearchPathsClear
826
827class CommandObjectTargetModulesSearchPathsClear : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000828{
829public:
830
Greg Claytone1f50b92011-05-03 22:09:39 +0000831 CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000832 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000833 "target modules search-paths clear",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000834 "Clear all current image search path substitution pairs from the current target.",
Greg Claytone1f50b92011-05-03 22:09:39 +0000835 "target modules search-paths clear")
Chris Lattner24943d22010-06-08 16:52:24 +0000836 {
837 }
838
Greg Claytone1f50b92011-05-03 22:09:39 +0000839 ~CommandObjectTargetModulesSearchPathsClear ()
Chris Lattner24943d22010-06-08 16:52:24 +0000840 {
841 }
842
843 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000844 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000845 CommandReturnObject &result)
846 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000847 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000848 if (target)
849 {
850 bool notify = true;
851 target->GetImageSearchPathList().Clear(notify);
Johnny Chen4d661352011-02-03 00:30:19 +0000852 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000853 }
854 else
855 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000856 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000857 result.SetStatus (eReturnStatusFailed);
858 }
859 return result.Succeeded();
860 }
861};
862
Greg Claytone1f50b92011-05-03 22:09:39 +0000863#pragma mark CommandObjectTargetModulesSearchPathsInsert
864
865class CommandObjectTargetModulesSearchPathsInsert : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000866{
867public:
868
Greg Claytone1f50b92011-05-03 22:09:39 +0000869 CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000870 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000871 "target modules search-paths insert",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000872 "Insert a new image search path substitution pair into the current target at the specified index.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000873 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000874 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000875 CommandArgumentEntry arg1;
876 CommandArgumentEntry arg2;
877 CommandArgumentData index_arg;
878 CommandArgumentData old_prefix_arg;
879 CommandArgumentData new_prefix_arg;
880
881 // Define the first and only variant of this arg.
882 index_arg.arg_type = eArgTypeIndex;
883 index_arg.arg_repetition = eArgRepeatPlain;
884
885 // Put the one and only variant into the first arg for m_arguments:
886 arg1.push_back (index_arg);
887
888 // Define the first variant of this arg pair.
889 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
890 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
891
892 // Define the first variant of this arg pair.
893 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
894 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
895
896 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
897 // must always occur together, they are treated as two variants of one argument rather than two independent
898 // arguments. Push them both into the same argument position for m_arguments...
899
900 arg2.push_back (old_prefix_arg);
901 arg2.push_back (new_prefix_arg);
902
903 // Add arguments to m_arguments.
904 m_arguments.push_back (arg1);
905 m_arguments.push_back (arg2);
Chris Lattner24943d22010-06-08 16:52:24 +0000906 }
907
Greg Claytone1f50b92011-05-03 22:09:39 +0000908 ~CommandObjectTargetModulesSearchPathsInsert ()
Chris Lattner24943d22010-06-08 16:52:24 +0000909 {
910 }
911
912 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000913 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000914 CommandReturnObject &result)
915 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000916 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000917 if (target)
918 {
919 uint32_t argc = command.GetArgumentCount();
920 // check for at least 3 arguments and an odd nubmer of parameters
921 if (argc >= 3 && argc & 1)
922 {
923 bool success = false;
924
925 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
926
927 if (!success)
928 {
929 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
930 result.SetStatus (eReturnStatusFailed);
931 return result.Succeeded();
932 }
933
934 // shift off the index
935 command.Shift();
936 argc = command.GetArgumentCount();
937
938 for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
939 {
940 const char *from = command.GetArgumentAtIndex(i);
941 const char *to = command.GetArgumentAtIndex(i+1);
942
943 if (from[0] && to[0])
944 {
945 bool last_pair = ((argc - i) == 2);
946 target->GetImageSearchPathList().Insert (ConstString(from),
947 ConstString(to),
948 insert_idx,
949 last_pair);
Johnny Chen4d661352011-02-03 00:30:19 +0000950 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000951 }
952 else
953 {
954 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +0000955 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000956 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000957 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000958 result.SetStatus (eReturnStatusFailed);
959 return false;
960 }
961 }
962 }
963 else
964 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000965 result.AppendError ("insert requires at least three arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000966 result.SetStatus (eReturnStatusFailed);
967 return result.Succeeded();
968 }
969
970 }
971 else
972 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000973 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000974 result.SetStatus (eReturnStatusFailed);
975 }
976 return result.Succeeded();
977 }
978};
979
Greg Claytone1f50b92011-05-03 22:09:39 +0000980
981#pragma mark CommandObjectTargetModulesSearchPathsList
982
983
984class CommandObjectTargetModulesSearchPathsList : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000985{
986public:
987
Greg Claytone1f50b92011-05-03 22:09:39 +0000988 CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000989 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000990 "target modules search-paths list",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000991 "List all current image search path substitution pairs in the current target.",
Greg Claytone1f50b92011-05-03 22:09:39 +0000992 "target modules search-paths list")
Chris Lattner24943d22010-06-08 16:52:24 +0000993 {
994 }
995
Greg Claytone1f50b92011-05-03 22:09:39 +0000996 ~CommandObjectTargetModulesSearchPathsList ()
Chris Lattner24943d22010-06-08 16:52:24 +0000997 {
998 }
999
1000 bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001001 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001002 CommandReturnObject &result)
1003 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001004 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001005 if (target)
1006 {
1007 if (command.GetArgumentCount() != 0)
1008 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001009 result.AppendError ("list takes no arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001010 result.SetStatus (eReturnStatusFailed);
1011 return result.Succeeded();
1012 }
1013
1014 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
Johnny Chen4d661352011-02-03 00:30:19 +00001015 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001016 }
1017 else
1018 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001019 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001020 result.SetStatus (eReturnStatusFailed);
1021 }
1022 return result.Succeeded();
1023 }
1024};
1025
Greg Claytone1f50b92011-05-03 22:09:39 +00001026#pragma mark CommandObjectTargetModulesSearchPathsQuery
1027
1028class CommandObjectTargetModulesSearchPathsQuery : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +00001029{
1030public:
1031
Greg Claytone1f50b92011-05-03 22:09:39 +00001032 CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001033 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +00001034 "target modules search-paths query",
Caroline Ticeabb507a2010-09-08 21:06:11 +00001035 "Transform a path using the first applicable image search path.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001036 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001037 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001038 CommandArgumentEntry arg;
1039 CommandArgumentData path_arg;
1040
1041 // Define the first (and only) variant of this arg.
1042 path_arg.arg_type = eArgTypePath;
1043 path_arg.arg_repetition = eArgRepeatPlain;
1044
1045 // There is only one variant this argument could be; put it into the argument entry.
1046 arg.push_back (path_arg);
1047
1048 // Push the data for the first argument into the m_arguments vector.
1049 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001050 }
1051
Greg Claytone1f50b92011-05-03 22:09:39 +00001052 ~CommandObjectTargetModulesSearchPathsQuery ()
Chris Lattner24943d22010-06-08 16:52:24 +00001053 {
1054 }
1055
1056 bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001057 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001058 CommandReturnObject &result)
1059 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001060 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001061 if (target)
1062 {
1063 if (command.GetArgumentCount() != 1)
1064 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001065 result.AppendError ("query requires one argument\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001066 result.SetStatus (eReturnStatusFailed);
1067 return result.Succeeded();
1068 }
1069
1070 ConstString orig(command.GetArgumentAtIndex(0));
1071 ConstString transformed;
1072 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1073 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1074 else
1075 result.GetOutputStream().Printf("%s\n", orig.GetCString());
Johnny Chen4d661352011-02-03 00:30:19 +00001076
1077 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001078 }
1079 else
1080 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001081 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001082 result.SetStatus (eReturnStatusFailed);
1083 }
1084 return result.Succeeded();
1085 }
1086};
1087
Greg Claytone1f50b92011-05-03 22:09:39 +00001088//----------------------------------------------------------------------
1089// Static Helper functions
1090//----------------------------------------------------------------------
1091static void
1092DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width)
1093{
1094 if (module)
1095 {
1096 const char *arch_cstr;
1097 if (full_triple)
1098 arch_cstr = module->GetArchitecture().GetTriple().str().c_str();
1099 else
1100 arch_cstr = module->GetArchitecture().GetArchitectureName();
1101 if (width)
1102 strm.Printf("%-*s", width, arch_cstr);
1103 else
1104 strm.PutCString(arch_cstr);
1105 }
1106}
1107
1108static void
1109DumpModuleUUID (Stream &strm, Module *module)
1110{
Greg Clayton153ccd72011-08-10 02:10:13 +00001111 if (module->GetUUID().IsValid())
1112 module->GetUUID().Dump (&strm);
1113 else
1114 strm.PutCString(" ");
Greg Claytone1f50b92011-05-03 22:09:39 +00001115}
1116
1117static uint32_t
1118DumpCompileUnitLineTable
1119(
1120 CommandInterpreter &interpreter,
1121 Stream &strm,
1122 Module *module,
1123 const FileSpec &file_spec,
1124 bool load_addresses
1125 )
1126{
1127 uint32_t num_matches = 0;
1128 if (module)
1129 {
1130 SymbolContextList sc_list;
1131 num_matches = module->ResolveSymbolContextsForFileSpec (file_spec,
1132 0,
1133 false,
1134 eSymbolContextCompUnit,
1135 sc_list);
1136
1137 for (uint32_t i=0; i<num_matches; ++i)
1138 {
1139 SymbolContext sc;
1140 if (sc_list.GetContextAtIndex(i, sc))
1141 {
1142 if (i > 0)
1143 strm << "\n\n";
1144
1145 strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `"
1146 << module->GetFileSpec().GetFilename() << "\n";
1147 LineTable *line_table = sc.comp_unit->GetLineTable();
1148 if (line_table)
1149 line_table->GetDescription (&strm,
1150 interpreter.GetExecutionContext().target,
1151 lldb::eDescriptionLevelBrief);
1152 else
1153 strm << "No line table";
1154 }
1155 }
1156 }
1157 return num_matches;
1158}
1159
1160static void
1161DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1162{
1163 if (file_spec_ptr)
1164 {
1165 if (width > 0)
1166 {
1167 char fullpath[PATH_MAX];
1168 if (file_spec_ptr->GetPath(fullpath, sizeof(fullpath)))
1169 {
1170 strm.Printf("%-*s", width, fullpath);
1171 return;
1172 }
1173 }
1174 else
1175 {
1176 file_spec_ptr->Dump(&strm);
1177 return;
1178 }
1179 }
1180 // Keep the width spacing correct if things go wrong...
1181 if (width > 0)
1182 strm.Printf("%-*s", width, "");
1183}
1184
1185static void
1186DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1187{
1188 if (file_spec_ptr)
1189 {
1190 if (width > 0)
1191 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1192 else
1193 file_spec_ptr->GetDirectory().Dump(&strm);
1194 return;
1195 }
1196 // Keep the width spacing correct if things go wrong...
1197 if (width > 0)
1198 strm.Printf("%-*s", width, "");
1199}
1200
1201static void
1202DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1203{
1204 if (file_spec_ptr)
1205 {
1206 if (width > 0)
1207 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1208 else
1209 file_spec_ptr->GetFilename().Dump(&strm);
1210 return;
1211 }
1212 // Keep the width spacing correct if things go wrong...
1213 if (width > 0)
1214 strm.Printf("%-*s", width, "");
1215}
1216
1217
1218static void
1219DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order)
1220{
1221 if (module)
1222 {
1223 ObjectFile *objfile = module->GetObjectFile ();
1224 if (objfile)
1225 {
1226 Symtab *symtab = objfile->GetSymtab();
1227 if (symtab)
1228 symtab->Dump(&strm, interpreter.GetExecutionContext().target, sort_order);
1229 }
1230 }
1231}
1232
1233static void
1234DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module)
1235{
1236 if (module)
1237 {
1238 ObjectFile *objfile = module->GetObjectFile ();
1239 if (objfile)
1240 {
1241 SectionList *section_list = objfile->GetSectionList();
1242 if (section_list)
1243 {
1244 strm.PutCString ("Sections for '");
1245 strm << module->GetFileSpec();
1246 if (module->GetObjectName())
1247 strm << '(' << module->GetObjectName() << ')';
1248 strm.Printf ("' (%s):\n", module->GetArchitecture().GetArchitectureName());
1249 strm.IndentMore();
1250 section_list->Dump(&strm, interpreter.GetExecutionContext().target, true, UINT32_MAX);
1251 strm.IndentLess();
1252 }
1253 }
1254 }
1255}
1256
1257static bool
1258DumpModuleSymbolVendor (Stream &strm, Module *module)
1259{
1260 if (module)
1261 {
1262 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1263 if (symbol_vendor)
1264 {
1265 symbol_vendor->Dump(&strm);
1266 return true;
1267 }
1268 }
1269 return false;
1270}
1271
1272static bool
1273LookupAddressInModule
1274(
1275 CommandInterpreter &interpreter,
1276 Stream &strm,
1277 Module *module,
1278 uint32_t resolve_mask,
1279 lldb::addr_t raw_addr,
1280 lldb::addr_t offset,
1281 bool verbose
1282 )
1283{
1284 if (module)
1285 {
1286 lldb::addr_t addr = raw_addr - offset;
1287 Address so_addr;
1288 SymbolContext sc;
1289 Target *target = interpreter.GetExecutionContext().target;
1290 if (target && !target->GetSectionLoadList().IsEmpty())
1291 {
1292 if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr))
1293 return false;
1294 else if (so_addr.GetModule() != module)
1295 return false;
1296 }
1297 else
1298 {
1299 if (!module->ResolveFileAddress (addr, so_addr))
1300 return false;
1301 }
1302
1303 // If an offset was given, print out the address we ended up looking up
1304 if (offset)
1305 strm.Printf("File Address: 0x%llx\n", addr);
1306
1307 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope();
1308 strm.IndentMore();
1309 strm.Indent (" Address: ");
1310 so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1311 strm.EOL();
1312 strm.Indent (" Summary: ");
1313 const uint32_t save_indent = strm.GetIndentLevel ();
1314 strm.SetIndentLevel (save_indent + 11);
1315 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
1316 strm.SetIndentLevel (save_indent);
1317 strm.EOL();
1318 // Print out detailed address information when verbose is enabled
1319 if (verbose)
1320 {
1321 if (so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext))
1322 strm.EOL();
1323 }
1324 strm.IndentLess();
1325 return true;
1326 }
1327
1328 return false;
1329}
1330
1331static uint32_t
1332LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
1333{
1334 if (module)
1335 {
1336 SymbolContext sc;
1337
1338 ObjectFile *objfile = module->GetObjectFile ();
1339 if (objfile)
1340 {
1341 Symtab *symtab = objfile->GetSymtab();
1342 if (symtab)
1343 {
1344 uint32_t i;
1345 std::vector<uint32_t> match_indexes;
1346 ConstString symbol_name (name);
1347 uint32_t num_matches = 0;
1348 if (name_is_regex)
1349 {
1350 RegularExpression name_regexp(name);
1351 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp,
1352 eSymbolTypeAny,
1353 match_indexes);
1354 }
1355 else
1356 {
1357 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
1358 }
1359
1360
1361 if (num_matches > 0)
1362 {
1363 strm.Indent ();
1364 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1365 name_is_regex ? "the regular expression " : "", name);
1366 DumpFullpath (strm, &module->GetFileSpec(), 0);
1367 strm.PutCString(":\n");
1368 strm.IndentMore ();
1369 Symtab::DumpSymbolHeader (&strm);
1370 for (i=0; i < num_matches; ++i)
1371 {
1372 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1373 strm.Indent ();
1374 symbol->Dump (&strm, interpreter.GetExecutionContext().target, i);
1375 }
1376 strm.IndentLess ();
1377 return num_matches;
1378 }
1379 }
1380 }
1381 }
1382 return 0;
1383}
1384
1385
1386static void
1387DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr, bool verbose)
1388{
1389 strm.IndentMore ();
1390 uint32_t i;
1391 const uint32_t num_matches = sc_list.GetSize();
1392
1393 for (i=0; i<num_matches; ++i)
1394 {
1395 SymbolContext sc;
1396 if (sc_list.GetContextAtIndex(i, sc))
1397 {
1398 strm.Indent();
1399 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope ();
1400
1401 if (prepend_addr)
1402 {
1403 if (sc.line_entry.range.GetBaseAddress().IsValid())
1404 {
1405 sc.line_entry.range.GetBaseAddress().Dump (&strm,
1406 exe_scope,
1407 Address::DumpStyleLoadAddress,
1408 Address::DumpStyleModuleWithFileAddress);
1409 strm.PutCString(" in ");
1410 }
1411 }
1412 sc.DumpStopContext(&strm,
1413 exe_scope,
1414 sc.line_entry.range.GetBaseAddress(),
1415 true,
1416 true,
1417 false);
1418 strm.EOL();
1419 if (verbose)
1420 {
1421 if (sc.line_entry.range.GetBaseAddress().IsValid())
1422 {
1423 if (sc.line_entry.range.GetBaseAddress().Dump (&strm,
1424 exe_scope,
1425 Address::DumpStyleDetailedSymbolContext))
1426 strm.PutCString("\n\n");
1427 }
1428 else if (sc.function->GetAddressRange().GetBaseAddress().IsValid())
1429 {
1430 if (sc.function->GetAddressRange().GetBaseAddress().Dump (&strm,
1431 exe_scope,
1432 Address::DumpStyleDetailedSymbolContext))
1433 strm.PutCString("\n\n");
1434 }
1435 }
1436 }
1437 }
1438 strm.IndentLess ();
1439}
1440
1441static uint32_t
1442LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose)
1443{
1444 if (module && name && name[0])
1445 {
1446 SymbolContextList sc_list;
1447 const bool include_symbols = false;
1448 const bool append = true;
1449 uint32_t num_matches = 0;
1450 if (name_is_regex)
1451 {
1452 RegularExpression function_name_regex (name);
1453 num_matches = module->FindFunctions (function_name_regex,
1454 include_symbols,
1455 append,
1456 sc_list);
1457 }
1458 else
1459 {
1460 ConstString function_name (name);
1461 num_matches = module->FindFunctions (function_name,
1462 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
1463 include_symbols,
1464 append,
1465 sc_list);
1466 }
1467
1468 if (num_matches)
1469 {
1470 strm.Indent ();
1471 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1472 DumpFullpath (strm, &module->GetFileSpec(), 0);
1473 strm.PutCString(":\n");
1474 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
1475 }
1476 return num_matches;
1477 }
1478 return 0;
1479}
1480
1481static uint32_t
Greg Clayton801417e2011-07-07 01:59:51 +00001482LookupTypeInModule (CommandInterpreter &interpreter,
1483 Stream &strm,
1484 Module *module,
1485 const char *name_cstr,
1486 bool name_is_regex)
Greg Claytone1f50b92011-05-03 22:09:39 +00001487{
1488 if (module && name_cstr && name_cstr[0])
1489 {
Enrico Granata979e20d2011-07-29 19:53:35 +00001490 /*SymbolContextList sc_list;
Greg Claytone1f50b92011-05-03 22:09:39 +00001491
1492 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
1493 if (symbol_vendor)
Enrico Granata979e20d2011-07-29 19:53:35 +00001494 {*/
Greg Claytone1f50b92011-05-03 22:09:39 +00001495 TypeList type_list;
1496 uint32_t num_matches = 0;
1497 SymbolContext sc;
1498 // if (name_is_regex)
1499 // {
1500 // RegularExpression name_regex (name_cstr);
1501 // num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list);
1502 // }
1503 // else
1504 // {
1505 ConstString name(name_cstr);
Enrico Granata979e20d2011-07-29 19:53:35 +00001506 num_matches = module->FindTypes(sc, name, true, UINT32_MAX, type_list);
Greg Claytone1f50b92011-05-03 22:09:39 +00001507 // }
1508
1509 if (num_matches)
1510 {
1511 strm.Indent ();
1512 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1513 DumpFullpath (strm, &module->GetFileSpec(), 0);
1514 strm.PutCString(":\n");
1515 const uint32_t num_types = type_list.GetSize();
1516 for (uint32_t i=0; i<num_types; ++i)
1517 {
1518 TypeSP type_sp (type_list.GetTypeAtIndex(i));
1519 if (type_sp)
1520 {
1521 // Resolve the clang type so that any forward references
1522 // to types that haven't yet been parsed will get parsed.
1523 type_sp->GetClangFullType ();
1524 type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1525 }
1526 strm.EOL();
1527 }
1528 }
1529 return num_matches;
Enrico Granata979e20d2011-07-29 19:53:35 +00001530 //}
Greg Claytone1f50b92011-05-03 22:09:39 +00001531 }
1532 return 0;
1533}
1534
1535static uint32_t
1536LookupFileAndLineInModule (CommandInterpreter &interpreter,
1537 Stream &strm,
1538 Module *module,
1539 const FileSpec &file_spec,
1540 uint32_t line,
1541 bool check_inlines,
1542 bool verbose)
1543{
1544 if (module && file_spec)
1545 {
1546 SymbolContextList sc_list;
1547 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
1548 eSymbolContextEverything, sc_list);
1549 if (num_matches > 0)
1550 {
1551 strm.Indent ();
1552 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1553 strm << file_spec;
1554 if (line > 0)
1555 strm.Printf (":%u", line);
1556 strm << " in ";
1557 DumpFullpath (strm, &module->GetFileSpec(), 0);
1558 strm.PutCString(":\n");
1559 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
1560 return num_matches;
1561 }
1562 }
1563 return 0;
1564
1565}
1566
1567#pragma mark CommandObjectTargetModulesModuleAutoComplete
1568
1569//----------------------------------------------------------------------
1570// A base command object class that can auto complete with module file
1571// paths
1572//----------------------------------------------------------------------
1573
1574class CommandObjectTargetModulesModuleAutoComplete : public CommandObject
1575{
1576public:
1577
1578 CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter,
1579 const char *name,
1580 const char *help,
1581 const char *syntax) :
1582 CommandObject (interpreter, name, help, syntax)
1583 {
1584 CommandArgumentEntry arg;
1585 CommandArgumentData file_arg;
1586
1587 // Define the first (and only) variant of this arg.
1588 file_arg.arg_type = eArgTypeFilename;
1589 file_arg.arg_repetition = eArgRepeatStar;
1590
1591 // There is only one variant this argument could be; put it into the argument entry.
1592 arg.push_back (file_arg);
1593
1594 // Push the data for the first argument into the m_arguments vector.
1595 m_arguments.push_back (arg);
1596 }
1597
1598 virtual
1599 ~CommandObjectTargetModulesModuleAutoComplete ()
1600 {
1601 }
1602
1603 virtual int
1604 HandleArgumentCompletion (Args &input,
1605 int &cursor_index,
1606 int &cursor_char_position,
1607 OptionElementVector &opt_element_vector,
1608 int match_start_point,
1609 int max_return_elements,
1610 bool &word_complete,
1611 StringList &matches)
1612 {
1613 // Arguments are the standard module completer.
1614 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1615 completion_str.erase (cursor_char_position);
1616
1617 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1618 CommandCompletions::eModuleCompletion,
1619 completion_str.c_str(),
1620 match_start_point,
1621 max_return_elements,
1622 NULL,
1623 word_complete,
1624 matches);
1625 return matches.GetSize();
1626 }
1627};
1628
1629#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1630
1631//----------------------------------------------------------------------
1632// A base command object class that can auto complete with module source
1633// file paths
1634//----------------------------------------------------------------------
1635
1636class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObject
1637{
1638public:
1639
1640 CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
1641 const char *name,
1642 const char *help,
1643 const char *syntax) :
1644 CommandObject (interpreter, name, help, syntax)
1645 {
1646 CommandArgumentEntry arg;
1647 CommandArgumentData source_file_arg;
1648
1649 // Define the first (and only) variant of this arg.
1650 source_file_arg.arg_type = eArgTypeSourceFile;
1651 source_file_arg.arg_repetition = eArgRepeatPlus;
1652
1653 // There is only one variant this argument could be; put it into the argument entry.
1654 arg.push_back (source_file_arg);
1655
1656 // Push the data for the first argument into the m_arguments vector.
1657 m_arguments.push_back (arg);
1658 }
1659
1660 virtual
1661 ~CommandObjectTargetModulesSourceFileAutoComplete ()
1662 {
1663 }
1664
1665 virtual int
1666 HandleArgumentCompletion (Args &input,
1667 int &cursor_index,
1668 int &cursor_char_position,
1669 OptionElementVector &opt_element_vector,
1670 int match_start_point,
1671 int max_return_elements,
1672 bool &word_complete,
1673 StringList &matches)
1674 {
1675 // Arguments are the standard source file completer.
1676 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1677 completion_str.erase (cursor_char_position);
1678
1679 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1680 CommandCompletions::eSourceFileCompletion,
1681 completion_str.c_str(),
1682 match_start_point,
1683 max_return_elements,
1684 NULL,
1685 word_complete,
1686 matches);
1687 return matches.GetSize();
1688 }
1689};
1690
1691
1692#pragma mark CommandObjectTargetModulesDumpSymtab
1693
1694
1695class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
1696{
1697public:
1698 CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
1699 CommandObjectTargetModulesModuleAutoComplete (interpreter,
1700 "target modules dump symtab",
1701 "Dump the symbol table from one or more target modules.",
1702 NULL),
1703 m_options (interpreter)
1704 {
1705 }
1706
1707 virtual
1708 ~CommandObjectTargetModulesDumpSymtab ()
1709 {
1710 }
1711
1712 virtual bool
1713 Execute (Args& command,
1714 CommandReturnObject &result)
1715 {
1716 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1717 if (target == NULL)
1718 {
1719 result.AppendError ("invalid target, create a debug target using the 'target create' command");
1720 result.SetStatus (eReturnStatusFailed);
1721 return false;
1722 }
1723 else
1724 {
1725 uint32_t num_dumped = 0;
1726
1727 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1728 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1729 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1730
1731 if (command.GetArgumentCount() == 0)
1732 {
1733 // Dump all sections for all modules images
1734 const uint32_t num_modules = target->GetImages().GetSize();
1735 if (num_modules > 0)
1736 {
1737 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
1738 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1739 {
1740 if (num_dumped > 0)
1741 {
1742 result.GetOutputStream().EOL();
1743 result.GetOutputStream().EOL();
1744 }
1745 num_dumped++;
1746 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order);
1747 }
1748 }
1749 else
1750 {
1751 result.AppendError ("the target has no associated executable images");
1752 result.SetStatus (eReturnStatusFailed);
1753 return false;
1754 }
1755 }
1756 else
1757 {
1758 // Dump specified images (by basename or fullpath)
1759 const char *arg_cstr;
1760 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1761 {
1762 FileSpec image_file(arg_cstr, false);
1763 ModuleList matching_modules;
1764 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
1765
1766 // Not found in our module list for our target, check the main
1767 // shared module list in case it is a extra file used somewhere
1768 // else
1769 if (num_matching_modules == 0)
1770 num_matching_modules = ModuleList::FindSharedModules (image_file,
1771 target->GetArchitecture(),
1772 NULL,
1773 NULL,
1774 matching_modules);
1775
1776 if (num_matching_modules > 0)
1777 {
1778 for (size_t i=0; i<num_matching_modules; ++i)
1779 {
1780 Module *image_module = matching_modules.GetModulePointerAtIndex(i);
1781 if (image_module)
1782 {
1783 if (num_dumped > 0)
1784 {
1785 result.GetOutputStream().EOL();
1786 result.GetOutputStream().EOL();
1787 }
1788 num_dumped++;
1789 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module, m_options.m_sort_order);
1790 }
1791 }
1792 }
1793 else
1794 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1795 }
1796 }
1797
1798 if (num_dumped > 0)
1799 result.SetStatus (eReturnStatusSuccessFinishResult);
1800 else
1801 {
1802 result.AppendError ("no matching executable images found");
1803 result.SetStatus (eReturnStatusFailed);
1804 }
1805 }
1806 return result.Succeeded();
1807 }
1808
1809 virtual Options *
1810 GetOptions ()
1811 {
1812 return &m_options;
1813 }
1814
1815 class CommandOptions : public Options
1816 {
1817 public:
1818
1819 CommandOptions (CommandInterpreter &interpreter) :
1820 Options(interpreter),
1821 m_sort_order (eSortOrderNone)
1822 {
1823 }
1824
1825 virtual
1826 ~CommandOptions ()
1827 {
1828 }
1829
1830 virtual Error
1831 SetOptionValue (uint32_t option_idx, const char *option_arg)
1832 {
1833 Error error;
1834 char short_option = (char) m_getopt_table[option_idx].val;
1835
1836 switch (short_option)
1837 {
1838 case 's':
1839 {
1840 bool found_one = false;
1841 m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
1842 g_option_table[option_idx].enum_values,
1843 eSortOrderNone,
1844 &found_one);
1845 if (!found_one)
1846 error.SetErrorStringWithFormat("Invalid enumeration value '%s' for option '%c'.\n",
1847 option_arg,
1848 short_option);
1849 }
1850 break;
1851
1852 default:
1853 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
1854 break;
1855
1856 }
1857 return error;
1858 }
1859
1860 void
1861 OptionParsingStarting ()
1862 {
1863 m_sort_order = eSortOrderNone;
1864 }
1865
1866 const OptionDefinition*
1867 GetDefinitions ()
1868 {
1869 return g_option_table;
1870 }
1871
1872 // Options table: Required for subclasses of Options.
1873 static OptionDefinition g_option_table[];
1874
1875 SortOrder m_sort_order;
1876 };
1877
1878protected:
1879
1880 CommandOptions m_options;
1881};
1882
1883static OptionEnumValueElement
1884g_sort_option_enumeration[4] =
1885{
1886 { eSortOrderNone, "none", "No sorting, use the original symbol table order."},
1887 { eSortOrderByAddress, "address", "Sort output by symbol address."},
1888 { eSortOrderByName, "name", "Sort output by symbol name."},
1889 { 0, NULL, NULL }
1890};
1891
1892
1893OptionDefinition
1894CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
1895{
1896 { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
1897 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1898};
1899
1900#pragma mark CommandObjectTargetModulesDumpSections
1901
1902//----------------------------------------------------------------------
1903// Image section dumping command
1904//----------------------------------------------------------------------
1905
1906class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
1907{
1908public:
1909 CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
1910 CommandObjectTargetModulesModuleAutoComplete (interpreter,
1911 "target modules dump sections",
1912 "Dump the sections from one or more target modules.",
1913 //"target modules dump sections [<file1> ...]")
1914 NULL)
1915 {
1916 }
1917
1918 virtual
1919 ~CommandObjectTargetModulesDumpSections ()
1920 {
1921 }
1922
1923 virtual bool
1924 Execute (Args& command,
1925 CommandReturnObject &result)
1926 {
1927 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1928 if (target == NULL)
1929 {
1930 result.AppendError ("invalid target, create a debug target using the 'target create' command");
1931 result.SetStatus (eReturnStatusFailed);
1932 return false;
1933 }
1934 else
1935 {
1936 uint32_t num_dumped = 0;
1937
1938 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1939 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1940 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1941
1942 if (command.GetArgumentCount() == 0)
1943 {
1944 // Dump all sections for all modules images
1945 const uint32_t num_modules = target->GetImages().GetSize();
1946 if (num_modules > 0)
1947 {
1948 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
1949 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1950 {
1951 num_dumped++;
1952 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
1953 }
1954 }
1955 else
1956 {
1957 result.AppendError ("the target has no associated executable images");
1958 result.SetStatus (eReturnStatusFailed);
1959 return false;
1960 }
1961 }
1962 else
1963 {
1964 // Dump specified images (by basename or fullpath)
1965 const char *arg_cstr;
1966 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1967 {
1968 FileSpec image_file(arg_cstr, false);
1969 ModuleList matching_modules;
1970 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
1971
1972 // Not found in our module list for our target, check the main
1973 // shared module list in case it is a extra file used somewhere
1974 // else
1975 if (num_matching_modules == 0)
1976 num_matching_modules = ModuleList::FindSharedModules (image_file,
1977 target->GetArchitecture(),
1978 NULL,
1979 NULL,
1980 matching_modules);
1981
1982 if (num_matching_modules > 0)
1983 {
1984 for (size_t i=0; i<num_matching_modules; ++i)
1985 {
1986 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
1987 if (image_module)
1988 {
1989 num_dumped++;
1990 DumpModuleSections (m_interpreter, result.GetOutputStream(), image_module);
1991 }
1992 }
1993 }
1994 else
1995 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1996 }
1997 }
1998
1999 if (num_dumped > 0)
2000 result.SetStatus (eReturnStatusSuccessFinishResult);
2001 else
2002 {
2003 result.AppendError ("no matching executable images found");
2004 result.SetStatus (eReturnStatusFailed);
2005 }
2006 }
2007 return result.Succeeded();
2008 }
2009};
2010
2011
2012#pragma mark CommandObjectTargetModulesDumpSymfile
2013
2014//----------------------------------------------------------------------
2015// Image debug symbol dumping command
2016//----------------------------------------------------------------------
2017
2018class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
2019{
2020public:
2021 CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
2022 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2023 "target modules dump symfile",
2024 "Dump the debug symbol file for one or more target modules.",
2025 //"target modules dump symfile [<file1> ...]")
2026 NULL)
2027 {
2028 }
2029
2030 virtual
2031 ~CommandObjectTargetModulesDumpSymfile ()
2032 {
2033 }
2034
2035 virtual bool
2036 Execute (Args& command,
2037 CommandReturnObject &result)
2038 {
2039 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2040 if (target == NULL)
2041 {
2042 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2043 result.SetStatus (eReturnStatusFailed);
2044 return false;
2045 }
2046 else
2047 {
2048 uint32_t num_dumped = 0;
2049
2050 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2051 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2052 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2053
2054 if (command.GetArgumentCount() == 0)
2055 {
2056 // Dump all sections for all modules images
2057 const uint32_t num_modules = target->GetImages().GetSize();
2058 if (num_modules > 0)
2059 {
2060 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
2061 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2062 {
2063 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
2064 num_dumped++;
2065 }
2066 }
2067 else
2068 {
2069 result.AppendError ("the target has no associated executable images");
2070 result.SetStatus (eReturnStatusFailed);
2071 return false;
2072 }
2073 }
2074 else
2075 {
2076 // Dump specified images (by basename or fullpath)
2077 const char *arg_cstr;
2078 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2079 {
2080 FileSpec image_file(arg_cstr, false);
2081 ModuleList matching_modules;
2082 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
2083
2084 // Not found in our module list for our target, check the main
2085 // shared module list in case it is a extra file used somewhere
2086 // else
2087 if (num_matching_modules == 0)
2088 num_matching_modules = ModuleList::FindSharedModules (image_file,
2089 target->GetArchitecture(),
2090 NULL,
2091 NULL,
2092 matching_modules);
2093
2094 if (num_matching_modules > 0)
2095 {
2096 for (size_t i=0; i<num_matching_modules; ++i)
2097 {
2098 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
2099 if (image_module)
2100 {
2101 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module))
2102 num_dumped++;
2103 }
2104 }
2105 }
2106 else
2107 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2108 }
2109 }
2110
2111 if (num_dumped > 0)
2112 result.SetStatus (eReturnStatusSuccessFinishResult);
2113 else
2114 {
2115 result.AppendError ("no matching executable images found");
2116 result.SetStatus (eReturnStatusFailed);
2117 }
2118 }
2119 return result.Succeeded();
2120 }
2121};
2122
2123
2124#pragma mark CommandObjectTargetModulesDumpLineTable
2125
2126//----------------------------------------------------------------------
2127// Image debug line table dumping command
2128//----------------------------------------------------------------------
2129
2130class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
2131{
2132public:
2133 CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
2134 CommandObjectTargetModulesSourceFileAutoComplete (interpreter,
2135 "target modules dump line-table",
2136 "Dump the debug symbol file for one or more target modules.",
2137 NULL)
2138 {
2139 }
2140
2141 virtual
2142 ~CommandObjectTargetModulesDumpLineTable ()
2143 {
2144 }
2145
2146 virtual bool
2147 Execute (Args& command,
2148 CommandReturnObject &result)
2149 {
2150 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2151 if (target == NULL)
2152 {
2153 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2154 result.SetStatus (eReturnStatusFailed);
2155 return false;
2156 }
2157 else
2158 {
2159 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
2160 uint32_t total_num_dumped = 0;
2161
2162 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2163 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2164 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2165
2166 if (command.GetArgumentCount() == 0)
2167 {
2168 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
2169 result.SetStatus (eReturnStatusFailed);
2170 }
2171 else
2172 {
2173 // Dump specified images (by basename or fullpath)
2174 const char *arg_cstr;
2175 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2176 {
2177 FileSpec file_spec(arg_cstr, false);
2178 const uint32_t num_modules = target->GetImages().GetSize();
2179 if (num_modules > 0)
2180 {
2181 uint32_t num_dumped = 0;
2182 for (uint32_t i = 0; i<num_modules; ++i)
2183 {
2184 if (DumpCompileUnitLineTable (m_interpreter,
2185 result.GetOutputStream(),
2186 target->GetImages().GetModulePointerAtIndex(i),
2187 file_spec,
2188 exe_ctx.process != NULL && exe_ctx.process->IsAlive()))
2189 num_dumped++;
2190 }
2191 if (num_dumped == 0)
2192 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
2193 else
2194 total_num_dumped += num_dumped;
2195 }
2196 }
2197 }
2198
2199 if (total_num_dumped > 0)
2200 result.SetStatus (eReturnStatusSuccessFinishResult);
2201 else
2202 {
2203 result.AppendError ("no source filenames matched any command arguments");
2204 result.SetStatus (eReturnStatusFailed);
2205 }
2206 }
2207 return result.Succeeded();
2208 }
2209};
2210
2211
2212#pragma mark CommandObjectTargetModulesDump
2213
2214//----------------------------------------------------------------------
2215// Dump multi-word command for target modules
2216//----------------------------------------------------------------------
2217
2218class CommandObjectTargetModulesDump : public CommandObjectMultiword
2219{
2220public:
2221
2222 //------------------------------------------------------------------
2223 // Constructors and Destructors
2224 //------------------------------------------------------------------
2225 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) :
2226 CommandObjectMultiword (interpreter,
2227 "target modules dump",
2228 "A set of commands for dumping information about one or more target modules.",
2229 "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
2230 {
2231 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
2232 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
2233 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
2234 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
2235 }
2236
2237 virtual
2238 ~CommandObjectTargetModulesDump()
2239 {
2240 }
2241};
2242
2243class CommandObjectTargetModulesAdd : public CommandObject
2244{
2245public:
2246 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
2247 CommandObject (interpreter,
2248 "target modules add",
2249 "Add a new module to the current target's modules.",
2250 "target modules add [<module>]")
2251 {
2252 }
2253
2254 virtual
2255 ~CommandObjectTargetModulesAdd ()
2256 {
2257 }
2258
2259 virtual bool
2260 Execute (Args& args,
2261 CommandReturnObject &result)
2262 {
2263 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2264 if (target == NULL)
2265 {
2266 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2267 result.SetStatus (eReturnStatusFailed);
2268 return false;
2269 }
2270 else
2271 {
2272 const size_t argc = args.GetArgumentCount();
2273 if (argc == 0)
2274 {
2275 result.AppendError ("one or more executable image paths must be specified");
2276 result.SetStatus (eReturnStatusFailed);
2277 return false;
2278 }
2279 else
2280 {
2281 for (size_t i=0; i<argc; ++i)
2282 {
2283 const char *path = args.GetArgumentAtIndex(i);
2284 if (path)
2285 {
2286 FileSpec file_spec(path, true);
2287 ArchSpec arch;
2288 if (file_spec.Exists())
2289 {
2290 ModuleSP module_sp (target->GetSharedModule(file_spec, arch));
2291 if (!module_sp)
2292 {
2293 result.AppendError ("one or more executable image paths must be specified");
2294 result.SetStatus (eReturnStatusFailed);
2295 return false;
2296 }
Jason Molenda36f6fb92011-08-02 23:28:55 +00002297 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytone1f50b92011-05-03 22:09:39 +00002298 }
2299 else
2300 {
2301 char resolved_path[PATH_MAX];
2302 result.SetStatus (eReturnStatusFailed);
2303 if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
2304 {
2305 if (strcmp (resolved_path, path) != 0)
2306 {
2307 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
2308 break;
2309 }
2310 }
2311 result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
2312 break;
2313 }
2314 }
2315 }
2316 }
2317 }
2318 return result.Succeeded();
2319 }
2320
2321 int
2322 HandleArgumentCompletion (Args &input,
2323 int &cursor_index,
2324 int &cursor_char_position,
2325 OptionElementVector &opt_element_vector,
2326 int match_start_point,
2327 int max_return_elements,
2328 bool &word_complete,
2329 StringList &matches)
2330 {
2331 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2332 completion_str.erase (cursor_char_position);
2333
2334 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2335 CommandCompletions::eDiskFileCompletion,
2336 completion_str.c_str(),
2337 match_start_point,
2338 max_return_elements,
2339 NULL,
2340 word_complete,
2341 matches);
2342 return matches.GetSize();
2343 }
2344
2345};
2346
2347class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
2348{
2349public:
2350 CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) :
2351 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2352 "target modules load",
2353 "Set the load addresses for one or more sections in a target module.",
2354 "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
2355 m_option_group (interpreter),
2356 m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "Fullpath or basename for module to load."),
2357 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)
2358 {
2359 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2360 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2361 m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2362 m_option_group.Finalize();
2363 }
2364
2365 virtual
2366 ~CommandObjectTargetModulesLoad ()
2367 {
2368 }
2369
2370 virtual bool
2371 Execute (Args& args,
2372 CommandReturnObject &result)
2373 {
2374 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2375 if (target == NULL)
2376 {
2377 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2378 result.SetStatus (eReturnStatusFailed);
2379 return false;
2380 }
2381 else
2382 {
2383 const size_t argc = args.GetArgumentCount();
2384 const FileSpec *file_ptr = NULL;
2385 const UUID *uuid_ptr = NULL;
2386 if (m_file_option.GetOptionValue().OptionWasSet())
2387 file_ptr = &m_file_option.GetOptionValue().GetCurrentValue();
2388
2389 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2390 uuid_ptr = &m_uuid_option_group.GetOptionValue().GetCurrentValue();
2391
2392 if (file_ptr || uuid_ptr)
2393 {
2394
2395 ModuleList matching_modules;
2396 const size_t num_matches = target->GetImages().FindModules (file_ptr, // File spec to match (can be NULL to match by UUID only)
2397 NULL, // Architecture
2398 uuid_ptr, // UUID to match (can be NULL to not match on UUID)
2399 NULL, // Object name
2400 matching_modules);
2401
2402 char path[PATH_MAX];
2403 if (num_matches == 1)
2404 {
2405 Module *module = matching_modules.GetModulePointerAtIndex(0);
2406 if (module)
2407 {
2408 ObjectFile *objfile = module->GetObjectFile();
2409 if (objfile)
2410 {
2411 SectionList *section_list = objfile->GetSectionList();
2412 if (section_list)
2413 {
2414 if (argc == 0)
2415 {
2416 if (m_slide_option.GetOptionValue().OptionWasSet())
2417 {
2418 Module *module = matching_modules.GetModulePointerAtIndex(0);
2419 if (module)
2420 {
2421 ObjectFile *objfile = module->GetObjectFile();
2422 if (objfile)
2423 {
2424 SectionList *section_list = objfile->GetSectionList();
2425 if (section_list)
2426 {
2427 const size_t num_sections = section_list->GetSize();
2428 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
2429 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
2430 {
2431 SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx));
2432 if (section_sp)
2433 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), section_sp->GetFileAddress() + slide);
2434 }
2435 }
2436 }
2437 }
2438 }
2439 else
2440 {
2441 result.AppendError ("one or more section name + load address pair must be specified");
2442 result.SetStatus (eReturnStatusFailed);
2443 return false;
2444 }
2445 }
2446 else
2447 {
2448 if (m_slide_option.GetOptionValue().OptionWasSet())
2449 {
2450 result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
2451 result.SetStatus (eReturnStatusFailed);
2452 return false;
2453 }
2454
2455 for (size_t i=0; i<argc; i += 2)
2456 {
2457 const char *sect_name = args.GetArgumentAtIndex(i);
2458 const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
2459 if (sect_name && load_addr_cstr)
2460 {
2461 ConstString const_sect_name(sect_name);
2462 bool success = false;
2463 addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2464 if (success)
2465 {
2466 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
2467 if (section_sp)
2468 {
2469 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), load_addr);
2470 result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr);
2471 }
2472 else
2473 {
2474 result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
2475 result.SetStatus (eReturnStatusFailed);
2476 break;
2477 }
2478 }
2479 else
2480 {
2481 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
2482 result.SetStatus (eReturnStatusFailed);
2483 break;
2484 }
2485 }
2486 else
2487 {
2488 if (sect_name)
2489 result.AppendError ("section names must be followed by a load address.\n");
2490 else
2491 result.AppendError ("one or more section name + load address pair must be specified.\n");
2492 result.SetStatus (eReturnStatusFailed);
2493 break;
2494 }
2495 }
2496 }
2497 }
2498 else
2499 {
2500 module->GetFileSpec().GetPath (path, sizeof(path));
2501 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
2502 result.SetStatus (eReturnStatusFailed);
2503 }
2504 }
2505 else
2506 {
2507 module->GetFileSpec().GetPath (path, sizeof(path));
2508 result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
2509 result.SetStatus (eReturnStatusFailed);
2510 }
2511 }
2512 else
2513 {
2514 module->GetFileSpec().GetPath (path, sizeof(path));
2515 result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
2516 result.SetStatus (eReturnStatusFailed);
2517 }
2518 }
2519 else
2520 {
2521 char uuid_cstr[64];
2522 if (file_ptr)
2523 file_ptr->GetPath (path, sizeof(path));
2524 else
2525 path[0] = '\0';
2526
2527 if (uuid_ptr)
2528 uuid_ptr->GetAsCString(uuid_cstr, sizeof(uuid_cstr));
2529 else
2530 uuid_cstr[0] = '\0';
2531 if (num_matches > 1)
2532 {
2533 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
2534 path[0] ? " file=" : "",
2535 path,
2536 uuid_cstr[0] ? " uuid=" : "",
2537 uuid_cstr);
2538 for (size_t i=0; i<num_matches; ++i)
2539 {
2540 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
2541 result.AppendMessageWithFormat("%s\n", path);
2542 }
2543 }
2544 else
2545 {
2546 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n",
2547 path[0] ? " file=" : "",
2548 path,
2549 uuid_cstr[0] ? " uuid=" : "",
2550 uuid_cstr);
2551 }
2552 result.SetStatus (eReturnStatusFailed);
2553 }
2554 }
2555 else
2556 {
2557 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
2558 result.SetStatus (eReturnStatusFailed);
2559 return false;
2560 }
2561 }
2562 return result.Succeeded();
2563 }
2564
2565 virtual Options *
2566 GetOptions ()
2567 {
2568 return &m_option_group;
2569 }
2570
2571protected:
2572 OptionGroupOptions m_option_group;
2573 OptionGroupUUID m_uuid_option_group;
2574 OptionGroupFile m_file_option;
2575 OptionGroupUInt64 m_slide_option;
2576};
2577
2578//----------------------------------------------------------------------
2579// List images with associated information
2580//----------------------------------------------------------------------
2581class CommandObjectTargetModulesList : public CommandObject
2582{
2583public:
2584
2585 class CommandOptions : public Options
2586 {
2587 public:
2588
2589 CommandOptions (CommandInterpreter &interpreter) :
Greg Clayton899025f2011-08-09 00:01:09 +00002590 Options(interpreter),
2591 m_format_array()
Greg Claytone1f50b92011-05-03 22:09:39 +00002592 {
2593 }
2594
2595 virtual
2596 ~CommandOptions ()
2597 {
2598 }
2599
2600 virtual Error
2601 SetOptionValue (uint32_t option_idx, const char *option_arg)
2602 {
2603 char short_option = (char) m_getopt_table[option_idx].val;
Greg Clayton899025f2011-08-09 00:01:09 +00002604 if (short_option == 'g')
2605 {
2606 m_use_global_module_list = true;
2607 }
2608 else
2609 {
2610 uint32_t width = 0;
2611 if (option_arg)
2612 width = strtoul (option_arg, NULL, 0);
2613 m_format_array.push_back(std::make_pair(short_option, width));
2614 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002615 Error error;
2616 return error;
2617 }
2618
2619 void
2620 OptionParsingStarting ()
2621 {
2622 m_format_array.clear();
Greg Clayton899025f2011-08-09 00:01:09 +00002623 m_use_global_module_list = false;
Greg Claytone1f50b92011-05-03 22:09:39 +00002624 }
2625
2626 const OptionDefinition*
2627 GetDefinitions ()
2628 {
2629 return g_option_table;
2630 }
2631
2632 // Options table: Required for subclasses of Options.
2633
2634 static OptionDefinition g_option_table[];
2635
2636 // Instance variables to hold the values for command options.
2637 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
2638 FormatWidthCollection m_format_array;
Greg Clayton899025f2011-08-09 00:01:09 +00002639 bool m_use_global_module_list;
Greg Claytone1f50b92011-05-03 22:09:39 +00002640 };
2641
2642 CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
2643 CommandObject (interpreter,
2644 "target modules list",
2645 "List current executable and dependent shared library images.",
2646 "target modules list [<cmd-options>]"),
2647 m_options (interpreter)
2648 {
2649 }
2650
2651 virtual
2652 ~CommandObjectTargetModulesList ()
2653 {
2654 }
2655
2656 virtual
2657 Options *
2658 GetOptions ()
2659 {
2660 return &m_options;
2661 }
2662
2663 virtual bool
2664 Execute (Args& command,
2665 CommandReturnObject &result)
2666 {
2667 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Clayton153ccd72011-08-10 02:10:13 +00002668 const bool use_global_module_list = m_options.m_use_global_module_list;
2669 if (target == NULL && use_global_module_list == false)
Greg Claytone1f50b92011-05-03 22:09:39 +00002670 {
2671 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2672 result.SetStatus (eReturnStatusFailed);
2673 return false;
2674 }
2675 else
2676 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002677 if (target)
2678 {
2679 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2680 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2681 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2682 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002683 // Dump all sections for all modules images
Greg Clayton899025f2011-08-09 00:01:09 +00002684 uint32_t num_modules = 0;
2685 Mutex::Locker locker;
Greg Clayton153ccd72011-08-10 02:10:13 +00002686 if (use_global_module_list)
Greg Clayton899025f2011-08-09 00:01:09 +00002687 {
2688 locker.Reset (Module::GetAllocationModuleCollectionMutex().GetMutex());
2689 num_modules = Module::GetNumberAllocatedModules();
2690 }
2691 else
2692 num_modules = target->GetImages().GetSize();
2693
Greg Claytone1f50b92011-05-03 22:09:39 +00002694 if (num_modules > 0)
2695 {
2696 Stream &strm = result.GetOutputStream();
2697
2698 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2699 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002700 ModuleSP module_sp;
Greg Clayton899025f2011-08-09 00:01:09 +00002701 Module *module;
Greg Clayton153ccd72011-08-10 02:10:13 +00002702 if (use_global_module_list)
Greg Clayton899025f2011-08-09 00:01:09 +00002703 {
2704 module = Module::GetAllocatedModuleAtIndex(image_idx);
Greg Clayton153ccd72011-08-10 02:10:13 +00002705 module_sp = module->GetSP();
Greg Clayton899025f2011-08-09 00:01:09 +00002706 }
2707 else
2708 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002709 module_sp = target->GetImages().GetModuleAtIndex(image_idx);
2710 module = module_sp.get();
Greg Clayton899025f2011-08-09 00:01:09 +00002711 }
Greg Clayton153ccd72011-08-10 02:10:13 +00002712
2713 strm.Printf("[%3u] ", image_idx);
2714
Greg Claytone1f50b92011-05-03 22:09:39 +00002715 bool dump_object_name = false;
2716 if (m_options.m_format_array.empty())
2717 {
2718 DumpFullpath(strm, &module->GetFileSpec(), 0);
2719 dump_object_name = true;
2720 }
2721 else
2722 {
2723 const size_t num_entries = m_options.m_format_array.size();
2724 for (size_t i=0; i<num_entries; ++i)
2725 {
2726 if (i > 0)
2727 strm.PutChar(' ');
2728 char format_char = m_options.m_format_array[i].first;
2729 uint32_t width = m_options.m_format_array[i].second;
2730 switch (format_char)
2731 {
2732 case 'a':
2733 DumpModuleArchitecture (strm, module, false, width);
2734 break;
2735
2736 case 't':
2737 DumpModuleArchitecture (strm, module, true, width);
2738 break;
2739
2740 case 'f':
2741 DumpFullpath (strm, &module->GetFileSpec(), width);
2742 dump_object_name = true;
2743 break;
2744
2745 case 'd':
2746 DumpDirectory (strm, &module->GetFileSpec(), width);
2747 break;
2748
2749 case 'b':
2750 DumpBasename (strm, &module->GetFileSpec(), width);
2751 dump_object_name = true;
2752 break;
2753
Greg Clayton153ccd72011-08-10 02:10:13 +00002754 case 'r':
2755 {
2756 uint32_t ref_count = 0;
2757 if (module_sp)
2758 {
2759 // Take one away to make sure we don't count our local "module_sp"
2760 ref_count = module_sp.use_count() - 1;
2761 }
2762 if (width)
2763 strm.Printf("{%*u}", width, ref_count);
2764 else
2765 strm.Printf("{%u}", ref_count);
2766 }
2767 break;
2768
Greg Claytone1f50b92011-05-03 22:09:39 +00002769 case 's':
2770 case 'S':
Greg Claytone1f50b92011-05-03 22:09:39 +00002771 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002772 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
2773 if (symbol_vendor)
Greg Claytone1f50b92011-05-03 22:09:39 +00002774 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002775 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
2776 if (symbol_file)
2777 {
2778 if (format_char == 'S')
2779 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
2780 else
2781 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
2782 dump_object_name = true;
2783 break;
2784 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002785 }
Greg Clayton153ccd72011-08-10 02:10:13 +00002786 strm.Printf("%.*s", width, "<NONE>");
Greg Claytone1f50b92011-05-03 22:09:39 +00002787 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002788 break;
2789
Greg Clayton153ccd72011-08-10 02:10:13 +00002790 case 'm':
2791 module->GetModificationTime().Dump(&strm, width);
2792 break;
2793
2794 case 'p':
2795 strm.Printf("%p", module);
2796 break;
2797
Greg Claytone1f50b92011-05-03 22:09:39 +00002798 case 'u':
2799 DumpModuleUUID(strm, module);
2800 break;
2801
2802 default:
2803 break;
2804 }
2805
2806 }
2807 }
2808 if (dump_object_name)
2809 {
2810 const char *object_name = module->GetObjectName().GetCString();
2811 if (object_name)
2812 strm.Printf ("(%s)", object_name);
2813 }
2814 strm.EOL();
2815 }
2816 result.SetStatus (eReturnStatusSuccessFinishResult);
2817 }
2818 else
2819 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002820 if (use_global_module_list)
2821 result.AppendError ("the global module list is empty");
2822 else
2823 result.AppendError ("the target has no associated executable images");
Greg Claytone1f50b92011-05-03 22:09:39 +00002824 result.SetStatus (eReturnStatusFailed);
2825 return false;
2826 }
2827 }
2828 return result.Succeeded();
2829 }
2830protected:
2831
2832 CommandOptions m_options;
2833};
2834
2835OptionDefinition
2836CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
2837{
2838 { LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."},
2839 { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."},
2840 { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."},
2841 { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
2842 { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
2843 { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
2844 { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
2845 { LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."},
Greg Clayton153ccd72011-08-10 02:10:13 +00002846 { LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."},
2847 { 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."},
2848 { LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."},
Greg Clayton899025f2011-08-09 00:01:09 +00002849 { 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 +00002850 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
2851};
2852
2853
2854
2855//----------------------------------------------------------------------
2856// Lookup information in images
2857//----------------------------------------------------------------------
2858class CommandObjectTargetModulesLookup : public CommandObject
2859{
2860public:
2861
2862 enum
2863 {
2864 eLookupTypeInvalid = -1,
2865 eLookupTypeAddress = 0,
2866 eLookupTypeSymbol,
2867 eLookupTypeFileLine, // Line is optional
2868 eLookupTypeFunction,
2869 eLookupTypeType,
2870 kNumLookupTypes
2871 };
2872
2873 class CommandOptions : public Options
2874 {
2875 public:
2876
2877 CommandOptions (CommandInterpreter &interpreter) :
2878 Options(interpreter)
2879 {
2880 OptionParsingStarting();
2881 }
2882
2883 virtual
2884 ~CommandOptions ()
2885 {
2886 }
2887
2888 virtual Error
2889 SetOptionValue (uint32_t option_idx, const char *option_arg)
2890 {
2891 Error error;
2892
2893 char short_option = (char) m_getopt_table[option_idx].val;
2894
2895 switch (short_option)
2896 {
2897 case 'a':
2898 m_type = eLookupTypeAddress;
2899 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
2900 if (m_addr == LLDB_INVALID_ADDRESS)
2901 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
2902 break;
2903
2904 case 'o':
2905 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
2906 if (m_offset == LLDB_INVALID_ADDRESS)
2907 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg);
2908 break;
2909
2910 case 's':
2911 m_str = option_arg;
2912 m_type = eLookupTypeSymbol;
2913 break;
2914
2915 case 'f':
2916 m_file.SetFile (option_arg, false);
2917 m_type = eLookupTypeFileLine;
2918 break;
2919
2920 case 'i':
2921 m_check_inlines = false;
2922 break;
2923
2924 case 'l':
2925 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
2926 if (m_line_number == UINT32_MAX)
2927 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg);
2928 else if (m_line_number == 0)
2929 error.SetErrorString ("Zero is an invalid line number.");
2930 m_type = eLookupTypeFileLine;
2931 break;
2932
2933 case 'n':
2934 m_str = option_arg;
2935 m_type = eLookupTypeFunction;
2936 break;
2937
2938 case 't':
2939 m_str = option_arg;
2940 m_type = eLookupTypeType;
2941 break;
2942
2943 case 'v':
2944 m_verbose = 1;
2945 break;
2946
2947 case 'r':
2948 m_use_regex = true;
2949 break;
2950 }
2951
2952 return error;
2953 }
2954
2955 void
2956 OptionParsingStarting ()
2957 {
2958 m_type = eLookupTypeInvalid;
2959 m_str.clear();
2960 m_file.Clear();
2961 m_addr = LLDB_INVALID_ADDRESS;
2962 m_offset = 0;
2963 m_line_number = 0;
2964 m_use_regex = false;
2965 m_check_inlines = true;
2966 m_verbose = false;
2967 }
2968
2969 const OptionDefinition*
2970 GetDefinitions ()
2971 {
2972 return g_option_table;
2973 }
2974
2975 // Options table: Required for subclasses of Options.
2976
2977 static OptionDefinition g_option_table[];
2978 int m_type; // Should be a eLookupTypeXXX enum after parsing options
2979 std::string m_str; // Holds name lookup
2980 FileSpec m_file; // Files for file lookups
2981 lldb::addr_t m_addr; // Holds the address to lookup
2982 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
2983 uint32_t m_line_number; // Line number for file+line lookups
2984 bool m_use_regex; // Name lookups in m_str are regular expressions.
2985 bool m_check_inlines;// Check for inline entries when looking up by file/line.
2986 bool m_verbose; // Enable verbose lookup info
2987
2988 };
2989
2990 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
2991 CommandObject (interpreter,
2992 "target modules lookup",
2993 "Look up information within executable and dependent shared library images.",
2994 NULL),
2995 m_options (interpreter)
2996 {
2997 CommandArgumentEntry arg;
2998 CommandArgumentData file_arg;
2999
3000 // Define the first (and only) variant of this arg.
3001 file_arg.arg_type = eArgTypeFilename;
3002 file_arg.arg_repetition = eArgRepeatStar;
3003
3004 // There is only one variant this argument could be; put it into the argument entry.
3005 arg.push_back (file_arg);
3006
3007 // Push the data for the first argument into the m_arguments vector.
3008 m_arguments.push_back (arg);
3009 }
3010
3011 virtual
3012 ~CommandObjectTargetModulesLookup ()
3013 {
3014 }
3015
3016 virtual Options *
3017 GetOptions ()
3018 {
3019 return &m_options;
3020 }
3021
3022
3023 bool
3024 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
3025 {
3026 switch (m_options.m_type)
3027 {
3028 case eLookupTypeAddress:
3029 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
3030 {
3031 if (LookupAddressInModule (m_interpreter,
3032 result.GetOutputStream(),
3033 module,
3034 eSymbolContextEverything,
3035 m_options.m_addr,
3036 m_options.m_offset,
3037 m_options.m_verbose))
3038 {
3039 result.SetStatus(eReturnStatusSuccessFinishResult);
3040 return true;
3041 }
3042 }
3043 break;
3044
3045 case eLookupTypeSymbol:
3046 if (!m_options.m_str.empty())
3047 {
3048 if (LookupSymbolInModule (m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex))
3049 {
3050 result.SetStatus(eReturnStatusSuccessFinishResult);
3051 return true;
3052 }
3053 }
3054 break;
3055
3056 case eLookupTypeFileLine:
3057 if (m_options.m_file)
3058 {
3059
3060 if (LookupFileAndLineInModule (m_interpreter,
3061 result.GetOutputStream(),
3062 module,
3063 m_options.m_file,
3064 m_options.m_line_number,
3065 m_options.m_check_inlines,
3066 m_options.m_verbose))
3067 {
3068 result.SetStatus(eReturnStatusSuccessFinishResult);
3069 return true;
3070 }
3071 }
3072 break;
3073
3074 case eLookupTypeFunction:
3075 if (!m_options.m_str.empty())
3076 {
3077 if (LookupFunctionInModule (m_interpreter,
3078 result.GetOutputStream(),
3079 module,
3080 m_options.m_str.c_str(),
3081 m_options.m_use_regex,
3082 m_options.m_verbose))
3083 {
3084 result.SetStatus(eReturnStatusSuccessFinishResult);
3085 return true;
3086 }
3087 }
3088 break;
3089
3090 case eLookupTypeType:
3091 if (!m_options.m_str.empty())
3092 {
3093 if (LookupTypeInModule (m_interpreter,
3094 result.GetOutputStream(),
3095 module,
3096 m_options.m_str.c_str(),
3097 m_options.m_use_regex))
3098 {
3099 result.SetStatus(eReturnStatusSuccessFinishResult);
3100 return true;
3101 }
3102 }
3103 break;
3104
3105 default:
3106 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
3107 syntax_error = true;
3108 break;
3109 }
3110
3111 result.SetStatus (eReturnStatusFailed);
3112 return false;
3113 }
3114
3115 virtual bool
3116 Execute (Args& command,
3117 CommandReturnObject &result)
3118 {
3119 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3120 if (target == NULL)
3121 {
3122 result.AppendError ("invalid target, create a debug target using the 'target create' command");
3123 result.SetStatus (eReturnStatusFailed);
3124 return false;
3125 }
3126 else
3127 {
3128 bool syntax_error = false;
3129 uint32_t i;
3130 uint32_t num_successful_lookups = 0;
3131 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3132 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3133 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3134 // Dump all sections for all modules images
3135
3136 if (command.GetArgumentCount() == 0)
3137 {
3138 // Dump all sections for all modules images
3139 const uint32_t num_modules = target->GetImages().GetSize();
3140 if (num_modules > 0)
3141 {
3142 for (i = 0; i<num_modules && syntax_error == false; ++i)
3143 {
3144 if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
3145 {
3146 result.GetOutputStream().EOL();
3147 num_successful_lookups++;
3148 }
3149 }
3150 }
3151 else
3152 {
3153 result.AppendError ("the target has no associated executable images");
3154 result.SetStatus (eReturnStatusFailed);
3155 return false;
3156 }
3157 }
3158 else
3159 {
3160 // Dump specified images (by basename or fullpath)
3161 const char *arg_cstr;
3162 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
3163 {
3164 FileSpec image_file(arg_cstr, false);
3165 ModuleList matching_modules;
3166 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
3167
3168 // Not found in our module list for our target, check the main
3169 // shared module list in case it is a extra file used somewhere
3170 // else
3171 if (num_matching_modules == 0)
3172 num_matching_modules = ModuleList::FindSharedModules (image_file,
3173 target->GetArchitecture(),
3174 NULL,
3175 NULL,
3176 matching_modules);
3177
3178 if (num_matching_modules > 0)
3179 {
3180 for (size_t j=0; j<num_matching_modules; ++j)
3181 {
3182 Module * image_module = matching_modules.GetModulePointerAtIndex(j);
3183 if (image_module)
3184 {
3185 if (LookupInModule (m_interpreter, image_module, result, syntax_error))
3186 {
3187 result.GetOutputStream().EOL();
3188 num_successful_lookups++;
3189 }
3190 }
3191 }
3192 }
3193 else
3194 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
3195 }
3196 }
3197
3198 if (num_successful_lookups > 0)
3199 result.SetStatus (eReturnStatusSuccessFinishResult);
3200 else
3201 result.SetStatus (eReturnStatusFailed);
3202 }
3203 return result.Succeeded();
3204 }
3205protected:
3206
3207 CommandOptions m_options;
3208};
3209
3210OptionDefinition
3211CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
3212{
3213 { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more target modules."},
3214 { 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."},
Jim Inghame7a91c12011-06-20 23:38:11 +00003215 { LLDB_OPT_SET_2| LLDB_OPT_SET_4
3216 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_5 */ ,
3217 false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."},
Greg Claytone1f50b92011-05-03 22:09:39 +00003218 { 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."},
Greg Claytone1f50b92011-05-03 22:09:39 +00003219 { 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."},
3220 { 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)."},
3221 { LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Check inline line entries (must be used in conjunction with --file)."},
3222 { LLDB_OPT_SET_4, true, "function", 'n', required_argument, NULL, 0, eArgTypeFunctionName, "Lookup a function by name in the debug symbols in one or more target modules."},
3223 { LLDB_OPT_SET_5, true, "type", 't', required_argument, NULL, 0, eArgTypeName, "Lookup a type by name in the debug symbols in one or more target modules."},
3224 { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."},
3225 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3226};
Chris Lattner24943d22010-06-08 16:52:24 +00003227
3228
Jim Inghamd60d94a2011-03-11 03:53:59 +00003229#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner24943d22010-06-08 16:52:24 +00003230
3231//-------------------------------------------------------------------------
3232// CommandObjectMultiwordImageSearchPaths
3233//-------------------------------------------------------------------------
3234
Greg Claytone1f50b92011-05-03 22:09:39 +00003235class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
Chris Lattner24943d22010-06-08 16:52:24 +00003236{
3237public:
Greg Claytone1f50b92011-05-03 22:09:39 +00003238
3239 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
3240 CommandObjectMultiword (interpreter,
3241 "target modules search-paths",
3242 "A set of commands for operating on debugger target image search paths.",
3243 "target modules search-paths <subcommand> [<subcommand-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +00003244 {
Greg Claytone1f50b92011-05-03 22:09:39 +00003245 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
3246 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
3247 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
3248 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
3249 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00003250 }
Greg Claytone1f50b92011-05-03 22:09:39 +00003251
3252 ~CommandObjectTargetModulesImageSearchPaths()
Chris Lattner24943d22010-06-08 16:52:24 +00003253 {
3254 }
3255};
3256
Greg Claytone1f50b92011-05-03 22:09:39 +00003257
3258
3259#pragma mark CommandObjectTargetModules
3260
3261//-------------------------------------------------------------------------
3262// CommandObjectTargetModules
3263//-------------------------------------------------------------------------
3264
3265class CommandObjectTargetModules : public CommandObjectMultiword
3266{
3267public:
3268 //------------------------------------------------------------------
3269 // Constructors and Destructors
3270 //------------------------------------------------------------------
3271 CommandObjectTargetModules(CommandInterpreter &interpreter) :
3272 CommandObjectMultiword (interpreter,
3273 "target modules",
3274 "A set of commands for accessing information for one or more target modules.",
3275 "target modules <sub-command> ...")
3276 {
3277 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
3278 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
3279 //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter)));
3280 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
3281 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
3282 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
3283 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
3284
3285 }
3286 virtual
3287 ~CommandObjectTargetModules()
3288 {
3289 }
3290
3291private:
3292 //------------------------------------------------------------------
3293 // For CommandObjectTargetModules only
3294 //------------------------------------------------------------------
3295 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
3296};
3297
3298
Jim Inghamd60d94a2011-03-11 03:53:59 +00003299#pragma mark CommandObjectTargetStopHookAdd
3300
3301//-------------------------------------------------------------------------
3302// CommandObjectTargetStopHookAdd
3303//-------------------------------------------------------------------------
3304
3305class CommandObjectTargetStopHookAdd : public CommandObject
3306{
3307public:
3308
3309 class CommandOptions : public Options
3310 {
3311 public:
Greg Claytonf15996e2011-04-07 22:46:35 +00003312 CommandOptions (CommandInterpreter &interpreter) :
3313 Options(interpreter),
Jim Inghamd60d94a2011-03-11 03:53:59 +00003314 m_line_start(0),
3315 m_line_end (UINT_MAX),
3316 m_func_name_type_mask (eFunctionNameTypeAuto),
3317 m_sym_ctx_specified (false),
Johnny Chen60fe60e2011-05-02 23:47:55 +00003318 m_thread_specified (false),
3319 m_use_one_liner (false),
3320 m_one_liner()
Jim Inghamd60d94a2011-03-11 03:53:59 +00003321 {
3322 }
3323
3324 ~CommandOptions () {}
3325
Greg Claytonb3448432011-03-24 21:19:54 +00003326 const OptionDefinition*
Jim Inghamd60d94a2011-03-11 03:53:59 +00003327 GetDefinitions ()
3328 {
3329 return g_option_table;
3330 }
3331
3332 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +00003333 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003334 {
3335 Error error;
3336 char short_option = (char) m_getopt_table[option_idx].val;
3337 bool success;
3338
3339 switch (short_option)
3340 {
3341 case 'c':
3342 m_class_name = option_arg;
3343 m_sym_ctx_specified = true;
3344 break;
3345
3346 case 'e':
3347 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
3348 if (!success)
3349 {
3350 error.SetErrorStringWithFormat ("Invalid end line number: \"%s\".", option_arg);
3351 break;
3352 }
3353 m_sym_ctx_specified = true;
3354 break;
3355
3356 case 'l':
3357 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
3358 if (!success)
3359 {
3360 error.SetErrorStringWithFormat ("Invalid start line number: \"%s\".", option_arg);
3361 break;
3362 }
3363 m_sym_ctx_specified = true;
3364 break;
3365
3366 case 'n':
3367 m_function_name = option_arg;
3368 m_func_name_type_mask |= eFunctionNameTypeAuto;
3369 m_sym_ctx_specified = true;
3370 break;
3371
3372 case 'f':
3373 m_file_name = option_arg;
3374 m_sym_ctx_specified = true;
3375 break;
3376 case 's':
3377 m_module_name = option_arg;
3378 m_sym_ctx_specified = true;
3379 break;
3380 case 't' :
3381 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003382 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003383 if (m_thread_id == LLDB_INVALID_THREAD_ID)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003384 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003385 m_thread_specified = true;
3386 }
3387 break;
3388 case 'T':
3389 m_thread_name = option_arg;
3390 m_thread_specified = true;
3391 break;
3392 case 'q':
3393 m_queue_name = option_arg;
3394 m_thread_specified = true;
3395 break;
3396 case 'x':
3397 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003398 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003399 if (m_thread_id == UINT32_MAX)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003400 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003401 m_thread_specified = true;
3402 }
3403 break;
Johnny Chen60fe60e2011-05-02 23:47:55 +00003404 case 'o':
3405 m_use_one_liner = true;
3406 m_one_liner = option_arg;
3407 break;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003408 default:
3409 error.SetErrorStringWithFormat ("Unrecognized option %c.");
3410 break;
3411 }
3412 return error;
3413 }
3414
3415 void
Greg Clayton143fcc32011-04-13 00:18:08 +00003416 OptionParsingStarting ()
Jim Inghamd60d94a2011-03-11 03:53:59 +00003417 {
3418 m_class_name.clear();
3419 m_function_name.clear();
3420 m_line_start = 0;
3421 m_line_end = UINT_MAX;
3422 m_file_name.clear();
3423 m_module_name.clear();
3424 m_func_name_type_mask = eFunctionNameTypeAuto;
3425 m_thread_id = LLDB_INVALID_THREAD_ID;
3426 m_thread_index = UINT32_MAX;
3427 m_thread_name.clear();
3428 m_queue_name.clear();
3429
3430 m_sym_ctx_specified = false;
3431 m_thread_specified = false;
Johnny Chen60fe60e2011-05-02 23:47:55 +00003432
3433 m_use_one_liner = false;
3434 m_one_liner.clear();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003435 }
3436
3437
Greg Claytonb3448432011-03-24 21:19:54 +00003438 static OptionDefinition g_option_table[];
Jim Inghamd60d94a2011-03-11 03:53:59 +00003439
3440 std::string m_class_name;
3441 std::string m_function_name;
3442 uint32_t m_line_start;
3443 uint32_t m_line_end;
3444 std::string m_file_name;
3445 std::string m_module_name;
3446 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
3447 lldb::tid_t m_thread_id;
3448 uint32_t m_thread_index;
3449 std::string m_thread_name;
3450 std::string m_queue_name;
3451 bool m_sym_ctx_specified;
3452 bool m_thread_specified;
Johnny Chen60fe60e2011-05-02 23:47:55 +00003453 // Instance variables to hold the values for one_liner options.
3454 bool m_use_one_liner;
3455 std::string m_one_liner;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003456 };
3457
3458 Options *
3459 GetOptions ()
3460 {
3461 return &m_options;
3462 }
3463
3464 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
3465 CommandObject (interpreter,
3466 "target stop-hook add ",
3467 "Add a hook to be executed when the target stops.",
Greg Claytonf15996e2011-04-07 22:46:35 +00003468 "target stop-hook add"),
3469 m_options (interpreter)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003470 {
3471 }
3472
3473 ~CommandObjectTargetStopHookAdd ()
3474 {
3475 }
3476
3477 static size_t
3478 ReadCommandsCallbackFunction (void *baton,
3479 InputReader &reader,
3480 lldb::InputReaderAction notification,
3481 const char *bytes,
3482 size_t bytes_len)
3483 {
Caroline Tice892fadd2011-06-16 16:27:19 +00003484 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003485 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
Jim Inghame15511a2011-05-05 01:03:36 +00003486 static bool got_interrupted;
Caroline Tice892fadd2011-06-16 16:27:19 +00003487 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003488
3489 switch (notification)
3490 {
3491 case eInputReaderActivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00003492 if (!batch_mode)
3493 {
3494 out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end.");
3495 if (reader.GetPrompt())
3496 out_stream->Printf ("%s", reader.GetPrompt());
3497 out_stream->Flush();
3498 }
Jim Inghame15511a2011-05-05 01:03:36 +00003499 got_interrupted = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003500 break;
3501
3502 case eInputReaderDeactivate:
3503 break;
3504
3505 case eInputReaderReactivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00003506 if (reader.GetPrompt() && !batch_mode)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003507 {
Caroline Tice892fadd2011-06-16 16:27:19 +00003508 out_stream->Printf ("%s", reader.GetPrompt());
3509 out_stream->Flush();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003510 }
Jim Inghame15511a2011-05-05 01:03:36 +00003511 got_interrupted = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003512 break;
3513
Caroline Tice4a348082011-05-02 20:41:46 +00003514 case eInputReaderAsynchronousOutputWritten:
3515 break;
3516
Jim Inghamd60d94a2011-03-11 03:53:59 +00003517 case eInputReaderGotToken:
3518 if (bytes && bytes_len && baton)
3519 {
3520 StringList *commands = new_stop_hook->GetCommandPointer();
3521 if (commands)
3522 {
3523 commands->AppendString (bytes, bytes_len);
3524 }
3525 }
Caroline Tice892fadd2011-06-16 16:27:19 +00003526 if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003527 {
Caroline Tice892fadd2011-06-16 16:27:19 +00003528 out_stream->Printf ("%s", reader.GetPrompt());
3529 out_stream->Flush();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003530 }
3531 break;
3532
3533 case eInputReaderInterrupt:
3534 {
3535 // Finish, and cancel the stop hook.
3536 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
Caroline Tice892fadd2011-06-16 16:27:19 +00003537 if (!batch_mode)
3538 {
3539 out_stream->Printf ("Stop hook cancelled.\n");
3540 out_stream->Flush();
3541 }
3542
Jim Inghamd60d94a2011-03-11 03:53:59 +00003543 reader.SetIsDone (true);
3544 }
Jim Inghame15511a2011-05-05 01:03:36 +00003545 got_interrupted = true;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003546 break;
3547
3548 case eInputReaderEndOfFile:
3549 reader.SetIsDone (true);
3550 break;
3551
3552 case eInputReaderDone:
Caroline Tice892fadd2011-06-16 16:27:19 +00003553 if (!got_interrupted && !batch_mode)
3554 {
3555 out_stream->Printf ("Stop hook #%d added.\n", new_stop_hook->GetID());
3556 out_stream->Flush();
3557 }
Jim Inghamd60d94a2011-03-11 03:53:59 +00003558 break;
3559 }
3560
3561 return bytes_len;
3562 }
3563
3564 bool
3565 Execute (Args& command,
3566 CommandReturnObject &result)
3567 {
3568 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3569 if (target)
3570 {
3571 Target::StopHookSP new_hook_sp;
3572 target->AddStopHook (new_hook_sp);
3573
3574 // First step, make the specifier.
3575 std::auto_ptr<SymbolContextSpecifier> specifier_ap;
3576 if (m_options.m_sym_ctx_specified)
3577 {
3578 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
3579
3580 if (!m_options.m_module_name.empty())
3581 {
3582 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
3583 }
3584
3585 if (!m_options.m_class_name.empty())
3586 {
3587 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
3588 }
3589
3590 if (!m_options.m_file_name.empty())
3591 {
3592 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
3593 }
3594
3595 if (m_options.m_line_start != 0)
3596 {
3597 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
3598 }
3599
3600 if (m_options.m_line_end != UINT_MAX)
3601 {
3602 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
3603 }
3604
3605 if (!m_options.m_function_name.empty())
3606 {
3607 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
3608 }
3609 }
3610
3611 if (specifier_ap.get())
3612 new_hook_sp->SetSpecifier (specifier_ap.release());
3613
3614 // Next see if any of the thread options have been entered:
3615
3616 if (m_options.m_thread_specified)
3617 {
3618 ThreadSpec *thread_spec = new ThreadSpec();
3619
3620 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
3621 {
3622 thread_spec->SetTID (m_options.m_thread_id);
3623 }
3624
3625 if (m_options.m_thread_index != UINT32_MAX)
3626 thread_spec->SetIndex (m_options.m_thread_index);
3627
3628 if (!m_options.m_thread_name.empty())
3629 thread_spec->SetName (m_options.m_thread_name.c_str());
3630
3631 if (!m_options.m_queue_name.empty())
3632 thread_spec->SetQueueName (m_options.m_queue_name.c_str());
3633
3634 new_hook_sp->SetThreadSpecifier (thread_spec);
3635
3636 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00003637 if (m_options.m_use_one_liner)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003638 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00003639 // Use one-liner.
3640 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
Johnny Chen44953902011-05-03 00:06:12 +00003641 result.AppendMessageWithFormat("Stop hook #%d added.\n", new_hook_sp->GetID());
Jim Inghamd60d94a2011-03-11 03:53:59 +00003642 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00003643 else
Jim Inghamd60d94a2011-03-11 03:53:59 +00003644 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00003645 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into
3646 // the new stop hook's command string.
3647 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
3648 if (!reader_sp)
3649 {
3650 result.AppendError("out of memory\n");
3651 result.SetStatus (eReturnStatusFailed);
3652 target->RemoveStopHookByID (new_hook_sp->GetID());
3653 return false;
3654 }
3655
3656 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
3657 new_hook_sp.get(), // baton
3658 eInputReaderGranularityLine, // token size, to pass to callback function
3659 "DONE", // end token
3660 "> ", // prompt
3661 true)); // echo input
3662 if (!err.Success())
3663 {
3664 result.AppendError (err.AsCString());
3665 result.SetStatus (eReturnStatusFailed);
3666 target->RemoveStopHookByID (new_hook_sp->GetID());
3667 return false;
3668 }
3669 m_interpreter.GetDebugger().PushInputReader (reader_sp);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003670 }
Jim Inghamd60d94a2011-03-11 03:53:59 +00003671 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3672 }
3673 else
3674 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003675 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003676 result.SetStatus (eReturnStatusFailed);
3677 }
3678
3679 return result.Succeeded();
3680 }
3681private:
3682 CommandOptions m_options;
3683};
3684
Greg Claytonb3448432011-03-24 21:19:54 +00003685OptionDefinition
Jim Inghamd60d94a2011-03-11 03:53:59 +00003686CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
3687{
Johnny Chen60fe60e2011-05-02 23:47:55 +00003688 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, NULL, eArgTypeOneLiner,
3689 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
Jim Inghamd60d94a2011-03-11 03:53:59 +00003690 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3691 "Set the module within which the stop-hook is to be run."},
3692 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex,
3693 "The stop hook is run only for the thread whose index matches this argument."},
3694 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID,
3695 "The stop hook is run only for the thread whose TID matches this argument."},
3696 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName,
3697 "The stop hook is run only for the thread whose thread name matches this argument."},
3698 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName,
3699 "The stop hook is run only for threads in the queue whose name is given by this argument."},
3700 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
3701 "Specify the source file within which the stop-hook is to be run." },
3702 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
3703 "Set the start of the line range for which the stop-hook is to be run."},
3704 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum,
3705 "Set the end of the line range for which the stop-hook is to be run."},
3706 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName,
3707 "Specify the class within which the stop-hook is to be run." },
3708 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
3709 "Set the function name within which the stop hook will be run." },
3710 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3711};
3712
3713#pragma mark CommandObjectTargetStopHookDelete
3714
3715//-------------------------------------------------------------------------
3716// CommandObjectTargetStopHookDelete
3717//-------------------------------------------------------------------------
3718
3719class CommandObjectTargetStopHookDelete : public CommandObject
3720{
3721public:
3722
3723 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
3724 CommandObject (interpreter,
3725 "target stop-hook delete [<id>]",
3726 "Delete a stop-hook.",
3727 "target stop-hook delete")
3728 {
3729 }
3730
3731 ~CommandObjectTargetStopHookDelete ()
3732 {
3733 }
3734
3735 bool
3736 Execute (Args& command,
3737 CommandReturnObject &result)
3738 {
3739 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3740 if (target)
3741 {
3742 // FIXME: see if we can use the breakpoint id style parser?
3743 size_t num_args = command.GetArgumentCount();
3744 if (num_args == 0)
3745 {
3746 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
3747 {
3748 result.SetStatus (eReturnStatusFailed);
3749 return false;
3750 }
3751 else
3752 {
3753 target->RemoveAllStopHooks();
3754 }
3755 }
3756 else
3757 {
3758 bool success;
3759 for (size_t i = 0; i < num_args; i++)
3760 {
3761 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
3762 if (!success)
3763 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003764 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003765 result.SetStatus(eReturnStatusFailed);
3766 return false;
3767 }
3768 success = target->RemoveStopHookByID (user_id);
3769 if (!success)
3770 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003771 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003772 result.SetStatus(eReturnStatusFailed);
3773 return false;
3774 }
3775 }
3776 }
3777 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3778 }
3779 else
3780 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003781 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003782 result.SetStatus (eReturnStatusFailed);
3783 }
3784
3785 return result.Succeeded();
3786 }
3787};
3788#pragma mark CommandObjectTargetStopHookEnableDisable
3789
3790//-------------------------------------------------------------------------
3791// CommandObjectTargetStopHookEnableDisable
3792//-------------------------------------------------------------------------
3793
3794class CommandObjectTargetStopHookEnableDisable : public CommandObject
3795{
3796public:
3797
3798 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
3799 CommandObject (interpreter,
3800 name,
3801 help,
3802 syntax),
3803 m_enable (enable)
3804 {
3805 }
3806
3807 ~CommandObjectTargetStopHookEnableDisable ()
3808 {
3809 }
3810
3811 bool
3812 Execute (Args& command,
3813 CommandReturnObject &result)
3814 {
3815 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3816 if (target)
3817 {
3818 // FIXME: see if we can use the breakpoint id style parser?
3819 size_t num_args = command.GetArgumentCount();
3820 bool success;
3821
3822 if (num_args == 0)
3823 {
3824 target->SetAllStopHooksActiveState (m_enable);
3825 }
3826 else
3827 {
3828 for (size_t i = 0; i < num_args; i++)
3829 {
3830 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
3831 if (!success)
3832 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003833 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003834 result.SetStatus(eReturnStatusFailed);
3835 return false;
3836 }
3837 success = target->SetStopHookActiveStateByID (user_id, m_enable);
3838 if (!success)
3839 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003840 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003841 result.SetStatus(eReturnStatusFailed);
3842 return false;
3843 }
3844 }
3845 }
3846 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3847 }
3848 else
3849 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003850 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003851 result.SetStatus (eReturnStatusFailed);
3852 }
3853 return result.Succeeded();
3854 }
3855private:
3856 bool m_enable;
3857};
3858
3859#pragma mark CommandObjectTargetStopHookList
3860
3861//-------------------------------------------------------------------------
3862// CommandObjectTargetStopHookList
3863//-------------------------------------------------------------------------
3864
3865class CommandObjectTargetStopHookList : public CommandObject
3866{
3867public:
3868
3869 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
3870 CommandObject (interpreter,
3871 "target stop-hook list [<type>]",
3872 "List all stop-hooks.",
3873 "target stop-hook list")
3874 {
3875 }
3876
3877 ~CommandObjectTargetStopHookList ()
3878 {
3879 }
3880
3881 bool
3882 Execute (Args& command,
3883 CommandReturnObject &result)
3884 {
3885 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3886 if (target)
3887 {
3888 bool notify = true;
3889 target->GetImageSearchPathList().Clear(notify);
3890 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3891 }
3892 else
3893 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003894 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003895 result.SetStatus (eReturnStatusFailed);
3896 }
3897
3898 size_t num_hooks = target->GetNumStopHooks ();
3899 if (num_hooks == 0)
3900 {
3901 result.GetOutputStream().PutCString ("No stop hooks.\n");
3902 }
3903 else
3904 {
3905 for (size_t i = 0; i < num_hooks; i++)
3906 {
3907 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
3908 if (i > 0)
3909 result.GetOutputStream().PutCString ("\n");
3910 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
3911 }
3912 }
3913 return result.Succeeded();
3914 }
3915};
3916
3917#pragma mark CommandObjectMultiwordTargetStopHooks
3918//-------------------------------------------------------------------------
3919// CommandObjectMultiwordTargetStopHooks
3920//-------------------------------------------------------------------------
3921
3922class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
3923{
3924public:
3925
3926 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
3927 CommandObjectMultiword (interpreter,
3928 "target stop-hook",
3929 "A set of commands for operating on debugger target stop-hooks.",
3930 "target stop-hook <subcommand> [<subcommand-options>]")
3931 {
3932 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
3933 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
3934 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
3935 false,
3936 "target stop-hook disable [<id>]",
3937 "Disable a stop-hook.",
3938 "target stop-hook disable")));
3939 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
3940 true,
3941 "target stop-hook enable [<id>]",
3942 "Enable a stop-hook.",
3943 "target stop-hook enable")));
3944 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
3945 }
3946
3947 ~CommandObjectMultiwordTargetStopHooks()
3948 {
3949 }
3950};
3951
3952
Chris Lattner24943d22010-06-08 16:52:24 +00003953
3954#pragma mark CommandObjectMultiwordTarget
3955
3956//-------------------------------------------------------------------------
3957// CommandObjectMultiwordTarget
3958//-------------------------------------------------------------------------
3959
Greg Clayton63094e02010-06-23 01:19:29 +00003960CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00003961 CommandObjectMultiword (interpreter,
3962 "target",
Chris Lattner24943d22010-06-08 16:52:24 +00003963 "A set of commands for operating on debugger targets.",
3964 "target <subcommand> [<subcommand-options>]")
3965{
Greg Claytonabe0fed2011-04-18 08:33:37 +00003966
3967 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
Greg Clayton153ccd72011-08-10 02:10:13 +00003968 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
Greg Claytonabe0fed2011-04-18 08:33:37 +00003969 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter)));
3970 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003971 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
Greg Claytone1f50b92011-05-03 22:09:39 +00003972 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter)));
Greg Clayton801417e2011-07-07 01:59:51 +00003973 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00003974}
3975
3976CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
3977{
3978}
3979
Greg Claytonabe0fed2011-04-18 08:33:37 +00003980