blob: 6332976a8753b0e7ac2b90fd5670ad77cdfc46cf [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{
40 ArchSpec &target_arch = target->GetArchitecture();
41
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 }
303 }
304 else
305 {
306 result.AppendError ("the 'target list' command takes no arguments\n");
307 result.SetStatus (eReturnStatusFailed);
308 }
309 return result.Succeeded();
310 }
311};
312
313
314#pragma mark CommandObjectTargetSelect
315
316//----------------------------------------------------------------------
317// "target select"
318//----------------------------------------------------------------------
319
320class CommandObjectTargetSelect : public CommandObject
321{
322public:
323 CommandObjectTargetSelect (CommandInterpreter &interpreter) :
324 CommandObject (interpreter,
325 "target select",
326 "Select a target as the current target by target index.",
327 NULL,
328 0)
329 {
330 }
331
332 virtual
333 ~CommandObjectTargetSelect ()
334 {
335 }
336
337 virtual bool
338 Execute (Args& args, CommandReturnObject &result)
339 {
340 if (args.GetArgumentCount() == 1)
341 {
342 bool success = false;
343 const char *target_idx_arg = args.GetArgumentAtIndex(0);
344 uint32_t target_idx = Args::StringToUInt32 (target_idx_arg, UINT32_MAX, 0, &success);
345 if (success)
346 {
347 TargetList &target_list = m_interpreter.GetDebugger().GetTargetList();
348 const uint32_t num_targets = target_list.GetNumTargets();
349 if (target_idx < num_targets)
350 {
351 TargetSP target_sp (target_list.GetTargetAtIndex (target_idx));
352 if (target_sp)
353 {
354 Stream &strm = result.GetOutputStream();
355 target_list.SetSelectedTarget (target_sp.get());
356 bool show_stopped_process_status = false;
357 DumpTargetList (target_list, show_stopped_process_status, strm);
358 }
359 else
360 {
361 result.AppendErrorWithFormat ("target #%u is NULL in target list\n", target_idx);
362 result.SetStatus (eReturnStatusFailed);
363 }
364 }
365 else
366 {
367 result.AppendErrorWithFormat ("index %u is out of range, valid target indexes are 0 - %u\n",
368 target_idx,
369 num_targets - 1);
370 result.SetStatus (eReturnStatusFailed);
371 }
372 }
373 else
374 {
375 result.AppendErrorWithFormat("invalid index string value '%s'\n", target_idx_arg);
376 result.SetStatus (eReturnStatusFailed);
377 }
378 }
379 else
380 {
381 result.AppendError ("'target select' takes a single argument: a target index\n");
382 result.SetStatus (eReturnStatusFailed);
383 }
384 return result.Succeeded();
385 }
386};
387
388
Chris Lattner24943d22010-06-08 16:52:24 +0000389#pragma mark CommandObjectTargetImageSearchPaths
390
391class CommandObjectTargetImageSearchPathsAdd : public CommandObject
392{
393public:
394
Greg Clayton238c0a12010-09-18 01:14:36 +0000395 CommandObjectTargetImageSearchPathsAdd (CommandInterpreter &interpreter) :
396 CommandObject (interpreter,
397 "target image-search-paths add",
Chris Lattner24943d22010-06-08 16:52:24 +0000398 "Add new image search paths substitution pairs to the current target.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000399 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000400 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000401 CommandArgumentEntry arg;
402 CommandArgumentData old_prefix_arg;
403 CommandArgumentData new_prefix_arg;
404
405 // Define the first variant of this arg pair.
406 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
407 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
408
409 // Define the first variant of this arg pair.
410 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
411 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
412
413 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
414 // must always occur together, they are treated as two variants of one argument rather than two independent
415 // arguments. Push them both into the first argument position for m_arguments...
416
417 arg.push_back (old_prefix_arg);
418 arg.push_back (new_prefix_arg);
419
420 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000421 }
422
423 ~CommandObjectTargetImageSearchPathsAdd ()
424 {
425 }
426
427 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000428 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000429 CommandReturnObject &result)
430 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000431 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000432 if (target)
433 {
434 uint32_t argc = command.GetArgumentCount();
435 if (argc & 1)
436 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000437 result.AppendError ("add requires an even number of arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000438 result.SetStatus (eReturnStatusFailed);
439 }
440 else
441 {
442 for (uint32_t i=0; i<argc; i+=2)
443 {
444 const char *from = command.GetArgumentAtIndex(i);
445 const char *to = command.GetArgumentAtIndex(i+1);
446
447 if (from[0] && to[0])
448 {
449 bool last_pair = ((argc - i) == 2);
Greg Clayton63094e02010-06-23 01:19:29 +0000450 target->GetImageSearchPathList().Append (ConstString(from),
451 ConstString(to),
452 last_pair); // Notify if this is the last pair
Johnny Chen4d661352011-02-03 00:30:19 +0000453 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000454 }
455 else
456 {
457 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +0000458 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000459 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000460 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000461 result.SetStatus (eReturnStatusFailed);
462 }
463 }
464 }
465 }
466 else
467 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000468 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000469 result.SetStatus (eReturnStatusFailed);
470 }
471 return result.Succeeded();
472 }
473};
474
475class CommandObjectTargetImageSearchPathsClear : public CommandObject
476{
477public:
478
Greg Clayton238c0a12010-09-18 01:14:36 +0000479 CommandObjectTargetImageSearchPathsClear (CommandInterpreter &interpreter) :
480 CommandObject (interpreter,
481 "target image-search-paths clear",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000482 "Clear all current image search path substitution pairs from the current target.",
Chris Lattner24943d22010-06-08 16:52:24 +0000483 "target image-search-paths clear")
484 {
485 }
486
487 ~CommandObjectTargetImageSearchPathsClear ()
488 {
489 }
490
491 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000492 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000493 CommandReturnObject &result)
494 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000495 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000496 if (target)
497 {
498 bool notify = true;
499 target->GetImageSearchPathList().Clear(notify);
Johnny Chen4d661352011-02-03 00:30:19 +0000500 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000501 }
502 else
503 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000504 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000505 result.SetStatus (eReturnStatusFailed);
506 }
507 return result.Succeeded();
508 }
509};
510
511class CommandObjectTargetImageSearchPathsInsert : public CommandObject
512{
513public:
514
Greg Clayton238c0a12010-09-18 01:14:36 +0000515 CommandObjectTargetImageSearchPathsInsert (CommandInterpreter &interpreter) :
516 CommandObject (interpreter,
517 "target image-search-paths insert",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000518 "Insert a new image search path substitution pair into the current target at the specified index.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000519 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000520 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000521 CommandArgumentEntry arg1;
522 CommandArgumentEntry arg2;
523 CommandArgumentData index_arg;
524 CommandArgumentData old_prefix_arg;
525 CommandArgumentData new_prefix_arg;
526
527 // Define the first and only variant of this arg.
528 index_arg.arg_type = eArgTypeIndex;
529 index_arg.arg_repetition = eArgRepeatPlain;
530
531 // Put the one and only variant into the first arg for m_arguments:
532 arg1.push_back (index_arg);
533
534 // Define the first variant of this arg pair.
535 old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
536 old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
537
538 // Define the first variant of this arg pair.
539 new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
540 new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
541
542 // There are two required arguments that must always occur together, i.e. an argument "pair". Because they
543 // must always occur together, they are treated as two variants of one argument rather than two independent
544 // arguments. Push them both into the same argument position for m_arguments...
545
546 arg2.push_back (old_prefix_arg);
547 arg2.push_back (new_prefix_arg);
548
549 // Add arguments to m_arguments.
550 m_arguments.push_back (arg1);
551 m_arguments.push_back (arg2);
Chris Lattner24943d22010-06-08 16:52:24 +0000552 }
553
554 ~CommandObjectTargetImageSearchPathsInsert ()
555 {
556 }
557
558 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000559 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000560 CommandReturnObject &result)
561 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000562 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000563 if (target)
564 {
565 uint32_t argc = command.GetArgumentCount();
566 // check for at least 3 arguments and an odd nubmer of parameters
567 if (argc >= 3 && argc & 1)
568 {
569 bool success = false;
570
571 uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
572
573 if (!success)
574 {
575 result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
576 result.SetStatus (eReturnStatusFailed);
577 return result.Succeeded();
578 }
579
580 // shift off the index
581 command.Shift();
582 argc = command.GetArgumentCount();
583
584 for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
585 {
586 const char *from = command.GetArgumentAtIndex(i);
587 const char *to = command.GetArgumentAtIndex(i+1);
588
589 if (from[0] && to[0])
590 {
591 bool last_pair = ((argc - i) == 2);
592 target->GetImageSearchPathList().Insert (ConstString(from),
593 ConstString(to),
594 insert_idx,
595 last_pair);
Johnny Chen4d661352011-02-03 00:30:19 +0000596 result.SetStatus (eReturnStatusSuccessFinishNoResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000597 }
598 else
599 {
600 if (from[0])
Greg Claytonabe0fed2011-04-18 08:33:37 +0000601 result.AppendError ("<path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000602 else
Greg Claytonabe0fed2011-04-18 08:33:37 +0000603 result.AppendError ("<new-path-prefix> can't be empty\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000604 result.SetStatus (eReturnStatusFailed);
605 return false;
606 }
607 }
608 }
609 else
610 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000611 result.AppendError ("insert requires at least three arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000612 result.SetStatus (eReturnStatusFailed);
613 return result.Succeeded();
614 }
615
616 }
617 else
618 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000619 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000620 result.SetStatus (eReturnStatusFailed);
621 }
622 return result.Succeeded();
623 }
624};
625
626class CommandObjectTargetImageSearchPathsList : public CommandObject
627{
628public:
629
Greg Clayton238c0a12010-09-18 01:14:36 +0000630 CommandObjectTargetImageSearchPathsList (CommandInterpreter &interpreter) :
631 CommandObject (interpreter,
632 "target image-search-paths list",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000633 "List all current image search path substitution pairs in the current target.",
Chris Lattner24943d22010-06-08 16:52:24 +0000634 "target image-search-paths list")
635 {
636 }
637
638 ~CommandObjectTargetImageSearchPathsList ()
639 {
640 }
641
642 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000643 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000644 CommandReturnObject &result)
645 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000646 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000647 if (target)
648 {
649 if (command.GetArgumentCount() != 0)
650 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000651 result.AppendError ("list takes no arguments\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000652 result.SetStatus (eReturnStatusFailed);
653 return result.Succeeded();
654 }
655
656 target->GetImageSearchPathList().Dump(&result.GetOutputStream());
Johnny Chen4d661352011-02-03 00:30:19 +0000657 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000658 }
659 else
660 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000661 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000662 result.SetStatus (eReturnStatusFailed);
663 }
664 return result.Succeeded();
665 }
666};
667
668class CommandObjectTargetImageSearchPathsQuery : public CommandObject
669{
670public:
671
Greg Clayton238c0a12010-09-18 01:14:36 +0000672 CommandObjectTargetImageSearchPathsQuery (CommandInterpreter &interpreter) :
673 CommandObject (interpreter,
674 "target image-search-paths query",
Caroline Ticeabb507a2010-09-08 21:06:11 +0000675 "Transform a path using the first applicable image search path.",
Caroline Tice43b014a2010-10-04 22:28:36 +0000676 NULL)
Chris Lattner24943d22010-06-08 16:52:24 +0000677 {
Caroline Tice43b014a2010-10-04 22:28:36 +0000678 CommandArgumentEntry arg;
679 CommandArgumentData path_arg;
680
681 // Define the first (and only) variant of this arg.
682 path_arg.arg_type = eArgTypePath;
683 path_arg.arg_repetition = eArgRepeatPlain;
684
685 // There is only one variant this argument could be; put it into the argument entry.
686 arg.push_back (path_arg);
687
688 // Push the data for the first argument into the m_arguments vector.
689 m_arguments.push_back (arg);
Chris Lattner24943d22010-06-08 16:52:24 +0000690 }
691
692 ~CommandObjectTargetImageSearchPathsQuery ()
693 {
694 }
695
696 bool
Greg Clayton238c0a12010-09-18 01:14:36 +0000697 Execute (Args& command,
Chris Lattner24943d22010-06-08 16:52:24 +0000698 CommandReturnObject &result)
699 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000700 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000701 if (target)
702 {
703 if (command.GetArgumentCount() != 1)
704 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000705 result.AppendError ("query requires one argument\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000706 result.SetStatus (eReturnStatusFailed);
707 return result.Succeeded();
708 }
709
710 ConstString orig(command.GetArgumentAtIndex(0));
711 ConstString transformed;
712 if (target->GetImageSearchPathList().RemapPath(orig, transformed))
713 result.GetOutputStream().Printf("%s\n", transformed.GetCString());
714 else
715 result.GetOutputStream().Printf("%s\n", orig.GetCString());
Johnny Chen4d661352011-02-03 00:30:19 +0000716
717 result.SetStatus (eReturnStatusSuccessFinishResult);
Chris Lattner24943d22010-06-08 16:52:24 +0000718 }
719 else
720 {
Greg Claytonabe0fed2011-04-18 08:33:37 +0000721 result.AppendError ("invalid target\n");
Chris Lattner24943d22010-06-08 16:52:24 +0000722 result.SetStatus (eReturnStatusFailed);
723 }
724 return result.Succeeded();
725 }
726};
727
728// TODO: implement the target select later when we start doing multiple targets
729//#pragma mark CommandObjectTargetSelect
730//
731////-------------------------------------------------------------------------
732//// CommandObjectTargetSelect
733////-------------------------------------------------------------------------
734//
735//class CommandObjectTargetSelect : public CommandObject
736//{
737//public:
738//
739// CommandObjectTargetSelect () :
Greg Clayton238c0a12010-09-18 01:14:36 +0000740// CommandObject (interpreter,
741// frame select",
Chris Lattner24943d22010-06-08 16:52:24 +0000742// "Select the current frame by index in the current thread.",
743// "frame select <frame-index>")
744// {
745// }
746//
747// ~CommandObjectTargetSelect ()
748// {
749// }
750//
751// bool
752// Execute (Args& command,
Greg Clayton63094e02010-06-23 01:19:29 +0000753// Debugger *context,
Greg Clayton238c0a12010-09-18 01:14:36 +0000754// CommandInterpreter &m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000755// CommandReturnObject &result)
756// {
757// ExecutionContext exe_ctx (context->GetExecutionContext());
758// if (exe_ctx.thread)
759// {
760// if (command.GetArgumentCount() == 1)
761// {
762// const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
763//
764// const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount();
765// const uint32_t frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0);
766// if (frame_idx < num_frames)
767// {
Jim Inghamc8332952010-08-26 21:32:51 +0000768// exe_ctx.thread->SetSelectedFrameByIndex (frame_idx);
769// exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get();
Chris Lattner24943d22010-06-08 16:52:24 +0000770//
771// if (exe_ctx.frame)
772// {
773// if (DisplayFrameForExecutionContext (exe_ctx.thread,
774// exe_ctx.frame,
Greg Clayton238c0a12010-09-18 01:14:36 +0000775// m_interpreter,
Chris Lattner24943d22010-06-08 16:52:24 +0000776// result.GetOutputStream(),
777// true,
778// true,
779// 3,
780// 3))
781// {
782// result.SetStatus (eReturnStatusSuccessFinishResult);
783// return result.Succeeded();
784// }
785// }
786// }
787// if (frame_idx == UINT32_MAX)
788// result.AppendErrorWithFormat ("Invalid frame index: %s.\n", frame_idx_cstr);
789// else
790// result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx);
791// }
792// else
793// {
794// result.AppendError ("invalid arguments");
795// result.AppendErrorWithFormat ("Usage: %s\n", m_cmd_syntax.c_str());
796// }
797// }
798// else
799// {
800// result.AppendError ("no current thread");
801// }
802// result.SetStatus (eReturnStatusFailed);
803// return false;
804// }
805//};
806
807
Jim Inghamd60d94a2011-03-11 03:53:59 +0000808#pragma mark CommandObjectMultiwordImageSearchPaths
Chris Lattner24943d22010-06-08 16:52:24 +0000809
810//-------------------------------------------------------------------------
811// CommandObjectMultiwordImageSearchPaths
812//-------------------------------------------------------------------------
813
814class CommandObjectMultiwordImageSearchPaths : public CommandObjectMultiword
815{
816public:
817
Greg Clayton63094e02010-06-23 01:19:29 +0000818 CommandObjectMultiwordImageSearchPaths (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +0000819 CommandObjectMultiword (interpreter,
820 "target image-search-paths",
Chris Lattner24943d22010-06-08 16:52:24 +0000821 "A set of commands for operating on debugger target image search paths.",
822 "target image-search-paths <subcommand> [<subcommand-options>]")
823 {
Greg Clayton238c0a12010-09-18 01:14:36 +0000824 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetImageSearchPathsAdd (interpreter)));
825 LoadSubCommand ("clear", CommandObjectSP (new CommandObjectTargetImageSearchPathsClear (interpreter)));
826 LoadSubCommand ("insert", CommandObjectSP (new CommandObjectTargetImageSearchPathsInsert (interpreter)));
827 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetImageSearchPathsList (interpreter)));
828 LoadSubCommand ("query", CommandObjectSP (new CommandObjectTargetImageSearchPathsQuery (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +0000829 }
830
831 ~CommandObjectMultiwordImageSearchPaths()
832 {
833 }
834};
835
Jim Inghamd60d94a2011-03-11 03:53:59 +0000836#pragma mark CommandObjectTargetStopHookAdd
837
838//-------------------------------------------------------------------------
839// CommandObjectTargetStopHookAdd
840//-------------------------------------------------------------------------
841
842class CommandObjectTargetStopHookAdd : public CommandObject
843{
844public:
845
846 class CommandOptions : public Options
847 {
848 public:
Greg Claytonf15996e2011-04-07 22:46:35 +0000849 CommandOptions (CommandInterpreter &interpreter) :
850 Options(interpreter),
Jim Inghamd60d94a2011-03-11 03:53:59 +0000851 m_line_start(0),
852 m_line_end (UINT_MAX),
853 m_func_name_type_mask (eFunctionNameTypeAuto),
854 m_sym_ctx_specified (false),
855 m_thread_specified (false)
856 {
857 }
858
859 ~CommandOptions () {}
860
Greg Claytonb3448432011-03-24 21:19:54 +0000861 const OptionDefinition*
Jim Inghamd60d94a2011-03-11 03:53:59 +0000862 GetDefinitions ()
863 {
864 return g_option_table;
865 }
866
867 virtual Error
Greg Clayton143fcc32011-04-13 00:18:08 +0000868 SetOptionValue (uint32_t option_idx, const char *option_arg)
Jim Inghamd60d94a2011-03-11 03:53:59 +0000869 {
870 Error error;
871 char short_option = (char) m_getopt_table[option_idx].val;
872 bool success;
873
874 switch (short_option)
875 {
876 case 'c':
877 m_class_name = option_arg;
878 m_sym_ctx_specified = true;
879 break;
880
881 case 'e':
882 m_line_end = Args::StringToUInt32 (option_arg, UINT_MAX, 0, &success);
883 if (!success)
884 {
885 error.SetErrorStringWithFormat ("Invalid end line number: \"%s\".", option_arg);
886 break;
887 }
888 m_sym_ctx_specified = true;
889 break;
890
891 case 'l':
892 m_line_start = Args::StringToUInt32 (option_arg, 0, 0, &success);
893 if (!success)
894 {
895 error.SetErrorStringWithFormat ("Invalid start line number: \"%s\".", option_arg);
896 break;
897 }
898 m_sym_ctx_specified = true;
899 break;
900
901 case 'n':
902 m_function_name = option_arg;
903 m_func_name_type_mask |= eFunctionNameTypeAuto;
904 m_sym_ctx_specified = true;
905 break;
906
907 case 'f':
908 m_file_name = option_arg;
909 m_sym_ctx_specified = true;
910 break;
911 case 's':
912 m_module_name = option_arg;
913 m_sym_ctx_specified = true;
914 break;
915 case 't' :
916 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000917 m_thread_id = Args::StringToUInt64(option_arg, LLDB_INVALID_THREAD_ID, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000918 if (m_thread_id == LLDB_INVALID_THREAD_ID)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000919 error.SetErrorStringWithFormat ("Invalid thread id string '%s'.\n", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000920 m_thread_specified = true;
921 }
922 break;
923 case 'T':
924 m_thread_name = option_arg;
925 m_thread_specified = true;
926 break;
927 case 'q':
928 m_queue_name = option_arg;
929 m_thread_specified = true;
930 break;
931 case 'x':
932 {
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000933 m_thread_index = Args::StringToUInt32(option_arg, UINT32_MAX, 0);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000934 if (m_thread_id == UINT32_MAX)
Jim Ingham7a4c8ea2011-03-22 01:53:33 +0000935 error.SetErrorStringWithFormat ("Invalid thread index string '%s'.\n", option_arg);
Jim Inghamd60d94a2011-03-11 03:53:59 +0000936 m_thread_specified = true;
937 }
938 break;
939 default:
940 error.SetErrorStringWithFormat ("Unrecognized option %c.");
941 break;
942 }
943 return error;
944 }
945
946 void
Greg Clayton143fcc32011-04-13 00:18:08 +0000947 OptionParsingStarting ()
Jim Inghamd60d94a2011-03-11 03:53:59 +0000948 {
949 m_class_name.clear();
950 m_function_name.clear();
951 m_line_start = 0;
952 m_line_end = UINT_MAX;
953 m_file_name.clear();
954 m_module_name.clear();
955 m_func_name_type_mask = eFunctionNameTypeAuto;
956 m_thread_id = LLDB_INVALID_THREAD_ID;
957 m_thread_index = UINT32_MAX;
958 m_thread_name.clear();
959 m_queue_name.clear();
960
961 m_sym_ctx_specified = false;
962 m_thread_specified = false;
963 }
964
965
Greg Claytonb3448432011-03-24 21:19:54 +0000966 static OptionDefinition g_option_table[];
Jim Inghamd60d94a2011-03-11 03:53:59 +0000967
968 std::string m_class_name;
969 std::string m_function_name;
970 uint32_t m_line_start;
971 uint32_t m_line_end;
972 std::string m_file_name;
973 std::string m_module_name;
974 uint32_t m_func_name_type_mask; // A pick from lldb::FunctionNameType.
975 lldb::tid_t m_thread_id;
976 uint32_t m_thread_index;
977 std::string m_thread_name;
978 std::string m_queue_name;
979 bool m_sym_ctx_specified;
980 bool m_thread_specified;
981
982 };
983
984 Options *
985 GetOptions ()
986 {
987 return &m_options;
988 }
989
990 CommandObjectTargetStopHookAdd (CommandInterpreter &interpreter) :
991 CommandObject (interpreter,
992 "target stop-hook add ",
993 "Add a hook to be executed when the target stops.",
Greg Claytonf15996e2011-04-07 22:46:35 +0000994 "target stop-hook add"),
995 m_options (interpreter)
Jim Inghamd60d94a2011-03-11 03:53:59 +0000996 {
997 }
998
999 ~CommandObjectTargetStopHookAdd ()
1000 {
1001 }
1002
1003 static size_t
1004 ReadCommandsCallbackFunction (void *baton,
1005 InputReader &reader,
1006 lldb::InputReaderAction notification,
1007 const char *bytes,
1008 size_t bytes_len)
1009 {
1010 File &out_file = reader.GetDebugger().GetOutputFile();
1011 Target::StopHook *new_stop_hook = ((Target::StopHook *) baton);
1012
1013 switch (notification)
1014 {
1015 case eInputReaderActivate:
1016 out_file.Printf ("%s\n", "Enter your stop hook command(s). Type 'DONE' to end.");
1017 if (reader.GetPrompt())
1018 out_file.Printf ("%s", reader.GetPrompt());
1019 out_file.Flush();
1020 break;
1021
1022 case eInputReaderDeactivate:
1023 break;
1024
1025 case eInputReaderReactivate:
1026 if (reader.GetPrompt())
1027 {
1028 out_file.Printf ("%s", reader.GetPrompt());
1029 out_file.Flush();
1030 }
1031 break;
1032
1033 case eInputReaderGotToken:
1034 if (bytes && bytes_len && baton)
1035 {
1036 StringList *commands = new_stop_hook->GetCommandPointer();
1037 if (commands)
1038 {
1039 commands->AppendString (bytes, bytes_len);
1040 }
1041 }
1042 if (!reader.IsDone() && reader.GetPrompt())
1043 {
1044 out_file.Printf ("%s", reader.GetPrompt());
1045 out_file.Flush();
1046 }
1047 break;
1048
1049 case eInputReaderInterrupt:
1050 {
1051 // Finish, and cancel the stop hook.
1052 new_stop_hook->GetTarget()->RemoveStopHookByID(new_stop_hook->GetID());
1053 out_file.Printf ("Stop hook cancelled.\n");
1054
1055 reader.SetIsDone (true);
1056 }
1057 break;
1058
1059 case eInputReaderEndOfFile:
1060 reader.SetIsDone (true);
1061 break;
1062
1063 case eInputReaderDone:
1064 out_file.Printf ("Stop hook #%d added.\n", new_stop_hook->GetID());
1065 break;
1066 }
1067
1068 return bytes_len;
1069 }
1070
1071 bool
1072 Execute (Args& command,
1073 CommandReturnObject &result)
1074 {
1075 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1076 if (target)
1077 {
1078 Target::StopHookSP new_hook_sp;
1079 target->AddStopHook (new_hook_sp);
1080
1081 // First step, make the specifier.
1082 std::auto_ptr<SymbolContextSpecifier> specifier_ap;
1083 if (m_options.m_sym_ctx_specified)
1084 {
1085 specifier_ap.reset(new SymbolContextSpecifier(m_interpreter.GetDebugger().GetSelectedTarget()));
1086
1087 if (!m_options.m_module_name.empty())
1088 {
1089 specifier_ap->AddSpecification (m_options.m_module_name.c_str(), SymbolContextSpecifier::eModuleSpecified);
1090 }
1091
1092 if (!m_options.m_class_name.empty())
1093 {
1094 specifier_ap->AddSpecification (m_options.m_class_name.c_str(), SymbolContextSpecifier::eClassOrNamespaceSpecified);
1095 }
1096
1097 if (!m_options.m_file_name.empty())
1098 {
1099 specifier_ap->AddSpecification (m_options.m_file_name.c_str(), SymbolContextSpecifier::eFileSpecified);
1100 }
1101
1102 if (m_options.m_line_start != 0)
1103 {
1104 specifier_ap->AddLineSpecification (m_options.m_line_start, SymbolContextSpecifier::eLineStartSpecified);
1105 }
1106
1107 if (m_options.m_line_end != UINT_MAX)
1108 {
1109 specifier_ap->AddLineSpecification (m_options.m_line_end, SymbolContextSpecifier::eLineEndSpecified);
1110 }
1111
1112 if (!m_options.m_function_name.empty())
1113 {
1114 specifier_ap->AddSpecification (m_options.m_function_name.c_str(), SymbolContextSpecifier::eFunctionSpecified);
1115 }
1116 }
1117
1118 if (specifier_ap.get())
1119 new_hook_sp->SetSpecifier (specifier_ap.release());
1120
1121 // Next see if any of the thread options have been entered:
1122
1123 if (m_options.m_thread_specified)
1124 {
1125 ThreadSpec *thread_spec = new ThreadSpec();
1126
1127 if (m_options.m_thread_id != LLDB_INVALID_THREAD_ID)
1128 {
1129 thread_spec->SetTID (m_options.m_thread_id);
1130 }
1131
1132 if (m_options.m_thread_index != UINT32_MAX)
1133 thread_spec->SetIndex (m_options.m_thread_index);
1134
1135 if (!m_options.m_thread_name.empty())
1136 thread_spec->SetName (m_options.m_thread_name.c_str());
1137
1138 if (!m_options.m_queue_name.empty())
1139 thread_spec->SetQueueName (m_options.m_queue_name.c_str());
1140
1141 new_hook_sp->SetThreadSpecifier (thread_spec);
1142
1143 }
1144 // Next gather up the command list, we'll push an input reader and suck the data from that directly into
1145 // the new stop hook's command string.
1146
1147 InputReaderSP reader_sp (new InputReader(m_interpreter.GetDebugger()));
1148 if (!reader_sp)
1149 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001150 result.AppendError("out of memory\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001151 result.SetStatus (eReturnStatusFailed);
1152 target->RemoveStopHookByID (new_hook_sp->GetID());
1153 return false;
1154 }
1155
1156 Error err (reader_sp->Initialize (CommandObjectTargetStopHookAdd::ReadCommandsCallbackFunction,
1157 new_hook_sp.get(), // baton
1158 eInputReaderGranularityLine, // token size, to pass to callback function
1159 "DONE", // end token
1160 "> ", // prompt
1161 true)); // echo input
1162 if (!err.Success())
1163 {
1164 result.AppendError (err.AsCString());
1165 result.SetStatus (eReturnStatusFailed);
1166 target->RemoveStopHookByID (new_hook_sp->GetID());
1167 return false;
1168 }
1169 m_interpreter.GetDebugger().PushInputReader (reader_sp);
1170
1171 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1172 }
1173 else
1174 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001175 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001176 result.SetStatus (eReturnStatusFailed);
1177 }
1178
1179 return result.Succeeded();
1180 }
1181private:
1182 CommandOptions m_options;
1183};
1184
Greg Claytonb3448432011-03-24 21:19:54 +00001185OptionDefinition
Jim Inghamd60d94a2011-03-11 03:53:59 +00001186CommandObjectTargetStopHookAdd::CommandOptions::g_option_table[] =
1187{
1188 { LLDB_OPT_SET_ALL, false, "shlib", 's', required_argument, NULL, CommandCompletions::eModuleCompletion, eArgTypeShlibName,
1189 "Set the module within which the stop-hook is to be run."},
1190 { LLDB_OPT_SET_ALL, false, "thread-index", 'x', required_argument, NULL, NULL, eArgTypeThreadIndex,
1191 "The stop hook is run only for the thread whose index matches this argument."},
1192 { LLDB_OPT_SET_ALL, false, "thread-id", 't', required_argument, NULL, NULL, eArgTypeThreadID,
1193 "The stop hook is run only for the thread whose TID matches this argument."},
1194 { LLDB_OPT_SET_ALL, false, "thread-name", 'T', required_argument, NULL, NULL, eArgTypeThreadName,
1195 "The stop hook is run only for the thread whose thread name matches this argument."},
1196 { LLDB_OPT_SET_ALL, false, "queue-name", 'q', required_argument, NULL, NULL, eArgTypeQueueName,
1197 "The stop hook is run only for threads in the queue whose name is given by this argument."},
1198 { LLDB_OPT_SET_1, false, "file", 'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, eArgTypeFilename,
1199 "Specify the source file within which the stop-hook is to be run." },
1200 { LLDB_OPT_SET_1, false, "start-line", 'l', required_argument, NULL, 0, eArgTypeLineNum,
1201 "Set the start of the line range for which the stop-hook is to be run."},
1202 { LLDB_OPT_SET_1, false, "end-line", 'e', required_argument, NULL, 0, eArgTypeLineNum,
1203 "Set the end of the line range for which the stop-hook is to be run."},
1204 { LLDB_OPT_SET_2, false, "classname", 'c', required_argument, NULL, NULL, eArgTypeClassName,
1205 "Specify the class within which the stop-hook is to be run." },
1206 { LLDB_OPT_SET_3, false, "name", 'n', required_argument, NULL, CommandCompletions::eSymbolCompletion, eArgTypeFunctionName,
1207 "Set the function name within which the stop hook will be run." },
1208 { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
1209};
1210
1211#pragma mark CommandObjectTargetStopHookDelete
1212
1213//-------------------------------------------------------------------------
1214// CommandObjectTargetStopHookDelete
1215//-------------------------------------------------------------------------
1216
1217class CommandObjectTargetStopHookDelete : public CommandObject
1218{
1219public:
1220
1221 CommandObjectTargetStopHookDelete (CommandInterpreter &interpreter) :
1222 CommandObject (interpreter,
1223 "target stop-hook delete [<id>]",
1224 "Delete a stop-hook.",
1225 "target stop-hook delete")
1226 {
1227 }
1228
1229 ~CommandObjectTargetStopHookDelete ()
1230 {
1231 }
1232
1233 bool
1234 Execute (Args& command,
1235 CommandReturnObject &result)
1236 {
1237 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1238 if (target)
1239 {
1240 // FIXME: see if we can use the breakpoint id style parser?
1241 size_t num_args = command.GetArgumentCount();
1242 if (num_args == 0)
1243 {
1244 if (!m_interpreter.Confirm ("Delete all stop hooks?", true))
1245 {
1246 result.SetStatus (eReturnStatusFailed);
1247 return false;
1248 }
1249 else
1250 {
1251 target->RemoveAllStopHooks();
1252 }
1253 }
1254 else
1255 {
1256 bool success;
1257 for (size_t i = 0; i < num_args; i++)
1258 {
1259 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
1260 if (!success)
1261 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001262 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001263 result.SetStatus(eReturnStatusFailed);
1264 return false;
1265 }
1266 success = target->RemoveStopHookByID (user_id);
1267 if (!success)
1268 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001269 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001270 result.SetStatus(eReturnStatusFailed);
1271 return false;
1272 }
1273 }
1274 }
1275 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1276 }
1277 else
1278 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001279 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001280 result.SetStatus (eReturnStatusFailed);
1281 }
1282
1283 return result.Succeeded();
1284 }
1285};
1286#pragma mark CommandObjectTargetStopHookEnableDisable
1287
1288//-------------------------------------------------------------------------
1289// CommandObjectTargetStopHookEnableDisable
1290//-------------------------------------------------------------------------
1291
1292class CommandObjectTargetStopHookEnableDisable : public CommandObject
1293{
1294public:
1295
1296 CommandObjectTargetStopHookEnableDisable (CommandInterpreter &interpreter, bool enable, const char *name, const char *help, const char *syntax) :
1297 CommandObject (interpreter,
1298 name,
1299 help,
1300 syntax),
1301 m_enable (enable)
1302 {
1303 }
1304
1305 ~CommandObjectTargetStopHookEnableDisable ()
1306 {
1307 }
1308
1309 bool
1310 Execute (Args& command,
1311 CommandReturnObject &result)
1312 {
1313 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1314 if (target)
1315 {
1316 // FIXME: see if we can use the breakpoint id style parser?
1317 size_t num_args = command.GetArgumentCount();
1318 bool success;
1319
1320 if (num_args == 0)
1321 {
1322 target->SetAllStopHooksActiveState (m_enable);
1323 }
1324 else
1325 {
1326 for (size_t i = 0; i < num_args; i++)
1327 {
1328 lldb::user_id_t user_id = Args::StringToUInt32 (command.GetArgumentAtIndex(i), 0, 0, &success);
1329 if (!success)
1330 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001331 result.AppendErrorWithFormat ("invalid stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001332 result.SetStatus(eReturnStatusFailed);
1333 return false;
1334 }
1335 success = target->SetStopHookActiveStateByID (user_id, m_enable);
1336 if (!success)
1337 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001338 result.AppendErrorWithFormat ("unknown stop hook id: \"%s\".\n", command.GetArgumentAtIndex(i));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001339 result.SetStatus(eReturnStatusFailed);
1340 return false;
1341 }
1342 }
1343 }
1344 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1345 }
1346 else
1347 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001348 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001349 result.SetStatus (eReturnStatusFailed);
1350 }
1351 return result.Succeeded();
1352 }
1353private:
1354 bool m_enable;
1355};
1356
1357#pragma mark CommandObjectTargetStopHookList
1358
1359//-------------------------------------------------------------------------
1360// CommandObjectTargetStopHookList
1361//-------------------------------------------------------------------------
1362
1363class CommandObjectTargetStopHookList : public CommandObject
1364{
1365public:
1366
1367 CommandObjectTargetStopHookList (CommandInterpreter &interpreter) :
1368 CommandObject (interpreter,
1369 "target stop-hook list [<type>]",
1370 "List all stop-hooks.",
1371 "target stop-hook list")
1372 {
1373 }
1374
1375 ~CommandObjectTargetStopHookList ()
1376 {
1377 }
1378
1379 bool
1380 Execute (Args& command,
1381 CommandReturnObject &result)
1382 {
1383 Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
1384 if (target)
1385 {
1386 bool notify = true;
1387 target->GetImageSearchPathList().Clear(notify);
1388 result.SetStatus (eReturnStatusSuccessFinishNoResult);
1389 }
1390 else
1391 {
Greg Claytonabe0fed2011-04-18 08:33:37 +00001392 result.AppendError ("invalid target\n");
Jim Inghamd60d94a2011-03-11 03:53:59 +00001393 result.SetStatus (eReturnStatusFailed);
1394 }
1395
1396 size_t num_hooks = target->GetNumStopHooks ();
1397 if (num_hooks == 0)
1398 {
1399 result.GetOutputStream().PutCString ("No stop hooks.\n");
1400 }
1401 else
1402 {
1403 for (size_t i = 0; i < num_hooks; i++)
1404 {
1405 Target::StopHookSP this_hook = target->GetStopHookAtIndex (i);
1406 if (i > 0)
1407 result.GetOutputStream().PutCString ("\n");
1408 this_hook->GetDescription (&(result.GetOutputStream()), eDescriptionLevelFull);
1409 }
1410 }
1411 return result.Succeeded();
1412 }
1413};
1414
1415#pragma mark CommandObjectMultiwordTargetStopHooks
1416//-------------------------------------------------------------------------
1417// CommandObjectMultiwordTargetStopHooks
1418//-------------------------------------------------------------------------
1419
1420class CommandObjectMultiwordTargetStopHooks : public CommandObjectMultiword
1421{
1422public:
1423
1424 CommandObjectMultiwordTargetStopHooks (CommandInterpreter &interpreter) :
1425 CommandObjectMultiword (interpreter,
1426 "target stop-hook",
1427 "A set of commands for operating on debugger target stop-hooks.",
1428 "target stop-hook <subcommand> [<subcommand-options>]")
1429 {
1430 LoadSubCommand ("add", CommandObjectSP (new CommandObjectTargetStopHookAdd (interpreter)));
1431 LoadSubCommand ("delete", CommandObjectSP (new CommandObjectTargetStopHookDelete (interpreter)));
1432 LoadSubCommand ("disable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
1433 false,
1434 "target stop-hook disable [<id>]",
1435 "Disable a stop-hook.",
1436 "target stop-hook disable")));
1437 LoadSubCommand ("enable", CommandObjectSP (new CommandObjectTargetStopHookEnableDisable (interpreter,
1438 true,
1439 "target stop-hook enable [<id>]",
1440 "Enable a stop-hook.",
1441 "target stop-hook enable")));
1442 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetStopHookList (interpreter)));
1443 }
1444
1445 ~CommandObjectMultiwordTargetStopHooks()
1446 {
1447 }
1448};
1449
1450
Chris Lattner24943d22010-06-08 16:52:24 +00001451
1452#pragma mark CommandObjectMultiwordTarget
1453
1454//-------------------------------------------------------------------------
1455// CommandObjectMultiwordTarget
1456//-------------------------------------------------------------------------
1457
Greg Clayton63094e02010-06-23 01:19:29 +00001458CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
Greg Clayton238c0a12010-09-18 01:14:36 +00001459 CommandObjectMultiword (interpreter,
1460 "target",
Chris Lattner24943d22010-06-08 16:52:24 +00001461 "A set of commands for operating on debugger targets.",
1462 "target <subcommand> [<subcommand-options>]")
1463{
Greg Claytonabe0fed2011-04-18 08:33:37 +00001464
1465 LoadSubCommand ("create", CommandObjectSP (new CommandObjectTargetCreate (interpreter)));
1466 LoadSubCommand ("list", CommandObjectSP (new CommandObjectTargetList (interpreter)));
1467 LoadSubCommand ("select", CommandObjectSP (new CommandObjectTargetSelect (interpreter)));
Jim Inghamd60d94a2011-03-11 03:53:59 +00001468 LoadSubCommand ("stop-hook", CommandObjectSP (new CommandObjectMultiwordTargetStopHooks (interpreter)));
Greg Claytonabe0fed2011-04-18 08:33:37 +00001469 LoadSubCommand ("image-search-paths", CommandObjectSP (new CommandObjectMultiwordImageSearchPaths (interpreter)));
Chris Lattner24943d22010-06-08 16:52:24 +00001470}
1471
1472CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
1473{
1474}
1475
Greg Claytonabe0fed2011-04-18 08:33:37 +00001476