blob: b957314cbd475bb014275d7c4e71996c3025626e [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 Claytone1f50b92011-05-03 22:09:39 +000029#include "lldb/Interpreter/OptionGroupFile.h"
Greg Clayton368f8222011-07-07 04:38:25 +000030#include "lldb/Interpreter/OptionGroupVariable.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000031#include "lldb/Interpreter/OptionGroupPlatform.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000032#include "lldb/Interpreter/OptionGroupUInt64.h"
33#include "lldb/Interpreter/OptionGroupUUID.h"
Greg Clayton801417e2011-07-07 01:59:51 +000034#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000035#include "lldb/Symbol/LineTable.h"
36#include "lldb/Symbol/ObjectFile.h"
37#include "lldb/Symbol/SymbolFile.h"
38#include "lldb/Symbol/SymbolVendor.h"
Greg Clayton801417e2011-07-07 01:59:51 +000039#include "lldb/Symbol/VariableList.h"
Chris Lattner24943d22010-06-08 16:52:24 +000040#include "lldb/Target/Process.h"
41#include "lldb/Target/StackFrame.h"
42#include "lldb/Target/Thread.h"
Jim Inghamd60d94a2011-03-11 03:53:59 +000043#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000044
45using namespace lldb;
46using namespace lldb_private;
47
Greg Claytonabe0fed2011-04-18 08:33:37 +000048
49
50static void
51DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
52{
Greg Clayton52c8b6e2011-04-19 04:19:37 +000053 const ArchSpec &target_arch = target->GetArchitecture();
Greg Claytonabe0fed2011-04-18 08:33:37 +000054
55 ModuleSP exe_module_sp (target->GetExecutableModule ());
56 char exe_path[PATH_MAX];
57 bool exe_valid = false;
58 if (exe_module_sp)
59 exe_valid = exe_module_sp->GetFileSpec().GetPath (exe_path, sizeof(exe_path));
60
61 if (!exe_valid)
62 ::strcpy (exe_path, "<none>");
63
64 strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path);
65
66 uint32_t properties = 0;
67 if (target_arch.IsValid())
68 {
69 strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str());
70 properties++;
71 }
72 PlatformSP platform_sp (target->GetPlatform());
73 if (platform_sp)
74 strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName());
75
76 ProcessSP process_sp (target->GetProcessSP());
77 bool show_process_status = false;
78 if (process_sp)
79 {
80 lldb::pid_t pid = process_sp->GetID();
81 StateType state = process_sp->GetState();
82 if (show_stopped_process_status)
83 show_process_status = StateIsStoppedState(state);
84 const char *state_cstr = StateAsCString (state);
85 if (pid != LLDB_INVALID_PROCESS_ID)
86 strm.Printf ("%spid=%i", properties++ > 0 ? ", " : " ( ", pid);
87 strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
88 }
89 if (properties > 0)
90 strm.PutCString (" )\n");
91 else
92 strm.EOL();
93 if (show_process_status)
94 {
95 const bool only_threads_with_stop_reason = true;
96 const uint32_t start_frame = 0;
97 const uint32_t num_frames = 1;
98 const uint32_t num_frames_with_source = 1;
99 process_sp->GetStatus (strm);
100 process_sp->GetThreadStatus (strm,
101 only_threads_with_stop_reason,
102 start_frame,
103 num_frames,
104 num_frames_with_source);
105
106 }
107}
108
109static uint32_t
110DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm)
111{
112 const uint32_t num_targets = target_list.GetNumTargets();
113 if (num_targets)
114 {
115 TargetSP selected_target_sp (target_list.GetSelectedTarget());
116 strm.PutCString ("Current targets:\n");
117 for (uint32_t i=0; i<num_targets; ++i)
118 {
119 TargetSP target_sp (target_list.GetTargetAtIndex (i));
120 if (target_sp)
121 {
122 bool is_selected = target_sp.get() == selected_target_sp.get();
123 DumpTargetInfo (i,
124 target_sp.get(),
125 is_selected ? "* " : " ",
126 show_stopped_process_status,
127 strm);
128 }
129 }
130 }
131 return num_targets;
132}
133#pragma mark CommandObjectTargetCreate
134
135//-------------------------------------------------------------------------
136// "target create"
137//-------------------------------------------------------------------------
138
139class CommandObjectTargetCreate : public CommandObject
140{
141public:
142 CommandObjectTargetCreate(CommandInterpreter &interpreter) :
143 CommandObject (interpreter,
144 "target create",
145 "Create a target using the argument as the main executable.",
146 NULL),
147 m_option_group (interpreter),
Greg Clayton801417e2011-07-07 01:59:51 +0000148 m_arch_option (),
Greg Claytonabe0fed2011-04-18 08:33:37 +0000149 m_platform_options(true) // Do include the "--platform" option in the platform settings by passing true
150 {
151 CommandArgumentEntry arg;
152 CommandArgumentData file_arg;
153
154 // Define the first (and only) variant of this arg.
155 file_arg.arg_type = eArgTypeFilename;
156 file_arg.arg_repetition = eArgRepeatPlain;
157
158 // There is only one variant this argument could be; put it into the argument entry.
159 arg.push_back (file_arg);
160
161 // Push the data for the first argument into the m_arguments vector.
162 m_arguments.push_back (arg);
163
Greg Clayton801417e2011-07-07 01:59:51 +0000164 m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000165 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
166 m_option_group.Finalize();
167 }
168
169 ~CommandObjectTargetCreate ()
170 {
171 }
172
173 Options *
174 GetOptions ()
175 {
176 return &m_option_group;
177 }
178
179 bool
180 Execute (Args& command, CommandReturnObject &result)
181 {
182 const int argc = command.GetArgumentCount();
183 if (argc == 1)
184 {
185 const char *file_path = command.GetArgumentAtIndex(0);
186 Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path);
187 FileSpec file_spec (file_path, true);
188
189 bool select = true;
190 PlatformSP platform_sp;
191
192 Error error;
193
194 if (m_platform_options.PlatformWasSpecified ())
195 {
196 platform_sp = m_platform_options.CreatePlatformWithOptions(m_interpreter, select, error);
197 if (!platform_sp)
198 {
199 result.AppendError(error.AsCString());
200 result.SetStatus (eReturnStatusFailed);
201 return false;
202 }
203 }
204 ArchSpec file_arch;
205
Greg Clayton801417e2011-07-07 01:59:51 +0000206 const char *arch_cstr = m_arch_option.GetArchitectureName();
Greg Claytonabe0fed2011-04-18 08:33:37 +0000207 if (arch_cstr)
208 {
209 if (!platform_sp)
210 platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
Greg Clayton801417e2011-07-07 01:59:51 +0000211 if (!m_arch_option.GetArchitecture(platform_sp.get(), file_arch))
Greg Claytonabe0fed2011-04-18 08:33:37 +0000212 {
213 result.AppendErrorWithFormat("invalid architecture '%s'\n", arch_cstr);
214 result.SetStatus (eReturnStatusFailed);
215 return false;
216 }
217 }
218
219 if (! file_spec.Exists() && !file_spec.ResolveExecutableLocation())
220 {
221 result.AppendErrorWithFormat ("File '%s' does not exist.\n", file_path);
222 result.SetStatus (eReturnStatusFailed);
223 return false;
224 }
225
226 TargetSP target_sp;
227 Debugger &debugger = m_interpreter.GetDebugger();
228 error = debugger.GetTargetList().CreateTarget (debugger, file_spec, file_arch, true, target_sp);
229
230 if (target_sp)
231 {
232 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
233 result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName());
234 result.SetStatus (eReturnStatusSuccessFinishNoResult);
235 }
236 else
237 {
238 result.AppendError(error.AsCString());
239 result.SetStatus (eReturnStatusFailed);
240 }
241 }
242 else
243 {
244 result.AppendErrorWithFormat("'%s' takes exactly one executable path argument.\n", m_cmd_name.c_str());
245 result.SetStatus (eReturnStatusFailed);
246 }
247 return result.Succeeded();
248
249 }
250
251 int
252 HandleArgumentCompletion (Args &input,
253 int &cursor_index,
254 int &cursor_char_position,
255 OptionElementVector &opt_element_vector,
256 int match_start_point,
257 int max_return_elements,
258 bool &word_complete,
259 StringList &matches)
260 {
261 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
262 completion_str.erase (cursor_char_position);
263
264 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
265 CommandCompletions::eDiskFileCompletion,
266 completion_str.c_str(),
267 match_start_point,
268 max_return_elements,
269 NULL,
270 word_complete,
271 matches);
272 return matches.GetSize();
273 }
274private:
275 OptionGroupOptions m_option_group;
Greg Clayton801417e2011-07-07 01:59:51 +0000276 OptionGroupArchitecture m_arch_option;
Greg Claytonabe0fed2011-04-18 08:33:37 +0000277 OptionGroupPlatform m_platform_options;
278
279};
280
281#pragma mark CommandObjectTargetList
282
283//----------------------------------------------------------------------
284// "target list"
285//----------------------------------------------------------------------
286
287class CommandObjectTargetList : public CommandObject
288{
289public:
290 CommandObjectTargetList (CommandInterpreter &interpreter) :
291 CommandObject (interpreter,
292 "target list",
293 "List all current targets in the current debug session.",
294 NULL,
295 0)
296 {
297 }
298
299 virtual
300 ~CommandObjectTargetList ()
301 {
302 }
303
304 virtual bool
305 Execute (Args& args, CommandReturnObject &result)
306 {
307 if (args.GetArgumentCount() == 0)
308 {
309 Stream &strm = result.GetOutputStream();
310
311 bool show_stopped_process_status = false;
312 if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0)
313 {
314 strm.PutCString ("No targets.\n");
315 }
Johnny Chen44dc9d32011-04-18 21:08:05 +0000316 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000317 }
318 else
319 {
320 result.AppendError ("the 'target list' command takes no arguments\n");
321 result.SetStatus (eReturnStatusFailed);
322 }
323 return result.Succeeded();
324 }
325};
326
327
328#pragma mark CommandObjectTargetSelect
329
330//----------------------------------------------------------------------
331// "target select"
332//----------------------------------------------------------------------
333
334class CommandObjectTargetSelect : public CommandObject
335{
336public:
337 CommandObjectTargetSelect (CommandInterpreter &interpreter) :
338 CommandObject (interpreter,
339 "target select",
340 "Select a target as the current target by target index.",
341 NULL,
342 0)
343 {
344 }
345
346 virtual
347 ~CommandObjectTargetSelect ()
348 {
349 }
350
351 virtual bool
352 Execute (Args& args, CommandReturnObject &result)
353 {
354 if (args.GetArgumentCount() == 1)
355 {
356 bool success = false;
357 const char *target_idx_arg = args.GetArgumentAtIndex(0);
358 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
359 if (success)
360 {
361 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
362 const uint32_t num_targets = target_list.GetNumTargets();
363 if (target_idx < num_targets)
364 {
365 TargetSP target_sp (target_list.GetTargetAtIndex (target_idx));
366 if (target_sp)
367 {
368 Stream &strm = result.GetOutputStream();
369 target_list.SetSelectedTarget (target_sp.get());
370 bool show_stopped_process_status = false;
371 DumpTargetList (target_list, show_stopped_process_status, strm);
Johnny Chen44dc9d32011-04-18 21:08:05 +0000372 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000373 }
374 else
375 {
376 result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx);
377 result.SetStatus (eReturnStatusFailed);
378 }
379 }
380 else
381 {
382 result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n",
383 target_idx,
384 num_targets - 1);
385 result.SetStatus (eReturnStatusFailed);
386 }
387 }
388 else
389 {
390 result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg);
391 result.SetStatus (eReturnStatusFailed);
392 }
393 }
394 else
395 {
396 result.AppendError ("'target select' takes a single argument: a target index\n");
397 result.SetStatus (eReturnStatusFailed);
398 }
399 return result.Succeeded();
400 }
401};
402
403
Greg Clayton801417e2011-07-07 01:59:51 +0000404#pragma mark CommandObjectTargetVariable
405
406//----------------------------------------------------------------------
407// "target variable"
408//----------------------------------------------------------------------
409
410class CommandObjectTargetVariable : public CommandObject
411{
412public:
413 CommandObjectTargetVariable (CommandInterpreter &interpreter) :
414 CommandObject (interpreter,
415 "target select",
416 "Select a target as the current target by target index.",
417 NULL,
418 0),
419 m_option_group (interpreter),
Greg Clayton368f8222011-07-07 04:38:25 +0000420 m_option_variable (false), // Don't include frame options
Greg Clayton801417e2011-07-07 01:59:51 +0000421 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."),
422 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."),
423 m_varobj_options()
424 {
425 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Clayton368f8222011-07-07 04:38:25 +0000426 m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Clayton801417e2011-07-07 01:59:51 +0000427 m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
428 m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
429 m_option_group.Finalize();
430 }
431
432 virtual
433 ~CommandObjectTargetVariable ()
434 {
435 }
Greg Clayton5d81f492011-07-08 21:46:14 +0000436
437 void
438 DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name)
439 {
440 if (m_option_variable.format != eFormatDefault)
441 valobj_sp->SetFormat (m_option_variable.format);
442
443 switch (var_sp->GetScope())
444 {
445 case eValueTypeVariableGlobal:
446 if (m_option_variable.show_scope)
447 s.PutCString("GLOBAL: ");
448 break;
449
450 case eValueTypeVariableStatic:
451 if (m_option_variable.show_scope)
452 s.PutCString("STATIC: ");
453 break;
454
455 case eValueTypeVariableArgument:
456 if (m_option_variable.show_scope)
457 s.PutCString(" ARG: ");
458 break;
459
460 case eValueTypeVariableLocal:
461 if (m_option_variable.show_scope)
462 s.PutCString(" LOCAL: ");
463 break;
464
465 default:
466 break;
467 }
468
Greg Claytonfb816422011-07-10 19:21:23 +0000469 if (m_option_variable.show_decl)
Greg Clayton5d81f492011-07-08 21:46:14 +0000470 {
Greg Claytonfb816422011-07-10 19:21:23 +0000471 bool show_fullpaths = false;
472 bool show_module = true;
473 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
474 s.PutCString (": ");
Greg Clayton5d81f492011-07-08 21:46:14 +0000475 }
476
477 const Format format = m_option_variable.format;
478 if (format != eFormatDefault)
479 valobj_sp->SetFormat (format);
480
481 ValueObject::DumpValueObject (s,
482 valobj_sp.get(),
483 root_name,
484 m_varobj_options.ptr_depth,
485 0,
486 m_varobj_options.max_depth,
487 m_varobj_options.show_types,
488 m_varobj_options.show_location,
489 m_varobj_options.use_objc,
490 m_varobj_options.use_dynamic,
491 false,
492 m_varobj_options.flat_output);
493
494 }
Greg Clayton801417e2011-07-07 01:59:51 +0000495
Greg Clayton5d81f492011-07-08 21:46:14 +0000496
497 static uint32_t GetVariableCallback (void *baton,
498 const char *name,
499 VariableList &variable_list)
500 {
501 Target *target = static_cast<Target *>(baton);
502 if (target)
503 {
504 return target->GetImages().FindGlobalVariables (ConstString(name),
505 true,
506 UINT32_MAX,
507 variable_list);
508 }
509 return 0;
510 }
511
512
513
Greg Clayton801417e2011-07-07 01:59:51 +0000514 virtual bool
515 Execute (Args& args, CommandReturnObject &result)
516 {
517 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
518
519 if (exe_ctx.target)
520 {
521 const size_t argc = args.GetArgumentCount();
522 if (argc > 0)
523 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000524 Stream &s = result.GetOutputStream();
525
Greg Clayton801417e2011-07-07 01:59:51 +0000526 for (size_t idx = 0; idx < argc; ++idx)
527 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000528 VariableList variable_list;
529 ValueObjectList valobj_list;
530
Greg Clayton368f8222011-07-07 04:38:25 +0000531 const char *arg = args.GetArgumentAtIndex(idx);
532 uint32_t matches = 0;
Greg Claytonfb816422011-07-10 19:21:23 +0000533 bool use_var_name = false;
Greg Clayton368f8222011-07-07 04:38:25 +0000534 if (m_option_variable.use_regex)
Greg Clayton801417e2011-07-07 01:59:51 +0000535 {
Greg Clayton368f8222011-07-07 04:38:25 +0000536 RegularExpression regex(arg);
537 if (!regex.IsValid ())
538 {
539 result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg);
540 result.SetStatus (eReturnStatusFailed);
541 return false;
542 }
Greg Claytonfb816422011-07-10 19:21:23 +0000543 use_var_name = true;
Greg Clayton368f8222011-07-07 04:38:25 +0000544 matches = exe_ctx.target->GetImages().FindGlobalVariables (regex,
545 true,
546 UINT32_MAX,
Greg Clayton5d81f492011-07-08 21:46:14 +0000547 variable_list);
Greg Clayton801417e2011-07-07 01:59:51 +0000548 }
549 else
550 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000551 Error error (Variable::GetValuesForVariableExpressionPath (arg,
Greg Clayton24b03102011-07-09 20:12:33 +0000552 exe_ctx.GetBestExecutionContextScope(),
Greg Clayton5d81f492011-07-08 21:46:14 +0000553 GetVariableCallback,
554 exe_ctx.target,
555 variable_list,
556 valobj_list));
557
558// matches = exe_ctx.target->GetImages().FindGlobalVariables (ConstString(arg),
559// true,
560// UINT32_MAX,
561// variable_list);
562 matches = variable_list.GetSize();
Greg Clayton368f8222011-07-07 04:38:25 +0000563 }
564
565 if (matches == 0)
566 {
567 result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg);
568 result.SetStatus (eReturnStatusFailed);
569 return false;
570 }
571 else
572 {
Greg Clayton801417e2011-07-07 01:59:51 +0000573 for (uint32_t global_idx=0; global_idx<matches; ++global_idx)
574 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000575 VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx));
Greg Clayton801417e2011-07-07 01:59:51 +0000576 if (var_sp)
577 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000578 ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx));
579 if (!valobj_sp)
Greg Claytonfb816422011-07-10 19:21:23 +0000580 valobj_sp = ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp);
Greg Clayton801417e2011-07-07 01:59:51 +0000581
582 if (valobj_sp)
Greg Claytonfb816422011-07-10 19:21:23 +0000583 DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg);
Greg Clayton801417e2011-07-07 01:59:51 +0000584 }
585 }
586 }
587 }
588 }
589 else
590 {
591 result.AppendError ("'target variable' takes one or more global variable names as arguments\n");
592 result.SetStatus (eReturnStatusFailed);
593 }
594 }
595 else
596 {
597 result.AppendError ("invalid target, create a debug target using the 'target create' command");
598 result.SetStatus (eReturnStatusFailed);
599 return false;
600 }
601 return result.Succeeded();
602 }
603
604 Options *
605 GetOptions ()
606 {
607 return &m_option_group;
608 }
609
610protected:
611 OptionGroupOptions m_option_group;
Greg Clayton368f8222011-07-07 04:38:25 +0000612 OptionGroupVariable m_option_variable;
Greg Clayton801417e2011-07-07 01:59:51 +0000613 OptionGroupFileList m_option_compile_units;
614 OptionGroupFileList m_option_shared_libraries;
615 OptionGroupValueObjectDisplay m_varobj_options;
616
617};
618
619
Greg Claytone1f50b92011-05-03 22:09:39 +0000620#pragma mark CommandObjectTargetModulesSearchPathsAdd
Chris Lattner24943d22010-06-08 16:52:24 +0000621
Greg Claytone1f50b92011-05-03 22:09:39 +0000622class CommandObjectTargetModulesSearchPathsAdd : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000623{
624public:
625
Greg Claytone1f50b92011-05-03 22:09:39 +0000626 CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000627 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000628 "target modules search-paths add",
Chris Lattner24943d22010-06-08 16:52:24 +0000629 "Add new image search paths substitution pairs to the current target.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000630 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000631 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000632 CommandArgumentEntry arg;
633 CommandArgumentData old_prefix_arg;
634 CommandArgumentData new_prefix_arg;
635
636 // Define the first variant of this arg pair.
637 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
638 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
639
640 // Define the first variant of this arg pair.
641 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
642 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
643
644 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
645 // must always occur together, they are treated as two variants of one argument rather than two independent
646 // arguments. Push them both into the first argument position for m_arguments...
647
648 arg.push_back (old_prefix_arg);
649 arg.push_back (new_prefix_arg);
650
651 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000652 }
653
Greg Claytone1f50b92011-05-03 22:09:39 +0000654 ~CommandObjectTargetModulesSearchPathsAdd ()
Chris Lattner24943d22010-06-08 16:52:24 +0000655 {
656 }
657
658 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000659 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000660 CommandReturnObject &result)
661 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000662 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000663 if (target)
664 {
665 uint32_t argc = command.GetArgumentCount();
666 if (argc & 1)
667 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000668 result.AppendError ("add requires an even number of arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000669 result.SetStatus (eReturnStatusFailed);
670 }
671 else
672 {
673 for (uint32_t i=0; i<argc; i+=2)
674 {
675 const char *from = command.GetArgumentAtIndex(i);
676 const char *to = command.GetArgumentAtIndex(i+1);
677
678 if (from[0] && to[0])
679 {
680 bool last_pair = ((argc - i) == 2);
Greg Clayton63094e02010-06-23 01:19:29 +0000681 target->GetImageSearchPathList().Append (ConstString(from),
682 ConstString(to),
683 last_pair); // Notify if this is the last pair
Johnny Chen4d661352011-02-03 00:30:19 +0000684 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000685 }
686 else
687 {
688 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +0000689 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000690 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000691 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000692 result.SetStatus (eReturnStatusFailed);
693 }
694 }
695 }
696 }
697 else
698 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000699 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000700 result.SetStatus (eReturnStatusFailed);
701 }
702 return result.Succeeded();
703 }
704};
705
Greg Claytone1f50b92011-05-03 22:09:39 +0000706#pragma mark CommandObjectTargetModulesSearchPathsClear
707
708class CommandObjectTargetModulesSearchPathsClear : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000709{
710public:
711
Greg Claytone1f50b92011-05-03 22:09:39 +0000712 CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000713 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000714 "target modules search-paths clear",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000715 "Clear all current image search path substitution pairs from the current target.",
Greg Claytone1f50b92011-05-03 22:09:39 +0000716 "target modules search-paths clear")
Chris Lattner24943d22010-06-08 16:52:24 +0000717 {
718 }
719
Greg Claytone1f50b92011-05-03 22:09:39 +0000720 ~CommandObjectTargetModulesSearchPathsClear ()
Chris Lattner24943d22010-06-08 16:52:24 +0000721 {
722 }
723
724 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000725 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000726 CommandReturnObject &result)
727 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000728 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000729 if (target)
730 {
731 bool notify = true;
732 target->GetImageSearchPathList().Clear(notify);
Johnny Chen4d661352011-02-03 00:30:19 +0000733 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000734 }
735 else
736 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000737 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000738 result.SetStatus (eReturnStatusFailed);
739 }
740 return result.Succeeded();
741 }
742};
743
Greg Claytone1f50b92011-05-03 22:09:39 +0000744#pragma mark CommandObjectTargetModulesSearchPathsInsert
745
746class CommandObjectTargetModulesSearchPathsInsert : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000747{
748public:
749
Greg Claytone1f50b92011-05-03 22:09:39 +0000750 CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000751 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000752 "target modules search-paths insert",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000753 "Insert a new image search path substitution pair into the current target at the specified index.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000754 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000755 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000756 CommandArgumentEntry arg1;
757 CommandArgumentEntry arg2;
758 CommandArgumentData index_arg;
759 CommandArgumentData old_prefix_arg;
760 CommandArgumentData new_prefix_arg;
761
762 // Define the first and only variant of this arg.
763 index_arg.arg_type = eArgTypeIndex;
764 index_arg.arg_repetition = eArgRepeatPlain;
765
766 // Put the one and only variant into the first arg for m_arguments:
767 arg1.push_back (index_arg);
768
769 // Define the first variant of this arg pair.
770 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
771 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
772
773 // Define the first variant of this arg pair.
774 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
775 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
776
777 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
778 // must always occur together, they are treated as two variants of one argument rather than two independent
779 // arguments. Push them both into the same argument position for m_arguments...
780
781 arg2.push_back (old_prefix_arg);
782 arg2.push_back (new_prefix_arg);
783
784 // Add arguments to m_arguments.
785 m_arguments.push_back (arg1);
786 m_arguments.push_back (arg2);
Chris Lattner24943d22010-06-08 16:52:24 +0000787 }
788
Greg Claytone1f50b92011-05-03 22:09:39 +0000789 ~CommandObjectTargetModulesSearchPathsInsert ()
Chris Lattner24943d22010-06-08 16:52:24 +0000790 {
791 }
792
793 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000794 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000795 CommandReturnObject &result)
796 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000797 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000798 if (target)
799 {
800 uint32_t argc = command.GetArgumentCount();
801 // check for at least 3 arguments and an odd nubmer of parameters
802 if (argc >= 3 && argc & 1)
803 {
804 bool success = false;
805
806 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
807
808 if (!success)
809 {
810 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
811 result.SetStatus (eReturnStatusFailed);
812 return result.Succeeded();
813 }
814
815 // shift off the index
816 command.Shift();
817 argc = command.GetArgumentCount();
818
819 for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
820 {
821 const char *from = command.GetArgumentAtIndex(i);
822 const char *to = command.GetArgumentAtIndex(i+1);
823
824 if (from[0] && to[0])
825 {
826 bool last_pair = ((argc - i) == 2);
827 target->GetImageSearchPathList().Insert (ConstString(from),
828 ConstString(to),
829 insert_idx,
830 last_pair);
Johnny Chen4d661352011-02-03 00:30:19 +0000831 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000832 }
833 else
834 {
835 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +0000836 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000837 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000838 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000839 result.SetStatus (eReturnStatusFailed);
840 return false;
841 }
842 }
843 }
844 else
845 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000846 result.AppendError ("insert requires at least three arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000847 result.SetStatus (eReturnStatusFailed);
848 return result.Succeeded();
849 }
850
851 }
852 else
853 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000854 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000855 result.SetStatus (eReturnStatusFailed);
856 }
857 return result.Succeeded();
858 }
859};
860
Greg Claytone1f50b92011-05-03 22:09:39 +0000861
862#pragma mark CommandObjectTargetModulesSearchPathsList
863
864
865class CommandObjectTargetModulesSearchPathsList : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000866{
867public:
868
Greg Claytone1f50b92011-05-03 22:09:39 +0000869 CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000870 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000871 "target modules search-paths list",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000872 "List all current image search path substitution pairs in the current target.",
Greg Claytone1f50b92011-05-03 22:09:39 +0000873 "target modules search-paths list")
Chris Lattner24943d22010-06-08 16:52:24 +0000874 {
875 }
876
Greg Claytone1f50b92011-05-03 22:09:39 +0000877 ~CommandObjectTargetModulesSearchPathsList ()
Chris Lattner24943d22010-06-08 16:52:24 +0000878 {
879 }
880
881 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000882 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000883 CommandReturnObject &result)
884 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000885 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000886 if (target)
887 {
888 if (command.GetArgumentCount() != 0)
889 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000890 result.AppendError ("list takes no arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000891 result.SetStatus (eReturnStatusFailed);
892 return result.Succeeded();
893 }
894
895 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
Johnny Chen4d661352011-02-03 00:30:19 +0000896 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000897 }
898 else
899 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000900 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000901 result.SetStatus (eReturnStatusFailed);
902 }
903 return result.Succeeded();
904 }
905};
906
Greg Claytone1f50b92011-05-03 22:09:39 +0000907#pragma mark CommandObjectTargetModulesSearchPathsQuery
908
909class CommandObjectTargetModulesSearchPathsQuery : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000910{
911public:
912
Greg Claytone1f50b92011-05-03 22:09:39 +0000913 CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000914 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000915 "target modules search-paths query",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000916 "Transform a path using the first applicable image search path.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000917 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000918 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000919 CommandArgumentEntry arg;
920 CommandArgumentData path_arg;
921
922 // Define the first (and only) variant of this arg.
923 path_arg.arg_type = eArgTypePath;
924 path_arg.arg_repetition = eArgRepeatPlain;
925
926 // There is only one variant this argument could be; put it into the argument entry.
927 arg.push_back (path_arg);
928
929 // Push the data for the first argument into the m_arguments vector.
930 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000931 }
932
Greg Claytone1f50b92011-05-03 22:09:39 +0000933 ~CommandObjectTargetModulesSearchPathsQuery ()
Chris Lattner24943d22010-06-08 16:52:24 +0000934 {
935 }
936
937 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000938 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000939 CommandReturnObject &result)
940 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000941 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000942 if (target)
943 {
944 if (command.GetArgumentCount() != 1)
945 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000946 result.AppendError ("query requires one argument\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000947 result.SetStatus (eReturnStatusFailed);
948 return result.Succeeded();
949 }
950
951 ConstString orig(command.GetArgumentAtIndex(0));
952 ConstString transformed;
953 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
954 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
955 else
956 result.GetOutputStream().Printf("%s\n", orig.GetCString());
Johnny Chen4d661352011-02-03 00:30:19 +0000957
958 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000959 }
960 else
961 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000962 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000963 result.SetStatus (eReturnStatusFailed);
964 }
965 return result.Succeeded();
966 }
967};
968
Greg Claytone1f50b92011-05-03 22:09:39 +0000969//----------------------------------------------------------------------
970// Static Helper functions
971//----------------------------------------------------------------------
972static void
973DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width)
974{
975 if (module)
976 {
977 const char *arch_cstr;
978 if (full_triple)
979 arch_cstr = module->GetArchitecture().GetTriple().str().c_str();
980 else
981 arch_cstr = module->GetArchitecture().GetArchitectureName();
982 if (width)
983 strm.Printf("%-*s", width, arch_cstr);
984 else
985 strm.PutCString(arch_cstr);
986 }
987}
988
989static void
990DumpModuleUUID (Stream &strm, Module *module)
991{
992 module->GetUUID().Dump (&strm);
993}
994
995static uint32_t
996DumpCompileUnitLineTable
997(
998 CommandInterpreter &interpreter,
999 Stream &strm,
1000 Module *module,
1001 const FileSpec &file_spec,
1002 bool load_addresses
1003 )
1004{
1005 uint32_t num_matches = 0;
1006 if (module)
1007 {
1008 SymbolContextList sc_list;
1009 num_matches = module->ResolveSymbolContextsForFileSpec (file_spec,
1010 0,
1011 false,
1012 eSymbolContextCompUnit,
1013 sc_list);
1014
1015 for (uint32_t i=0; i<num_matches; ++i)
1016 {
1017 SymbolContext sc;
1018 if (sc_list.GetContextAtIndex(i, sc))
1019 {
1020 if (i > 0)
1021 strm << "\n\n";
1022
1023 strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `"
1024 << module->GetFileSpec().GetFilename() << "\n";
1025 LineTable *line_table = sc.comp_unit->GetLineTable();
1026 if (line_table)
1027 line_table->GetDescription (&strm,
1028 interpreter.GetExecutionContext().target,
1029 lldb::eDescriptionLevelBrief);
1030 else
1031 strm << "No line table";
1032 }
1033 }
1034 }
1035 return num_matches;
1036}
1037
1038static void
1039DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1040{
1041 if (file_spec_ptr)
1042 {
1043 if (width > 0)
1044 {
1045 char fullpath[PATH_MAX];
1046 if (file_spec_ptr->GetPath(fullpath, sizeof(fullpath)))
1047 {
1048 strm.Printf("%-*s", width, fullpath);
1049 return;
1050 }
1051 }
1052 else
1053 {
1054 file_spec_ptr->Dump(&strm);
1055 return;
1056 }
1057 }
1058 // Keep the width spacing correct if things go wrong...
1059 if (width > 0)
1060 strm.Printf("%-*s", width, "");
1061}
1062
1063static void
1064DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1065{
1066 if (file_spec_ptr)
1067 {
1068 if (width > 0)
1069 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1070 else
1071 file_spec_ptr->GetDirectory().Dump(&strm);
1072 return;
1073 }
1074 // Keep the width spacing correct if things go wrong...
1075 if (width > 0)
1076 strm.Printf("%-*s", width, "");
1077}
1078
1079static void
1080DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1081{
1082 if (file_spec_ptr)
1083 {
1084 if (width > 0)
1085 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1086 else
1087 file_spec_ptr->GetFilename().Dump(&strm);
1088 return;
1089 }
1090 // Keep the width spacing correct if things go wrong...
1091 if (width > 0)
1092 strm.Printf("%-*s", width, "");
1093}
1094
1095
1096static void
1097DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order)
1098{
1099 if (module)
1100 {
1101 ObjectFile *objfile = module->GetObjectFile ();
1102 if (objfile)
1103 {
1104 Symtab *symtab = objfile->GetSymtab();
1105 if (symtab)
1106 symtab->Dump(&strm, interpreter.GetExecutionContext().target, sort_order);
1107 }
1108 }
1109}
1110
1111static void
1112DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module)
1113{
1114 if (module)
1115 {
1116 ObjectFile *objfile = module->GetObjectFile ();
1117 if (objfile)
1118 {
1119 SectionList *section_list = objfile->GetSectionList();
1120 if (section_list)
1121 {
1122 strm.PutCString ("Sections for '");
1123 strm << module->GetFileSpec();
1124 if (module->GetObjectName())
1125 strm << '(' << module->GetObjectName() << ')';
1126 strm.Printf ("' (%s):\n", module->GetArchitecture().GetArchitectureName());
1127 strm.IndentMore();
1128 section_list->Dump(&strm, interpreter.GetExecutionContext().target, true, UINT32_MAX);
1129 strm.IndentLess();
1130 }
1131 }
1132 }
1133}
1134
1135static bool
1136DumpModuleSymbolVendor (Stream &strm, Module *module)
1137{
1138 if (module)
1139 {
1140 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1141 if (symbol_vendor)
1142 {
1143 symbol_vendor->Dump(&strm);
1144 return true;
1145 }
1146 }
1147 return false;
1148}
1149
1150static bool
1151LookupAddressInModule
1152(
1153 CommandInterpreter &interpreter,
1154 Stream &strm,
1155 Module *module,
1156 uint32_t resolve_mask,
1157 lldb::addr_t raw_addr,
1158 lldb::addr_t offset,
1159 bool verbose
1160 )
1161{
1162 if (module)
1163 {
1164 lldb::addr_t addr = raw_addr - offset;
1165 Address so_addr;
1166 SymbolContext sc;
1167 Target *target = interpreter.GetExecutionContext().target;
1168 if (target && !target->GetSectionLoadList().IsEmpty())
1169 {
1170 if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr))
1171 return false;
1172 else if (so_addr.GetModule() != module)
1173 return false;
1174 }
1175 else
1176 {
1177 if (!module->ResolveFileAddress (addr, so_addr))
1178 return false;
1179 }
1180
1181 // If an offset was given, print out the address we ended up looking up
1182 if (offset)
1183 strm.Printf("File Address: 0x%llx\n", addr);
1184
1185 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope();
1186 strm.IndentMore();
1187 strm.Indent (" Address: ");
1188 so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1189 strm.EOL();
1190 strm.Indent (" Summary: ");
1191 const uint32_t save_indent = strm.GetIndentLevel ();
1192 strm.SetIndentLevel (save_indent + 11);
1193 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
1194 strm.SetIndentLevel (save_indent);
1195 strm.EOL();
1196 // Print out detailed address information when verbose is enabled
1197 if (verbose)
1198 {
1199 if (so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext))
1200 strm.EOL();
1201 }
1202 strm.IndentLess();
1203 return true;
1204 }
1205
1206 return false;
1207}
1208
1209static uint32_t
1210LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
1211{
1212 if (module)
1213 {
1214 SymbolContext sc;
1215
1216 ObjectFile *objfile = module->GetObjectFile ();
1217 if (objfile)
1218 {
1219 Symtab *symtab = objfile->GetSymtab();
1220 if (symtab)
1221 {
1222 uint32_t i;
1223 std::vector<uint32_t> match_indexes;
1224 ConstString symbol_name (name);
1225 uint32_t num_matches = 0;
1226 if (name_is_regex)
1227 {
1228 RegularExpression name_regexp(name);
1229 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp,
1230 eSymbolTypeAny,
1231 match_indexes);
1232 }
1233 else
1234 {
1235 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
1236 }
1237
1238
1239 if (num_matches > 0)
1240 {
1241 strm.Indent ();
1242 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1243 name_is_regex ? "the regular expression " : "", name);
1244 DumpFullpath (strm, &module->GetFileSpec(), 0);
1245 strm.PutCString(":\n");
1246 strm.IndentMore ();
1247 Symtab::DumpSymbolHeader (&strm);
1248 for (i=0; i < num_matches; ++i)
1249 {
1250 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1251 strm.Indent ();
1252 symbol->Dump (&strm, interpreter.GetExecutionContext().target, i);
1253 }
1254 strm.IndentLess ();
1255 return num_matches;
1256 }
1257 }
1258 }
1259 }
1260 return 0;
1261}
1262
1263
1264static void
1265DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr, bool verbose)
1266{
1267 strm.IndentMore ();
1268 uint32_t i;
1269 const uint32_t num_matches = sc_list.GetSize();
1270
1271 for (i=0; i<num_matches; ++i)
1272 {
1273 SymbolContext sc;
1274 if (sc_list.GetContextAtIndex(i, sc))
1275 {
1276 strm.Indent();
1277 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope ();
1278
1279 if (prepend_addr)
1280 {
1281 if (sc.line_entry.range.GetBaseAddress().IsValid())
1282 {
1283 sc.line_entry.range.GetBaseAddress().Dump (&strm,
1284 exe_scope,
1285 Address::DumpStyleLoadAddress,
1286 Address::DumpStyleModuleWithFileAddress);
1287 strm.PutCString(" in ");
1288 }
1289 }
1290 sc.DumpStopContext(&strm,
1291 exe_scope,
1292 sc.line_entry.range.GetBaseAddress(),
1293 true,
1294 true,
1295 false);
1296 strm.EOL();
1297 if (verbose)
1298 {
1299 if (sc.line_entry.range.GetBaseAddress().IsValid())
1300 {
1301 if (sc.line_entry.range.GetBaseAddress().Dump (&strm,
1302 exe_scope,
1303 Address::DumpStyleDetailedSymbolContext))
1304 strm.PutCString("\n\n");
1305 }
1306 else if (sc.function->GetAddressRange().GetBaseAddress().IsValid())
1307 {
1308 if (sc.function->GetAddressRange().GetBaseAddress().Dump (&strm,
1309 exe_scope,
1310 Address::DumpStyleDetailedSymbolContext))
1311 strm.PutCString("\n\n");
1312 }
1313 }
1314 }
1315 }
1316 strm.IndentLess ();
1317}
1318
1319static uint32_t
1320LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose)
1321{
1322 if (module && name && name[0])
1323 {
1324 SymbolContextList sc_list;
1325 const bool include_symbols = false;
1326 const bool append = true;
1327 uint32_t num_matches = 0;
1328 if (name_is_regex)
1329 {
1330 RegularExpression function_name_regex (name);
1331 num_matches = module->FindFunctions (function_name_regex,
1332 include_symbols,
1333 append,
1334 sc_list);
1335 }
1336 else
1337 {
1338 ConstString function_name (name);
1339 num_matches = module->FindFunctions (function_name,
1340 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
1341 include_symbols,
1342 append,
1343 sc_list);
1344 }
1345
1346 if (num_matches)
1347 {
1348 strm.Indent ();
1349 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1350 DumpFullpath (strm, &module->GetFileSpec(), 0);
1351 strm.PutCString(":\n");
1352 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
1353 }
1354 return num_matches;
1355 }
1356 return 0;
1357}
1358
1359static uint32_t
Greg Clayton801417e2011-07-07 01:59:51 +00001360LookupTypeInModule (CommandInterpreter &interpreter,
1361 Stream &strm,
1362 Module *module,
1363 const char *name_cstr,
1364 bool name_is_regex)
Greg Claytone1f50b92011-05-03 22:09:39 +00001365{
1366 if (module && name_cstr && name_cstr[0])
1367 {
1368 SymbolContextList sc_list;
1369
1370 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
1371 if (symbol_vendor)
1372 {
1373 TypeList type_list;
1374 uint32_t num_matches = 0;
1375 SymbolContext sc;
1376 // if (name_is_regex)
1377 // {
1378 // RegularExpression name_regex (name_cstr);
1379 // num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list);
1380 // }
1381 // else
1382 // {
1383 ConstString name(name_cstr);
1384 num_matches = symbol_vendor->FindTypes(sc, name, true, UINT32_MAX, type_list);
1385 // }
1386
1387 if (num_matches)
1388 {
1389 strm.Indent ();
1390 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1391 DumpFullpath (strm, &module->GetFileSpec(), 0);
1392 strm.PutCString(":\n");
1393 const uint32_t num_types = type_list.GetSize();
1394 for (uint32_t i=0; i<num_types; ++i)
1395 {
1396 TypeSP type_sp (type_list.GetTypeAtIndex(i));
1397 if (type_sp)
1398 {
1399 // Resolve the clang type so that any forward references
1400 // to types that haven't yet been parsed will get parsed.
1401 type_sp->GetClangFullType ();
1402 type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1403 }
1404 strm.EOL();
1405 }
1406 }
1407 return num_matches;
1408 }
1409 }
1410 return 0;
1411}
1412
1413static uint32_t
1414LookupFileAndLineInModule (CommandInterpreter &interpreter,
1415 Stream &strm,
1416 Module *module,
1417 const FileSpec &file_spec,
1418 uint32_t line,
1419 bool check_inlines,
1420 bool verbose)
1421{
1422 if (module && file_spec)
1423 {
1424 SymbolContextList sc_list;
1425 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
1426 eSymbolContextEverything, sc_list);
1427 if (num_matches > 0)
1428 {
1429 strm.Indent ();
1430 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1431 strm << file_spec;
1432 if (line > 0)
1433 strm.Printf (":%u", line);
1434 strm << " in ";
1435 DumpFullpath (strm, &module->GetFileSpec(), 0);
1436 strm.PutCString(":\n");
1437 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
1438 return num_matches;
1439 }
1440 }
1441 return 0;
1442
1443}
1444
1445#pragma mark CommandObjectTargetModulesModuleAutoComplete
1446
1447//----------------------------------------------------------------------
1448// A base command object class that can auto complete with module file
1449// paths
1450//----------------------------------------------------------------------
1451
1452class CommandObjectTargetModulesModuleAutoComplete : public CommandObject
1453{
1454public:
1455
1456 CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter,
1457 const char *name,
1458 const char *help,
1459 const char *syntax) :
1460 CommandObject (interpreter, name, help, syntax)
1461 {
1462 CommandArgumentEntry arg;
1463 CommandArgumentData file_arg;
1464
1465 // Define the first (and only) variant of this arg.
1466 file_arg.arg_type = eArgTypeFilename;
1467 file_arg.arg_repetition = eArgRepeatStar;
1468
1469 // There is only one variant this argument could be; put it into the argument entry.
1470 arg.push_back (file_arg);
1471
1472 // Push the data for the first argument into the m_arguments vector.
1473 m_arguments.push_back (arg);
1474 }
1475
1476 virtual
1477 ~CommandObjectTargetModulesModuleAutoComplete ()
1478 {
1479 }
1480
1481 virtual int
1482 HandleArgumentCompletion (Args &input,
1483 int &cursor_index,
1484 int &cursor_char_position,
1485 OptionElementVector &opt_element_vector,
1486 int match_start_point,
1487 int max_return_elements,
1488 bool &word_complete,
1489 StringList &matches)
1490 {
1491 // Arguments are the standard module completer.
1492 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1493 completion_str.erase (cursor_char_position);
1494
1495 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1496 CommandCompletions::eModuleCompletion,
1497 completion_str.c_str(),
1498 match_start_point,
1499 max_return_elements,
1500 NULL,
1501 word_complete,
1502 matches);
1503 return matches.GetSize();
1504 }
1505};
1506
1507#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1508
1509//----------------------------------------------------------------------
1510// A base command object class that can auto complete with module source
1511// file paths
1512//----------------------------------------------------------------------
1513
1514class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObject
1515{
1516public:
1517
1518 CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
1519 const char *name,
1520 const char *help,
1521 const char *syntax) :
1522 CommandObject (interpreter, name, help, syntax)
1523 {
1524 CommandArgumentEntry arg;
1525 CommandArgumentData source_file_arg;
1526
1527 // Define the first (and only) variant of this arg.
1528 source_file_arg.arg_type = eArgTypeSourceFile;
1529 source_file_arg.arg_repetition = eArgRepeatPlus;
1530
1531 // There is only one variant this argument could be; put it into the argument entry.
1532 arg.push_back (source_file_arg);
1533
1534 // Push the data for the first argument into the m_arguments vector.
1535 m_arguments.push_back (arg);
1536 }
1537
1538 virtual
1539 ~CommandObjectTargetModulesSourceFileAutoComplete ()
1540 {
1541 }
1542
1543 virtual int
1544 HandleArgumentCompletion (Args &input,
1545 int &cursor_index,
1546 int &cursor_char_position,
1547 OptionElementVector &opt_element_vector,
1548 int match_start_point,
1549 int max_return_elements,
1550 bool &word_complete,
1551 StringList &matches)
1552 {
1553 // Arguments are the standard source file completer.
1554 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1555 completion_str.erase (cursor_char_position);
1556
1557 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1558 CommandCompletions::eSourceFileCompletion,
1559 completion_str.c_str(),
1560 match_start_point,
1561 max_return_elements,
1562 NULL,
1563 word_complete,
1564 matches);
1565 return matches.GetSize();
1566 }
1567};
1568
1569
1570#pragma mark CommandObjectTargetModulesDumpSymtab
1571
1572
1573class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
1574{
1575public:
1576 CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
1577 CommandObjectTargetModulesModuleAutoComplete (interpreter,
1578 "target modules dump symtab",
1579 "Dump the symbol table from one or more target modules.",
1580 NULL),
1581 m_options (interpreter)
1582 {
1583 }
1584
1585 virtual
1586 ~CommandObjectTargetModulesDumpSymtab ()
1587 {
1588 }
1589
1590 virtual bool
1591 Execute (Args& command,
1592 CommandReturnObject &result)
1593 {
1594 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1595 if (target == NULL)
1596 {
1597 result.AppendError ("invalid target, create a debug target using the 'target create' command");
1598 result.SetStatus (eReturnStatusFailed);
1599 return false;
1600 }
1601 else
1602 {
1603 uint32_t num_dumped = 0;
1604
1605 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1606 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1607 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1608
1609 if (command.GetArgumentCount() == 0)
1610 {
1611 // Dump all sections for all modules images
1612 const uint32_t num_modules = target->GetImages().GetSize();
1613 if (num_modules > 0)
1614 {
1615 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
1616 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1617 {
1618 if (num_dumped > 0)
1619 {
1620 result.GetOutputStream().EOL();
1621 result.GetOutputStream().EOL();
1622 }
1623 num_dumped++;
1624 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order);
1625 }
1626 }
1627 else
1628 {
1629 result.AppendError ("the target has no associated executable images");
1630 result.SetStatus (eReturnStatusFailed);
1631 return false;
1632 }
1633 }
1634 else
1635 {
1636 // Dump specified images (by basename or fullpath)
1637 const char *arg_cstr;
1638 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1639 {
1640 FileSpec image_file(arg_cstr, false);
1641 ModuleList matching_modules;
1642 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
1643
1644 // Not found in our module list for our target, check the main
1645 // shared module list in case it is a extra file used somewhere
1646 // else
1647 if (num_matching_modules == 0)
1648 num_matching_modules = ModuleList::FindSharedModules (image_file,
1649 target->GetArchitecture(),
1650 NULL,
1651 NULL,
1652 matching_modules);
1653
1654 if (num_matching_modules > 0)
1655 {
1656 for (size_t i=0; i<num_matching_modules; ++i)
1657 {
1658 Module *image_module = matching_modules.GetModulePointerAtIndex(i);
1659 if (image_module)
1660 {
1661 if (num_dumped > 0)
1662 {
1663 result.GetOutputStream().EOL();
1664 result.GetOutputStream().EOL();
1665 }
1666 num_dumped++;
1667 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module, m_options.m_sort_order);
1668 }
1669 }
1670 }
1671 else
1672 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1673 }
1674 }
1675
1676 if (num_dumped > 0)
1677 result.SetStatus (eReturnStatusSuccessFinishResult);
1678 else
1679 {
1680 result.AppendError ("no matching executable images found");
1681 result.SetStatus (eReturnStatusFailed);
1682 }
1683 }
1684 return result.Succeeded();
1685 }
1686
1687 virtual Options *
1688 GetOptions ()
1689 {
1690 return &m_options;
1691 }
1692
1693 class CommandOptions : public Options
1694 {
1695 public:
1696
1697 CommandOptions (CommandInterpreter &interpreter) :
1698 Options(interpreter),
1699 m_sort_order (eSortOrderNone)
1700 {
1701 }
1702
1703 virtual
1704 ~CommandOptions ()
1705 {
1706 }
1707
1708 virtual Error
1709 SetOptionValue (uint32_t option_idx, const char *option_arg)
1710 {
1711 Error error;
1712 char short_option = (char) m_getopt_table[option_idx].val;
1713
1714 switch (short_option)
1715 {
1716 case 's':
1717 {
1718 bool found_one = false;
1719 m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
1720 g_option_table[option_idx].enum_values,
1721 eSortOrderNone,
1722 &found_one);
1723 if (!found_one)
1724 error.SetErrorStringWithFormat("Invalid enumeration value '%s' for option '%c'.\n",
1725 option_arg,
1726 short_option);
1727 }
1728 break;
1729
1730 default:
1731 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
1732 break;
1733
1734 }
1735 return error;
1736 }
1737
1738 void
1739 OptionParsingStarting ()
1740 {
1741 m_sort_order = eSortOrderNone;
1742 }
1743
1744 const OptionDefinition*
1745 GetDefinitions ()
1746 {
1747 return g_option_table;
1748 }
1749
1750 // Options table: Required for subclasses of Options.
1751 static OptionDefinition g_option_table[];
1752
1753 SortOrder m_sort_order;
1754 };
1755
1756protected:
1757
1758 CommandOptions m_options;
1759};
1760
1761static OptionEnumValueElement
1762g_sort_option_enumeration[4] =
1763{
1764 { eSortOrderNone, "none", "No sorting, use the original symbol table order."},
1765 { eSortOrderByAddress, "address", "Sort output by symbol address."},
1766 { eSortOrderByName, "name", "Sort output by symbol name."},
1767 { 0, NULL, NULL }
1768};
1769
1770
1771OptionDefinition
1772CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
1773{
1774 { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
1775 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1776};
1777
1778#pragma mark CommandObjectTargetModulesDumpSections
1779
1780//----------------------------------------------------------------------
1781// Image section dumping command
1782//----------------------------------------------------------------------
1783
1784class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
1785{
1786public:
1787 CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
1788 CommandObjectTargetModulesModuleAutoComplete (interpreter,
1789 "target modules dump sections",
1790 "Dump the sections from one or more target modules.",
1791 //"target modules dump sections [<file1> ...]")
1792 NULL)
1793 {
1794 }
1795
1796 virtual
1797 ~CommandObjectTargetModulesDumpSections ()
1798 {
1799 }
1800
1801 virtual bool
1802 Execute (Args& command,
1803 CommandReturnObject &result)
1804 {
1805 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1806 if (target == NULL)
1807 {
1808 result.AppendError ("invalid target, create a debug target using the 'target create' command");
1809 result.SetStatus (eReturnStatusFailed);
1810 return false;
1811 }
1812 else
1813 {
1814 uint32_t num_dumped = 0;
1815
1816 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1817 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1818 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1819
1820 if (command.GetArgumentCount() == 0)
1821 {
1822 // Dump all sections for all modules images
1823 const uint32_t num_modules = target->GetImages().GetSize();
1824 if (num_modules > 0)
1825 {
1826 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
1827 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1828 {
1829 num_dumped++;
1830 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
1831 }
1832 }
1833 else
1834 {
1835 result.AppendError ("the target has no associated executable images");
1836 result.SetStatus (eReturnStatusFailed);
1837 return false;
1838 }
1839 }
1840 else
1841 {
1842 // Dump specified images (by basename or fullpath)
1843 const char *arg_cstr;
1844 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1845 {
1846 FileSpec image_file(arg_cstr, false);
1847 ModuleList matching_modules;
1848 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
1849
1850 // Not found in our module list for our target, check the main
1851 // shared module list in case it is a extra file used somewhere
1852 // else
1853 if (num_matching_modules == 0)
1854 num_matching_modules = ModuleList::FindSharedModules (image_file,
1855 target->GetArchitecture(),
1856 NULL,
1857 NULL,
1858 matching_modules);
1859
1860 if (num_matching_modules > 0)
1861 {
1862 for (size_t i=0; i<num_matching_modules; ++i)
1863 {
1864 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
1865 if (image_module)
1866 {
1867 num_dumped++;
1868 DumpModuleSections (m_interpreter, result.GetOutputStream(), image_module);
1869 }
1870 }
1871 }
1872 else
1873 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1874 }
1875 }
1876
1877 if (num_dumped > 0)
1878 result.SetStatus (eReturnStatusSuccessFinishResult);
1879 else
1880 {
1881 result.AppendError ("no matching executable images found");
1882 result.SetStatus (eReturnStatusFailed);
1883 }
1884 }
1885 return result.Succeeded();
1886 }
1887};
1888
1889
1890#pragma mark CommandObjectTargetModulesDumpSymfile
1891
1892//----------------------------------------------------------------------
1893// Image debug symbol dumping command
1894//----------------------------------------------------------------------
1895
1896class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
1897{
1898public:
1899 CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
1900 CommandObjectTargetModulesModuleAutoComplete (interpreter,
1901 "target modules dump symfile",
1902 "Dump the debug symbol file for one or more target modules.",
1903 //"target modules dump symfile [<file1> ...]")
1904 NULL)
1905 {
1906 }
1907
1908 virtual
1909 ~CommandObjectTargetModulesDumpSymfile ()
1910 {
1911 }
1912
1913 virtual bool
1914 Execute (Args& command,
1915 CommandReturnObject &result)
1916 {
1917 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1918 if (target == NULL)
1919 {
1920 result.AppendError ("invalid target, create a debug target using the 'target create' command");
1921 result.SetStatus (eReturnStatusFailed);
1922 return false;
1923 }
1924 else
1925 {
1926 uint32_t num_dumped = 0;
1927
1928 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1929 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1930 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1931
1932 if (command.GetArgumentCount() == 0)
1933 {
1934 // Dump all sections for all modules images
1935 const uint32_t num_modules = target->GetImages().GetSize();
1936 if (num_modules > 0)
1937 {
1938 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
1939 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1940 {
1941 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
1942 num_dumped++;
1943 }
1944 }
1945 else
1946 {
1947 result.AppendError ("the target has no associated executable images");
1948 result.SetStatus (eReturnStatusFailed);
1949 return false;
1950 }
1951 }
1952 else
1953 {
1954 // Dump specified images (by basename or fullpath)
1955 const char *arg_cstr;
1956 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1957 {
1958 FileSpec image_file(arg_cstr, false);
1959 ModuleList matching_modules;
1960 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
1961
1962 // Not found in our module list for our target, check the main
1963 // shared module list in case it is a extra file used somewhere
1964 // else
1965 if (num_matching_modules == 0)
1966 num_matching_modules = ModuleList::FindSharedModules (image_file,
1967 target->GetArchitecture(),
1968 NULL,
1969 NULL,
1970 matching_modules);
1971
1972 if (num_matching_modules > 0)
1973 {
1974 for (size_t i=0; i<num_matching_modules; ++i)
1975 {
1976 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
1977 if (image_module)
1978 {
1979 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module))
1980 num_dumped++;
1981 }
1982 }
1983 }
1984 else
1985 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1986 }
1987 }
1988
1989 if (num_dumped > 0)
1990 result.SetStatus (eReturnStatusSuccessFinishResult);
1991 else
1992 {
1993 result.AppendError ("no matching executable images found");
1994 result.SetStatus (eReturnStatusFailed);
1995 }
1996 }
1997 return result.Succeeded();
1998 }
1999};
2000
2001
2002#pragma mark CommandObjectTargetModulesDumpLineTable
2003
2004//----------------------------------------------------------------------
2005// Image debug line table dumping command
2006//----------------------------------------------------------------------
2007
2008class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
2009{
2010public:
2011 CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
2012 CommandObjectTargetModulesSourceFileAutoComplete (interpreter,
2013 "target modules dump line-table",
2014 "Dump the debug symbol file for one or more target modules.",
2015 NULL)
2016 {
2017 }
2018
2019 virtual
2020 ~CommandObjectTargetModulesDumpLineTable ()
2021 {
2022 }
2023
2024 virtual bool
2025 Execute (Args& command,
2026 CommandReturnObject &result)
2027 {
2028 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2029 if (target == NULL)
2030 {
2031 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2032 result.SetStatus (eReturnStatusFailed);
2033 return false;
2034 }
2035 else
2036 {
2037 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
2038 uint32_t total_num_dumped = 0;
2039
2040 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2041 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2042 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2043
2044 if (command.GetArgumentCount() == 0)
2045 {
2046 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
2047 result.SetStatus (eReturnStatusFailed);
2048 }
2049 else
2050 {
2051 // Dump specified images (by basename or fullpath)
2052 const char *arg_cstr;
2053 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2054 {
2055 FileSpec file_spec(arg_cstr, false);
2056 const uint32_t num_modules = target->GetImages().GetSize();
2057 if (num_modules > 0)
2058 {
2059 uint32_t num_dumped = 0;
2060 for (uint32_t i = 0; i<num_modules; ++i)
2061 {
2062 if (DumpCompileUnitLineTable (m_interpreter,
2063 result.GetOutputStream(),
2064 target->GetImages().GetModulePointerAtIndex(i),
2065 file_spec,
2066 exe_ctx.process != NULL && exe_ctx.process->IsAlive()))
2067 num_dumped++;
2068 }
2069 if (num_dumped == 0)
2070 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
2071 else
2072 total_num_dumped += num_dumped;
2073 }
2074 }
2075 }
2076
2077 if (total_num_dumped > 0)
2078 result.SetStatus (eReturnStatusSuccessFinishResult);
2079 else
2080 {
2081 result.AppendError ("no source filenames matched any command arguments");
2082 result.SetStatus (eReturnStatusFailed);
2083 }
2084 }
2085 return result.Succeeded();
2086 }
2087};
2088
2089
2090#pragma mark CommandObjectTargetModulesDump
2091
2092//----------------------------------------------------------------------
2093// Dump multi-word command for target modules
2094//----------------------------------------------------------------------
2095
2096class CommandObjectTargetModulesDump : public CommandObjectMultiword
2097{
2098public:
2099
2100 //------------------------------------------------------------------
2101 // Constructors and Destructors
2102 //------------------------------------------------------------------
2103 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) :
2104 CommandObjectMultiword (interpreter,
2105 "target modules dump",
2106 "A set of commands for dumping information about one or more target modules.",
2107 "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
2108 {
2109 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
2110 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
2111 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
2112 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
2113 }
2114
2115 virtual
2116 ~CommandObjectTargetModulesDump()
2117 {
2118 }
2119};
2120
2121class CommandObjectTargetModulesAdd : public CommandObject
2122{
2123public:
2124 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
2125 CommandObject (interpreter,
2126 "target modules add",
2127 "Add a new module to the current target's modules.",
2128 "target modules add [<module>]")
2129 {
2130 }
2131
2132 virtual
2133 ~CommandObjectTargetModulesAdd ()
2134 {
2135 }
2136
2137 virtual bool
2138 Execute (Args& args,
2139 CommandReturnObject &result)
2140 {
2141 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2142 if (target == NULL)
2143 {
2144 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2145 result.SetStatus (eReturnStatusFailed);
2146 return false;
2147 }
2148 else
2149 {
2150 const size_t argc = args.GetArgumentCount();
2151 if (argc == 0)
2152 {
2153 result.AppendError ("one or more executable image paths must be specified");
2154 result.SetStatus (eReturnStatusFailed);
2155 return false;
2156 }
2157 else
2158 {
2159 for (size_t i=0; i<argc; ++i)
2160 {
2161 const char *path = args.GetArgumentAtIndex(i);
2162 if (path)
2163 {
2164 FileSpec file_spec(path, true);
2165 ArchSpec arch;
2166 if (file_spec.Exists())
2167 {
2168 ModuleSP module_sp (target->GetSharedModule(file_spec, arch));
2169 if (!module_sp)
2170 {
2171 result.AppendError ("one or more executable image paths must be specified");
2172 result.SetStatus (eReturnStatusFailed);
2173 return false;
2174 }
2175 }
2176 else
2177 {
2178 char resolved_path[PATH_MAX];
2179 result.SetStatus (eReturnStatusFailed);
2180 if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
2181 {
2182 if (strcmp (resolved_path, path) != 0)
2183 {
2184 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
2185 break;
2186 }
2187 }
2188 result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
2189 break;
2190 }
2191 }
2192 }
2193 }
2194 }
2195 return result.Succeeded();
2196 }
2197
2198 int
2199 HandleArgumentCompletion (Args &input,
2200 int &cursor_index,
2201 int &cursor_char_position,
2202 OptionElementVector &opt_element_vector,
2203 int match_start_point,
2204 int max_return_elements,
2205 bool &word_complete,
2206 StringList &matches)
2207 {
2208 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2209 completion_str.erase (cursor_char_position);
2210
2211 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2212 CommandCompletions::eDiskFileCompletion,
2213 completion_str.c_str(),
2214 match_start_point,
2215 max_return_elements,
2216 NULL,
2217 word_complete,
2218 matches);
2219 return matches.GetSize();
2220 }
2221
2222};
2223
2224class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
2225{
2226public:
2227 CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) :
2228 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2229 "target modules load",
2230 "Set the load addresses for one or more sections in a target module.",
2231 "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
2232 m_option_group (interpreter),
2233 m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "Fullpath or basename for module to load."),
2234 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)
2235 {
2236 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2237 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2238 m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2239 m_option_group.Finalize();
2240 }
2241
2242 virtual
2243 ~CommandObjectTargetModulesLoad ()
2244 {
2245 }
2246
2247 virtual bool
2248 Execute (Args& args,
2249 CommandReturnObject &result)
2250 {
2251 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2252 if (target == NULL)
2253 {
2254 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2255 result.SetStatus (eReturnStatusFailed);
2256 return false;
2257 }
2258 else
2259 {
2260 const size_t argc = args.GetArgumentCount();
2261 const FileSpec *file_ptr = NULL;
2262 const UUID *uuid_ptr = NULL;
2263 if (m_file_option.GetOptionValue().OptionWasSet())
2264 file_ptr = &m_file_option.GetOptionValue().GetCurrentValue();
2265
2266 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2267 uuid_ptr = &m_uuid_option_group.GetOptionValue().GetCurrentValue();
2268
2269 if (file_ptr || uuid_ptr)
2270 {
2271
2272 ModuleList matching_modules;
2273 const size_t num_matches = target->GetImages().FindModules (file_ptr, // File spec to match (can be NULL to match by UUID only)
2274 NULL, // Architecture
2275 uuid_ptr, // UUID to match (can be NULL to not match on UUID)
2276 NULL, // Object name
2277 matching_modules);
2278
2279 char path[PATH_MAX];
2280 if (num_matches == 1)
2281 {
2282 Module *module = matching_modules.GetModulePointerAtIndex(0);
2283 if (module)
2284 {
2285 ObjectFile *objfile = module->GetObjectFile();
2286 if (objfile)
2287 {
2288 SectionList *section_list = objfile->GetSectionList();
2289 if (section_list)
2290 {
2291 if (argc == 0)
2292 {
2293 if (m_slide_option.GetOptionValue().OptionWasSet())
2294 {
2295 Module *module = matching_modules.GetModulePointerAtIndex(0);
2296 if (module)
2297 {
2298 ObjectFile *objfile = module->GetObjectFile();
2299 if (objfile)
2300 {
2301 SectionList *section_list = objfile->GetSectionList();
2302 if (section_list)
2303 {
2304 const size_t num_sections = section_list->GetSize();
2305 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
2306 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
2307 {
2308 SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx));
2309 if (section_sp)
2310 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), section_sp->GetFileAddress() + slide);
2311 }
2312 }
2313 }
2314 }
2315 }
2316 else
2317 {
2318 result.AppendError ("one or more section name + load address pair must be specified");
2319 result.SetStatus (eReturnStatusFailed);
2320 return false;
2321 }
2322 }
2323 else
2324 {
2325 if (m_slide_option.GetOptionValue().OptionWasSet())
2326 {
2327 result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
2328 result.SetStatus (eReturnStatusFailed);
2329 return false;
2330 }
2331
2332 for (size_t i=0; i<argc; i += 2)
2333 {
2334 const char *sect_name = args.GetArgumentAtIndex(i);
2335 const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
2336 if (sect_name && load_addr_cstr)
2337 {
2338 ConstString const_sect_name(sect_name);
2339 bool success = false;
2340 addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2341 if (success)
2342 {
2343 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
2344 if (section_sp)
2345 {
2346 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), load_addr);
2347 result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr);
2348 }
2349 else
2350 {
2351 result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
2352 result.SetStatus (eReturnStatusFailed);
2353 break;
2354 }
2355 }
2356 else
2357 {
2358 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
2359 result.SetStatus (eReturnStatusFailed);
2360 break;
2361 }
2362 }
2363 else
2364 {
2365 if (sect_name)
2366 result.AppendError ("section names must be followed by a load address.\n");
2367 else
2368 result.AppendError ("one or more section name + load address pair must be specified.\n");
2369 result.SetStatus (eReturnStatusFailed);
2370 break;
2371 }
2372 }
2373 }
2374 }
2375 else
2376 {
2377 module->GetFileSpec().GetPath (path, sizeof(path));
2378 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
2379 result.SetStatus (eReturnStatusFailed);
2380 }
2381 }
2382 else
2383 {
2384 module->GetFileSpec().GetPath (path, sizeof(path));
2385 result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
2386 result.SetStatus (eReturnStatusFailed);
2387 }
2388 }
2389 else
2390 {
2391 module->GetFileSpec().GetPath (path, sizeof(path));
2392 result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
2393 result.SetStatus (eReturnStatusFailed);
2394 }
2395 }
2396 else
2397 {
2398 char uuid_cstr[64];
2399 if (file_ptr)
2400 file_ptr->GetPath (path, sizeof(path));
2401 else
2402 path[0] = '\0';
2403
2404 if (uuid_ptr)
2405 uuid_ptr->GetAsCString(uuid_cstr, sizeof(uuid_cstr));
2406 else
2407 uuid_cstr[0] = '\0';
2408 if (num_matches > 1)
2409 {
2410 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
2411 path[0] ? " file=" : "",
2412 path,
2413 uuid_cstr[0] ? " uuid=" : "",
2414 uuid_cstr);
2415 for (size_t i=0; i<num_matches; ++i)
2416 {
2417 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
2418 result.AppendMessageWithFormat("%s\n", path);
2419 }
2420 }
2421 else
2422 {
2423 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n",
2424 path[0] ? " file=" : "",
2425 path,
2426 uuid_cstr[0] ? " uuid=" : "",
2427 uuid_cstr);
2428 }
2429 result.SetStatus (eReturnStatusFailed);
2430 }
2431 }
2432 else
2433 {
2434 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
2435 result.SetStatus (eReturnStatusFailed);
2436 return false;
2437 }
2438 }
2439 return result.Succeeded();
2440 }
2441
2442 virtual Options *
2443 GetOptions ()
2444 {
2445 return &m_option_group;
2446 }
2447
2448protected:
2449 OptionGroupOptions m_option_group;
2450 OptionGroupUUID m_uuid_option_group;
2451 OptionGroupFile m_file_option;
2452 OptionGroupUInt64 m_slide_option;
2453};
2454
2455//----------------------------------------------------------------------
2456// List images with associated information
2457//----------------------------------------------------------------------
2458class CommandObjectTargetModulesList : public CommandObject
2459{
2460public:
2461
2462 class CommandOptions : public Options
2463 {
2464 public:
2465
2466 CommandOptions (CommandInterpreter &interpreter) :
2467 Options(interpreter),
2468 m_format_array()
2469 {
2470 }
2471
2472 virtual
2473 ~CommandOptions ()
2474 {
2475 }
2476
2477 virtual Error
2478 SetOptionValue (uint32_t option_idx, const char *option_arg)
2479 {
2480 char short_option = (char) m_getopt_table[option_idx].val;
2481 uint32_t width = 0;
2482 if (option_arg)
2483 width = strtoul (option_arg, NULL, 0);
2484 m_format_array.push_back(std::make_pair(short_option, width));
2485 Error error;
2486 return error;
2487 }
2488
2489 void
2490 OptionParsingStarting ()
2491 {
2492 m_format_array.clear();
2493 }
2494
2495 const OptionDefinition*
2496 GetDefinitions ()
2497 {
2498 return g_option_table;
2499 }
2500
2501 // Options table: Required for subclasses of Options.
2502
2503 static OptionDefinition g_option_table[];
2504
2505 // Instance variables to hold the values for command options.
2506 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
2507 FormatWidthCollection m_format_array;
2508 };
2509
2510 CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
2511 CommandObject (interpreter,
2512 "target modules list",
2513 "List current executable and dependent shared library images.",
2514 "target modules list [<cmd-options>]"),
2515 m_options (interpreter)
2516 {
2517 }
2518
2519 virtual
2520 ~CommandObjectTargetModulesList ()
2521 {
2522 }
2523
2524 virtual
2525 Options *
2526 GetOptions ()
2527 {
2528 return &m_options;
2529 }
2530
2531 virtual bool
2532 Execute (Args& command,
2533 CommandReturnObject &result)
2534 {
2535 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2536 if (target == NULL)
2537 {
2538 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2539 result.SetStatus (eReturnStatusFailed);
2540 return false;
2541 }
2542 else
2543 {
2544 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2545 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2546 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2547 // Dump all sections for all modules images
2548 const uint32_t num_modules = target->GetImages().GetSize();
2549 if (num_modules > 0)
2550 {
2551 Stream &strm = result.GetOutputStream();
2552
2553 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2554 {
2555 Module *module = target->GetImages().GetModulePointerAtIndex(image_idx);
2556 strm.Printf("[%3u] ", image_idx);
2557
2558 bool dump_object_name = false;
2559 if (m_options.m_format_array.empty())
2560 {
2561 DumpFullpath(strm, &module->GetFileSpec(), 0);
2562 dump_object_name = true;
2563 }
2564 else
2565 {
2566 const size_t num_entries = m_options.m_format_array.size();
2567 for (size_t i=0; i<num_entries; ++i)
2568 {
2569 if (i > 0)
2570 strm.PutChar(' ');
2571 char format_char = m_options.m_format_array[i].first;
2572 uint32_t width = m_options.m_format_array[i].second;
2573 switch (format_char)
2574 {
2575 case 'a':
2576 DumpModuleArchitecture (strm, module, false, width);
2577 break;
2578
2579 case 't':
2580 DumpModuleArchitecture (strm, module, true, width);
2581 break;
2582
2583 case 'f':
2584 DumpFullpath (strm, &module->GetFileSpec(), width);
2585 dump_object_name = true;
2586 break;
2587
2588 case 'd':
2589 DumpDirectory (strm, &module->GetFileSpec(), width);
2590 break;
2591
2592 case 'b':
2593 DumpBasename (strm, &module->GetFileSpec(), width);
2594 dump_object_name = true;
2595 break;
2596
2597 case 's':
2598 case 'S':
2599 {
2600 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
2601 if (symbol_vendor)
2602 {
2603 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
2604 if (symbol_file)
2605 {
2606 if (format_char == 'S')
2607 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
2608 else
2609 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
2610 dump_object_name = true;
2611 break;
2612 }
2613 }
2614 strm.Printf("%.*s", width, "<NONE>");
2615 }
2616 break;
2617
2618 case 'u':
2619 DumpModuleUUID(strm, module);
2620 break;
2621
2622 default:
2623 break;
2624 }
2625
2626 }
2627 }
2628 if (dump_object_name)
2629 {
2630 const char *object_name = module->GetObjectName().GetCString();
2631 if (object_name)
2632 strm.Printf ("(%s)", object_name);
2633 }
2634 strm.EOL();
2635 }
2636 result.SetStatus (eReturnStatusSuccessFinishResult);
2637 }
2638 else
2639 {
2640 result.AppendError ("the target has no associated executable images");
2641 result.SetStatus (eReturnStatusFailed);
2642 return false;
2643 }
2644 }
2645 return result.Succeeded();
2646 }
2647protected:
2648
2649 CommandOptions m_options;
2650};
2651
2652OptionDefinition
2653CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
2654{
2655 { LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."},
2656 { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."},
2657 { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."},
2658 { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
2659 { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
2660 { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
2661 { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
2662 { LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."},
2663 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
2664};
2665
2666
2667
2668//----------------------------------------------------------------------
2669// Lookup information in images
2670//----------------------------------------------------------------------
2671class CommandObjectTargetModulesLookup : public CommandObject
2672{
2673public:
2674
2675 enum
2676 {
2677 eLookupTypeInvalid = -1,
2678 eLookupTypeAddress = 0,
2679 eLookupTypeSymbol,
2680 eLookupTypeFileLine, // Line is optional
2681 eLookupTypeFunction,
2682 eLookupTypeType,
2683 kNumLookupTypes
2684 };
2685
2686 class CommandOptions : public Options
2687 {
2688 public:
2689
2690 CommandOptions (CommandInterpreter &interpreter) :
2691 Options(interpreter)
2692 {
2693 OptionParsingStarting();
2694 }
2695
2696 virtual
2697 ~CommandOptions ()
2698 {
2699 }
2700
2701 virtual Error
2702 SetOptionValue (uint32_t option_idx, const char *option_arg)
2703 {
2704 Error error;
2705
2706 char short_option = (char) m_getopt_table[option_idx].val;
2707
2708 switch (short_option)
2709 {
2710 case 'a':
2711 m_type = eLookupTypeAddress;
2712 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
2713 if (m_addr == LLDB_INVALID_ADDRESS)
2714 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
2715 break;
2716
2717 case 'o':
2718 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
2719 if (m_offset == LLDB_INVALID_ADDRESS)
2720 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg);
2721 break;
2722
2723 case 's':
2724 m_str = option_arg;
2725 m_type = eLookupTypeSymbol;
2726 break;
2727
2728 case 'f':
2729 m_file.SetFile (option_arg, false);
2730 m_type = eLookupTypeFileLine;
2731 break;
2732
2733 case 'i':
2734 m_check_inlines = false;
2735 break;
2736
2737 case 'l':
2738 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
2739 if (m_line_number == UINT32_MAX)
2740 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg);
2741 else if (m_line_number == 0)
2742 error.SetErrorString ("Zero is an invalid line number.");
2743 m_type = eLookupTypeFileLine;
2744 break;
2745
2746 case 'n':
2747 m_str = option_arg;
2748 m_type = eLookupTypeFunction;
2749 break;
2750
2751 case 't':
2752 m_str = option_arg;
2753 m_type = eLookupTypeType;
2754 break;
2755
2756 case 'v':
2757 m_verbose = 1;
2758 break;
2759
2760 case 'r':
2761 m_use_regex = true;
2762 break;
2763 }
2764
2765 return error;
2766 }
2767
2768 void
2769 OptionParsingStarting ()
2770 {
2771 m_type = eLookupTypeInvalid;
2772 m_str.clear();
2773 m_file.Clear();
2774 m_addr = LLDB_INVALID_ADDRESS;
2775 m_offset = 0;
2776 m_line_number = 0;
2777 m_use_regex = false;
2778 m_check_inlines = true;
2779 m_verbose = false;
2780 }
2781
2782 const OptionDefinition*
2783 GetDefinitions ()
2784 {
2785 return g_option_table;
2786 }
2787
2788 // Options table: Required for subclasses of Options.
2789
2790 static OptionDefinition g_option_table[];
2791 int m_type; // Should be a eLookupTypeXXX enum after parsing options
2792 std::string m_str; // Holds name lookup
2793 FileSpec m_file; // Files for file lookups
2794 lldb::addr_t m_addr; // Holds the address to lookup
2795 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
2796 uint32_t m_line_number; // Line number for file+line lookups
2797 bool m_use_regex; // Name lookups in m_str are regular expressions.
2798 bool m_check_inlines;// Check for inline entries when looking up by file/line.
2799 bool m_verbose; // Enable verbose lookup info
2800
2801 };
2802
2803 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
2804 CommandObject (interpreter,
2805 "target modules lookup",
2806 "Look up information within executable and dependent shared library images.",
2807 NULL),
2808 m_options (interpreter)
2809 {
2810 CommandArgumentEntry arg;
2811 CommandArgumentData file_arg;
2812
2813 // Define the first (and only) variant of this arg.
2814 file_arg.arg_type = eArgTypeFilename;
2815 file_arg.arg_repetition = eArgRepeatStar;
2816
2817 // There is only one variant this argument could be; put it into the argument entry.
2818 arg.push_back (file_arg);
2819
2820 // Push the data for the first argument into the m_arguments vector.
2821 m_arguments.push_back (arg);
2822 }
2823
2824 virtual
2825 ~CommandObjectTargetModulesLookup ()
2826 {
2827 }
2828
2829 virtual Options *
2830 GetOptions ()
2831 {
2832 return &m_options;
2833 }
2834
2835
2836 bool
2837 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
2838 {
2839 switch (m_options.m_type)
2840 {
2841 case eLookupTypeAddress:
2842 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
2843 {
2844 if (LookupAddressInModule (m_interpreter,
2845 result.GetOutputStream(),
2846 module,
2847 eSymbolContextEverything,
2848 m_options.m_addr,
2849 m_options.m_offset,
2850 m_options.m_verbose))
2851 {
2852 result.SetStatus(eReturnStatusSuccessFinishResult);
2853 return true;
2854 }
2855 }
2856 break;
2857
2858 case eLookupTypeSymbol:
2859 if (!m_options.m_str.empty())
2860 {
2861 if (LookupSymbolInModule (m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex))
2862 {
2863 result.SetStatus(eReturnStatusSuccessFinishResult);
2864 return true;
2865 }
2866 }
2867 break;
2868
2869 case eLookupTypeFileLine:
2870 if (m_options.m_file)
2871 {
2872
2873 if (LookupFileAndLineInModule (m_interpreter,
2874 result.GetOutputStream(),
2875 module,
2876 m_options.m_file,
2877 m_options.m_line_number,
2878 m_options.m_check_inlines,
2879 m_options.m_verbose))
2880 {
2881 result.SetStatus(eReturnStatusSuccessFinishResult);
2882 return true;
2883 }
2884 }
2885 break;
2886
2887 case eLookupTypeFunction:
2888 if (!m_options.m_str.empty())
2889 {
2890 if (LookupFunctionInModule (m_interpreter,
2891 result.GetOutputStream(),
2892 module,
2893 m_options.m_str.c_str(),
2894 m_options.m_use_regex,
2895 m_options.m_verbose))
2896 {
2897 result.SetStatus(eReturnStatusSuccessFinishResult);
2898 return true;
2899 }
2900 }
2901 break;
2902
2903 case eLookupTypeType:
2904 if (!m_options.m_str.empty())
2905 {
2906 if (LookupTypeInModule (m_interpreter,
2907 result.GetOutputStream(),
2908 module,
2909 m_options.m_str.c_str(),
2910 m_options.m_use_regex))
2911 {
2912 result.SetStatus(eReturnStatusSuccessFinishResult);
2913 return true;
2914 }
2915 }
2916 break;
2917
2918 default:
2919 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
2920 syntax_error = true;
2921 break;
2922 }
2923
2924 result.SetStatus (eReturnStatusFailed);
2925 return false;
2926 }
2927
2928 virtual bool
2929 Execute (Args& command,
2930 CommandReturnObject &result)
2931 {
2932 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2933 if (target == NULL)
2934 {
2935 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2936 result.SetStatus (eReturnStatusFailed);
2937 return false;
2938 }
2939 else
2940 {
2941 bool syntax_error = false;
2942 uint32_t i;
2943 uint32_t num_successful_lookups = 0;
2944 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2945 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2946 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2947 // Dump all sections for all modules images
2948
2949 if (command.GetArgumentCount() == 0)
2950 {
2951 // Dump all sections for all modules images
2952 const uint32_t num_modules = target->GetImages().GetSize();
2953 if (num_modules > 0)
2954 {
2955 for (i = 0; i<num_modules && syntax_error == false; ++i)
2956 {
2957 if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
2958 {
2959 result.GetOutputStream().EOL();
2960 num_successful_lookups++;
2961 }
2962 }
2963 }
2964 else
2965 {
2966 result.AppendError ("the target has no associated executable images");
2967 result.SetStatus (eReturnStatusFailed);
2968 return false;
2969 }
2970 }
2971 else
2972 {
2973 // Dump specified images (by basename or fullpath)
2974 const char *arg_cstr;
2975 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
2976 {
2977 FileSpec image_file(arg_cstr, false);
2978 ModuleList matching_modules;
2979 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
2980
2981 // Not found in our module list for our target, check the main
2982 // shared module list in case it is a extra file used somewhere
2983 // else
2984 if (num_matching_modules == 0)
2985 num_matching_modules = ModuleList::FindSharedModules (image_file,
2986 target->GetArchitecture(),
2987 NULL,
2988 NULL,
2989 matching_modules);
2990
2991 if (num_matching_modules > 0)
2992 {
2993 for (size_t j=0; j<num_matching_modules; ++j)
2994 {
2995 Module * image_module = matching_modules.GetModulePointerAtIndex(j);
2996 if (image_module)
2997 {
2998 if (LookupInModule (m_interpreter, image_module, result, syntax_error))
2999 {
3000 result.GetOutputStream().EOL();
3001 num_successful_lookups++;
3002 }
3003 }
3004 }
3005 }
3006 else
3007 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
3008 }
3009 }
3010
3011 if (num_successful_lookups > 0)
3012 result.SetStatus (eReturnStatusSuccessFinishResult);
3013 else
3014 result.SetStatus (eReturnStatusFailed);
3015 }
3016 return result.Succeeded();
3017 }
3018protected:
3019
3020 CommandOptions m_options;
3021};
3022
3023OptionDefinition
3024CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
3025{
3026 { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more target modules."},
3027 { 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 +00003028 { LLDB_OPT_SET_2| LLDB_OPT_SET_4
3029 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_5 */ ,
3030 false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."},
Greg Claytone1f50b92011-05-03 22:09:39 +00003031 { 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 +00003032 { 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."},
3033 { 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)."},
3034 { LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Check inline line entries (must be used in conjunction with --file)."},
3035 { 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."},
3036 { 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."},
3037 { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."},
3038 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3039};
Chris Lattner24943d22010-06-08 16:52:24 +00003040
3041
Jim Inghamd60d94a2011-03-11 03:53:59 +00003042#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner24943d22010-06-08 16:52:24 +00003043
3044//-------------------------------------------------------------------------
3045// CommandObjectMultiwordImageSearchPaths
3046//-------------------------------------------------------------------------
3047
Greg Claytone1f50b92011-05-03 22:09:39 +00003048class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
Chris Lattner24943d22010-06-08 16:52:24 +00003049{
3050public:
Greg Claytone1f50b92011-05-03 22:09:39 +00003051
3052 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
3053 CommandObjectMultiword (interpreter,
3054 "target modules search-paths",
3055 "A set of commands for operating on debugger target image search paths.",
3056 "target modules search-paths <subcommand> [<subcommand-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +00003057 {
Greg Claytone1f50b92011-05-03 22:09:39 +00003058 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
3059 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
3060 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
3061 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
3062 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00003063 }
Greg Claytone1f50b92011-05-03 22:09:39 +00003064
3065 ~CommandObjectTargetModulesImageSearchPaths()
Chris Lattner24943d22010-06-08 16:52:24 +00003066 {
3067 }
3068};
3069
Greg Claytone1f50b92011-05-03 22:09:39 +00003070
3071
3072#pragma mark CommandObjectTargetModules
3073
3074//-------------------------------------------------------------------------
3075// CommandObjectTargetModules
3076//-------------------------------------------------------------------------
3077
3078class CommandObjectTargetModules : public CommandObjectMultiword
3079{
3080public:
3081 //------------------------------------------------------------------
3082 // Constructors and Destructors
3083 //------------------------------------------------------------------
3084 CommandObjectTargetModules(CommandInterpreter &interpreter) :
3085 CommandObjectMultiword (interpreter,
3086 "target modules",
3087 "A set of commands for accessing information for one or more target modules.",
3088 "target modules <sub-command> ...")
3089 {
3090 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
3091 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
3092 //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter)));
3093 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
3094 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
3095 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
3096 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
3097
3098 }
3099 virtual
3100 ~CommandObjectTargetModules()
3101 {
3102 }
3103
3104private:
3105 //------------------------------------------------------------------
3106 // For CommandObjectTargetModules only
3107 //------------------------------------------------------------------
3108 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
3109};
3110
3111
Jim Inghamd60d94a2011-03-11 03:53:59 +00003112#pragma mark CommandObjectTargetStopHookAdd
3113
3114//-------------------------------------------------------------------------
3115// CommandObjectTargetStopHookAdd
3116//-------------------------------------------------------------------------
3117
3118class CommandObjectTargetStopHookAdd : public CommandObject
3119{
3120public:
3121
3122 class CommandOptions : public Options
3123 {
3124 public:
Greg Claytonf15996e2011-04-07 22:46:35 +00003125 CommandOptions (CommandInterpreter &interpreter) :
3126 Options(interpreter),
Jim Inghamd60d94a2011-03-11 03:53:59 +00003127 m_line_start(0),
3128 m_line_end (UINT_MAX),
3129 m_func_name_type_mask (eFunctionNameTypeAuto),
3130 m_sym_ctx_specified (false),
Johnny Chen60fe60e2011-05-02 23:47:55 +00003131 m_thread_specified (false),
3132 m_use_one_liner (false),
3133 m_one_liner()
Jim Inghamd60d94a2011-03-11 03:53:59 +00003134 {
3135 }
3136
3137 ~CommandOptions () {}
3138
Greg Claytonb3448432011-03-24 21:19:54 +00003139 const OptionDefinition*
Jim Inghamd60d94a2011-03-11 03:53:59 +00003140 GetDefinitions ()
3141 {
3142 return g_option_table;
3143 }
3144
3145 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +00003146 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003147 {
3148 Error error;
3149 char short_option = (char) m_getopt_table[option_idx].val;
3150 bool success;
3151
3152 switch (short_option)
3153 {
3154 case 'c':
3155 m_class_name = option_arg;
3156 m_sym_ctx_specified = true;
3157 break;
3158
3159 case 'e':
3160 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
3161 if (!success)
3162 {
3163 error.SetErrorStringWithFormat ("Invalid end line number: \"%s\".", option_arg);
3164 break;
3165 }
3166 m_sym_ctx_specified = true;
3167 break;
3168
3169 case 'l':
3170 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
3171 if (!success)
3172 {
3173 error.SetErrorStringWithFormat ("Invalid start line number: \"%s\".", option_arg);
3174 break;
3175 }
3176 m_sym_ctx_specified = true;
3177 break;
3178
3179 case 'n':
3180 m_function_name = option_arg;
3181 m_func_name_type_mask |= eFunctionNameTypeAuto;
3182 m_sym_ctx_specified = true;
3183 break;
3184
3185 case 'f':
3186 m_file_name = option_arg;
3187 m_sym_ctx_specified = true;
3188 break;
3189 case 's':
3190 m_module_name = option_arg;
3191 m_sym_ctx_specified = true;
3192 break;
3193 case 't' :
3194 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003195 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003196 if (m_thread_id == LLDB_INVALID_THREAD_ID)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003197 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003198 m_thread_specified = true;
3199 }
3200 break;
3201 case 'T':
3202 m_thread_name = option_arg;
3203 m_thread_specified = true;
3204 break;
3205 case 'q':
3206 m_queue_name = option_arg;
3207 m_thread_specified = true;
3208 break;
3209 case 'x':
3210 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003211 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003212 if (m_thread_id == UINT32_MAX)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003213 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003214 m_thread_specified = true;
3215 }
3216 break;
Johnny Chen60fe60e2011-05-02 23:47:55 +00003217 case 'o':
3218 m_use_one_liner = true;
3219 m_one_liner = option_arg;
3220 break;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003221 default:
3222 error.SetErrorStringWithFormat ("Unrecognized option %c.");
3223 break;
3224 }
3225 return error;
3226 }
3227
3228 void
Greg Clayton143fcc32011-04-13 00:18:08 +00003229 OptionParsingStarting ()
Jim Inghamd60d94a2011-03-11 03:53:59 +00003230 {
3231 m_class_name.clear();
3232 m_function_name.clear();
3233 m_line_start = 0;
3234 m_line_end = UINT_MAX;
3235 m_file_name.clear();
3236 m_module_name.clear();
3237 m_func_name_type_mask = eFunctionNameTypeAuto;
3238 m_thread_id = LLDB_INVALID_THREAD_ID;
3239 m_thread_index = UINT32_MAX;
3240 m_thread_name.clear();
3241 m_queue_name.clear();
3242
3243 m_sym_ctx_specified = false;
3244 m_thread_specified = false;
Johnny Chen60fe60e2011-05-02 23:47:55 +00003245
3246 m_use_one_liner = false;
3247 m_one_liner.clear();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003248 }
3249
3250
Greg Claytonb3448432011-03-24 21:19:54 +00003251 static OptionDefinition g_option_table[];
Jim Inghamd60d94a2011-03-11 03:53:59 +00003252
3253 std::string m_class_name;
3254 std::string m_function_name;
3255 uint32_t m_line_start;
3256 uint32_t m_line_end;
3257 std::string m_file_name;
3258 std::string m_module_name;
3259 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
3260 lldb::tid_t m_thread_id;
3261 uint32_t m_thread_index;
3262 std::string m_thread_name;
3263 std::string m_queue_name;
3264 bool m_sym_ctx_specified;
3265 bool m_thread_specified;
Johnny Chen60fe60e2011-05-02 23:47:55 +00003266 // Instance variables to hold the values for one_liner options.
3267 bool m_use_one_liner;
3268 std::string m_one_liner;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003269 };
3270
3271 Options *
3272 GetOptions ()
3273 {
3274 return &m_options;
3275 }
3276
3277 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
3278 CommandObject (interpreter,
3279 "target stop-hook add ",
3280 "Add a hook to be executed when the target stops.",
Greg Claytonf15996e2011-04-07 22:46:35 +00003281 "target stop-hook add"),
3282 m_options (interpreter)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003283 {
3284 }
3285
3286 ~CommandObjectTargetStopHookAdd ()
3287 {
3288 }
3289
3290 static size_t
3291 ReadCommandsCallbackFunction (void *baton,
3292 InputReader &reader,
3293 lldb::InputReaderAction notification,
3294 const char *bytes,
3295 size_t bytes_len)
3296 {
Caroline Tice892fadd2011-06-16 16:27:19 +00003297 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003298 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
Jim Inghame15511a2011-05-05 01:03:36 +00003299 static bool got_interrupted;
Caroline Tice892fadd2011-06-16 16:27:19 +00003300 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003301
3302 switch (notification)
3303 {
3304 case eInputReaderActivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00003305 if (!batch_mode)
3306 {
3307 out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end.");
3308 if (reader.GetPrompt())
3309 out_stream->Printf ("%s", reader.GetPrompt());
3310 out_stream->Flush();
3311 }
Jim Inghame15511a2011-05-05 01:03:36 +00003312 got_interrupted = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003313 break;
3314
3315 case eInputReaderDeactivate:
3316 break;
3317
3318 case eInputReaderReactivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00003319 if (reader.GetPrompt() && !batch_mode)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003320 {
Caroline Tice892fadd2011-06-16 16:27:19 +00003321 out_stream->Printf ("%s", reader.GetPrompt());
3322 out_stream->Flush();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003323 }
Jim Inghame15511a2011-05-05 01:03:36 +00003324 got_interrupted = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003325 break;
3326
Caroline Tice4a348082011-05-02 20:41:46 +00003327 case eInputReaderAsynchronousOutputWritten:
3328 break;
3329
Jim Inghamd60d94a2011-03-11 03:53:59 +00003330 case eInputReaderGotToken:
3331 if (bytes && bytes_len && baton)
3332 {
3333 StringList *commands = new_stop_hook->GetCommandPointer();
3334 if (commands)
3335 {
3336 commands->AppendString (bytes, bytes_len);
3337 }
3338 }
Caroline Tice892fadd2011-06-16 16:27:19 +00003339 if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003340 {
Caroline Tice892fadd2011-06-16 16:27:19 +00003341 out_stream->Printf ("%s", reader.GetPrompt());
3342 out_stream->Flush();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003343 }
3344 break;
3345
3346 case eInputReaderInterrupt:
3347 {
3348 // Finish, and cancel the stop hook.
3349 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
Caroline Tice892fadd2011-06-16 16:27:19 +00003350 if (!batch_mode)
3351 {
3352 out_stream->Printf ("Stop hook cancelled.\n");
3353 out_stream->Flush();
3354 }
3355
Jim Inghamd60d94a2011-03-11 03:53:59 +00003356 reader.SetIsDone (true);
3357 }
Jim Inghame15511a2011-05-05 01:03:36 +00003358 got_interrupted = true;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003359 break;
3360
3361 case eInputReaderEndOfFile:
3362 reader.SetIsDone (true);
3363 break;
3364
3365 case eInputReaderDone:
Caroline Tice892fadd2011-06-16 16:27:19 +00003366 if (!got_interrupted && !batch_mode)
3367 {
3368 out_stream->Printf ("Stop hook #%d added.\n", new_stop_hook->GetID());
3369 out_stream->Flush();
3370 }
Jim Inghamd60d94a2011-03-11 03:53:59 +00003371 break;
3372 }
3373
3374 return bytes_len;
3375 }
3376
3377 bool
3378 Execute (Args& command,
3379 CommandReturnObject &result)
3380 {
3381 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3382 if (target)
3383 {
3384 Target::StopHookSP new_hook_sp;
3385 target->AddStopHook (new_hook_sp);
3386
3387 // First step, make the specifier.
3388 std::auto_ptr<SymbolContextSpecifier> specifier_ap;
3389 if (m_options.m_sym_ctx_specified)
3390 {
3391 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
3392
3393 if (!m_options.m_module_name.empty())
3394 {
3395 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
3396 }
3397
3398 if (!m_options.m_class_name.empty())
3399 {
3400 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
3401 }
3402
3403 if (!m_options.m_file_name.empty())
3404 {
3405 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
3406 }
3407
3408 if (m_options.m_line_start != 0)
3409 {
3410 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
3411 }
3412
3413 if (m_options.m_line_end != UINT_MAX)
3414 {
3415 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
3416 }
3417
3418 if (!m_options.m_function_name.empty())
3419 {
3420 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
3421 }
3422 }
3423
3424 if (specifier_ap.get())
3425 new_hook_sp->SetSpecifier (specifier_ap.release());
3426
3427 // Next see if any of the thread options have been entered:
3428
3429 if (m_options.m_thread_specified)
3430 {
3431 ThreadSpec *thread_spec = new ThreadSpec();
3432
3433 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
3434 {
3435 thread_spec->SetTID (m_options.m_thread_id);
3436 }
3437
3438 if (m_options.m_thread_index != UINT32_MAX)
3439 thread_spec->SetIndex (m_options.m_thread_index);
3440
3441 if (!m_options.m_thread_name.empty())
3442 thread_spec->SetName (m_options.m_thread_name.c_str());
3443
3444 if (!m_options.m_queue_name.empty())
3445 thread_spec->SetQueueName (m_options.m_queue_name.c_str());
3446
3447 new_hook_sp->SetThreadSpecifier (thread_spec);
3448
3449 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00003450 if (m_options.m_use_one_liner)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003451 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00003452 // Use one-liner.
3453 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
Johnny Chen44953902011-05-03 00:06:12 +00003454 result.AppendMessageWithFormat("Stop hook #%d added.\n", new_hook_sp->GetID());
Jim Inghamd60d94a2011-03-11 03:53:59 +00003455 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00003456 else
Jim Inghamd60d94a2011-03-11 03:53:59 +00003457 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00003458 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into
3459 // the new stop hook's command string.
3460 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
3461 if (!reader_sp)
3462 {
3463 result.AppendError("out of memory\n");
3464 result.SetStatus (eReturnStatusFailed);
3465 target->RemoveStopHookByID (new_hook_sp->GetID());
3466 return false;
3467 }
3468
3469 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
3470 new_hook_sp.get(), // baton
3471 eInputReaderGranularityLine, // token size, to pass to callback function
3472 "DONE", // end token
3473 "> ", // prompt
3474 true)); // echo input
3475 if (!err.Success())
3476 {
3477 result.AppendError (err.AsCString());
3478 result.SetStatus (eReturnStatusFailed);
3479 target->RemoveStopHookByID (new_hook_sp->GetID());
3480 return false;
3481 }
3482 m_interpreter.GetDebugger().PushInputReader (reader_sp);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003483 }
Jim Inghamd60d94a2011-03-11 03:53:59 +00003484 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3485 }
3486 else
3487 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003488 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003489 result.SetStatus (eReturnStatusFailed);
3490 }
3491
3492 return result.Succeeded();
3493 }
3494private:
3495 CommandOptions m_options;
3496};
3497
Greg Claytonb3448432011-03-24 21:19:54 +00003498OptionDefinition
Jim Inghamd60d94a2011-03-11 03:53:59 +00003499CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
3500{
Johnny Chen60fe60e2011-05-02 23:47:55 +00003501 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, NULL, eArgTypeOneLiner,
3502 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
Jim Inghamd60d94a2011-03-11 03:53:59 +00003503 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3504 "Set the module within which the stop-hook is to be run."},
3505 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex,
3506 "The stop hook is run only for the thread whose index matches this argument."},
3507 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID,
3508 "The stop hook is run only for the thread whose TID matches this argument."},
3509 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName,
3510 "The stop hook is run only for the thread whose thread name matches this argument."},
3511 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName,
3512 "The stop hook is run only for threads in the queue whose name is given by this argument."},
3513 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
3514 "Specify the source file within which the stop-hook is to be run." },
3515 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
3516 "Set the start of the line range for which the stop-hook is to be run."},
3517 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum,
3518 "Set the end of the line range for which the stop-hook is to be run."},
3519 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName,
3520 "Specify the class within which the stop-hook is to be run." },
3521 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
3522 "Set the function name within which the stop hook will be run." },
3523 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3524};
3525
3526#pragma mark CommandObjectTargetStopHookDelete
3527
3528//-------------------------------------------------------------------------
3529// CommandObjectTargetStopHookDelete
3530//-------------------------------------------------------------------------
3531
3532class CommandObjectTargetStopHookDelete : public CommandObject
3533{
3534public:
3535
3536 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
3537 CommandObject (interpreter,
3538 "target stop-hook delete [<id>]",
3539 "Delete a stop-hook.",
3540 "target stop-hook delete")
3541 {
3542 }
3543
3544 ~CommandObjectTargetStopHookDelete ()
3545 {
3546 }
3547
3548 bool
3549 Execute (Args& command,
3550 CommandReturnObject &result)
3551 {
3552 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3553 if (target)
3554 {
3555 // FIXME: see if we can use the breakpoint id style parser?
3556 size_t num_args = command.GetArgumentCount();
3557 if (num_args == 0)
3558 {
3559 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
3560 {
3561 result.SetStatus (eReturnStatusFailed);
3562 return false;
3563 }
3564 else
3565 {
3566 target->RemoveAllStopHooks();
3567 }
3568 }
3569 else
3570 {
3571 bool success;
3572 for (size_t i = 0; i < num_args; i++)
3573 {
3574 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
3575 if (!success)
3576 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003577 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003578 result.SetStatus(eReturnStatusFailed);
3579 return false;
3580 }
3581 success = target->RemoveStopHookByID (user_id);
3582 if (!success)
3583 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003584 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003585 result.SetStatus(eReturnStatusFailed);
3586 return false;
3587 }
3588 }
3589 }
3590 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3591 }
3592 else
3593 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003594 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003595 result.SetStatus (eReturnStatusFailed);
3596 }
3597
3598 return result.Succeeded();
3599 }
3600};
3601#pragma mark CommandObjectTargetStopHookEnableDisable
3602
3603//-------------------------------------------------------------------------
3604// CommandObjectTargetStopHookEnableDisable
3605//-------------------------------------------------------------------------
3606
3607class CommandObjectTargetStopHookEnableDisable : public CommandObject
3608{
3609public:
3610
3611 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
3612 CommandObject (interpreter,
3613 name,
3614 help,
3615 syntax),
3616 m_enable (enable)
3617 {
3618 }
3619
3620 ~CommandObjectTargetStopHookEnableDisable ()
3621 {
3622 }
3623
3624 bool
3625 Execute (Args& command,
3626 CommandReturnObject &result)
3627 {
3628 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3629 if (target)
3630 {
3631 // FIXME: see if we can use the breakpoint id style parser?
3632 size_t num_args = command.GetArgumentCount();
3633 bool success;
3634
3635 if (num_args == 0)
3636 {
3637 target->SetAllStopHooksActiveState (m_enable);
3638 }
3639 else
3640 {
3641 for (size_t i = 0; i < num_args; i++)
3642 {
3643 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
3644 if (!success)
3645 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003646 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003647 result.SetStatus(eReturnStatusFailed);
3648 return false;
3649 }
3650 success = target->SetStopHookActiveStateByID (user_id, m_enable);
3651 if (!success)
3652 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003653 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003654 result.SetStatus(eReturnStatusFailed);
3655 return false;
3656 }
3657 }
3658 }
3659 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3660 }
3661 else
3662 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003663 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003664 result.SetStatus (eReturnStatusFailed);
3665 }
3666 return result.Succeeded();
3667 }
3668private:
3669 bool m_enable;
3670};
3671
3672#pragma mark CommandObjectTargetStopHookList
3673
3674//-------------------------------------------------------------------------
3675// CommandObjectTargetStopHookList
3676//-------------------------------------------------------------------------
3677
3678class CommandObjectTargetStopHookList : public CommandObject
3679{
3680public:
3681
3682 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
3683 CommandObject (interpreter,
3684 "target stop-hook list [<type>]",
3685 "List all stop-hooks.",
3686 "target stop-hook list")
3687 {
3688 }
3689
3690 ~CommandObjectTargetStopHookList ()
3691 {
3692 }
3693
3694 bool
3695 Execute (Args& command,
3696 CommandReturnObject &result)
3697 {
3698 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3699 if (target)
3700 {
3701 bool notify = true;
3702 target->GetImageSearchPathList().Clear(notify);
3703 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3704 }
3705 else
3706 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003707 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003708 result.SetStatus (eReturnStatusFailed);
3709 }
3710
3711 size_t num_hooks = target->GetNumStopHooks ();
3712 if (num_hooks == 0)
3713 {
3714 result.GetOutputStream().PutCString ("No stop hooks.\n");
3715 }
3716 else
3717 {
3718 for (size_t i = 0; i < num_hooks; i++)
3719 {
3720 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
3721 if (i > 0)
3722 result.GetOutputStream().PutCString ("\n");
3723 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
3724 }
3725 }
3726 return result.Succeeded();
3727 }
3728};
3729
3730#pragma mark CommandObjectMultiwordTargetStopHooks
3731//-------------------------------------------------------------------------
3732// CommandObjectMultiwordTargetStopHooks
3733//-------------------------------------------------------------------------
3734
3735class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
3736{
3737public:
3738
3739 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
3740 CommandObjectMultiword (interpreter,
3741 "target stop-hook",
3742 "A set of commands for operating on debugger target stop-hooks.",
3743 "target stop-hook <subcommand> [<subcommand-options>]")
3744 {
3745 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
3746 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
3747 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
3748 false,
3749 "target stop-hook disable [<id>]",
3750 "Disable a stop-hook.",
3751 "target stop-hook disable")));
3752 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
3753 true,
3754 "target stop-hook enable [<id>]",
3755 "Enable a stop-hook.",
3756 "target stop-hook enable")));
3757 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
3758 }
3759
3760 ~CommandObjectMultiwordTargetStopHooks()
3761 {
3762 }
3763};
3764
3765
Chris Lattner24943d22010-06-08 16:52:24 +00003766
3767#pragma mark CommandObjectMultiwordTarget
3768
3769//-------------------------------------------------------------------------
3770// CommandObjectMultiwordTarget
3771//-------------------------------------------------------------------------
3772
Greg Clayton63094e02010-06-23 01:19:29 +00003773CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00003774 CommandObjectMultiword (interpreter,
3775 "target",
Chris Lattner24943d22010-06-08 16:52:24 +00003776 "A set of commands for operating on debugger targets.",
3777 "target <subcommand> [<subcommand-options>]")
3778{
Greg Claytonabe0fed2011-04-18 08:33:37 +00003779
3780 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
3781 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter)));
3782 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003783 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
Greg Claytone1f50b92011-05-03 22:09:39 +00003784 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter)));
Greg Clayton801417e2011-07-07 01:59:51 +00003785 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00003786}
3787
3788CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
3789{
3790}
3791
Greg Claytonabe0fed2011-04-18 08:33:37 +00003792