blob: 958aa2cf047b97fcc629abe9737b0e4022302d41 [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
1035 case eInputReaderGotToken:
1036 if (bytes && bytes_len && baton)
1037 {
1038 StringList *commands = new_stop_hook->GetCommandPointer();
1039 if (commands)
1040 {
1041 commands->AppendString (bytes, bytes_len);
1042 }
1043 }
1044 if (!reader.IsDone() && reader.GetPrompt())
1045 {
1046 out_file.Printf ("%s", reader.GetPrompt());
1047 out_file.Flush();
1048 }
1049 break;
1050
1051 case eInputReaderInterrupt:
1052 {
1053 // Finish, and cancel the stop hook.
1054 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
1055 out_file.Printf ("Stop hook cancelled.\n");
1056
1057 reader.SetIsDone (true);
1058 }
1059 break;
1060
1061 case eInputReaderEndOfFile:
1062 reader.SetIsDone (true);
1063 break;
1064
1065 case eInputReaderDone:
1066 out_file.Printf ("Stop hook #%d added.\n", new_stop_hook->GetID());
1067 break;
1068 }
1069
1070 return bytes_len;
1071 }
1072
1073 bool
1074 Execute (Args& command,
1075 CommandReturnObject &result)
1076 {
1077 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1078 if (target)
1079 {
1080 Target::StopHookSP new_hook_sp;
1081 target->AddStopHook (new_hook_sp);
1082
1083 // First step, make the specifier.
1084 std::auto_ptr<SymbolContextSpecifier> specifier_ap;
1085 if (m_options.m_sym_ctx_specified)
1086 {
1087 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
1088
1089 if (!m_options.m_module_name.empty())
1090 {
1091 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
1092 }
1093
1094 if (!m_options.m_class_name.empty())
1095 {
1096 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
1097 }
1098
1099 if (!m_options.m_file_name.empty())
1100 {
1101 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
1102 }
1103
1104 if (m_options.m_line_start != 0)
1105 {
1106 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
1107 }
1108
1109 if (m_options.m_line_end != UINT_MAX)
1110 {
1111 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
1112 }
1113
1114 if (!m_options.m_function_name.empty())
1115 {
1116 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
1117 }
1118 }
1119
1120 if (specifier_ap.get())
1121 new_hook_sp->SetSpecifier (specifier_ap.release());
1122
1123 // Next see if any of the thread options have been entered:
1124
1125 if (m_options.m_thread_specified)
1126 {
1127 ThreadSpec *thread_spec = new ThreadSpec();
1128
1129 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
1130 {
1131 thread_spec->SetTID (m_options.m_thread_id);
1132 }
1133
1134 if (m_options.m_thread_index != UINT32_MAX)
1135 thread_spec->SetIndex (m_options.m_thread_index);
1136
1137 if (!m_options.m_thread_name.empty())
1138 thread_spec->SetName (m_options.m_thread_name.c_str());
1139
1140 if (!m_options.m_queue_name.empty())
1141 thread_spec->SetQueueName (m_options.m_queue_name.c_str());
1142
1143 new_hook_sp->SetThreadSpecifier (thread_spec);
1144
1145 }
1146 // Next gather up the command list, we'll push an input reader and suck the data from that directly into
1147 // the new stop hook's command string.
1148
1149 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
1150 if (!reader_sp)
1151 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001152 result.AppendError("out of memory\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001153 result.SetStatus (eReturnStatusFailed);
1154 target->RemoveStopHookByID (new_hook_sp->GetID());
1155 return false;
1156 }
1157
1158 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
1159 new_hook_sp.get(), // baton
1160 eInputReaderGranularityLine, // token size, to pass to callback function
1161 "DONE", // end token
1162 "> ", // prompt
1163 true)); // echo input
1164 if (!err.Success())
1165 {
1166 result.AppendError (err.AsCString());
1167 result.SetStatus (eReturnStatusFailed);
1168 target->RemoveStopHookByID (new_hook_sp->GetID());
1169 return false;
1170 }
1171 m_interpreter.GetDebugger().PushInputReader (reader_sp);
1172
1173 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1174 }
1175 else
1176 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001177 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001178 result.SetStatus (eReturnStatusFailed);
1179 }
1180
1181 return result.Succeeded();
1182 }
1183private:
1184 CommandOptions m_options;
1185};
1186
Greg Claytonb3448432011-03-24 21:19:54 +00001187OptionDefinition
Jim Inghamd60d94a2011-03-11 03:53:59 +00001188CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
1189{
1190 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
1191 "Set the module within which the stop-hook is to be run."},
1192 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex,
1193 "The stop hook is run only for the thread whose index matches this argument."},
1194 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID,
1195 "The stop hook is run only for the thread whose TID matches this argument."},
1196 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName,
1197 "The stop hook is run only for the thread whose thread name matches this argument."},
1198 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName,
1199 "The stop hook is run only for threads in the queue whose name is given by this argument."},
1200 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1201 "Specify the source file within which the stop-hook is to be run." },
1202 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
1203 "Set the start of the line range for which the stop-hook is to be run."},
1204 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum,
1205 "Set the end of the line range for which the stop-hook is to be run."},
1206 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName,
1207 "Specify the class within which the stop-hook is to be run." },
1208 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
1209 "Set the function name within which the stop hook will be run." },
1210 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1211};
1212
1213#pragma mark CommandObjectTargetStopHookDelete
1214
1215//-------------------------------------------------------------------------
1216// CommandObjectTargetStopHookDelete
1217//-------------------------------------------------------------------------
1218
1219class CommandObjectTargetStopHookDelete : public CommandObject
1220{
1221public:
1222
1223 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
1224 CommandObject (interpreter,
1225 "target stop-hook delete [<id>]",
1226 "Delete a stop-hook.",
1227 "target stop-hook delete")
1228 {
1229 }
1230
1231 ~CommandObjectTargetStopHookDelete ()
1232 {
1233 }
1234
1235 bool
1236 Execute (Args& command,
1237 CommandReturnObject &result)
1238 {
1239 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1240 if (target)
1241 {
1242 // FIXME: see if we can use the breakpoint id style parser?
1243 size_t num_args = command.GetArgumentCount();
1244 if (num_args == 0)
1245 {
1246 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
1247 {
1248 result.SetStatus (eReturnStatusFailed);
1249 return false;
1250 }
1251 else
1252 {
1253 target->RemoveAllStopHooks();
1254 }
1255 }
1256 else
1257 {
1258 bool success;
1259 for (size_t i = 0; i < num_args; i++)
1260 {
1261 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
1262 if (!success)
1263 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001264 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001265 result.SetStatus(eReturnStatusFailed);
1266 return false;
1267 }
1268 success = target->RemoveStopHookByID (user_id);
1269 if (!success)
1270 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001271 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001272 result.SetStatus(eReturnStatusFailed);
1273 return false;
1274 }
1275 }
1276 }
1277 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1278 }
1279 else
1280 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001281 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001282 result.SetStatus (eReturnStatusFailed);
1283 }
1284
1285 return result.Succeeded();
1286 }
1287};
1288#pragma mark CommandObjectTargetStopHookEnableDisable
1289
1290//-------------------------------------------------------------------------
1291// CommandObjectTargetStopHookEnableDisable
1292//-------------------------------------------------------------------------
1293
1294class CommandObjectTargetStopHookEnableDisable : public CommandObject
1295{
1296public:
1297
1298 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
1299 CommandObject (interpreter,
1300 name,
1301 help,
1302 syntax),
1303 m_enable (enable)
1304 {
1305 }
1306
1307 ~CommandObjectTargetStopHookEnableDisable ()
1308 {
1309 }
1310
1311 bool
1312 Execute (Args& command,
1313 CommandReturnObject &result)
1314 {
1315 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1316 if (target)
1317 {
1318 // FIXME: see if we can use the breakpoint id style parser?
1319 size_t num_args = command.GetArgumentCount();
1320 bool success;
1321
1322 if (num_args == 0)
1323 {
1324 target->SetAllStopHooksActiveState (m_enable);
1325 }
1326 else
1327 {
1328 for (size_t i = 0; i < num_args; i++)
1329 {
1330 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
1331 if (!success)
1332 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001333 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001334 result.SetStatus(eReturnStatusFailed);
1335 return false;
1336 }
1337 success = target->SetStopHookActiveStateByID (user_id, m_enable);
1338 if (!success)
1339 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001340 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001341 result.SetStatus(eReturnStatusFailed);
1342 return false;
1343 }
1344 }
1345 }
1346 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1347 }
1348 else
1349 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001350 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001351 result.SetStatus (eReturnStatusFailed);
1352 }
1353 return result.Succeeded();
1354 }
1355private:
1356 bool m_enable;
1357};
1358
1359#pragma mark CommandObjectTargetStopHookList
1360
1361//-------------------------------------------------------------------------
1362// CommandObjectTargetStopHookList
1363//-------------------------------------------------------------------------
1364
1365class CommandObjectTargetStopHookList : public CommandObject
1366{
1367public:
1368
1369 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
1370 CommandObject (interpreter,
1371 "target stop-hook list [<type>]",
1372 "List all stop-hooks.",
1373 "target stop-hook list")
1374 {
1375 }
1376
1377 ~CommandObjectTargetStopHookList ()
1378 {
1379 }
1380
1381 bool
1382 Execute (Args& command,
1383 CommandReturnObject &result)
1384 {
1385 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1386 if (target)
1387 {
1388 bool notify = true;
1389 target->GetImageSearchPathList().Clear(notify);
1390 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1391 }
1392 else
1393 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001394 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001395 result.SetStatus (eReturnStatusFailed);
1396 }
1397
1398 size_t num_hooks = target->GetNumStopHooks ();
1399 if (num_hooks == 0)
1400 {
1401 result.GetOutputStream().PutCString ("No stop hooks.\n");
1402 }
1403 else
1404 {
1405 for (size_t i = 0; i < num_hooks; i++)
1406 {
1407 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
1408 if (i > 0)
1409 result.GetOutputStream().PutCString ("\n");
1410 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
1411 }
1412 }
1413 return result.Succeeded();
1414 }
1415};
1416
1417#pragma mark CommandObjectMultiwordTargetStopHooks
1418//-------------------------------------------------------------------------
1419// CommandObjectMultiwordTargetStopHooks
1420//-------------------------------------------------------------------------
1421
1422class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
1423{
1424public:
1425
1426 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
1427 CommandObjectMultiword (interpreter,
1428 "target stop-hook",
1429 "A set of commands for operating on debugger target stop-hooks.",
1430 "target stop-hook <subcommand> [<subcommand-options>]")
1431 {
1432 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
1433 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
1434 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
1435 false,
1436 "target stop-hook disable [<id>]",
1437 "Disable a stop-hook.",
1438 "target stop-hook disable")));
1439 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
1440 true,
1441 "target stop-hook enable [<id>]",
1442 "Enable a stop-hook.",
1443 "target stop-hook enable")));
1444 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
1445 }
1446
1447 ~CommandObjectMultiwordTargetStopHooks()
1448 {
1449 }
1450};
1451
1452
Chris Lattner24943d22010-06-08 16:52:24 +00001453
1454#pragma mark CommandObjectMultiwordTarget
1455
1456//-------------------------------------------------------------------------
1457// CommandObjectMultiwordTarget
1458//-------------------------------------------------------------------------
1459
Greg Clayton63094e02010-06-23 01:19:29 +00001460CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001461 CommandObjectMultiword (interpreter,
1462 "target",
Chris Lattner24943d22010-06-08 16:52:24 +00001463 "A set of commands for operating on debugger targets.",
1464 "target <subcommand> [<subcommand-options>]")
1465{
Greg Claytonabe0fed2011-04-18 08:33:37 +00001466
1467 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
1468 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter)));
1469 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001470 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
Greg Claytonabe0fed2011-04-18 08:33:37 +00001471 LoadSubCommand ("image-search-paths", CommandObjectSP (new CommandObjectMultiwordImageSearchPaths (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001472}
1473
1474CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
1475{
1476}
1477
Greg Claytonabe0fed2011-04-18 08:33:37 +00001478