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