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 (CommandInterpreter &interpreter) :
38         CommandObject (interpreter,
39                        "target image-search-paths add",
40                        "Add new image search paths substitution pairs to the current target.",
41                        "target image-search-paths add <path-prefix> <new-path-prefix> [<path-prefix> <new-path-prefix>] ...")
42     {
43     }
44 
45     ~CommandObjectTargetImageSearchPathsAdd ()
46     {
47     }
48 
49     bool
50     Execute (Args& command,
51              CommandReturnObject &result)
52     {
53         Target *target = m_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 
96 class CommandObjectTargetImageSearchPathsClear : public CommandObject
97 {
98 public:
99 
100     CommandObjectTargetImageSearchPathsClear (CommandInterpreter &interpreter) :
101         CommandObject (interpreter,
102                        "target image-search-paths clear",
103                        "Clear all current image search path substitution pairs from the current target.",
104                        "target image-search-paths clear")
105     {
106     }
107 
108     ~CommandObjectTargetImageSearchPathsClear ()
109     {
110     }
111 
112     bool
113     Execute (Args& command,
114              CommandReturnObject &result)
115     {
116         Target *target = m_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 
131 class CommandObjectTargetImageSearchPathsInsert : public CommandObject
132 {
133 public:
134 
135     CommandObjectTargetImageSearchPathsInsert (CommandInterpreter &interpreter) :
136         CommandObject (interpreter,
137                        "target image-search-paths insert",
138                        "Insert a new image search path substitution pair into the current target at the specified index.",
139                        "target image-search-paths insert <index> <path-prefix> <new-path-prefix> [<path-prefix> <new-path-prefix>] ...")
140     {
141     }
142 
143     ~CommandObjectTargetImageSearchPathsInsert ()
144     {
145     }
146 
147     bool
148     Execute (Args& command,
149              CommandReturnObject &result)
150     {
151         Target *target = m_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 
214 class CommandObjectTargetImageSearchPathsList : public CommandObject
215 {
216 public:
217 
218     CommandObjectTargetImageSearchPathsList (CommandInterpreter &interpreter) :
219         CommandObject (interpreter,
220                        "target image-search-paths list",
221                        "List all current image search path substitution pairs in the current target.",
222                        "target image-search-paths list")
223     {
224     }
225 
226     ~CommandObjectTargetImageSearchPathsList ()
227     {
228     }
229 
230     bool
231     Execute (Args& command,
232              CommandReturnObject &result)
233     {
234         Target *target = m_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 
255 class CommandObjectTargetImageSearchPathsQuery : public CommandObject
256 {
257 public:
258 
259     CommandObjectTargetImageSearchPathsQuery (CommandInterpreter &interpreter) :
260     CommandObject (interpreter,
261                    "target image-search-paths query",
262                    "Transform a path using the first applicable image search path.",
263                    "target image-search-paths query <path>")
264     {
265     }
266 
267     ~CommandObjectTargetImageSearchPathsQuery ()
268     {
269     }
270 
271     bool
272     Execute (Args& command,
273              CommandReturnObject &result)
274     {
275         Target *target = m_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 (interpreter,
314 //                   frame select",
315 //                   "Select the current frame by index in the current thread.",
316 //                   "frame select <frame-index>")
317 //    {
318 //    }
319 //
320 //    ~CommandObjectTargetSelect ()
321 //    {
322 //    }
323 //
324 //    bool
325 //    Execute (Args& command,
326 //             Debugger *context,
327 //             CommandInterpreter &m_interpreter,
328 //             CommandReturnObject &result)
329 //    {
330 //        ExecutionContext exe_ctx (context->GetExecutionContext());
331 //        if (exe_ctx.thread)
332 //        {
333 //            if (command.GetArgumentCount() == 1)
334 //            {
335 //                const char *frame_idx_cstr = command.GetArgumentAtIndex(0);
336 //
337 //                const uint32_t num_frames = exe_ctx.thread->GetStackFrameCount();
338 //                const uint32_t frame_idx = Args::StringToUInt32 (frame_idx_cstr, UINT32_MAX, 0);
339 //                if (frame_idx < num_frames)
340 //                {
341 //                    exe_ctx.thread->SetSelectedFrameByIndex (frame_idx);
342 //                    exe_ctx.frame = exe_ctx.thread->GetSelectedFrame ().get();
343 //
344 //                    if (exe_ctx.frame)
345 //                    {
346 //                        if (DisplayFrameForExecutionContext (exe_ctx.thread,
347 //                                                             exe_ctx.frame,
348 //                                                             m_interpreter,
349 //                                                             result.GetOutputStream(),
350 //                                                             true,
351 //                                                             true,
352 //                                                             3,
353 //                                                             3))
354 //                        {
355 //                            result.SetStatus (eReturnStatusSuccessFinishResult);
356 //                            return result.Succeeded();
357 //                        }
358 //                    }
359 //                }
360 //                if (frame_idx == UINT32_MAX)
361 //                    result.AppendErrorWithFormat ("Invalid frame index: %s.\n", frame_idx_cstr);
362 //                else
363 //                    result.AppendErrorWithFormat ("Frame index (%u) out of range.\n", frame_idx);
364 //            }
365 //            else
366 //            {
367 //                result.AppendError ("invalid arguments");
368 //                result.AppendErrorWithFormat ("Usage: %s\n", m_cmd_syntax.c_str());
369 //            }
370 //        }
371 //        else
372 //        {
373 //            result.AppendError ("no current thread");
374 //        }
375 //        result.SetStatus (eReturnStatusFailed);
376 //        return false;
377 //    }
378 //};
379 
380 
381 #pragma mark CommandObjectMultiwordTarget
382 
383 //-------------------------------------------------------------------------
384 // CommandObjectMultiwordImageSearchPaths
385 //-------------------------------------------------------------------------
386 
387 class CommandObjectMultiwordImageSearchPaths : public CommandObjectMultiword
388 {
389 public:
390 
391     CommandObjectMultiwordImageSearchPaths (CommandInterpreter &interpreter) :
392         CommandObjectMultiword (interpreter,
393                                 "target image-search-paths",
394                                 "A set of commands for operating on debugger target image search paths.",
395                                 "target image-search-paths <subcommand> [<subcommand-options>]")
396     {
397         LoadSubCommand ("add",     CommandObjectSP (new CommandObjectTargetImageSearchPathsAdd (interpreter)));
398         LoadSubCommand ("clear",   CommandObjectSP (new CommandObjectTargetImageSearchPathsClear (interpreter)));
399         LoadSubCommand ("insert",  CommandObjectSP (new CommandObjectTargetImageSearchPathsInsert (interpreter)));
400         LoadSubCommand ("list",    CommandObjectSP (new CommandObjectTargetImageSearchPathsList (interpreter)));
401         LoadSubCommand ("query",   CommandObjectSP (new CommandObjectTargetImageSearchPathsQuery (interpreter)));
402     }
403 
404     ~CommandObjectMultiwordImageSearchPaths()
405     {
406     }
407 };
408 
409 
410 #pragma mark CommandObjectMultiwordTarget
411 
412 //-------------------------------------------------------------------------
413 // CommandObjectMultiwordTarget
414 //-------------------------------------------------------------------------
415 
416 CommandObjectMultiwordTarget::CommandObjectMultiwordTarget (CommandInterpreter &interpreter) :
417     CommandObjectMultiword (interpreter,
418                             "target",
419                             "A set of commands for operating on debugger targets.",
420                             "target <subcommand> [<subcommand-options>]")
421 {
422     LoadSubCommand ("image-search-paths", CommandObjectSP (new CommandObjectMultiwordImageSearchPaths (interpreter)));
423 }
424 
425 CommandObjectMultiwordTarget::~CommandObjectMultiwordTarget ()
426 {
427 }
428 
429