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