CommandObjectArgs.cpp revision 254729
169800Stomsoft//===-- CommandObjectArgs.cpp -----------------------------------*- C++ -*-===// 269800Stomsoft// 369800Stomsoft// The LLVM Compiler Infrastructure 469800Stomsoft// 5114067Sschweikh// This file is distributed under the University of Illinois Open Source 669800Stomsoft// License. See LICENSE.TXT for details. 769800Stomsoft// 8114067Sschweikh//===----------------------------------------------------------------------===// 969800Stomsoft 1069800Stomsoft#include "lldb/lldb-python.h" 1169800Stomsoft 1269800Stomsoft#include "CommandObjectArgs.h" 1369800Stomsoft 1469800Stomsoft// C Includes 1569800Stomsoft// C++ Includes 1669800Stomsoft// Other libraries and framework includes 1769800Stomsoft// Project includes 1869800Stomsoft#include "lldb/Interpreter/Args.h" 1969800Stomsoft#include "lldb/Core/Debugger.h" 2069800Stomsoft#include "lldb/Core/Module.h" 2169800Stomsoft#include "lldb/Core/Value.h" 2269800Stomsoft#include "lldb/Expression/ClangExpression.h" 2369800Stomsoft#include "lldb/Expression/ClangExpressionVariable.h" 2469800Stomsoft#include "lldb/Expression/ClangFunction.h" 25114067Sschweikh#include "lldb/Host/Host.h" 2669800Stomsoft#include "lldb/Interpreter/CommandInterpreter.h" 2769800Stomsoft#include "lldb/Interpreter/CommandReturnObject.h" 2869800Stomsoft#include "lldb/Symbol/ObjectFile.h" 2969800Stomsoft#include "lldb/Symbol/Variable.h" 3069800Stomsoft#include "lldb/Target/Process.h" 3169800Stomsoft#include "lldb/Target/Target.h" 3269800Stomsoft#include "lldb/Target/Thread.h" 3369800Stomsoft#include "lldb/Target/StackFrame.h" 3469800Stomsoft 3569800Stomsoftusing namespace lldb; 3669800Stomsoftusing namespace lldb_private; 3769800Stomsoft 3869926Stomsoft// This command is a toy. I'm just using it to have a way to construct the arguments to 3969800Stomsoft// calling functions. 4069800Stomsoft// 4169800Stomsoft 4269800StomsoftCommandObjectArgs::CommandOptions::CommandOptions (CommandInterpreter &interpreter) : 4369800Stomsoft Options(interpreter) 4469800Stomsoft{ 4569800Stomsoft // Keep only one place to reset the values to their defaults 4669800Stomsoft OptionParsingStarting(); 4769800Stomsoft} 4869800Stomsoft 49140351Scharnier 50140351ScharnierCommandObjectArgs::CommandOptions::~CommandOptions () 5169800Stomsoft{ 5269800Stomsoft} 5369800Stomsoft 5469800StomsoftError 5569800StomsoftCommandObjectArgs::CommandOptions::SetOptionValue (uint32_t option_idx, const char *option_arg) 5669800Stomsoft{ 57114936Sgrog Error error; 5869800Stomsoft 5969800Stomsoft const int short_option = m_getopt_table[option_idx].val; 6069800Stomsoft 6169800Stomsoft switch (short_option) 6269800Stomsoft { 6369800Stomsoft default: 64103949Smike error.SetErrorStringWithFormat("invalid short option character '%c'", short_option); 6569800Stomsoft break; 66127798Sle } 6769800Stomsoft 68127821Sbde return error; 6969800Stomsoft} 7069800Stomsoft 7169800Stomsoftvoid 7269800StomsoftCommandObjectArgs::CommandOptions::OptionParsingStarting () 7369800Stomsoft{ 7469800Stomsoft} 7569800Stomsoft 7669800Stomsoftconst OptionDefinition* 7769800StomsoftCommandObjectArgs::CommandOptions::GetDefinitions () 7869800Stomsoft{ 7969800Stomsoft return g_option_table; 8069800Stomsoft} 8169800Stomsoft 8298542SmckusickCommandObjectArgs::CommandObjectArgs (CommandInterpreter &interpreter) : 8369800Stomsoft CommandObjectParsed (interpreter, 8469800Stomsoft "args", 8569800Stomsoft "When stopped at the start of a function, reads function arguments of type (u?)int(8|16|32|64)_t, (void|char)*", 8669800Stomsoft "args"), 8798542Smckusick m_options (interpreter) 8898542Smckusick{ 8998542Smckusick} 9098542Smckusick 9198542SmckusickCommandObjectArgs::~CommandObjectArgs () 9298542Smckusick{ 9369800Stomsoft} 9469800Stomsoft 9569800StomsoftOptions * 9669800StomsoftCommandObjectArgs::GetOptions () 9769800Stomsoft{ 9869800Stomsoft return &m_options; 9969800Stomsoft} 10098542Smckusick 10169800Stomsoftbool 10298542SmckusickCommandObjectArgs::DoExecute (Args& args, CommandReturnObject &result) 10369800Stomsoft{ 10498542Smckusick ConstString target_triple; 10598542Smckusick 10698542Smckusick 10769800Stomsoft Process *process = m_exe_ctx.GetProcessPtr(); 10898542Smckusick if (!process) 10998542Smckusick { 110127798Sle result.AppendError ("Args found no process."); 111132832Sle result.SetStatus (eReturnStatusFailed); 112132832Sle return false; 113132832Sle } 114132832Sle 115132832Sle const ABI *abi = process->GetABI().get(); 116132832Sle if (!abi) 11798542Smckusick { 11898542Smckusick result.AppendError ("The current process has no ABI."); 119127798Sle result.SetStatus (eReturnStatusFailed); 120114936Sgrog return false; 12169800Stomsoft } 12269800Stomsoft 123114067Sschweikh const size_t num_args = args.GetArgumentCount (); 12469800Stomsoft size_t arg_index; 12569800Stomsoft 12669800Stomsoft if (!num_args) 12769800Stomsoft { 12898542Smckusick result.AppendError ("args requires at least one argument"); 12998542Smckusick result.SetStatus (eReturnStatusFailed); 13069800Stomsoft return false; 13169800Stomsoft } 13277885Stomsoft 13369800Stomsoft Thread *thread = m_exe_ctx.GetThreadPtr(); 13469800Stomsoft 13569800Stomsoft if (!thread) 13669800Stomsoft { 13777885Stomsoft result.AppendError ("args found no thread."); 13898542Smckusick result.SetStatus (eReturnStatusFailed); 13998542Smckusick return false; 14098542Smckusick } 14169800Stomsoft 14269926Stomsoft lldb::StackFrameSP thread_cur_frame = thread->GetSelectedFrame (); 14369800Stomsoft if (!thread_cur_frame) 14469800Stomsoft { 14569800Stomsoft result.AppendError ("The current thread has no current frame."); 14677885Stomsoft result.SetStatus (eReturnStatusFailed); 14777885Stomsoft return false; 14877885Stomsoft } 14969800Stomsoft 15077885Stomsoft ModuleSP thread_module_sp (thread_cur_frame->GetFrameCodeAddress ().GetModule()); 15198542Smckusick if (!thread_module_sp) 15298542Smckusick { 15398542Smckusick result.AppendError ("The PC has no associated module."); 15498542Smckusick result.SetStatus (eReturnStatusFailed); 15569800Stomsoft return false; 15677885Stomsoft } 15798542Smckusick 15898542Smckusick ClangASTContext &ast_context = thread_module_sp->GetClangASTContext(); 159114936Sgrog 16069800Stomsoft ValueList value_list; 16169800Stomsoft 16269800Stomsoft for (arg_index = 0; arg_index < num_args; ++arg_index) 163114067Sschweikh { 164114067Sschweikh const char *arg_type_cstr = args.GetArgumentAtIndex(arg_index); 165114067Sschweikh Value value; 16669800Stomsoft value.SetValueType(Value::eValueTypeScalar); 167114067Sschweikh ClangASTType clang_type; 168114067Sschweikh 169114067Sschweikh char *int_pos; 17069800Stomsoft if ((int_pos = strstr (const_cast<char*>(arg_type_cstr), "int"))) 17169800Stomsoft { 17269800Stomsoft Encoding encoding = eEncodingSint; 17369800Stomsoft 17477885Stomsoft int width = 0; 17569800Stomsoft 17669800Stomsoft if (int_pos > arg_type_cstr + 1) 17769800Stomsoft { 178203770Smckusick result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr); 179203770Smckusick result.SetStatus (eReturnStatusFailed); 18069800Stomsoft return false; 18169800Stomsoft } 18269800Stomsoft if (int_pos == arg_type_cstr + 1 && arg_type_cstr[0] != 'u') 18369800Stomsoft { 18469800Stomsoft result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr); 18569800Stomsoft result.SetStatus (eReturnStatusFailed); 18669800Stomsoft return false; 18769800Stomsoft } 18869800Stomsoft if (arg_type_cstr[0] == 'u') 18969800Stomsoft { 19069800Stomsoft encoding = eEncodingUint; 19169800Stomsoft } 19269800Stomsoft 19369800Stomsoft char *width_pos = int_pos + 3; 19469800Stomsoft 19569800Stomsoft if (!strcmp (width_pos, "8_t")) 19669800Stomsoft width = 8; 19769800Stomsoft else if (!strcmp (width_pos, "16_t")) 19869800Stomsoft width = 16; 19969800Stomsoft else if (!strcmp (width_pos, "32_t")) 20077885Stomsoft width = 32; 20169926Stomsoft else if (!strcmp (width_pos, "64_t")) 20269926Stomsoft width = 64; 20369926Stomsoft else 20469800Stomsoft { 20569800Stomsoft result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr); 20677885Stomsoft result.SetStatus (eReturnStatusFailed); 20777885Stomsoft return false; 20869800Stomsoft } 20969800Stomsoft 21069800Stomsoft clang_type = ast_context.GetBuiltinTypeForEncodingAndBitSize(encoding, width); 21169800Stomsoft 21269800Stomsoft if (!clang_type.IsValid()) 21369800Stomsoft { 21469800Stomsoft result.AppendErrorWithFormat ("Couldn't get Clang type for format %s (%s integer, width %d).\n", 21569800Stomsoft arg_type_cstr, 21669800Stomsoft (encoding == eEncodingSint ? "signed" : "unsigned"), 21769800Stomsoft width); 21877885Stomsoft 21977885Stomsoft result.SetStatus (eReturnStatusFailed); 22069926Stomsoft return false; 22169926Stomsoft } 22269926Stomsoft } 22369800Stomsoft else if (strchr (arg_type_cstr, '*')) 22469800Stomsoft { 22569800Stomsoft if (!strcmp (arg_type_cstr, "void*")) 22669800Stomsoft clang_type = ast_context.GetBasicType(eBasicTypeVoid).GetPointerType(); 22769800Stomsoft else if (!strcmp (arg_type_cstr, "char*")) 22869800Stomsoft clang_type = ast_context.GetCStringType (false); 22969800Stomsoft else 23069800Stomsoft { 23169800Stomsoft result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr); 23269800Stomsoft result.SetStatus (eReturnStatusFailed); 23369800Stomsoft return false; 234102231Strhodes } 23569800Stomsoft } 23698542Smckusick else 237127816Smux { 23869800Stomsoft result.AppendErrorWithFormat ("Invalid format: %s.\n", arg_type_cstr); 239127816Smux result.SetStatus (eReturnStatusFailed); 240127816Smux return false; 24198542Smckusick } 24298542Smckusick 24398542Smckusick value.SetClangType (clang_type); 24498542Smckusick value_list.PushValue(value); 24598542Smckusick } 24698542Smckusick 24769800Stomsoft if (!abi->GetArgumentValues (*thread, value_list)) 24869800Stomsoft { 24969800Stomsoft result.AppendError ("Couldn't get argument values"); 25069800Stomsoft result.SetStatus (eReturnStatusFailed); 25169800Stomsoft return false; 25269800Stomsoft } 25369800Stomsoft 25469800Stomsoft result.GetOutputStream ().Printf("Arguments : \n"); 25569800Stomsoft 25669800Stomsoft for (arg_index = 0; arg_index < num_args; ++arg_index) 25769800Stomsoft { 25869800Stomsoft result.GetOutputStream ().Printf ("%zu (%s): ", arg_index, args.GetArgumentAtIndex (arg_index)); 25969800Stomsoft value_list.GetValueAtIndex (arg_index)->Dump (&result.GetOutputStream ()); 26069800Stomsoft result.GetOutputStream ().Printf("\n"); 261174706Sdas } 262174706Sdas 26369800Stomsoft return result.Succeeded(); 26469800Stomsoft} 26569800Stomsoft 26669800StomsoftOptionDefinition 26769800StomsoftCommandObjectArgs::CommandOptions::g_option_table[] = 26869800Stomsoft{ 26969800Stomsoft { LLDB_OPT_SET_1, false, "debug", 'g', no_argument, NULL, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."}, 27069800Stomsoft { 0, false, NULL, 0, 0, NULL, 0, eArgTypeNone, NULL } 27169800Stomsoft}; 27269800Stomsoft 27369800Stomsoft