1254721Semaste//===-- CommandObjectArgs.cpp -----------------------------------*- C++ -*-===//
2254721Semaste//
3254721Semaste//                     The LLVM Compiler Infrastructure
4254721Semaste//
5254721Semaste// This file is distributed under the University of Illinois Open Source
6254721Semaste// License. See LICENSE.TXT for details.
7254721Semaste//
8254721Semaste//===----------------------------------------------------------------------===//
9254721Semaste
10254721Semaste#include "lldb/lldb-python.h"
11254721Semaste
12254721Semaste#include "CommandObjectArgs.h"
13254721Semaste
14254721Semaste// C Includes
15254721Semaste// C++ Includes
16254721Semaste// Other libraries and framework includes
17254721Semaste// Project includes
18254721Semaste#include "lldb/Interpreter/Args.h"
19254721Semaste#include "lldb/Core/Debugger.h"
20254721Semaste#include "lldb/Core/Module.h"
21254721Semaste#include "lldb/Core/Value.h"
22254721Semaste#include "lldb/Expression/ClangExpression.h"
23254721Semaste#include "lldb/Expression/ClangExpressionVariable.h"
24254721Semaste#include "lldb/Expression/ClangFunction.h"
25254721Semaste#include "lldb/Host/Host.h"
26254721Semaste#include "lldb/Interpreter/CommandInterpreter.h"
27254721Semaste#include "lldb/Interpreter/CommandReturnObject.h"
28254721Semaste#include "lldb/Symbol/ObjectFile.h"
29254721Semaste#include "lldb/Symbol/Variable.h"
30254721Semaste#include "lldb/Target/Process.h"
31254721Semaste#include "lldb/Target/Target.h"
32254721Semaste#include "lldb/Target/Thread.h"
33254721Semaste#include "lldb/Target/StackFrame.h"
34254721Semaste
35254721Semasteusing namespace lldb;
36254721Semasteusing namespace lldb_private;
37254721Semaste
38254721Semaste// This command is a toy.  I'm just using it to have a way to construct the arguments to
39254721Semaste// calling functions.
40254721Semaste//
41254721Semaste
42254721SemasteCommandObjectArgs::CommandOptions::CommandOptions (CommandInterpreter &interpreter) :
43254721Semaste    Options(interpreter)
44254721Semaste{
45254721Semaste    // Keep only one place to reset the values to their defaults
46254721Semaste    OptionParsingStarting();
47254721Semaste}
48254721Semaste
49254721Semaste
50254721SemasteCommandObjectArgs::CommandOptions::~CommandOptions ()
51254721Semaste{
52254721Semaste}
53254721Semaste
54254721SemasteError
55254721SemasteCommandObjectArgs::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
56254721Semaste{
57254721Semaste    Error error;
58254721Semaste
59254721Semaste    const int short_option = m_getopt_table[option_idx].val;
60254721Semaste
61254721Semaste    switch (short_option)
62254721Semaste    {
63254721Semaste        default:
64254721Semaste            error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
65254721Semaste            break;
66254721Semaste    }
67254721Semaste
68254721Semaste    return error;
69254721Semaste}
70254721Semaste
71254721Semastevoid
72254721SemasteCommandObjectArgs::CommandOptions::OptionParsingStarting ()
73254721Semaste{
74254721Semaste}
75254721Semaste
76254721Semasteconst OptionDefinition*
77254721SemasteCommandObjectArgs::CommandOptions::GetDefinitions ()
78254721Semaste{
79254721Semaste    return g_option_table;
80254721Semaste}
81254721Semaste
82254721SemasteCommandObjectArgs::CommandObjectArgs (CommandInterpreter &interpreter) :
83254721Semaste    CommandObjectParsed (interpreter,
84254721Semaste                         "args",
85254721Semaste                         "When stopped at the start of a function, reads function arguments of type (u?)int(8|16|32|64)_t, (void|char)*",
86254721Semaste                         "args"),
87254721Semaste    m_options (interpreter)
88254721Semaste{
89254721Semaste}
90254721Semaste
91254721SemasteCommandObjectArgs::~CommandObjectArgs ()
92254721Semaste{
93254721Semaste}
94254721Semaste
95254721SemasteOptions *
96254721SemasteCommandObjectArgs::GetOptions ()
97254721Semaste{
98254721Semaste    return &m_options;
99254721Semaste}
100254721Semaste
101254721Semastebool
102254721SemasteCommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result)
103254721Semaste{
104254721Semaste    ConstString target_triple;
105254721Semaste
106254721Semaste
107254721Semaste    Process *process = m_exe_ctx.GetProcessPtr();
108254721Semaste    if (!process)
109254721Semaste    {
110254721Semaste        result.AppendError ("Args found no process.");
111254721Semaste        result.SetStatus (eReturnStatusFailed);
112254721Semaste        return false;
113254721Semaste    }
114254721Semaste
115254721Semaste    const ABI *abi = process->GetABI().get();
116254721Semaste    if (!abi)
117254721Semaste    {
118254721Semaste        result.AppendError ("The current process has no ABI.");
119254721Semaste        result.SetStatus (eReturnStatusFailed);
120254721Semaste        return false;
121254721Semaste    }
122254721Semaste
123254721Semaste    const size_t num_args = args.GetArgumentCount ();
124254721Semaste    size_t arg_index;
125254721Semaste
126254721Semaste    if (!num_args)
127254721Semaste    {
128254721Semaste        result.AppendError ("args requires at least one argument");
129254721Semaste        result.SetStatus (eReturnStatusFailed);
130254721Semaste        return false;
131254721Semaste    }
132254721Semaste
133254721Semaste    Thread *thread = m_exe_ctx.GetThreadPtr();
134254721Semaste
135254721Semaste    if (!thread)
136254721Semaste    {
137254721Semaste        result.AppendError ("args found no thread.");
138254721Semaste        result.SetStatus (eReturnStatusFailed);
139254721Semaste        return false;
140254721Semaste    }
141254721Semaste
142254721Semaste    lldb::StackFrameSP thread_cur_frame = thread->GetSelectedFrame ();
143254721Semaste    if (!thread_cur_frame)
144254721Semaste    {
145254721Semaste        result.AppendError ("The current thread has no current frame.");
146254721Semaste        result.SetStatus (eReturnStatusFailed);
147254721Semaste        return false;
148254721Semaste    }
149254721Semaste
150254721Semaste    ModuleSP thread_module_sp (thread_cur_frame->GetFrameCodeAddress ().GetModule());
151254721Semaste    if (!thread_module_sp)
152254721Semaste    {
153254721Semaste        result.AppendError ("The PC has no associated module.");
154254721Semaste        result.SetStatus (eReturnStatusFailed);
155254721Semaste        return false;
156254721Semaste    }
157254721Semaste
158254721Semaste    ClangASTContext &ast_context = thread_module_sp->GetClangASTContext();
159254721Semaste
160254721Semaste    ValueList value_list;
161254721Semaste
162254721Semaste    for (arg_index = 0; arg_index < num_args; ++arg_index)
163254721Semaste    {
164254721Semaste        const char *arg_type_cstr = args.GetArgumentAtIndex(arg_index);
165254721Semaste        Value value;
166254721Semaste        value.SetValueType(Value::eValueTypeScalar);
167254721Semaste        ClangASTType clang_type;
168254721Semaste
169254721Semaste        char *int_pos;
170254721Semaste        if ((int_pos = strstr (const_cast<char*>(arg_type_cstr), "int")))
171254721Semaste        {
172254721Semaste            Encoding encoding = eEncodingSint;
173254721Semaste
174254721Semaste            int width = 0;
175254721Semaste
176254721Semaste            if (int_pos > arg_type_cstr + 1)
177254721Semaste            {
178254721Semaste                result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
179254721Semaste                result.SetStatus (eReturnStatusFailed);
180254721Semaste                return false;
181254721Semaste            }
182254721Semaste            if (int_pos == arg_type_cstr + 1 && arg_type_cstr[0] != 'u')
183254721Semaste            {
184254721Semaste                result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
185254721Semaste                result.SetStatus (eReturnStatusFailed);
186254721Semaste                return false;
187254721Semaste            }
188254721Semaste            if (arg_type_cstr[0] == 'u')
189254721Semaste            {
190254721Semaste                encoding = eEncodingUint;
191254721Semaste            }
192254721Semaste
193254721Semaste            char *width_pos = int_pos + 3;
194254721Semaste
195254721Semaste            if (!strcmp (width_pos, "8_t"))
196254721Semaste                width = 8;
197254721Semaste            else if (!strcmp (width_pos, "16_t"))
198254721Semaste                width = 16;
199254721Semaste            else if (!strcmp (width_pos, "32_t"))
200254721Semaste                width = 32;
201254721Semaste            else if (!strcmp (width_pos, "64_t"))
202254721Semaste                width = 64;
203254721Semaste            else
204254721Semaste            {
205254721Semaste                result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
206254721Semaste                result.SetStatus (eReturnStatusFailed);
207254721Semaste                return false;
208254721Semaste            }
209254721Semaste
210254721Semaste            clang_type = ast_context.GetBuiltinTypeForEncodingAndBitSize(encoding, width);
211254721Semaste
212254721Semaste            if (!clang_type.IsValid())
213254721Semaste            {
214254721Semaste                result.AppendErrorWithFormat ("Couldn't get Clang type for format %s (%s integer, width %d).\n",
215254721Semaste                                             arg_type_cstr,
216254721Semaste                                             (encoding == eEncodingSint ? "signed" : "unsigned"),
217254721Semaste                                             width);
218254721Semaste
219254721Semaste                result.SetStatus (eReturnStatusFailed);
220254721Semaste                return false;
221254721Semaste            }
222254721Semaste        }
223254721Semaste        else if (strchr (arg_type_cstr, '*'))
224254721Semaste        {
225254721Semaste            if (!strcmp (arg_type_cstr, "void*"))
226254721Semaste                clang_type = ast_context.GetBasicType(eBasicTypeVoid).GetPointerType();
227254721Semaste            else if (!strcmp (arg_type_cstr, "char*"))
228254721Semaste                clang_type = ast_context.GetCStringType (false);
229254721Semaste            else
230254721Semaste            {
231254721Semaste                result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
232254721Semaste                result.SetStatus (eReturnStatusFailed);
233254721Semaste                return false;
234254721Semaste            }
235254721Semaste        }
236254721Semaste        else
237254721Semaste        {
238254721Semaste            result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
239254721Semaste            result.SetStatus (eReturnStatusFailed);
240254721Semaste            return false;
241254721Semaste        }
242254721Semaste
243254721Semaste        value.SetClangType (clang_type);
244254721Semaste        value_list.PushValue(value);
245254721Semaste    }
246254721Semaste
247254721Semaste    if (!abi->GetArgumentValues (*thread, value_list))
248254721Semaste    {
249254721Semaste        result.AppendError ("Couldn't get argument values");
250254721Semaste        result.SetStatus (eReturnStatusFailed);
251254721Semaste        return false;
252254721Semaste    }
253254721Semaste
254254721Semaste    result.GetOutputStream ().Printf("Arguments : \n");
255254721Semaste
256254721Semaste    for (arg_index = 0; arg_index < num_args; ++arg_index)
257254721Semaste    {
258254721Semaste        result.GetOutputStream ().Printf ("%zu (%s): ", arg_index, args.GetArgumentAtIndex (arg_index));
259254721Semaste        value_list.GetValueAtIndex (arg_index)->Dump (&result.GetOutputStream ());
260254721Semaste        result.GetOutputStream ().Printf("\n");
261254721Semaste    }
262254721Semaste
263254721Semaste    return result.Succeeded();
264254721Semaste}
265254721Semaste
266254721SemasteOptionDefinition
267254721SemasteCommandObjectArgs::CommandOptions::g_option_table[] =
268254721Semaste{
269254721Semaste    { LLDB_OPT_SET_1, false, "debug", 'g', no_argument, NULL, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."},
270254721Semaste    { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL }
271254721Semaste};
272254721Semaste
273