130fdc8d8SChris Lattner //===-- CommandObjectRegister.cpp -------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1030fdc8d8SChris Lattner #include "CommandObjectRegister.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner // C Includes 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 1630fdc8d8SChris Lattner #include "lldb/Core/DataExtractor.h" 1730fdc8d8SChris Lattner #include "lldb/Core/Scalar.h" 186611103cSGreg Clayton #include "lldb/Core/Debugger.h" 196611103cSGreg Clayton #include "lldb/Interpreter/Args.h" 206611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 2130fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 22*eb0103f2SGreg Clayton #include "lldb/Interpreter/Options.h" 2330fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h" 2430fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 2530fdc8d8SChris Lattner 2630fdc8d8SChris Lattner using namespace lldb; 2730fdc8d8SChris Lattner using namespace lldb_private; 2830fdc8d8SChris Lattner 2930fdc8d8SChris Lattner //---------------------------------------------------------------------- 3030fdc8d8SChris Lattner // "register read" 3130fdc8d8SChris Lattner //---------------------------------------------------------------------- 3230fdc8d8SChris Lattner class CommandObjectRegisterRead : public CommandObject 3330fdc8d8SChris Lattner { 3430fdc8d8SChris Lattner public: 35a7015092SGreg Clayton CommandObjectRegisterRead (CommandInterpreter &interpreter) : 36a7015092SGreg Clayton CommandObject (interpreter, 37a7015092SGreg Clayton "register read", 38405fe67fSCaroline Tice "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.", 39405fe67fSCaroline Tice //"register read [<reg-name1> [<reg-name2> [...]]]", 40405fe67fSCaroline Tice NULL, 41*eb0103f2SGreg Clayton eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), 42*eb0103f2SGreg Clayton m_options (interpreter) 4330fdc8d8SChris Lattner { 44405fe67fSCaroline Tice CommandArgumentEntry arg; 45405fe67fSCaroline Tice CommandArgumentData register_arg; 46405fe67fSCaroline Tice 47405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 48405fe67fSCaroline Tice register_arg.arg_type = eArgTypeRegisterName; 49405fe67fSCaroline Tice register_arg.arg_repetition = eArgRepeatStar; 50405fe67fSCaroline Tice 51405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 52405fe67fSCaroline Tice arg.push_back (register_arg); 53405fe67fSCaroline Tice 54405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 55405fe67fSCaroline Tice m_arguments.push_back (arg); 5630fdc8d8SChris Lattner } 5730fdc8d8SChris Lattner 5830fdc8d8SChris Lattner virtual 5930fdc8d8SChris Lattner ~CommandObjectRegisterRead () 6030fdc8d8SChris Lattner { 6130fdc8d8SChris Lattner } 6230fdc8d8SChris Lattner 6332e0a750SGreg Clayton Options * 6432e0a750SGreg Clayton GetOptions () 6532e0a750SGreg Clayton { 6632e0a750SGreg Clayton return &m_options; 6732e0a750SGreg Clayton } 6832e0a750SGreg Clayton 6930fdc8d8SChris Lattner virtual bool 706611103cSGreg Clayton Execute 716611103cSGreg Clayton ( 726611103cSGreg Clayton Args& command, 736611103cSGreg Clayton CommandReturnObject &result 746611103cSGreg Clayton ) 7530fdc8d8SChris Lattner { 7685e8b814SJim Ingham Stream &output_stream = result.GetOutputStream(); 7730fdc8d8SChris Lattner DataExtractor reg_data; 78a7015092SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext()); 7930fdc8d8SChris Lattner RegisterContext *reg_context = exe_ctx.GetRegisterContext (); 8030fdc8d8SChris Lattner 8130fdc8d8SChris Lattner if (reg_context) 8230fdc8d8SChris Lattner { 8330fdc8d8SChris Lattner const RegisterInfo *reg_info = NULL; 8430fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 8530fdc8d8SChris Lattner { 8630fdc8d8SChris Lattner uint32_t set_idx; 8730fdc8d8SChris Lattner const uint32_t num_register_sets = reg_context->GetRegisterSetCount(); 8830fdc8d8SChris Lattner for (set_idx = 0; set_idx < num_register_sets; ++set_idx) 8930fdc8d8SChris Lattner { 9030fdc8d8SChris Lattner uint32_t unavailable_count = 0; 9130fdc8d8SChris Lattner const RegisterSet * const reg_set = reg_context->GetRegisterSet(set_idx); 9230fdc8d8SChris Lattner output_stream.Printf ("%s:\n", reg_set->name); 9330fdc8d8SChris Lattner output_stream.IndentMore (); 9430fdc8d8SChris Lattner const uint32_t num_registers = reg_set->num_registers; 9530fdc8d8SChris Lattner for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) 9630fdc8d8SChris Lattner { 9730fdc8d8SChris Lattner uint32_t reg = reg_set->registers[reg_idx]; 9830fdc8d8SChris Lattner reg_info = reg_context->GetRegisterInfoAtIndex(reg); 9930fdc8d8SChris Lattner if (reg_context->ReadRegisterBytes(reg, reg_data)) 10030fdc8d8SChris Lattner { 10130fdc8d8SChris Lattner output_stream.Indent (); 10230fdc8d8SChris Lattner output_stream.Printf ("%-12s = ", reg_info ? reg_info->name : "<INVALID REGINFO>"); 10330fdc8d8SChris Lattner reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); 10430fdc8d8SChris Lattner output_stream.EOL(); 10530fdc8d8SChris Lattner } 10630fdc8d8SChris Lattner else 10730fdc8d8SChris Lattner { 10830fdc8d8SChris Lattner ++unavailable_count; 10930fdc8d8SChris Lattner } 11030fdc8d8SChris Lattner } 11130fdc8d8SChris Lattner if (unavailable_count) 11230fdc8d8SChris Lattner { 11330fdc8d8SChris Lattner output_stream.Indent (); 11430fdc8d8SChris Lattner output_stream.Printf("%u registers were unavailable.\n", unavailable_count); 11530fdc8d8SChris Lattner } 11630fdc8d8SChris Lattner output_stream.IndentLess (); 11730fdc8d8SChris Lattner output_stream.EOL(); 11830fdc8d8SChris Lattner } 11930fdc8d8SChris Lattner } 12030fdc8d8SChris Lattner else 12130fdc8d8SChris Lattner { 12230fdc8d8SChris Lattner const char *arg_cstr; 12330fdc8d8SChris Lattner for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 12430fdc8d8SChris Lattner { 12530fdc8d8SChris Lattner reg_info = reg_context->GetRegisterInfoByName(arg_cstr); 12630fdc8d8SChris Lattner 12730fdc8d8SChris Lattner if (reg_info) 12830fdc8d8SChris Lattner { 12930fdc8d8SChris Lattner output_stream.Printf("%-12s = ", reg_info->name); 130fbcb7f2cSJason Molenda if (reg_context->ReadRegisterBytes(reg_info->kinds[eRegisterKindLLDB], reg_data)) 13130fdc8d8SChris Lattner { 13230fdc8d8SChris Lattner reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); 13330fdc8d8SChris Lattner } 13430fdc8d8SChris Lattner else 13530fdc8d8SChris Lattner { 13630fdc8d8SChris Lattner output_stream.PutCString ("error: unavailable"); 13730fdc8d8SChris Lattner } 13830fdc8d8SChris Lattner output_stream.EOL(); 13930fdc8d8SChris Lattner } 14030fdc8d8SChris Lattner else 14130fdc8d8SChris Lattner { 14230fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); 14330fdc8d8SChris Lattner } 14430fdc8d8SChris Lattner } 14530fdc8d8SChris Lattner } 14630fdc8d8SChris Lattner } 14730fdc8d8SChris Lattner else 14830fdc8d8SChris Lattner { 14930fdc8d8SChris Lattner result.AppendError ("no current frame"); 15030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 15130fdc8d8SChris Lattner } 15230fdc8d8SChris Lattner return result.Succeeded(); 15330fdc8d8SChris Lattner } 15432e0a750SGreg Clayton 15532e0a750SGreg Clayton protected: 15632e0a750SGreg Clayton class CommandOptions : public Options 15732e0a750SGreg Clayton { 15832e0a750SGreg Clayton public: 159*eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 160*eb0103f2SGreg Clayton Options(interpreter) 16132e0a750SGreg Clayton { 16232e0a750SGreg Clayton ResetOptionValues(); 16332e0a750SGreg Clayton } 16432e0a750SGreg Clayton 16532e0a750SGreg Clayton virtual 16632e0a750SGreg Clayton ~CommandOptions () 16732e0a750SGreg Clayton { 16832e0a750SGreg Clayton } 16932e0a750SGreg Clayton 17032e0a750SGreg Clayton virtual Error 17132e0a750SGreg Clayton SetOptionValue (int option_idx, const char *option_arg) 17232e0a750SGreg Clayton { 17332e0a750SGreg Clayton Error error; 17432e0a750SGreg Clayton char short_option = (char) m_getopt_table[option_idx].val; 17532e0a750SGreg Clayton switch (short_option) 17632e0a750SGreg Clayton { 17732e0a750SGreg Clayton case 'f': 17832e0a750SGreg Clayton error = Args::StringToFormat (option_arg, m_format); 17932e0a750SGreg Clayton break; 18032e0a750SGreg Clayton 18132e0a750SGreg Clayton default: 18232e0a750SGreg Clayton error.SetErrorStringWithFormat("Unrecognized short option '%c'\n", short_option); 18332e0a750SGreg Clayton break; 18432e0a750SGreg Clayton } 18532e0a750SGreg Clayton return error; 18632e0a750SGreg Clayton } 18732e0a750SGreg Clayton 18832e0a750SGreg Clayton void 18932e0a750SGreg Clayton ResetOptionValues () 19032e0a750SGreg Clayton { 19132e0a750SGreg Clayton m_format = eFormatBytes; 19232e0a750SGreg Clayton } 19332e0a750SGreg Clayton 19432e0a750SGreg Clayton const OptionDefinition* 19532e0a750SGreg Clayton GetDefinitions () 19632e0a750SGreg Clayton { 19732e0a750SGreg Clayton return g_option_table; 19832e0a750SGreg Clayton } 19932e0a750SGreg Clayton 20032e0a750SGreg Clayton // Options table: Required for subclasses of Options. 20132e0a750SGreg Clayton 20232e0a750SGreg Clayton static OptionDefinition g_option_table[]; 20332e0a750SGreg Clayton 20432e0a750SGreg Clayton // Instance variables to hold the values for command options. 20532e0a750SGreg Clayton lldb::Format m_format; 20630fdc8d8SChris Lattner }; 20730fdc8d8SChris Lattner 20832e0a750SGreg Clayton CommandOptions m_options; 20932e0a750SGreg Clayton }; 21032e0a750SGreg Clayton 21132e0a750SGreg Clayton OptionDefinition 21232e0a750SGreg Clayton CommandObjectRegisterRead::CommandOptions::g_option_table[] = 21332e0a750SGreg Clayton { 21432e0a750SGreg Clayton //{ LLDB_OPT_SET_ALL, false, "language", 'l', required_argument, NULL, 0, "[c|c++|objc|objc++]", "Sets the language to use when parsing the expression."}, 21532e0a750SGreg Clayton //{ LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]", "Specify the format that the expression output should use."}, 21632e0a750SGreg Clayton { LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, eArgTypeExprFormat, "Specify the format that the expression output should use."}, 21732e0a750SGreg Clayton { LLDB_OPT_SET_2, false, "object-description", 'o', no_argument, NULL, 0, eArgTypeNone, "Print the object description of the value resulting from the expression."}, 21832e0a750SGreg Clayton { LLDB_OPT_SET_ALL, false, "unwind-on-error", 'u', required_argument, NULL, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, breakpoint hit or signal."}, 21932e0a750SGreg Clayton { LLDB_OPT_SET_ALL, false, "debug", 'g', no_argument, NULL, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."}, 22032e0a750SGreg Clayton { LLDB_OPT_SET_ALL, false, "use-ir", 'i', no_argument, NULL, 0, eArgTypeNone, "[Temporary] Instructs the expression evaluator to use IR instead of ASTs."}, 22132e0a750SGreg Clayton { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL } 22232e0a750SGreg Clayton }; 22332e0a750SGreg Clayton 22432e0a750SGreg Clayton 22530fdc8d8SChris Lattner 22630fdc8d8SChris Lattner //---------------------------------------------------------------------- 22730fdc8d8SChris Lattner // "register write" 22830fdc8d8SChris Lattner //---------------------------------------------------------------------- 22930fdc8d8SChris Lattner class CommandObjectRegisterWrite : public CommandObject 23030fdc8d8SChris Lattner { 23130fdc8d8SChris Lattner public: 232a7015092SGreg Clayton CommandObjectRegisterWrite (CommandInterpreter &interpreter) : 233a7015092SGreg Clayton CommandObject (interpreter, 234a7015092SGreg Clayton "register write", 23530fdc8d8SChris Lattner "Modify a single register value.", 236405fe67fSCaroline Tice //"register write <reg-name> <value>", 237405fe67fSCaroline Tice NULL, 23830fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 23930fdc8d8SChris Lattner { 240405fe67fSCaroline Tice CommandArgumentEntry arg1; 241405fe67fSCaroline Tice CommandArgumentEntry arg2; 242405fe67fSCaroline Tice CommandArgumentData register_arg; 243405fe67fSCaroline Tice CommandArgumentData value_arg; 244405fe67fSCaroline Tice 245405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 246405fe67fSCaroline Tice register_arg.arg_type = eArgTypeRegisterName; 247405fe67fSCaroline Tice register_arg.arg_repetition = eArgRepeatPlain; 248405fe67fSCaroline Tice 249405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 250405fe67fSCaroline Tice arg1.push_back (register_arg); 251405fe67fSCaroline Tice 252405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 253405fe67fSCaroline Tice value_arg.arg_type = eArgTypeValue; 254405fe67fSCaroline Tice value_arg.arg_repetition = eArgRepeatPlain; 255405fe67fSCaroline Tice 256405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 257405fe67fSCaroline Tice arg2.push_back (value_arg); 258405fe67fSCaroline Tice 259405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 260405fe67fSCaroline Tice m_arguments.push_back (arg1); 261405fe67fSCaroline Tice m_arguments.push_back (arg2); 26230fdc8d8SChris Lattner } 26330fdc8d8SChris Lattner 26430fdc8d8SChris Lattner virtual 26530fdc8d8SChris Lattner ~CommandObjectRegisterWrite () 26630fdc8d8SChris Lattner { 26730fdc8d8SChris Lattner } 26830fdc8d8SChris Lattner 26930fdc8d8SChris Lattner virtual bool 2706611103cSGreg Clayton Execute 2716611103cSGreg Clayton ( 2726611103cSGreg Clayton Args& command, 2736611103cSGreg Clayton CommandReturnObject &result 2746611103cSGreg Clayton ) 27530fdc8d8SChris Lattner { 27630fdc8d8SChris Lattner DataExtractor reg_data; 277a7015092SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext()); 27830fdc8d8SChris Lattner RegisterContext *reg_context = exe_ctx.GetRegisterContext (); 27930fdc8d8SChris Lattner 28030fdc8d8SChris Lattner if (reg_context) 28130fdc8d8SChris Lattner { 28230fdc8d8SChris Lattner if (command.GetArgumentCount() != 2) 28330fdc8d8SChris Lattner { 28430fdc8d8SChris Lattner result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>"); 28530fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 28630fdc8d8SChris Lattner } 28730fdc8d8SChris Lattner else 28830fdc8d8SChris Lattner { 28930fdc8d8SChris Lattner const char *reg_name = command.GetArgumentAtIndex(0); 29030fdc8d8SChris Lattner const char *value_str = command.GetArgumentAtIndex(1); 29130fdc8d8SChris Lattner const RegisterInfo *reg_info = reg_context->GetRegisterInfoByName(reg_name); 29230fdc8d8SChris Lattner 29330fdc8d8SChris Lattner if (reg_info) 29430fdc8d8SChris Lattner { 29530fdc8d8SChris Lattner Scalar scalar; 29630fdc8d8SChris Lattner Error error(scalar.SetValueFromCString (value_str, reg_info->encoding, reg_info->byte_size)); 29730fdc8d8SChris Lattner if (error.Success()) 29830fdc8d8SChris Lattner { 299fbcb7f2cSJason Molenda if (reg_context->WriteRegisterValue(reg_info->kinds[eRegisterKindLLDB], scalar)) 30030fdc8d8SChris Lattner { 30130fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 30230fdc8d8SChris Lattner return true; 30330fdc8d8SChris Lattner } 30430fdc8d8SChris Lattner } 30530fdc8d8SChris Lattner else 30630fdc8d8SChris Lattner { 30730fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n", 30830fdc8d8SChris Lattner reg_name, 30930fdc8d8SChris Lattner value_str, 31030fdc8d8SChris Lattner error.AsCString()); 31130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 31230fdc8d8SChris Lattner } 31330fdc8d8SChris Lattner } 31430fdc8d8SChris Lattner else 31530fdc8d8SChris Lattner { 31630fdc8d8SChris Lattner result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name); 31730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 31830fdc8d8SChris Lattner } 31930fdc8d8SChris Lattner } 32030fdc8d8SChris Lattner } 32130fdc8d8SChris Lattner else 32230fdc8d8SChris Lattner { 32330fdc8d8SChris Lattner result.AppendError ("no current frame"); 32430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 32530fdc8d8SChris Lattner } 32630fdc8d8SChris Lattner return result.Succeeded(); 32730fdc8d8SChris Lattner } 32830fdc8d8SChris Lattner }; 32930fdc8d8SChris Lattner 33030fdc8d8SChris Lattner 33130fdc8d8SChris Lattner //---------------------------------------------------------------------- 33230fdc8d8SChris Lattner // CommandObjectRegister constructor 33330fdc8d8SChris Lattner //---------------------------------------------------------------------- 3346611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) : 335a7015092SGreg Clayton CommandObjectMultiword (interpreter, 336a7015092SGreg Clayton "register", 3373f4c09c1SCaroline Tice "A set of commands to access thread registers.", 33830fdc8d8SChris Lattner "register [read|write] ...") 33930fdc8d8SChris Lattner { 340a7015092SGreg Clayton LoadSubCommand ("read", CommandObjectSP (new CommandObjectRegisterRead (interpreter))); 341a7015092SGreg Clayton LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter))); 34230fdc8d8SChris Lattner } 34330fdc8d8SChris Lattner 34430fdc8d8SChris Lattner 34530fdc8d8SChris Lattner //---------------------------------------------------------------------- 34630fdc8d8SChris Lattner // Destructor 34730fdc8d8SChris Lattner //---------------------------------------------------------------------- 34830fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister() 34930fdc8d8SChris Lattner { 35030fdc8d8SChris Lattner } 351