CommandObjectTarget.cpp revision c833295baeec641086f536e78050388af36784f8
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 () :
38        CommandObject ("target image-search-paths add",
39                       "Add new image search paths substitution pairs to the current target.",
40                       "target image-search-paths add <path-prefix> <new-path-prefix> [<path-prefix> <new-path-prefix>] ...")
41    {
42    }
43
44    ~CommandObjectTargetImageSearchPathsAdd ()
45    {
46    }
47
48    bool
49    Execute (CommandInterpreter &interpreter,
50             Args& command,
51             CommandReturnObject &result)
52    {
53        Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
54        if (target)
55        {
56            uint32_t argc = command.GetArgumentCount();
57            if (argc & 1)
58            {
59                result.AppendError ("add requires an even number of arguments");
60                result.SetStatus (eReturnStatusFailed);
61            }
62            else
63            {
64                for (uint32_t i=0; i<argc; i+=2)
65                {
66                    const char *from = command.GetArgumentAtIndex(i);
67                    const char *to = command.GetArgumentAtIndex(i+1);
68
69                    if (from[0] && to[0])
70                    {
71                        bool last_pair = ((argc - i) == 2);
72                        target->GetImageSearchPathList().Append (ConstString(from),
73                                                                 ConstString(to),
74                                                                 last_pair); // Notify if this is the last pair
75                    }
76                    else
77                    {
78                        if (from[0])
79                            result.AppendError ("<path-prefix> can't be empty");
80                        else
81                            result.AppendError ("<new-path-prefix> can't be empty");
82                        result.SetStatus (eReturnStatusFailed);
83                    }
84                }
85            }
86        }
87        else
88        {
89            result.AppendError ("invalid target");
90            result.SetStatus (eReturnStatusFailed);
91        }
92        return result.Succeeded();
93    }
94};
95
96class CommandObjectTargetImageSearchPathsClear : public CommandObject
97{
98public:
99
100    CommandObjectTargetImageSearchPathsClear () :
101        CommandObject ("target image-search-paths clear",
102                       "Clears all current image search paths substitution pairs from the current target.",
103                       "target image-search-paths clear")
104    {
105    }
106
107    ~CommandObjectTargetImageSearchPathsClear ()
108    {
109    }
110
111    bool
112    Execute (CommandInterpreter &interpreter,
113             Args& command,
114             CommandReturnObject &result)
115    {
116        Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
117        if (target)
118        {
119            bool notify = true;
120            target->GetImageSearchPathList().Clear(notify);
121        }
122        else
123        {
124            result.AppendError ("invalid target");
125            result.SetStatus (eReturnStatusFailed);
126        }
127        return result.Succeeded();
128    }
129};
130
131class CommandObjectTargetImageSearchPathsInsert : public CommandObject
132{
133public:
134
135    CommandObjectTargetImageSearchPathsInsert () :
136        CommandObject ("target image-search-paths insert",
137                       "Inserts a new image search paths substitution pair to the current target at the specified index.",
138                       "target image-search-paths insert <index> <path-prefix> <new-path-prefix> [<path-prefix> <new-path-prefix>] ...")
139    {
140    }
141
142    ~CommandObjectTargetImageSearchPathsInsert ()
143    {
144    }
145
146    bool
147    Execute (CommandInterpreter &interpreter,
148             Args& command,
149             CommandReturnObject &result)
150    {
151        Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
152        if (target)
153        {
154            uint32_t argc = command.GetArgumentCount();
155            // check for at least 3 arguments and an odd nubmer of parameters
156            if (argc >= 3 && argc & 1)
157            {
158                bool success = false;
159
160                uint32_t insert_idx = Args::StringToUInt32(command.GetArgumentAtIndex(0), UINT32_MAX, 0, &success);
161
162                if (!success)
163                {
164                    result.AppendErrorWithFormat("<index> parameter is not an integer: '%s'.\n", command.GetArgumentAtIndex(0));
165                    result.SetStatus (eReturnStatusFailed);
166                    return result.Succeeded();
167                }
168
169                // shift off the index
170                command.Shift();
171                argc = command.GetArgumentCount();
172
173                for (uint32_t i=0; i<argc; i+=2, ++insert_idx)
174                {
175                    const char *from = command.GetArgumentAtIndex(i);
176                    const char *to = command.GetArgumentAtIndex(i+1);
177
178                    if (from[0] && to[0])
179                    {
180                        bool last_pair = ((argc - i) == 2);
181                        target->GetImageSearchPathList().Insert (ConstString(from),
182                                                                 ConstString(to),
183                                                                 insert_idx,
184                                                                 last_pair);
185                    }
186                    else
187                    {
188                        if (from[0])
189                            result.AppendError ("<path-prefix> can't be empty");
190                        else
191                            result.AppendError ("<new-path-prefix> can't be empty");
192                        result.SetStatus (eReturnStatusFailed);
193                        return false;
194                    }
195                }
196            }
197            else
198            {
199                result.AppendError ("insert requires at least three arguments");
200                result.SetStatus (eReturnStatusFailed);
201                return result.Succeeded();
202            }
203
204        }
205        else
206        {
207            result.AppendError ("invalid target");
208            result.SetStatus (eReturnStatusFailed);
209        }
210        return result.Succeeded();
211    }
212};
213
214class CommandObjectTargetImageSearchPathsList : public CommandObject
215{
216public:
217
218    CommandObjectTargetImageSearchPathsList () :
219        CommandObject ("target image-search-paths list",
220                       "Lists all current image search paths substitution pairs in the current target.",
221                       "target image-search-paths list")
222    {
223    }
224
225    ~CommandObjectTargetImageSearchPathsList ()
226    {
227    }
228
229    bool
230    Execute (CommandInterpreter &interpreter,
231             Args& command,
232             CommandReturnObject &result)
233    {
234        Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
235        if (target)
236        {
237            if (command.GetArgumentCount() != 0)
238            {
239                result.AppendError ("list takes no arguments");
240                result.SetStatus (eReturnStatusFailed);
241                return result.Succeeded();
242            }
243
244            target->GetImageSearchPathList().Dump(&result.GetOutputStream());
245        }
246        else
247        {
248            result.AppendError ("invalid target");
249            result.SetStatus (eReturnStatusFailed);
250        }
251        return result.Succeeded();
252    }
253};
254
255class CommandObjectTargetImageSearchPathsQuery : public CommandObject
256{
257public:
258
259    CommandObjectTargetImageSearchPathsQuery () :
260    CommandObject ("target image-search-paths query",
261                   "Transforms a path using the first applicable image search path.",
262                   "target image-search-paths query <path>")
263    {
264    }
265
266    ~CommandObjectTargetImageSearchPathsQuery ()
267    {
268    }
269
270    bool
271    Execute (CommandInterpreter &interpreter,
272             Args& command,
273             CommandReturnObject &result)
274    {
275        Target *target = interpreter.GetDebugger().GetSelectedTarget().get();
276        if (target)
277        {
278            if (command.GetArgumentCount() != 1)
279            {
280                result.AppendError ("query requires one argument");
281                result.SetStatus (eReturnStatusFailed);
282                return result.Succeeded();
283            }
284
285            ConstString orig(command.GetArgumentAtIndex(0));
286            ConstString transformed;
287            if (target->GetImageSearchPathList().RemapPath(orig, transformed))
288                result.GetOutputStream().Printf("%s\n", transformed.GetCString());
289            else
290                result.GetOutputStream().Printf("%s\n", orig.GetCString());
291        }
292        else
293        {
294            result.AppendError ("invalid target");
295            result.SetStatus (eReturnStatusFailed);
296        }
297        return result.Succeeded();
298    }
299};
300
301// TODO: implement the target select later when we start doing multiple targets
302//#pragma mark CommandObjectTargetSelect
303//
304////-------------------------------------------------------------------------
305//// CommandObjectTargetSelect
306////-------------------------------------------------------------------------
307//
308//class CommandObjectTargetSelect : public CommandObject
309//{
310//public:
311//
312//    CommandObjectTargetSelect () :
313//    CommandObject ("frame select",
314//                   "Select the current frame by index in the current thread.",
315//                   "frame select <frame-index>")
316//    {
317//    }
318//
319//    ~CommandObjectTargetSelect ()
320//    {
321//    }
322//
323//    bool
324//    Execute (Args& command,
325//             Debugger *context,
326//             CommandInterpreter &interpreter,
327//             CommandReturnObject &result)
328//    {
329//        ExecutionContext exe_ctx (context->GetExecutionContext());
330//        if (exe_ctx.thread)
331//        {
332//            if (command.GetArgumentCount() == 1)
333//            {
334//                const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
335//
336//                const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount();
337//                const uint32_t frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0);
338//                if (frame_idx < num_frames)
339//                {
340//                    exe_ctx.thread->SetSelectedFrameByIndex (frame_idx);
341//                    exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get();
342//
343//                    if (exe_ctx.frame)
344//                    {
345//                        if (DisplayFrameForExecutionContext (exe_ctx.thread,
346//                                                             exe_ctx.frame,
347//                                                             interpreter,
348//                                                             result.GetOutputStream(),
349//                                                             true,
350//                                                             true,
351//                                                             3,
352//                                                             3))
353//                        {
354//                            result.SetStatus (eReturnStatusSuccessFinishResult);
355//                            return result.Succeeded();
356//                        }
357//                    }
358//                }
359//                if (frame_idx == UINT32_MAX)
360//                    result.AppendErrorWithFormat ("Invalid frame index: %s.\n", frame_idx_cstr);
361//                else
362//                    result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx);
363//            }
364//            else
365//            {
366//                result.AppendError ("invalid arguments");
367//                result.AppendErrorWithFormat ("Usage: %s\n", m_cmd_syntax.c_str());
368//            }
369//        }
370//        else
371//        {
372//            result.AppendError ("no current thread");
373//        }
374//        result.SetStatus (eReturnStatusFailed);
375//        return false;
376//    }
377//};
378
379
380#pragma mark CommandObjectMultiwordTarget
381
382//-------------------------------------------------------------------------
383// CommandObjectMultiwordImageSearchPaths
384//-------------------------------------------------------------------------
385
386class CommandObjectMultiwordImageSearchPaths : public CommandObjectMultiword
387{
388public:
389
390    CommandObjectMultiwordImageSearchPaths (CommandInterpreter &interpreter) :
391        CommandObjectMultiword ("target image-search-paths",
392                                "A set of commands for operating on debugger target image search paths.",
393                                "target image-search-paths <subcommand> [<subcommand-options>]")
394    {
395        LoadSubCommand (interpreter, "add",     CommandObjectSP (new CommandObjectTargetImageSearchPathsAdd ()));
396        LoadSubCommand (interpreter, "clear",   CommandObjectSP (new CommandObjectTargetImageSearchPathsClear ()));
397        LoadSubCommand (interpreter, "insert",  CommandObjectSP (new CommandObjectTargetImageSearchPathsInsert ()));
398        LoadSubCommand (interpreter, "list",    CommandObjectSP (new CommandObjectTargetImageSearchPathsList ()));
399        LoadSubCommand (interpreter, "query",   CommandObjectSP (new CommandObjectTargetImageSearchPathsQuery ()));
400    }
401
402    ~CommandObjectMultiwordImageSearchPaths()
403    {
404    }
405};
406
407
408#pragma mark CommandObjectMultiwordTarget
409
410//-------------------------------------------------------------------------
411// CommandObjectMultiwordTarget
412//-------------------------------------------------------------------------
413
414CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
415    CommandObjectMultiword ("target",
416                            "A set of commands for operating on debugger targets.",
417                            "target <subcommand> [<subcommand-options>]")
418{
419    LoadSubCommand (interpreter, "image-search-paths", CommandObjectSP (new CommandObjectMultiwordImageSearchPaths (interpreter)));
420}
421
422CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
423{
424}
425
426