blob: 6ea4486b24c83f0e80581b56cdb3eb28b197b7a4 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- CommandObjectTarget.cpp ---------------------------------*- C++ -*-===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#include "CommandObjectTarget.h"
11
12// C Includes
13#include <errno.h>
Greg Clayton81040f42011-02-01 01:13:32 +000014
Chris Lattner24943d22010-06-08 16:52:24 +000015// C++ Includes
16// Other libraries and framework includes
17// Project includes
Jim Ingham84cdc152010-06-15 19:49:27 +000018#include "lldb/Interpreter/Args.h"
Chris Lattner24943d22010-06-08 16:52:24 +000019#include "lldb/Core/Debugger.h"
Jim Inghamd60d94a2011-03-11 03:53:59 +000020#include "lldb/Core/InputReader.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000021#include "lldb/Core/Section.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000022#include "lldb/Core/State.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Core/Timer.h"
Greg Clayton801417e2011-07-07 01:59:51 +000024#include "lldb/Core/ValueObjectVariable.h"
Chris Lattner24943d22010-06-08 16:52:24 +000025#include "lldb/Interpreter/CommandInterpreter.h"
26#include "lldb/Interpreter/CommandReturnObject.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000027#include "lldb/Interpreter/Options.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000028#include "lldb/Interpreter/OptionGroupArchitecture.h"
Greg Clayton5beb99d2011-08-11 02:48:45 +000029#include "lldb/Interpreter/OptionGroupBoolean.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000030#include "lldb/Interpreter/OptionGroupFile.h"
Greg Claytona42880a2011-10-25 06:44:01 +000031#include "lldb/Interpreter/OptionGroupFormat.h"
Greg Clayton368f8222011-07-07 04:38:25 +000032#include "lldb/Interpreter/OptionGroupVariable.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000033#include "lldb/Interpreter/OptionGroupPlatform.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000034#include "lldb/Interpreter/OptionGroupUInt64.h"
35#include "lldb/Interpreter/OptionGroupUUID.h"
Greg Clayton801417e2011-07-07 01:59:51 +000036#include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
Greg Claytone1f50b92011-05-03 22:09:39 +000037#include "lldb/Symbol/LineTable.h"
38#include "lldb/Symbol/ObjectFile.h"
39#include "lldb/Symbol/SymbolFile.h"
40#include "lldb/Symbol/SymbolVendor.h"
Greg Clayton801417e2011-07-07 01:59:51 +000041#include "lldb/Symbol/VariableList.h"
Chris Lattner24943d22010-06-08 16:52:24 +000042#include "lldb/Target/Process.h"
43#include "lldb/Target/StackFrame.h"
44#include "lldb/Target/Thread.h"
Jim Inghamd60d94a2011-03-11 03:53:59 +000045#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000046
47using namespace lldb;
48using namespace lldb_private;
49
Greg Claytonabe0fed2011-04-18 08:33:37 +000050
51
52static void
53DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
54{
Greg Clayton52c8b6e2011-04-19 04:19:37 +000055 const ArchSpec &target_arch = target->GetArchitecture();
Greg Claytonabe0fed2011-04-18 08:33:37 +000056
Greg Clayton5beb99d2011-08-11 02:48:45 +000057 Module *exe_module = target->GetExecutableModulePointer();
Greg Claytonabe0fed2011-04-18 08:33:37 +000058 char exe_path[PATH_MAX];
59 bool exe_valid = false;
Greg Clayton5beb99d2011-08-11 02:48:45 +000060 if (exe_module)
61 exe_valid = exe_module->GetFileSpec().GetPath (exe_path, sizeof(exe_path));
Greg Claytonabe0fed2011-04-18 08:33:37 +000062
63 if (!exe_valid)
64 ::strcpy (exe_path, "<none>");
65
66 strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path);
67
68 uint32_t properties = 0;
69 if (target_arch.IsValid())
70 {
71 strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str());
72 properties++;
73 }
74 PlatformSP platform_sp (target->GetPlatform());
75 if (platform_sp)
76 strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName());
77
78 ProcessSP process_sp (target->GetProcessSP());
79 bool show_process_status = false;
80 if (process_sp)
81 {
82 lldb::pid_t pid = process_sp->GetID();
83 StateType state = process_sp->GetState();
84 if (show_stopped_process_status)
Greg Clayton20206082011-11-17 01:23:07 +000085 show_process_status = StateIsStoppedState(state, true);
Greg Claytonabe0fed2011-04-18 08:33:37 +000086 const char *state_cstr = StateAsCString (state);
87 if (pid != LLDB_INVALID_PROCESS_ID)
Greg Claytond9919d32011-12-01 23:28:38 +000088 strm.Printf ("%spid=%llu", properties++ > 0 ? ", " : " ( ", pid);
Greg Claytonabe0fed2011-04-18 08:33:37 +000089 strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
90 }
91 if (properties > 0)
92 strm.PutCString (" )\n");
93 else
94 strm.EOL();
95 if (show_process_status)
96 {
97 const bool only_threads_with_stop_reason = true;
98 const uint32_t start_frame = 0;
99 const uint32_t num_frames = 1;
100 const uint32_t num_frames_with_source = 1;
101 process_sp->GetStatus (strm);
102 process_sp->GetThreadStatus (strm,
103 only_threads_with_stop_reason,
104 start_frame,
105 num_frames,
106 num_frames_with_source);
107
108 }
109}
110
111static uint32_t
112DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm)
113{
114 const uint32_t num_targets = target_list.GetNumTargets();
115 if (num_targets)
116 {
117 TargetSP selected_target_sp (target_list.GetSelectedTarget());
118 strm.PutCString ("Current targets:\n");
119 for (uint32_t i=0; i<num_targets; ++i)
120 {
121 TargetSP target_sp (target_list.GetTargetAtIndex (i));
122 if (target_sp)
123 {
124 bool is_selected = target_sp.get() == selected_target_sp.get();
125 DumpTargetInfo (i,
126 target_sp.get(),
127 is_selected ? "* " : " ",
128 show_stopped_process_status,
129 strm);
130 }
131 }
132 }
133 return num_targets;
134}
135#pragma mark CommandObjectTargetCreate
136
137//-------------------------------------------------------------------------
138// "target create"
139//-------------------------------------------------------------------------
140
141class CommandObjectTargetCreate : public CommandObject
142{
143public:
144 CommandObjectTargetCreate(CommandInterpreter &interpreter) :
145 CommandObject (interpreter,
146 "target create",
147 "Create a target using the argument as the main executable.",
148 NULL),
149 m_option_group (interpreter),
Greg Clayton801417e2011-07-07 01:59:51 +0000150 m_arch_option (),
Greg Clayton46c9a352012-02-09 06:16:32 +0000151 m_platform_options(true), // Do include the "--platform" option in the platform settings by passing true
152 m_core_file (LLDB_OPT_SET_1, false, "core-file", 'c', 0, eArgTypePath, "Fullpath to a core file to use for this target.")
Greg Claytonabe0fed2011-04-18 08:33:37 +0000153 {
154 CommandArgumentEntry arg;
155 CommandArgumentData file_arg;
156
157 // Define the first (and only) variant of this arg.
158 file_arg.arg_type = eArgTypeFilename;
159 file_arg.arg_repetition = eArgRepeatPlain;
160
161 // There is only one variant this argument could be; put it into the argument entry.
162 arg.push_back (file_arg);
163
164 // Push the data for the first argument into the m_arguments vector.
165 m_arguments.push_back (arg);
166
Greg Clayton801417e2011-07-07 01:59:51 +0000167 m_option_group.Append (&m_arch_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000168 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Clayton46c9a352012-02-09 06:16:32 +0000169 m_option_group.Append (&m_core_file, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000170 m_option_group.Finalize();
171 }
172
173 ~CommandObjectTargetCreate ()
174 {
175 }
176
177 Options *
178 GetOptions ()
179 {
180 return &m_option_group;
181 }
182
183 bool
184 Execute (Args& command, CommandReturnObject &result)
185 {
186 const int argc = command.GetArgumentCount();
Greg Clayton46c9a352012-02-09 06:16:32 +0000187 FileSpec core_file (m_core_file.GetOptionValue().GetCurrentValue());
188
189 if (argc == 1 || core_file)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000190 {
191 const char *file_path = command.GetArgumentAtIndex(0);
192 Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path);
Greg Clayton46c9a352012-02-09 06:16:32 +0000193 FileSpec file_spec;
194
195 if (file_path)
196 file_spec.SetFile (file_path, true);
Greg Clayton3e8c25f2011-09-24 00:52:29 +0000197
Greg Claytonabe0fed2011-04-18 08:33:37 +0000198 TargetSP target_sp;
199 Debugger &debugger = m_interpreter.GetDebugger();
Greg Clayton3e8c25f2011-09-24 00:52:29 +0000200 const char *arch_cstr = m_arch_option.GetArchitectureName();
201 const bool get_dependent_files = true;
202 Error error (debugger.GetTargetList().CreateTarget (debugger,
203 file_spec,
204 arch_cstr,
205 get_dependent_files,
206 &m_platform_options,
207 target_sp));
208
Greg Claytonabe0fed2011-04-18 08:33:37 +0000209 if (target_sp)
210 {
211 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
Greg Clayton46c9a352012-02-09 06:16:32 +0000212 if (core_file)
213 {
214 ProcessSP process_sp (target_sp->CreateProcess (m_interpreter.GetDebugger().GetListener(), NULL, &core_file));
215 char core_path[PATH_MAX];
216 core_file.GetPath(core_path, sizeof(core_path));
217
218 if (process_sp)
219 {
220 // Seems wierd that we Launch a core file, but that is
221 // what we do!
222 error = process_sp->LoadCore();
223
224 if (error.Fail())
225 {
226 result.AppendError(error.AsCString("can't find plug-in for core file"));
227 result.SetStatus (eReturnStatusFailed);
228 return false;
229 }
230 else
231 {
232 result.AppendMessageWithFormat ("Core file '%s' (%s) was loaded.\n", core_path, target_sp->GetArchitecture().GetArchitectureName());
233 result.SetStatus (eReturnStatusSuccessFinishNoResult);
234 }
235 }
236 else
237 {
238 result.AppendErrorWithFormat ("Unable to find process plug-in for core file '%s'\n", core_path);
239 result.SetStatus (eReturnStatusFailed);
240 }
241 }
242 else
243 {
244 result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName());
245 result.SetStatus (eReturnStatusSuccessFinishNoResult);
246 }
Greg Claytonabe0fed2011-04-18 08:33:37 +0000247 }
248 else
249 {
250 result.AppendError(error.AsCString());
251 result.SetStatus (eReturnStatusFailed);
252 }
253 }
254 else
255 {
Greg Clayton46c9a352012-02-09 06:16:32 +0000256 result.AppendErrorWithFormat("'%s' takes exactly one executable path argument, or use the --core-file option.\n", m_cmd_name.c_str());
Greg Claytonabe0fed2011-04-18 08:33:37 +0000257 result.SetStatus (eReturnStatusFailed);
258 }
259 return result.Succeeded();
260
261 }
262
263 int
264 HandleArgumentCompletion (Args &input,
265 int &cursor_index,
266 int &cursor_char_position,
267 OptionElementVector &opt_element_vector,
268 int match_start_point,
269 int max_return_elements,
270 bool &word_complete,
271 StringList &matches)
272 {
273 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
274 completion_str.erase (cursor_char_position);
275
276 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
277 CommandCompletions::eDiskFileCompletion,
278 completion_str.c_str(),
279 match_start_point,
280 max_return_elements,
281 NULL,
282 word_complete,
283 matches);
284 return matches.GetSize();
285 }
286private:
287 OptionGroupOptions m_option_group;
Greg Clayton801417e2011-07-07 01:59:51 +0000288 OptionGroupArchitecture m_arch_option;
Greg Claytonabe0fed2011-04-18 08:33:37 +0000289 OptionGroupPlatform m_platform_options;
Greg Clayton46c9a352012-02-09 06:16:32 +0000290 OptionGroupFile m_core_file;
Greg Claytonabe0fed2011-04-18 08:33:37 +0000291
292};
293
294#pragma mark CommandObjectTargetList
295
296//----------------------------------------------------------------------
297// "target list"
298//----------------------------------------------------------------------
299
300class CommandObjectTargetList : public CommandObject
301{
302public:
303 CommandObjectTargetList (CommandInterpreter &interpreter) :
304 CommandObject (interpreter,
305 "target list",
306 "List all current targets in the current debug session.",
307 NULL,
308 0)
309 {
310 }
311
312 virtual
313 ~CommandObjectTargetList ()
314 {
315 }
316
317 virtual bool
318 Execute (Args& args, CommandReturnObject &result)
319 {
320 if (args.GetArgumentCount() == 0)
321 {
322 Stream &strm = result.GetOutputStream();
323
324 bool show_stopped_process_status = false;
325 if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0)
326 {
327 strm.PutCString ("No targets.\n");
328 }
Johnny Chen44dc9d32011-04-18 21:08:05 +0000329 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000330 }
331 else
332 {
333 result.AppendError ("the 'target list' command takes no arguments\n");
334 result.SetStatus (eReturnStatusFailed);
335 }
336 return result.Succeeded();
337 }
338};
339
340
341#pragma mark CommandObjectTargetSelect
342
343//----------------------------------------------------------------------
344// "target select"
345//----------------------------------------------------------------------
346
347class CommandObjectTargetSelect : public CommandObject
348{
349public:
350 CommandObjectTargetSelect (CommandInterpreter &interpreter) :
351 CommandObject (interpreter,
352 "target select",
353 "Select a target as the current target by target index.",
354 NULL,
355 0)
356 {
357 }
358
359 virtual
360 ~CommandObjectTargetSelect ()
361 {
362 }
363
364 virtual bool
365 Execute (Args& args, CommandReturnObject &result)
366 {
367 if (args.GetArgumentCount() == 1)
368 {
369 bool success = false;
370 const char *target_idx_arg = args.GetArgumentAtIndex(0);
371 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
372 if (success)
373 {
374 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
375 const uint32_t num_targets = target_list.GetNumTargets();
376 if (target_idx < num_targets)
377 {
378 TargetSP target_sp (target_list.GetTargetAtIndex (target_idx));
379 if (target_sp)
380 {
381 Stream &strm = result.GetOutputStream();
382 target_list.SetSelectedTarget (target_sp.get());
383 bool show_stopped_process_status = false;
384 DumpTargetList (target_list, show_stopped_process_status, strm);
Johnny Chen44dc9d32011-04-18 21:08:05 +0000385 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000386 }
387 else
388 {
389 result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx);
390 result.SetStatus (eReturnStatusFailed);
391 }
392 }
393 else
394 {
395 result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n",
396 target_idx,
397 num_targets - 1);
398 result.SetStatus (eReturnStatusFailed);
399 }
400 }
401 else
402 {
403 result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg);
404 result.SetStatus (eReturnStatusFailed);
405 }
406 }
407 else
408 {
409 result.AppendError ("'target select' takes a single argument: a target index\n");
410 result.SetStatus (eReturnStatusFailed);
411 }
412 return result.Succeeded();
413 }
414};
415
Greg Clayton153ccd72011-08-10 02:10:13 +0000416#pragma mark CommandObjectTargetSelect
417
418//----------------------------------------------------------------------
419// "target delete"
420//----------------------------------------------------------------------
421
422class CommandObjectTargetDelete : public CommandObject
423{
424public:
425 CommandObjectTargetDelete (CommandInterpreter &interpreter) :
Greg Clayton5beb99d2011-08-11 02:48:45 +0000426 CommandObject (interpreter,
427 "target delete",
428 "Delete one or more targets by target index.",
429 NULL,
430 0),
431 m_option_group (interpreter),
432 m_cleanup_option (LLDB_OPT_SET_1, false, "clean", 'c', 0, eArgTypeNone, "Perform extra cleanup to minimize memory consumption after deleting the target.", false)
Greg Clayton153ccd72011-08-10 02:10:13 +0000433 {
Greg Clayton5beb99d2011-08-11 02:48:45 +0000434 m_option_group.Append (&m_cleanup_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
435 m_option_group.Finalize();
Greg Clayton153ccd72011-08-10 02:10:13 +0000436 }
437
438 virtual
439 ~CommandObjectTargetDelete ()
440 {
441 }
442
443 virtual bool
444 Execute (Args& args, CommandReturnObject &result)
445 {
446 const size_t argc = args.GetArgumentCount();
447 std::vector<TargetSP> delete_target_list;
448 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
449 bool success = true;
450 TargetSP target_sp;
451 if (argc > 0)
452 {
453 const uint32_t num_targets = target_list.GetNumTargets();
454 for (uint32_t arg_idx = 0; success && arg_idx < argc; ++arg_idx)
455 {
456 const char *target_idx_arg = args.GetArgumentAtIndex(arg_idx);
457 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
458 if (success)
459 {
460 if (target_idx < num_targets)
461 {
462 target_sp = target_list.GetTargetAtIndex (target_idx);
463 if (target_sp)
464 {
465 delete_target_list.push_back (target_sp);
466 continue;
467 }
468 }
469 result.AppendErrorWithFormat ("target index %u is out of range, valid target indexes are 0 - %u\n",
470 target_idx,
471 num_targets - 1);
472 result.SetStatus (eReturnStatusFailed);
473 success = false;
474 }
475 else
476 {
477 result.AppendErrorWithFormat("invalid target index '%s'\n", target_idx_arg);
478 result.SetStatus (eReturnStatusFailed);
479 success = false;
480 }
481 }
482
483 }
484 else
485 {
486 target_sp = target_list.GetSelectedTarget();
487 if (target_sp)
488 {
489 delete_target_list.push_back (target_sp);
490 }
491 else
492 {
493 result.AppendErrorWithFormat("no target is currently selected\n");
494 result.SetStatus (eReturnStatusFailed);
495 success = false;
496 }
497 }
498 if (success)
499 {
500 const size_t num_targets_to_delete = delete_target_list.size();
501 for (size_t idx = 0; idx < num_targets_to_delete; ++idx)
502 {
503 target_sp = delete_target_list[idx];
504 target_list.DeleteTarget(target_sp);
505 target_sp->Destroy();
506 }
Greg Clayton5beb99d2011-08-11 02:48:45 +0000507 // If "--clean" was specified, prune any orphaned shared modules from
508 // the global shared module list
509 if (m_cleanup_option.GetOptionValue ())
510 {
511 ModuleList::RemoveOrphanSharedModules();
512 }
Greg Clayton153ccd72011-08-10 02:10:13 +0000513 result.GetOutputStream().Printf("%u targets deleted.\n", (uint32_t)num_targets_to_delete);
514 result.SetStatus(eReturnStatusSuccessFinishResult);
515 }
516
517 return result.Succeeded();
518 }
Greg Clayton5beb99d2011-08-11 02:48:45 +0000519
520 Options *
521 GetOptions ()
522 {
523 return &m_option_group;
524 }
525
526protected:
527 OptionGroupOptions m_option_group;
528 OptionGroupBoolean m_cleanup_option;
Greg Clayton153ccd72011-08-10 02:10:13 +0000529};
530
Greg Claytonabe0fed2011-04-18 08:33:37 +0000531
Greg Clayton801417e2011-07-07 01:59:51 +0000532#pragma mark CommandObjectTargetVariable
533
534//----------------------------------------------------------------------
535// "target variable"
536//----------------------------------------------------------------------
537
538class CommandObjectTargetVariable : public CommandObject
539{
540public:
541 CommandObjectTargetVariable (CommandInterpreter &interpreter) :
542 CommandObject (interpreter,
Johnny Chen34bfa4f2011-07-12 22:34:30 +0000543 "target variable",
544 "Read global variable(s) prior to running your binary.",
Greg Clayton801417e2011-07-07 01:59:51 +0000545 NULL,
546 0),
547 m_option_group (interpreter),
Greg Clayton368f8222011-07-07 04:38:25 +0000548 m_option_variable (false), // Don't include frame options
Greg Claytona42880a2011-10-25 06:44:01 +0000549 m_option_format (eFormatDefault),
Greg Clayton801417e2011-07-07 01:59:51 +0000550 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."),
551 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."),
552 m_varobj_options()
553 {
Johnny Chen24b81e32011-08-22 22:22:00 +0000554 CommandArgumentEntry arg;
555 CommandArgumentData var_name_arg;
556
557 // Define the first (and only) variant of this arg.
558 var_name_arg.arg_type = eArgTypeVarName;
559 var_name_arg.arg_repetition = eArgRepeatPlus;
560
561 // There is only one variant this argument could be; put it into the argument entry.
562 arg.push_back (var_name_arg);
563
564 // Push the data for the first argument into the m_arguments vector.
565 m_arguments.push_back (arg);
566
Greg Clayton801417e2011-07-07 01:59:51 +0000567 m_option_group.Append (&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Clayton368f8222011-07-07 04:38:25 +0000568 m_option_group.Append (&m_option_variable, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
Greg Clayton24a6bd92011-10-27 17:55:14 +0000569 m_option_group.Append (&m_option_format, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_1);
Greg Clayton801417e2011-07-07 01:59:51 +0000570 m_option_group.Append (&m_option_compile_units, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
571 m_option_group.Append (&m_option_shared_libraries, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
572 m_option_group.Finalize();
573 }
574
575 virtual
576 ~CommandObjectTargetVariable ()
577 {
578 }
Greg Clayton5d81f492011-07-08 21:46:14 +0000579
580 void
581 DumpValueObject (Stream &s, VariableSP &var_sp, ValueObjectSP &valobj_sp, const char *root_name)
582 {
Enrico Granata19030d82011-08-15 18:01:31 +0000583 ValueObject::DumpValueObjectOptions options;
584
585 options.SetPointerDepth(m_varobj_options.ptr_depth)
586 .SetMaximumDepth(m_varobj_options.max_depth)
587 .SetShowTypes(m_varobj_options.show_types)
588 .SetShowLocation(m_varobj_options.show_location)
589 .SetUseObjectiveC(m_varobj_options.use_objc)
590 .SetUseDynamicType(m_varobj_options.use_dynamic)
591 .SetUseSyntheticValue((lldb::SyntheticValueType)m_varobj_options.use_synth)
592 .SetFlatOutput(m_varobj_options.flat_output)
593 .SetOmitSummaryDepth(m_varobj_options.no_summary_depth)
594 .SetIgnoreCap(m_varobj_options.ignore_cap);
595
Greg Clayton5d81f492011-07-08 21:46:14 +0000596 switch (var_sp->GetScope())
597 {
598 case eValueTypeVariableGlobal:
599 if (m_option_variable.show_scope)
600 s.PutCString("GLOBAL: ");
601 break;
602
603 case eValueTypeVariableStatic:
604 if (m_option_variable.show_scope)
605 s.PutCString("STATIC: ");
606 break;
607
608 case eValueTypeVariableArgument:
609 if (m_option_variable.show_scope)
610 s.PutCString(" ARG: ");
611 break;
612
613 case eValueTypeVariableLocal:
614 if (m_option_variable.show_scope)
615 s.PutCString(" LOCAL: ");
616 break;
617
618 default:
619 break;
620 }
621
Greg Claytonfb816422011-07-10 19:21:23 +0000622 if (m_option_variable.show_decl)
Greg Clayton5d81f492011-07-08 21:46:14 +0000623 {
Greg Claytonfb816422011-07-10 19:21:23 +0000624 bool show_fullpaths = false;
625 bool show_module = true;
626 if (var_sp->DumpDeclaration(&s, show_fullpaths, show_module))
627 s.PutCString (": ");
Greg Clayton5d81f492011-07-08 21:46:14 +0000628 }
629
Greg Claytona42880a2011-10-25 06:44:01 +0000630 const Format format = m_option_format.GetFormat();
Greg Clayton5d81f492011-07-08 21:46:14 +0000631 if (format != eFormatDefault)
632 valobj_sp->SetFormat (format);
633
634 ValueObject::DumpValueObject (s,
635 valobj_sp.get(),
636 root_name,
Greg Claytonccf44502012-01-26 21:08:30 +0000637 options,
638 format);
Greg Clayton5d81f492011-07-08 21:46:14 +0000639
640 }
Greg Clayton801417e2011-07-07 01:59:51 +0000641
Greg Clayton5d81f492011-07-08 21:46:14 +0000642
643 static uint32_t GetVariableCallback (void *baton,
644 const char *name,
645 VariableList &variable_list)
646 {
647 Target *target = static_cast<Target *>(baton);
648 if (target)
649 {
650 return target->GetImages().FindGlobalVariables (ConstString(name),
651 true,
652 UINT32_MAX,
653 variable_list);
654 }
655 return 0;
656 }
657
658
659
Greg Clayton801417e2011-07-07 01:59:51 +0000660 virtual bool
661 Execute (Args& args, CommandReturnObject &result)
662 {
663 ExecutionContext exe_ctx (m_interpreter.GetExecutionContext());
Greg Clayton567e7f32011-09-22 04:58:26 +0000664 Target *target = exe_ctx.GetTargetPtr();
665 if (target)
Greg Clayton801417e2011-07-07 01:59:51 +0000666 {
667 const size_t argc = args.GetArgumentCount();
Greg Claytonfac93882011-10-05 22:17:32 +0000668 Stream &s = result.GetOutputStream();
Greg Clayton801417e2011-07-07 01:59:51 +0000669 if (argc > 0)
670 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000671
Greg Clayton801417e2011-07-07 01:59:51 +0000672 for (size_t idx = 0; idx < argc; ++idx)
673 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000674 VariableList variable_list;
675 ValueObjectList valobj_list;
676
Greg Clayton368f8222011-07-07 04:38:25 +0000677 const char *arg = args.GetArgumentAtIndex(idx);
678 uint32_t matches = 0;
Greg Claytonfb816422011-07-10 19:21:23 +0000679 bool use_var_name = false;
Greg Clayton368f8222011-07-07 04:38:25 +0000680 if (m_option_variable.use_regex)
Greg Clayton801417e2011-07-07 01:59:51 +0000681 {
Greg Clayton368f8222011-07-07 04:38:25 +0000682 RegularExpression regex(arg);
683 if (!regex.IsValid ())
684 {
685 result.GetErrorStream().Printf ("error: invalid regular expression: '%s'\n", arg);
686 result.SetStatus (eReturnStatusFailed);
687 return false;
688 }
Greg Claytonfb816422011-07-10 19:21:23 +0000689 use_var_name = true;
Greg Clayton567e7f32011-09-22 04:58:26 +0000690 matches = target->GetImages().FindGlobalVariables (regex,
691 true,
692 UINT32_MAX,
693 variable_list);
Greg Clayton801417e2011-07-07 01:59:51 +0000694 }
695 else
696 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000697 Error error (Variable::GetValuesForVariableExpressionPath (arg,
Greg Clayton24b03102011-07-09 20:12:33 +0000698 exe_ctx.GetBestExecutionContextScope(),
Greg Clayton5d81f492011-07-08 21:46:14 +0000699 GetVariableCallback,
Greg Clayton567e7f32011-09-22 04:58:26 +0000700 target,
Greg Clayton5d81f492011-07-08 21:46:14 +0000701 variable_list,
702 valobj_list));
Greg Clayton5d81f492011-07-08 21:46:14 +0000703 matches = variable_list.GetSize();
Greg Clayton368f8222011-07-07 04:38:25 +0000704 }
705
706 if (matches == 0)
707 {
708 result.GetErrorStream().Printf ("error: can't find global variable '%s'\n", arg);
709 result.SetStatus (eReturnStatusFailed);
710 return false;
711 }
712 else
713 {
Greg Clayton801417e2011-07-07 01:59:51 +0000714 for (uint32_t global_idx=0; global_idx<matches; ++global_idx)
715 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000716 VariableSP var_sp (variable_list.GetVariableAtIndex(global_idx));
Greg Clayton801417e2011-07-07 01:59:51 +0000717 if (var_sp)
718 {
Greg Clayton5d81f492011-07-08 21:46:14 +0000719 ValueObjectSP valobj_sp (valobj_list.GetValueObjectAtIndex(global_idx));
720 if (!valobj_sp)
Greg Claytonfb816422011-07-10 19:21:23 +0000721 valobj_sp = ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp);
Greg Clayton801417e2011-07-07 01:59:51 +0000722
723 if (valobj_sp)
Greg Claytonb304a742011-10-13 18:31:02 +0000724 DumpValueObject (s, var_sp, valobj_sp, use_var_name ? var_sp->GetName().GetCString() : arg);
Greg Clayton801417e2011-07-07 01:59:51 +0000725 }
726 }
727 }
728 }
729 }
730 else
731 {
Greg Claytonfac93882011-10-05 22:17:32 +0000732 bool success = false;
733 StackFrame *frame = exe_ctx.GetFramePtr();
734 CompileUnit *comp_unit = NULL;
735 if (frame)
736 {
737 comp_unit = frame->GetSymbolContext (eSymbolContextCompUnit).comp_unit;
738 if (comp_unit)
739 {
740 const bool can_create = true;
741 VariableListSP comp_unit_varlist_sp (comp_unit->GetVariableList(can_create));
742 if (comp_unit_varlist_sp)
743 {
744 size_t count = comp_unit_varlist_sp->GetSize();
745 if (count > 0)
746 {
Greg Claytona1b9a902011-11-13 04:15:56 +0000747 s.Printf ("Global variables for %s/%s:\n",
Greg Claytonfac93882011-10-05 22:17:32 +0000748 comp_unit->GetDirectory().GetCString(),
749 comp_unit->GetFilename().GetCString());
750
751 success = true;
752 for (uint32_t i=0; i<count; ++i)
753 {
754 VariableSP var_sp (comp_unit_varlist_sp->GetVariableAtIndex(i));
755 if (var_sp)
756 {
757 ValueObjectSP valobj_sp (ValueObjectVariable::Create (exe_ctx.GetBestExecutionContextScope(), var_sp));
758
759 if (valobj_sp)
760 DumpValueObject (s, var_sp, valobj_sp, var_sp->GetName().GetCString());
761 }
762 }
763 }
764 }
765 }
766 }
767 if (!success)
768 {
769 if (frame)
770 {
771 if (comp_unit)
772 result.AppendErrorWithFormat ("no global variables in current compile unit: %s/%s\n",
773 comp_unit->GetDirectory().GetCString(),
774 comp_unit->GetFilename().GetCString());
775 else
776 result.AppendError ("no debug information for frame %u\n", frame->GetFrameIndex());
777 }
778 else
779 result.AppendError ("'target variable' takes one or more global variable names as arguments\n");
780 result.SetStatus (eReturnStatusFailed);
781 }
Greg Clayton801417e2011-07-07 01:59:51 +0000782 }
783 }
784 else
785 {
786 result.AppendError ("invalid target, create a debug target using the 'target create' command");
787 result.SetStatus (eReturnStatusFailed);
788 return false;
789 }
Enrico Granatadb64d952011-08-12 16:42:31 +0000790
791 if (m_interpreter.TruncationWarningNecessary())
792 {
793 result.GetOutputStream().Printf(m_interpreter.TruncationWarningText(),
794 m_cmd_name.c_str());
795 m_interpreter.TruncationWarningGiven();
796 }
797
Greg Clayton801417e2011-07-07 01:59:51 +0000798 return result.Succeeded();
799 }
800
801 Options *
802 GetOptions ()
803 {
804 return &m_option_group;
805 }
806
807protected:
808 OptionGroupOptions m_option_group;
Greg Clayton368f8222011-07-07 04:38:25 +0000809 OptionGroupVariable m_option_variable;
Greg Claytona42880a2011-10-25 06:44:01 +0000810 OptionGroupFormat m_option_format;
Greg Clayton801417e2011-07-07 01:59:51 +0000811 OptionGroupFileList m_option_compile_units;
812 OptionGroupFileList m_option_shared_libraries;
813 OptionGroupValueObjectDisplay m_varobj_options;
814
815};
816
817
Greg Claytone1f50b92011-05-03 22:09:39 +0000818#pragma mark CommandObjectTargetModulesSearchPathsAdd
Chris Lattner24943d22010-06-08 16:52:24 +0000819
Greg Claytone1f50b92011-05-03 22:09:39 +0000820class CommandObjectTargetModulesSearchPathsAdd : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000821{
822public:
823
Greg Claytone1f50b92011-05-03 22:09:39 +0000824 CommandObjectTargetModulesSearchPathsAdd (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000825 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000826 "target modules search-paths add",
Chris Lattner24943d22010-06-08 16:52:24 +0000827 "Add new image search paths substitution pairs to the current target.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000828 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000829 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000830 CommandArgumentEntry arg;
831 CommandArgumentData old_prefix_arg;
832 CommandArgumentData new_prefix_arg;
833
834 // Define the first variant of this arg pair.
835 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
836 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
837
838 // Define the first variant of this arg pair.
839 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
840 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
841
842 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
843 // must always occur together, they are treated as two variants of one argument rather than two independent
844 // arguments. Push them both into the first argument position for m_arguments...
845
846 arg.push_back (old_prefix_arg);
847 arg.push_back (new_prefix_arg);
848
849 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000850 }
851
Greg Claytone1f50b92011-05-03 22:09:39 +0000852 ~CommandObjectTargetModulesSearchPathsAdd ()
Chris Lattner24943d22010-06-08 16:52:24 +0000853 {
854 }
855
856 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000857 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000858 CommandReturnObject &result)
859 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000860 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000861 if (target)
862 {
863 uint32_t argc = command.GetArgumentCount();
864 if (argc & 1)
865 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000866 result.AppendError ("add requires an even number of arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000867 result.SetStatus (eReturnStatusFailed);
868 }
869 else
870 {
871 for (uint32_t i=0; i<argc; i+=2)
872 {
873 const char *from = command.GetArgumentAtIndex(i);
874 const char *to = command.GetArgumentAtIndex(i+1);
875
876 if (from[0] && to[0])
877 {
878 bool last_pair = ((argc - i) == 2);
Greg Clayton63094e02010-06-23 01:19:29 +0000879 target->GetImageSearchPathList().Append (ConstString(from),
880 ConstString(to),
881 last_pair); // Notify if this is the last pair
Johnny Chen4d661352011-02-03 00:30:19 +0000882 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000883 }
884 else
885 {
886 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +0000887 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000888 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000889 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000890 result.SetStatus (eReturnStatusFailed);
891 }
892 }
893 }
894 }
895 else
896 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000897 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000898 result.SetStatus (eReturnStatusFailed);
899 }
900 return result.Succeeded();
901 }
902};
903
Greg Claytone1f50b92011-05-03 22:09:39 +0000904#pragma mark CommandObjectTargetModulesSearchPathsClear
905
906class CommandObjectTargetModulesSearchPathsClear : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000907{
908public:
909
Greg Claytone1f50b92011-05-03 22:09:39 +0000910 CommandObjectTargetModulesSearchPathsClear (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000911 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000912 "target modules search-paths clear",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000913 "Clear all current image search path substitution pairs from the current target.",
Greg Claytone1f50b92011-05-03 22:09:39 +0000914 "target modules search-paths clear")
Chris Lattner24943d22010-06-08 16:52:24 +0000915 {
916 }
917
Greg Claytone1f50b92011-05-03 22:09:39 +0000918 ~CommandObjectTargetModulesSearchPathsClear ()
Chris Lattner24943d22010-06-08 16:52:24 +0000919 {
920 }
921
922 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000923 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000924 CommandReturnObject &result)
925 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000926 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000927 if (target)
928 {
929 bool notify = true;
930 target->GetImageSearchPathList().Clear(notify);
Johnny Chen4d661352011-02-03 00:30:19 +0000931 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000932 }
933 else
934 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000935 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000936 result.SetStatus (eReturnStatusFailed);
937 }
938 return result.Succeeded();
939 }
940};
941
Greg Claytone1f50b92011-05-03 22:09:39 +0000942#pragma mark CommandObjectTargetModulesSearchPathsInsert
943
944class CommandObjectTargetModulesSearchPathsInsert : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +0000945{
946public:
947
Greg Claytone1f50b92011-05-03 22:09:39 +0000948 CommandObjectTargetModulesSearchPathsInsert (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000949 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +0000950 "target modules search-paths insert",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000951 "Insert a new image search path substitution pair into the current target at the specified index.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000952 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000953 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000954 CommandArgumentEntry arg1;
955 CommandArgumentEntry arg2;
956 CommandArgumentData index_arg;
957 CommandArgumentData old_prefix_arg;
958 CommandArgumentData new_prefix_arg;
959
960 // Define the first and only variant of this arg.
961 index_arg.arg_type = eArgTypeIndex;
962 index_arg.arg_repetition = eArgRepeatPlain;
963
964 // Put the one and only variant into the first arg for m_arguments:
965 arg1.push_back (index_arg);
966
967 // Define the first variant of this arg pair.
968 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
969 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
970
971 // Define the first variant of this arg pair.
972 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
973 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
974
975 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
976 // must always occur together, they are treated as two variants of one argument rather than two independent
977 // arguments. Push them both into the same argument position for m_arguments...
978
979 arg2.push_back (old_prefix_arg);
980 arg2.push_back (new_prefix_arg);
981
982 // Add arguments to m_arguments.
983 m_arguments.push_back (arg1);
984 m_arguments.push_back (arg2);
Chris Lattner24943d22010-06-08 16:52:24 +0000985 }
986
Greg Claytone1f50b92011-05-03 22:09:39 +0000987 ~CommandObjectTargetModulesSearchPathsInsert ()
Chris Lattner24943d22010-06-08 16:52:24 +0000988 {
989 }
990
991 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000992 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000993 CommandReturnObject &result)
994 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000995 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000996 if (target)
997 {
998 uint32_t argc = command.GetArgumentCount();
999 // check for at least 3 arguments and an odd nubmer of parameters
1000 if (argc >= 3 && argc & 1)
1001 {
1002 bool success = false;
1003
1004 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
1005
1006 if (!success)
1007 {
1008 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
1009 result.SetStatus (eReturnStatusFailed);
1010 return result.Succeeded();
1011 }
1012
1013 // shift off the index
1014 command.Shift();
1015 argc = command.GetArgumentCount();
1016
1017 for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
1018 {
1019 const char *from = command.GetArgumentAtIndex(i);
1020 const char *to = command.GetArgumentAtIndex(i+1);
1021
1022 if (from[0] && to[0])
1023 {
1024 bool last_pair = ((argc - i) == 2);
1025 target->GetImageSearchPathList().Insert (ConstString(from),
1026 ConstString(to),
1027 insert_idx,
1028 last_pair);
Johnny Chen4d661352011-02-03 00:30:19 +00001029 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001030 }
1031 else
1032 {
1033 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +00001034 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001035 else
Greg Claytonabe0fed2011-04-18 08:33:37 +00001036 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001037 result.SetStatus (eReturnStatusFailed);
1038 return false;
1039 }
1040 }
1041 }
1042 else
1043 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001044 result.AppendError ("insert requires at least three arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001045 result.SetStatus (eReturnStatusFailed);
1046 return result.Succeeded();
1047 }
1048
1049 }
1050 else
1051 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001052 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001053 result.SetStatus (eReturnStatusFailed);
1054 }
1055 return result.Succeeded();
1056 }
1057};
1058
Greg Claytone1f50b92011-05-03 22:09:39 +00001059
1060#pragma mark CommandObjectTargetModulesSearchPathsList
1061
1062
1063class CommandObjectTargetModulesSearchPathsList : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +00001064{
1065public:
1066
Greg Claytone1f50b92011-05-03 22:09:39 +00001067 CommandObjectTargetModulesSearchPathsList (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001068 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +00001069 "target modules search-paths list",
Caroline Ticeabb507a2010-09-08 21:06:11 +00001070 "List all current image search path substitution pairs in the current target.",
Greg Claytone1f50b92011-05-03 22:09:39 +00001071 "target modules search-paths list")
Chris Lattner24943d22010-06-08 16:52:24 +00001072 {
1073 }
1074
Greg Claytone1f50b92011-05-03 22:09:39 +00001075 ~CommandObjectTargetModulesSearchPathsList ()
Chris Lattner24943d22010-06-08 16:52:24 +00001076 {
1077 }
1078
1079 bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001080 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001081 CommandReturnObject &result)
1082 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001083 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001084 if (target)
1085 {
1086 if (command.GetArgumentCount() != 0)
1087 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001088 result.AppendError ("list takes no arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001089 result.SetStatus (eReturnStatusFailed);
1090 return result.Succeeded();
1091 }
1092
1093 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
Johnny Chen4d661352011-02-03 00:30:19 +00001094 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001095 }
1096 else
1097 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001098 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001099 result.SetStatus (eReturnStatusFailed);
1100 }
1101 return result.Succeeded();
1102 }
1103};
1104
Greg Claytone1f50b92011-05-03 22:09:39 +00001105#pragma mark CommandObjectTargetModulesSearchPathsQuery
1106
1107class CommandObjectTargetModulesSearchPathsQuery : public CommandObject
Chris Lattner24943d22010-06-08 16:52:24 +00001108{
1109public:
1110
Greg Claytone1f50b92011-05-03 22:09:39 +00001111 CommandObjectTargetModulesSearchPathsQuery (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001112 CommandObject (interpreter,
Greg Claytone1f50b92011-05-03 22:09:39 +00001113 "target modules search-paths query",
Caroline Ticeabb507a2010-09-08 21:06:11 +00001114 "Transform a path using the first applicable image search path.",
Caroline Tice43b014a2010-10-04 22:28:36 +00001115 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +00001116 {
Caroline Tice43b014a2010-10-04 22:28:36 +00001117 CommandArgumentEntry arg;
1118 CommandArgumentData path_arg;
1119
1120 // Define the first (and only) variant of this arg.
1121 path_arg.arg_type = eArgTypePath;
1122 path_arg.arg_repetition = eArgRepeatPlain;
1123
1124 // There is only one variant this argument could be; put it into the argument entry.
1125 arg.push_back (path_arg);
1126
1127 // Push the data for the first argument into the m_arguments vector.
1128 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +00001129 }
1130
Greg Claytone1f50b92011-05-03 22:09:39 +00001131 ~CommandObjectTargetModulesSearchPathsQuery ()
Chris Lattner24943d22010-06-08 16:52:24 +00001132 {
1133 }
1134
1135 bool
Greg Clayton238c0a12010-09-18 01:14:36 +00001136 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +00001137 CommandReturnObject &result)
1138 {
Greg Clayton238c0a12010-09-18 01:14:36 +00001139 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +00001140 if (target)
1141 {
1142 if (command.GetArgumentCount() != 1)
1143 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001144 result.AppendError ("query requires one argument\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001145 result.SetStatus (eReturnStatusFailed);
1146 return result.Succeeded();
1147 }
1148
1149 ConstString orig(command.GetArgumentAtIndex(0));
1150 ConstString transformed;
1151 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
1152 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
1153 else
1154 result.GetOutputStream().Printf("%s\n", orig.GetCString());
Johnny Chen4d661352011-02-03 00:30:19 +00001155
1156 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +00001157 }
1158 else
1159 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001160 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +00001161 result.SetStatus (eReturnStatusFailed);
1162 }
1163 return result.Succeeded();
1164 }
1165};
1166
Greg Claytone1f50b92011-05-03 22:09:39 +00001167//----------------------------------------------------------------------
1168// Static Helper functions
1169//----------------------------------------------------------------------
1170static void
1171DumpModuleArchitecture (Stream &strm, Module *module, bool full_triple, uint32_t width)
1172{
1173 if (module)
1174 {
1175 const char *arch_cstr;
1176 if (full_triple)
1177 arch_cstr = module->GetArchitecture().GetTriple().str().c_str();
1178 else
1179 arch_cstr = module->GetArchitecture().GetArchitectureName();
1180 if (width)
1181 strm.Printf("%-*s", width, arch_cstr);
1182 else
1183 strm.PutCString(arch_cstr);
1184 }
1185}
1186
1187static void
1188DumpModuleUUID (Stream &strm, Module *module)
1189{
Greg Clayton153ccd72011-08-10 02:10:13 +00001190 if (module->GetUUID().IsValid())
1191 module->GetUUID().Dump (&strm);
1192 else
1193 strm.PutCString(" ");
Greg Claytone1f50b92011-05-03 22:09:39 +00001194}
1195
1196static uint32_t
1197DumpCompileUnitLineTable
1198(
1199 CommandInterpreter &interpreter,
1200 Stream &strm,
1201 Module *module,
1202 const FileSpec &file_spec,
1203 bool load_addresses
1204 )
1205{
1206 uint32_t num_matches = 0;
1207 if (module)
1208 {
1209 SymbolContextList sc_list;
1210 num_matches = module->ResolveSymbolContextsForFileSpec (file_spec,
1211 0,
1212 false,
1213 eSymbolContextCompUnit,
1214 sc_list);
1215
1216 for (uint32_t i=0; i<num_matches; ++i)
1217 {
1218 SymbolContext sc;
1219 if (sc_list.GetContextAtIndex(i, sc))
1220 {
1221 if (i > 0)
1222 strm << "\n\n";
1223
1224 strm << "Line table for " << *static_cast<FileSpec*> (sc.comp_unit) << " in `"
1225 << module->GetFileSpec().GetFilename() << "\n";
1226 LineTable *line_table = sc.comp_unit->GetLineTable();
1227 if (line_table)
1228 line_table->GetDescription (&strm,
Greg Clayton567e7f32011-09-22 04:58:26 +00001229 interpreter.GetExecutionContext().GetTargetPtr(),
Greg Claytone1f50b92011-05-03 22:09:39 +00001230 lldb::eDescriptionLevelBrief);
1231 else
1232 strm << "No line table";
1233 }
1234 }
1235 }
1236 return num_matches;
1237}
1238
1239static void
1240DumpFullpath (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1241{
1242 if (file_spec_ptr)
1243 {
1244 if (width > 0)
1245 {
1246 char fullpath[PATH_MAX];
1247 if (file_spec_ptr->GetPath(fullpath, sizeof(fullpath)))
1248 {
1249 strm.Printf("%-*s", width, fullpath);
1250 return;
1251 }
1252 }
1253 else
1254 {
1255 file_spec_ptr->Dump(&strm);
1256 return;
1257 }
1258 }
1259 // Keep the width spacing correct if things go wrong...
1260 if (width > 0)
1261 strm.Printf("%-*s", width, "");
1262}
1263
1264static void
1265DumpDirectory (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1266{
1267 if (file_spec_ptr)
1268 {
1269 if (width > 0)
1270 strm.Printf("%-*s", width, file_spec_ptr->GetDirectory().AsCString(""));
1271 else
1272 file_spec_ptr->GetDirectory().Dump(&strm);
1273 return;
1274 }
1275 // Keep the width spacing correct if things go wrong...
1276 if (width > 0)
1277 strm.Printf("%-*s", width, "");
1278}
1279
1280static void
1281DumpBasename (Stream &strm, const FileSpec *file_spec_ptr, uint32_t width)
1282{
1283 if (file_spec_ptr)
1284 {
1285 if (width > 0)
1286 strm.Printf("%-*s", width, file_spec_ptr->GetFilename().AsCString(""));
1287 else
1288 file_spec_ptr->GetFilename().Dump(&strm);
1289 return;
1290 }
1291 // Keep the width spacing correct if things go wrong...
1292 if (width > 0)
1293 strm.Printf("%-*s", width, "");
1294}
1295
1296
1297static void
1298DumpModuleSymtab (CommandInterpreter &interpreter, Stream &strm, Module *module, SortOrder sort_order)
1299{
1300 if (module)
1301 {
1302 ObjectFile *objfile = module->GetObjectFile ();
1303 if (objfile)
1304 {
1305 Symtab *symtab = objfile->GetSymtab();
1306 if (symtab)
Greg Clayton567e7f32011-09-22 04:58:26 +00001307 symtab->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), sort_order);
Greg Claytone1f50b92011-05-03 22:09:39 +00001308 }
1309 }
1310}
1311
1312static void
1313DumpModuleSections (CommandInterpreter &interpreter, Stream &strm, Module *module)
1314{
1315 if (module)
1316 {
1317 ObjectFile *objfile = module->GetObjectFile ();
1318 if (objfile)
1319 {
1320 SectionList *section_list = objfile->GetSectionList();
1321 if (section_list)
1322 {
1323 strm.PutCString ("Sections for '");
1324 strm << module->GetFileSpec();
1325 if (module->GetObjectName())
1326 strm << '(' << module->GetObjectName() << ')';
1327 strm.Printf ("' (%s):\n", module->GetArchitecture().GetArchitectureName());
1328 strm.IndentMore();
Greg Clayton567e7f32011-09-22 04:58:26 +00001329 section_list->Dump(&strm, interpreter.GetExecutionContext().GetTargetPtr(), true, UINT32_MAX);
Greg Claytone1f50b92011-05-03 22:09:39 +00001330 strm.IndentLess();
1331 }
1332 }
1333 }
1334}
1335
1336static bool
1337DumpModuleSymbolVendor (Stream &strm, Module *module)
1338{
1339 if (module)
1340 {
1341 SymbolVendor *symbol_vendor = module->GetSymbolVendor(true);
1342 if (symbol_vendor)
1343 {
1344 symbol_vendor->Dump(&strm);
1345 return true;
1346 }
1347 }
1348 return false;
1349}
1350
1351static bool
1352LookupAddressInModule
1353(
1354 CommandInterpreter &interpreter,
1355 Stream &strm,
1356 Module *module,
1357 uint32_t resolve_mask,
1358 lldb::addr_t raw_addr,
1359 lldb::addr_t offset,
1360 bool verbose
1361 )
1362{
1363 if (module)
1364 {
1365 lldb::addr_t addr = raw_addr - offset;
1366 Address so_addr;
1367 SymbolContext sc;
Greg Clayton567e7f32011-09-22 04:58:26 +00001368 Target *target = interpreter.GetExecutionContext().GetTargetPtr();
Greg Claytone1f50b92011-05-03 22:09:39 +00001369 if (target && !target->GetSectionLoadList().IsEmpty())
1370 {
1371 if (!target->GetSectionLoadList().ResolveLoadAddress (addr, so_addr))
1372 return false;
Greg Clayton13d24fb2012-01-29 20:56:30 +00001373 else if (so_addr.GetModulePtr() != module)
Greg Claytone1f50b92011-05-03 22:09:39 +00001374 return false;
1375 }
1376 else
1377 {
1378 if (!module->ResolveFileAddress (addr, so_addr))
1379 return false;
1380 }
1381
Greg Claytone1f50b92011-05-03 22:09:39 +00001382 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope();
1383 strm.IndentMore();
1384 strm.Indent (" Address: ");
Greg Clayton00b11c32012-01-10 00:25:18 +00001385 so_addr.Dump (&strm, exe_scope, Address::DumpStyleModuleWithFileAddress);
1386 strm.PutCString (" (");
Greg Claytone1f50b92011-05-03 22:09:39 +00001387 so_addr.Dump (&strm, exe_scope, Address::DumpStyleSectionNameOffset);
Greg Clayton00b11c32012-01-10 00:25:18 +00001388 strm.PutCString (")\n");
Greg Claytone1f50b92011-05-03 22:09:39 +00001389 strm.Indent (" Summary: ");
1390 const uint32_t save_indent = strm.GetIndentLevel ();
Greg Clayton2f57db02011-10-01 00:45:15 +00001391 strm.SetIndentLevel (save_indent + 13);
Greg Claytone1f50b92011-05-03 22:09:39 +00001392 so_addr.Dump (&strm, exe_scope, Address::DumpStyleResolvedDescription);
1393 strm.SetIndentLevel (save_indent);
Greg Claytone1f50b92011-05-03 22:09:39 +00001394 // Print out detailed address information when verbose is enabled
1395 if (verbose)
1396 {
Greg Clayton2f57db02011-10-01 00:45:15 +00001397 strm.EOL();
Jason Molendafb66bb52011-09-23 00:27:44 +00001398 so_addr.Dump (&strm, exe_scope, Address::DumpStyleDetailedSymbolContext);
Greg Claytone1f50b92011-05-03 22:09:39 +00001399 }
1400 strm.IndentLess();
1401 return true;
1402 }
1403
1404 return false;
1405}
1406
1407static uint32_t
1408LookupSymbolInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex)
1409{
1410 if (module)
1411 {
1412 SymbolContext sc;
1413
1414 ObjectFile *objfile = module->GetObjectFile ();
1415 if (objfile)
1416 {
1417 Symtab *symtab = objfile->GetSymtab();
1418 if (symtab)
1419 {
1420 uint32_t i;
1421 std::vector<uint32_t> match_indexes;
1422 ConstString symbol_name (name);
1423 uint32_t num_matches = 0;
1424 if (name_is_regex)
1425 {
1426 RegularExpression name_regexp(name);
1427 num_matches = symtab->AppendSymbolIndexesMatchingRegExAndType (name_regexp,
1428 eSymbolTypeAny,
1429 match_indexes);
1430 }
1431 else
1432 {
1433 num_matches = symtab->AppendSymbolIndexesWithName (symbol_name, match_indexes);
1434 }
1435
1436
1437 if (num_matches > 0)
1438 {
1439 strm.Indent ();
1440 strm.Printf("%u symbols match %s'%s' in ", num_matches,
1441 name_is_regex ? "the regular expression " : "", name);
1442 DumpFullpath (strm, &module->GetFileSpec(), 0);
1443 strm.PutCString(":\n");
1444 strm.IndentMore ();
1445 Symtab::DumpSymbolHeader (&strm);
1446 for (i=0; i < num_matches; ++i)
1447 {
1448 Symbol *symbol = symtab->SymbolAtIndex(match_indexes[i]);
1449 strm.Indent ();
Greg Clayton567e7f32011-09-22 04:58:26 +00001450 symbol->Dump (&strm, interpreter.GetExecutionContext().GetTargetPtr(), i);
Greg Claytone1f50b92011-05-03 22:09:39 +00001451 }
1452 strm.IndentLess ();
1453 return num_matches;
1454 }
1455 }
1456 }
1457 }
1458 return 0;
1459}
1460
1461
1462static void
1463DumpSymbolContextList (CommandInterpreter &interpreter, Stream &strm, SymbolContextList &sc_list, bool prepend_addr, bool verbose)
1464{
1465 strm.IndentMore ();
1466 uint32_t i;
1467 const uint32_t num_matches = sc_list.GetSize();
1468
1469 for (i=0; i<num_matches; ++i)
1470 {
1471 SymbolContext sc;
1472 if (sc_list.GetContextAtIndex(i, sc))
1473 {
1474 strm.Indent();
1475 ExecutionContextScope *exe_scope = interpreter.GetExecutionContext().GetBestExecutionContextScope ();
1476
1477 if (prepend_addr)
1478 {
1479 if (sc.line_entry.range.GetBaseAddress().IsValid())
1480 {
1481 sc.line_entry.range.GetBaseAddress().Dump (&strm,
1482 exe_scope,
1483 Address::DumpStyleLoadAddress,
1484 Address::DumpStyleModuleWithFileAddress);
1485 strm.PutCString(" in ");
1486 }
1487 }
Sean Callanand7793d22012-02-11 00:24:04 +00001488
1489 AddressRange range;
1490
1491 sc.GetAddressRange(eSymbolContextEverything,
1492 0,
1493 true,
1494 range);
1495
Greg Claytone1f50b92011-05-03 22:09:39 +00001496 sc.DumpStopContext(&strm,
1497 exe_scope,
Sean Callanand7793d22012-02-11 00:24:04 +00001498 range.GetBaseAddress(),
Greg Claytone1f50b92011-05-03 22:09:39 +00001499 true,
1500 true,
1501 false);
Sean Callanand7793d22012-02-11 00:24:04 +00001502
Greg Claytone1f50b92011-05-03 22:09:39 +00001503 strm.EOL();
1504 if (verbose)
1505 {
1506 if (sc.line_entry.range.GetBaseAddress().IsValid())
1507 {
1508 if (sc.line_entry.range.GetBaseAddress().Dump (&strm,
1509 exe_scope,
1510 Address::DumpStyleDetailedSymbolContext))
1511 strm.PutCString("\n\n");
1512 }
1513 else if (sc.function->GetAddressRange().GetBaseAddress().IsValid())
1514 {
1515 if (sc.function->GetAddressRange().GetBaseAddress().Dump (&strm,
1516 exe_scope,
1517 Address::DumpStyleDetailedSymbolContext))
1518 strm.PutCString("\n\n");
1519 }
1520 }
1521 }
1522 }
1523 strm.IndentLess ();
1524}
1525
1526static uint32_t
Sean Callanan9ad19532012-02-11 01:22:21 +00001527LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool include_inlines, bool verbose)
Greg Claytone1f50b92011-05-03 22:09:39 +00001528{
1529 if (module && name && name[0])
1530 {
1531 SymbolContextList sc_list;
1532 const bool include_symbols = false;
1533 const bool append = true;
1534 uint32_t num_matches = 0;
1535 if (name_is_regex)
1536 {
1537 RegularExpression function_name_regex (name);
1538 num_matches = module->FindFunctions (function_name_regex,
1539 include_symbols,
Sean Callanan302d78c2012-02-10 22:52:19 +00001540 include_inlines,
Greg Claytone1f50b92011-05-03 22:09:39 +00001541 append,
1542 sc_list);
1543 }
1544 else
1545 {
1546 ConstString function_name (name);
Sean Callanan3e80cd92011-10-12 02:08:07 +00001547 num_matches = module->FindFunctions (function_name,
1548 NULL,
Greg Claytone1f50b92011-05-03 22:09:39 +00001549 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
1550 include_symbols,
Sean Callanan302d78c2012-02-10 22:52:19 +00001551 include_inlines,
Greg Claytone1f50b92011-05-03 22:09:39 +00001552 append,
1553 sc_list);
1554 }
1555
1556 if (num_matches)
1557 {
1558 strm.Indent ();
1559 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1560 DumpFullpath (strm, &module->GetFileSpec(), 0);
1561 strm.PutCString(":\n");
1562 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
1563 }
1564 return num_matches;
1565 }
1566 return 0;
1567}
1568
1569static uint32_t
Greg Clayton801417e2011-07-07 01:59:51 +00001570LookupTypeInModule (CommandInterpreter &interpreter,
1571 Stream &strm,
1572 Module *module,
1573 const char *name_cstr,
1574 bool name_is_regex)
Greg Claytone1f50b92011-05-03 22:09:39 +00001575{
1576 if (module && name_cstr && name_cstr[0])
1577 {
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001578 TypeList type_list;
1579 const uint32_t max_num_matches = 1;
1580 uint32_t num_matches = 0;
1581 SymbolContext sc;
1582
1583 ConstString name(name_cstr);
1584 num_matches = module->FindTypes(sc, name, NULL, true, max_num_matches, type_list);
Greg Claytone1f50b92011-05-03 22:09:39 +00001585
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001586 if (num_matches)
1587 {
1588 strm.Indent ();
1589 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1590 DumpFullpath (strm, &module->GetFileSpec(), 0);
1591 strm.PutCString(":\n");
1592 const uint32_t num_types = type_list.GetSize();
1593 for (uint32_t i=0; i<num_types; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00001594 {
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001595 TypeSP type_sp (type_list.GetTypeAtIndex(i));
1596 if (type_sp)
Greg Claytone1f50b92011-05-03 22:09:39 +00001597 {
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001598 // Resolve the clang type so that any forward references
1599 // to types that haven't yet been parsed will get parsed.
1600 type_sp->GetClangFullType ();
1601 type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
Greg Claytone1f50b92011-05-03 22:09:39 +00001602 }
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001603 strm.EOL();
Greg Claytone1f50b92011-05-03 22:09:39 +00001604 }
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001605 }
1606 return num_matches;
Greg Claytone1f50b92011-05-03 22:09:39 +00001607 }
1608 return 0;
1609}
1610
1611static uint32_t
1612LookupFileAndLineInModule (CommandInterpreter &interpreter,
1613 Stream &strm,
1614 Module *module,
1615 const FileSpec &file_spec,
1616 uint32_t line,
1617 bool check_inlines,
1618 bool verbose)
1619{
1620 if (module && file_spec)
1621 {
1622 SymbolContextList sc_list;
1623 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
1624 eSymbolContextEverything, sc_list);
1625 if (num_matches > 0)
1626 {
1627 strm.Indent ();
1628 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1629 strm << file_spec;
1630 if (line > 0)
1631 strm.Printf (":%u", line);
1632 strm << " in ";
1633 DumpFullpath (strm, &module->GetFileSpec(), 0);
1634 strm.PutCString(":\n");
1635 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
1636 return num_matches;
1637 }
1638 }
1639 return 0;
1640
1641}
1642
Greg Clayton91048ef2011-11-10 01:18:58 +00001643
1644static size_t
1645FindModulesByName (Target *target,
1646 const char *module_name,
1647 ModuleList &module_list,
1648 bool check_global_list)
1649{
1650// Dump specified images (by basename or fullpath)
1651 FileSpec module_file_spec(module_name, false);
1652
1653 const size_t initial_size = module_list.GetSize ();
1654
1655 size_t num_matches = 0;
1656
1657 if (target)
1658 {
1659 num_matches = target->GetImages().FindModules (&module_file_spec,
1660 NULL,
1661 NULL,
1662 NULL,
1663 module_list);
1664
1665 // Not found in our module list for our target, check the main
1666 // shared module list in case it is a extra file used somewhere
1667 // else
1668 if (num_matches == 0)
1669 num_matches = ModuleList::FindSharedModules (module_file_spec,
1670 target->GetArchitecture(),
1671 NULL,
1672 NULL,
1673 module_list);
1674 }
1675 else
1676 {
1677 num_matches = ModuleList::FindSharedModules (module_file_spec,
1678 ArchSpec(),
1679 NULL,
1680 NULL,
1681 module_list);
1682 }
1683
1684 if (check_global_list && num_matches == 0)
1685 {
1686 // Check the global list
Greg Claytonc149c8b2012-01-27 18:08:35 +00001687 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
Greg Clayton91048ef2011-11-10 01:18:58 +00001688 const uint32_t num_modules = Module::GetNumberAllocatedModules();
1689 ModuleSP module_sp;
1690 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1691 {
1692 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1693
1694 if (module)
1695 {
1696 if (FileSpec::Equal(module->GetFileSpec(), module_file_spec, true))
1697 {
Greg Clayton13d24fb2012-01-29 20:56:30 +00001698 module_sp = module->shared_from_this();
Greg Clayton91048ef2011-11-10 01:18:58 +00001699 module_list.AppendIfNeeded(module_sp);
1700 }
1701 }
1702 }
1703 }
1704 return module_list.GetSize () - initial_size;
1705}
1706
Greg Claytone1f50b92011-05-03 22:09:39 +00001707#pragma mark CommandObjectTargetModulesModuleAutoComplete
1708
1709//----------------------------------------------------------------------
1710// A base command object class that can auto complete with module file
1711// paths
1712//----------------------------------------------------------------------
1713
1714class CommandObjectTargetModulesModuleAutoComplete : public CommandObject
1715{
1716public:
1717
1718 CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter,
1719 const char *name,
1720 const char *help,
1721 const char *syntax) :
1722 CommandObject (interpreter, name, help, syntax)
1723 {
1724 CommandArgumentEntry arg;
1725 CommandArgumentData file_arg;
1726
1727 // Define the first (and only) variant of this arg.
1728 file_arg.arg_type = eArgTypeFilename;
1729 file_arg.arg_repetition = eArgRepeatStar;
1730
1731 // There is only one variant this argument could be; put it into the argument entry.
1732 arg.push_back (file_arg);
1733
1734 // Push the data for the first argument into the m_arguments vector.
1735 m_arguments.push_back (arg);
1736 }
1737
1738 virtual
1739 ~CommandObjectTargetModulesModuleAutoComplete ()
1740 {
1741 }
1742
1743 virtual int
1744 HandleArgumentCompletion (Args &input,
1745 int &cursor_index,
1746 int &cursor_char_position,
1747 OptionElementVector &opt_element_vector,
1748 int match_start_point,
1749 int max_return_elements,
1750 bool &word_complete,
1751 StringList &matches)
1752 {
1753 // Arguments are the standard module completer.
1754 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1755 completion_str.erase (cursor_char_position);
1756
1757 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1758 CommandCompletions::eModuleCompletion,
1759 completion_str.c_str(),
1760 match_start_point,
1761 max_return_elements,
1762 NULL,
1763 word_complete,
1764 matches);
1765 return matches.GetSize();
1766 }
1767};
1768
1769#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1770
1771//----------------------------------------------------------------------
1772// A base command object class that can auto complete with module source
1773// file paths
1774//----------------------------------------------------------------------
1775
1776class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObject
1777{
1778public:
1779
1780 CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
1781 const char *name,
1782 const char *help,
1783 const char *syntax) :
1784 CommandObject (interpreter, name, help, syntax)
1785 {
1786 CommandArgumentEntry arg;
1787 CommandArgumentData source_file_arg;
1788
1789 // Define the first (and only) variant of this arg.
1790 source_file_arg.arg_type = eArgTypeSourceFile;
1791 source_file_arg.arg_repetition = eArgRepeatPlus;
1792
1793 // There is only one variant this argument could be; put it into the argument entry.
1794 arg.push_back (source_file_arg);
1795
1796 // Push the data for the first argument into the m_arguments vector.
1797 m_arguments.push_back (arg);
1798 }
1799
1800 virtual
1801 ~CommandObjectTargetModulesSourceFileAutoComplete ()
1802 {
1803 }
1804
1805 virtual int
1806 HandleArgumentCompletion (Args &input,
1807 int &cursor_index,
1808 int &cursor_char_position,
1809 OptionElementVector &opt_element_vector,
1810 int match_start_point,
1811 int max_return_elements,
1812 bool &word_complete,
1813 StringList &matches)
1814 {
1815 // Arguments are the standard source file completer.
1816 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1817 completion_str.erase (cursor_char_position);
1818
1819 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1820 CommandCompletions::eSourceFileCompletion,
1821 completion_str.c_str(),
1822 match_start_point,
1823 max_return_elements,
1824 NULL,
1825 word_complete,
1826 matches);
1827 return matches.GetSize();
1828 }
1829};
1830
1831
1832#pragma mark CommandObjectTargetModulesDumpSymtab
1833
1834
1835class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
1836{
1837public:
1838 CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
1839 CommandObjectTargetModulesModuleAutoComplete (interpreter,
1840 "target modules dump symtab",
1841 "Dump the symbol table from one or more target modules.",
1842 NULL),
1843 m_options (interpreter)
1844 {
1845 }
1846
1847 virtual
1848 ~CommandObjectTargetModulesDumpSymtab ()
1849 {
1850 }
1851
1852 virtual bool
1853 Execute (Args& command,
1854 CommandReturnObject &result)
1855 {
1856 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1857 if (target == NULL)
1858 {
1859 result.AppendError ("invalid target, create a debug target using the 'target create' command");
1860 result.SetStatus (eReturnStatusFailed);
1861 return false;
1862 }
1863 else
1864 {
1865 uint32_t num_dumped = 0;
1866
1867 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1868 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1869 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1870
1871 if (command.GetArgumentCount() == 0)
1872 {
1873 // Dump all sections for all modules images
1874 const uint32_t num_modules = target->GetImages().GetSize();
1875 if (num_modules > 0)
1876 {
1877 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
1878 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1879 {
1880 if (num_dumped > 0)
1881 {
1882 result.GetOutputStream().EOL();
1883 result.GetOutputStream().EOL();
1884 }
1885 num_dumped++;
1886 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order);
1887 }
1888 }
1889 else
1890 {
1891 result.AppendError ("the target has no associated executable images");
1892 result.SetStatus (eReturnStatusFailed);
1893 return false;
1894 }
1895 }
1896 else
1897 {
1898 // Dump specified images (by basename or fullpath)
1899 const char *arg_cstr;
1900 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1901 {
Greg Clayton91048ef2011-11-10 01:18:58 +00001902 ModuleList module_list;
1903 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
1904 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00001905 {
Greg Clayton91048ef2011-11-10 01:18:58 +00001906 for (size_t i=0; i<num_matches; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00001907 {
Greg Clayton91048ef2011-11-10 01:18:58 +00001908 Module *module = module_list.GetModulePointerAtIndex(i);
1909 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00001910 {
1911 if (num_dumped > 0)
1912 {
1913 result.GetOutputStream().EOL();
1914 result.GetOutputStream().EOL();
1915 }
1916 num_dumped++;
Greg Clayton91048ef2011-11-10 01:18:58 +00001917 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order);
Greg Claytone1f50b92011-05-03 22:09:39 +00001918 }
1919 }
1920 }
1921 else
1922 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1923 }
1924 }
1925
1926 if (num_dumped > 0)
1927 result.SetStatus (eReturnStatusSuccessFinishResult);
1928 else
1929 {
1930 result.AppendError ("no matching executable images found");
1931 result.SetStatus (eReturnStatusFailed);
1932 }
1933 }
1934 return result.Succeeded();
1935 }
1936
1937 virtual Options *
1938 GetOptions ()
1939 {
1940 return &m_options;
1941 }
1942
1943 class CommandOptions : public Options
1944 {
1945 public:
1946
1947 CommandOptions (CommandInterpreter &interpreter) :
1948 Options(interpreter),
1949 m_sort_order (eSortOrderNone)
1950 {
1951 }
1952
1953 virtual
1954 ~CommandOptions ()
1955 {
1956 }
1957
1958 virtual Error
1959 SetOptionValue (uint32_t option_idx, const char *option_arg)
1960 {
1961 Error error;
1962 char short_option = (char) m_getopt_table[option_idx].val;
1963
1964 switch (short_option)
1965 {
1966 case 's':
Greg Claytone1f50b92011-05-03 22:09:39 +00001967 m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
1968 g_option_table[option_idx].enum_values,
1969 eSortOrderNone,
Greg Clayton61aca5d2011-10-07 18:58:12 +00001970 error);
Greg Claytone1f50b92011-05-03 22:09:39 +00001971 break;
1972
1973 default:
Greg Clayton9c236732011-10-26 00:56:27 +00001974 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Claytone1f50b92011-05-03 22:09:39 +00001975 break;
1976
1977 }
1978 return error;
1979 }
1980
1981 void
1982 OptionParsingStarting ()
1983 {
1984 m_sort_order = eSortOrderNone;
1985 }
1986
1987 const OptionDefinition*
1988 GetDefinitions ()
1989 {
1990 return g_option_table;
1991 }
1992
1993 // Options table: Required for subclasses of Options.
1994 static OptionDefinition g_option_table[];
1995
1996 SortOrder m_sort_order;
1997 };
1998
1999protected:
2000
2001 CommandOptions m_options;
2002};
2003
2004static OptionEnumValueElement
2005g_sort_option_enumeration[4] =
2006{
2007 { eSortOrderNone, "none", "No sorting, use the original symbol table order."},
2008 { eSortOrderByAddress, "address", "Sort output by symbol address."},
2009 { eSortOrderByName, "name", "Sort output by symbol name."},
2010 { 0, NULL, NULL }
2011};
2012
2013
2014OptionDefinition
2015CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
2016{
2017 { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
2018 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
2019};
2020
2021#pragma mark CommandObjectTargetModulesDumpSections
2022
2023//----------------------------------------------------------------------
2024// Image section dumping command
2025//----------------------------------------------------------------------
2026
2027class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
2028{
2029public:
2030 CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
2031 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2032 "target modules dump sections",
2033 "Dump the sections from one or more target modules.",
2034 //"target modules dump sections [<file1> ...]")
2035 NULL)
2036 {
2037 }
2038
2039 virtual
2040 ~CommandObjectTargetModulesDumpSections ()
2041 {
2042 }
2043
2044 virtual bool
2045 Execute (Args& command,
2046 CommandReturnObject &result)
2047 {
2048 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2049 if (target == NULL)
2050 {
2051 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2052 result.SetStatus (eReturnStatusFailed);
2053 return false;
2054 }
2055 else
2056 {
2057 uint32_t num_dumped = 0;
2058
2059 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2060 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2061 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2062
2063 if (command.GetArgumentCount() == 0)
2064 {
2065 // Dump all sections for all modules images
2066 const uint32_t num_modules = target->GetImages().GetSize();
2067 if (num_modules > 0)
2068 {
2069 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
2070 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2071 {
2072 num_dumped++;
2073 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
2074 }
2075 }
2076 else
2077 {
2078 result.AppendError ("the target has no associated executable images");
2079 result.SetStatus (eReturnStatusFailed);
2080 return false;
2081 }
2082 }
2083 else
2084 {
2085 // Dump specified images (by basename or fullpath)
2086 const char *arg_cstr;
2087 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2088 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002089 ModuleList module_list;
2090 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2091 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00002092 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002093 for (size_t i=0; i<num_matches; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00002094 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002095 Module *module = module_list.GetModulePointerAtIndex(i);
2096 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00002097 {
2098 num_dumped++;
Greg Clayton91048ef2011-11-10 01:18:58 +00002099 DumpModuleSections (m_interpreter, result.GetOutputStream(), module);
Greg Claytone1f50b92011-05-03 22:09:39 +00002100 }
2101 }
2102 }
2103 else
Greg Clayton91048ef2011-11-10 01:18:58 +00002104 {
2105 // Check the global list
Greg Claytonc149c8b2012-01-27 18:08:35 +00002106 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
Greg Clayton91048ef2011-11-10 01:18:58 +00002107
Greg Claytone1f50b92011-05-03 22:09:39 +00002108 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
Greg Clayton91048ef2011-11-10 01:18:58 +00002109 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002110 }
2111 }
2112
2113 if (num_dumped > 0)
2114 result.SetStatus (eReturnStatusSuccessFinishResult);
2115 else
2116 {
2117 result.AppendError ("no matching executable images found");
2118 result.SetStatus (eReturnStatusFailed);
2119 }
2120 }
2121 return result.Succeeded();
2122 }
2123};
2124
2125
2126#pragma mark CommandObjectTargetModulesDumpSymfile
2127
2128//----------------------------------------------------------------------
2129// Image debug symbol dumping command
2130//----------------------------------------------------------------------
2131
2132class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
2133{
2134public:
2135 CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
2136 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2137 "target modules dump symfile",
2138 "Dump the debug symbol file for one or more target modules.",
2139 //"target modules dump symfile [<file1> ...]")
2140 NULL)
2141 {
2142 }
2143
2144 virtual
2145 ~CommandObjectTargetModulesDumpSymfile ()
2146 {
2147 }
2148
2149 virtual bool
2150 Execute (Args& command,
2151 CommandReturnObject &result)
2152 {
2153 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2154 if (target == NULL)
2155 {
2156 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2157 result.SetStatus (eReturnStatusFailed);
2158 return false;
2159 }
2160 else
2161 {
2162 uint32_t num_dumped = 0;
2163
2164 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2165 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2166 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2167
2168 if (command.GetArgumentCount() == 0)
2169 {
2170 // Dump all sections for all modules images
2171 const uint32_t num_modules = target->GetImages().GetSize();
2172 if (num_modules > 0)
2173 {
2174 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
2175 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2176 {
2177 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
2178 num_dumped++;
2179 }
2180 }
2181 else
2182 {
2183 result.AppendError ("the target has no associated executable images");
2184 result.SetStatus (eReturnStatusFailed);
2185 return false;
2186 }
2187 }
2188 else
2189 {
2190 // Dump specified images (by basename or fullpath)
2191 const char *arg_cstr;
2192 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2193 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002194 ModuleList module_list;
2195 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2196 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00002197 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002198 for (size_t i=0; i<num_matches; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00002199 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002200 Module *module = module_list.GetModulePointerAtIndex(i);
2201 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00002202 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002203 if (DumpModuleSymbolVendor (result.GetOutputStream(), module))
Greg Claytone1f50b92011-05-03 22:09:39 +00002204 num_dumped++;
2205 }
2206 }
2207 }
2208 else
2209 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2210 }
2211 }
2212
2213 if (num_dumped > 0)
2214 result.SetStatus (eReturnStatusSuccessFinishResult);
2215 else
2216 {
2217 result.AppendError ("no matching executable images found");
2218 result.SetStatus (eReturnStatusFailed);
2219 }
2220 }
2221 return result.Succeeded();
2222 }
2223};
2224
2225
2226#pragma mark CommandObjectTargetModulesDumpLineTable
2227
2228//----------------------------------------------------------------------
2229// Image debug line table dumping command
2230//----------------------------------------------------------------------
2231
2232class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
2233{
2234public:
2235 CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
2236 CommandObjectTargetModulesSourceFileAutoComplete (interpreter,
2237 "target modules dump line-table",
2238 "Dump the debug symbol file for one or more target modules.",
2239 NULL)
2240 {
2241 }
2242
2243 virtual
2244 ~CommandObjectTargetModulesDumpLineTable ()
2245 {
2246 }
2247
2248 virtual bool
2249 Execute (Args& command,
2250 CommandReturnObject &result)
2251 {
2252 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2253 if (target == NULL)
2254 {
2255 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2256 result.SetStatus (eReturnStatusFailed);
2257 return false;
2258 }
2259 else
2260 {
2261 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
2262 uint32_t total_num_dumped = 0;
2263
2264 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2265 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2266 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2267
2268 if (command.GetArgumentCount() == 0)
2269 {
2270 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
2271 result.SetStatus (eReturnStatusFailed);
2272 }
2273 else
2274 {
2275 // Dump specified images (by basename or fullpath)
2276 const char *arg_cstr;
2277 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2278 {
2279 FileSpec file_spec(arg_cstr, false);
2280 const uint32_t num_modules = target->GetImages().GetSize();
2281 if (num_modules > 0)
2282 {
2283 uint32_t num_dumped = 0;
2284 for (uint32_t i = 0; i<num_modules; ++i)
2285 {
2286 if (DumpCompileUnitLineTable (m_interpreter,
2287 result.GetOutputStream(),
2288 target->GetImages().GetModulePointerAtIndex(i),
2289 file_spec,
Greg Clayton567e7f32011-09-22 04:58:26 +00002290 exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive()))
Greg Claytone1f50b92011-05-03 22:09:39 +00002291 num_dumped++;
2292 }
2293 if (num_dumped == 0)
2294 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
2295 else
2296 total_num_dumped += num_dumped;
2297 }
2298 }
2299 }
2300
2301 if (total_num_dumped > 0)
2302 result.SetStatus (eReturnStatusSuccessFinishResult);
2303 else
2304 {
2305 result.AppendError ("no source filenames matched any command arguments");
2306 result.SetStatus (eReturnStatusFailed);
2307 }
2308 }
2309 return result.Succeeded();
2310 }
2311};
2312
2313
2314#pragma mark CommandObjectTargetModulesDump
2315
2316//----------------------------------------------------------------------
2317// Dump multi-word command for target modules
2318//----------------------------------------------------------------------
2319
2320class CommandObjectTargetModulesDump : public CommandObjectMultiword
2321{
2322public:
2323
2324 //------------------------------------------------------------------
2325 // Constructors and Destructors
2326 //------------------------------------------------------------------
2327 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) :
2328 CommandObjectMultiword (interpreter,
2329 "target modules dump",
2330 "A set of commands for dumping information about one or more target modules.",
2331 "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
2332 {
2333 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
2334 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
2335 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
2336 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
2337 }
2338
2339 virtual
2340 ~CommandObjectTargetModulesDump()
2341 {
2342 }
2343};
2344
2345class CommandObjectTargetModulesAdd : public CommandObject
2346{
2347public:
2348 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
2349 CommandObject (interpreter,
2350 "target modules add",
2351 "Add a new module to the current target's modules.",
2352 "target modules add [<module>]")
2353 {
2354 }
2355
2356 virtual
2357 ~CommandObjectTargetModulesAdd ()
2358 {
2359 }
2360
2361 virtual bool
2362 Execute (Args& args,
2363 CommandReturnObject &result)
2364 {
2365 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2366 if (target == NULL)
2367 {
2368 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2369 result.SetStatus (eReturnStatusFailed);
2370 return false;
2371 }
2372 else
2373 {
2374 const size_t argc = args.GetArgumentCount();
2375 if (argc == 0)
2376 {
2377 result.AppendError ("one or more executable image paths must be specified");
2378 result.SetStatus (eReturnStatusFailed);
2379 return false;
2380 }
2381 else
2382 {
2383 for (size_t i=0; i<argc; ++i)
2384 {
2385 const char *path = args.GetArgumentAtIndex(i);
2386 if (path)
2387 {
2388 FileSpec file_spec(path, true);
2389 ArchSpec arch;
2390 if (file_spec.Exists())
2391 {
2392 ModuleSP module_sp (target->GetSharedModule(file_spec, arch));
2393 if (!module_sp)
2394 {
2395 result.AppendError ("one or more executable image paths must be specified");
2396 result.SetStatus (eReturnStatusFailed);
2397 return false;
2398 }
Jason Molenda36f6fb92011-08-02 23:28:55 +00002399 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytone1f50b92011-05-03 22:09:39 +00002400 }
2401 else
2402 {
2403 char resolved_path[PATH_MAX];
2404 result.SetStatus (eReturnStatusFailed);
2405 if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
2406 {
2407 if (strcmp (resolved_path, path) != 0)
2408 {
2409 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
2410 break;
2411 }
2412 }
2413 result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
2414 break;
2415 }
2416 }
2417 }
2418 }
2419 }
2420 return result.Succeeded();
2421 }
2422
2423 int
2424 HandleArgumentCompletion (Args &input,
2425 int &cursor_index,
2426 int &cursor_char_position,
2427 OptionElementVector &opt_element_vector,
2428 int match_start_point,
2429 int max_return_elements,
2430 bool &word_complete,
2431 StringList &matches)
2432 {
2433 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2434 completion_str.erase (cursor_char_position);
2435
2436 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2437 CommandCompletions::eDiskFileCompletion,
2438 completion_str.c_str(),
2439 match_start_point,
2440 max_return_elements,
2441 NULL,
2442 word_complete,
2443 matches);
2444 return matches.GetSize();
2445 }
2446
2447};
2448
2449class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
2450{
2451public:
2452 CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) :
2453 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2454 "target modules load",
2455 "Set the load addresses for one or more sections in a target module.",
2456 "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
2457 m_option_group (interpreter),
2458 m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "Fullpath or basename for module to load."),
2459 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)
2460 {
2461 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2462 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2463 m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2464 m_option_group.Finalize();
2465 }
2466
2467 virtual
2468 ~CommandObjectTargetModulesLoad ()
2469 {
2470 }
2471
2472 virtual bool
2473 Execute (Args& args,
2474 CommandReturnObject &result)
2475 {
2476 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2477 if (target == NULL)
2478 {
2479 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2480 result.SetStatus (eReturnStatusFailed);
2481 return false;
2482 }
2483 else
2484 {
2485 const size_t argc = args.GetArgumentCount();
2486 const FileSpec *file_ptr = NULL;
2487 const UUID *uuid_ptr = NULL;
2488 if (m_file_option.GetOptionValue().OptionWasSet())
2489 file_ptr = &m_file_option.GetOptionValue().GetCurrentValue();
2490
2491 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2492 uuid_ptr = &m_uuid_option_group.GetOptionValue().GetCurrentValue();
2493
2494 if (file_ptr || uuid_ptr)
2495 {
2496
2497 ModuleList matching_modules;
2498 const size_t num_matches = target->GetImages().FindModules (file_ptr, // File spec to match (can be NULL to match by UUID only)
2499 NULL, // Architecture
2500 uuid_ptr, // UUID to match (can be NULL to not match on UUID)
2501 NULL, // Object name
2502 matching_modules);
2503
2504 char path[PATH_MAX];
2505 if (num_matches == 1)
2506 {
2507 Module *module = matching_modules.GetModulePointerAtIndex(0);
2508 if (module)
2509 {
2510 ObjectFile *objfile = module->GetObjectFile();
2511 if (objfile)
2512 {
2513 SectionList *section_list = objfile->GetSectionList();
2514 if (section_list)
2515 {
2516 if (argc == 0)
2517 {
2518 if (m_slide_option.GetOptionValue().OptionWasSet())
2519 {
2520 Module *module = matching_modules.GetModulePointerAtIndex(0);
2521 if (module)
2522 {
2523 ObjectFile *objfile = module->GetObjectFile();
2524 if (objfile)
2525 {
2526 SectionList *section_list = objfile->GetSectionList();
2527 if (section_list)
2528 {
2529 const size_t num_sections = section_list->GetSize();
2530 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
2531 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
2532 {
2533 SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx));
2534 if (section_sp)
2535 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), section_sp->GetFileAddress() + slide);
2536 }
2537 }
2538 }
2539 }
2540 }
2541 else
2542 {
2543 result.AppendError ("one or more section name + load address pair must be specified");
2544 result.SetStatus (eReturnStatusFailed);
2545 return false;
2546 }
2547 }
2548 else
2549 {
2550 if (m_slide_option.GetOptionValue().OptionWasSet())
2551 {
2552 result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
2553 result.SetStatus (eReturnStatusFailed);
2554 return false;
2555 }
2556
2557 for (size_t i=0; i<argc; i += 2)
2558 {
2559 const char *sect_name = args.GetArgumentAtIndex(i);
2560 const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
2561 if (sect_name && load_addr_cstr)
2562 {
2563 ConstString const_sect_name(sect_name);
2564 bool success = false;
2565 addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2566 if (success)
2567 {
2568 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
2569 if (section_sp)
2570 {
2571 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), load_addr);
2572 result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr);
2573 }
2574 else
2575 {
2576 result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
2577 result.SetStatus (eReturnStatusFailed);
2578 break;
2579 }
2580 }
2581 else
2582 {
2583 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
2584 result.SetStatus (eReturnStatusFailed);
2585 break;
2586 }
2587 }
2588 else
2589 {
2590 if (sect_name)
2591 result.AppendError ("section names must be followed by a load address.\n");
2592 else
2593 result.AppendError ("one or more section name + load address pair must be specified.\n");
2594 result.SetStatus (eReturnStatusFailed);
2595 break;
2596 }
2597 }
2598 }
2599 }
2600 else
2601 {
2602 module->GetFileSpec().GetPath (path, sizeof(path));
2603 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
2604 result.SetStatus (eReturnStatusFailed);
2605 }
2606 }
2607 else
2608 {
2609 module->GetFileSpec().GetPath (path, sizeof(path));
2610 result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
2611 result.SetStatus (eReturnStatusFailed);
2612 }
2613 }
2614 else
2615 {
2616 module->GetFileSpec().GetPath (path, sizeof(path));
2617 result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
2618 result.SetStatus (eReturnStatusFailed);
2619 }
2620 }
2621 else
2622 {
2623 char uuid_cstr[64];
2624 if (file_ptr)
2625 file_ptr->GetPath (path, sizeof(path));
2626 else
2627 path[0] = '\0';
2628
2629 if (uuid_ptr)
2630 uuid_ptr->GetAsCString(uuid_cstr, sizeof(uuid_cstr));
2631 else
2632 uuid_cstr[0] = '\0';
2633 if (num_matches > 1)
2634 {
2635 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
2636 path[0] ? " file=" : "",
2637 path,
2638 uuid_cstr[0] ? " uuid=" : "",
2639 uuid_cstr);
2640 for (size_t i=0; i<num_matches; ++i)
2641 {
2642 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
2643 result.AppendMessageWithFormat("%s\n", path);
2644 }
2645 }
2646 else
2647 {
2648 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n",
2649 path[0] ? " file=" : "",
2650 path,
2651 uuid_cstr[0] ? " uuid=" : "",
2652 uuid_cstr);
2653 }
2654 result.SetStatus (eReturnStatusFailed);
2655 }
2656 }
2657 else
2658 {
2659 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
2660 result.SetStatus (eReturnStatusFailed);
2661 return false;
2662 }
2663 }
2664 return result.Succeeded();
2665 }
2666
2667 virtual Options *
2668 GetOptions ()
2669 {
2670 return &m_option_group;
2671 }
2672
2673protected:
2674 OptionGroupOptions m_option_group;
2675 OptionGroupUUID m_uuid_option_group;
2676 OptionGroupFile m_file_option;
2677 OptionGroupUInt64 m_slide_option;
2678};
2679
2680//----------------------------------------------------------------------
2681// List images with associated information
2682//----------------------------------------------------------------------
2683class CommandObjectTargetModulesList : public CommandObject
2684{
2685public:
2686
2687 class CommandOptions : public Options
2688 {
2689 public:
2690
2691 CommandOptions (CommandInterpreter &interpreter) :
Greg Clayton899025f2011-08-09 00:01:09 +00002692 Options(interpreter),
Jim Ingham6bdea822011-10-24 18:36:33 +00002693 m_format_array(),
Daniel Dunbar97c89572011-10-31 22:50:49 +00002694 m_use_global_module_list (false),
Jim Ingham6bdea822011-10-24 18:36:33 +00002695 m_module_addr (LLDB_INVALID_ADDRESS)
Greg Claytone1f50b92011-05-03 22:09:39 +00002696 {
2697 }
2698
2699 virtual
2700 ~CommandOptions ()
2701 {
2702 }
2703
2704 virtual Error
2705 SetOptionValue (uint32_t option_idx, const char *option_arg)
2706 {
2707 char short_option = (char) m_getopt_table[option_idx].val;
Greg Clayton899025f2011-08-09 00:01:09 +00002708 if (short_option == 'g')
2709 {
2710 m_use_global_module_list = true;
2711 }
Jim Ingham6bdea822011-10-24 18:36:33 +00002712 else if (short_option == 'a')
2713 {
2714 bool success;
2715 m_module_addr = Args::StringToAddress(option_arg, LLDB_INVALID_ADDRESS, &success);
2716 if (!success)
2717 {
2718 Error error;
Greg Clayton9c236732011-10-26 00:56:27 +00002719 error.SetErrorStringWithFormat("invalid address: \"%s\"", option_arg);
Jim Ingham6bdea822011-10-24 18:36:33 +00002720 }
2721 }
Greg Clayton899025f2011-08-09 00:01:09 +00002722 else
2723 {
2724 uint32_t width = 0;
2725 if (option_arg)
2726 width = strtoul (option_arg, NULL, 0);
2727 m_format_array.push_back(std::make_pair(short_option, width));
2728 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002729 Error error;
2730 return error;
2731 }
2732
2733 void
2734 OptionParsingStarting ()
2735 {
2736 m_format_array.clear();
Greg Clayton899025f2011-08-09 00:01:09 +00002737 m_use_global_module_list = false;
Jim Ingham6bdea822011-10-24 18:36:33 +00002738 m_module_addr = LLDB_INVALID_ADDRESS;
Greg Claytone1f50b92011-05-03 22:09:39 +00002739 }
2740
2741 const OptionDefinition*
2742 GetDefinitions ()
2743 {
2744 return g_option_table;
2745 }
2746
2747 // Options table: Required for subclasses of Options.
2748
2749 static OptionDefinition g_option_table[];
2750
2751 // Instance variables to hold the values for command options.
2752 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
2753 FormatWidthCollection m_format_array;
Greg Clayton899025f2011-08-09 00:01:09 +00002754 bool m_use_global_module_list;
Jim Ingham6bdea822011-10-24 18:36:33 +00002755 lldb::addr_t m_module_addr;
Greg Claytone1f50b92011-05-03 22:09:39 +00002756 };
2757
2758 CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
2759 CommandObject (interpreter,
2760 "target modules list",
2761 "List current executable and dependent shared library images.",
2762 "target modules list [<cmd-options>]"),
2763 m_options (interpreter)
2764 {
2765 }
2766
2767 virtual
2768 ~CommandObjectTargetModulesList ()
2769 {
2770 }
2771
2772 virtual
2773 Options *
2774 GetOptions ()
2775 {
2776 return &m_options;
2777 }
2778
2779 virtual bool
2780 Execute (Args& command,
2781 CommandReturnObject &result)
2782 {
2783 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Clayton153ccd72011-08-10 02:10:13 +00002784 const bool use_global_module_list = m_options.m_use_global_module_list;
2785 if (target == NULL && use_global_module_list == false)
Greg Claytone1f50b92011-05-03 22:09:39 +00002786 {
2787 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2788 result.SetStatus (eReturnStatusFailed);
2789 return false;
2790 }
2791 else
2792 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002793 if (target)
2794 {
2795 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2796 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2797 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2798 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002799 // Dump all sections for all modules images
Greg Clayton899025f2011-08-09 00:01:09 +00002800 uint32_t num_modules = 0;
2801 Mutex::Locker locker;
Jim Ingham6bdea822011-10-24 18:36:33 +00002802
2803 Stream &strm = result.GetOutputStream();
2804
2805 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS)
2806 {
2807 if (target)
2808 {
2809 Address module_address;
2810 if (module_address.SetLoadAddress(m_options.m_module_addr, target))
2811 {
Greg Clayton13d24fb2012-01-29 20:56:30 +00002812 Module *module = module_address.GetModulePtr();
Jim Ingham6bdea822011-10-24 18:36:33 +00002813 if (module)
2814 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00002815 PrintModule (target, module, UINT32_MAX, 0, strm);
Jim Ingham6bdea822011-10-24 18:36:33 +00002816 result.SetStatus (eReturnStatusSuccessFinishResult);
2817 }
2818 else
2819 {
2820 result.AppendError ("Couldn't find module matching address: 0x%llx.", m_options.m_module_addr);
2821 result.SetStatus (eReturnStatusFailed);
2822 }
2823 }
2824 else
2825 {
2826 result.AppendError ("Couldn't find module containing address: 0x%llx.", m_options.m_module_addr);
2827 result.SetStatus (eReturnStatusFailed);
2828 }
2829 }
2830 else
2831 {
2832 result.AppendError ("Can only look up modules by address with a valid target.");
2833 result.SetStatus (eReturnStatusFailed);
2834 }
2835 return result.Succeeded();
2836 }
2837
Greg Clayton153ccd72011-08-10 02:10:13 +00002838 if (use_global_module_list)
Greg Clayton899025f2011-08-09 00:01:09 +00002839 {
Greg Claytonc149c8b2012-01-27 18:08:35 +00002840 locker.Reset (Module::GetAllocationModuleCollectionMutex()->GetMutex());
Greg Clayton899025f2011-08-09 00:01:09 +00002841 num_modules = Module::GetNumberAllocatedModules();
2842 }
2843 else
2844 num_modules = target->GetImages().GetSize();
2845
Greg Claytone1f50b92011-05-03 22:09:39 +00002846 if (num_modules > 0)
Jim Ingham6bdea822011-10-24 18:36:33 +00002847 {
Greg Claytone1f50b92011-05-03 22:09:39 +00002848 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2849 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002850 ModuleSP module_sp;
Greg Clayton899025f2011-08-09 00:01:09 +00002851 Module *module;
Greg Clayton153ccd72011-08-10 02:10:13 +00002852 if (use_global_module_list)
Greg Clayton899025f2011-08-09 00:01:09 +00002853 {
2854 module = Module::GetAllocatedModuleAtIndex(image_idx);
Greg Clayton13d24fb2012-01-29 20:56:30 +00002855 module_sp = module->shared_from_this();
Greg Clayton899025f2011-08-09 00:01:09 +00002856 }
2857 else
2858 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002859 module_sp = target->GetImages().GetModuleAtIndex(image_idx);
2860 module = module_sp.get();
Greg Clayton899025f2011-08-09 00:01:09 +00002861 }
Jim Ingham6bdea822011-10-24 18:36:33 +00002862
Greg Claytonb5a8f142012-02-05 02:38:54 +00002863 int indent = strm.Printf("[%3u] ", image_idx);
2864 PrintModule (target, module, image_idx, indent, strm);
Greg Clayton153ccd72011-08-10 02:10:13 +00002865
Greg Claytone1f50b92011-05-03 22:09:39 +00002866 }
2867 result.SetStatus (eReturnStatusSuccessFinishResult);
2868 }
2869 else
2870 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002871 if (use_global_module_list)
2872 result.AppendError ("the global module list is empty");
2873 else
2874 result.AppendError ("the target has no associated executable images");
Greg Claytone1f50b92011-05-03 22:09:39 +00002875 result.SetStatus (eReturnStatusFailed);
2876 return false;
2877 }
2878 }
2879 return result.Succeeded();
2880 }
2881protected:
Jim Ingham6bdea822011-10-24 18:36:33 +00002882
2883 void
Greg Claytonb5a8f142012-02-05 02:38:54 +00002884 PrintModule (Target *target, Module *module, uint32_t idx, int indent, Stream &strm)
Jim Ingham6bdea822011-10-24 18:36:33 +00002885 {
2886
2887 bool dump_object_name = false;
2888 if (m_options.m_format_array.empty())
2889 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00002890 m_options.m_format_array.push_back(std::make_pair('u', 0));
2891 m_options.m_format_array.push_back(std::make_pair('h', 0));
2892 m_options.m_format_array.push_back(std::make_pair('f', 0));
2893 m_options.m_format_array.push_back(std::make_pair('S', 0));
Jim Ingham6bdea822011-10-24 18:36:33 +00002894 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00002895 const size_t num_entries = m_options.m_format_array.size();
2896 bool print_space = false;
2897 for (size_t i=0; i<num_entries; ++i)
Jim Ingham6bdea822011-10-24 18:36:33 +00002898 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00002899 if (print_space)
2900 strm.PutChar(' ');
2901 print_space = true;
2902 const char format_char = m_options.m_format_array[i].first;
2903 uint32_t width = m_options.m_format_array[i].second;
2904 switch (format_char)
Jim Ingham6bdea822011-10-24 18:36:33 +00002905 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00002906 case 'A':
2907 DumpModuleArchitecture (strm, module, false, width);
2908 break;
2909
2910 case 't':
2911 DumpModuleArchitecture (strm, module, true, width);
2912 break;
2913
2914 case 'f':
2915 DumpFullpath (strm, &module->GetFileSpec(), width);
2916 dump_object_name = true;
2917 break;
2918
2919 case 'd':
2920 DumpDirectory (strm, &module->GetFileSpec(), width);
2921 break;
2922
2923 case 'b':
2924 DumpBasename (strm, &module->GetFileSpec(), width);
2925 dump_object_name = true;
2926 break;
2927
2928 case 'h':
2929 case 'o':
2930 // Image header address
2931 {
2932 uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16;
Jim Ingham6bdea822011-10-24 18:36:33 +00002933
Greg Claytonb5a8f142012-02-05 02:38:54 +00002934 ObjectFile *objfile = module->GetObjectFile ();
2935 if (objfile)
Jim Ingham6bdea822011-10-24 18:36:33 +00002936 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00002937 Address header_addr(objfile->GetHeaderAddress());
2938 if (header_addr.IsValid())
Jim Ingham6bdea822011-10-24 18:36:33 +00002939 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00002940 if (target && !target->GetSectionLoadList().IsEmpty())
Jim Ingham6bdea822011-10-24 18:36:33 +00002941 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00002942 lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target);
2943 if (header_load_addr == LLDB_INVALID_ADDRESS)
2944 {
2945 header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress);
2946 }
Jim Ingham6bdea822011-10-24 18:36:33 +00002947 else
Greg Claytonb5a8f142012-02-05 02:38:54 +00002948 {
2949 if (format_char == 'o')
2950 {
2951 // Show the offset of slide for the image
2952 strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
2953 }
2954 else
2955 {
2956 // Show the load address of the image
2957 strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr);
2958 }
2959 }
Jim Ingham6bdea822011-10-24 18:36:33 +00002960 break;
2961 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00002962 // The address was valid, but the image isn't loaded, output the address in an appropriate format
2963 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress);
2964 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00002965 }
Jim Ingham6bdea822011-10-24 18:36:33 +00002966 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00002967 strm.Printf ("%*s", addr_nibble_width + 2, "");
2968 }
2969 break;
2970 case 'r':
2971 {
2972 uint32_t ref_count = 0;
2973 ModuleSP module_sp (module->shared_from_this());
2974 if (module_sp)
2975 {
2976 // Take one away to make sure we don't count our local "module_sp"
2977 ref_count = module_sp.use_count() - 1;
2978 }
2979 if (width)
2980 strm.Printf("{%*u}", width, ref_count);
2981 else
2982 strm.Printf("{%u}", ref_count);
2983 }
2984 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00002985
Greg Claytonb5a8f142012-02-05 02:38:54 +00002986 case 's':
2987 case 'S':
2988 {
2989 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
2990 if (symbol_vendor)
2991 {
2992 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
2993 if (symbol_file)
2994 {
2995 if (format_char == 'S')
2996 {
2997 FileSpec &symfile_spec = symbol_file->GetObjectFile()->GetFileSpec();
2998 // Dump symbol file only if different from module file
2999 if (!symfile_spec || symfile_spec == module->GetFileSpec())
3000 {
3001 print_space = false;
3002 break;
3003 }
3004 // Add a newline and indent past the index
3005 strm.Printf ("\n%*s", indent, "");
3006 }
3007 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
3008 dump_object_name = true;
3009 break;
3010 }
3011 }
3012 strm.Printf("%.*s", width, "<NONE>");
3013 }
3014 break;
3015
3016 case 'm':
3017 module->GetModificationTime().Dump(&strm, width);
3018 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00003019
Greg Claytonb5a8f142012-02-05 02:38:54 +00003020 case 'p':
3021 strm.Printf("%p", module);
3022 break;
3023
3024 case 'u':
3025 DumpModuleUUID(strm, module);
3026 break;
3027
3028 default:
3029 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00003030 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00003031
3032 }
3033 if (dump_object_name)
3034 {
3035 const char *object_name = module->GetObjectName().GetCString();
3036 if (object_name)
3037 strm.Printf ("(%s)", object_name);
Jim Ingham6bdea822011-10-24 18:36:33 +00003038 }
3039 strm.EOL();
3040 }
3041
Greg Claytone1f50b92011-05-03 22:09:39 +00003042 CommandOptions m_options;
3043};
3044
3045OptionDefinition
3046CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
3047{
Jim Ingham6bdea822011-10-24 18:36:33 +00003048 { LLDB_OPT_SET_1, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Display the image at this address."},
3049 { LLDB_OPT_SET_1, false, "arch", 'A', optional_argument, NULL, 0, eArgTypeWidth, "Display the architecture when listing images."},
Greg Claytone1f50b92011-05-03 22:09:39 +00003050 { LLDB_OPT_SET_1, false, "triple", 't', optional_argument, NULL, 0, eArgTypeWidth, "Display the triple when listing images."},
Greg Claytonb5a8f142012-02-05 02:38:54 +00003051 { LLDB_OPT_SET_1, false, "header", 'h', no_argument, NULL, 0, eArgTypeNone, "Display the image header address as a load address if debugging, a file address otherwise."},
3052 { LLDB_OPT_SET_1, false, "offset", 'o', no_argument, NULL, 0, eArgTypeNone, "Display the image header address offset from the header file address (the slide amount)."},
Greg Claytone1f50b92011-05-03 22:09:39 +00003053 { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."},
3054 { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
3055 { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
3056 { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
3057 { LLDB_OPT_SET_1, false, "symfile", 's', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image symbol file with optional width."},
Greg Claytonb5a8f142012-02-05 02:38:54 +00003058 { LLDB_OPT_SET_1, false, "symfile-unique", 'S', optional_argument, NULL, 0, eArgTypeWidth, "Display the symbol file with optional width only if it is different from the executable object file."},
Greg Clayton153ccd72011-08-10 02:10:13 +00003059 { LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."},
3060 { LLDB_OPT_SET_1, false, "ref-count", 'r', optional_argument, NULL, 0, eArgTypeWidth, "Display the reference count if the module is still in the shared module cache."},
3061 { LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."},
Greg Clayton899025f2011-08-09 00:01:09 +00003062 { LLDB_OPT_SET_1, false, "global", 'g', no_argument, NULL, 0, eArgTypeNone, "Display the modules from the global module list, not just the current target."},
Greg Claytone1f50b92011-05-03 22:09:39 +00003063 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3064};
3065
3066
3067
3068//----------------------------------------------------------------------
3069// Lookup information in images
3070//----------------------------------------------------------------------
3071class CommandObjectTargetModulesLookup : public CommandObject
3072{
3073public:
3074
3075 enum
3076 {
3077 eLookupTypeInvalid = -1,
3078 eLookupTypeAddress = 0,
3079 eLookupTypeSymbol,
3080 eLookupTypeFileLine, // Line is optional
3081 eLookupTypeFunction,
3082 eLookupTypeType,
3083 kNumLookupTypes
3084 };
3085
3086 class CommandOptions : public Options
3087 {
3088 public:
3089
3090 CommandOptions (CommandInterpreter &interpreter) :
3091 Options(interpreter)
3092 {
3093 OptionParsingStarting();
3094 }
3095
3096 virtual
3097 ~CommandOptions ()
3098 {
3099 }
3100
3101 virtual Error
3102 SetOptionValue (uint32_t option_idx, const char *option_arg)
3103 {
3104 Error error;
3105
3106 char short_option = (char) m_getopt_table[option_idx].val;
3107
3108 switch (short_option)
3109 {
3110 case 'a':
3111 m_type = eLookupTypeAddress;
3112 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3113 if (m_addr == LLDB_INVALID_ADDRESS)
Greg Clayton9c236732011-10-26 00:56:27 +00003114 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
Greg Claytone1f50b92011-05-03 22:09:39 +00003115 break;
3116
3117 case 'o':
3118 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3119 if (m_offset == LLDB_INVALID_ADDRESS)
Greg Clayton9c236732011-10-26 00:56:27 +00003120 error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
Greg Claytone1f50b92011-05-03 22:09:39 +00003121 break;
3122
3123 case 's':
3124 m_str = option_arg;
3125 m_type = eLookupTypeSymbol;
3126 break;
3127
3128 case 'f':
3129 m_file.SetFile (option_arg, false);
3130 m_type = eLookupTypeFileLine;
3131 break;
3132
3133 case 'i':
Sean Callanan9ad19532012-02-11 01:22:21 +00003134 m_include_inlines = false;
Greg Claytone1f50b92011-05-03 22:09:39 +00003135 break;
3136
3137 case 'l':
3138 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
3139 if (m_line_number == UINT32_MAX)
Greg Clayton9c236732011-10-26 00:56:27 +00003140 error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
Greg Claytone1f50b92011-05-03 22:09:39 +00003141 else if (m_line_number == 0)
Greg Clayton9c236732011-10-26 00:56:27 +00003142 error.SetErrorString ("zero is an invalid line number");
Greg Claytone1f50b92011-05-03 22:09:39 +00003143 m_type = eLookupTypeFileLine;
3144 break;
3145
3146 case 'n':
3147 m_str = option_arg;
3148 m_type = eLookupTypeFunction;
3149 break;
3150
3151 case 't':
3152 m_str = option_arg;
3153 m_type = eLookupTypeType;
3154 break;
3155
3156 case 'v':
3157 m_verbose = 1;
3158 break;
3159
3160 case 'r':
3161 m_use_regex = true;
3162 break;
3163 }
3164
3165 return error;
3166 }
3167
3168 void
3169 OptionParsingStarting ()
3170 {
3171 m_type = eLookupTypeInvalid;
3172 m_str.clear();
3173 m_file.Clear();
3174 m_addr = LLDB_INVALID_ADDRESS;
3175 m_offset = 0;
3176 m_line_number = 0;
3177 m_use_regex = false;
Sean Callanan9ad19532012-02-11 01:22:21 +00003178 m_include_inlines = true;
Greg Claytone1f50b92011-05-03 22:09:39 +00003179 m_verbose = false;
3180 }
3181
3182 const OptionDefinition*
3183 GetDefinitions ()
3184 {
3185 return g_option_table;
3186 }
3187
3188 // Options table: Required for subclasses of Options.
3189
3190 static OptionDefinition g_option_table[];
3191 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3192 std::string m_str; // Holds name lookup
3193 FileSpec m_file; // Files for file lookups
3194 lldb::addr_t m_addr; // Holds the address to lookup
3195 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
3196 uint32_t m_line_number; // Line number for file+line lookups
3197 bool m_use_regex; // Name lookups in m_str are regular expressions.
Sean Callanan9ad19532012-02-11 01:22:21 +00003198 bool m_include_inlines;// Check for inline entries when looking up by file/line.
Greg Claytone1f50b92011-05-03 22:09:39 +00003199 bool m_verbose; // Enable verbose lookup info
3200
3201 };
3202
3203 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
3204 CommandObject (interpreter,
3205 "target modules lookup",
3206 "Look up information within executable and dependent shared library images.",
3207 NULL),
3208 m_options (interpreter)
3209 {
3210 CommandArgumentEntry arg;
3211 CommandArgumentData file_arg;
3212
3213 // Define the first (and only) variant of this arg.
3214 file_arg.arg_type = eArgTypeFilename;
3215 file_arg.arg_repetition = eArgRepeatStar;
3216
3217 // There is only one variant this argument could be; put it into the argument entry.
3218 arg.push_back (file_arg);
3219
3220 // Push the data for the first argument into the m_arguments vector.
3221 m_arguments.push_back (arg);
3222 }
3223
3224 virtual
3225 ~CommandObjectTargetModulesLookup ()
3226 {
3227 }
3228
3229 virtual Options *
3230 GetOptions ()
3231 {
3232 return &m_options;
3233 }
3234
3235
3236 bool
3237 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
3238 {
3239 switch (m_options.m_type)
3240 {
3241 case eLookupTypeAddress:
3242 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
3243 {
3244 if (LookupAddressInModule (m_interpreter,
3245 result.GetOutputStream(),
3246 module,
3247 eSymbolContextEverything,
3248 m_options.m_addr,
3249 m_options.m_offset,
3250 m_options.m_verbose))
3251 {
3252 result.SetStatus(eReturnStatusSuccessFinishResult);
3253 return true;
3254 }
3255 }
3256 break;
3257
3258 case eLookupTypeSymbol:
3259 if (!m_options.m_str.empty())
3260 {
3261 if (LookupSymbolInModule (m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex))
3262 {
3263 result.SetStatus(eReturnStatusSuccessFinishResult);
3264 return true;
3265 }
3266 }
3267 break;
3268
3269 case eLookupTypeFileLine:
3270 if (m_options.m_file)
3271 {
3272
3273 if (LookupFileAndLineInModule (m_interpreter,
3274 result.GetOutputStream(),
3275 module,
3276 m_options.m_file,
3277 m_options.m_line_number,
Sean Callanan9ad19532012-02-11 01:22:21 +00003278 m_options.m_include_inlines,
Greg Claytone1f50b92011-05-03 22:09:39 +00003279 m_options.m_verbose))
3280 {
3281 result.SetStatus(eReturnStatusSuccessFinishResult);
3282 return true;
3283 }
3284 }
3285 break;
3286
3287 case eLookupTypeFunction:
3288 if (!m_options.m_str.empty())
3289 {
3290 if (LookupFunctionInModule (m_interpreter,
3291 result.GetOutputStream(),
3292 module,
3293 m_options.m_str.c_str(),
3294 m_options.m_use_regex,
Sean Callanan9ad19532012-02-11 01:22:21 +00003295 m_options.m_include_inlines,
Greg Claytone1f50b92011-05-03 22:09:39 +00003296 m_options.m_verbose))
3297 {
3298 result.SetStatus(eReturnStatusSuccessFinishResult);
3299 return true;
3300 }
3301 }
3302 break;
3303
3304 case eLookupTypeType:
3305 if (!m_options.m_str.empty())
3306 {
3307 if (LookupTypeInModule (m_interpreter,
3308 result.GetOutputStream(),
3309 module,
3310 m_options.m_str.c_str(),
3311 m_options.m_use_regex))
3312 {
3313 result.SetStatus(eReturnStatusSuccessFinishResult);
3314 return true;
3315 }
3316 }
3317 break;
3318
3319 default:
3320 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
3321 syntax_error = true;
3322 break;
3323 }
3324
3325 result.SetStatus (eReturnStatusFailed);
3326 return false;
3327 }
3328
3329 virtual bool
3330 Execute (Args& command,
3331 CommandReturnObject &result)
3332 {
3333 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3334 if (target == NULL)
3335 {
3336 result.AppendError ("invalid target, create a debug target using the 'target create' command");
3337 result.SetStatus (eReturnStatusFailed);
3338 return false;
3339 }
3340 else
3341 {
3342 bool syntax_error = false;
3343 uint32_t i;
3344 uint32_t num_successful_lookups = 0;
3345 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3346 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3347 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3348 // Dump all sections for all modules images
3349
3350 if (command.GetArgumentCount() == 0)
3351 {
3352 // Dump all sections for all modules images
3353 const uint32_t num_modules = target->GetImages().GetSize();
3354 if (num_modules > 0)
3355 {
3356 for (i = 0; i<num_modules && syntax_error == false; ++i)
3357 {
3358 if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
3359 {
3360 result.GetOutputStream().EOL();
3361 num_successful_lookups++;
3362 }
3363 }
3364 }
3365 else
3366 {
3367 result.AppendError ("the target has no associated executable images");
3368 result.SetStatus (eReturnStatusFailed);
3369 return false;
3370 }
3371 }
3372 else
3373 {
3374 // Dump specified images (by basename or fullpath)
3375 const char *arg_cstr;
3376 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
3377 {
Greg Clayton91048ef2011-11-10 01:18:58 +00003378 ModuleList module_list;
3379 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
3380 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00003381 {
Greg Clayton91048ef2011-11-10 01:18:58 +00003382 for (size_t i=0; i<num_matches; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00003383 {
Greg Clayton91048ef2011-11-10 01:18:58 +00003384 Module *module = module_list.GetModulePointerAtIndex(i);
3385 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00003386 {
Greg Clayton91048ef2011-11-10 01:18:58 +00003387 if (LookupInModule (m_interpreter, module, result, syntax_error))
Greg Claytone1f50b92011-05-03 22:09:39 +00003388 {
3389 result.GetOutputStream().EOL();
3390 num_successful_lookups++;
3391 }
3392 }
3393 }
3394 }
3395 else
3396 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
3397 }
3398 }
3399
3400 if (num_successful_lookups > 0)
3401 result.SetStatus (eReturnStatusSuccessFinishResult);
3402 else
3403 result.SetStatus (eReturnStatusFailed);
3404 }
3405 return result.Succeeded();
3406 }
3407protected:
3408
3409 CommandOptions m_options;
3410};
3411
3412OptionDefinition
3413CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
3414{
3415 { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more target modules."},
3416 { 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 +00003417 { LLDB_OPT_SET_2| LLDB_OPT_SET_4
3418 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_5 */ ,
3419 false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."},
Greg Claytone1f50b92011-05-03 22:09:39 +00003420 { 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 +00003421 { 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."},
3422 { 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)."},
Sean Callanan9ad19532012-02-11 01:22:21 +00003423 { LLDB_OPT_SET_3|
3424 LLDB_OPT_SET_4, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Ignore inline entries (must be used in conjunction with --file or --function)."},
Greg Claytone1f50b92011-05-03 22:09:39 +00003425 { 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."},
3426 { 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."},
3427 { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."},
3428 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3429};
Chris Lattner24943d22010-06-08 16:52:24 +00003430
3431
Jim Inghamd60d94a2011-03-11 03:53:59 +00003432#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner24943d22010-06-08 16:52:24 +00003433
3434//-------------------------------------------------------------------------
3435// CommandObjectMultiwordImageSearchPaths
3436//-------------------------------------------------------------------------
3437
Greg Claytone1f50b92011-05-03 22:09:39 +00003438class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
Chris Lattner24943d22010-06-08 16:52:24 +00003439{
3440public:
Greg Claytone1f50b92011-05-03 22:09:39 +00003441
3442 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
3443 CommandObjectMultiword (interpreter,
3444 "target modules search-paths",
3445 "A set of commands for operating on debugger target image search paths.",
3446 "target modules search-paths <subcommand> [<subcommand-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +00003447 {
Greg Claytone1f50b92011-05-03 22:09:39 +00003448 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
3449 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
3450 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
3451 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
3452 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00003453 }
Greg Claytone1f50b92011-05-03 22:09:39 +00003454
3455 ~CommandObjectTargetModulesImageSearchPaths()
Chris Lattner24943d22010-06-08 16:52:24 +00003456 {
3457 }
3458};
3459
Greg Claytone1f50b92011-05-03 22:09:39 +00003460
3461
3462#pragma mark CommandObjectTargetModules
3463
3464//-------------------------------------------------------------------------
3465// CommandObjectTargetModules
3466//-------------------------------------------------------------------------
3467
3468class CommandObjectTargetModules : public CommandObjectMultiword
3469{
3470public:
3471 //------------------------------------------------------------------
3472 // Constructors and Destructors
3473 //------------------------------------------------------------------
3474 CommandObjectTargetModules(CommandInterpreter &interpreter) :
3475 CommandObjectMultiword (interpreter,
3476 "target modules",
3477 "A set of commands for accessing information for one or more target modules.",
3478 "target modules <sub-command> ...")
3479 {
3480 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
3481 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
3482 //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter)));
3483 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
3484 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
3485 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
3486 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
3487
3488 }
3489 virtual
3490 ~CommandObjectTargetModules()
3491 {
3492 }
3493
3494private:
3495 //------------------------------------------------------------------
3496 // For CommandObjectTargetModules only
3497 //------------------------------------------------------------------
3498 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
3499};
3500
3501
Jim Inghamd60d94a2011-03-11 03:53:59 +00003502#pragma mark CommandObjectTargetStopHookAdd
3503
3504//-------------------------------------------------------------------------
3505// CommandObjectTargetStopHookAdd
3506//-------------------------------------------------------------------------
3507
3508class CommandObjectTargetStopHookAdd : public CommandObject
3509{
3510public:
3511
3512 class CommandOptions : public Options
3513 {
3514 public:
Greg Claytonf15996e2011-04-07 22:46:35 +00003515 CommandOptions (CommandInterpreter &interpreter) :
3516 Options(interpreter),
Jim Inghamd60d94a2011-03-11 03:53:59 +00003517 m_line_start(0),
3518 m_line_end (UINT_MAX),
3519 m_func_name_type_mask (eFunctionNameTypeAuto),
3520 m_sym_ctx_specified (false),
Johnny Chen60fe60e2011-05-02 23:47:55 +00003521 m_thread_specified (false),
3522 m_use_one_liner (false),
3523 m_one_liner()
Jim Inghamd60d94a2011-03-11 03:53:59 +00003524 {
3525 }
3526
3527 ~CommandOptions () {}
3528
Greg Claytonb3448432011-03-24 21:19:54 +00003529 const OptionDefinition*
Jim Inghamd60d94a2011-03-11 03:53:59 +00003530 GetDefinitions ()
3531 {
3532 return g_option_table;
3533 }
3534
3535 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +00003536 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003537 {
3538 Error error;
3539 char short_option = (char) m_getopt_table[option_idx].val;
3540 bool success;
3541
3542 switch (short_option)
3543 {
3544 case 'c':
3545 m_class_name = option_arg;
3546 m_sym_ctx_specified = true;
3547 break;
3548
3549 case 'e':
3550 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
3551 if (!success)
3552 {
Greg Clayton9c236732011-10-26 00:56:27 +00003553 error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003554 break;
3555 }
3556 m_sym_ctx_specified = true;
3557 break;
3558
3559 case 'l':
3560 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
3561 if (!success)
3562 {
Greg Clayton9c236732011-10-26 00:56:27 +00003563 error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003564 break;
3565 }
3566 m_sym_ctx_specified = true;
3567 break;
Sean Callanan9ad19532012-02-11 01:22:21 +00003568
3569 case 'i':
3570 m_no_inlines = true;
3571 break;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003572
3573 case 'n':
3574 m_function_name = option_arg;
3575 m_func_name_type_mask |= eFunctionNameTypeAuto;
3576 m_sym_ctx_specified = true;
3577 break;
3578
3579 case 'f':
3580 m_file_name = option_arg;
3581 m_sym_ctx_specified = true;
3582 break;
3583 case 's':
3584 m_module_name = option_arg;
3585 m_sym_ctx_specified = true;
3586 break;
3587 case 't' :
3588 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003589 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003590 if (m_thread_id == LLDB_INVALID_THREAD_ID)
Greg Clayton9c236732011-10-26 00:56:27 +00003591 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003592 m_thread_specified = true;
3593 }
3594 break;
3595 case 'T':
3596 m_thread_name = option_arg;
3597 m_thread_specified = true;
3598 break;
3599 case 'q':
3600 m_queue_name = option_arg;
3601 m_thread_specified = true;
3602 break;
3603 case 'x':
3604 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003605 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003606 if (m_thread_id == UINT32_MAX)
Greg Clayton9c236732011-10-26 00:56:27 +00003607 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003608 m_thread_specified = true;
3609 }
3610 break;
Johnny Chen60fe60e2011-05-02 23:47:55 +00003611 case 'o':
3612 m_use_one_liner = true;
3613 m_one_liner = option_arg;
3614 break;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003615 default:
Greg Clayton9c236732011-10-26 00:56:27 +00003616 error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003617 break;
3618 }
3619 return error;
3620 }
3621
3622 void
Greg Clayton143fcc32011-04-13 00:18:08 +00003623 OptionParsingStarting ()
Jim Inghamd60d94a2011-03-11 03:53:59 +00003624 {
3625 m_class_name.clear();
3626 m_function_name.clear();
3627 m_line_start = 0;
3628 m_line_end = UINT_MAX;
3629 m_file_name.clear();
3630 m_module_name.clear();
3631 m_func_name_type_mask = eFunctionNameTypeAuto;
3632 m_thread_id = LLDB_INVALID_THREAD_ID;
3633 m_thread_index = UINT32_MAX;
3634 m_thread_name.clear();
3635 m_queue_name.clear();
Sean Callanan9ad19532012-02-11 01:22:21 +00003636
3637 m_no_inlines = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003638 m_sym_ctx_specified = false;
3639 m_thread_specified = false;
Johnny Chen60fe60e2011-05-02 23:47:55 +00003640
3641 m_use_one_liner = false;
3642 m_one_liner.clear();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003643 }
3644
3645
Greg Claytonb3448432011-03-24 21:19:54 +00003646 static OptionDefinition g_option_table[];
Jim Inghamd60d94a2011-03-11 03:53:59 +00003647
3648 std::string m_class_name;
3649 std::string m_function_name;
3650 uint32_t m_line_start;
3651 uint32_t m_line_end;
3652 std::string m_file_name;
3653 std::string m_module_name;
3654 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
3655 lldb::tid_t m_thread_id;
3656 uint32_t m_thread_index;
3657 std::string m_thread_name;
3658 std::string m_queue_name;
3659 bool m_sym_ctx_specified;
Sean Callanan9ad19532012-02-11 01:22:21 +00003660 bool m_no_inlines;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003661 bool m_thread_specified;
Johnny Chen60fe60e2011-05-02 23:47:55 +00003662 // Instance variables to hold the values for one_liner options.
3663 bool m_use_one_liner;
3664 std::string m_one_liner;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003665 };
3666
3667 Options *
3668 GetOptions ()
3669 {
3670 return &m_options;
3671 }
3672
3673 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
3674 CommandObject (interpreter,
3675 "target stop-hook add ",
3676 "Add a hook to be executed when the target stops.",
Greg Claytonf15996e2011-04-07 22:46:35 +00003677 "target stop-hook add"),
3678 m_options (interpreter)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003679 {
3680 }
3681
3682 ~CommandObjectTargetStopHookAdd ()
3683 {
3684 }
3685
3686 static size_t
3687 ReadCommandsCallbackFunction (void *baton,
3688 InputReader &reader,
3689 lldb::InputReaderAction notification,
3690 const char *bytes,
3691 size_t bytes_len)
3692 {
Caroline Tice892fadd2011-06-16 16:27:19 +00003693 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003694 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
Jim Inghame15511a2011-05-05 01:03:36 +00003695 static bool got_interrupted;
Caroline Tice892fadd2011-06-16 16:27:19 +00003696 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003697
3698 switch (notification)
3699 {
3700 case eInputReaderActivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00003701 if (!batch_mode)
3702 {
3703 out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end.");
3704 if (reader.GetPrompt())
3705 out_stream->Printf ("%s", reader.GetPrompt());
3706 out_stream->Flush();
3707 }
Jim Inghame15511a2011-05-05 01:03:36 +00003708 got_interrupted = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003709 break;
3710
3711 case eInputReaderDeactivate:
3712 break;
3713
3714 case eInputReaderReactivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00003715 if (reader.GetPrompt() && !batch_mode)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003716 {
Caroline Tice892fadd2011-06-16 16:27:19 +00003717 out_stream->Printf ("%s", reader.GetPrompt());
3718 out_stream->Flush();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003719 }
Jim Inghame15511a2011-05-05 01:03:36 +00003720 got_interrupted = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003721 break;
3722
Caroline Tice4a348082011-05-02 20:41:46 +00003723 case eInputReaderAsynchronousOutputWritten:
3724 break;
3725
Jim Inghamd60d94a2011-03-11 03:53:59 +00003726 case eInputReaderGotToken:
3727 if (bytes && bytes_len && baton)
3728 {
3729 StringList *commands = new_stop_hook->GetCommandPointer();
3730 if (commands)
3731 {
3732 commands->AppendString (bytes, bytes_len);
3733 }
3734 }
Caroline Tice892fadd2011-06-16 16:27:19 +00003735 if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003736 {
Caroline Tice892fadd2011-06-16 16:27:19 +00003737 out_stream->Printf ("%s", reader.GetPrompt());
3738 out_stream->Flush();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003739 }
3740 break;
3741
3742 case eInputReaderInterrupt:
3743 {
3744 // Finish, and cancel the stop hook.
3745 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
Caroline Tice892fadd2011-06-16 16:27:19 +00003746 if (!batch_mode)
3747 {
3748 out_stream->Printf ("Stop hook cancelled.\n");
3749 out_stream->Flush();
3750 }
3751
Jim Inghamd60d94a2011-03-11 03:53:59 +00003752 reader.SetIsDone (true);
3753 }
Jim Inghame15511a2011-05-05 01:03:36 +00003754 got_interrupted = true;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003755 break;
3756
3757 case eInputReaderEndOfFile:
3758 reader.SetIsDone (true);
3759 break;
3760
3761 case eInputReaderDone:
Caroline Tice892fadd2011-06-16 16:27:19 +00003762 if (!got_interrupted && !batch_mode)
3763 {
Greg Clayton444e35b2011-10-19 18:09:39 +00003764 out_stream->Printf ("Stop hook #%llu added.\n", new_stop_hook->GetID());
Caroline Tice892fadd2011-06-16 16:27:19 +00003765 out_stream->Flush();
3766 }
Jim Inghamd60d94a2011-03-11 03:53:59 +00003767 break;
3768 }
3769
3770 return bytes_len;
3771 }
3772
3773 bool
3774 Execute (Args& command,
3775 CommandReturnObject &result)
3776 {
3777 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3778 if (target)
3779 {
3780 Target::StopHookSP new_hook_sp;
3781 target->AddStopHook (new_hook_sp);
3782
3783 // First step, make the specifier.
3784 std::auto_ptr<SymbolContextSpecifier> specifier_ap;
3785 if (m_options.m_sym_ctx_specified)
3786 {
3787 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
3788
3789 if (!m_options.m_module_name.empty())
3790 {
3791 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
3792 }
3793
3794 if (!m_options.m_class_name.empty())
3795 {
3796 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
3797 }
3798
3799 if (!m_options.m_file_name.empty())
3800 {
3801 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
3802 }
3803
3804 if (m_options.m_line_start != 0)
3805 {
3806 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
3807 }
3808
3809 if (m_options.m_line_end != UINT_MAX)
3810 {
3811 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
3812 }
3813
3814 if (!m_options.m_function_name.empty())
3815 {
3816 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
3817 }
3818 }
3819
3820 if (specifier_ap.get())
3821 new_hook_sp->SetSpecifier (specifier_ap.release());
3822
3823 // Next see if any of the thread options have been entered:
3824
3825 if (m_options.m_thread_specified)
3826 {
3827 ThreadSpec *thread_spec = new ThreadSpec();
3828
3829 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
3830 {
3831 thread_spec->SetTID (m_options.m_thread_id);
3832 }
3833
3834 if (m_options.m_thread_index != UINT32_MAX)
3835 thread_spec->SetIndex (m_options.m_thread_index);
3836
3837 if (!m_options.m_thread_name.empty())
3838 thread_spec->SetName (m_options.m_thread_name.c_str());
3839
3840 if (!m_options.m_queue_name.empty())
3841 thread_spec->SetQueueName (m_options.m_queue_name.c_str());
3842
3843 new_hook_sp->SetThreadSpecifier (thread_spec);
3844
3845 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00003846 if (m_options.m_use_one_liner)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003847 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00003848 // Use one-liner.
3849 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
Greg Clayton444e35b2011-10-19 18:09:39 +00003850 result.AppendMessageWithFormat("Stop hook #%llu added.\n", new_hook_sp->GetID());
Jim Inghamd60d94a2011-03-11 03:53:59 +00003851 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00003852 else
Jim Inghamd60d94a2011-03-11 03:53:59 +00003853 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00003854 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into
3855 // the new stop hook's command string.
3856 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
3857 if (!reader_sp)
3858 {
3859 result.AppendError("out of memory\n");
3860 result.SetStatus (eReturnStatusFailed);
3861 target->RemoveStopHookByID (new_hook_sp->GetID());
3862 return false;
3863 }
3864
3865 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
3866 new_hook_sp.get(), // baton
3867 eInputReaderGranularityLine, // token size, to pass to callback function
3868 "DONE", // end token
3869 "> ", // prompt
3870 true)); // echo input
3871 if (!err.Success())
3872 {
3873 result.AppendError (err.AsCString());
3874 result.SetStatus (eReturnStatusFailed);
3875 target->RemoveStopHookByID (new_hook_sp->GetID());
3876 return false;
3877 }
3878 m_interpreter.GetDebugger().PushInputReader (reader_sp);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003879 }
Jim Inghamd60d94a2011-03-11 03:53:59 +00003880 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3881 }
3882 else
3883 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003884 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003885 result.SetStatus (eReturnStatusFailed);
3886 }
3887
3888 return result.Succeeded();
3889 }
3890private:
3891 CommandOptions m_options;
3892};
3893
Greg Claytonb3448432011-03-24 21:19:54 +00003894OptionDefinition
Jim Inghamd60d94a2011-03-11 03:53:59 +00003895CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
3896{
Johnny Chen60fe60e2011-05-02 23:47:55 +00003897 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, NULL, eArgTypeOneLiner,
3898 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
Jim Inghamd60d94a2011-03-11 03:53:59 +00003899 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3900 "Set the module within which the stop-hook is to be run."},
3901 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex,
3902 "The stop hook is run only for the thread whose index matches this argument."},
3903 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID,
3904 "The stop hook is run only for the thread whose TID matches this argument."},
3905 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName,
3906 "The stop hook is run only for the thread whose thread name matches this argument."},
3907 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName,
3908 "The stop hook is run only for threads in the queue whose name is given by this argument."},
3909 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
3910 "Specify the source file within which the stop-hook is to be run." },
3911 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
3912 "Set the start of the line range for which the stop-hook is to be run."},
3913 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum,
3914 "Set the end of the line range for which the stop-hook is to be run."},
3915 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName,
3916 "Specify the class within which the stop-hook is to be run." },
3917 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
3918 "Set the function name within which the stop hook will be run." },
3919 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3920};
3921
3922#pragma mark CommandObjectTargetStopHookDelete
3923
3924//-------------------------------------------------------------------------
3925// CommandObjectTargetStopHookDelete
3926//-------------------------------------------------------------------------
3927
3928class CommandObjectTargetStopHookDelete : public CommandObject
3929{
3930public:
3931
3932 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
3933 CommandObject (interpreter,
Jason Molenda3fccc902011-11-10 23:03:44 +00003934 "target stop-hook delete",
Jim Inghamd60d94a2011-03-11 03:53:59 +00003935 "Delete a stop-hook.",
Jason Molenda3fccc902011-11-10 23:03:44 +00003936 "target stop-hook delete [<idx>]")
Jim Inghamd60d94a2011-03-11 03:53:59 +00003937 {
3938 }
3939
3940 ~CommandObjectTargetStopHookDelete ()
3941 {
3942 }
3943
3944 bool
3945 Execute (Args& command,
3946 CommandReturnObject &result)
3947 {
3948 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3949 if (target)
3950 {
3951 // FIXME: see if we can use the breakpoint id style parser?
3952 size_t num_args = command.GetArgumentCount();
3953 if (num_args == 0)
3954 {
3955 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
3956 {
3957 result.SetStatus (eReturnStatusFailed);
3958 return false;
3959 }
3960 else
3961 {
3962 target->RemoveAllStopHooks();
3963 }
3964 }
3965 else
3966 {
3967 bool success;
3968 for (size_t i = 0; i < num_args; i++)
3969 {
3970 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
3971 if (!success)
3972 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003973 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003974 result.SetStatus(eReturnStatusFailed);
3975 return false;
3976 }
3977 success = target->RemoveStopHookByID (user_id);
3978 if (!success)
3979 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003980 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003981 result.SetStatus(eReturnStatusFailed);
3982 return false;
3983 }
3984 }
3985 }
3986 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3987 }
3988 else
3989 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003990 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003991 result.SetStatus (eReturnStatusFailed);
3992 }
3993
3994 return result.Succeeded();
3995 }
3996};
3997#pragma mark CommandObjectTargetStopHookEnableDisable
3998
3999//-------------------------------------------------------------------------
4000// CommandObjectTargetStopHookEnableDisable
4001//-------------------------------------------------------------------------
4002
4003class CommandObjectTargetStopHookEnableDisable : public CommandObject
4004{
4005public:
4006
4007 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
4008 CommandObject (interpreter,
4009 name,
4010 help,
4011 syntax),
4012 m_enable (enable)
4013 {
4014 }
4015
4016 ~CommandObjectTargetStopHookEnableDisable ()
4017 {
4018 }
4019
4020 bool
4021 Execute (Args& command,
4022 CommandReturnObject &result)
4023 {
4024 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4025 if (target)
4026 {
4027 // FIXME: see if we can use the breakpoint id style parser?
4028 size_t num_args = command.GetArgumentCount();
4029 bool success;
4030
4031 if (num_args == 0)
4032 {
4033 target->SetAllStopHooksActiveState (m_enable);
4034 }
4035 else
4036 {
4037 for (size_t i = 0; i < num_args; i++)
4038 {
4039 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
4040 if (!success)
4041 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004042 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00004043 result.SetStatus(eReturnStatusFailed);
4044 return false;
4045 }
4046 success = target->SetStopHookActiveStateByID (user_id, m_enable);
4047 if (!success)
4048 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004049 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00004050 result.SetStatus(eReturnStatusFailed);
4051 return false;
4052 }
4053 }
4054 }
4055 result.SetStatus (eReturnStatusSuccessFinishNoResult);
4056 }
4057 else
4058 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004059 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00004060 result.SetStatus (eReturnStatusFailed);
4061 }
4062 return result.Succeeded();
4063 }
4064private:
4065 bool m_enable;
4066};
4067
4068#pragma mark CommandObjectTargetStopHookList
4069
4070//-------------------------------------------------------------------------
4071// CommandObjectTargetStopHookList
4072//-------------------------------------------------------------------------
4073
4074class CommandObjectTargetStopHookList : public CommandObject
4075{
4076public:
4077
4078 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
4079 CommandObject (interpreter,
Jason Molenda3fccc902011-11-10 23:03:44 +00004080 "target stop-hook list",
Jim Inghamd60d94a2011-03-11 03:53:59 +00004081 "List all stop-hooks.",
Jason Molenda3fccc902011-11-10 23:03:44 +00004082 "target stop-hook list [<type>]")
Jim Inghamd60d94a2011-03-11 03:53:59 +00004083 {
4084 }
4085
4086 ~CommandObjectTargetStopHookList ()
4087 {
4088 }
4089
4090 bool
4091 Execute (Args& command,
4092 CommandReturnObject &result)
4093 {
4094 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Johnny Chen9fc16922011-11-29 23:56:14 +00004095 if (!target)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004096 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004097 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00004098 result.SetStatus (eReturnStatusFailed);
Jason Molenda6e3a2412011-09-23 21:15:42 +00004099 return result.Succeeded();
Jim Inghamd60d94a2011-03-11 03:53:59 +00004100 }
4101
4102 size_t num_hooks = target->GetNumStopHooks ();
4103 if (num_hooks == 0)
4104 {
4105 result.GetOutputStream().PutCString ("No stop hooks.\n");
4106 }
4107 else
4108 {
4109 for (size_t i = 0; i < num_hooks; i++)
4110 {
4111 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
4112 if (i > 0)
4113 result.GetOutputStream().PutCString ("\n");
4114 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
4115 }
4116 }
Johnny Chen6c7c3902011-11-30 19:09:20 +00004117 result.SetStatus (eReturnStatusSuccessFinishResult);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004118 return result.Succeeded();
4119 }
4120};
4121
4122#pragma mark CommandObjectMultiwordTargetStopHooks
4123//-------------------------------------------------------------------------
4124// CommandObjectMultiwordTargetStopHooks
4125//-------------------------------------------------------------------------
4126
4127class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
4128{
4129public:
4130
4131 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
4132 CommandObjectMultiword (interpreter,
4133 "target stop-hook",
4134 "A set of commands for operating on debugger target stop-hooks.",
4135 "target stop-hook <subcommand> [<subcommand-options>]")
4136 {
4137 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
4138 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
4139 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
4140 false,
4141 "target stop-hook disable [<id>]",
4142 "Disable a stop-hook.",
4143 "target stop-hook disable")));
4144 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
4145 true,
4146 "target stop-hook enable [<id>]",
4147 "Enable a stop-hook.",
4148 "target stop-hook enable")));
4149 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
4150 }
4151
4152 ~CommandObjectMultiwordTargetStopHooks()
4153 {
4154 }
4155};
4156
4157
Chris Lattner24943d22010-06-08 16:52:24 +00004158
4159#pragma mark CommandObjectMultiwordTarget
4160
4161//-------------------------------------------------------------------------
4162// CommandObjectMultiwordTarget
4163//-------------------------------------------------------------------------
4164
Greg Clayton63094e02010-06-23 01:19:29 +00004165CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00004166 CommandObjectMultiword (interpreter,
4167 "target",
Chris Lattner24943d22010-06-08 16:52:24 +00004168 "A set of commands for operating on debugger targets.",
4169 "target <subcommand> [<subcommand-options>]")
4170{
Greg Claytonabe0fed2011-04-18 08:33:37 +00004171
4172 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
Greg Clayton153ccd72011-08-10 02:10:13 +00004173 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
Greg Claytonabe0fed2011-04-18 08:33:37 +00004174 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter)));
4175 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
Jim Inghamd60d94a2011-03-11 03:53:59 +00004176 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
Greg Claytone1f50b92011-05-03 22:09:39 +00004177 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter)));
Greg Clayton801417e2011-07-07 01:59:51 +00004178 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00004179}
4180
4181CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
4182{
4183}
4184
Greg Claytonabe0fed2011-04-18 08:33:37 +00004185