blob: a31a8ec3e2eaf3ef7e7261dcb74a15b271e3b612 [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 }
1488 sc.DumpStopContext(&strm,
1489 exe_scope,
1490 sc.line_entry.range.GetBaseAddress(),
1491 true,
1492 true,
1493 false);
1494 strm.EOL();
1495 if (verbose)
1496 {
1497 if (sc.line_entry.range.GetBaseAddress().IsValid())
1498 {
1499 if (sc.line_entry.range.GetBaseAddress().Dump (&strm,
1500 exe_scope,
1501 Address::DumpStyleDetailedSymbolContext))
1502 strm.PutCString("\n\n");
1503 }
1504 else if (sc.function->GetAddressRange().GetBaseAddress().IsValid())
1505 {
1506 if (sc.function->GetAddressRange().GetBaseAddress().Dump (&strm,
1507 exe_scope,
1508 Address::DumpStyleDetailedSymbolContext))
1509 strm.PutCString("\n\n");
1510 }
1511 }
1512 }
1513 }
1514 strm.IndentLess ();
1515}
1516
1517static uint32_t
1518LookupFunctionInModule (CommandInterpreter &interpreter, Stream &strm, Module *module, const char *name, bool name_is_regex, bool verbose)
1519{
1520 if (module && name && name[0])
1521 {
1522 SymbolContextList sc_list;
1523 const bool include_symbols = false;
1524 const bool append = true;
1525 uint32_t num_matches = 0;
1526 if (name_is_regex)
1527 {
1528 RegularExpression function_name_regex (name);
1529 num_matches = module->FindFunctions (function_name_regex,
1530 include_symbols,
1531 append,
1532 sc_list);
1533 }
1534 else
1535 {
1536 ConstString function_name (name);
Sean Callanan3e80cd92011-10-12 02:08:07 +00001537 num_matches = module->FindFunctions (function_name,
1538 NULL,
Greg Claytone1f50b92011-05-03 22:09:39 +00001539 eFunctionNameTypeBase | eFunctionNameTypeFull | eFunctionNameTypeMethod | eFunctionNameTypeSelector,
1540 include_symbols,
1541 append,
1542 sc_list);
1543 }
1544
1545 if (num_matches)
1546 {
1547 strm.Indent ();
1548 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1549 DumpFullpath (strm, &module->GetFileSpec(), 0);
1550 strm.PutCString(":\n");
1551 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
1552 }
1553 return num_matches;
1554 }
1555 return 0;
1556}
1557
1558static uint32_t
Greg Clayton801417e2011-07-07 01:59:51 +00001559LookupTypeInModule (CommandInterpreter &interpreter,
1560 Stream &strm,
1561 Module *module,
1562 const char *name_cstr,
1563 bool name_is_regex)
Greg Claytone1f50b92011-05-03 22:09:39 +00001564{
1565 if (module && name_cstr && name_cstr[0])
1566 {
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001567 TypeList type_list;
1568 const uint32_t max_num_matches = 1;
1569 uint32_t num_matches = 0;
1570 SymbolContext sc;
1571
1572 ConstString name(name_cstr);
1573 num_matches = module->FindTypes(sc, name, NULL, true, max_num_matches, type_list);
Greg Claytone1f50b92011-05-03 22:09:39 +00001574
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001575 if (num_matches)
1576 {
1577 strm.Indent ();
1578 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1579 DumpFullpath (strm, &module->GetFileSpec(), 0);
1580 strm.PutCString(":\n");
1581 const uint32_t num_types = type_list.GetSize();
1582 for (uint32_t i=0; i<num_types; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00001583 {
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001584 TypeSP type_sp (type_list.GetTypeAtIndex(i));
1585 if (type_sp)
Greg Claytone1f50b92011-05-03 22:09:39 +00001586 {
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001587 // Resolve the clang type so that any forward references
1588 // to types that haven't yet been parsed will get parsed.
1589 type_sp->GetClangFullType ();
1590 type_sp->GetDescription (&strm, eDescriptionLevelFull, true);
Greg Claytone1f50b92011-05-03 22:09:39 +00001591 }
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001592 strm.EOL();
Greg Claytone1f50b92011-05-03 22:09:39 +00001593 }
Greg Clayton37bb8dd2011-12-08 02:13:16 +00001594 }
1595 return num_matches;
Greg Claytone1f50b92011-05-03 22:09:39 +00001596 }
1597 return 0;
1598}
1599
1600static uint32_t
1601LookupFileAndLineInModule (CommandInterpreter &interpreter,
1602 Stream &strm,
1603 Module *module,
1604 const FileSpec &file_spec,
1605 uint32_t line,
1606 bool check_inlines,
1607 bool verbose)
1608{
1609 if (module && file_spec)
1610 {
1611 SymbolContextList sc_list;
1612 const uint32_t num_matches = module->ResolveSymbolContextsForFileSpec(file_spec, line, check_inlines,
1613 eSymbolContextEverything, sc_list);
1614 if (num_matches > 0)
1615 {
1616 strm.Indent ();
1617 strm.Printf("%u match%s found in ", num_matches, num_matches > 1 ? "es" : "");
1618 strm << file_spec;
1619 if (line > 0)
1620 strm.Printf (":%u", line);
1621 strm << " in ";
1622 DumpFullpath (strm, &module->GetFileSpec(), 0);
1623 strm.PutCString(":\n");
1624 DumpSymbolContextList (interpreter, strm, sc_list, true, verbose);
1625 return num_matches;
1626 }
1627 }
1628 return 0;
1629
1630}
1631
Greg Clayton91048ef2011-11-10 01:18:58 +00001632
1633static size_t
1634FindModulesByName (Target *target,
1635 const char *module_name,
1636 ModuleList &module_list,
1637 bool check_global_list)
1638{
1639// Dump specified images (by basename or fullpath)
1640 FileSpec module_file_spec(module_name, false);
1641
1642 const size_t initial_size = module_list.GetSize ();
1643
1644 size_t num_matches = 0;
1645
1646 if (target)
1647 {
1648 num_matches = target->GetImages().FindModules (&module_file_spec,
1649 NULL,
1650 NULL,
1651 NULL,
1652 module_list);
1653
1654 // Not found in our module list for our target, check the main
1655 // shared module list in case it is a extra file used somewhere
1656 // else
1657 if (num_matches == 0)
1658 num_matches = ModuleList::FindSharedModules (module_file_spec,
1659 target->GetArchitecture(),
1660 NULL,
1661 NULL,
1662 module_list);
1663 }
1664 else
1665 {
1666 num_matches = ModuleList::FindSharedModules (module_file_spec,
1667 ArchSpec(),
1668 NULL,
1669 NULL,
1670 module_list);
1671 }
1672
1673 if (check_global_list && num_matches == 0)
1674 {
1675 // Check the global list
Greg Claytonc149c8b2012-01-27 18:08:35 +00001676 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
Greg Clayton91048ef2011-11-10 01:18:58 +00001677 const uint32_t num_modules = Module::GetNumberAllocatedModules();
1678 ModuleSP module_sp;
1679 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1680 {
1681 Module *module = Module::GetAllocatedModuleAtIndex(image_idx);
1682
1683 if (module)
1684 {
1685 if (FileSpec::Equal(module->GetFileSpec(), module_file_spec, true))
1686 {
Greg Clayton13d24fb2012-01-29 20:56:30 +00001687 module_sp = module->shared_from_this();
Greg Clayton91048ef2011-11-10 01:18:58 +00001688 module_list.AppendIfNeeded(module_sp);
1689 }
1690 }
1691 }
1692 }
1693 return module_list.GetSize () - initial_size;
1694}
1695
Greg Claytone1f50b92011-05-03 22:09:39 +00001696#pragma mark CommandObjectTargetModulesModuleAutoComplete
1697
1698//----------------------------------------------------------------------
1699// A base command object class that can auto complete with module file
1700// paths
1701//----------------------------------------------------------------------
1702
1703class CommandObjectTargetModulesModuleAutoComplete : public CommandObject
1704{
1705public:
1706
1707 CommandObjectTargetModulesModuleAutoComplete (CommandInterpreter &interpreter,
1708 const char *name,
1709 const char *help,
1710 const char *syntax) :
1711 CommandObject (interpreter, name, help, syntax)
1712 {
1713 CommandArgumentEntry arg;
1714 CommandArgumentData file_arg;
1715
1716 // Define the first (and only) variant of this arg.
1717 file_arg.arg_type = eArgTypeFilename;
1718 file_arg.arg_repetition = eArgRepeatStar;
1719
1720 // There is only one variant this argument could be; put it into the argument entry.
1721 arg.push_back (file_arg);
1722
1723 // Push the data for the first argument into the m_arguments vector.
1724 m_arguments.push_back (arg);
1725 }
1726
1727 virtual
1728 ~CommandObjectTargetModulesModuleAutoComplete ()
1729 {
1730 }
1731
1732 virtual int
1733 HandleArgumentCompletion (Args &input,
1734 int &cursor_index,
1735 int &cursor_char_position,
1736 OptionElementVector &opt_element_vector,
1737 int match_start_point,
1738 int max_return_elements,
1739 bool &word_complete,
1740 StringList &matches)
1741 {
1742 // Arguments are the standard module completer.
1743 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1744 completion_str.erase (cursor_char_position);
1745
1746 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1747 CommandCompletions::eModuleCompletion,
1748 completion_str.c_str(),
1749 match_start_point,
1750 max_return_elements,
1751 NULL,
1752 word_complete,
1753 matches);
1754 return matches.GetSize();
1755 }
1756};
1757
1758#pragma mark CommandObjectTargetModulesSourceFileAutoComplete
1759
1760//----------------------------------------------------------------------
1761// A base command object class that can auto complete with module source
1762// file paths
1763//----------------------------------------------------------------------
1764
1765class CommandObjectTargetModulesSourceFileAutoComplete : public CommandObject
1766{
1767public:
1768
1769 CommandObjectTargetModulesSourceFileAutoComplete (CommandInterpreter &interpreter,
1770 const char *name,
1771 const char *help,
1772 const char *syntax) :
1773 CommandObject (interpreter, name, help, syntax)
1774 {
1775 CommandArgumentEntry arg;
1776 CommandArgumentData source_file_arg;
1777
1778 // Define the first (and only) variant of this arg.
1779 source_file_arg.arg_type = eArgTypeSourceFile;
1780 source_file_arg.arg_repetition = eArgRepeatPlus;
1781
1782 // There is only one variant this argument could be; put it into the argument entry.
1783 arg.push_back (source_file_arg);
1784
1785 // Push the data for the first argument into the m_arguments vector.
1786 m_arguments.push_back (arg);
1787 }
1788
1789 virtual
1790 ~CommandObjectTargetModulesSourceFileAutoComplete ()
1791 {
1792 }
1793
1794 virtual int
1795 HandleArgumentCompletion (Args &input,
1796 int &cursor_index,
1797 int &cursor_char_position,
1798 OptionElementVector &opt_element_vector,
1799 int match_start_point,
1800 int max_return_elements,
1801 bool &word_complete,
1802 StringList &matches)
1803 {
1804 // Arguments are the standard source file completer.
1805 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
1806 completion_str.erase (cursor_char_position);
1807
1808 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
1809 CommandCompletions::eSourceFileCompletion,
1810 completion_str.c_str(),
1811 match_start_point,
1812 max_return_elements,
1813 NULL,
1814 word_complete,
1815 matches);
1816 return matches.GetSize();
1817 }
1818};
1819
1820
1821#pragma mark CommandObjectTargetModulesDumpSymtab
1822
1823
1824class CommandObjectTargetModulesDumpSymtab : public CommandObjectTargetModulesModuleAutoComplete
1825{
1826public:
1827 CommandObjectTargetModulesDumpSymtab (CommandInterpreter &interpreter) :
1828 CommandObjectTargetModulesModuleAutoComplete (interpreter,
1829 "target modules dump symtab",
1830 "Dump the symbol table from one or more target modules.",
1831 NULL),
1832 m_options (interpreter)
1833 {
1834 }
1835
1836 virtual
1837 ~CommandObjectTargetModulesDumpSymtab ()
1838 {
1839 }
1840
1841 virtual bool
1842 Execute (Args& command,
1843 CommandReturnObject &result)
1844 {
1845 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1846 if (target == NULL)
1847 {
1848 result.AppendError ("invalid target, create a debug target using the 'target create' command");
1849 result.SetStatus (eReturnStatusFailed);
1850 return false;
1851 }
1852 else
1853 {
1854 uint32_t num_dumped = 0;
1855
1856 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
1857 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
1858 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
1859
1860 if (command.GetArgumentCount() == 0)
1861 {
1862 // Dump all sections for all modules images
1863 const uint32_t num_modules = target->GetImages().GetSize();
1864 if (num_modules > 0)
1865 {
1866 result.GetOutputStream().Printf("Dumping symbol table for %u modules.\n", num_modules);
1867 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
1868 {
1869 if (num_dumped > 0)
1870 {
1871 result.GetOutputStream().EOL();
1872 result.GetOutputStream().EOL();
1873 }
1874 num_dumped++;
1875 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx), m_options.m_sort_order);
1876 }
1877 }
1878 else
1879 {
1880 result.AppendError ("the target has no associated executable images");
1881 result.SetStatus (eReturnStatusFailed);
1882 return false;
1883 }
1884 }
1885 else
1886 {
1887 // Dump specified images (by basename or fullpath)
1888 const char *arg_cstr;
1889 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
1890 {
Greg Clayton91048ef2011-11-10 01:18:58 +00001891 ModuleList module_list;
1892 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
1893 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00001894 {
Greg Clayton91048ef2011-11-10 01:18:58 +00001895 for (size_t i=0; i<num_matches; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00001896 {
Greg Clayton91048ef2011-11-10 01:18:58 +00001897 Module *module = module_list.GetModulePointerAtIndex(i);
1898 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00001899 {
1900 if (num_dumped > 0)
1901 {
1902 result.GetOutputStream().EOL();
1903 result.GetOutputStream().EOL();
1904 }
1905 num_dumped++;
Greg Clayton91048ef2011-11-10 01:18:58 +00001906 DumpModuleSymtab (m_interpreter, result.GetOutputStream(), module, m_options.m_sort_order);
Greg Claytone1f50b92011-05-03 22:09:39 +00001907 }
1908 }
1909 }
1910 else
1911 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
1912 }
1913 }
1914
1915 if (num_dumped > 0)
1916 result.SetStatus (eReturnStatusSuccessFinishResult);
1917 else
1918 {
1919 result.AppendError ("no matching executable images found");
1920 result.SetStatus (eReturnStatusFailed);
1921 }
1922 }
1923 return result.Succeeded();
1924 }
1925
1926 virtual Options *
1927 GetOptions ()
1928 {
1929 return &m_options;
1930 }
1931
1932 class CommandOptions : public Options
1933 {
1934 public:
1935
1936 CommandOptions (CommandInterpreter &interpreter) :
1937 Options(interpreter),
1938 m_sort_order (eSortOrderNone)
1939 {
1940 }
1941
1942 virtual
1943 ~CommandOptions ()
1944 {
1945 }
1946
1947 virtual Error
1948 SetOptionValue (uint32_t option_idx, const char *option_arg)
1949 {
1950 Error error;
1951 char short_option = (char) m_getopt_table[option_idx].val;
1952
1953 switch (short_option)
1954 {
1955 case 's':
Greg Claytone1f50b92011-05-03 22:09:39 +00001956 m_sort_order = (SortOrder) Args::StringToOptionEnum (option_arg,
1957 g_option_table[option_idx].enum_values,
1958 eSortOrderNone,
Greg Clayton61aca5d2011-10-07 18:58:12 +00001959 error);
Greg Claytone1f50b92011-05-03 22:09:39 +00001960 break;
1961
1962 default:
Greg Clayton9c236732011-10-26 00:56:27 +00001963 error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
Greg Claytone1f50b92011-05-03 22:09:39 +00001964 break;
1965
1966 }
1967 return error;
1968 }
1969
1970 void
1971 OptionParsingStarting ()
1972 {
1973 m_sort_order = eSortOrderNone;
1974 }
1975
1976 const OptionDefinition*
1977 GetDefinitions ()
1978 {
1979 return g_option_table;
1980 }
1981
1982 // Options table: Required for subclasses of Options.
1983 static OptionDefinition g_option_table[];
1984
1985 SortOrder m_sort_order;
1986 };
1987
1988protected:
1989
1990 CommandOptions m_options;
1991};
1992
1993static OptionEnumValueElement
1994g_sort_option_enumeration[4] =
1995{
1996 { eSortOrderNone, "none", "No sorting, use the original symbol table order."},
1997 { eSortOrderByAddress, "address", "Sort output by symbol address."},
1998 { eSortOrderByName, "name", "Sort output by symbol name."},
1999 { 0, NULL, NULL }
2000};
2001
2002
2003OptionDefinition
2004CommandObjectTargetModulesDumpSymtab::CommandOptions::g_option_table[] =
2005{
2006 { LLDB_OPT_SET_1, false, "sort", 's', required_argument, g_sort_option_enumeration, 0, eArgTypeSortOrder, "Supply a sort order when dumping the symbol table."},
2007 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
2008};
2009
2010#pragma mark CommandObjectTargetModulesDumpSections
2011
2012//----------------------------------------------------------------------
2013// Image section dumping command
2014//----------------------------------------------------------------------
2015
2016class CommandObjectTargetModulesDumpSections : public CommandObjectTargetModulesModuleAutoComplete
2017{
2018public:
2019 CommandObjectTargetModulesDumpSections (CommandInterpreter &interpreter) :
2020 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2021 "target modules dump sections",
2022 "Dump the sections from one or more target modules.",
2023 //"target modules dump sections [<file1> ...]")
2024 NULL)
2025 {
2026 }
2027
2028 virtual
2029 ~CommandObjectTargetModulesDumpSections ()
2030 {
2031 }
2032
2033 virtual bool
2034 Execute (Args& command,
2035 CommandReturnObject &result)
2036 {
2037 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2038 if (target == NULL)
2039 {
2040 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2041 result.SetStatus (eReturnStatusFailed);
2042 return false;
2043 }
2044 else
2045 {
2046 uint32_t num_dumped = 0;
2047
2048 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2049 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2050 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2051
2052 if (command.GetArgumentCount() == 0)
2053 {
2054 // Dump all sections for all modules images
2055 const uint32_t num_modules = target->GetImages().GetSize();
2056 if (num_modules > 0)
2057 {
2058 result.GetOutputStream().Printf("Dumping sections for %u modules.\n", num_modules);
2059 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2060 {
2061 num_dumped++;
2062 DumpModuleSections (m_interpreter, result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx));
2063 }
2064 }
2065 else
2066 {
2067 result.AppendError ("the target has no associated executable images");
2068 result.SetStatus (eReturnStatusFailed);
2069 return false;
2070 }
2071 }
2072 else
2073 {
2074 // Dump specified images (by basename or fullpath)
2075 const char *arg_cstr;
2076 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2077 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002078 ModuleList module_list;
2079 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2080 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00002081 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002082 for (size_t i=0; i<num_matches; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00002083 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002084 Module *module = module_list.GetModulePointerAtIndex(i);
2085 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00002086 {
2087 num_dumped++;
Greg Clayton91048ef2011-11-10 01:18:58 +00002088 DumpModuleSections (m_interpreter, result.GetOutputStream(), module);
Greg Claytone1f50b92011-05-03 22:09:39 +00002089 }
2090 }
2091 }
2092 else
Greg Clayton91048ef2011-11-10 01:18:58 +00002093 {
2094 // Check the global list
Greg Claytonc149c8b2012-01-27 18:08:35 +00002095 Mutex::Locker locker(Module::GetAllocationModuleCollectionMutex());
Greg Clayton91048ef2011-11-10 01:18:58 +00002096
Greg Claytone1f50b92011-05-03 22:09:39 +00002097 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
Greg Clayton91048ef2011-11-10 01:18:58 +00002098 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002099 }
2100 }
2101
2102 if (num_dumped > 0)
2103 result.SetStatus (eReturnStatusSuccessFinishResult);
2104 else
2105 {
2106 result.AppendError ("no matching executable images found");
2107 result.SetStatus (eReturnStatusFailed);
2108 }
2109 }
2110 return result.Succeeded();
2111 }
2112};
2113
2114
2115#pragma mark CommandObjectTargetModulesDumpSymfile
2116
2117//----------------------------------------------------------------------
2118// Image debug symbol dumping command
2119//----------------------------------------------------------------------
2120
2121class CommandObjectTargetModulesDumpSymfile : public CommandObjectTargetModulesModuleAutoComplete
2122{
2123public:
2124 CommandObjectTargetModulesDumpSymfile (CommandInterpreter &interpreter) :
2125 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2126 "target modules dump symfile",
2127 "Dump the debug symbol file for one or more target modules.",
2128 //"target modules dump symfile [<file1> ...]")
2129 NULL)
2130 {
2131 }
2132
2133 virtual
2134 ~CommandObjectTargetModulesDumpSymfile ()
2135 {
2136 }
2137
2138 virtual bool
2139 Execute (Args& command,
2140 CommandReturnObject &result)
2141 {
2142 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2143 if (target == NULL)
2144 {
2145 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2146 result.SetStatus (eReturnStatusFailed);
2147 return false;
2148 }
2149 else
2150 {
2151 uint32_t num_dumped = 0;
2152
2153 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2154 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2155 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2156
2157 if (command.GetArgumentCount() == 0)
2158 {
2159 // Dump all sections for all modules images
2160 const uint32_t num_modules = target->GetImages().GetSize();
2161 if (num_modules > 0)
2162 {
2163 result.GetOutputStream().Printf("Dumping debug symbols for %u modules.\n", num_modules);
2164 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2165 {
2166 if (DumpModuleSymbolVendor (result.GetOutputStream(), target->GetImages().GetModulePointerAtIndex(image_idx)))
2167 num_dumped++;
2168 }
2169 }
2170 else
2171 {
2172 result.AppendError ("the target has no associated executable images");
2173 result.SetStatus (eReturnStatusFailed);
2174 return false;
2175 }
2176 }
2177 else
2178 {
2179 // Dump specified images (by basename or fullpath)
2180 const char *arg_cstr;
2181 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2182 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002183 ModuleList module_list;
2184 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, true);
2185 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00002186 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002187 for (size_t i=0; i<num_matches; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00002188 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002189 Module *module = module_list.GetModulePointerAtIndex(i);
2190 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00002191 {
Greg Clayton91048ef2011-11-10 01:18:58 +00002192 if (DumpModuleSymbolVendor (result.GetOutputStream(), module))
Greg Claytone1f50b92011-05-03 22:09:39 +00002193 num_dumped++;
2194 }
2195 }
2196 }
2197 else
2198 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
2199 }
2200 }
2201
2202 if (num_dumped > 0)
2203 result.SetStatus (eReturnStatusSuccessFinishResult);
2204 else
2205 {
2206 result.AppendError ("no matching executable images found");
2207 result.SetStatus (eReturnStatusFailed);
2208 }
2209 }
2210 return result.Succeeded();
2211 }
2212};
2213
2214
2215#pragma mark CommandObjectTargetModulesDumpLineTable
2216
2217//----------------------------------------------------------------------
2218// Image debug line table dumping command
2219//----------------------------------------------------------------------
2220
2221class CommandObjectTargetModulesDumpLineTable : public CommandObjectTargetModulesSourceFileAutoComplete
2222{
2223public:
2224 CommandObjectTargetModulesDumpLineTable (CommandInterpreter &interpreter) :
2225 CommandObjectTargetModulesSourceFileAutoComplete (interpreter,
2226 "target modules dump line-table",
2227 "Dump the debug symbol file for one or more target modules.",
2228 NULL)
2229 {
2230 }
2231
2232 virtual
2233 ~CommandObjectTargetModulesDumpLineTable ()
2234 {
2235 }
2236
2237 virtual bool
2238 Execute (Args& command,
2239 CommandReturnObject &result)
2240 {
2241 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2242 if (target == NULL)
2243 {
2244 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2245 result.SetStatus (eReturnStatusFailed);
2246 return false;
2247 }
2248 else
2249 {
2250 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
2251 uint32_t total_num_dumped = 0;
2252
2253 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2254 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2255 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2256
2257 if (command.GetArgumentCount() == 0)
2258 {
2259 result.AppendErrorWithFormat ("\nSyntax: %s\n", m_cmd_syntax.c_str());
2260 result.SetStatus (eReturnStatusFailed);
2261 }
2262 else
2263 {
2264 // Dump specified images (by basename or fullpath)
2265 const char *arg_cstr;
2266 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
2267 {
2268 FileSpec file_spec(arg_cstr, false);
2269 const uint32_t num_modules = target->GetImages().GetSize();
2270 if (num_modules > 0)
2271 {
2272 uint32_t num_dumped = 0;
2273 for (uint32_t i = 0; i<num_modules; ++i)
2274 {
2275 if (DumpCompileUnitLineTable (m_interpreter,
2276 result.GetOutputStream(),
2277 target->GetImages().GetModulePointerAtIndex(i),
2278 file_spec,
Greg Clayton567e7f32011-09-22 04:58:26 +00002279 exe_ctx.GetProcessPtr() && exe_ctx.GetProcessRef().IsAlive()))
Greg Claytone1f50b92011-05-03 22:09:39 +00002280 num_dumped++;
2281 }
2282 if (num_dumped == 0)
2283 result.AppendWarningWithFormat ("No source filenames matched '%s'.\n", arg_cstr);
2284 else
2285 total_num_dumped += num_dumped;
2286 }
2287 }
2288 }
2289
2290 if (total_num_dumped > 0)
2291 result.SetStatus (eReturnStatusSuccessFinishResult);
2292 else
2293 {
2294 result.AppendError ("no source filenames matched any command arguments");
2295 result.SetStatus (eReturnStatusFailed);
2296 }
2297 }
2298 return result.Succeeded();
2299 }
2300};
2301
2302
2303#pragma mark CommandObjectTargetModulesDump
2304
2305//----------------------------------------------------------------------
2306// Dump multi-word command for target modules
2307//----------------------------------------------------------------------
2308
2309class CommandObjectTargetModulesDump : public CommandObjectMultiword
2310{
2311public:
2312
2313 //------------------------------------------------------------------
2314 // Constructors and Destructors
2315 //------------------------------------------------------------------
2316 CommandObjectTargetModulesDump(CommandInterpreter &interpreter) :
2317 CommandObjectMultiword (interpreter,
2318 "target modules dump",
2319 "A set of commands for dumping information about one or more target modules.",
2320 "target modules dump [symtab|sections|symfile|line-table] [<file1> <file2> ...]")
2321 {
2322 LoadSubCommand ("symtab", CommandObjectSP (new CommandObjectTargetModulesDumpSymtab (interpreter)));
2323 LoadSubCommand ("sections", CommandObjectSP (new CommandObjectTargetModulesDumpSections (interpreter)));
2324 LoadSubCommand ("symfile", CommandObjectSP (new CommandObjectTargetModulesDumpSymfile (interpreter)));
2325 LoadSubCommand ("line-table", CommandObjectSP (new CommandObjectTargetModulesDumpLineTable (interpreter)));
2326 }
2327
2328 virtual
2329 ~CommandObjectTargetModulesDump()
2330 {
2331 }
2332};
2333
2334class CommandObjectTargetModulesAdd : public CommandObject
2335{
2336public:
2337 CommandObjectTargetModulesAdd (CommandInterpreter &interpreter) :
2338 CommandObject (interpreter,
2339 "target modules add",
2340 "Add a new module to the current target's modules.",
2341 "target modules add [<module>]")
2342 {
2343 }
2344
2345 virtual
2346 ~CommandObjectTargetModulesAdd ()
2347 {
2348 }
2349
2350 virtual bool
2351 Execute (Args& args,
2352 CommandReturnObject &result)
2353 {
2354 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2355 if (target == NULL)
2356 {
2357 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2358 result.SetStatus (eReturnStatusFailed);
2359 return false;
2360 }
2361 else
2362 {
2363 const size_t argc = args.GetArgumentCount();
2364 if (argc == 0)
2365 {
2366 result.AppendError ("one or more executable image paths must be specified");
2367 result.SetStatus (eReturnStatusFailed);
2368 return false;
2369 }
2370 else
2371 {
2372 for (size_t i=0; i<argc; ++i)
2373 {
2374 const char *path = args.GetArgumentAtIndex(i);
2375 if (path)
2376 {
2377 FileSpec file_spec(path, true);
2378 ArchSpec arch;
2379 if (file_spec.Exists())
2380 {
2381 ModuleSP module_sp (target->GetSharedModule(file_spec, arch));
2382 if (!module_sp)
2383 {
2384 result.AppendError ("one or more executable image paths must be specified");
2385 result.SetStatus (eReturnStatusFailed);
2386 return false;
2387 }
Jason Molenda36f6fb92011-08-02 23:28:55 +00002388 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytone1f50b92011-05-03 22:09:39 +00002389 }
2390 else
2391 {
2392 char resolved_path[PATH_MAX];
2393 result.SetStatus (eReturnStatusFailed);
2394 if (file_spec.GetPath (resolved_path, sizeof(resolved_path)))
2395 {
2396 if (strcmp (resolved_path, path) != 0)
2397 {
2398 result.AppendErrorWithFormat ("invalid module path '%s' with resolved path '%s'\n", path, resolved_path);
2399 break;
2400 }
2401 }
2402 result.AppendErrorWithFormat ("invalid module path '%s'\n", path);
2403 break;
2404 }
2405 }
2406 }
2407 }
2408 }
2409 return result.Succeeded();
2410 }
2411
2412 int
2413 HandleArgumentCompletion (Args &input,
2414 int &cursor_index,
2415 int &cursor_char_position,
2416 OptionElementVector &opt_element_vector,
2417 int match_start_point,
2418 int max_return_elements,
2419 bool &word_complete,
2420 StringList &matches)
2421 {
2422 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
2423 completion_str.erase (cursor_char_position);
2424
2425 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
2426 CommandCompletions::eDiskFileCompletion,
2427 completion_str.c_str(),
2428 match_start_point,
2429 max_return_elements,
2430 NULL,
2431 word_complete,
2432 matches);
2433 return matches.GetSize();
2434 }
2435
2436};
2437
2438class CommandObjectTargetModulesLoad : public CommandObjectTargetModulesModuleAutoComplete
2439{
2440public:
2441 CommandObjectTargetModulesLoad (CommandInterpreter &interpreter) :
2442 CommandObjectTargetModulesModuleAutoComplete (interpreter,
2443 "target modules load",
2444 "Set the load addresses for one or more sections in a target module.",
2445 "target modules load [--file <module> --uuid <uuid>] <sect-name> <address> [<sect-name> <address> ....]"),
2446 m_option_group (interpreter),
2447 m_file_option (LLDB_OPT_SET_1, false, "file", 'f', 0, eArgTypePath, "Fullpath or basename for module to load."),
2448 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)
2449 {
2450 m_option_group.Append (&m_uuid_option_group, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2451 m_option_group.Append (&m_file_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2452 m_option_group.Append (&m_slide_option, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
2453 m_option_group.Finalize();
2454 }
2455
2456 virtual
2457 ~CommandObjectTargetModulesLoad ()
2458 {
2459 }
2460
2461 virtual bool
2462 Execute (Args& args,
2463 CommandReturnObject &result)
2464 {
2465 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
2466 if (target == NULL)
2467 {
2468 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2469 result.SetStatus (eReturnStatusFailed);
2470 return false;
2471 }
2472 else
2473 {
2474 const size_t argc = args.GetArgumentCount();
2475 const FileSpec *file_ptr = NULL;
2476 const UUID *uuid_ptr = NULL;
2477 if (m_file_option.GetOptionValue().OptionWasSet())
2478 file_ptr = &m_file_option.GetOptionValue().GetCurrentValue();
2479
2480 if (m_uuid_option_group.GetOptionValue().OptionWasSet())
2481 uuid_ptr = &m_uuid_option_group.GetOptionValue().GetCurrentValue();
2482
2483 if (file_ptr || uuid_ptr)
2484 {
2485
2486 ModuleList matching_modules;
2487 const size_t num_matches = target->GetImages().FindModules (file_ptr, // File spec to match (can be NULL to match by UUID only)
2488 NULL, // Architecture
2489 uuid_ptr, // UUID to match (can be NULL to not match on UUID)
2490 NULL, // Object name
2491 matching_modules);
2492
2493 char path[PATH_MAX];
2494 if (num_matches == 1)
2495 {
2496 Module *module = matching_modules.GetModulePointerAtIndex(0);
2497 if (module)
2498 {
2499 ObjectFile *objfile = module->GetObjectFile();
2500 if (objfile)
2501 {
2502 SectionList *section_list = objfile->GetSectionList();
2503 if (section_list)
2504 {
2505 if (argc == 0)
2506 {
2507 if (m_slide_option.GetOptionValue().OptionWasSet())
2508 {
2509 Module *module = matching_modules.GetModulePointerAtIndex(0);
2510 if (module)
2511 {
2512 ObjectFile *objfile = module->GetObjectFile();
2513 if (objfile)
2514 {
2515 SectionList *section_list = objfile->GetSectionList();
2516 if (section_list)
2517 {
2518 const size_t num_sections = section_list->GetSize();
2519 const addr_t slide = m_slide_option.GetOptionValue().GetCurrentValue();
2520 for (size_t sect_idx = 0; sect_idx < num_sections; ++sect_idx)
2521 {
2522 SectionSP section_sp (section_list->GetSectionAtIndex(sect_idx));
2523 if (section_sp)
2524 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), section_sp->GetFileAddress() + slide);
2525 }
2526 }
2527 }
2528 }
2529 }
2530 else
2531 {
2532 result.AppendError ("one or more section name + load address pair must be specified");
2533 result.SetStatus (eReturnStatusFailed);
2534 return false;
2535 }
2536 }
2537 else
2538 {
2539 if (m_slide_option.GetOptionValue().OptionWasSet())
2540 {
2541 result.AppendError ("The \"--slide <offset>\" option can't be used in conjunction with setting section load addresses.\n");
2542 result.SetStatus (eReturnStatusFailed);
2543 return false;
2544 }
2545
2546 for (size_t i=0; i<argc; i += 2)
2547 {
2548 const char *sect_name = args.GetArgumentAtIndex(i);
2549 const char *load_addr_cstr = args.GetArgumentAtIndex(i+1);
2550 if (sect_name && load_addr_cstr)
2551 {
2552 ConstString const_sect_name(sect_name);
2553 bool success = false;
2554 addr_t load_addr = Args::StringToUInt64(load_addr_cstr, LLDB_INVALID_ADDRESS, 0, &success);
2555 if (success)
2556 {
2557 SectionSP section_sp (section_list->FindSectionByName(const_sect_name));
2558 if (section_sp)
2559 {
2560 target->GetSectionLoadList().SetSectionLoadAddress (section_sp.get(), load_addr);
2561 result.AppendMessageWithFormat("section '%s' loaded at 0x%llx\n", sect_name, load_addr);
2562 }
2563 else
2564 {
2565 result.AppendErrorWithFormat ("no section found that matches the section name '%s'\n", sect_name);
2566 result.SetStatus (eReturnStatusFailed);
2567 break;
2568 }
2569 }
2570 else
2571 {
2572 result.AppendErrorWithFormat ("invalid load address string '%s'\n", load_addr_cstr);
2573 result.SetStatus (eReturnStatusFailed);
2574 break;
2575 }
2576 }
2577 else
2578 {
2579 if (sect_name)
2580 result.AppendError ("section names must be followed by a load address.\n");
2581 else
2582 result.AppendError ("one or more section name + load address pair must be specified.\n");
2583 result.SetStatus (eReturnStatusFailed);
2584 break;
2585 }
2586 }
2587 }
2588 }
2589 else
2590 {
2591 module->GetFileSpec().GetPath (path, sizeof(path));
2592 result.AppendErrorWithFormat ("no sections in object file '%s'\n", path);
2593 result.SetStatus (eReturnStatusFailed);
2594 }
2595 }
2596 else
2597 {
2598 module->GetFileSpec().GetPath (path, sizeof(path));
2599 result.AppendErrorWithFormat ("no object file for module '%s'\n", path);
2600 result.SetStatus (eReturnStatusFailed);
2601 }
2602 }
2603 else
2604 {
2605 module->GetFileSpec().GetPath (path, sizeof(path));
2606 result.AppendErrorWithFormat ("invalid module '%s'.\n", path);
2607 result.SetStatus (eReturnStatusFailed);
2608 }
2609 }
2610 else
2611 {
2612 char uuid_cstr[64];
2613 if (file_ptr)
2614 file_ptr->GetPath (path, sizeof(path));
2615 else
2616 path[0] = '\0';
2617
2618 if (uuid_ptr)
2619 uuid_ptr->GetAsCString(uuid_cstr, sizeof(uuid_cstr));
2620 else
2621 uuid_cstr[0] = '\0';
2622 if (num_matches > 1)
2623 {
2624 result.AppendErrorWithFormat ("multiple modules match%s%s%s%s:\n",
2625 path[0] ? " file=" : "",
2626 path,
2627 uuid_cstr[0] ? " uuid=" : "",
2628 uuid_cstr);
2629 for (size_t i=0; i<num_matches; ++i)
2630 {
2631 if (matching_modules.GetModulePointerAtIndex(i)->GetFileSpec().GetPath (path, sizeof(path)))
2632 result.AppendMessageWithFormat("%s\n", path);
2633 }
2634 }
2635 else
2636 {
2637 result.AppendErrorWithFormat ("no modules were found that match%s%s%s%s.\n",
2638 path[0] ? " file=" : "",
2639 path,
2640 uuid_cstr[0] ? " uuid=" : "",
2641 uuid_cstr);
2642 }
2643 result.SetStatus (eReturnStatusFailed);
2644 }
2645 }
2646 else
2647 {
2648 result.AppendError ("either the \"--file <module>\" or the \"--uuid <uuid>\" option must be specified.\n");
2649 result.SetStatus (eReturnStatusFailed);
2650 return false;
2651 }
2652 }
2653 return result.Succeeded();
2654 }
2655
2656 virtual Options *
2657 GetOptions ()
2658 {
2659 return &m_option_group;
2660 }
2661
2662protected:
2663 OptionGroupOptions m_option_group;
2664 OptionGroupUUID m_uuid_option_group;
2665 OptionGroupFile m_file_option;
2666 OptionGroupUInt64 m_slide_option;
2667};
2668
2669//----------------------------------------------------------------------
2670// List images with associated information
2671//----------------------------------------------------------------------
2672class CommandObjectTargetModulesList : public CommandObject
2673{
2674public:
2675
2676 class CommandOptions : public Options
2677 {
2678 public:
2679
2680 CommandOptions (CommandInterpreter &interpreter) :
Greg Clayton899025f2011-08-09 00:01:09 +00002681 Options(interpreter),
Jim Ingham6bdea822011-10-24 18:36:33 +00002682 m_format_array(),
Daniel Dunbar97c89572011-10-31 22:50:49 +00002683 m_use_global_module_list (false),
Jim Ingham6bdea822011-10-24 18:36:33 +00002684 m_module_addr (LLDB_INVALID_ADDRESS)
Greg Claytone1f50b92011-05-03 22:09:39 +00002685 {
2686 }
2687
2688 virtual
2689 ~CommandOptions ()
2690 {
2691 }
2692
2693 virtual Error
2694 SetOptionValue (uint32_t option_idx, const char *option_arg)
2695 {
2696 char short_option = (char) m_getopt_table[option_idx].val;
Greg Clayton899025f2011-08-09 00:01:09 +00002697 if (short_option == 'g')
2698 {
2699 m_use_global_module_list = true;
2700 }
Jim Ingham6bdea822011-10-24 18:36:33 +00002701 else if (short_option == 'a')
2702 {
2703 bool success;
2704 m_module_addr = Args::StringToAddress(option_arg, LLDB_INVALID_ADDRESS, &success);
2705 if (!success)
2706 {
2707 Error error;
Greg Clayton9c236732011-10-26 00:56:27 +00002708 error.SetErrorStringWithFormat("invalid address: \"%s\"", option_arg);
Jim Ingham6bdea822011-10-24 18:36:33 +00002709 }
2710 }
Greg Clayton899025f2011-08-09 00:01:09 +00002711 else
2712 {
2713 uint32_t width = 0;
2714 if (option_arg)
2715 width = strtoul (option_arg, NULL, 0);
2716 m_format_array.push_back(std::make_pair(short_option, width));
2717 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002718 Error error;
2719 return error;
2720 }
2721
2722 void
2723 OptionParsingStarting ()
2724 {
2725 m_format_array.clear();
Greg Clayton899025f2011-08-09 00:01:09 +00002726 m_use_global_module_list = false;
Jim Ingham6bdea822011-10-24 18:36:33 +00002727 m_module_addr = LLDB_INVALID_ADDRESS;
Greg Claytone1f50b92011-05-03 22:09:39 +00002728 }
2729
2730 const OptionDefinition*
2731 GetDefinitions ()
2732 {
2733 return g_option_table;
2734 }
2735
2736 // Options table: Required for subclasses of Options.
2737
2738 static OptionDefinition g_option_table[];
2739
2740 // Instance variables to hold the values for command options.
2741 typedef std::vector< std::pair<char, uint32_t> > FormatWidthCollection;
2742 FormatWidthCollection m_format_array;
Greg Clayton899025f2011-08-09 00:01:09 +00002743 bool m_use_global_module_list;
Jim Ingham6bdea822011-10-24 18:36:33 +00002744 lldb::addr_t m_module_addr;
Greg Claytone1f50b92011-05-03 22:09:39 +00002745 };
2746
2747 CommandObjectTargetModulesList (CommandInterpreter &interpreter) :
2748 CommandObject (interpreter,
2749 "target modules list",
2750 "List current executable and dependent shared library images.",
2751 "target modules list [<cmd-options>]"),
2752 m_options (interpreter)
2753 {
2754 }
2755
2756 virtual
2757 ~CommandObjectTargetModulesList ()
2758 {
2759 }
2760
2761 virtual
2762 Options *
2763 GetOptions ()
2764 {
2765 return &m_options;
2766 }
2767
2768 virtual bool
2769 Execute (Args& command,
2770 CommandReturnObject &result)
2771 {
2772 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Greg Clayton153ccd72011-08-10 02:10:13 +00002773 const bool use_global_module_list = m_options.m_use_global_module_list;
2774 if (target == NULL && use_global_module_list == false)
Greg Claytone1f50b92011-05-03 22:09:39 +00002775 {
2776 result.AppendError ("invalid target, create a debug target using the 'target create' command");
2777 result.SetStatus (eReturnStatusFailed);
2778 return false;
2779 }
2780 else
2781 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002782 if (target)
2783 {
2784 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
2785 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
2786 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
2787 }
Greg Claytone1f50b92011-05-03 22:09:39 +00002788 // Dump all sections for all modules images
Greg Clayton899025f2011-08-09 00:01:09 +00002789 uint32_t num_modules = 0;
2790 Mutex::Locker locker;
Jim Ingham6bdea822011-10-24 18:36:33 +00002791
2792 Stream &strm = result.GetOutputStream();
2793
2794 if (m_options.m_module_addr != LLDB_INVALID_ADDRESS)
2795 {
2796 if (target)
2797 {
2798 Address module_address;
2799 if (module_address.SetLoadAddress(m_options.m_module_addr, target))
2800 {
Greg Clayton13d24fb2012-01-29 20:56:30 +00002801 Module *module = module_address.GetModulePtr();
Jim Ingham6bdea822011-10-24 18:36:33 +00002802 if (module)
2803 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00002804 PrintModule (target, module, UINT32_MAX, 0, strm);
Jim Ingham6bdea822011-10-24 18:36:33 +00002805 result.SetStatus (eReturnStatusSuccessFinishResult);
2806 }
2807 else
2808 {
2809 result.AppendError ("Couldn't find module matching address: 0x%llx.", m_options.m_module_addr);
2810 result.SetStatus (eReturnStatusFailed);
2811 }
2812 }
2813 else
2814 {
2815 result.AppendError ("Couldn't find module containing address: 0x%llx.", m_options.m_module_addr);
2816 result.SetStatus (eReturnStatusFailed);
2817 }
2818 }
2819 else
2820 {
2821 result.AppendError ("Can only look up modules by address with a valid target.");
2822 result.SetStatus (eReturnStatusFailed);
2823 }
2824 return result.Succeeded();
2825 }
2826
Greg Clayton153ccd72011-08-10 02:10:13 +00002827 if (use_global_module_list)
Greg Clayton899025f2011-08-09 00:01:09 +00002828 {
Greg Claytonc149c8b2012-01-27 18:08:35 +00002829 locker.Reset (Module::GetAllocationModuleCollectionMutex()->GetMutex());
Greg Clayton899025f2011-08-09 00:01:09 +00002830 num_modules = Module::GetNumberAllocatedModules();
2831 }
2832 else
2833 num_modules = target->GetImages().GetSize();
2834
Greg Claytone1f50b92011-05-03 22:09:39 +00002835 if (num_modules > 0)
Jim Ingham6bdea822011-10-24 18:36:33 +00002836 {
Greg Claytone1f50b92011-05-03 22:09:39 +00002837 for (uint32_t image_idx = 0; image_idx<num_modules; ++image_idx)
2838 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002839 ModuleSP module_sp;
Greg Clayton899025f2011-08-09 00:01:09 +00002840 Module *module;
Greg Clayton153ccd72011-08-10 02:10:13 +00002841 if (use_global_module_list)
Greg Clayton899025f2011-08-09 00:01:09 +00002842 {
2843 module = Module::GetAllocatedModuleAtIndex(image_idx);
Greg Clayton13d24fb2012-01-29 20:56:30 +00002844 module_sp = module->shared_from_this();
Greg Clayton899025f2011-08-09 00:01:09 +00002845 }
2846 else
2847 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002848 module_sp = target->GetImages().GetModuleAtIndex(image_idx);
2849 module = module_sp.get();
Greg Clayton899025f2011-08-09 00:01:09 +00002850 }
Jim Ingham6bdea822011-10-24 18:36:33 +00002851
Greg Claytonb5a8f142012-02-05 02:38:54 +00002852 int indent = strm.Printf("[%3u] ", image_idx);
2853 PrintModule (target, module, image_idx, indent, strm);
Greg Clayton153ccd72011-08-10 02:10:13 +00002854
Greg Claytone1f50b92011-05-03 22:09:39 +00002855 }
2856 result.SetStatus (eReturnStatusSuccessFinishResult);
2857 }
2858 else
2859 {
Greg Clayton153ccd72011-08-10 02:10:13 +00002860 if (use_global_module_list)
2861 result.AppendError ("the global module list is empty");
2862 else
2863 result.AppendError ("the target has no associated executable images");
Greg Claytone1f50b92011-05-03 22:09:39 +00002864 result.SetStatus (eReturnStatusFailed);
2865 return false;
2866 }
2867 }
2868 return result.Succeeded();
2869 }
2870protected:
Jim Ingham6bdea822011-10-24 18:36:33 +00002871
2872 void
Greg Claytonb5a8f142012-02-05 02:38:54 +00002873 PrintModule (Target *target, Module *module, uint32_t idx, int indent, Stream &strm)
Jim Ingham6bdea822011-10-24 18:36:33 +00002874 {
2875
2876 bool dump_object_name = false;
2877 if (m_options.m_format_array.empty())
2878 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00002879 m_options.m_format_array.push_back(std::make_pair('u', 0));
2880 m_options.m_format_array.push_back(std::make_pair('h', 0));
2881 m_options.m_format_array.push_back(std::make_pair('f', 0));
2882 m_options.m_format_array.push_back(std::make_pair('S', 0));
Jim Ingham6bdea822011-10-24 18:36:33 +00002883 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00002884 const size_t num_entries = m_options.m_format_array.size();
2885 bool print_space = false;
2886 for (size_t i=0; i<num_entries; ++i)
Jim Ingham6bdea822011-10-24 18:36:33 +00002887 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00002888 if (print_space)
2889 strm.PutChar(' ');
2890 print_space = true;
2891 const char format_char = m_options.m_format_array[i].first;
2892 uint32_t width = m_options.m_format_array[i].second;
2893 switch (format_char)
Jim Ingham6bdea822011-10-24 18:36:33 +00002894 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00002895 case 'A':
2896 DumpModuleArchitecture (strm, module, false, width);
2897 break;
2898
2899 case 't':
2900 DumpModuleArchitecture (strm, module, true, width);
2901 break;
2902
2903 case 'f':
2904 DumpFullpath (strm, &module->GetFileSpec(), width);
2905 dump_object_name = true;
2906 break;
2907
2908 case 'd':
2909 DumpDirectory (strm, &module->GetFileSpec(), width);
2910 break;
2911
2912 case 'b':
2913 DumpBasename (strm, &module->GetFileSpec(), width);
2914 dump_object_name = true;
2915 break;
2916
2917 case 'h':
2918 case 'o':
2919 // Image header address
2920 {
2921 uint32_t addr_nibble_width = target ? (target->GetArchitecture().GetAddressByteSize() * 2) : 16;
Jim Ingham6bdea822011-10-24 18:36:33 +00002922
Greg Claytonb5a8f142012-02-05 02:38:54 +00002923 ObjectFile *objfile = module->GetObjectFile ();
2924 if (objfile)
Jim Ingham6bdea822011-10-24 18:36:33 +00002925 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00002926 Address header_addr(objfile->GetHeaderAddress());
2927 if (header_addr.IsValid())
Jim Ingham6bdea822011-10-24 18:36:33 +00002928 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00002929 if (target && !target->GetSectionLoadList().IsEmpty())
Jim Ingham6bdea822011-10-24 18:36:33 +00002930 {
Greg Claytonb5a8f142012-02-05 02:38:54 +00002931 lldb::addr_t header_load_addr = header_addr.GetLoadAddress (target);
2932 if (header_load_addr == LLDB_INVALID_ADDRESS)
2933 {
2934 header_addr.Dump (&strm, target, Address::DumpStyleModuleWithFileAddress, Address::DumpStyleFileAddress);
2935 }
Jim Ingham6bdea822011-10-24 18:36:33 +00002936 else
Greg Claytonb5a8f142012-02-05 02:38:54 +00002937 {
2938 if (format_char == 'o')
2939 {
2940 // Show the offset of slide for the image
2941 strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr - header_addr.GetFileAddress());
2942 }
2943 else
2944 {
2945 // Show the load address of the image
2946 strm.Printf ("0x%*.*llx", addr_nibble_width, addr_nibble_width, header_load_addr);
2947 }
2948 }
Jim Ingham6bdea822011-10-24 18:36:33 +00002949 break;
2950 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00002951 // The address was valid, but the image isn't loaded, output the address in an appropriate format
2952 header_addr.Dump (&strm, target, Address::DumpStyleFileAddress);
2953 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00002954 }
Jim Ingham6bdea822011-10-24 18:36:33 +00002955 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00002956 strm.Printf ("%*s", addr_nibble_width + 2, "");
2957 }
2958 break;
2959 case 'r':
2960 {
2961 uint32_t ref_count = 0;
2962 ModuleSP module_sp (module->shared_from_this());
2963 if (module_sp)
2964 {
2965 // Take one away to make sure we don't count our local "module_sp"
2966 ref_count = module_sp.use_count() - 1;
2967 }
2968 if (width)
2969 strm.Printf("{%*u}", width, ref_count);
2970 else
2971 strm.Printf("{%u}", ref_count);
2972 }
2973 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00002974
Greg Claytonb5a8f142012-02-05 02:38:54 +00002975 case 's':
2976 case 'S':
2977 {
2978 SymbolVendor *symbol_vendor = module->GetSymbolVendor();
2979 if (symbol_vendor)
2980 {
2981 SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
2982 if (symbol_file)
2983 {
2984 if (format_char == 'S')
2985 {
2986 FileSpec &symfile_spec = symbol_file->GetObjectFile()->GetFileSpec();
2987 // Dump symbol file only if different from module file
2988 if (!symfile_spec || symfile_spec == module->GetFileSpec())
2989 {
2990 print_space = false;
2991 break;
2992 }
2993 // Add a newline and indent past the index
2994 strm.Printf ("\n%*s", indent, "");
2995 }
2996 DumpFullpath (strm, &symbol_file->GetObjectFile()->GetFileSpec(), width);
2997 dump_object_name = true;
2998 break;
2999 }
3000 }
3001 strm.Printf("%.*s", width, "<NONE>");
3002 }
3003 break;
3004
3005 case 'm':
3006 module->GetModificationTime().Dump(&strm, width);
3007 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00003008
Greg Claytonb5a8f142012-02-05 02:38:54 +00003009 case 'p':
3010 strm.Printf("%p", module);
3011 break;
3012
3013 case 'u':
3014 DumpModuleUUID(strm, module);
3015 break;
3016
3017 default:
3018 break;
Jim Ingham6bdea822011-10-24 18:36:33 +00003019 }
Greg Claytonb5a8f142012-02-05 02:38:54 +00003020
3021 }
3022 if (dump_object_name)
3023 {
3024 const char *object_name = module->GetObjectName().GetCString();
3025 if (object_name)
3026 strm.Printf ("(%s)", object_name);
Jim Ingham6bdea822011-10-24 18:36:33 +00003027 }
3028 strm.EOL();
3029 }
3030
Greg Claytone1f50b92011-05-03 22:09:39 +00003031 CommandOptions m_options;
3032};
3033
3034OptionDefinition
3035CommandObjectTargetModulesList::CommandOptions::g_option_table[] =
3036{
Jim Ingham6bdea822011-10-24 18:36:33 +00003037 { LLDB_OPT_SET_1, false, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Display the image at this address."},
3038 { 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 +00003039 { 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 +00003040 { 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."},
3041 { 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 +00003042 { LLDB_OPT_SET_1, false, "uuid", 'u', no_argument, NULL, 0, eArgTypeNone, "Display the UUID when listing images."},
3043 { LLDB_OPT_SET_1, false, "fullpath", 'f', optional_argument, NULL, 0, eArgTypeWidth, "Display the fullpath to the image object file."},
3044 { LLDB_OPT_SET_1, false, "directory", 'd', optional_argument, NULL, 0, eArgTypeWidth, "Display the directory with optional width for the image object file."},
3045 { LLDB_OPT_SET_1, false, "basename", 'b', optional_argument, NULL, 0, eArgTypeWidth, "Display the basename with optional width for the image object file."},
3046 { 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 +00003047 { 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 +00003048 { LLDB_OPT_SET_1, false, "mod-time", 'm', optional_argument, NULL, 0, eArgTypeWidth, "Display the modification time with optional width of the module."},
3049 { 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."},
3050 { LLDB_OPT_SET_1, false, "pointer", 'p', optional_argument, NULL, 0, eArgTypeNone, "Display the module pointer."},
Greg Clayton899025f2011-08-09 00:01:09 +00003051 { 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 +00003052 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3053};
3054
3055
3056
3057//----------------------------------------------------------------------
3058// Lookup information in images
3059//----------------------------------------------------------------------
3060class CommandObjectTargetModulesLookup : public CommandObject
3061{
3062public:
3063
3064 enum
3065 {
3066 eLookupTypeInvalid = -1,
3067 eLookupTypeAddress = 0,
3068 eLookupTypeSymbol,
3069 eLookupTypeFileLine, // Line is optional
3070 eLookupTypeFunction,
3071 eLookupTypeType,
3072 kNumLookupTypes
3073 };
3074
3075 class CommandOptions : public Options
3076 {
3077 public:
3078
3079 CommandOptions (CommandInterpreter &interpreter) :
3080 Options(interpreter)
3081 {
3082 OptionParsingStarting();
3083 }
3084
3085 virtual
3086 ~CommandOptions ()
3087 {
3088 }
3089
3090 virtual Error
3091 SetOptionValue (uint32_t option_idx, const char *option_arg)
3092 {
3093 Error error;
3094
3095 char short_option = (char) m_getopt_table[option_idx].val;
3096
3097 switch (short_option)
3098 {
3099 case 'a':
3100 m_type = eLookupTypeAddress;
3101 m_addr = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3102 if (m_addr == LLDB_INVALID_ADDRESS)
Greg Clayton9c236732011-10-26 00:56:27 +00003103 error.SetErrorStringWithFormat ("invalid address string '%s'", option_arg);
Greg Claytone1f50b92011-05-03 22:09:39 +00003104 break;
3105
3106 case 'o':
3107 m_offset = Args::StringToUInt64(option_arg, LLDB_INVALID_ADDRESS);
3108 if (m_offset == LLDB_INVALID_ADDRESS)
Greg Clayton9c236732011-10-26 00:56:27 +00003109 error.SetErrorStringWithFormat ("invalid offset string '%s'", option_arg);
Greg Claytone1f50b92011-05-03 22:09:39 +00003110 break;
3111
3112 case 's':
3113 m_str = option_arg;
3114 m_type = eLookupTypeSymbol;
3115 break;
3116
3117 case 'f':
3118 m_file.SetFile (option_arg, false);
3119 m_type = eLookupTypeFileLine;
3120 break;
3121
3122 case 'i':
3123 m_check_inlines = false;
3124 break;
3125
3126 case 'l':
3127 m_line_number = Args::StringToUInt32(option_arg, UINT32_MAX);
3128 if (m_line_number == UINT32_MAX)
Greg Clayton9c236732011-10-26 00:56:27 +00003129 error.SetErrorStringWithFormat ("invalid line number string '%s'", option_arg);
Greg Claytone1f50b92011-05-03 22:09:39 +00003130 else if (m_line_number == 0)
Greg Clayton9c236732011-10-26 00:56:27 +00003131 error.SetErrorString ("zero is an invalid line number");
Greg Claytone1f50b92011-05-03 22:09:39 +00003132 m_type = eLookupTypeFileLine;
3133 break;
3134
3135 case 'n':
3136 m_str = option_arg;
3137 m_type = eLookupTypeFunction;
3138 break;
3139
3140 case 't':
3141 m_str = option_arg;
3142 m_type = eLookupTypeType;
3143 break;
3144
3145 case 'v':
3146 m_verbose = 1;
3147 break;
3148
3149 case 'r':
3150 m_use_regex = true;
3151 break;
3152 }
3153
3154 return error;
3155 }
3156
3157 void
3158 OptionParsingStarting ()
3159 {
3160 m_type = eLookupTypeInvalid;
3161 m_str.clear();
3162 m_file.Clear();
3163 m_addr = LLDB_INVALID_ADDRESS;
3164 m_offset = 0;
3165 m_line_number = 0;
3166 m_use_regex = false;
3167 m_check_inlines = true;
3168 m_verbose = false;
3169 }
3170
3171 const OptionDefinition*
3172 GetDefinitions ()
3173 {
3174 return g_option_table;
3175 }
3176
3177 // Options table: Required for subclasses of Options.
3178
3179 static OptionDefinition g_option_table[];
3180 int m_type; // Should be a eLookupTypeXXX enum after parsing options
3181 std::string m_str; // Holds name lookup
3182 FileSpec m_file; // Files for file lookups
3183 lldb::addr_t m_addr; // Holds the address to lookup
3184 lldb::addr_t m_offset; // Subtract this offset from m_addr before doing lookups.
3185 uint32_t m_line_number; // Line number for file+line lookups
3186 bool m_use_regex; // Name lookups in m_str are regular expressions.
3187 bool m_check_inlines;// Check for inline entries when looking up by file/line.
3188 bool m_verbose; // Enable verbose lookup info
3189
3190 };
3191
3192 CommandObjectTargetModulesLookup (CommandInterpreter &interpreter) :
3193 CommandObject (interpreter,
3194 "target modules lookup",
3195 "Look up information within executable and dependent shared library images.",
3196 NULL),
3197 m_options (interpreter)
3198 {
3199 CommandArgumentEntry arg;
3200 CommandArgumentData file_arg;
3201
3202 // Define the first (and only) variant of this arg.
3203 file_arg.arg_type = eArgTypeFilename;
3204 file_arg.arg_repetition = eArgRepeatStar;
3205
3206 // There is only one variant this argument could be; put it into the argument entry.
3207 arg.push_back (file_arg);
3208
3209 // Push the data for the first argument into the m_arguments vector.
3210 m_arguments.push_back (arg);
3211 }
3212
3213 virtual
3214 ~CommandObjectTargetModulesLookup ()
3215 {
3216 }
3217
3218 virtual Options *
3219 GetOptions ()
3220 {
3221 return &m_options;
3222 }
3223
3224
3225 bool
3226 LookupInModule (CommandInterpreter &interpreter, Module *module, CommandReturnObject &result, bool &syntax_error)
3227 {
3228 switch (m_options.m_type)
3229 {
3230 case eLookupTypeAddress:
3231 if (m_options.m_addr != LLDB_INVALID_ADDRESS)
3232 {
3233 if (LookupAddressInModule (m_interpreter,
3234 result.GetOutputStream(),
3235 module,
3236 eSymbolContextEverything,
3237 m_options.m_addr,
3238 m_options.m_offset,
3239 m_options.m_verbose))
3240 {
3241 result.SetStatus(eReturnStatusSuccessFinishResult);
3242 return true;
3243 }
3244 }
3245 break;
3246
3247 case eLookupTypeSymbol:
3248 if (!m_options.m_str.empty())
3249 {
3250 if (LookupSymbolInModule (m_interpreter, result.GetOutputStream(), module, m_options.m_str.c_str(), m_options.m_use_regex))
3251 {
3252 result.SetStatus(eReturnStatusSuccessFinishResult);
3253 return true;
3254 }
3255 }
3256 break;
3257
3258 case eLookupTypeFileLine:
3259 if (m_options.m_file)
3260 {
3261
3262 if (LookupFileAndLineInModule (m_interpreter,
3263 result.GetOutputStream(),
3264 module,
3265 m_options.m_file,
3266 m_options.m_line_number,
3267 m_options.m_check_inlines,
3268 m_options.m_verbose))
3269 {
3270 result.SetStatus(eReturnStatusSuccessFinishResult);
3271 return true;
3272 }
3273 }
3274 break;
3275
3276 case eLookupTypeFunction:
3277 if (!m_options.m_str.empty())
3278 {
3279 if (LookupFunctionInModule (m_interpreter,
3280 result.GetOutputStream(),
3281 module,
3282 m_options.m_str.c_str(),
3283 m_options.m_use_regex,
3284 m_options.m_verbose))
3285 {
3286 result.SetStatus(eReturnStatusSuccessFinishResult);
3287 return true;
3288 }
3289 }
3290 break;
3291
3292 case eLookupTypeType:
3293 if (!m_options.m_str.empty())
3294 {
3295 if (LookupTypeInModule (m_interpreter,
3296 result.GetOutputStream(),
3297 module,
3298 m_options.m_str.c_str(),
3299 m_options.m_use_regex))
3300 {
3301 result.SetStatus(eReturnStatusSuccessFinishResult);
3302 return true;
3303 }
3304 }
3305 break;
3306
3307 default:
3308 m_options.GenerateOptionUsage (result.GetErrorStream(), this);
3309 syntax_error = true;
3310 break;
3311 }
3312
3313 result.SetStatus (eReturnStatusFailed);
3314 return false;
3315 }
3316
3317 virtual bool
3318 Execute (Args& command,
3319 CommandReturnObject &result)
3320 {
3321 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3322 if (target == NULL)
3323 {
3324 result.AppendError ("invalid target, create a debug target using the 'target create' command");
3325 result.SetStatus (eReturnStatusFailed);
3326 return false;
3327 }
3328 else
3329 {
3330 bool syntax_error = false;
3331 uint32_t i;
3332 uint32_t num_successful_lookups = 0;
3333 uint32_t addr_byte_size = target->GetArchitecture().GetAddressByteSize();
3334 result.GetOutputStream().SetAddressByteSize(addr_byte_size);
3335 result.GetErrorStream().SetAddressByteSize(addr_byte_size);
3336 // Dump all sections for all modules images
3337
3338 if (command.GetArgumentCount() == 0)
3339 {
3340 // Dump all sections for all modules images
3341 const uint32_t num_modules = target->GetImages().GetSize();
3342 if (num_modules > 0)
3343 {
3344 for (i = 0; i<num_modules && syntax_error == false; ++i)
3345 {
3346 if (LookupInModule (m_interpreter, target->GetImages().GetModulePointerAtIndex(i), result, syntax_error))
3347 {
3348 result.GetOutputStream().EOL();
3349 num_successful_lookups++;
3350 }
3351 }
3352 }
3353 else
3354 {
3355 result.AppendError ("the target has no associated executable images");
3356 result.SetStatus (eReturnStatusFailed);
3357 return false;
3358 }
3359 }
3360 else
3361 {
3362 // Dump specified images (by basename or fullpath)
3363 const char *arg_cstr;
3364 for (i = 0; (arg_cstr = command.GetArgumentAtIndex(i)) != NULL && syntax_error == false; ++i)
3365 {
Greg Clayton91048ef2011-11-10 01:18:58 +00003366 ModuleList module_list;
3367 const size_t num_matches = FindModulesByName (target, arg_cstr, module_list, false);
3368 if (num_matches > 0)
Greg Claytone1f50b92011-05-03 22:09:39 +00003369 {
Greg Clayton91048ef2011-11-10 01:18:58 +00003370 for (size_t i=0; i<num_matches; ++i)
Greg Claytone1f50b92011-05-03 22:09:39 +00003371 {
Greg Clayton91048ef2011-11-10 01:18:58 +00003372 Module *module = module_list.GetModulePointerAtIndex(i);
3373 if (module)
Greg Claytone1f50b92011-05-03 22:09:39 +00003374 {
Greg Clayton91048ef2011-11-10 01:18:58 +00003375 if (LookupInModule (m_interpreter, module, result, syntax_error))
Greg Claytone1f50b92011-05-03 22:09:39 +00003376 {
3377 result.GetOutputStream().EOL();
3378 num_successful_lookups++;
3379 }
3380 }
3381 }
3382 }
3383 else
3384 result.AppendWarningWithFormat("Unable to find an image that matches '%s'.\n", arg_cstr);
3385 }
3386 }
3387
3388 if (num_successful_lookups > 0)
3389 result.SetStatus (eReturnStatusSuccessFinishResult);
3390 else
3391 result.SetStatus (eReturnStatusFailed);
3392 }
3393 return result.Succeeded();
3394 }
3395protected:
3396
3397 CommandOptions m_options;
3398};
3399
3400OptionDefinition
3401CommandObjectTargetModulesLookup::CommandOptions::g_option_table[] =
3402{
3403 { LLDB_OPT_SET_1, true, "address", 'a', required_argument, NULL, 0, eArgTypeAddress, "Lookup an address in one or more target modules."},
3404 { 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 +00003405 { LLDB_OPT_SET_2| LLDB_OPT_SET_4
3406 /* FIXME: re-enable this for types when the LookupTypeInModule actually uses the regex option: | LLDB_OPT_SET_5 */ ,
3407 false, "regex", 'r', no_argument, NULL, 0, eArgTypeNone, "The <name> argument for name lookups are regular expressions."},
Greg Claytone1f50b92011-05-03 22:09:39 +00003408 { 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 +00003409 { 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."},
3410 { 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)."},
3411 { LLDB_OPT_SET_3, false, "no-inlines", 'i', no_argument, NULL, 0, eArgTypeNone, "Check inline line entries (must be used in conjunction with --file)."},
3412 { 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."},
3413 { 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."},
3414 { LLDB_OPT_SET_ALL, false, "verbose", 'v', no_argument, NULL, 0, eArgTypeNone, "Enable verbose lookup information."},
3415 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3416};
Chris Lattner24943d22010-06-08 16:52:24 +00003417
3418
Jim Inghamd60d94a2011-03-11 03:53:59 +00003419#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner24943d22010-06-08 16:52:24 +00003420
3421//-------------------------------------------------------------------------
3422// CommandObjectMultiwordImageSearchPaths
3423//-------------------------------------------------------------------------
3424
Greg Claytone1f50b92011-05-03 22:09:39 +00003425class CommandObjectTargetModulesImageSearchPaths : public CommandObjectMultiword
Chris Lattner24943d22010-06-08 16:52:24 +00003426{
3427public:
Greg Claytone1f50b92011-05-03 22:09:39 +00003428
3429 CommandObjectTargetModulesImageSearchPaths (CommandInterpreter &interpreter) :
3430 CommandObjectMultiword (interpreter,
3431 "target modules search-paths",
3432 "A set of commands for operating on debugger target image search paths.",
3433 "target modules search-paths <subcommand> [<subcommand-options>]")
Chris Lattner24943d22010-06-08 16:52:24 +00003434 {
Greg Claytone1f50b92011-05-03 22:09:39 +00003435 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesSearchPathsAdd (interpreter)));
3436 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetModulesSearchPathsClear (interpreter)));
3437 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetModulesSearchPathsInsert (interpreter)));
3438 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesSearchPathsList (interpreter)));
3439 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetModulesSearchPathsQuery (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00003440 }
Greg Claytone1f50b92011-05-03 22:09:39 +00003441
3442 ~CommandObjectTargetModulesImageSearchPaths()
Chris Lattner24943d22010-06-08 16:52:24 +00003443 {
3444 }
3445};
3446
Greg Claytone1f50b92011-05-03 22:09:39 +00003447
3448
3449#pragma mark CommandObjectTargetModules
3450
3451//-------------------------------------------------------------------------
3452// CommandObjectTargetModules
3453//-------------------------------------------------------------------------
3454
3455class CommandObjectTargetModules : public CommandObjectMultiword
3456{
3457public:
3458 //------------------------------------------------------------------
3459 // Constructors and Destructors
3460 //------------------------------------------------------------------
3461 CommandObjectTargetModules(CommandInterpreter &interpreter) :
3462 CommandObjectMultiword (interpreter,
3463 "target modules",
3464 "A set of commands for accessing information for one or more target modules.",
3465 "target modules <sub-command> ...")
3466 {
3467 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetModulesAdd (interpreter)));
3468 LoadSubCommand ("load", CommandObjectSP (new CommandObjectTargetModulesLoad (interpreter)));
3469 //LoadSubCommand ("unload", CommandObjectSP (new CommandObjectTargetModulesUnload (interpreter)));
3470 LoadSubCommand ("dump", CommandObjectSP (new CommandObjectTargetModulesDump (interpreter)));
3471 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetModulesList (interpreter)));
3472 LoadSubCommand ("lookup", CommandObjectSP (new CommandObjectTargetModulesLookup (interpreter)));
3473 LoadSubCommand ("search-paths", CommandObjectSP (new CommandObjectTargetModulesImageSearchPaths (interpreter)));
3474
3475 }
3476 virtual
3477 ~CommandObjectTargetModules()
3478 {
3479 }
3480
3481private:
3482 //------------------------------------------------------------------
3483 // For CommandObjectTargetModules only
3484 //------------------------------------------------------------------
3485 DISALLOW_COPY_AND_ASSIGN (CommandObjectTargetModules);
3486};
3487
3488
Jim Inghamd60d94a2011-03-11 03:53:59 +00003489#pragma mark CommandObjectTargetStopHookAdd
3490
3491//-------------------------------------------------------------------------
3492// CommandObjectTargetStopHookAdd
3493//-------------------------------------------------------------------------
3494
3495class CommandObjectTargetStopHookAdd : public CommandObject
3496{
3497public:
3498
3499 class CommandOptions : public Options
3500 {
3501 public:
Greg Claytonf15996e2011-04-07 22:46:35 +00003502 CommandOptions (CommandInterpreter &interpreter) :
3503 Options(interpreter),
Jim Inghamd60d94a2011-03-11 03:53:59 +00003504 m_line_start(0),
3505 m_line_end (UINT_MAX),
3506 m_func_name_type_mask (eFunctionNameTypeAuto),
3507 m_sym_ctx_specified (false),
Johnny Chen60fe60e2011-05-02 23:47:55 +00003508 m_thread_specified (false),
3509 m_use_one_liner (false),
3510 m_one_liner()
Jim Inghamd60d94a2011-03-11 03:53:59 +00003511 {
3512 }
3513
3514 ~CommandOptions () {}
3515
Greg Claytonb3448432011-03-24 21:19:54 +00003516 const OptionDefinition*
Jim Inghamd60d94a2011-03-11 03:53:59 +00003517 GetDefinitions ()
3518 {
3519 return g_option_table;
3520 }
3521
3522 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +00003523 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003524 {
3525 Error error;
3526 char short_option = (char) m_getopt_table[option_idx].val;
3527 bool success;
3528
3529 switch (short_option)
3530 {
3531 case 'c':
3532 m_class_name = option_arg;
3533 m_sym_ctx_specified = true;
3534 break;
3535
3536 case 'e':
3537 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
3538 if (!success)
3539 {
Greg Clayton9c236732011-10-26 00:56:27 +00003540 error.SetErrorStringWithFormat ("invalid end line number: \"%s\"", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003541 break;
3542 }
3543 m_sym_ctx_specified = true;
3544 break;
3545
3546 case 'l':
3547 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
3548 if (!success)
3549 {
Greg Clayton9c236732011-10-26 00:56:27 +00003550 error.SetErrorStringWithFormat ("invalid start line number: \"%s\"", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003551 break;
3552 }
3553 m_sym_ctx_specified = true;
3554 break;
3555
3556 case 'n':
3557 m_function_name = option_arg;
3558 m_func_name_type_mask |= eFunctionNameTypeAuto;
3559 m_sym_ctx_specified = true;
3560 break;
3561
3562 case 'f':
3563 m_file_name = option_arg;
3564 m_sym_ctx_specified = true;
3565 break;
3566 case 's':
3567 m_module_name = option_arg;
3568 m_sym_ctx_specified = true;
3569 break;
3570 case 't' :
3571 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003572 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003573 if (m_thread_id == LLDB_INVALID_THREAD_ID)
Greg Clayton9c236732011-10-26 00:56:27 +00003574 error.SetErrorStringWithFormat ("invalid thread id string '%s'", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003575 m_thread_specified = true;
3576 }
3577 break;
3578 case 'T':
3579 m_thread_name = option_arg;
3580 m_thread_specified = true;
3581 break;
3582 case 'q':
3583 m_queue_name = option_arg;
3584 m_thread_specified = true;
3585 break;
3586 case 'x':
3587 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +00003588 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003589 if (m_thread_id == UINT32_MAX)
Greg Clayton9c236732011-10-26 00:56:27 +00003590 error.SetErrorStringWithFormat ("invalid thread index string '%s'", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003591 m_thread_specified = true;
3592 }
3593 break;
Johnny Chen60fe60e2011-05-02 23:47:55 +00003594 case 'o':
3595 m_use_one_liner = true;
3596 m_one_liner = option_arg;
3597 break;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003598 default:
Greg Clayton9c236732011-10-26 00:56:27 +00003599 error.SetErrorStringWithFormat ("unrecognized option %c.", short_option);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003600 break;
3601 }
3602 return error;
3603 }
3604
3605 void
Greg Clayton143fcc32011-04-13 00:18:08 +00003606 OptionParsingStarting ()
Jim Inghamd60d94a2011-03-11 03:53:59 +00003607 {
3608 m_class_name.clear();
3609 m_function_name.clear();
3610 m_line_start = 0;
3611 m_line_end = UINT_MAX;
3612 m_file_name.clear();
3613 m_module_name.clear();
3614 m_func_name_type_mask = eFunctionNameTypeAuto;
3615 m_thread_id = LLDB_INVALID_THREAD_ID;
3616 m_thread_index = UINT32_MAX;
3617 m_thread_name.clear();
3618 m_queue_name.clear();
3619
3620 m_sym_ctx_specified = false;
3621 m_thread_specified = false;
Johnny Chen60fe60e2011-05-02 23:47:55 +00003622
3623 m_use_one_liner = false;
3624 m_one_liner.clear();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003625 }
3626
3627
Greg Claytonb3448432011-03-24 21:19:54 +00003628 static OptionDefinition g_option_table[];
Jim Inghamd60d94a2011-03-11 03:53:59 +00003629
3630 std::string m_class_name;
3631 std::string m_function_name;
3632 uint32_t m_line_start;
3633 uint32_t m_line_end;
3634 std::string m_file_name;
3635 std::string m_module_name;
3636 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
3637 lldb::tid_t m_thread_id;
3638 uint32_t m_thread_index;
3639 std::string m_thread_name;
3640 std::string m_queue_name;
3641 bool m_sym_ctx_specified;
3642 bool m_thread_specified;
Johnny Chen60fe60e2011-05-02 23:47:55 +00003643 // Instance variables to hold the values for one_liner options.
3644 bool m_use_one_liner;
3645 std::string m_one_liner;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003646 };
3647
3648 Options *
3649 GetOptions ()
3650 {
3651 return &m_options;
3652 }
3653
3654 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
3655 CommandObject (interpreter,
3656 "target stop-hook add ",
3657 "Add a hook to be executed when the target stops.",
Greg Claytonf15996e2011-04-07 22:46:35 +00003658 "target stop-hook add"),
3659 m_options (interpreter)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003660 {
3661 }
3662
3663 ~CommandObjectTargetStopHookAdd ()
3664 {
3665 }
3666
3667 static size_t
3668 ReadCommandsCallbackFunction (void *baton,
3669 InputReader &reader,
3670 lldb::InputReaderAction notification,
3671 const char *bytes,
3672 size_t bytes_len)
3673 {
Caroline Tice892fadd2011-06-16 16:27:19 +00003674 StreamSP out_stream = reader.GetDebugger().GetAsyncOutputStream();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003675 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
Jim Inghame15511a2011-05-05 01:03:36 +00003676 static bool got_interrupted;
Caroline Tice892fadd2011-06-16 16:27:19 +00003677 bool batch_mode = reader.GetDebugger().GetCommandInterpreter().GetBatchCommandMode();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003678
3679 switch (notification)
3680 {
3681 case eInputReaderActivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00003682 if (!batch_mode)
3683 {
3684 out_stream->Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end.");
3685 if (reader.GetPrompt())
3686 out_stream->Printf ("%s", reader.GetPrompt());
3687 out_stream->Flush();
3688 }
Jim Inghame15511a2011-05-05 01:03:36 +00003689 got_interrupted = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003690 break;
3691
3692 case eInputReaderDeactivate:
3693 break;
3694
3695 case eInputReaderReactivate:
Caroline Tice892fadd2011-06-16 16:27:19 +00003696 if (reader.GetPrompt() && !batch_mode)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003697 {
Caroline Tice892fadd2011-06-16 16:27:19 +00003698 out_stream->Printf ("%s", reader.GetPrompt());
3699 out_stream->Flush();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003700 }
Jim Inghame15511a2011-05-05 01:03:36 +00003701 got_interrupted = false;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003702 break;
3703
Caroline Tice4a348082011-05-02 20:41:46 +00003704 case eInputReaderAsynchronousOutputWritten:
3705 break;
3706
Jim Inghamd60d94a2011-03-11 03:53:59 +00003707 case eInputReaderGotToken:
3708 if (bytes && bytes_len && baton)
3709 {
3710 StringList *commands = new_stop_hook->GetCommandPointer();
3711 if (commands)
3712 {
3713 commands->AppendString (bytes, bytes_len);
3714 }
3715 }
Caroline Tice892fadd2011-06-16 16:27:19 +00003716 if (!reader.IsDone() && reader.GetPrompt() && !batch_mode)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003717 {
Caroline Tice892fadd2011-06-16 16:27:19 +00003718 out_stream->Printf ("%s", reader.GetPrompt());
3719 out_stream->Flush();
Jim Inghamd60d94a2011-03-11 03:53:59 +00003720 }
3721 break;
3722
3723 case eInputReaderInterrupt:
3724 {
3725 // Finish, and cancel the stop hook.
3726 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
Caroline Tice892fadd2011-06-16 16:27:19 +00003727 if (!batch_mode)
3728 {
3729 out_stream->Printf ("Stop hook cancelled.\n");
3730 out_stream->Flush();
3731 }
3732
Jim Inghamd60d94a2011-03-11 03:53:59 +00003733 reader.SetIsDone (true);
3734 }
Jim Inghame15511a2011-05-05 01:03:36 +00003735 got_interrupted = true;
Jim Inghamd60d94a2011-03-11 03:53:59 +00003736 break;
3737
3738 case eInputReaderEndOfFile:
3739 reader.SetIsDone (true);
3740 break;
3741
3742 case eInputReaderDone:
Caroline Tice892fadd2011-06-16 16:27:19 +00003743 if (!got_interrupted && !batch_mode)
3744 {
Greg Clayton444e35b2011-10-19 18:09:39 +00003745 out_stream->Printf ("Stop hook #%llu added.\n", new_stop_hook->GetID());
Caroline Tice892fadd2011-06-16 16:27:19 +00003746 out_stream->Flush();
3747 }
Jim Inghamd60d94a2011-03-11 03:53:59 +00003748 break;
3749 }
3750
3751 return bytes_len;
3752 }
3753
3754 bool
3755 Execute (Args& command,
3756 CommandReturnObject &result)
3757 {
3758 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3759 if (target)
3760 {
3761 Target::StopHookSP new_hook_sp;
3762 target->AddStopHook (new_hook_sp);
3763
3764 // First step, make the specifier.
3765 std::auto_ptr<SymbolContextSpecifier> specifier_ap;
3766 if (m_options.m_sym_ctx_specified)
3767 {
3768 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
3769
3770 if (!m_options.m_module_name.empty())
3771 {
3772 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
3773 }
3774
3775 if (!m_options.m_class_name.empty())
3776 {
3777 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
3778 }
3779
3780 if (!m_options.m_file_name.empty())
3781 {
3782 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
3783 }
3784
3785 if (m_options.m_line_start != 0)
3786 {
3787 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
3788 }
3789
3790 if (m_options.m_line_end != UINT_MAX)
3791 {
3792 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
3793 }
3794
3795 if (!m_options.m_function_name.empty())
3796 {
3797 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
3798 }
3799 }
3800
3801 if (specifier_ap.get())
3802 new_hook_sp->SetSpecifier (specifier_ap.release());
3803
3804 // Next see if any of the thread options have been entered:
3805
3806 if (m_options.m_thread_specified)
3807 {
3808 ThreadSpec *thread_spec = new ThreadSpec();
3809
3810 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
3811 {
3812 thread_spec->SetTID (m_options.m_thread_id);
3813 }
3814
3815 if (m_options.m_thread_index != UINT32_MAX)
3816 thread_spec->SetIndex (m_options.m_thread_index);
3817
3818 if (!m_options.m_thread_name.empty())
3819 thread_spec->SetName (m_options.m_thread_name.c_str());
3820
3821 if (!m_options.m_queue_name.empty())
3822 thread_spec->SetQueueName (m_options.m_queue_name.c_str());
3823
3824 new_hook_sp->SetThreadSpecifier (thread_spec);
3825
3826 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00003827 if (m_options.m_use_one_liner)
Jim Inghamd60d94a2011-03-11 03:53:59 +00003828 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00003829 // Use one-liner.
3830 new_hook_sp->GetCommandPointer()->AppendString (m_options.m_one_liner.c_str());
Greg Clayton444e35b2011-10-19 18:09:39 +00003831 result.AppendMessageWithFormat("Stop hook #%llu added.\n", new_hook_sp->GetID());
Jim Inghamd60d94a2011-03-11 03:53:59 +00003832 }
Johnny Chen60fe60e2011-05-02 23:47:55 +00003833 else
Jim Inghamd60d94a2011-03-11 03:53:59 +00003834 {
Johnny Chen60fe60e2011-05-02 23:47:55 +00003835 // Otherwise gather up the command list, we'll push an input reader and suck the data from that directly into
3836 // the new stop hook's command string.
3837 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
3838 if (!reader_sp)
3839 {
3840 result.AppendError("out of memory\n");
3841 result.SetStatus (eReturnStatusFailed);
3842 target->RemoveStopHookByID (new_hook_sp->GetID());
3843 return false;
3844 }
3845
3846 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
3847 new_hook_sp.get(), // baton
3848 eInputReaderGranularityLine, // token size, to pass to callback function
3849 "DONE", // end token
3850 "> ", // prompt
3851 true)); // echo input
3852 if (!err.Success())
3853 {
3854 result.AppendError (err.AsCString());
3855 result.SetStatus (eReturnStatusFailed);
3856 target->RemoveStopHookByID (new_hook_sp->GetID());
3857 return false;
3858 }
3859 m_interpreter.GetDebugger().PushInputReader (reader_sp);
Jim Inghamd60d94a2011-03-11 03:53:59 +00003860 }
Jim Inghamd60d94a2011-03-11 03:53:59 +00003861 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3862 }
3863 else
3864 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003865 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003866 result.SetStatus (eReturnStatusFailed);
3867 }
3868
3869 return result.Succeeded();
3870 }
3871private:
3872 CommandOptions m_options;
3873};
3874
Greg Claytonb3448432011-03-24 21:19:54 +00003875OptionDefinition
Jim Inghamd60d94a2011-03-11 03:53:59 +00003876CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
3877{
Johnny Chen60fe60e2011-05-02 23:47:55 +00003878 { LLDB_OPT_SET_ALL, false, "one-liner", 'o', required_argument, NULL, NULL, eArgTypeOneLiner,
3879 "Specify a one-line breakpoint command inline. Be sure to surround it with quotes." },
Jim Inghamd60d94a2011-03-11 03:53:59 +00003880 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
3881 "Set the module within which the stop-hook is to be run."},
3882 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex,
3883 "The stop hook is run only for the thread whose index matches this argument."},
3884 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID,
3885 "The stop hook is run only for the thread whose TID matches this argument."},
3886 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName,
3887 "The stop hook is run only for the thread whose thread name matches this argument."},
3888 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName,
3889 "The stop hook is run only for threads in the queue whose name is given by this argument."},
3890 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
3891 "Specify the source file within which the stop-hook is to be run." },
3892 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
3893 "Set the start of the line range for which the stop-hook is to be run."},
3894 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum,
3895 "Set the end of the line range for which the stop-hook is to be run."},
3896 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName,
3897 "Specify the class within which the stop-hook is to be run." },
3898 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
3899 "Set the function name within which the stop hook will be run." },
3900 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
3901};
3902
3903#pragma mark CommandObjectTargetStopHookDelete
3904
3905//-------------------------------------------------------------------------
3906// CommandObjectTargetStopHookDelete
3907//-------------------------------------------------------------------------
3908
3909class CommandObjectTargetStopHookDelete : public CommandObject
3910{
3911public:
3912
3913 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
3914 CommandObject (interpreter,
Jason Molenda3fccc902011-11-10 23:03:44 +00003915 "target stop-hook delete",
Jim Inghamd60d94a2011-03-11 03:53:59 +00003916 "Delete a stop-hook.",
Jason Molenda3fccc902011-11-10 23:03:44 +00003917 "target stop-hook delete [<idx>]")
Jim Inghamd60d94a2011-03-11 03:53:59 +00003918 {
3919 }
3920
3921 ~CommandObjectTargetStopHookDelete ()
3922 {
3923 }
3924
3925 bool
3926 Execute (Args& command,
3927 CommandReturnObject &result)
3928 {
3929 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
3930 if (target)
3931 {
3932 // FIXME: see if we can use the breakpoint id style parser?
3933 size_t num_args = command.GetArgumentCount();
3934 if (num_args == 0)
3935 {
3936 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
3937 {
3938 result.SetStatus (eReturnStatusFailed);
3939 return false;
3940 }
3941 else
3942 {
3943 target->RemoveAllStopHooks();
3944 }
3945 }
3946 else
3947 {
3948 bool success;
3949 for (size_t i = 0; i < num_args; i++)
3950 {
3951 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
3952 if (!success)
3953 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003954 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003955 result.SetStatus(eReturnStatusFailed);
3956 return false;
3957 }
3958 success = target->RemoveStopHookByID (user_id);
3959 if (!success)
3960 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003961 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00003962 result.SetStatus(eReturnStatusFailed);
3963 return false;
3964 }
3965 }
3966 }
3967 result.SetStatus (eReturnStatusSuccessFinishNoResult);
3968 }
3969 else
3970 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00003971 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00003972 result.SetStatus (eReturnStatusFailed);
3973 }
3974
3975 return result.Succeeded();
3976 }
3977};
3978#pragma mark CommandObjectTargetStopHookEnableDisable
3979
3980//-------------------------------------------------------------------------
3981// CommandObjectTargetStopHookEnableDisable
3982//-------------------------------------------------------------------------
3983
3984class CommandObjectTargetStopHookEnableDisable : public CommandObject
3985{
3986public:
3987
3988 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
3989 CommandObject (interpreter,
3990 name,
3991 help,
3992 syntax),
3993 m_enable (enable)
3994 {
3995 }
3996
3997 ~CommandObjectTargetStopHookEnableDisable ()
3998 {
3999 }
4000
4001 bool
4002 Execute (Args& command,
4003 CommandReturnObject &result)
4004 {
4005 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
4006 if (target)
4007 {
4008 // FIXME: see if we can use the breakpoint id style parser?
4009 size_t num_args = command.GetArgumentCount();
4010 bool success;
4011
4012 if (num_args == 0)
4013 {
4014 target->SetAllStopHooksActiveState (m_enable);
4015 }
4016 else
4017 {
4018 for (size_t i = 0; i < num_args; i++)
4019 {
4020 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
4021 if (!success)
4022 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004023 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00004024 result.SetStatus(eReturnStatusFailed);
4025 return false;
4026 }
4027 success = target->SetStopHookActiveStateByID (user_id, m_enable);
4028 if (!success)
4029 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004030 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00004031 result.SetStatus(eReturnStatusFailed);
4032 return false;
4033 }
4034 }
4035 }
4036 result.SetStatus (eReturnStatusSuccessFinishNoResult);
4037 }
4038 else
4039 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004040 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00004041 result.SetStatus (eReturnStatusFailed);
4042 }
4043 return result.Succeeded();
4044 }
4045private:
4046 bool m_enable;
4047};
4048
4049#pragma mark CommandObjectTargetStopHookList
4050
4051//-------------------------------------------------------------------------
4052// CommandObjectTargetStopHookList
4053//-------------------------------------------------------------------------
4054
4055class CommandObjectTargetStopHookList : public CommandObject
4056{
4057public:
4058
4059 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
4060 CommandObject (interpreter,
Jason Molenda3fccc902011-11-10 23:03:44 +00004061 "target stop-hook list",
Jim Inghamd60d94a2011-03-11 03:53:59 +00004062 "List all stop-hooks.",
Jason Molenda3fccc902011-11-10 23:03:44 +00004063 "target stop-hook list [<type>]")
Jim Inghamd60d94a2011-03-11 03:53:59 +00004064 {
4065 }
4066
4067 ~CommandObjectTargetStopHookList ()
4068 {
4069 }
4070
4071 bool
4072 Execute (Args& command,
4073 CommandReturnObject &result)
4074 {
4075 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Johnny Chen9fc16922011-11-29 23:56:14 +00004076 if (!target)
Jim Inghamd60d94a2011-03-11 03:53:59 +00004077 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00004078 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00004079 result.SetStatus (eReturnStatusFailed);
Jason Molenda6e3a2412011-09-23 21:15:42 +00004080 return result.Succeeded();
Jim Inghamd60d94a2011-03-11 03:53:59 +00004081 }
4082
4083 size_t num_hooks = target->GetNumStopHooks ();
4084 if (num_hooks == 0)
4085 {
4086 result.GetOutputStream().PutCString ("No stop hooks.\n");
4087 }
4088 else
4089 {
4090 for (size_t i = 0; i < num_hooks; i++)
4091 {
4092 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
4093 if (i > 0)
4094 result.GetOutputStream().PutCString ("\n");
4095 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
4096 }
4097 }
Johnny Chen6c7c3902011-11-30 19:09:20 +00004098 result.SetStatus (eReturnStatusSuccessFinishResult);
Jim Inghamd60d94a2011-03-11 03:53:59 +00004099 return result.Succeeded();
4100 }
4101};
4102
4103#pragma mark CommandObjectMultiwordTargetStopHooks
4104//-------------------------------------------------------------------------
4105// CommandObjectMultiwordTargetStopHooks
4106//-------------------------------------------------------------------------
4107
4108class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
4109{
4110public:
4111
4112 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
4113 CommandObjectMultiword (interpreter,
4114 "target stop-hook",
4115 "A set of commands for operating on debugger target stop-hooks.",
4116 "target stop-hook <subcommand> [<subcommand-options>]")
4117 {
4118 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
4119 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
4120 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
4121 false,
4122 "target stop-hook disable [<id>]",
4123 "Disable a stop-hook.",
4124 "target stop-hook disable")));
4125 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
4126 true,
4127 "target stop-hook enable [<id>]",
4128 "Enable a stop-hook.",
4129 "target stop-hook enable")));
4130 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
4131 }
4132
4133 ~CommandObjectMultiwordTargetStopHooks()
4134 {
4135 }
4136};
4137
4138
Chris Lattner24943d22010-06-08 16:52:24 +00004139
4140#pragma mark CommandObjectMultiwordTarget
4141
4142//-------------------------------------------------------------------------
4143// CommandObjectMultiwordTarget
4144//-------------------------------------------------------------------------
4145
Greg Clayton63094e02010-06-23 01:19:29 +00004146CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00004147 CommandObjectMultiword (interpreter,
4148 "target",
Chris Lattner24943d22010-06-08 16:52:24 +00004149 "A set of commands for operating on debugger targets.",
4150 "target <subcommand> [<subcommand-options>]")
4151{
Greg Claytonabe0fed2011-04-18 08:33:37 +00004152
4153 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
Greg Clayton153ccd72011-08-10 02:10:13 +00004154 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetDelete (interpreter)));
Greg Claytonabe0fed2011-04-18 08:33:37 +00004155 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter)));
4156 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
Jim Inghamd60d94a2011-03-11 03:53:59 +00004157 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
Greg Claytone1f50b92011-05-03 22:09:39 +00004158 LoadSubCommand ("modules", CommandObjectSP (new CommandObjectTargetModules (interpreter)));
Greg Clayton801417e2011-07-07 01:59:51 +00004159 LoadSubCommand ("variable", CommandObjectSP (new CommandObjectTargetVariable (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00004160}
4161
4162CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
4163{
4164}
4165
Greg Claytonabe0fed2011-04-18 08:33:37 +00004166