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