llvm-project/lldb/source/Commands/CommandObjectArgs.cpp
Zachary Turner 1124045ac7 Don't #include "lldb-python.h" from anywhere.
Since interaction with the python interpreter is moving towards
being more isolated, we won't be able to include this header from
normal files anymore, all includes of it should be localized to
the python library which will live under source/bindings/API/Python
after a future patch.

None of the files that were including this header actually depended
on it anyway, so it was just a dead include in every single instance.

llvm-svn: 238581
2015-05-29 17:41:47 +00:00

267 lines
8.1 KiB
C++

//===-- CommandObjectArgs.cpp -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#include "CommandObjectArgs.h"
// C Includes
// C++ Includes
// Other libraries and framework includes
// Project includes
#include "lldb/Interpreter/Args.h"
#include "lldb/Core/Debugger.h"
#include "lldb/Core/Module.h"
#include "lldb/Core/Value.h"
#include "lldb/Expression/ClangExpression.h"
#include "lldb/Expression/ClangExpressionVariable.h"
#include "lldb/Expression/ClangFunction.h"
#include "lldb/Host/Host.h"
#include "lldb/Interpreter/CommandInterpreter.h"
#include "lldb/Interpreter/CommandReturnObject.h"
#include "lldb/Symbol/ClangASTContext.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/Variable.h"
#include "lldb/Target/ABI.h"
#include "lldb/Target/Process.h"
#include "lldb/Target/Target.h"
#include "lldb/Target/Thread.h"
#include "lldb/Target/StackFrame.h"
using namespace lldb;
using namespace lldb_private;
// This command is a toy. I'm just using it to have a way to construct the arguments to
// calling functions.
//
CommandObjectArgs::CommandOptions::CommandOptions (CommandInterpreter &interpreter) :
Options(interpreter)
{
// Keep only one place to reset the values to their defaults
OptionParsingStarting();
}
CommandObjectArgs::CommandOptions::~CommandOptions ()
{
}
Error
CommandObjectArgs::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg)
{
Error error;
const int short_option = m_getopt_table[option_idx].val;
error.SetErrorStringWithFormat("invalid short option character '%c'", short_option);
return error;
}
void
CommandObjectArgs::CommandOptions::OptionParsingStarting ()
{
}
const OptionDefinition*
CommandObjectArgs::CommandOptions::GetDefinitions ()
{
return g_option_table;
}
CommandObjectArgs::CommandObjectArgs (CommandInterpreter &interpreter) :
CommandObjectParsed (interpreter,
"args",
"When stopped at the start of a function, reads function arguments of type (u?)int(8|16|32|64)_t, (void|char)*",
"args"),
m_options (interpreter)
{
}
CommandObjectArgs::~CommandObjectArgs ()
{
}
Options *
CommandObjectArgs::GetOptions ()
{
return &m_options;
}
bool
CommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result)
{
ConstString target_triple;
Process *process = m_exe_ctx.GetProcessPtr();
if (!process)
{
result.AppendError ("Args found no process.");
result.SetStatus (eReturnStatusFailed);
return false;
}
const ABI *abi = process->GetABI().get();
if (!abi)
{
result.AppendError ("The current process has no ABI.");
result.SetStatus (eReturnStatusFailed);
return false;
}
const size_t num_args = args.GetArgumentCount ();
size_t arg_index;
if (!num_args)
{
result.AppendError ("args requires at least one argument");
result.SetStatus (eReturnStatusFailed);
return false;
}
Thread *thread = m_exe_ctx.GetThreadPtr();
if (!thread)
{
result.AppendError ("args found no thread.");
result.SetStatus (eReturnStatusFailed);
return false;
}
lldb::StackFrameSP thread_cur_frame = thread->GetSelectedFrame ();
if (!thread_cur_frame)
{
result.AppendError ("The current thread has no current frame.");
result.SetStatus (eReturnStatusFailed);
return false;
}
ModuleSP thread_module_sp (thread_cur_frame->GetFrameCodeAddress ().GetModule());
if (!thread_module_sp)
{
result.AppendError ("The PC has no associated module.");
result.SetStatus (eReturnStatusFailed);
return false;
}
ClangASTContext &ast_context = thread_module_sp->GetClangASTContext();
ValueList value_list;
for (arg_index = 0; arg_index < num_args; ++arg_index)
{
const char *arg_type_cstr = args.GetArgumentAtIndex(arg_index);
Value value;
value.SetValueType(Value::eValueTypeScalar);
ClangASTType clang_type;
char *int_pos;
if ((int_pos = strstr (const_cast<char*>(arg_type_cstr), "int")))
{
Encoding encoding = eEncodingSint;
int width = 0;
if (int_pos > arg_type_cstr + 1)
{
result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
result.SetStatus (eReturnStatusFailed);
return false;
}
if (int_pos == arg_type_cstr + 1 && arg_type_cstr[0] != 'u')
{
result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
result.SetStatus (eReturnStatusFailed);
return false;
}
if (arg_type_cstr[0] == 'u')
{
encoding = eEncodingUint;
}
char *width_pos = int_pos + 3;
if (!strcmp (width_pos, "8_t"))
width = 8;
else if (!strcmp (width_pos, "16_t"))
width = 16;
else if (!strcmp (width_pos, "32_t"))
width = 32;
else if (!strcmp (width_pos, "64_t"))
width = 64;
else
{
result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
result.SetStatus (eReturnStatusFailed);
return false;
}
clang_type = ast_context.GetBuiltinTypeForEncodingAndBitSize(encoding, width);
if (!clang_type.IsValid())
{
result.AppendErrorWithFormat ("Couldn't get Clang type for format %s (%s integer, width %d).\n",
arg_type_cstr,
(encoding == eEncodingSint ? "signed" : "unsigned"),
width);
result.SetStatus (eReturnStatusFailed);
return false;
}
}
else if (strchr (arg_type_cstr, '*'))
{
if (!strcmp (arg_type_cstr, "void*"))
clang_type = ast_context.GetBasicType(eBasicTypeVoid).GetPointerType();
else if (!strcmp (arg_type_cstr, "char*"))
clang_type = ast_context.GetCStringType (false);
else
{
result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
result.SetStatus (eReturnStatusFailed);
return false;
}
}
else
{
result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr);
result.SetStatus (eReturnStatusFailed);
return false;
}
value.SetClangType (clang_type);
value_list.PushValue(value);
}
if (!abi->GetArgumentValues (*thread, value_list))
{
result.AppendError ("Couldn't get argument values");
result.SetStatus (eReturnStatusFailed);
return false;
}
result.GetOutputStream ().Printf("Arguments : \n");
for (arg_index = 0; arg_index < num_args; ++arg_index)
{
result.GetOutputStream ().Printf ("%" PRIu64 " (%s): ", (uint64_t)arg_index, args.GetArgumentAtIndex (arg_index));
value_list.GetValueAtIndex (arg_index)->Dump (&result.GetOutputStream ());
result.GetOutputStream ().Printf("\n");
}
return result.Succeeded();
}
OptionDefinition
CommandObjectArgs::CommandOptions::g_option_table[] =
{
{ LLDB_OPT_SET_1, false, "debug", 'g', OptionParser::eNoArgument, NULL, NULL, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."},
{ 0, false, NULL, 0, 0, NULL, NULL, 0, eArgTypeNone, NULL }
};