blob: 7b000a96a9d53e1540e498fc62b46448d9798cd3 [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 Clayton801417e2011-07-07 01:59:51 +000030#include "lldb/Interpreter/OptionGroupFormat.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),
420 m_format_options (eFormatDefault, 0, false),
421 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);
426 m_option_group.Append (&m_format_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
427 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 }
436
437 virtual bool
438 Execute (Args& args, CommandReturnObject &result)
439 {
440 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
441
442 if (exe_ctx.target)
443 {
444 const size_t argc = args.GetArgumentCount();
445 if (argc > 0)
446 {
447 for (size_t idx = 0; idx < argc; ++idx)
448 {
449 VariableList global_var_list;
450 const char *global_var_name = args.GetArgumentAtIndex(idx);
451 const uint32_t matches = exe_ctx.target->GetImages().FindGlobalVariables (global_var_name,
452 true,
453 UINT32_MAX,
454 global_var_list);
455
456 if (matches == 0)
457 {
458 result.GetErrorStream().Printf ("error: can't find global variable '%s'\n",
459 global_var_name);
460 }
461 else
462 {
463 for (uint32_t global_idx=0; global_idx<matches; ++global_idx)
464 {
465 VariableSP var_sp (global_var_list.GetVariableAtIndex(global_idx));
466 if (var_sp)
467 {
468 ValueObjectSP valobj_sp(ValueObjectVariable::Create (exe_ctx.target, var_sp));
469
470 if (valobj_sp)
471 {
472 const Format format = m_format_options.GetFormat ();
473 if (format != eFormatDefault)
474 valobj_sp->SetFormat (format);
475
476// if (m_format_options.show_decl && var_sp->GetDeclaration ().GetFile())
477// {
478// var_sp->GetDeclaration ().DumpStopContext (&s, false);
479// s.PutCString (": ");
480// }
481
482 ValueObject::DumpValueObject (result.GetOutputStream(),
483 valobj_sp.get(),
484 global_var_name,
485 m_varobj_options.ptr_depth,
486 0,
487 m_varobj_options.max_depth,
488 m_varobj_options.show_types,
489 m_varobj_options.show_location,
490 m_varobj_options.use_objc,
491 m_varobj_options.use_dynamic,
492 false,
493 m_varobj_options.flat_output);
494 }
495 }
496 }
497 }
498 }
499 }
500 else
501 {
502 result.AppendError ("'target variable' takes one or more global variable names as arguments\n");
503 result.SetStatus (eReturnStatusFailed);
504 }
505 }
506 else
507 {
508 result.AppendError ("invalid target, create a debug target using the 'target create' command");
509 result.SetStatus (eReturnStatusFailed);
510 return false;
511 }
512 return result.Succeeded();
513 }
514
515 Options *
516 GetOptions ()
517 {
518 return &m_option_group;
519 }
520
521protected:
522 OptionGroupOptions m_option_group;
523 OptionGroupFormat m_format_options;
524 OptionGroupFileList m_option_compile_units;
525 OptionGroupFileList m_option_shared_libraries;
526 OptionGroupValueObjectDisplay m_varobj_options;
527
528};
529
530
Greg Claytone1f50b92011-05-03 22:09:39 +0000531#pragma mark CommandObjectTargetModulesSearchPathsAdd
Chris Lattner24943d22010-06-08 16:52:24 +0000532
Greg Claytone1f50b92011-05-03 22:09:39 +0000533class CommandObjectTargetModulesSearchPathsAdd : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000534{
535public:
536
Greg Claytone1f50b92011-05-03 22:09:39 +0000537 CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000538 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000539 "target modules search-paths add",
Chris Lattner24943d22010-06-08 16:52:24 +0000540 "Add new image search paths substitution pairs to the current target.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000541 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000542 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000543 CommandArgumentEntry arg;
544 CommandArgumentData old_prefix_arg;
545 CommandArgumentData new_prefix_arg;
546
547 // Define the first variant of this arg pair.
548 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
549 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
550
551 // Define the first variant of this arg pair.
552 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
553 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
554
555 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
556 // must always occur together, they are treated as two variants of one argument rather than two independent
557 // arguments. Push them both into the first argument position for m_arguments...
558
559 arg.push_back (old_prefix_arg);
560 arg.push_back (new_prefix_arg);
561
562 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000563 }
564
Greg Claytone1f50b92011-05-03 22:09:39 +0000565 ~CommandObjectTargetModulesSearchPathsAdd ()
Chris Lattner24943d22010-06-08 16:52:24 +0000566 {
567 }
568
569 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000570 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000571 CommandReturnObject &result)
572 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000573 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000574 if (target)
575 {
576 uint32_t argc = command.GetArgumentCount();
577 if (argc & 1)
578 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000579 result.AppendError ("add requires an even number of arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000580 result.SetStatus (eReturnStatusFailed);
581 }
582 else
583 {
584 for (uint32_t i=0; i<argc; i+=2)
585 {
586 const char *from = command.GetArgumentAtIndex(i);
587 const char *to = command.GetArgumentAtIndex(i+1);
588
589 if (from[0] && to[0])
590 {
591 bool last_pair = ((argc - i) == 2);
Greg Clayton63094e02010-06-23 01:19:29 +0000592 target->GetImageSearchPathList().Append (ConstString(from),
593 ConstString(to),
594 last_pair); // Notify if this is the last pair
Johnny Chen4d661352011-02-03 00:30:19 +0000595 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000596 }
597 else
598 {
599 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +0000600 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000601 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000602 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000603 result.SetStatus (eReturnStatusFailed);
604 }
605 }
606 }
607 }
608 else
609 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000610 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000611 result.SetStatus (eReturnStatusFailed);
612 }
613 return result.Succeeded();
614 }
615};
616
Greg Claytone1f50b92011-05-03 22:09:39 +0000617#pragma mark CommandObjectTargetModulesSearchPathsClear
618
619class CommandObjectTargetModulesSearchPathsClear : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000620{
621public:
622
Greg Claytone1f50b92011-05-03 22:09:39 +0000623 CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000624 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000625 "target modules search-paths clear",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000626 "Clear all current image search path substitution pairs from the current target.",
Greg Claytone1f50b92011-05-03 22:09:39 +0000627 "target modules search-paths clear")
Chris Lattner24943d22010-06-08 16:52:24 +0000628 {
629 }
630
Greg Claytone1f50b92011-05-03 22:09:39 +0000631 ~CommandObjectTargetModulesSearchPathsClear ()
Chris Lattner24943d22010-06-08 16:52:24 +0000632 {
633 }
634
635 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000636 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000637 CommandReturnObject &result)
638 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000639 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000640 if (target)
641 {
642 bool notify = true;
643 target->GetImageSearchPathList().Clear(notify);
Johnny Chen4d661352011-02-03 00:30:19 +0000644 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000645 }
646 else
647 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000648 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000649 result.SetStatus (eReturnStatusFailed);
650 }
651 return result.Succeeded();
652 }
653};
654
Greg Claytone1f50b92011-05-03 22:09:39 +0000655#pragma mark CommandObjectTargetModulesSearchPathsInsert
656
657class CommandObjectTargetModulesSearchPathsInsert : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000658{
659public:
660
Greg Claytone1f50b92011-05-03 22:09:39 +0000661 CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000662 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000663 "target modules search-paths insert",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000664 "Insert a new image search path substitution pair into the current target at the specified index.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000665 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000666 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000667 CommandArgumentEntry arg1;
668 CommandArgumentEntry arg2;
669 CommandArgumentData index_arg;
670 CommandArgumentData old_prefix_arg;
671 CommandArgumentData new_prefix_arg;
672
673 // Define the first and only variant of this arg.
674 index_arg.arg_type = eArgTypeIndex;
675 index_arg.arg_repetition = eArgRepeatPlain;
676
677 // Put the one and only variant into the first arg for m_arguments:
678 arg1.push_back (index_arg);
679
680 // Define the first variant of this arg pair.
681 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
682 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
683
684 // Define the first variant of this arg pair.
685 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
686 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
687
688 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
689 // must always occur together, they are treated as two variants of one argument rather than two independent
690 // arguments. Push them both into the same argument position for m_arguments...
691
692 arg2.push_back (old_prefix_arg);
693 arg2.push_back (new_prefix_arg);
694
695 // Add arguments to m_arguments.
696 m_arguments.push_back (arg1);
697 m_arguments.push_back (arg2);
Chris Lattner24943d22010-06-08 16:52:24 +0000698 }
699
Greg Claytone1f50b92011-05-03 22:09:39 +0000700 ~CommandObjectTargetModulesSearchPathsInsert ()
Chris Lattner24943d22010-06-08 16:52:24 +0000701 {
702 }
703
704 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000705 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000706 CommandReturnObject &result)
707 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000708 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000709 if (target)
710 {
711 uint32_t argc = command.GetArgumentCount();
712 // check for at least 3 arguments and an odd nubmer of parameters
713 if (argc >= 3 && argc & 1)
714 {
715 bool success = false;
716
717 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
718
719 if (!success)
720 {
721 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
722 result.SetStatus (eReturnStatusFailed);
723 return result.Succeeded();
724 }
725
726 // shift off the index
727 command.Shift();
728 argc = command.GetArgumentCount();
729
730 for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
731 {
732 const char *from = command.GetArgumentAtIndex(i);
733 const char *to = command.GetArgumentAtIndex(i+1);
734
735 if (from[0] && to[0])
736 {
737 bool last_pair = ((argc - i) == 2);
738 target->GetImageSearchPathList().Insert (ConstString(from),
739 ConstString(to),
740 insert_idx,
741 last_pair);
Johnny Chen4d661352011-02-03 00:30:19 +0000742 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000743 }
744 else
745 {
746 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +0000747 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000748 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000749 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000750 result.SetStatus (eReturnStatusFailed);
751 return false;
752 }
753 }
754 }
755 else
756 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000757 result.AppendError ("insert requires at least three arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000758 result.SetStatus (eReturnStatusFailed);
759 return result.Succeeded();
760 }
761
762 }
763 else
764 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000765 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000766 result.SetStatus (eReturnStatusFailed);
767 }
768 return result.Succeeded();
769 }
770};
771
Greg Claytone1f50b92011-05-03 22:09:39 +0000772
773#pragma mark CommandObjectTargetModulesSearchPathsList
774
775
776class CommandObjectTargetModulesSearchPathsList : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000777{
778public:
779
Greg Claytone1f50b92011-05-03 22:09:39 +0000780 CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000781 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000782 "target modules search-paths list",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000783 "List all current image search path substitution pairs in the current target.",
Greg Claytone1f50b92011-05-03 22:09:39 +0000784 "target modules search-paths list")
Chris Lattner24943d22010-06-08 16:52:24 +0000785 {
786 }
787
Greg Claytone1f50b92011-05-03 22:09:39 +0000788 ~CommandObjectTargetModulesSearchPathsList ()
Chris Lattner24943d22010-06-08 16:52:24 +0000789 {
790 }
791
792 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000793 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000794 CommandReturnObject &result)
795 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000796 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000797 if (target)
798 {
799 if (command.GetArgumentCount() != 0)
800 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000801 result.AppendError ("list takes no arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000802 result.SetStatus (eReturnStatusFailed);
803 return result.Succeeded();
804 }
805
806 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
Johnny Chen4d661352011-02-03 00:30:19 +0000807 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000808 }
809 else
810 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000811 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000812 result.SetStatus (eReturnStatusFailed);
813 }
814 return result.Succeeded();
815 }
816};
817
Greg Claytone1f50b92011-05-03 22:09:39 +0000818#pragma mark CommandObjectTargetModulesSearchPathsQuery
819
820class CommandObjectTargetModulesSearchPathsQuery : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000821{
822public:
823
Greg Claytone1f50b92011-05-03 22:09:39 +0000824 CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000825 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000826 "target modules search-paths query",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000827 "Transform a path using the first applicable image search path.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000828 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000829 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000830 CommandArgumentEntry arg;
831 CommandArgumentData path_arg;
832
833 // Define the first (and only) variant of this arg.
834 path_arg.arg_type = eArgTypePath;
835 path_arg.arg_repetition = eArgRepeatPlain;
836
837 // There is only one variant this argument could be; put it into the argument entry.
838 arg.push_back (path_arg);
839
840 // Push the data for the first argument into the m_arguments vector.
841 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000842 }
843
Greg Claytone1f50b92011-05-03 22:09:39 +0000844 ~CommandObjectTargetModulesSearchPathsQuery ()
Chris Lattner24943d22010-06-08 16:52:24 +0000845 {
846 }
847
848 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000849 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000850 CommandReturnObject &result)
851 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000852 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000853 if (target)
854 {
855 if (command.GetArgumentCount() != 1)
856 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000857 result.AppendError ("query requires one argument\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000858 result.SetStatus (eReturnStatusFailed);
859 return result.Succeeded();
860 }
861
862 ConstString orig(command.GetArgumentAtIndex(0));
863 ConstString transformed;
864 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
865 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
866 else
867 result.GetOutputStream().Printf("%s\n", orig.GetCString());
Johnny Chen4d661352011-02-03 00:30:19 +0000868
869 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000870 }
871 else
872 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000873 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000874 result.SetStatus (eReturnStatusFailed);
875 }
876 return result.Succeeded();
877 }
878};
879
Greg Claytone1f50b92011-05-03 22:09:39 +0000880//----------------------------------------------------------------------
881// Static Helper functions
882//----------------------------------------------------------------------
883static void
884DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width)
885{
886 if (module)
887 {
888 const char *arch_cstr;
889 if (full_triple)
890 arch_cstr = module->GetArchitecture().GetTriple().str().c_str();
891 else
892 arch_cstr = module->GetArchitecture().GetArchitectureName();
893 if (width)
894 strm.Printf("%-*s", width, arch_cstr);
895 else
896 strm.PutCString(arch_cstr);
897 }
898}
899
900static void
901DumpModuleUUID (Stream &strm, Module *module)
902{
903 module->GetUUID().Dump (&strm);
904}
905
906static uint32_t
907DumpCompileUnitLineTable
908(
909 CommandInterpreter &interpreter,
910 Stream &strm,
911 Module *module,
912 const FileSpec &file_spec,
913 bool load_addresses
914 )
915{
916 uint32_t num_matches = 0;
917 if (module)
918 {
919 SymbolContextList sc_list;
920 num_matches = module->ResolveSymbolContextsForFileSpec (file_spec,
921 0,
922 false,
923 eSymbolContextCompUnit,
924 sc_list);
925
926 for (uint32_t i=0; i<num_matches; ++i)
927 {
928 SymbolContext sc;
929 if (sc_list.GetContextAtIndex(i, sc))
930 {
931 if (i > 0)
932 strm << "\n\n";
933
934 strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `"
935 << module->GetFileSpec().GetFilename() << "\n";
936 LineTable *line_table = sc.comp_unit->GetLineTable();
937 if (line_table)
938 line_table->GetDescription (&strm,
939 interpreter.GetExecutionContext().target,
940 lldb::eDescriptionLevelBrief);
941 else
942 strm << "No line table";
943 }
944 }
945 }
946 return num_matches;
947}
948
949static void
950DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
951{
952 if (file_spec_ptr)
953 {
954 if (width > 0)
955 {
956 char fullpath[PATH_MAX];
957 if (file_spec_ptr->GetPath(fullpath, sizeof(fullpath)))
958 {
959 strm.Printf("%-*s", width, fullpath);
960 return;
961 }
962 }
963 else
964 {
965 file_spec_ptr->Dump(&strm);
966 return;
967 }
968 }
969 // Keep the width spacing correct if things go wrong...
970 if (width > 0)
971 strm.Printf("%-*s", width, "");
972}
973
974static void
975DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
976{
977 if (file_spec_ptr)
978 {
979 if (width > 0)
980 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
981 else
982 file_spec_ptr->GetDirectory().Dump(&strm);
983 return;
984 }
985 // Keep the width spacing correct if things go wrong...
986 if (width > 0)
987 strm.Printf("%-*s", width, "");
988}
989
990static void
991DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
992{
993 if (file_spec_ptr)
994 {
995 if (width > 0)
996 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
997 else
998 file_spec_ptr->GetFilename().Dump(&strm);
999 return;
1000 }
1001 // Keep the width spacing correct if things go wrong...
1002 if (width > 0)
1003 strm.Printf("%-*s", width, "");
1004}
1005
1006
1007static void
1008DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order)
1009{
1010 if (module)
1011 {
1012 ObjectFile *objfile = module->GetObjectFile ();
1013 if (objfile)
1014 {
1015 Symtab *symtab = objfile->GetSymtab();
1016 if (symtab)
1017 symtab->Dump(&strm, interpreter.GetExecutionContext().target, sort_order);
1018 }
1019 }
1020}
1021
1022static void
1023DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module)
1024{
1025 if (module)
1026 {
1027 ObjectFile *objfile = module->GetObjectFile ();
1028 if (objfile)
1029 {
1030 SectionList *section_list = objfile->GetSectionList();
1031 if (section_list)
1032 {
1033 strm.PutCString ("Sections for '");
1034 strm << module->GetFileSpec();
1035 if (module->GetObjectName())
1036 strm << '(' << module->GetObjectName() << ')';
1037 strm.Printf ("' (%s):\n", module->GetArchitecture().GetArchitectureName());
1038 strm.IndentMore();
1039 section_list->Dump(&strm, interpreter.GetExecutionContext().target, true, UINT32_MAX);
1040 strm.IndentLess();
1041 }
1042 }
1043 }
1044}
1045
1046static bool
1047DumpModuleSymbolVendor (Stream &strm, Module *module)
1048{
1049 if (module)
1050 {
1051 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1052 if (symbol_vendor)
1053 {
1054 symbol_vendor->Dump(&strm);
1055 return true;
1056 }
1057 }
1058 return false;
1059}
1060
1061static bool
1062LookupAddressInModule
1063(
1064 CommandInterpreter &interpreter,
1065 Stream &strm,
1066 Module *module,
1067 uint32_t resolve_mask,
1068 lldb::addr_t raw_addr,
1069 lldb::addr_t offset,
1070 bool verbose
1071 )
1072{
1073 if (module)
1074 {
1075 lldb::addr_t addr = raw_addr - offset;
1076 Address so_addr;
1077 SymbolContext sc;
1078 Target *target = interpreter.GetExecutionContext().target;
1079 if (target && !target->GetSectionLoadList().IsEmpty())
1080 {
1081 if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr))
1082 return false;
1083 else if (so_addr.GetModule() != module)
1084 return false;
1085 }
1086 else
1087 {
1088 if (!module->ResolveFileAddress (addr, so_addr))
1089 return false;
1090 }
1091
1092 // If an offset was given, print out the address we ended up looking up
1093 if (offset)
1094 strm.Printf("File Address: 0x%llx\n", addr);
1095
1096 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope();
1097 strm.IndentMore();
1098 strm.Indent (" Address: ");
1099 so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
1100 strm.EOL();
1101 strm.Indent (" Summary: ");
1102 const uint32_t save_indent = strm.GetIndentLevel ();
1103 strm.SetIndentLevel (save_indent + 11);
1104 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
1105 strm.SetIndentLevel (save_indent);
1106 strm.EOL();
1107 // Print out detailed address information when verbose is enabled
1108 if (verbose)
1109 {
1110 if (so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext))
1111 strm.EOL();
1112 }
1113 strm.IndentLess();
1114 return true;
1115 }
1116
1117 return false;
1118}
1119
1120static uint32_t
1121LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
1122{
1123 if (module)
1124 {
1125 SymbolContext sc;
1126
1127 ObjectFile *objfile = module->GetObjectFile ();
1128 if (objfile)
1129 {
1130 Symtab *symtab = objfile->GetSymtab();
1131 if (symtab)
1132 {
1133 uint32_t i;
1134 std::vector<uint32_t> match_indexes;
1135 ConstString symbol_name (name);
1136 uint32_t num_matches = 0;
1137 if (name_is_regex)
1138 {
1139 RegularExpression name_regexp(name);
1140 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp,
1141 eSymbolTypeAny,
1142 match_indexes);
1143 }
1144 else
1145 {
1146 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
1147 }
1148
1149
1150 if (num_matches > 0)
1151 {
1152 strm.Indent ();
1153 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1154 name_is_regex ? "the regular expression " : "", name);
1155 DumpFullpath (strm, &module->GetFileSpec(), 0);
1156 strm.PutCString(":\n");
1157 strm.IndentMore ();
1158 Symtab::DumpSymbolHeader (&strm);
1159 for (i=0; i < num_matches; ++i)
1160 {
1161 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1162 strm.Indent ();
1163 symbol->Dump (&strm, interpreter.GetExecutionContext().target, i);
1164 }
1165 strm.IndentLess ();
1166 return num_matches;
1167 }
1168 }
1169 }
1170 }
1171 return 0;
1172}
1173
1174
1175static void
1176DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr, bool verbose)
1177{
1178 strm.IndentMore ();
1179 uint32_t i;
1180 const uint32_t num_matches = sc_list.GetSize();
1181
1182 for (i=0; i<num_matches; ++i)
1183 {
1184 SymbolContext sc;
1185 if (sc_list.GetContextAtIndex(i, sc))
1186 {
1187 strm.Indent();
1188 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope ();
1189
1190 if (prepend_addr)
1191 {
1192 if (sc.line_entry.range.GetBaseAddress().IsValid())
1193 {
1194 sc.line_entry.range.GetBaseAddress().Dump (&strm,
1195 exe_scope,
1196 Address::DumpStyleLoadAddress,
1197 Address::DumpStyleModuleWithFileAddress);
1198 strm.PutCString(" in ");
1199 }
1200 }
1201 sc.DumpStopContext(&strm,
1202 exe_scope,
1203 sc.line_entry.range.GetBaseAddress(),
1204 true,
1205 true,
1206 false);
1207 strm.EOL();
1208 if (verbose)
1209 {
1210 if (sc.line_entry.range.GetBaseAddress().IsValid())
1211 {
1212 if (sc.line_entry.range.GetBaseAddress().Dump (&strm,
1213 exe_scope,
1214 Address::DumpStyleDetailedSymbolContext))
1215 strm.PutCString("\n\n");
1216 }
1217 else if (sc.function->GetAddressRange().GetBaseAddress().IsValid())
1218 {
1219 if (sc.function->GetAddressRange().GetBaseAddress().Dump (&strm,
1220 exe_scope,
1221 Address::DumpStyleDetailedSymbolContext))
1222 strm.PutCString("\n\n");
1223 }
1224 }
1225 }
1226 }
1227 strm.IndentLess ();
1228}
1229
1230static uint32_t
1231LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose)
1232{
1233 if (module && name && name[0])
1234 {
1235 SymbolContextList sc_list;
1236 const bool include_symbols = false;
1237 const bool append = true;
1238 uint32_t num_matches = 0;
1239 if (name_is_regex)
1240 {
1241 RegularExpression function_name_regex (name);
1242 num_matches = module->FindFunctions (function_name_regex,
1243 include_symbols,
1244 append,
1245 sc_list);
1246 }
1247 else
1248 {
1249 ConstString function_name (name);
1250 num_matches = module->FindFunctions (function_name,
1251 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
1252 include_symbols,
1253 append,
1254 sc_list);
1255 }
1256
1257 if (num_matches)
1258 {
1259 strm.Indent ();
1260 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1261 DumpFullpath (strm, &module->GetFileSpec(), 0);
1262 strm.PutCString(":\n");
1263 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
1264 }
1265 return num_matches;
1266 }
1267 return 0;
1268}
1269
1270static uint32_t
Greg Clayton801417e2011-07-07 01:59:51 +00001271LookupTypeInModule (CommandInterpreter &interpreter,
1272 Stream &strm,
1273 Module *module,
1274 const char *name_cstr,
1275 bool name_is_regex)
Greg Claytone1f50b92011-05-03 22:09:39 +00001276{
1277 if (module && name_cstr && name_cstr[0])
1278 {
1279 SymbolContextList sc_list;
1280
1281 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
1282 if (symbol_vendor)
1283 {
1284 TypeList type_list;
1285 uint32_t num_matches = 0;
1286 SymbolContext sc;
1287 // if (name_is_regex)
1288 // {
1289 // RegularExpression name_regex (name_cstr);
1290 // num_matches = symbol_vendor->FindFunctions(sc, name_regex, true, UINT32_MAX, type_list);
1291 // }
1292 // else
1293 // {
1294 ConstString name(name_cstr);
1295 num_matches = symbol_vendor->FindTypes(sc, name, true, UINT32_MAX, type_list);
1296 // }
1297
1298 if (num_matches)
1299 {
1300 strm.Indent ();
1301 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1302 DumpFullpath (strm, &module->GetFileSpec(), 0);
1303 strm.PutCString(":\n");
1304 const uint32_t num_types = type_list.GetSize();
1305 for (uint32_t i=0; i<num_types; ++i)
1306 {
1307 TypeSP type_sp (type_list.GetTypeAtIndex(i));
1308 if (type_sp)
1309 {
1310 // Resolve the clang type so that any forward references
1311 // to types that haven't yet been parsed will get parsed.
1312 type_sp->GetClangFullType ();
1313 type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
1314 }
1315 strm.EOL();
1316 }
1317 }
1318 return num_matches;
1319 }
1320 }
1321 return 0;
1322}
1323
1324static uint32_t
1325LookupFileAndLineInModule (CommandInterpreter &interpreter,
1326 Stream &strm,
1327 Module *module,
1328 const FileSpec &file_spec,
1329 uint32_t line,
1330 bool check_inlines,
1331 bool verbose)
1332{
1333 if (module && file_spec)
1334 {
1335 SymbolContextList sc_list;
1336 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
1337 eSymbolContextEverything, sc_list);
1338 if (num_matches > 0)
1339 {
1340 strm.Indent ();
1341 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1342 strm << file_spec;
1343 if (line > 0)
1344 strm.Printf (":%u", line);
1345 strm << " in ";
1346 DumpFullpath (strm, &module->GetFileSpec(), 0);
1347 strm.PutCString(":\n");
1348 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
1349 return num_matches;
1350 }
1351 }
1352 return 0;
1353
1354}
1355
1356#pragma mark CommandObjectTargetModulesModuleAutoComplete
1357
1358//----------------------------------------------------------------------
1359// A base command object class that can auto complete with module file
1360// paths
1361//----------------------------------------------------------------------
1362
1363class CommandObjectTargetModulesModuleAutoComplete : public CommandObject
1364{
1365public:
1366
1367 CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter,
1368 const char *name,
1369 const char *help,
1370 const char *syntax) :
1371 CommandObject (interpreter, name, help, syntax)
1372 {
1373 CommandArgumentEntry arg;
1374 CommandArgumentData file_arg;
1375
1376 // Define the first (and only) variant of this arg.
1377 file_arg.arg_type = eArgTypeFilename;
1378 file_arg.arg_repetition = eArgRepeatStar;
1379
1380 // There is only one variant this argument could be; put it into the argument entry.
1381 arg.push_back (file_arg);
1382
1383 // Push the data for the first argument into the m_arguments vector.
1384 m_arguments.push_back (arg);
1385 }
1386
1387 virtual
1388 ~CommandObjectTargetModulesModuleAutoComplete ()
1389 {
1390 }
1391
1392 virtual int
1393 HandleArgumentCompletion (Args &input,
1394 int &cursor_index,
1395 int &cursor_char_position,
1396 OptionElementVector &opt_element_vector,
1397 int match_start_point,
1398 int max_return_elements,
1399 bool &word_complete,
1400 StringList &matches)
1401 {
1402 // Arguments are the standard module completer.
1403 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1404 completion_str.erase (cursor_char_position);
1405
1406 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1407 CommandCompletions::eModuleCompletion,
1408 completion_str.c_str(),
1409 match_start_point,
1410 max_return_elements,
1411 NULL,
1412 word_complete,
1413 matches);
1414 return matches.GetSize();
1415 }
1416};
1417
1418#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1419
1420//----------------------------------------------------------------------
1421// A base command object class that can auto complete with module source
1422// file paths
1423//----------------------------------------------------------------------
1424
1425class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObject
1426{
1427public:
1428
1429 CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
1430 const char *name,
1431 const char *help,
1432 const char *syntax) :
1433 CommandObject (interpreter, name, help, syntax)
1434 {
1435 CommandArgumentEntry arg;
1436 CommandArgumentData source_file_arg;
1437
1438 // Define the first (and only) variant of this arg.
1439 source_file_arg.arg_type = eArgTypeSourceFile;
1440 source_file_arg.arg_repetition = eArgRepeatPlus;
1441
1442 // There is only one variant this argument could be; put it into the argument entry.
1443 arg.push_back (source_file_arg);
1444
1445 // Push the data for the first argument into the m_arguments vector.
1446 m_arguments.push_back (arg);
1447 }
1448
1449 virtual
1450 ~CommandObjectTargetModulesSourceFileAutoComplete ()
1451 {
1452 }
1453
1454 virtual int
1455 HandleArgumentCompletion (Args &input,
1456 int &cursor_index,
1457 int &cursor_char_position,
1458 OptionElementVector &opt_element_vector,
1459 int match_start_point,
1460 int max_return_elements,
1461 bool &word_complete,
1462 StringList &matches)
1463 {
1464 // Arguments are the standard source file completer.
1465 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1466 completion_str.erase (cursor_char_position);
1467
1468 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1469 CommandCompletions::eSourceFileCompletion,
1470 completion_str.c_str(),
1471 match_start_point,
1472 max_return_elements,
1473 NULL,
1474 word_complete,
1475 matches);
1476 return matches.GetSize();
1477 }
1478};
1479
1480
1481#pragma mark CommandObjectTargetModulesDumpSymtab
1482
1483
1484class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
1485{
1486public:
1487 CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
1488 CommandObjectTargetModulesModuleAutoComplete (interpreter,
1489 "target modules dump symtab",
1490 "Dump the symbol table from one or more target modules.",
1491 NULL),
1492 m_options (interpreter)
1493 {
1494 }
1495
1496 virtual
1497 ~CommandObjectTargetModulesDumpSymtab ()
1498 {
1499 }
1500
1501 virtual bool
1502 Execute (Args& command,
1503 CommandReturnObject &result)
1504 {
1505 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1506 if (target == NULL)
1507 {
1508 result.AppendError ("invalid target, create a debug target using the 'target create' command");
1509 result.SetStatus (eReturnStatusFailed);
1510 return false;
1511 }
1512 else
1513 {
1514 uint32_t num_dumped = 0;
1515
1516 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1517 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1518 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1519
1520 if (command.GetArgumentCount() == 0)
1521 {
1522 // Dump all sections for all modules images
1523 const uint32_t num_modules = target->GetImages().GetSize();
1524 if (num_modules > 0)
1525 {
1526 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
1527 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1528 {
1529 if (num_dumped > 0)
1530 {
1531 result.GetOutputStream().EOL();
1532 result.GetOutputStream().EOL();
1533 }
1534 num_dumped++;
1535 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order);
1536 }
1537 }
1538 else
1539 {
1540 result.AppendError ("the target has no associated executable images");
1541 result.SetStatus (eReturnStatusFailed);
1542 return false;
1543 }
1544 }
1545 else
1546 {
1547 // Dump specified images (by basename or fullpath)
1548 const char *arg_cstr;
1549 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1550 {
1551 FileSpec image_file(arg_cstr, false);
1552 ModuleList matching_modules;
1553 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
1554
1555 // Not found in our module list for our target, check the main
1556 // shared module list in case it is a extra file used somewhere
1557 // else
1558 if (num_matching_modules == 0)
1559 num_matching_modules = ModuleList::FindSharedModules (image_file,
1560 target->GetArchitecture(),
1561 NULL,
1562 NULL,
1563 matching_modules);
1564
1565 if (num_matching_modules > 0)
1566 {
1567 for (size_t i=0; i<num_matching_modules; ++i)
1568 {
1569 Module *image_module = matching_modules.GetModulePointerAtIndex(i);
1570 if (image_module)
1571 {
1572 if (num_dumped > 0)
1573 {
1574 result.GetOutputStream().EOL();
1575 result.GetOutputStream().EOL();
1576 }
1577 num_dumped++;
1578 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), image_module, m_options.m_sort_order);
1579 }
1580 }
1581 }
1582 else
1583 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1584 }
1585 }
1586
1587 if (num_dumped > 0)
1588 result.SetStatus (eReturnStatusSuccessFinishResult);
1589 else
1590 {
1591 result.AppendError ("no matching executable images found");
1592 result.SetStatus (eReturnStatusFailed);
1593 }
1594 }
1595 return result.Succeeded();
1596 }
1597
1598 virtual Options *
1599 GetOptions ()
1600 {
1601 return &m_options;
1602 }
1603
1604 class CommandOptions : public Options
1605 {
1606 public:
1607
1608 CommandOptions (CommandInterpreter &interpreter) :
1609 Options(interpreter),
1610 m_sort_order (eSortOrderNone)
1611 {
1612 }
1613
1614 virtual
1615 ~CommandOptions ()
1616 {
1617 }
1618
1619 virtual Error
1620 SetOptionValue (uint32_t option_idx, const char *option_arg)
1621 {
1622 Error error;
1623 char short_option = (char) m_getopt_table[option_idx].val;
1624
1625 switch (short_option)
1626 {
1627 case 's':
1628 {
1629 bool found_one = false;
1630 m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
1631 g_option_table[option_idx].enum_values,
1632 eSortOrderNone,
1633 &found_one);
1634 if (!found_one)
1635 error.SetErrorStringWithFormat("Invalid enumeration value '%s' for option '%c'.\n",
1636 option_arg,
1637 short_option);
1638 }
1639 break;
1640
1641 default:
1642 error.SetErrorStringWithFormat("Invalid short option character '%c'.\n", short_option);
1643 break;
1644
1645 }
1646 return error;
1647 }
1648
1649 void
1650 OptionParsingStarting ()
1651 {
1652 m_sort_order = eSortOrderNone;
1653 }
1654
1655 const OptionDefinition*
1656 GetDefinitions ()
1657 {
1658 return g_option_table;
1659 }
1660
1661 // Options table: Required for subclasses of Options.
1662 static OptionDefinition g_option_table[];
1663
1664 SortOrder m_sort_order;
1665 };
1666
1667protected:
1668
1669 CommandOptions m_options;
1670};
1671
1672static OptionEnumValueElement
1673g_sort_option_enumeration[4] =
1674{
1675 { eSortOrderNone, "none", "No sorting, use the original symbol table order."},
1676 { eSortOrderByAddress, "address", "Sort output by symbol address."},
1677 { eSortOrderByName, "name", "Sort output by symbol name."},
1678 { 0, NULL, NULL }
1679};
1680
1681
1682OptionDefinition
1683CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
1684{
1685 { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
1686 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1687};
1688
1689#pragma mark CommandObjectTargetModulesDumpSections
1690
1691//----------------------------------------------------------------------
1692// Image section dumping command
1693//----------------------------------------------------------------------
1694
1695class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
1696{
1697public:
1698 CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
1699 CommandObjectTargetModulesModuleAutoComplete (interpreter,
1700 "target modules dump sections",
1701 "Dump the sections from one or more target modules.",
1702 //"target modules dump sections [<file1> ...]")
1703 NULL)
1704 {
1705 }
1706
1707 virtual
1708 ~CommandObjectTargetModulesDumpSections ()
1709 {
1710 }
1711
1712 virtual bool
1713 Execute (Args& command,
1714 CommandReturnObject &result)
1715 {
1716 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1717 if (target == NULL)
1718 {
1719 result.AppendError ("invalid target, create a debug target using the 'target create' command");
1720 result.SetStatus (eReturnStatusFailed);
1721 return false;
1722 }
1723 else
1724 {
1725 uint32_t num_dumped = 0;
1726
1727 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1728 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1729 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1730
1731 if (command.GetArgumentCount() == 0)
1732 {
1733 // Dump all sections for all modules images
1734 const uint32_t num_modules = target->GetImages().GetSize();
1735 if (num_modules > 0)
1736 {
1737 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
1738 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1739 {
1740 num_dumped++;
1741 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
1742 }
1743 }
1744 else
1745 {
1746 result.AppendError ("the target has no associated executable images");
1747 result.SetStatus (eReturnStatusFailed);
1748 return false;
1749 }
1750 }
1751 else
1752 {
1753 // Dump specified images (by basename or fullpath)
1754 const char *arg_cstr;
1755 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1756 {
1757 FileSpec image_file(arg_cstr, false);
1758 ModuleList matching_modules;
1759 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
1760
1761 // Not found in our module list for our target, check the main
1762 // shared module list in case it is a extra file used somewhere
1763 // else
1764 if (num_matching_modules == 0)
1765 num_matching_modules = ModuleList::FindSharedModules (image_file,
1766 target->GetArchitecture(),
1767 NULL,
1768 NULL,
1769 matching_modules);
1770
1771 if (num_matching_modules > 0)
1772 {
1773 for (size_t i=0; i<num_matching_modules; ++i)
1774 {
1775 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
1776 if (image_module)
1777 {
1778 num_dumped++;
1779 DumpModuleSections (m_interpreter, result.GetOutputStream(), image_module);
1780 }
1781 }
1782 }
1783 else
1784 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1785 }
1786 }
1787
1788 if (num_dumped > 0)
1789 result.SetStatus (eReturnStatusSuccessFinishResult);
1790 else
1791 {
1792 result.AppendError ("no matching executable images found");
1793 result.SetStatus (eReturnStatusFailed);
1794 }
1795 }
1796 return result.Succeeded();
1797 }
1798};
1799
1800
1801#pragma mark CommandObjectTargetModulesDumpSymfile
1802
1803//----------------------------------------------------------------------
1804// Image debug symbol dumping command
1805//----------------------------------------------------------------------
1806
1807class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
1808{
1809public:
1810 CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
1811 CommandObjectTargetModulesModuleAutoComplete (interpreter,
1812 "target modules dump symfile",
1813 "Dump the debug symbol file for one or more target modules.",
1814 //"target modules dump symfile [<file1> ...]")
1815 NULL)
1816 {
1817 }
1818
1819 virtual
1820 ~CommandObjectTargetModulesDumpSymfile ()
1821 {
1822 }
1823
1824 virtual bool
1825 Execute (Args& command,
1826 CommandReturnObject &result)
1827 {
1828 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1829 if (target == NULL)
1830 {
1831 result.AppendError ("invalid target, create a debug target using the 'target create' command");
1832 result.SetStatus (eReturnStatusFailed);
1833 return false;
1834 }
1835 else
1836 {
1837 uint32_t num_dumped = 0;
1838
1839 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1840 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1841 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1842
1843 if (command.GetArgumentCount() == 0)
1844 {
1845 // Dump all sections for all modules images
1846 const uint32_t num_modules = target->GetImages().GetSize();
1847 if (num_modules > 0)
1848 {
1849 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
1850 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1851 {
1852 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
1853 num_dumped++;
1854 }
1855 }
1856 else
1857 {
1858 result.AppendError ("the target has no associated executable images");
1859 result.SetStatus (eReturnStatusFailed);
1860 return false;
1861 }
1862 }
1863 else
1864 {
1865 // Dump specified images (by basename or fullpath)
1866 const char *arg_cstr;
1867 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1868 {
1869 FileSpec image_file(arg_cstr, false);
1870 ModuleList matching_modules;
1871 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
1872
1873 // Not found in our module list for our target, check the main
1874 // shared module list in case it is a extra file used somewhere
1875 // else
1876 if (num_matching_modules == 0)
1877 num_matching_modules = ModuleList::FindSharedModules (image_file,
1878 target->GetArchitecture(),
1879 NULL,
1880 NULL,
1881 matching_modules);
1882
1883 if (num_matching_modules > 0)
1884 {
1885 for (size_t i=0; i<num_matching_modules; ++i)
1886 {
1887 Module * image_module = matching_modules.GetModulePointerAtIndex(i);
1888 if (image_module)
1889 {
1890 if (DumpModuleSymbolVendor (result.GetOutputStream(), image_module))
1891 num_dumped++;
1892 }
1893 }
1894 }
1895 else
1896 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1897 }
1898 }
1899
1900 if (num_dumped > 0)
1901 result.SetStatus (eReturnStatusSuccessFinishResult);
1902 else
1903 {
1904 result.AppendError ("no matching executable images found");
1905 result.SetStatus (eReturnStatusFailed);
1906 }
1907 }
1908 return result.Succeeded();
1909 }
1910};
1911
1912
1913#pragma mark CommandObjectTargetModulesDumpLineTable
1914
1915//----------------------------------------------------------------------
1916// Image debug line table dumping command
1917//----------------------------------------------------------------------
1918
1919class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
1920{
1921public:
1922 CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
1923 CommandObjectTargetModulesSourceFileAutoComplete (interpreter,
1924 "target modules dump line-table",
1925 "Dump the debug symbol file for one or more target modules.",
1926 NULL)
1927 {
1928 }
1929
1930 virtual
1931 ~CommandObjectTargetModulesDumpLineTable ()
1932 {
1933 }
1934
1935 virtual bool
1936 Execute (Args& command,
1937 CommandReturnObject &result)
1938 {
1939 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1940 if (target == NULL)
1941 {
1942 result.AppendError ("invalid target, create a debug target using the 'target create' command");
1943 result.SetStatus (eReturnStatusFailed);
1944 return false;
1945 }
1946 else
1947 {
1948 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
1949 uint32_t total_num_dumped = 0;
1950
1951 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1952 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1953 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1954
1955 if (command.GetArgumentCount() == 0)
1956 {
1957 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
1958 result.SetStatus (eReturnStatusFailed);
1959 }
1960 else
1961 {
1962 // Dump specified images (by basename or fullpath)
1963 const char *arg_cstr;
1964 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1965 {
1966 FileSpec file_spec(arg_cstr, false);
1967 const uint32_t num_modules = target->GetImages().GetSize();
1968 if (num_modules > 0)
1969 {
1970 uint32_t num_dumped = 0;
1971 for (uint32_t i = 0; i<num_modules; ++i)
1972 {
1973 if (DumpCompileUnitLineTable (m_interpreter,
1974 result.GetOutputStream(),
1975 target->GetImages().GetModulePointerAtIndex(i),
1976 file_spec,
1977 exe_ctx.process != NULL && exe_ctx.process->IsAlive()))
1978 num_dumped++;
1979 }
1980 if (num_dumped == 0)
1981 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
1982 else
1983 total_num_dumped += num_dumped;
1984 }
1985 }
1986 }
1987
1988 if (total_num_dumped > 0)
1989 result.SetStatus (eReturnStatusSuccessFinishResult);
1990 else
1991 {
1992 result.AppendError ("no source filenames matched any command arguments");
1993 result.SetStatus (eReturnStatusFailed);
1994 }
1995 }
1996 return result.Succeeded();
1997 }
1998};
1999
2000
2001#pragma mark CommandObjectTargetModulesDump
2002
2003//----------------------------------------------------------------------
2004// Dump multi-word command for target modules
2005//----------------------------------------------------------------------
2006
2007class CommandObjectTargetModulesDump : public CommandObjectMultiword
2008{
2009public:
2010
2011 //------------------------------------------------------------------
2012 // Constructors and Destructors
2013 //------------------------------------------------------------------
2014 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) :
2015 CommandObjectMultiword (interpreter,
2016 "target modules dump",
2017 "A set of commands for dumping information about one or more target modules.",
2018 "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
2019 {
2020 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
2021 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
2022 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
2023 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
2024 }
2025
2026 virtual
2027 ~CommandObjectTargetModulesDump()
2028 {
2029 }
2030};
2031
2032class CommandObjectTargetModulesAdd : public CommandObject
2033{
2034public:
2035 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
2036 CommandObject (interpreter,
2037 "target modules add",
2038 "Add a new module to the current target's modules.",
2039 "target modules add [<module>]")
2040 {
2041 }
2042
2043 virtual
2044 ~CommandObjectTargetModulesAdd ()
2045 {
2046 }
2047
2048 virtual bool
2049 Execute (Args& args,
2050 CommandReturnObject &result)
2051 {
2052 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2053 if (target == NULL)
2054 {
2055 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2056 result.SetStatus (eReturnStatusFailed);
2057 return false;
2058 }
2059 else
2060 {
2061 const size_t argc = args.GetArgumentCount();
2062 if (argc == 0)
2063 {
2064 result.AppendError ("one or more executable image paths must be specified");
2065 result.SetStatus (eReturnStatusFailed);
2066 return false;
2067 }
2068 else
2069 {
2070 for (size_t i=0; i<argc; ++i)
2071 {
2072 const char *path = args.GetArgumentAtIndex(i);
2073 if (path)
2074 {
2075 FileSpec file_spec(path, true);
2076 ArchSpec arch;
2077 if (file_spec.Exists())
2078 {
2079 ModuleSP module_sp (target->GetSharedModule(file_spec, arch));
2080 if (!module_sp)
2081 {
2082 result.AppendError ("one or more executable image paths must be specified");
2083 result.SetStatus (eReturnStatusFailed);
2084 return false;
2085 }
2086 }
2087 else
2088 {
2089 char resolved_path[PATH_MAX];
2090 result.SetStatus (eReturnStatusFailed);
2091 if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
2092 {
2093 if (strcmp (resolved_path, path) != 0)
2094 {
2095 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
2096 break;
2097 }
2098 }
2099 result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
2100 break;
2101 }
2102 }
2103 }
2104 }
2105 }
2106 return result.Succeeded();
2107 }
2108
2109 int
2110 HandleArgumentCompletion (Args &input,
2111 int &cursor_index,
2112 int &cursor_char_position,
2113 OptionElementVector &opt_element_vector,
2114 int match_start_point,
2115 int max_return_elements,
2116 bool &word_complete,
2117 StringList &matches)
2118 {
2119 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2120 completion_str.erase (cursor_char_position);
2121
2122 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2123 CommandCompletions::eDiskFileCompletion,
2124 completion_str.c_str(),
2125 match_start_point,
2126 max_return_elements,
2127 NULL,
2128 word_complete,
2129 matches);
2130 return matches.GetSize();
2131 }
2132
2133};
2134
2135class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
2136{
2137public:
2138 CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) :
2139 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2140 "target modules load",
2141 "Set the load addresses for one or more sections in a target module.",
2142 "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
2143 m_option_group (interpreter),
2144 m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "Fullpath or basename for module to load."),
2145 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)
2146 {
2147 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2148 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2149 m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2150 m_option_group.Finalize();
2151 }
2152
2153 virtual
2154 ~CommandObjectTargetModulesLoad ()
2155 {
2156 }
2157
2158 virtual bool
2159 Execute (Args& args,
2160 CommandReturnObject &result)
2161 {
2162 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2163 if (target == NULL)
2164 {
2165 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2166 result.SetStatus (eReturnStatusFailed);
2167 return false;
2168 }
2169 else
2170 {
2171 const size_t argc = args.GetArgumentCount();
2172 const FileSpec *file_ptr = NULL;
2173 const UUID *uuid_ptr = NULL;
2174 if (m_file_option.GetOptionValue().OptionWasSet())
2175 file_ptr = &m_file_option.GetOptionValue().GetCurrentValue();
2176
2177 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2178 uuid_ptr = &m_uuid_option_group.GetOptionValue().GetCurrentValue();
2179
2180 if (file_ptr || uuid_ptr)
2181 {
2182
2183 ModuleList matching_modules;
2184 const size_t num_matches = target->GetImages().FindModules (file_ptr, // File spec to match (can be NULL to match by UUID only)
2185 NULL, // Architecture
2186 uuid_ptr, // UUID to match (can be NULL to not match on UUID)
2187 NULL, // Object name
2188 matching_modules);
2189
2190 char path[PATH_MAX];
2191 if (num_matches == 1)
2192 {
2193 Module *module = matching_modules.GetModulePointerAtIndex(0);
2194 if (module)
2195 {
2196 ObjectFile *objfile = module->GetObjectFile();
2197 if (objfile)
2198 {
2199 SectionList *section_list = objfile->GetSectionList();
2200 if (section_list)
2201 {
2202 if (argc == 0)
2203 {
2204 if (m_slide_option.GetOptionValue().OptionWasSet())
2205 {
2206 Module *module = matching_modules.GetModulePointerAtIndex(0);
2207 if (module)
2208 {
2209 ObjectFile *objfile = module->GetObjectFile();
2210 if (objfile)
2211 {
2212 SectionList *section_list = objfile->GetSectionList();
2213 if (section_list)
2214 {
2215 const size_t num_sections = section_list->GetSize();
2216 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
2217 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
2218 {
2219 SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx));
2220 if (section_sp)
2221 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), section_sp->GetFileAddress() + slide);
2222 }
2223 }
2224 }
2225 }
2226 }
2227 else
2228 {
2229 result.AppendError ("one or more section name + load address pair must be specified");
2230 result.SetStatus (eReturnStatusFailed);
2231 return false;
2232 }
2233 }
2234 else
2235 {
2236 if (m_slide_option.GetOptionValue().OptionWasSet())
2237 {
2238 result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
2239 result.SetStatus (eReturnStatusFailed);
2240 return false;
2241 }
2242
2243 for (size_t i=0; i<argc; i += 2)
2244 {
2245 const char *sect_name = args.GetArgumentAtIndex(i);
2246 const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
2247 if (sect_name && load_addr_cstr)
2248 {
2249 ConstString const_sect_name(sect_name);
2250 bool success = false;
2251 addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2252 if (success)
2253 {
2254 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
2255 if (section_sp)
2256 {
2257 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), load_addr);
2258 result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr);
2259 }
2260 else
2261 {
2262 result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
2263 result.SetStatus (eReturnStatusFailed);
2264 break;
2265 }
2266 }
2267 else
2268 {
2269 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
2270 result.SetStatus (eReturnStatusFailed);
2271 break;
2272 }
2273 }
2274 else
2275 {
2276 if (sect_name)
2277 result.AppendError ("section names must be followed by a load address.\n");
2278 else
2279 result.AppendError ("one or more section name + load address pair must be specified.\n");
2280 result.SetStatus (eReturnStatusFailed);
2281 break;
2282 }
2283 }
2284 }
2285 }
2286 else
2287 {
2288 module->GetFileSpec().GetPath (path, sizeof(path));
2289 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
2290 result.SetStatus (eReturnStatusFailed);
2291 }
2292 }
2293 else
2294 {
2295 module->GetFileSpec().GetPath (path, sizeof(path));
2296 result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
2297 result.SetStatus (eReturnStatusFailed);
2298 }
2299 }
2300 else
2301 {
2302 module->GetFileSpec().GetPath (path, sizeof(path));
2303 result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
2304 result.SetStatus (eReturnStatusFailed);
2305 }
2306 }
2307 else
2308 {
2309 char uuid_cstr[64];
2310 if (file_ptr)
2311 file_ptr->GetPath (path, sizeof(path));
2312 else
2313 path[0] = '\0';
2314
2315 if (uuid_ptr)
2316 uuid_ptr->GetAsCString(uuid_cstr, sizeof(uuid_cstr));
2317 else
2318 uuid_cstr[0] = '\0';
2319 if (num_matches > 1)
2320 {
2321 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
2322 path[0] ? " file=" : "",
2323 path,
2324 uuid_cstr[0] ? " uuid=" : "",
2325 uuid_cstr);
2326 for (size_t i=0; i<num_matches; ++i)
2327 {
2328 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
2329 result.AppendMessageWithFormat("%s\n", path);
2330 }
2331 }
2332 else
2333 {
2334 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n",
2335 path[0] ? " file=" : "",
2336 path,
2337 uuid_cstr[0] ? " uuid=" : "",
2338 uuid_cstr);
2339 }
2340 result.SetStatus (eReturnStatusFailed);
2341 }
2342 }
2343 else
2344 {
2345 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
2346 result.SetStatus (eReturnStatusFailed);
2347 return false;
2348 }
2349 }
2350 return result.Succeeded();
2351 }
2352
2353 virtual Options *
2354 GetOptions ()
2355 {
2356 return &m_option_group;
2357 }
2358
2359protected:
2360 OptionGroupOptions m_option_group;
2361 OptionGroupUUID m_uuid_option_group;
2362 OptionGroupFile m_file_option;
2363 OptionGroupUInt64 m_slide_option;
2364};
2365
2366//----------------------------------------------------------------------
2367// List images with associated information
2368//----------------------------------------------------------------------
2369class CommandObjectTargetModulesList : public CommandObject
2370{
2371public:
2372
2373 class CommandOptions : public Options
2374 {
2375 public:
2376
2377 CommandOptions (CommandInterpreter &interpreter) :
2378 Options(interpreter),
2379 m_format_array()
2380 {
2381 }
2382
2383 virtual
2384 ~CommandOptions ()
2385 {
2386 }
2387
2388 virtual Error
2389 SetOptionValue (uint32_t option_idx, const char *option_arg)
2390 {
2391 char short_option = (char) m_getopt_table[option_idx].val;
2392 uint32_t width = 0;
2393 if (option_arg)
2394 width = strtoul (option_arg, NULL, 0);
2395 m_format_array.push_back(std::make_pair(short_option, width));
2396 Error error;
2397 return error;
2398 }
2399
2400 void
2401 OptionParsingStarting ()
2402 {
2403 m_format_array.clear();
2404 }
2405
2406 const OptionDefinition*
2407 GetDefinitions ()
2408 {
2409 return g_option_table;
2410 }
2411
2412 // Options table: Required for subclasses of Options.
2413
2414 static OptionDefinition g_option_table[];
2415
2416 // Instance variables to hold the values for command options.
2417 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
2418 FormatWidthCollection m_format_array;
2419 };
2420
2421 CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
2422 CommandObject (interpreter,
2423 "target modules list",
2424 "List current executable and dependent shared library images.",
2425 "target modules list [<cmd-options>]"),
2426 m_options (interpreter)
2427 {
2428 }
2429
2430 virtual
2431 ~CommandObjectTargetModulesList ()
2432 {
2433 }
2434
2435 virtual
2436 Options *
2437 GetOptions ()
2438 {
2439 return &m_options;
2440 }
2441
2442 virtual bool
2443 Execute (Args& command,
2444 CommandReturnObject &result)
2445 {
2446 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2447 if (target == NULL)
2448 {
2449 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2450 result.SetStatus (eReturnStatusFailed);
2451 return false;
2452 }
2453 else
2454 {
2455 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2456 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2457 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2458 // Dump all sections for all modules images
2459 const uint32_t num_modules = target->GetImages().GetSize();
2460 if (num_modules > 0)
2461 {
2462 Stream &strm = result.GetOutputStream();
2463
2464 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2465 {
2466 Module *module = target->GetImages().GetModulePointerAtIndex(image_idx);
2467 strm.Printf("[%3u] ", image_idx);
2468
2469 bool dump_object_name = false;
2470 if (m_options.m_format_array.empty())
2471 {
2472 DumpFullpath(strm, &module->GetFileSpec(), 0);
2473 dump_object_name = true;
2474 }
2475 else
2476 {
2477 const size_t num_entries = m_options.m_format_array.size();
2478 for (size_t i=0; i<num_entries; ++i)
2479 {
2480 if (i > 0)
2481 strm.PutChar(' ');
2482 char format_char = m_options.m_format_array[i].first;
2483 uint32_t width = m_options.m_format_array[i].second;
2484 switch (format_char)
2485 {
2486 case 'a':
2487 DumpModuleArchitecture (strm, module, false, width);
2488 break;
2489
2490 case 't':
2491 DumpModuleArchitecture (strm, module, true, width);
2492 break;
2493
2494 case 'f':
2495 DumpFullpath (strm, &module->GetFileSpec(), width);
2496 dump_object_name = true;
2497 break;
2498
2499 case 'd':
2500 DumpDirectory (strm, &module->GetFileSpec(), width);
2501 break;
2502
2503 case 'b':
2504 DumpBasename (strm, &module->GetFileSpec(), width);
2505 dump_object_name = true;
2506 break;
2507
2508 case 's':
2509 case 'S':
2510 {
2511 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
2512 if (symbol_vendor)
2513 {
2514 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
2515 if (symbol_file)
2516 {
2517 if (format_char == 'S')
2518 DumpBasename(strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
2519 else
2520 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
2521 dump_object_name = true;
2522 break;
2523 }
2524 }
2525 strm.Printf("%.*s", width, "<NONE>");
2526 }
2527 break;
2528
2529 case 'u':
2530 DumpModuleUUID(strm, module);
2531 break;
2532
2533 default:
2534 break;
2535 }
2536
2537 }
2538 }
2539 if (dump_object_name)
2540 {
2541 const char *object_name = module->GetObjectName().GetCString();
2542 if (object_name)
2543 strm.Printf ("(%s)", object_name);
2544 }
2545 strm.EOL();
2546 }
2547 result.SetStatus (eReturnStatusSuccessFinishResult);
2548 }
2549 else
2550 {
2551 result.AppendError ("the target has no associated executable images");
2552 result.SetStatus (eReturnStatusFailed);
2553 return false;
2554 }
2555 }
2556 return result.Succeeded();
2557 }
2558protected:
2559
2560 CommandOptions m_options;
2561};
2562
2563OptionDefinition
2564CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
2565{
2566 { LLDB_OPT_SET_1, false, "arch", 'a', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."},
2567 { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."},
2568 { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."},
2569 { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
2570 { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
2571 { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
2572 { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
2573 { LLDB_OPT_SET_1, false, "symfile-basename", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename to the image symbol file with optional width."},
2574 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
2575};
2576
2577
2578
2579//----------------------------------------------------------------------
2580// Lookup information in images
2581//----------------------------------------------------------------------
2582class CommandObjectTargetModulesLookup : public CommandObject
2583{
2584public:
2585
2586 enum
2587 {
2588 eLookupTypeInvalid = -1,
2589 eLookupTypeAddress = 0,
2590 eLookupTypeSymbol,
2591 eLookupTypeFileLine, // Line is optional
2592 eLookupTypeFunction,
2593 eLookupTypeType,
2594 kNumLookupTypes
2595 };
2596
2597 class CommandOptions : public Options
2598 {
2599 public:
2600
2601 CommandOptions (CommandInterpreter &interpreter) :
2602 Options(interpreter)
2603 {
2604 OptionParsingStarting();
2605 }
2606
2607 virtual
2608 ~CommandOptions ()
2609 {
2610 }
2611
2612 virtual Error
2613 SetOptionValue (uint32_t option_idx, const char *option_arg)
2614 {
2615 Error error;
2616
2617 char short_option = (char) m_getopt_table[option_idx].val;
2618
2619 switch (short_option)
2620 {
2621 case 'a':
2622 m_type = eLookupTypeAddress;
2623 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
2624 if (m_addr == LLDB_INVALID_ADDRESS)
2625 error.SetErrorStringWithFormat ("Invalid address string '%s'.\n", option_arg);
2626 break;
2627
2628 case 'o':
2629 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
2630 if (m_offset == LLDB_INVALID_ADDRESS)
2631 error.SetErrorStringWithFormat ("Invalid offset string '%s'.\n", option_arg);
2632 break;
2633
2634 case 's':
2635 m_str = option_arg;
2636 m_type = eLookupTypeSymbol;
2637 break;
2638
2639 case 'f':
2640 m_file.SetFile (option_arg, false);
2641 m_type = eLookupTypeFileLine;
2642 break;
2643
2644 case 'i':
2645 m_check_inlines = false;
2646 break;
2647
2648 case 'l':
2649 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
2650 if (m_line_number == UINT32_MAX)
2651 error.SetErrorStringWithFormat ("Invalid line number string '%s'.\n", option_arg);
2652 else if (m_line_number == 0)
2653 error.SetErrorString ("Zero is an invalid line number.");
2654 m_type = eLookupTypeFileLine;
2655 break;
2656
2657 case 'n':
2658 m_str = option_arg;
2659 m_type = eLookupTypeFunction;
2660 break;
2661
2662 case 't':
2663 m_str = option_arg;
2664 m_type = eLookupTypeType;
2665 break;
2666
2667 case 'v':
2668 m_verbose = 1;
2669 break;
2670
2671 case 'r':
2672 m_use_regex = true;
2673 break;
2674 }
2675
2676 return error;
2677 }
2678
2679 void
2680 OptionParsingStarting ()
2681 {
2682 m_type = eLookupTypeInvalid;
2683 m_str.clear();
2684 m_file.Clear();
2685 m_addr = LLDB_INVALID_ADDRESS;
2686 m_offset = 0;
2687 m_line_number = 0;
2688 m_use_regex = false;
2689 m_check_inlines = true;
2690 m_verbose = false;
2691 }
2692
2693 const OptionDefinition*
2694 GetDefinitions ()
2695 {
2696 return g_option_table;
2697 }
2698
2699 // Options table: Required for subclasses of Options.
2700
2701 static OptionDefinition g_option_table[];
2702 int m_type; // Should be a eLookupTypeXXX enum after parsing options
2703 std::string m_str; // Holds name lookup
2704 FileSpec m_file; // Files for file lookups
2705 lldb::addr_t m_addr; // Holds the address to lookup
2706 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
2707 uint32_t m_line_number; // Line number for file+line lookups
2708 bool m_use_regex; // Name lookups in m_str are regular expressions.
2709 bool m_check_inlines;// Check for inline entries when looking up by file/line.
2710 bool m_verbose; // Enable verbose lookup info
2711
2712 };
2713
2714 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
2715 CommandObject (interpreter,
2716 "target modules lookup",
2717 "Look up information within executable and dependent shared library images.",
2718 NULL),
2719 m_options (interpreter)
2720 {
2721 CommandArgumentEntry arg;
2722 CommandArgumentData file_arg;
2723
2724 // Define the first (and only) variant of this arg.
2725 file_arg.arg_type = eArgTypeFilename;
2726 file_arg.arg_repetition = eArgRepeatStar;
2727
2728 // There is only one variant this argument could be; put it into the argument entry.
2729 arg.push_back (file_arg);
2730
2731 // Push the data for the first argument into the m_arguments vector.
2732 m_arguments.push_back (arg);
2733 }
2734
2735 virtual
2736 ~CommandObjectTargetModulesLookup ()
2737 {
2738 }
2739
2740 virtual Options *
2741 GetOptions ()
2742 {
2743 return &m_options;
2744 }
2745
2746
2747 bool
2748 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
2749 {
2750 switch (m_options.m_type)
2751 {
2752 case eLookupTypeAddress:
2753 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
2754 {
2755 if (LookupAddressInModule (m_interpreter,
2756 result.GetOutputStream(),
2757 module,
2758 eSymbolContextEverything,
2759 m_options.m_addr,
2760 m_options.m_offset,
2761 m_options.m_verbose))
2762 {
2763 result.SetStatus(eReturnStatusSuccessFinishResult);
2764 return true;
2765 }
2766 }
2767 break;
2768
2769 case eLookupTypeSymbol:
2770 if (!m_options.m_str.empty())
2771 {
2772 if (LookupSymbolInModule (m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex))
2773 {
2774 result.SetStatus(eReturnStatusSuccessFinishResult);
2775 return true;
2776 }
2777 }
2778 break;
2779
2780 case eLookupTypeFileLine:
2781 if (m_options.m_file)
2782 {
2783
2784 if (LookupFileAndLineInModule (m_interpreter,
2785 result.GetOutputStream(),
2786 module,
2787 m_options.m_file,
2788 m_options.m_line_number,
2789 m_options.m_check_inlines,
2790 m_options.m_verbose))
2791 {
2792 result.SetStatus(eReturnStatusSuccessFinishResult);
2793 return true;
2794 }
2795 }
2796 break;
2797
2798 case eLookupTypeFunction:
2799 if (!m_options.m_str.empty())
2800 {
2801 if (LookupFunctionInModule (m_interpreter,
2802 result.GetOutputStream(),
2803 module,
2804 m_options.m_str.c_str(),
2805 m_options.m_use_regex,
2806 m_options.m_verbose))
2807 {
2808 result.SetStatus(eReturnStatusSuccessFinishResult);
2809 return true;
2810 }
2811 }
2812 break;
2813
2814 case eLookupTypeType:
2815 if (!m_options.m_str.empty())
2816 {
2817 if (LookupTypeInModule (m_interpreter,
2818 result.GetOutputStream(),
2819 module,
2820 m_options.m_str.c_str(),
2821 m_options.m_use_regex))
2822 {
2823 result.SetStatus(eReturnStatusSuccessFinishResult);
2824 return true;
2825 }
2826 }
2827 break;
2828
2829 default:
2830 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
2831 syntax_error = true;
2832 break;
2833 }
2834
2835 result.SetStatus (eReturnStatusFailed);
2836 return false;
2837 }
2838
2839 virtual bool
2840 Execute (Args& command,
2841 CommandReturnObject &result)
2842 {
2843 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2844 if (target == NULL)
2845 {
2846 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2847 result.SetStatus (eReturnStatusFailed);
2848 return false;
2849 }
2850 else
2851 {
2852 bool syntax_error = false;
2853 uint32_t i;
2854 uint32_t num_successful_lookups = 0;
2855 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2856 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2857 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2858 // Dump all sections for all modules images
2859
2860 if (command.GetArgumentCount() == 0)
2861 {
2862 // Dump all sections for all modules images
2863 const uint32_t num_modules = target->GetImages().GetSize();
2864 if (num_modules > 0)
2865 {
2866 for (i = 0; i<num_modules && syntax_error == false; ++i)
2867 {
2868 if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
2869 {
2870 result.GetOutputStream().EOL();
2871 num_successful_lookups++;
2872 }
2873 }
2874 }
2875 else
2876 {
2877 result.AppendError ("the target has no associated executable images");
2878 result.SetStatus (eReturnStatusFailed);
2879 return false;
2880 }
2881 }
2882 else
2883 {
2884 // Dump specified images (by basename or fullpath)
2885 const char *arg_cstr;
2886 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
2887 {
2888 FileSpec image_file(arg_cstr, false);
2889 ModuleList matching_modules;
2890 size_t num_matching_modules = target->GetImages().FindModules(&image_file, NULL, NULL, NULL, matching_modules);
2891
2892 // Not found in our module list for our target, check the main
2893 // shared module list in case it is a extra file used somewhere
2894 // else
2895 if (num_matching_modules == 0)
2896 num_matching_modules = ModuleList::FindSharedModules (image_file,
2897 target->GetArchitecture(),
2898 NULL,
2899 NULL,
2900 matching_modules);
2901
2902 if (num_matching_modules > 0)
2903 {
2904 for (size_t j=0; j<num_matching_modules; ++j)
2905 {
2906 Module * image_module = matching_modules.GetModulePointerAtIndex(j);
2907 if (image_module)
2908 {
2909 if (LookupInModule (m_interpreter, image_module, result, syntax_error))
2910 {
2911 result.GetOutputStream().EOL();
2912 num_successful_lookups++;
2913 }
2914 }
2915 }
2916 }
2917 else
2918 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2919 }
2920 }
2921
2922 if (num_successful_lookups > 0)
2923 result.SetStatus (eReturnStatusSuccessFinishResult);
2924 else
2925 result.SetStatus (eReturnStatusFailed);
2926 }
2927 return result.Succeeded();
2928 }
2929protected:
2930
2931 CommandOptions m_options;
2932};
2933
2934OptionDefinition
2935CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
2936{
2937 { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more target modules."},
2938 { 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 +00002939 { LLDB_OPT_SET_2| LLDB_OPT_SET_4
2940 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_5 */ ,
2941 false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."},
Greg Claytone1f50b92011-05-03 22:09:39 +00002942 { 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 +00002943 { 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."},
2944 { 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)."},
2945 { LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Check inline line entries (must be used in conjunction with --file)."},
2946 { 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."},
2947 { 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."},
2948 { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."},
2949 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
2950};
Chris Lattner24943d22010-06-08 16:52:24 +00002951
2952
Jim Inghamd60d94a2011-03-11 03:53:59 +00002953#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner24943d22010-06-08 16:52:24 +00002954
2955//-------------------------------------------------------------------------
2956// CommandObjectMultiwordImageSearchPaths
2957//-------------------------------------------------------------------------
2958
Greg Claytone1f50b92011-05-03 22:09:39 +00002959class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
Chris Lattner24943d22010-06-08 16:52:24 +00002960{
2961public:
Greg Claytone1f50b92011-05-03 22:09:39 +00002962
2963 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
2964 CommandObjectMultiword (interpreter,
2965 "target modules search-paths",
2966 "A set of commands for operating on debugger target image search paths.",
2967 "target modules search-paths <subcommand> [<subcommand-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +00002968 {
Greg Claytone1f50b92011-05-03 22:09:39 +00002969 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
2970 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
2971 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
2972 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
2973 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00002974 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002975
2976 ~CommandObjectTargetModulesImageSearchPaths()
Chris Lattner24943d22010-06-08 16:52:24 +00002977 {
2978 }
2979};
2980
Greg Claytone1f50b92011-05-03 22:09:39 +00002981
2982
2983#pragma mark CommandObjectTargetModules
2984
2985//-------------------------------------------------------------------------
2986// CommandObjectTargetModules
2987//-------------------------------------------------------------------------
2988
2989class CommandObjectTargetModules : public CommandObjectMultiword
2990{
2991public:
2992 //------------------------------------------------------------------
2993 // Constructors and Destructors
2994 //------------------------------------------------------------------
2995 CommandObjectTargetModules(CommandInterpreter &interpreter) :
2996 CommandObjectMultiword (interpreter,
2997 "target modules",
2998 "A set of commands for accessing information for one or more target modules.",
2999 "target modules <sub-command> ...")
3000 {
3001 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
3002 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
3003 //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter)));
3004 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
3005 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
3006 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
3007 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
3008
3009 }
3010 virtual
3011 ~CommandObjectTargetModules()
3012 {
3013 }
3014
3015private:
3016 //------------------------------------------------------------------
3017 // For CommandObjectTargetModules only
3018 //------------------------------------------------------------------
3019 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
3020};
3021
3022
Jim Inghamd60d94a2011-03-11 03:53:59 +00003023#pragma mark CommandObjectTargetStopHookAdd
3024
3025//-------------------------------------------------------------------------
3026// CommandObjectTargetStopHookAdd
3027//-------------------------------------------------------------------------
3028
3029class CommandObjectTargetStopHookAdd : public CommandObject
3030{
3031public:
3032
3033 class CommandOptions : public Options
3034 {
3035 public:
Greg Claytonf15996e2011-04-07 22:46:35 +00003036 CommandOptions (CommandInterpreter &interpreter) :
3037 Options(interpreter),
Jim Inghamd60d94a2011-03-11 03:53:59 +00003038 m_line_start(0),
3039 m_line_end (UINT_MAX),
3040 m_func_name_type_mask (eFunctionNameTypeAuto),
3041 m_sym_ctx_specified (false),
Johnny Chen60fe60e2011-05-02 23:47:55 +00003042 m_thread_specified (false),
3043 m_use_one_liner (false),
3044 m_one_liner()
Jim Inghamd60d94a2011-03-11 03:53:59 +00003045 {
3046 }
3047
3048 ~CommandOptions () {}
3049
Greg Claytonb3448432011-03-24 21:19:54 +00003050 const OptionDefinition*
Jim Inghamd60d94a2011-03-11 03:53:59 +00003051 GetDefinitions ()
3052 {
3053 return g_option_table;
3054 }
3055
3056 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +00003057 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003058 {
3059 Error error;
3060 char short_option = (char) m_getopt_table[option_idx].val;
3061 bool success;
3062
3063 switch (short_option)
3064 {
3065 case 'c':
3066 m_class_name = option_arg;
3067 m_sym_ctx_specified = true;
3068 break;
3069
3070 case 'e':
3071 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
3072 if (!success)
3073 {
3074 error.SetErrorStringWithFormat ("Invalid end line number: \"%s\".", option_arg);
3075 break;
3076 }
3077 m_sym_ctx_specified = true;
3078 break;
3079
3080 case 'l':
3081 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
3082 if (!success)
3083 {
3084 error.SetErrorStringWithFormat ("Invalid start line number: \"%s\".", option_arg);
3085 break;
3086 }
3087 m_sym_ctx_specified = true;
3088 break;
3089
3090 case 'n':
3091 m_function_name = option_arg;
3092 m_func_name_type_mask |= eFunctionNameTypeAuto;
3093 m_sym_ctx_specified = true;
3094 break;
3095
3096 case 'f':
3097 m_file_name = option_arg;
3098 m_sym_ctx_specified = true;
3099 break;
3100 case 's':
3101 m_module_name = option_arg;
3102 m_sym_ctx_specified = true;
3103 break;
3104 case 't' :
3105 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003106 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003107 if (m_thread_id == LLDB_INVALID_THREAD_ID)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003108 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003109 m_thread_specified = true;
3110 }
3111 break;
3112 case 'T':
3113 m_thread_name = option_arg;
3114 m_thread_specified = true;
3115 break;
3116 case 'q':
3117 m_queue_name = option_arg;
3118 m_thread_specified = true;
3119 break;
3120 case 'x':
3121 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003122 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003123 if (m_thread_id == UINT32_MAX)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003124 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003125 m_thread_specified = true;
3126 }
3127 break;
Johnny Chen60fe60e2011-05-02 23:47:55 +00003128 case 'o':
3129 m_use_one_liner = true;
3130 m_one_liner = option_arg;
3131 break;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003132 default:
3133 error.SetErrorStringWithFormat ("Unrecognized option %c.");
3134 break;
3135 }
3136 return error;
3137 }
3138
3139 void
Greg Clayton143fcc32011-04-13 00:18:08 +00003140 OptionParsingStarting ()
Jim Inghamd60d94a2011-03-11 03:53:59 +00003141 {
3142 m_class_name.clear();
3143 m_function_name.clear();
3144 m_line_start = 0;
3145 m_line_end = UINT_MAX;
3146 m_file_name.clear();
3147 m_module_name.clear();
3148 m_func_name_type_mask = eFunctionNameTypeAuto;
3149 m_thread_id = LLDB_INVALID_THREAD_ID;
3150 m_thread_index = UINT32_MAX;
3151 m_thread_name.clear();
3152 m_queue_name.clear();
3153
3154 m_sym_ctx_specified = false;
3155 m_thread_specified = false;
Johnny Chen60fe60e2011-05-02 23:47:55 +00003156
3157 m_use_one_liner = false;
3158 m_one_liner.clear();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003159 }
3160
3161
Greg Claytonb3448432011-03-24 21:19:54 +00003162 static OptionDefinition g_option_table[];
Jim Inghamd60d94a2011-03-11 03:53:59 +00003163
3164 std::string m_class_name;
3165 std::string m_function_name;
3166 uint32_t m_line_start;
3167 uint32_t m_line_end;
3168 std::string m_file_name;
3169 std::string m_module_name;
3170 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
3171 lldb::tid_t m_thread_id;
3172 uint32_t m_thread_index;
3173 std::string m_thread_name;
3174 std::string m_queue_name;
3175 bool m_sym_ctx_specified;
3176 bool m_thread_specified;
Johnny Chen60fe60e2011-05-02 23:47:55 +00003177 // Instance variables to hold the values for one_liner options.
3178 bool m_use_one_liner;
3179 std::string m_one_liner;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003180 };
3181
3182 Options *
3183 GetOptions ()
3184 {
3185 return &m_options;
3186 }
3187
3188 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
3189 CommandObject (interpreter,
3190 "target stop-hook add ",
3191 "Add a hook to be executed when the target stops.",
Greg Claytonf15996e2011-04-07 22:46:35 +00003192 "target stop-hook add"),
3193 m_options (interpreter)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003194 {
3195 }
3196
3197 ~CommandObjectTargetStopHookAdd ()
3198 {
3199 }
3200
3201 static size_t
3202 ReadCommandsCallbackFunction (void *baton,
3203 InputReader &reader,
3204 lldb::InputReaderAction notification,
3205 const char *bytes,
3206 size_t bytes_len)
3207 {
Caroline Tice892fadd2011-06-16 16:27:19 +00003208 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003209 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
Jim Inghame15511a2011-05-05 01:03:36 +00003210 static bool got_interrupted;
Caroline Tice892fadd2011-06-16 16:27:19 +00003211 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003212
3213 switch (notification)
3214 {
3215 case eInputReaderActivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00003216 if (!batch_mode)
3217 {
3218 out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end.");
3219 if (reader.GetPrompt())
3220 out_stream->Printf ("%s", reader.GetPrompt());
3221 out_stream->Flush();
3222 }
Jim Inghame15511a2011-05-05 01:03:36 +00003223 got_interrupted = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003224 break;
3225
3226 case eInputReaderDeactivate:
3227 break;
3228
3229 case eInputReaderReactivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00003230 if (reader.GetPrompt() && !batch_mode)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003231 {
Caroline Tice892fadd2011-06-16 16:27:19 +00003232 out_stream->Printf ("%s", reader.GetPrompt());
3233 out_stream->Flush();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003234 }
Jim Inghame15511a2011-05-05 01:03:36 +00003235 got_interrupted = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003236 break;
3237
Caroline Tice4a348082011-05-02 20:41:46 +00003238 case eInputReaderAsynchronousOutputWritten:
3239 break;
3240
Jim Inghamd60d94a2011-03-11 03:53:59 +00003241 case eInputReaderGotToken:
3242 if (bytes && bytes_len && baton)
3243 {
3244 StringList *commands = new_stop_hook->GetCommandPointer();
3245 if (commands)
3246 {
3247 commands->AppendString (bytes, bytes_len);
3248 }
3249 }
Caroline Tice892fadd2011-06-16 16:27:19 +00003250 if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003251 {
Caroline Tice892fadd2011-06-16 16:27:19 +00003252 out_stream->Printf ("%s", reader.GetPrompt());
3253 out_stream->Flush();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003254 }
3255 break;
3256
3257 case eInputReaderInterrupt:
3258 {
3259 // Finish, and cancel the stop hook.
3260 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
Caroline Tice892fadd2011-06-16 16:27:19 +00003261 if (!batch_mode)
3262 {
3263 out_stream->Printf ("Stop hook cancelled.\n");
3264 out_stream->Flush();
3265 }
3266
Jim Inghamd60d94a2011-03-11 03:53:59 +00003267 reader.SetIsDone (true);
3268 }
Jim Inghame15511a2011-05-05 01:03:36 +00003269 got_interrupted = true;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003270 break;
3271
3272 case eInputReaderEndOfFile:
3273 reader.SetIsDone (true);
3274 break;
3275
3276 case eInputReaderDone:
Caroline Tice892fadd2011-06-16 16:27:19 +00003277 if (!got_interrupted && !batch_mode)
3278 {
3279 out_stream->Printf ("Stop hook #%d added.\n", new_stop_hook->GetID());
3280 out_stream->Flush();
3281 }
Jim Inghamd60d94a2011-03-11 03:53:59 +00003282 break;
3283 }
3284
3285 return bytes_len;
3286 }
3287
3288 bool
3289 Execute (Args& command,
3290 CommandReturnObject &result)
3291 {
3292 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3293 if (target)
3294 {
3295 Target::StopHookSP new_hook_sp;
3296 target->AddStopHook (new_hook_sp);
3297
3298 // First step, make the specifier.
3299 std::auto_ptr<SymbolContextSpecifier> specifier_ap;
3300 if (m_options.m_sym_ctx_specified)
3301 {
3302 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
3303
3304 if (!m_options.m_module_name.empty())
3305 {
3306 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
3307 }
3308
3309 if (!m_options.m_class_name.empty())
3310 {
3311 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
3312 }
3313
3314 if (!m_options.m_file_name.empty())
3315 {
3316 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
3317 }
3318
3319 if (m_options.m_line_start != 0)
3320 {
3321 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
3322 }
3323
3324 if (m_options.m_line_end != UINT_MAX)
3325 {
3326 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
3327 }
3328
3329 if (!m_options.m_function_name.empty())
3330 {
3331 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
3332 }
3333 }
3334
3335 if (specifier_ap.get())
3336 new_hook_sp->SetSpecifier (specifier_ap.release());
3337
3338 // Next see if any of the thread options have been entered:
3339
3340 if (m_options.m_thread_specified)
3341 {
3342 ThreadSpec *thread_spec = new ThreadSpec();
3343
3344 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
3345 {
3346 thread_spec->SetTID (m_options.m_thread_id);
3347 }
3348
3349 if (m_options.m_thread_index != UINT32_MAX)
3350 thread_spec->SetIndex (m_options.m_thread_index);
3351
3352 if (!m_options.m_thread_name.empty())
3353 thread_spec->SetName (m_options.m_thread_name.c_str());
3354
3355 if (!m_options.m_queue_name.empty())
3356 thread_spec->SetQueueName (m_options.m_queue_name.c_str());
3357
3358 new_hook_sp->SetThreadSpecifier (thread_spec);
3359
3360 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00003361 if (m_options.m_use_one_liner)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003362 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00003363 // Use one-liner.
3364 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
Johnny Chen44953902011-05-03 00:06:12 +00003365 result.AppendMessageWithFormat("Stop hook #%d added.\n", new_hook_sp->GetID());
Jim Inghamd60d94a2011-03-11 03:53:59 +00003366 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00003367 else
Jim Inghamd60d94a2011-03-11 03:53:59 +00003368 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00003369 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into
3370 // the new stop hook's command string.
3371 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
3372 if (!reader_sp)
3373 {
3374 result.AppendError("out of memory\n");
3375 result.SetStatus (eReturnStatusFailed);
3376 target->RemoveStopHookByID (new_hook_sp->GetID());
3377 return false;
3378 }
3379
3380 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
3381 new_hook_sp.get(), // baton
3382 eInputReaderGranularityLine, // token size, to pass to callback function
3383 "DONE", // end token
3384 "> ", // prompt
3385 true)); // echo input
3386 if (!err.Success())
3387 {
3388 result.AppendError (err.AsCString());
3389 result.SetStatus (eReturnStatusFailed);
3390 target->RemoveStopHookByID (new_hook_sp->GetID());
3391 return false;
3392 }
3393 m_interpreter.GetDebugger().PushInputReader (reader_sp);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003394 }
Jim Inghamd60d94a2011-03-11 03:53:59 +00003395 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3396 }
3397 else
3398 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003399 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003400 result.SetStatus (eReturnStatusFailed);
3401 }
3402
3403 return result.Succeeded();
3404 }
3405private:
3406 CommandOptions m_options;
3407};
3408
Greg Claytonb3448432011-03-24 21:19:54 +00003409OptionDefinition
Jim Inghamd60d94a2011-03-11 03:53:59 +00003410CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
3411{
Johnny Chen60fe60e2011-05-02 23:47:55 +00003412 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, NULL, eArgTypeOneLiner,
3413 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
Jim Inghamd60d94a2011-03-11 03:53:59 +00003414 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3415 "Set the module within which the stop-hook is to be run."},
3416 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex,
3417 "The stop hook is run only for the thread whose index matches this argument."},
3418 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID,
3419 "The stop hook is run only for the thread whose TID matches this argument."},
3420 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName,
3421 "The stop hook is run only for the thread whose thread name matches this argument."},
3422 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName,
3423 "The stop hook is run only for threads in the queue whose name is given by this argument."},
3424 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
3425 "Specify the source file within which the stop-hook is to be run." },
3426 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
3427 "Set the start of the line range for which the stop-hook is to be run."},
3428 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum,
3429 "Set the end of the line range for which the stop-hook is to be run."},
3430 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName,
3431 "Specify the class within which the stop-hook is to be run." },
3432 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
3433 "Set the function name within which the stop hook will be run." },
3434 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3435};
3436
3437#pragma mark CommandObjectTargetStopHookDelete
3438
3439//-------------------------------------------------------------------------
3440// CommandObjectTargetStopHookDelete
3441//-------------------------------------------------------------------------
3442
3443class CommandObjectTargetStopHookDelete : public CommandObject
3444{
3445public:
3446
3447 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
3448 CommandObject (interpreter,
3449 "target stop-hook delete [<id>]",
3450 "Delete a stop-hook.",
3451 "target stop-hook delete")
3452 {
3453 }
3454
3455 ~CommandObjectTargetStopHookDelete ()
3456 {
3457 }
3458
3459 bool
3460 Execute (Args& command,
3461 CommandReturnObject &result)
3462 {
3463 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3464 if (target)
3465 {
3466 // FIXME: see if we can use the breakpoint id style parser?
3467 size_t num_args = command.GetArgumentCount();
3468 if (num_args == 0)
3469 {
3470 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
3471 {
3472 result.SetStatus (eReturnStatusFailed);
3473 return false;
3474 }
3475 else
3476 {
3477 target->RemoveAllStopHooks();
3478 }
3479 }
3480 else
3481 {
3482 bool success;
3483 for (size_t i = 0; i < num_args; i++)
3484 {
3485 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
3486 if (!success)
3487 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003488 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003489 result.SetStatus(eReturnStatusFailed);
3490 return false;
3491 }
3492 success = target->RemoveStopHookByID (user_id);
3493 if (!success)
3494 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003495 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003496 result.SetStatus(eReturnStatusFailed);
3497 return false;
3498 }
3499 }
3500 }
3501 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3502 }
3503 else
3504 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003505 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003506 result.SetStatus (eReturnStatusFailed);
3507 }
3508
3509 return result.Succeeded();
3510 }
3511};
3512#pragma mark CommandObjectTargetStopHookEnableDisable
3513
3514//-------------------------------------------------------------------------
3515// CommandObjectTargetStopHookEnableDisable
3516//-------------------------------------------------------------------------
3517
3518class CommandObjectTargetStopHookEnableDisable : public CommandObject
3519{
3520public:
3521
3522 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
3523 CommandObject (interpreter,
3524 name,
3525 help,
3526 syntax),
3527 m_enable (enable)
3528 {
3529 }
3530
3531 ~CommandObjectTargetStopHookEnableDisable ()
3532 {
3533 }
3534
3535 bool
3536 Execute (Args& command,
3537 CommandReturnObject &result)
3538 {
3539 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3540 if (target)
3541 {
3542 // FIXME: see if we can use the breakpoint id style parser?
3543 size_t num_args = command.GetArgumentCount();
3544 bool success;
3545
3546 if (num_args == 0)
3547 {
3548 target->SetAllStopHooksActiveState (m_enable);
3549 }
3550 else
3551 {
3552 for (size_t i = 0; i < num_args; i++)
3553 {
3554 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
3555 if (!success)
3556 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003557 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003558 result.SetStatus(eReturnStatusFailed);
3559 return false;
3560 }
3561 success = target->SetStopHookActiveStateByID (user_id, m_enable);
3562 if (!success)
3563 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003564 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003565 result.SetStatus(eReturnStatusFailed);
3566 return false;
3567 }
3568 }
3569 }
3570 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3571 }
3572 else
3573 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003574 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003575 result.SetStatus (eReturnStatusFailed);
3576 }
3577 return result.Succeeded();
3578 }
3579private:
3580 bool m_enable;
3581};
3582
3583#pragma mark CommandObjectTargetStopHookList
3584
3585//-------------------------------------------------------------------------
3586// CommandObjectTargetStopHookList
3587//-------------------------------------------------------------------------
3588
3589class CommandObjectTargetStopHookList : public CommandObject
3590{
3591public:
3592
3593 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
3594 CommandObject (interpreter,
3595 "target stop-hook list [<type>]",
3596 "List all stop-hooks.",
3597 "target stop-hook list")
3598 {
3599 }
3600
3601 ~CommandObjectTargetStopHookList ()
3602 {
3603 }
3604
3605 bool
3606 Execute (Args& command,
3607 CommandReturnObject &result)
3608 {
3609 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3610 if (target)
3611 {
3612 bool notify = true;
3613 target->GetImageSearchPathList().Clear(notify);
3614 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3615 }
3616 else
3617 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003618 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003619 result.SetStatus (eReturnStatusFailed);
3620 }
3621
3622 size_t num_hooks = target->GetNumStopHooks ();
3623 if (num_hooks == 0)
3624 {
3625 result.GetOutputStream().PutCString ("No stop hooks.\n");
3626 }
3627 else
3628 {
3629 for (size_t i = 0; i < num_hooks; i++)
3630 {
3631 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
3632 if (i > 0)
3633 result.GetOutputStream().PutCString ("\n");
3634 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
3635 }
3636 }
3637 return result.Succeeded();
3638 }
3639};
3640
3641#pragma mark CommandObjectMultiwordTargetStopHooks
3642//-------------------------------------------------------------------------
3643// CommandObjectMultiwordTargetStopHooks
3644//-------------------------------------------------------------------------
3645
3646class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
3647{
3648public:
3649
3650 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
3651 CommandObjectMultiword (interpreter,
3652 "target stop-hook",
3653 "A set of commands for operating on debugger target stop-hooks.",
3654 "target stop-hook <subcommand> [<subcommand-options>]")
3655 {
3656 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
3657 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
3658 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
3659 false,
3660 "target stop-hook disable [<id>]",
3661 "Disable a stop-hook.",
3662 "target stop-hook disable")));
3663 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
3664 true,
3665 "target stop-hook enable [<id>]",
3666 "Enable a stop-hook.",
3667 "target stop-hook enable")));
3668 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
3669 }
3670
3671 ~CommandObjectMultiwordTargetStopHooks()
3672 {
3673 }
3674};
3675
3676
Chris Lattner24943d22010-06-08 16:52:24 +00003677
3678#pragma mark CommandObjectMultiwordTarget
3679
3680//-------------------------------------------------------------------------
3681// CommandObjectMultiwordTarget
3682//-------------------------------------------------------------------------
3683
Greg Clayton63094e02010-06-23 01:19:29 +00003684CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00003685 CommandObjectMultiword (interpreter,
3686 "target",
Chris Lattner24943d22010-06-08 16:52:24 +00003687 "A set of commands for operating on debugger targets.",
3688 "target <subcommand> [<subcommand-options>]")
3689{
Greg Claytonabe0fed2011-04-18 08:33:37 +00003690
3691 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
3692 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter)));
3693 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003694 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
Greg Claytone1f50b92011-05-03 22:09:39 +00003695 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter)));
Greg Clayton801417e2011-07-07 01:59:51 +00003696 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00003697}
3698
3699CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
3700{
3701}
3702
Greg Claytonabe0fed2011-04-18 08:33:37 +00003703