CommandObjectTarget.cpp revision 43b014aa33e20e61790e16ed69a2c57aae2fbc6e
1//===-- 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>
14#include <sys/errno.h>
15// C++ Includes
16// Other libraries and framework includes
17// Project includes
18#include "lldb/Interpreter/Args.h"
19#include "lldb/Core/Debugger.h"
20#include "lldb/Core/Timer.h"
21#include "lldb/Core/Debugger.h"
22#include "lldb/Interpreter/CommandInterpreter.h"
23#include "lldb/Interpreter/CommandReturnObject.h"
24#include "lldb/Target/Process.h"
25#include "lldb/Target/StackFrame.h"
26#include "lldb/Target/Thread.h"
27
28using namespace lldb;
29using namespace lldb_private;
30
31#pragma mark CommandObjectTargetImageSearchPaths
32
33class CommandObjectTargetImageSearchPathsAdd : public CommandObject
34{
35public:
36
37    CommandObjectTargetImageSearchPathsAdd (CommandInterpreter &interpreter) :
38        CommandObject (interpreter,
39                       "target image-search-paths add",
40                       "Add new image search paths substitution pairs to the current target.",
41                       NULL)
42    {
43        CommandArgumentEntry arg;
44        CommandArgumentData old_prefix_arg;
45        CommandArgumentData new_prefix_arg;
46
47        // Define the first variant of this arg pair.
48        old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
49        old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
50
51        // Define the first variant of this arg pair.
52        new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
53        new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
54
55        // There are two required arguments that must always occur together, i.e. an argument "pair".  Because they
56        // must always occur together, they are treated as two variants of one argument rather than two independent
57        // arguments.  Push them both into the first argument position for m_arguments...
58
59        arg.push_back (old_prefix_arg);
60        arg.push_back (new_prefix_arg);
61
62        m_arguments.push_back (arg);
63    }
64
65    ~CommandObjectTargetImageSearchPathsAdd ()
66    {
67    }
68
69    bool
70    Execute (Args& command,
71             CommandReturnObject &result)
72    {
73        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
74        if (target)
75        {
76            uint32_t argc = command.GetArgumentCount();
77            if (argc & 1)
78            {
79                result.AppendError ("add requires an even number of arguments");
80                result.SetStatus (eReturnStatusFailed);
81            }
82            else
83            {
84                for (uint32_t i=0; i<argc; i+=2)
85                {
86                    const char *from = command.GetArgumentAtIndex(i);
87                    const char *to = command.GetArgumentAtIndex(i+1);
88
89                    if (from[0] && to[0])
90                    {
91                        bool last_pair = ((argc - i) == 2);
92                        target->GetImageSearchPathList().Append (ConstString(from),
93                                                                 ConstString(to),
94                                                                 last_pair); // Notify if this is the last pair
95                    }
96                    else
97                    {
98                        if (from[0])
99                            result.AppendError ("<path-prefix> can't be empty");
100                        else
101                            result.AppendError ("<new-path-prefix> can't be empty");
102                        result.SetStatus (eReturnStatusFailed);
103                    }
104                }
105            }
106        }
107        else
108        {
109            result.AppendError ("invalid target");
110            result.SetStatus (eReturnStatusFailed);
111        }
112        return result.Succeeded();
113    }
114};
115
116class CommandObjectTargetImageSearchPathsClear : public CommandObject
117{
118public:
119
120    CommandObjectTargetImageSearchPathsClear (CommandInterpreter &interpreter) :
121        CommandObject (interpreter,
122                       "target image-search-paths clear",
123                       "Clear all current image search path substitution pairs from the current target.",
124                       "target image-search-paths clear")
125    {
126    }
127
128    ~CommandObjectTargetImageSearchPathsClear ()
129    {
130    }
131
132    bool
133    Execute (Args& command,
134             CommandReturnObject &result)
135    {
136        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
137        if (target)
138        {
139            bool notify = true;
140            target->GetImageSearchPathList().Clear(notify);
141        }
142        else
143        {
144            result.AppendError ("invalid target");
145            result.SetStatus (eReturnStatusFailed);
146        }
147        return result.Succeeded();
148    }
149};
150
151class CommandObjectTargetImageSearchPathsInsert : public CommandObject
152{
153public:
154
155    CommandObjectTargetImageSearchPathsInsert (CommandInterpreter &interpreter) :
156        CommandObject (interpreter,
157                       "target image-search-paths insert",
158                       "Insert a new image search path substitution pair into the current target at the specified index.",
159                       NULL)
160    {
161        CommandArgumentEntry arg1;
162        CommandArgumentEntry arg2;
163        CommandArgumentData index_arg;
164        CommandArgumentData old_prefix_arg;
165        CommandArgumentData new_prefix_arg;
166
167        // Define the first and only variant of this arg.
168        index_arg.arg_type = eArgTypeIndex;
169        index_arg.arg_repetition = eArgRepeatPlain;
170
171        // Put the one and only variant into the first arg for m_arguments:
172        arg1.push_back (index_arg);
173
174        // Define the first variant of this arg pair.
175        old_prefix_arg.arg_type = eArgTypeOldPathPrefix;
176        old_prefix_arg.arg_repetition = eArgRepeatPairPlus;
177
178        // Define the first variant of this arg pair.
179        new_prefix_arg.arg_type = eArgTypeNewPathPrefix;
180        new_prefix_arg.arg_repetition = eArgRepeatPairPlus;
181
182        // There are two required arguments that must always occur together, i.e. an argument "pair".  Because they
183        // must always occur together, they are treated as two variants of one argument rather than two independent
184        // arguments.  Push them both into the same argument position for m_arguments...
185
186        arg2.push_back (old_prefix_arg);
187        arg2.push_back (new_prefix_arg);
188
189        // Add arguments to m_arguments.
190        m_arguments.push_back (arg1);
191        m_arguments.push_back (arg2);
192    }
193
194    ~CommandObjectTargetImageSearchPathsInsert ()
195    {
196    }
197
198    bool
199    Execute (Args& command,
200             CommandReturnObject &result)
201    {
202        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
203        if (target)
204        {
205            uint32_t argc = command.GetArgumentCount();
206            // check for at least 3 arguments and an odd nubmer of parameters
207            if (argc >= 3 && argc & 1)
208            {
209                bool success = false;
210
211                uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
212
213                if (!success)
214                {
215                    result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
216                    result.SetStatus (eReturnStatusFailed);
217                    return result.Succeeded();
218                }
219
220                // shift off the index
221                command.Shift();
222                argc = command.GetArgumentCount();
223
224                for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
225                {
226                    const char *from = command.GetArgumentAtIndex(i);
227                    const char *to = command.GetArgumentAtIndex(i+1);
228
229                    if (from[0] && to[0])
230                    {
231                        bool last_pair = ((argc - i) == 2);
232                        target->GetImageSearchPathList().Insert (ConstString(from),
233                                                                 ConstString(to),
234                                                                 insert_idx,
235                                                                 last_pair);
236                    }
237                    else
238                    {
239                        if (from[0])
240                            result.AppendError ("<path-prefix> can't be empty");
241                        else
242                            result.AppendError ("<new-path-prefix> can't be empty");
243                        result.SetStatus (eReturnStatusFailed);
244                        return false;
245                    }
246                }
247            }
248            else
249            {
250                result.AppendError ("insert requires at least three arguments");
251                result.SetStatus (eReturnStatusFailed);
252                return result.Succeeded();
253            }
254
255        }
256        else
257        {
258            result.AppendError ("invalid target");
259            result.SetStatus (eReturnStatusFailed);
260        }
261        return result.Succeeded();
262    }
263};
264
265class CommandObjectTargetImageSearchPathsList : public CommandObject
266{
267public:
268
269    CommandObjectTargetImageSearchPathsList (CommandInterpreter &interpreter) :
270        CommandObject (interpreter,
271                       "target image-search-paths list",
272                       "List all current image search path substitution pairs in the current target.",
273                       "target image-search-paths list")
274    {
275    }
276
277    ~CommandObjectTargetImageSearchPathsList ()
278    {
279    }
280
281    bool
282    Execute (Args& command,
283             CommandReturnObject &result)
284    {
285        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
286        if (target)
287        {
288            if (command.GetArgumentCount() != 0)
289            {
290                result.AppendError ("list takes no arguments");
291                result.SetStatus (eReturnStatusFailed);
292                return result.Succeeded();
293            }
294
295            target->GetImageSearchPathList().Dump(&result.GetOutputStream());
296        }
297        else
298        {
299            result.AppendError ("invalid target");
300            result.SetStatus (eReturnStatusFailed);
301        }
302        return result.Succeeded();
303    }
304};
305
306class CommandObjectTargetImageSearchPathsQuery : public CommandObject
307{
308public:
309
310    CommandObjectTargetImageSearchPathsQuery (CommandInterpreter &interpreter) :
311    CommandObject (interpreter,
312                   "target image-search-paths query",
313                   "Transform a path using the first applicable image search path.",
314                   NULL)
315    {
316        CommandArgumentEntry arg;
317        CommandArgumentData path_arg;
318
319        // Define the first (and only) variant of this arg.
320        path_arg.arg_type = eArgTypePath;
321        path_arg.arg_repetition = eArgRepeatPlain;
322
323        // There is only one variant this argument could be; put it into the argument entry.
324        arg.push_back (path_arg);
325
326        // Push the data for the first argument into the m_arguments vector.
327        m_arguments.push_back (arg);
328    }
329
330    ~CommandObjectTargetImageSearchPathsQuery ()
331    {
332    }
333
334    bool
335    Execute (Args& command,
336             CommandReturnObject &result)
337    {
338        Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
339        if (target)
340        {
341            if (command.GetArgumentCount() != 1)
342            {
343                result.AppendError ("query requires one argument");
344                result.SetStatus (eReturnStatusFailed);
345                return result.Succeeded();
346            }
347
348            ConstString orig(command.GetArgumentAtIndex(0));
349            ConstString transformed;
350            if (target->GetImageSearchPathList().RemapPath(orig, transformed))
351                result.GetOutputStream().Printf("%s\n", transformed.GetCString());
352            else
353                result.GetOutputStream().Printf("%s\n", orig.GetCString());
354        }
355        else
356        {
357            result.AppendError ("invalid target");
358            result.SetStatus (eReturnStatusFailed);
359        }
360        return result.Succeeded();
361    }
362};
363
364// TODO: implement the target select later when we start doing multiple targets
365//#pragma mark CommandObjectTargetSelect
366//
367////-------------------------------------------------------------------------
368//// CommandObjectTargetSelect
369////-------------------------------------------------------------------------
370//
371//class CommandObjectTargetSelect : public CommandObject
372//{
373//public:
374//
375//    CommandObjectTargetSelect () :
376//    CommandObject (interpreter,
377//                   frame select",
378//                   "Select the current frame by index in the current thread.",
379//                   "frame select <frame-index>")
380//    {
381//    }
382//
383//    ~CommandObjectTargetSelect ()
384//    {
385//    }
386//
387//    bool
388//    Execute (Args& command,
389//             Debugger *context,
390//             CommandInterpreter &m_interpreter,
391//             CommandReturnObject &result)
392//    {
393//        ExecutionContext exe_ctx (context->GetExecutionContext());
394//        if (exe_ctx.thread)
395//        {
396//            if (command.GetArgumentCount() == 1)
397//            {
398//                const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
399//
400//                const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount();
401//                const uint32_t frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0);
402//                if (frame_idx < num_frames)
403//                {
404//                    exe_ctx.thread->SetSelectedFrameByIndex (frame_idx);
405//                    exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get();
406//
407//                    if (exe_ctx.frame)
408//                    {
409//                        if (DisplayFrameForExecutionContext (exe_ctx.thread,
410//                                                             exe_ctx.frame,
411//                                                             m_interpreter,
412//                                                             result.GetOutputStream(),
413//                                                             true,
414//                                                             true,
415//                                                             3,
416//                                                             3))
417//                        {
418//                            result.SetStatus (eReturnStatusSuccessFinishResult);
419//                            return result.Succeeded();
420//                        }
421//                    }
422//                }
423//                if (frame_idx == UINT32_MAX)
424//                    result.AppendErrorWithFormat ("Invalid frame index: %s.\n", frame_idx_cstr);
425//                else
426//                    result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx);
427//            }
428//            else
429//            {
430//                result.AppendError ("invalid arguments");
431//                result.AppendErrorWithFormat ("Usage: %s\n", m_cmd_syntax.c_str());
432//            }
433//        }
434//        else
435//        {
436//            result.AppendError ("no current thread");
437//        }
438//        result.SetStatus (eReturnStatusFailed);
439//        return false;
440//    }
441//};
442
443
444#pragma mark CommandObjectMultiwordTarget
445
446//-------------------------------------------------------------------------
447// CommandObjectMultiwordImageSearchPaths
448//-------------------------------------------------------------------------
449
450class CommandObjectMultiwordImageSearchPaths : public CommandObjectMultiword
451{
452public:
453
454    CommandObjectMultiwordImageSearchPaths (CommandInterpreter &interpreter) :
455        CommandObjectMultiword (interpreter,
456                                "target image-search-paths",
457                                "A set of commands for operating on debugger target image search paths.",
458                                "target image-search-paths <subcommand> [<subcommand-options>]")
459    {
460        LoadSubCommand ("add",     CommandObjectSP (new CommandObjectTargetImageSearchPathsAdd (interpreter)));
461        LoadSubCommand ("clear",   CommandObjectSP (new CommandObjectTargetImageSearchPathsClear (interpreter)));
462        LoadSubCommand ("insert",  CommandObjectSP (new CommandObjectTargetImageSearchPathsInsert (interpreter)));
463        LoadSubCommand ("list",    CommandObjectSP (new CommandObjectTargetImageSearchPathsList (interpreter)));
464        LoadSubCommand ("query",   CommandObjectSP (new CommandObjectTargetImageSearchPathsQuery (interpreter)));
465    }
466
467    ~CommandObjectMultiwordImageSearchPaths()
468    {
469    }
470};
471
472
473#pragma mark CommandObjectMultiwordTarget
474
475//-------------------------------------------------------------------------
476// CommandObjectMultiwordTarget
477//-------------------------------------------------------------------------
478
479CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
480    CommandObjectMultiword (interpreter,
481                            "target",
482                            "A set of commands for operating on debugger targets.",
483                            "target <subcommand> [<subcommand-options>]")
484{
485    LoadSubCommand ("image-search-paths", CommandObjectSP (new CommandObjectMultiwordImageSearchPaths (interpreter)));
486}
487
488CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
489{
490}
491
492