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 
28 using namespace lldb;
29 using namespace lldb_private;
30 
31 #pragma mark CommandObjectTargetImageSearchPaths
32 
33 class CommandObjectTargetImageSearchPathsAdd : public CommandObject
34 {
35 public:
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().GetCurrentTarget().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 
96 class CommandObjectTargetImageSearchPathsClear : public CommandObject
97 {
98 public:
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().GetCurrentTarget().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 
131 class CommandObjectTargetImageSearchPathsInsert : public CommandObject
132 {
133 public:
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().GetCurrentTarget().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 
214 class CommandObjectTargetImageSearchPathsList : public CommandObject
215 {
216 public:
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().GetCurrentTarget().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 
255 class CommandObjectTargetImageSearchPathsQuery : public CommandObject
256 {
257 public:
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().GetCurrentTarget().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->SetCurrentFrameByIndex (frame_idx);
341 //                    exe_ctx.frame = exe_ctx.thread->GetCurrentFrame ().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 
386 class CommandObjectMultiwordImageSearchPaths : public CommandObjectMultiword
387 {
388 public:
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 
414 CommandObjectMultiwordTarget::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 
422 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
423 {
424 }
425 
426