]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/llvm/tools/lldb/source/Commands/CommandObjectArgs.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / llvm / tools / lldb / source / Commands / CommandObjectArgs.cpp
1 //===-- CommandObjectArgs.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 "lldb/lldb-python.h"
11
12 #include "CommandObjectArgs.h"
13
14 // C Includes
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/Module.h"
21 #include "lldb/Core/Value.h"
22 #include "lldb/Expression/ClangExpression.h"
23 #include "lldb/Expression/ClangExpressionVariable.h"
24 #include "lldb/Expression/ClangFunction.h"
25 #include "lldb/Host/Host.h"
26 #include "lldb/Interpreter/CommandInterpreter.h"
27 #include "lldb/Interpreter/CommandReturnObject.h"
28 #include "lldb/Symbol/ObjectFile.h"
29 #include "lldb/Symbol/Variable.h"
30 #include "lldb/Target/Process.h"
31 #include "lldb/Target/Target.h"
32 #include "lldb/Target/Thread.h"
33 #include "lldb/Target/StackFrame.h"
34
35 using namespace lldb;
36 using namespace lldb_private;
37
38 // This command is a toy.  I'm just using it to have a way to construct the arguments to
39 // calling functions.
40 //
41
42 CommandObjectArgs::CommandOptions::CommandOptions (CommandInterpreter &interpreter) :
43     Options(interpreter)
44 {
45     // Keep only one place to reset the values to their defaults
46     OptionParsingStarting();
47 }
48
49
50 CommandObjectArgs::CommandOptions::~CommandOptions ()
51 {
52 }
53
54 Error
55 CommandObjectArgs::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
56 {
57     Error error;
58     
59     const int short_option = m_getopt_table[option_idx].val;
60     
61     switch (short_option)
62     {
63         default:
64             error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
65             break;
66     }
67     
68     return error;
69 }
70
71 void
72 CommandObjectArgs::CommandOptions::OptionParsingStarting ()
73 {
74 }
75
76 const OptionDefinition*
77 CommandObjectArgs::CommandOptions::GetDefinitions ()
78 {
79     return g_option_table;
80 }
81
82 CommandObjectArgs::CommandObjectArgs (CommandInterpreter &interpreter) :
83     CommandObjectParsed (interpreter,
84                          "args",
85                          "When stopped at the start of a function, reads function arguments of type (u?)int(8|16|32|64)_t, (void|char)*",
86                          "args"),
87     m_options (interpreter)
88 {
89 }
90
91 CommandObjectArgs::~CommandObjectArgs ()
92 {
93 }
94
95 Options *
96 CommandObjectArgs::GetOptions ()
97 {
98     return &m_options;
99 }
100
101 bool
102 CommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result)
103 {
104     ConstString target_triple;
105     
106     
107     Process *process = m_exe_ctx.GetProcessPtr();
108     if (!process)
109     {
110         result.AppendError ("Args found no process.");
111         result.SetStatus (eReturnStatusFailed);
112         return false;
113     }
114     
115     const ABI *abi = process->GetABI().get();
116     if (!abi)
117     {
118         result.AppendError ("The current process has no ABI.");
119         result.SetStatus (eReturnStatusFailed);
120         return false;
121     }
122     
123     const size_t num_args = args.GetArgumentCount ();
124     size_t arg_index;
125     
126     if (!num_args)
127     {
128         result.AppendError ("args requires at least one argument");
129         result.SetStatus (eReturnStatusFailed);
130         return false;
131     }
132     
133     Thread *thread = m_exe_ctx.GetThreadPtr();
134     
135     if (!thread)
136     {
137         result.AppendError ("args found no thread.");
138         result.SetStatus (eReturnStatusFailed);
139         return false;
140     }
141         
142     lldb::StackFrameSP thread_cur_frame = thread->GetSelectedFrame ();
143     if (!thread_cur_frame)
144     {
145         result.AppendError ("The current thread has no current frame.");
146         result.SetStatus (eReturnStatusFailed);
147         return false;
148     }
149     
150     ModuleSP thread_module_sp (thread_cur_frame->GetFrameCodeAddress ().GetModule());
151     if (!thread_module_sp)
152     {
153         result.AppendError ("The PC has no associated module.");
154         result.SetStatus (eReturnStatusFailed);
155         return false;
156     }
157     
158     ClangASTContext &ast_context = thread_module_sp->GetClangASTContext();
159     
160     ValueList value_list;
161     
162     for (arg_index = 0; arg_index < num_args; ++arg_index)
163     {
164         const char *arg_type_cstr = args.GetArgumentAtIndex(arg_index);
165         Value value;
166         value.SetValueType(Value::eValueTypeScalar);
167         ClangASTType clang_type;
168         
169         char *int_pos;
170         if ((int_pos = strstr (const_cast<char*>(arg_type_cstr), "int")))
171         {
172             Encoding encoding = eEncodingSint;
173             
174             int width = 0;
175             
176             if (int_pos > arg_type_cstr + 1)
177             {
178                 result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
179                 result.SetStatus (eReturnStatusFailed);
180                 return false;
181             }
182             if (int_pos == arg_type_cstr + 1 && arg_type_cstr[0] != 'u')
183             {
184                 result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
185                 result.SetStatus (eReturnStatusFailed);
186                 return false;
187             }
188             if (arg_type_cstr[0] == 'u')
189             {
190                 encoding = eEncodingUint;
191             }
192             
193             char *width_pos = int_pos + 3;
194             
195             if (!strcmp (width_pos, "8_t"))
196                 width = 8;
197             else if (!strcmp (width_pos, "16_t"))
198                 width = 16;
199             else if (!strcmp (width_pos, "32_t"))
200                 width = 32;
201             else if (!strcmp (width_pos, "64_t"))
202                 width = 64;
203             else
204             {
205                 result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
206                 result.SetStatus (eReturnStatusFailed);
207                 return false;
208             }
209             
210             clang_type = ast_context.GetBuiltinTypeForEncodingAndBitSize(encoding, width);
211             
212             if (!clang_type.IsValid())
213             {
214                 result.AppendErrorWithFormat ("Couldn't get Clang type for format %s (%s integer, width %d).\n",
215                                              arg_type_cstr,
216                                              (encoding == eEncodingSint ? "signed" : "unsigned"),
217                                              width);
218                 
219                 result.SetStatus (eReturnStatusFailed);
220                 return false;
221             }
222         }
223         else if (strchr (arg_type_cstr, '*'))
224         {
225             if (!strcmp (arg_type_cstr, "void*"))
226                 clang_type = ast_context.GetBasicType(eBasicTypeVoid).GetPointerType();
227             else if (!strcmp (arg_type_cstr, "char*"))
228                 clang_type = ast_context.GetCStringType (false);
229             else
230             {
231                 result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
232                 result.SetStatus (eReturnStatusFailed);
233                 return false;
234             }
235         }
236         else 
237         {
238             result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
239             result.SetStatus (eReturnStatusFailed);
240             return false;
241         }
242                      
243         value.SetClangType (clang_type);
244         value_list.PushValue(value);
245     }
246     
247     if (!abi->GetArgumentValues (*thread, value_list))
248     {
249         result.AppendError ("Couldn't get argument values");
250         result.SetStatus (eReturnStatusFailed);
251         return false;
252     }
253     
254     result.GetOutputStream ().Printf("Arguments : \n");
255
256     for (arg_index = 0; arg_index < num_args; ++arg_index)
257     {
258         result.GetOutputStream ().Printf ("%zu (%s): ", arg_index, args.GetArgumentAtIndex (arg_index));
259         value_list.GetValueAtIndex (arg_index)->Dump (&result.GetOutputStream ());
260         result.GetOutputStream ().Printf("\n");
261     }
262     
263     return result.Succeeded();
264 }
265
266 OptionDefinition
267 CommandObjectArgs::CommandOptions::g_option_table[] =
268 {
269     { LLDB_OPT_SET_1, false, "debug", 'g', no_argument, NULL, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."},
270     { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
271 };
272