blob: f7f873cd8f34bb5d5bc4a70a350b9aa5a895a607 [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 Claytonabe0fed2011-04-18 08:33:37 +000021#include "lldb/Core/State.h"
Chris Lattner24943d22010-06-08 16:52:24 +000022#include "lldb/Core/Timer.h"
Chris Lattner24943d22010-06-08 16:52:24 +000023#include "lldb/Interpreter/CommandInterpreter.h"
24#include "lldb/Interpreter/CommandReturnObject.h"
Greg Claytonabe0fed2011-04-18 08:33:37 +000025#include "lldb/Interpreter/OptionGroupArchitecture.h"
26#include "lldb/Interpreter/OptionGroupPlatform.h"
Chris Lattner24943d22010-06-08 16:52:24 +000027#include "lldb/Target/Process.h"
28#include "lldb/Target/StackFrame.h"
29#include "lldb/Target/Thread.h"
Jim Inghamd60d94a2011-03-11 03:53:59 +000030#include "lldb/Target/ThreadSpec.h"
Chris Lattner24943d22010-06-08 16:52:24 +000031
32using namespace lldb;
33using namespace lldb_private;
34
Greg Claytonabe0fed2011-04-18 08:33:37 +000035
36
37static void
38DumpTargetInfo (uint32_t target_idx, Target *target, const char *prefix_cstr, bool show_stopped_process_status, Stream &strm)
39{
Greg Clayton52c8b6e2011-04-19 04:19:37 +000040 const ArchSpec &target_arch = target->GetArchitecture();
Greg Claytonabe0fed2011-04-18 08:33:37 +000041
42 ModuleSP exe_module_sp (target->GetExecutableModule ());
43 char exe_path[PATH_MAX];
44 bool exe_valid = false;
45 if (exe_module_sp)
46 exe_valid = exe_module_sp->GetFileSpec().GetPath (exe_path, sizeof(exe_path));
47
48 if (!exe_valid)
49 ::strcpy (exe_path, "<none>");
50
51 strm.Printf ("%starget #%u: %s", prefix_cstr ? prefix_cstr : "", target_idx, exe_path);
52
53 uint32_t properties = 0;
54 if (target_arch.IsValid())
55 {
56 strm.Printf ("%sarch=%s", properties++ > 0 ? ", " : " ( ", target_arch.GetTriple().str().c_str());
57 properties++;
58 }
59 PlatformSP platform_sp (target->GetPlatform());
60 if (platform_sp)
61 strm.Printf ("%splatform=%s", properties++ > 0 ? ", " : " ( ", platform_sp->GetName());
62
63 ProcessSP process_sp (target->GetProcessSP());
64 bool show_process_status = false;
65 if (process_sp)
66 {
67 lldb::pid_t pid = process_sp->GetID();
68 StateType state = process_sp->GetState();
69 if (show_stopped_process_status)
70 show_process_status = StateIsStoppedState(state);
71 const char *state_cstr = StateAsCString (state);
72 if (pid != LLDB_INVALID_PROCESS_ID)
73 strm.Printf ("%spid=%i", properties++ > 0 ? ", " : " ( ", pid);
74 strm.Printf ("%sstate=%s", properties++ > 0 ? ", " : " ( ", state_cstr);
75 }
76 if (properties > 0)
77 strm.PutCString (" )\n");
78 else
79 strm.EOL();
80 if (show_process_status)
81 {
82 const bool only_threads_with_stop_reason = true;
83 const uint32_t start_frame = 0;
84 const uint32_t num_frames = 1;
85 const uint32_t num_frames_with_source = 1;
86 process_sp->GetStatus (strm);
87 process_sp->GetThreadStatus (strm,
88 only_threads_with_stop_reason,
89 start_frame,
90 num_frames,
91 num_frames_with_source);
92
93 }
94}
95
96static uint32_t
97DumpTargetList (TargetList &target_list, bool show_stopped_process_status, Stream &strm)
98{
99 const uint32_t num_targets = target_list.GetNumTargets();
100 if (num_targets)
101 {
102 TargetSP selected_target_sp (target_list.GetSelectedTarget());
103 strm.PutCString ("Current targets:\n");
104 for (uint32_t i=0; i<num_targets; ++i)
105 {
106 TargetSP target_sp (target_list.GetTargetAtIndex (i));
107 if (target_sp)
108 {
109 bool is_selected = target_sp.get() == selected_target_sp.get();
110 DumpTargetInfo (i,
111 target_sp.get(),
112 is_selected ? "* " : " ",
113 show_stopped_process_status,
114 strm);
115 }
116 }
117 }
118 return num_targets;
119}
120#pragma mark CommandObjectTargetCreate
121
122//-------------------------------------------------------------------------
123// "target create"
124//-------------------------------------------------------------------------
125
126class CommandObjectTargetCreate : public CommandObject
127{
128public:
129 CommandObjectTargetCreate(CommandInterpreter &interpreter) :
130 CommandObject (interpreter,
131 "target create",
132 "Create a target using the argument as the main executable.",
133 NULL),
134 m_option_group (interpreter),
135 m_file_options (),
136 m_platform_options(true) // Do include the "--platform" option in the platform settings by passing true
137 {
138 CommandArgumentEntry arg;
139 CommandArgumentData file_arg;
140
141 // Define the first (and only) variant of this arg.
142 file_arg.arg_type = eArgTypeFilename;
143 file_arg.arg_repetition = eArgRepeatPlain;
144
145 // There is only one variant this argument could be; put it into the argument entry.
146 arg.push_back (file_arg);
147
148 // Push the data for the first argument into the m_arguments vector.
149 m_arguments.push_back (arg);
150
151 m_option_group.Append (&m_file_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
152 m_option_group.Append (&m_platform_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_1);
153 m_option_group.Finalize();
154 }
155
156 ~CommandObjectTargetCreate ()
157 {
158 }
159
160 Options *
161 GetOptions ()
162 {
163 return &m_option_group;
164 }
165
166 bool
167 Execute (Args& command, CommandReturnObject &result)
168 {
169 const int argc = command.GetArgumentCount();
170 if (argc == 1)
171 {
172 const char *file_path = command.GetArgumentAtIndex(0);
173 Timer scoped_timer(__PRETTY_FUNCTION__, "(lldb) target create '%s'", file_path);
174 FileSpec file_spec (file_path, true);
175
176 bool select = true;
177 PlatformSP platform_sp;
178
179 Error error;
180
181 if (m_platform_options.PlatformWasSpecified ())
182 {
183 platform_sp = m_platform_options.CreatePlatformWithOptions(m_interpreter, select, error);
184 if (!platform_sp)
185 {
186 result.AppendError(error.AsCString());
187 result.SetStatus (eReturnStatusFailed);
188 return false;
189 }
190 }
191 ArchSpec file_arch;
192
193 const char *arch_cstr = m_file_options.GetArchitectureName();
194 if (arch_cstr)
195 {
196 if (!platform_sp)
197 platform_sp = m_interpreter.GetDebugger().GetPlatformList().GetSelectedPlatform();
198 if (!m_file_options.GetArchitecture(platform_sp.get(), file_arch))
199 {
200 result.AppendErrorWithFormat("invalid architecture '%s'\n", arch_cstr);
201 result.SetStatus (eReturnStatusFailed);
202 return false;
203 }
204 }
205
206 if (! file_spec.Exists() && !file_spec.ResolveExecutableLocation())
207 {
208 result.AppendErrorWithFormat ("File '%s' does not exist.\n", file_path);
209 result.SetStatus (eReturnStatusFailed);
210 return false;
211 }
212
213 TargetSP target_sp;
214 Debugger &debugger = m_interpreter.GetDebugger();
215 error = debugger.GetTargetList().CreateTarget (debugger, file_spec, file_arch, true, target_sp);
216
217 if (target_sp)
218 {
219 debugger.GetTargetList().SetSelectedTarget(target_sp.get());
220 result.AppendMessageWithFormat ("Current executable set to '%s' (%s).\n", file_path, target_sp->GetArchitecture().GetArchitectureName());
221 result.SetStatus (eReturnStatusSuccessFinishNoResult);
222 }
223 else
224 {
225 result.AppendError(error.AsCString());
226 result.SetStatus (eReturnStatusFailed);
227 }
228 }
229 else
230 {
231 result.AppendErrorWithFormat("'%s' takes exactly one executable path argument.\n", m_cmd_name.c_str());
232 result.SetStatus (eReturnStatusFailed);
233 }
234 return result.Succeeded();
235
236 }
237
238 int
239 HandleArgumentCompletion (Args &input,
240 int &cursor_index,
241 int &cursor_char_position,
242 OptionElementVector &opt_element_vector,
243 int match_start_point,
244 int max_return_elements,
245 bool &word_complete,
246 StringList &matches)
247 {
248 std::string completion_str (input.GetArgumentAtIndex(cursor_index));
249 completion_str.erase (cursor_char_position);
250
251 CommandCompletions::InvokeCommonCompletionCallbacks (m_interpreter,
252 CommandCompletions::eDiskFileCompletion,
253 completion_str.c_str(),
254 match_start_point,
255 max_return_elements,
256 NULL,
257 word_complete,
258 matches);
259 return matches.GetSize();
260 }
261private:
262 OptionGroupOptions m_option_group;
263 OptionGroupArchitecture m_file_options;
264 OptionGroupPlatform m_platform_options;
265
266};
267
268#pragma mark CommandObjectTargetList
269
270//----------------------------------------------------------------------
271// "target list"
272//----------------------------------------------------------------------
273
274class CommandObjectTargetList : public CommandObject
275{
276public:
277 CommandObjectTargetList (CommandInterpreter &interpreter) :
278 CommandObject (interpreter,
279 "target list",
280 "List all current targets in the current debug session.",
281 NULL,
282 0)
283 {
284 }
285
286 virtual
287 ~CommandObjectTargetList ()
288 {
289 }
290
291 virtual bool
292 Execute (Args& args, CommandReturnObject &result)
293 {
294 if (args.GetArgumentCount() == 0)
295 {
296 Stream &strm = result.GetOutputStream();
297
298 bool show_stopped_process_status = false;
299 if (DumpTargetList (m_interpreter.GetDebugger().GetTargetList(), show_stopped_process_status, strm) == 0)
300 {
301 strm.PutCString ("No targets.\n");
302 }
Johnny Chen44dc9d32011-04-18 21:08:05 +0000303 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000304 }
305 else
306 {
307 result.AppendError ("the 'target list' command takes no arguments\n");
308 result.SetStatus (eReturnStatusFailed);
309 }
310 return result.Succeeded();
311 }
312};
313
314
315#pragma mark CommandObjectTargetSelect
316
317//----------------------------------------------------------------------
318// "target select"
319//----------------------------------------------------------------------
320
321class CommandObjectTargetSelect : public CommandObject
322{
323public:
324 CommandObjectTargetSelect (CommandInterpreter &interpreter) :
325 CommandObject (interpreter,
326 "target select",
327 "Select a target as the current target by target index.",
328 NULL,
329 0)
330 {
331 }
332
333 virtual
334 ~CommandObjectTargetSelect ()
335 {
336 }
337
338 virtual bool
339 Execute (Args& args, CommandReturnObject &result)
340 {
341 if (args.GetArgumentCount() == 1)
342 {
343 bool success = false;
344 const char *target_idx_arg = args.GetArgumentAtIndex(0);
345 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
346 if (success)
347 {
348 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
349 const uint32_t num_targets = target_list.GetNumTargets();
350 if (target_idx < num_targets)
351 {
352 TargetSP target_sp (target_list.GetTargetAtIndex (target_idx));
353 if (target_sp)
354 {
355 Stream &strm = result.GetOutputStream();
356 target_list.SetSelectedTarget (target_sp.get());
357 bool show_stopped_process_status = false;
358 DumpTargetList (target_list, show_stopped_process_status, strm);
Johnny Chen44dc9d32011-04-18 21:08:05 +0000359 result.SetStatus (eReturnStatusSuccessFinishResult);
Greg Claytonabe0fed2011-04-18 08:33:37 +0000360 }
361 else
362 {
363 result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx);
364 result.SetStatus (eReturnStatusFailed);
365 }
366 }
367 else
368 {
369 result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n",
370 target_idx,
371 num_targets - 1);
372 result.SetStatus (eReturnStatusFailed);
373 }
374 }
375 else
376 {
377 result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg);
378 result.SetStatus (eReturnStatusFailed);
379 }
380 }
381 else
382 {
383 result.AppendError ("'target select' takes a single argument: a target index\n");
384 result.SetStatus (eReturnStatusFailed);
385 }
386 return result.Succeeded();
387 }
388};
389
390
Chris Lattner24943d22010-06-08 16:52:24 +0000391#pragma mark CommandObjectTargetImageSearchPaths
392
393class CommandObjectTargetImageSearchPathsAdd : public CommandObject
394{
395public:
396
Greg Clayton238c0a12010-09-18 01:14:36 +0000397 CommandObjectTargetImageSearchPathsAdd (CommandInterpreter &interpreter) :
398 CommandObject (interpreter,
399 "target image-search-paths add",
Chris Lattner24943d22010-06-08 16:52:24 +0000400 "Add new image search paths substitution pairs to the current target.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000401 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000402 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000403 CommandArgumentEntry arg;
404 CommandArgumentData old_prefix_arg;
405 CommandArgumentData new_prefix_arg;
406
407 // Define the first variant of this arg pair.
408 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
409 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
410
411 // Define the first variant of this arg pair.
412 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
413 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
414
415 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
416 // must always occur together, they are treated as two variants of one argument rather than two independent
417 // arguments. Push them both into the first argument position for m_arguments...
418
419 arg.push_back (old_prefix_arg);
420 arg.push_back (new_prefix_arg);
421
422 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000423 }
424
425 ~CommandObjectTargetImageSearchPathsAdd ()
426 {
427 }
428
429 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000430 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000431 CommandReturnObject &result)
432 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000433 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000434 if (target)
435 {
436 uint32_t argc = command.GetArgumentCount();
437 if (argc & 1)
438 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000439 result.AppendError ("add requires an even number of arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000440 result.SetStatus (eReturnStatusFailed);
441 }
442 else
443 {
444 for (uint32_t i=0; i<argc; i+=2)
445 {
446 const char *from = command.GetArgumentAtIndex(i);
447 const char *to = command.GetArgumentAtIndex(i+1);
448
449 if (from[0] && to[0])
450 {
451 bool last_pair = ((argc - i) == 2);
Greg Clayton63094e02010-06-23 01:19:29 +0000452 target->GetImageSearchPathList().Append (ConstString(from),
453 ConstString(to),
454 last_pair); // Notify if this is the last pair
Johnny Chen4d661352011-02-03 00:30:19 +0000455 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000456 }
457 else
458 {
459 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +0000460 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000461 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000462 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000463 result.SetStatus (eReturnStatusFailed);
464 }
465 }
466 }
467 }
468 else
469 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000470 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000471 result.SetStatus (eReturnStatusFailed);
472 }
473 return result.Succeeded();
474 }
475};
476
477class CommandObjectTargetImageSearchPathsClear : public CommandObject
478{
479public:
480
Greg Clayton238c0a12010-09-18 01:14:36 +0000481 CommandObjectTargetImageSearchPathsClear (CommandInterpreter &interpreter) :
482 CommandObject (interpreter,
483 "target image-search-paths clear",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000484 "Clear all current image search path substitution pairs from the current target.",
Chris Lattner24943d22010-06-08 16:52:24 +0000485 "target image-search-paths clear")
486 {
487 }
488
489 ~CommandObjectTargetImageSearchPathsClear ()
490 {
491 }
492
493 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000494 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000495 CommandReturnObject &result)
496 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000497 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000498 if (target)
499 {
500 bool notify = true;
501 target->GetImageSearchPathList().Clear(notify);
Johnny Chen4d661352011-02-03 00:30:19 +0000502 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000503 }
504 else
505 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000506 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000507 result.SetStatus (eReturnStatusFailed);
508 }
509 return result.Succeeded();
510 }
511};
512
513class CommandObjectTargetImageSearchPathsInsert : public CommandObject
514{
515public:
516
Greg Clayton238c0a12010-09-18 01:14:36 +0000517 CommandObjectTargetImageSearchPathsInsert (CommandInterpreter &interpreter) :
518 CommandObject (interpreter,
519 "target image-search-paths insert",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000520 "Insert a new image search path substitution pair into the current target at the specified index.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000521 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000522 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000523 CommandArgumentEntry arg1;
524 CommandArgumentEntry arg2;
525 CommandArgumentData index_arg;
526 CommandArgumentData old_prefix_arg;
527 CommandArgumentData new_prefix_arg;
528
529 // Define the first and only variant of this arg.
530 index_arg.arg_type = eArgTypeIndex;
531 index_arg.arg_repetition = eArgRepeatPlain;
532
533 // Put the one and only variant into the first arg for m_arguments:
534 arg1.push_back (index_arg);
535
536 // Define the first variant of this arg pair.
537 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
538 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
539
540 // Define the first variant of this arg pair.
541 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
542 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
543
544 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
545 // must always occur together, they are treated as two variants of one argument rather than two independent
546 // arguments. Push them both into the same argument position for m_arguments...
547
548 arg2.push_back (old_prefix_arg);
549 arg2.push_back (new_prefix_arg);
550
551 // Add arguments to m_arguments.
552 m_arguments.push_back (arg1);
553 m_arguments.push_back (arg2);
Chris Lattner24943d22010-06-08 16:52:24 +0000554 }
555
556 ~CommandObjectTargetImageSearchPathsInsert ()
557 {
558 }
559
560 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000561 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000562 CommandReturnObject &result)
563 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000564 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000565 if (target)
566 {
567 uint32_t argc = command.GetArgumentCount();
568 // check for at least 3 arguments and an odd nubmer of parameters
569 if (argc >= 3 && argc & 1)
570 {
571 bool success = false;
572
573 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
574
575 if (!success)
576 {
577 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
578 result.SetStatus (eReturnStatusFailed);
579 return result.Succeeded();
580 }
581
582 // shift off the index
583 command.Shift();
584 argc = command.GetArgumentCount();
585
586 for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
587 {
588 const char *from = command.GetArgumentAtIndex(i);
589 const char *to = command.GetArgumentAtIndex(i+1);
590
591 if (from[0] && to[0])
592 {
593 bool last_pair = ((argc - i) == 2);
594 target->GetImageSearchPathList().Insert (ConstString(from),
595 ConstString(to),
596 insert_idx,
597 last_pair);
Johnny Chen4d661352011-02-03 00:30:19 +0000598 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000599 }
600 else
601 {
602 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +0000603 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000604 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000605 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000606 result.SetStatus (eReturnStatusFailed);
607 return false;
608 }
609 }
610 }
611 else
612 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000613 result.AppendError ("insert requires at least three arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000614 result.SetStatus (eReturnStatusFailed);
615 return result.Succeeded();
616 }
617
618 }
619 else
620 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000621 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000622 result.SetStatus (eReturnStatusFailed);
623 }
624 return result.Succeeded();
625 }
626};
627
628class CommandObjectTargetImageSearchPathsList : public CommandObject
629{
630public:
631
Greg Clayton238c0a12010-09-18 01:14:36 +0000632 CommandObjectTargetImageSearchPathsList (CommandInterpreter &interpreter) :
633 CommandObject (interpreter,
634 "target image-search-paths list",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000635 "List all current image search path substitution pairs in the current target.",
Chris Lattner24943d22010-06-08 16:52:24 +0000636 "target image-search-paths list")
637 {
638 }
639
640 ~CommandObjectTargetImageSearchPathsList ()
641 {
642 }
643
644 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000645 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000646 CommandReturnObject &result)
647 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000648 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000649 if (target)
650 {
651 if (command.GetArgumentCount() != 0)
652 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000653 result.AppendError ("list takes no arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000654 result.SetStatus (eReturnStatusFailed);
655 return result.Succeeded();
656 }
657
658 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
Johnny Chen4d661352011-02-03 00:30:19 +0000659 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000660 }
661 else
662 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000663 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000664 result.SetStatus (eReturnStatusFailed);
665 }
666 return result.Succeeded();
667 }
668};
669
670class CommandObjectTargetImageSearchPathsQuery : public CommandObject
671{
672public:
673
Greg Clayton238c0a12010-09-18 01:14:36 +0000674 CommandObjectTargetImageSearchPathsQuery (CommandInterpreter &interpreter) :
675 CommandObject (interpreter,
676 "target image-search-paths query",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000677 "Transform a path using the first applicable image search path.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000678 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000679 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000680 CommandArgumentEntry arg;
681 CommandArgumentData path_arg;
682
683 // Define the first (and only) variant of this arg.
684 path_arg.arg_type = eArgTypePath;
685 path_arg.arg_repetition = eArgRepeatPlain;
686
687 // There is only one variant this argument could be; put it into the argument entry.
688 arg.push_back (path_arg);
689
690 // Push the data for the first argument into the m_arguments vector.
691 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000692 }
693
694 ~CommandObjectTargetImageSearchPathsQuery ()
695 {
696 }
697
698 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000699 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000700 CommandReturnObject &result)
701 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000702 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000703 if (target)
704 {
705 if (command.GetArgumentCount() != 1)
706 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000707 result.AppendError ("query requires one argument\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000708 result.SetStatus (eReturnStatusFailed);
709 return result.Succeeded();
710 }
711
712 ConstString orig(command.GetArgumentAtIndex(0));
713 ConstString transformed;
714 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
715 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
716 else
717 result.GetOutputStream().Printf("%s\n", orig.GetCString());
Johnny Chen4d661352011-02-03 00:30:19 +0000718
719 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000720 }
721 else
722 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000723 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000724 result.SetStatus (eReturnStatusFailed);
725 }
726 return result.Succeeded();
727 }
728};
729
730// TODO: implement the target select later when we start doing multiple targets
731//#pragma mark CommandObjectTargetSelect
732//
733////-------------------------------------------------------------------------
734//// CommandObjectTargetSelect
735////-------------------------------------------------------------------------
736//
737//class CommandObjectTargetSelect : public CommandObject
738//{
739//public:
740//
741// CommandObjectTargetSelect () :
Greg Clayton238c0a12010-09-18 01:14:36 +0000742// CommandObject (interpreter,
743// frame select",
Chris Lattner24943d22010-06-08 16:52:24 +0000744// "Select the current frame by index in the current thread.",
745// "frame select <frame-index>")
746// {
747// }
748//
749// ~CommandObjectTargetSelect ()
750// {
751// }
752//
753// bool
754// Execute (Args& command,
Greg Clayton63094e02010-06-23 01:19:29 +0000755// Debugger *context,
Greg Clayton238c0a12010-09-18 01:14:36 +0000756// CommandInterpreter &m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000757// CommandReturnObject &result)
758// {
759// ExecutionContext exe_ctx (context->GetExecutionContext());
760// if (exe_ctx.thread)
761// {
762// if (command.GetArgumentCount() == 1)
763// {
764// const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
765//
766// const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount();
767// const uint32_t frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0);
768// if (frame_idx < num_frames)
769// {
Jim Inghamc8332952010-08-26 21:32:51 +0000770// exe_ctx.thread->SetSelectedFrameByIndex (frame_idx);
771// exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000772//
773// if (exe_ctx.frame)
774// {
775// if (DisplayFrameForExecutionContext (exe_ctx.thread,
776// exe_ctx.frame,
Greg Clayton238c0a12010-09-18 01:14:36 +0000777// m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000778// result.GetOutputStream(),
779// true,
780// true,
781// 3,
782// 3))
783// {
784// result.SetStatus (eReturnStatusSuccessFinishResult);
785// return result.Succeeded();
786// }
787// }
788// }
789// if (frame_idx == UINT32_MAX)
790// result.AppendErrorWithFormat ("Invalid frame index: %s.\n", frame_idx_cstr);
791// else
792// result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx);
793// }
794// else
795// {
796// result.AppendError ("invalid arguments");
797// result.AppendErrorWithFormat ("Usage: %s\n", m_cmd_syntax.c_str());
798// }
799// }
800// else
801// {
802// result.AppendError ("no current thread");
803// }
804// result.SetStatus (eReturnStatusFailed);
805// return false;
806// }
807//};
808
809
Jim Inghamd60d94a2011-03-11 03:53:59 +0000810#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner24943d22010-06-08 16:52:24 +0000811
812//-------------------------------------------------------------------------
813// CommandObjectMultiwordImageSearchPaths
814//-------------------------------------------------------------------------
815
816class CommandObjectMultiwordImageSearchPaths : public CommandObjectMultiword
817{
818public:
819
Greg Clayton63094e02010-06-23 01:19:29 +0000820 CommandObjectMultiwordImageSearchPaths (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000821 CommandObjectMultiword (interpreter,
822 "target image-search-paths",
Chris Lattner24943d22010-06-08 16:52:24 +0000823 "A set of commands for operating on debugger target image search paths.",
824 "target image-search-paths <subcommand> [<subcommand-options>]")
825 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000826 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetImageSearchPathsAdd (interpreter)));
827 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetImageSearchPathsClear (interpreter)));
828 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetImageSearchPathsInsert (interpreter)));
829 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetImageSearchPathsList (interpreter)));
830 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetImageSearchPathsQuery (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +0000831 }
832
833 ~CommandObjectMultiwordImageSearchPaths()
834 {
835 }
836};
837
Jim Inghamd60d94a2011-03-11 03:53:59 +0000838#pragma mark CommandObjectTargetStopHookAdd
839
840//-------------------------------------------------------------------------
841// CommandObjectTargetStopHookAdd
842//-------------------------------------------------------------------------
843
844class CommandObjectTargetStopHookAdd : public CommandObject
845{
846public:
847
848 class CommandOptions : public Options
849 {
850 public:
Greg Claytonf15996e2011-04-07 22:46:35 +0000851 CommandOptions (CommandInterpreter &interpreter) :
852 Options(interpreter),
Jim Inghamd60d94a2011-03-11 03:53:59 +0000853 m_line_start(0),
854 m_line_end (UINT_MAX),
855 m_func_name_type_mask (eFunctionNameTypeAuto),
856 m_sym_ctx_specified (false),
857 m_thread_specified (false)
858 {
859 }
860
861 ~CommandOptions () {}
862
Greg Claytonb3448432011-03-24 21:19:54 +0000863 const OptionDefinition*
Jim Inghamd60d94a2011-03-11 03:53:59 +0000864 GetDefinitions ()
865 {
866 return g_option_table;
867 }
868
869 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000870 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghamd60d94a2011-03-11 03:53:59 +0000871 {
872 Error error;
873 char short_option = (char) m_getopt_table[option_idx].val;
874 bool success;
875
876 switch (short_option)
877 {
878 case 'c':
879 m_class_name = option_arg;
880 m_sym_ctx_specified = true;
881 break;
882
883 case 'e':
884 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
885 if (!success)
886 {
887 error.SetErrorStringWithFormat ("Invalid end line number: \"%s\".", option_arg);
888 break;
889 }
890 m_sym_ctx_specified = true;
891 break;
892
893 case 'l':
894 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
895 if (!success)
896 {
897 error.SetErrorStringWithFormat ("Invalid start line number: \"%s\".", option_arg);
898 break;
899 }
900 m_sym_ctx_specified = true;
901 break;
902
903 case 'n':
904 m_function_name = option_arg;
905 m_func_name_type_mask |= eFunctionNameTypeAuto;
906 m_sym_ctx_specified = true;
907 break;
908
909 case 'f':
910 m_file_name = option_arg;
911 m_sym_ctx_specified = true;
912 break;
913 case 's':
914 m_module_name = option_arg;
915 m_sym_ctx_specified = true;
916 break;
917 case 't' :
918 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000919 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000920 if (m_thread_id == LLDB_INVALID_THREAD_ID)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000921 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000922 m_thread_specified = true;
923 }
924 break;
925 case 'T':
926 m_thread_name = option_arg;
927 m_thread_specified = true;
928 break;
929 case 'q':
930 m_queue_name = option_arg;
931 m_thread_specified = true;
932 break;
933 case 'x':
934 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000935 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000936 if (m_thread_id == UINT32_MAX)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000937 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000938 m_thread_specified = true;
939 }
940 break;
941 default:
942 error.SetErrorStringWithFormat ("Unrecognized option %c.");
943 break;
944 }
945 return error;
946 }
947
948 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000949 OptionParsingStarting ()
Jim Inghamd60d94a2011-03-11 03:53:59 +0000950 {
951 m_class_name.clear();
952 m_function_name.clear();
953 m_line_start = 0;
954 m_line_end = UINT_MAX;
955 m_file_name.clear();
956 m_module_name.clear();
957 m_func_name_type_mask = eFunctionNameTypeAuto;
958 m_thread_id = LLDB_INVALID_THREAD_ID;
959 m_thread_index = UINT32_MAX;
960 m_thread_name.clear();
961 m_queue_name.clear();
962
963 m_sym_ctx_specified = false;
964 m_thread_specified = false;
965 }
966
967
Greg Claytonb3448432011-03-24 21:19:54 +0000968 static OptionDefinition g_option_table[];
Jim Inghamd60d94a2011-03-11 03:53:59 +0000969
970 std::string m_class_name;
971 std::string m_function_name;
972 uint32_t m_line_start;
973 uint32_t m_line_end;
974 std::string m_file_name;
975 std::string m_module_name;
976 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
977 lldb::tid_t m_thread_id;
978 uint32_t m_thread_index;
979 std::string m_thread_name;
980 std::string m_queue_name;
981 bool m_sym_ctx_specified;
982 bool m_thread_specified;
983
984 };
985
986 Options *
987 GetOptions ()
988 {
989 return &m_options;
990 }
991
992 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
993 CommandObject (interpreter,
994 "target stop-hook add ",
995 "Add a hook to be executed when the target stops.",
Greg Claytonf15996e2011-04-07 22:46:35 +0000996 "target stop-hook add"),
997 m_options (interpreter)
Jim Inghamd60d94a2011-03-11 03:53:59 +0000998 {
999 }
1000
1001 ~CommandObjectTargetStopHookAdd ()
1002 {
1003 }
1004
1005 static size_t
1006 ReadCommandsCallbackFunction (void *baton,
1007 InputReader &reader,
1008 lldb::InputReaderAction notification,
1009 const char *bytes,
1010 size_t bytes_len)
1011 {
1012 File &out_file = reader.GetDebugger().GetOutputFile();
1013 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
1014
1015 switch (notification)
1016 {
1017 case eInputReaderActivate:
1018 out_file.Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end.");
1019 if (reader.GetPrompt())
1020 out_file.Printf ("%s", reader.GetPrompt());
1021 out_file.Flush();
1022 break;
1023
1024 case eInputReaderDeactivate:
1025 break;
1026
1027 case eInputReaderReactivate:
1028 if (reader.GetPrompt())
1029 {
1030 out_file.Printf ("%s", reader.GetPrompt());
1031 out_file.Flush();
1032 }
1033 break;
1034
Caroline Tice4a348082011-05-02 20:41:46 +00001035 case eInputReaderAsynchronousOutputWritten:
1036 break;
1037
Jim Inghamd60d94a2011-03-11 03:53:59 +00001038 case eInputReaderGotToken:
1039 if (bytes && bytes_len && baton)
1040 {
1041 StringList *commands = new_stop_hook->GetCommandPointer();
1042 if (commands)
1043 {
1044 commands->AppendString (bytes, bytes_len);
1045 }
1046 }
1047 if (!reader.IsDone() && reader.GetPrompt())
1048 {
1049 out_file.Printf ("%s", reader.GetPrompt());
1050 out_file.Flush();
1051 }
1052 break;
1053
1054 case eInputReaderInterrupt:
1055 {
1056 // Finish, and cancel the stop hook.
1057 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
1058 out_file.Printf ("Stop hook cancelled.\n");
1059
1060 reader.SetIsDone (true);
1061 }
1062 break;
1063
1064 case eInputReaderEndOfFile:
1065 reader.SetIsDone (true);
1066 break;
1067
1068 case eInputReaderDone:
1069 out_file.Printf ("Stop hook #%d added.\n", new_stop_hook->GetID());
1070 break;
1071 }
1072
1073 return bytes_len;
1074 }
1075
1076 bool
1077 Execute (Args& command,
1078 CommandReturnObject &result)
1079 {
1080 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1081 if (target)
1082 {
1083 Target::StopHookSP new_hook_sp;
1084 target->AddStopHook (new_hook_sp);
1085
1086 // First step, make the specifier.
1087 std::auto_ptr<SymbolContextSpecifier> specifier_ap;
1088 if (m_options.m_sym_ctx_specified)
1089 {
1090 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
1091
1092 if (!m_options.m_module_name.empty())
1093 {
1094 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
1095 }
1096
1097 if (!m_options.m_class_name.empty())
1098 {
1099 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
1100 }
1101
1102 if (!m_options.m_file_name.empty())
1103 {
1104 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
1105 }
1106
1107 if (m_options.m_line_start != 0)
1108 {
1109 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
1110 }
1111
1112 if (m_options.m_line_end != UINT_MAX)
1113 {
1114 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
1115 }
1116
1117 if (!m_options.m_function_name.empty())
1118 {
1119 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
1120 }
1121 }
1122
1123 if (specifier_ap.get())
1124 new_hook_sp->SetSpecifier (specifier_ap.release());
1125
1126 // Next see if any of the thread options have been entered:
1127
1128 if (m_options.m_thread_specified)
1129 {
1130 ThreadSpec *thread_spec = new ThreadSpec();
1131
1132 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
1133 {
1134 thread_spec->SetTID (m_options.m_thread_id);
1135 }
1136
1137 if (m_options.m_thread_index != UINT32_MAX)
1138 thread_spec->SetIndex (m_options.m_thread_index);
1139
1140 if (!m_options.m_thread_name.empty())
1141 thread_spec->SetName (m_options.m_thread_name.c_str());
1142
1143 if (!m_options.m_queue_name.empty())
1144 thread_spec->SetQueueName (m_options.m_queue_name.c_str());
1145
1146 new_hook_sp->SetThreadSpecifier (thread_spec);
1147
1148 }
1149 // Next gather up the command list, we'll push an input reader and suck the data from that directly into
1150 // the new stop hook's command string.
1151
1152 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
1153 if (!reader_sp)
1154 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001155 result.AppendError("out of memory\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001156 result.SetStatus (eReturnStatusFailed);
1157 target->RemoveStopHookByID (new_hook_sp->GetID());
1158 return false;
1159 }
1160
1161 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
1162 new_hook_sp.get(), // baton
1163 eInputReaderGranularityLine, // token size, to pass to callback function
1164 "DONE", // end token
1165 "> ", // prompt
1166 true)); // echo input
1167 if (!err.Success())
1168 {
1169 result.AppendError (err.AsCString());
1170 result.SetStatus (eReturnStatusFailed);
1171 target->RemoveStopHookByID (new_hook_sp->GetID());
1172 return false;
1173 }
1174 m_interpreter.GetDebugger().PushInputReader (reader_sp);
1175
1176 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1177 }
1178 else
1179 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001180 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001181 result.SetStatus (eReturnStatusFailed);
1182 }
1183
1184 return result.Succeeded();
1185 }
1186private:
1187 CommandOptions m_options;
1188};
1189
Greg Claytonb3448432011-03-24 21:19:54 +00001190OptionDefinition
Jim Inghamd60d94a2011-03-11 03:53:59 +00001191CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
1192{
1193 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
1194 "Set the module within which the stop-hook is to be run."},
1195 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex,
1196 "The stop hook is run only for the thread whose index matches this argument."},
1197 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID,
1198 "The stop hook is run only for the thread whose TID matches this argument."},
1199 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName,
1200 "The stop hook is run only for the thread whose thread name matches this argument."},
1201 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName,
1202 "The stop hook is run only for threads in the queue whose name is given by this argument."},
1203 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1204 "Specify the source file within which the stop-hook is to be run." },
1205 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
1206 "Set the start of the line range for which the stop-hook is to be run."},
1207 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum,
1208 "Set the end of the line range for which the stop-hook is to be run."},
1209 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName,
1210 "Specify the class within which the stop-hook is to be run." },
1211 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
1212 "Set the function name within which the stop hook will be run." },
1213 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1214};
1215
1216#pragma mark CommandObjectTargetStopHookDelete
1217
1218//-------------------------------------------------------------------------
1219// CommandObjectTargetStopHookDelete
1220//-------------------------------------------------------------------------
1221
1222class CommandObjectTargetStopHookDelete : public CommandObject
1223{
1224public:
1225
1226 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
1227 CommandObject (interpreter,
1228 "target stop-hook delete [<id>]",
1229 "Delete a stop-hook.",
1230 "target stop-hook delete")
1231 {
1232 }
1233
1234 ~CommandObjectTargetStopHookDelete ()
1235 {
1236 }
1237
1238 bool
1239 Execute (Args& command,
1240 CommandReturnObject &result)
1241 {
1242 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1243 if (target)
1244 {
1245 // FIXME: see if we can use the breakpoint id style parser?
1246 size_t num_args = command.GetArgumentCount();
1247 if (num_args == 0)
1248 {
1249 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
1250 {
1251 result.SetStatus (eReturnStatusFailed);
1252 return false;
1253 }
1254 else
1255 {
1256 target->RemoveAllStopHooks();
1257 }
1258 }
1259 else
1260 {
1261 bool success;
1262 for (size_t i = 0; i < num_args; i++)
1263 {
1264 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
1265 if (!success)
1266 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001267 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001268 result.SetStatus(eReturnStatusFailed);
1269 return false;
1270 }
1271 success = target->RemoveStopHookByID (user_id);
1272 if (!success)
1273 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001274 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001275 result.SetStatus(eReturnStatusFailed);
1276 return false;
1277 }
1278 }
1279 }
1280 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1281 }
1282 else
1283 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001284 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001285 result.SetStatus (eReturnStatusFailed);
1286 }
1287
1288 return result.Succeeded();
1289 }
1290};
1291#pragma mark CommandObjectTargetStopHookEnableDisable
1292
1293//-------------------------------------------------------------------------
1294// CommandObjectTargetStopHookEnableDisable
1295//-------------------------------------------------------------------------
1296
1297class CommandObjectTargetStopHookEnableDisable : public CommandObject
1298{
1299public:
1300
1301 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
1302 CommandObject (interpreter,
1303 name,
1304 help,
1305 syntax),
1306 m_enable (enable)
1307 {
1308 }
1309
1310 ~CommandObjectTargetStopHookEnableDisable ()
1311 {
1312 }
1313
1314 bool
1315 Execute (Args& command,
1316 CommandReturnObject &result)
1317 {
1318 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1319 if (target)
1320 {
1321 // FIXME: see if we can use the breakpoint id style parser?
1322 size_t num_args = command.GetArgumentCount();
1323 bool success;
1324
1325 if (num_args == 0)
1326 {
1327 target->SetAllStopHooksActiveState (m_enable);
1328 }
1329 else
1330 {
1331 for (size_t i = 0; i < num_args; i++)
1332 {
1333 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
1334 if (!success)
1335 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001336 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001337 result.SetStatus(eReturnStatusFailed);
1338 return false;
1339 }
1340 success = target->SetStopHookActiveStateByID (user_id, m_enable);
1341 if (!success)
1342 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001343 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001344 result.SetStatus(eReturnStatusFailed);
1345 return false;
1346 }
1347 }
1348 }
1349 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1350 }
1351 else
1352 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001353 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001354 result.SetStatus (eReturnStatusFailed);
1355 }
1356 return result.Succeeded();
1357 }
1358private:
1359 bool m_enable;
1360};
1361
1362#pragma mark CommandObjectTargetStopHookList
1363
1364//-------------------------------------------------------------------------
1365// CommandObjectTargetStopHookList
1366//-------------------------------------------------------------------------
1367
1368class CommandObjectTargetStopHookList : public CommandObject
1369{
1370public:
1371
1372 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
1373 CommandObject (interpreter,
1374 "target stop-hook list [<type>]",
1375 "List all stop-hooks.",
1376 "target stop-hook list")
1377 {
1378 }
1379
1380 ~CommandObjectTargetStopHookList ()
1381 {
1382 }
1383
1384 bool
1385 Execute (Args& command,
1386 CommandReturnObject &result)
1387 {
1388 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1389 if (target)
1390 {
1391 bool notify = true;
1392 target->GetImageSearchPathList().Clear(notify);
1393 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1394 }
1395 else
1396 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001397 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001398 result.SetStatus (eReturnStatusFailed);
1399 }
1400
1401 size_t num_hooks = target->GetNumStopHooks ();
1402 if (num_hooks == 0)
1403 {
1404 result.GetOutputStream().PutCString ("No stop hooks.\n");
1405 }
1406 else
1407 {
1408 for (size_t i = 0; i < num_hooks; i++)
1409 {
1410 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
1411 if (i > 0)
1412 result.GetOutputStream().PutCString ("\n");
1413 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
1414 }
1415 }
1416 return result.Succeeded();
1417 }
1418};
1419
1420#pragma mark CommandObjectMultiwordTargetStopHooks
1421//-------------------------------------------------------------------------
1422// CommandObjectMultiwordTargetStopHooks
1423//-------------------------------------------------------------------------
1424
1425class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
1426{
1427public:
1428
1429 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
1430 CommandObjectMultiword (interpreter,
1431 "target stop-hook",
1432 "A set of commands for operating on debugger target stop-hooks.",
1433 "target stop-hook <subcommand> [<subcommand-options>]")
1434 {
1435 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
1436 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
1437 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
1438 false,
1439 "target stop-hook disable [<id>]",
1440 "Disable a stop-hook.",
1441 "target stop-hook disable")));
1442 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
1443 true,
1444 "target stop-hook enable [<id>]",
1445 "Enable a stop-hook.",
1446 "target stop-hook enable")));
1447 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
1448 }
1449
1450 ~CommandObjectMultiwordTargetStopHooks()
1451 {
1452 }
1453};
1454
1455
Chris Lattner24943d22010-06-08 16:52:24 +00001456
1457#pragma mark CommandObjectMultiwordTarget
1458
1459//-------------------------------------------------------------------------
1460// CommandObjectMultiwordTarget
1461//-------------------------------------------------------------------------
1462
Greg Clayton63094e02010-06-23 01:19:29 +00001463CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001464 CommandObjectMultiword (interpreter,
1465 "target",
Chris Lattner24943d22010-06-08 16:52:24 +00001466 "A set of commands for operating on debugger targets.",
1467 "target <subcommand> [<subcommand-options>]")
1468{
Greg Claytonabe0fed2011-04-18 08:33:37 +00001469
1470 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
1471 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter)));
1472 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001473 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
Greg Claytonabe0fed2011-04-18 08:33:37 +00001474 LoadSubCommand ("image-search-paths", CommandObjectSP (new CommandObjectMultiwordImageSearchPaths (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001475}
1476
1477CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
1478{
1479}
1480
Greg Claytonabe0fed2011-04-18 08:33:37 +00001481