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" 2230fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h" 2330fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 2430fdc8d8SChris Lattner 2530fdc8d8SChris Lattner using namespace lldb; 2630fdc8d8SChris Lattner using namespace lldb_private; 2730fdc8d8SChris Lattner 2830fdc8d8SChris Lattner //---------------------------------------------------------------------- 2930fdc8d8SChris Lattner // "register read" 3030fdc8d8SChris Lattner //---------------------------------------------------------------------- 3130fdc8d8SChris Lattner class CommandObjectRegisterRead : public CommandObject 3230fdc8d8SChris Lattner { 3330fdc8d8SChris Lattner public: 34a7015092SGreg Clayton CommandObjectRegisterRead (CommandInterpreter &interpreter) : 35a7015092SGreg Clayton CommandObject (interpreter, 36a7015092SGreg Clayton "register read", 37*405fe67fSCaroline Tice "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.", 38*405fe67fSCaroline Tice //"register read [<reg-name1> [<reg-name2> [...]]]", 39*405fe67fSCaroline Tice NULL, 4030fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 4130fdc8d8SChris Lattner { 42*405fe67fSCaroline Tice CommandArgumentEntry arg; 43*405fe67fSCaroline Tice CommandArgumentData register_arg; 44*405fe67fSCaroline Tice 45*405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 46*405fe67fSCaroline Tice register_arg.arg_type = eArgTypeRegisterName; 47*405fe67fSCaroline Tice register_arg.arg_repetition = eArgRepeatStar; 48*405fe67fSCaroline Tice 49*405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 50*405fe67fSCaroline Tice arg.push_back (register_arg); 51*405fe67fSCaroline Tice 52*405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 53*405fe67fSCaroline Tice m_arguments.push_back (arg); 5430fdc8d8SChris Lattner } 5530fdc8d8SChris Lattner 5630fdc8d8SChris Lattner virtual 5730fdc8d8SChris Lattner ~CommandObjectRegisterRead () 5830fdc8d8SChris Lattner { 5930fdc8d8SChris Lattner } 6030fdc8d8SChris Lattner 6130fdc8d8SChris Lattner virtual bool 626611103cSGreg Clayton Execute 636611103cSGreg Clayton ( 646611103cSGreg Clayton Args& command, 656611103cSGreg Clayton CommandReturnObject &result 666611103cSGreg Clayton ) 6730fdc8d8SChris Lattner { 6830fdc8d8SChris Lattner StreamString &output_stream = result.GetOutputStream(); 6930fdc8d8SChris Lattner DataExtractor reg_data; 70a7015092SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext()); 7130fdc8d8SChris Lattner RegisterContext *reg_context = exe_ctx.GetRegisterContext (); 7230fdc8d8SChris Lattner 7330fdc8d8SChris Lattner if (reg_context) 7430fdc8d8SChris Lattner { 7530fdc8d8SChris Lattner const RegisterInfo *reg_info = NULL; 7630fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 7730fdc8d8SChris Lattner { 7830fdc8d8SChris Lattner uint32_t set_idx; 7930fdc8d8SChris Lattner const uint32_t num_register_sets = reg_context->GetRegisterSetCount(); 8030fdc8d8SChris Lattner for (set_idx = 0; set_idx < num_register_sets; ++set_idx) 8130fdc8d8SChris Lattner { 8230fdc8d8SChris Lattner uint32_t unavailable_count = 0; 8330fdc8d8SChris Lattner const RegisterSet * const reg_set = reg_context->GetRegisterSet(set_idx); 8430fdc8d8SChris Lattner output_stream.Printf ("%s:\n", reg_set->name); 8530fdc8d8SChris Lattner output_stream.IndentMore (); 8630fdc8d8SChris Lattner const uint32_t num_registers = reg_set->num_registers; 8730fdc8d8SChris Lattner for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) 8830fdc8d8SChris Lattner { 8930fdc8d8SChris Lattner uint32_t reg = reg_set->registers[reg_idx]; 9030fdc8d8SChris Lattner reg_info = reg_context->GetRegisterInfoAtIndex(reg); 9130fdc8d8SChris Lattner if (reg_context->ReadRegisterBytes(reg, reg_data)) 9230fdc8d8SChris Lattner { 9330fdc8d8SChris Lattner output_stream.Indent (); 9430fdc8d8SChris Lattner output_stream.Printf ("%-12s = ", reg_info ? reg_info->name : "<INVALID REGINFO>"); 9530fdc8d8SChris Lattner reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); 9630fdc8d8SChris Lattner output_stream.EOL(); 9730fdc8d8SChris Lattner } 9830fdc8d8SChris Lattner else 9930fdc8d8SChris Lattner { 10030fdc8d8SChris Lattner ++unavailable_count; 10130fdc8d8SChris Lattner } 10230fdc8d8SChris Lattner } 10330fdc8d8SChris Lattner if (unavailable_count) 10430fdc8d8SChris Lattner { 10530fdc8d8SChris Lattner output_stream.Indent (); 10630fdc8d8SChris Lattner output_stream.Printf("%u registers were unavailable.\n", unavailable_count); 10730fdc8d8SChris Lattner } 10830fdc8d8SChris Lattner output_stream.IndentLess (); 10930fdc8d8SChris Lattner output_stream.EOL(); 11030fdc8d8SChris Lattner } 11130fdc8d8SChris Lattner } 11230fdc8d8SChris Lattner else 11330fdc8d8SChris Lattner { 11430fdc8d8SChris Lattner const char *arg_cstr; 11530fdc8d8SChris Lattner for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 11630fdc8d8SChris Lattner { 11730fdc8d8SChris Lattner reg_info = reg_context->GetRegisterInfoByName(arg_cstr); 11830fdc8d8SChris Lattner 11930fdc8d8SChris Lattner if (reg_info) 12030fdc8d8SChris Lattner { 12130fdc8d8SChris Lattner output_stream.Printf("%-12s = ", reg_info->name); 122fbcb7f2cSJason Molenda if (reg_context->ReadRegisterBytes(reg_info->kinds[eRegisterKindLLDB], reg_data)) 12330fdc8d8SChris Lattner { 12430fdc8d8SChris Lattner reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); 12530fdc8d8SChris Lattner } 12630fdc8d8SChris Lattner else 12730fdc8d8SChris Lattner { 12830fdc8d8SChris Lattner output_stream.PutCString ("error: unavailable"); 12930fdc8d8SChris Lattner } 13030fdc8d8SChris Lattner output_stream.EOL(); 13130fdc8d8SChris Lattner } 13230fdc8d8SChris Lattner else 13330fdc8d8SChris Lattner { 13430fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); 13530fdc8d8SChris Lattner } 13630fdc8d8SChris Lattner } 13730fdc8d8SChris Lattner } 13830fdc8d8SChris Lattner } 13930fdc8d8SChris Lattner else 14030fdc8d8SChris Lattner { 14130fdc8d8SChris Lattner result.AppendError ("no current frame"); 14230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 14330fdc8d8SChris Lattner } 14430fdc8d8SChris Lattner return result.Succeeded(); 14530fdc8d8SChris Lattner } 14630fdc8d8SChris Lattner }; 14730fdc8d8SChris Lattner 14830fdc8d8SChris Lattner 14930fdc8d8SChris Lattner //---------------------------------------------------------------------- 15030fdc8d8SChris Lattner // "register write" 15130fdc8d8SChris Lattner //---------------------------------------------------------------------- 15230fdc8d8SChris Lattner class CommandObjectRegisterWrite : public CommandObject 15330fdc8d8SChris Lattner { 15430fdc8d8SChris Lattner public: 155a7015092SGreg Clayton CommandObjectRegisterWrite (CommandInterpreter &interpreter) : 156a7015092SGreg Clayton CommandObject (interpreter, 157a7015092SGreg Clayton "register write", 15830fdc8d8SChris Lattner "Modify a single register value.", 159*405fe67fSCaroline Tice //"register write <reg-name> <value>", 160*405fe67fSCaroline Tice NULL, 16130fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 16230fdc8d8SChris Lattner { 163*405fe67fSCaroline Tice CommandArgumentEntry arg1; 164*405fe67fSCaroline Tice CommandArgumentEntry arg2; 165*405fe67fSCaroline Tice CommandArgumentData register_arg; 166*405fe67fSCaroline Tice CommandArgumentData value_arg; 167*405fe67fSCaroline Tice 168*405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 169*405fe67fSCaroline Tice register_arg.arg_type = eArgTypeRegisterName; 170*405fe67fSCaroline Tice register_arg.arg_repetition = eArgRepeatPlain; 171*405fe67fSCaroline Tice 172*405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 173*405fe67fSCaroline Tice arg1.push_back (register_arg); 174*405fe67fSCaroline Tice 175*405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 176*405fe67fSCaroline Tice value_arg.arg_type = eArgTypeValue; 177*405fe67fSCaroline Tice value_arg.arg_repetition = eArgRepeatPlain; 178*405fe67fSCaroline Tice 179*405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 180*405fe67fSCaroline Tice arg2.push_back (value_arg); 181*405fe67fSCaroline Tice 182*405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 183*405fe67fSCaroline Tice m_arguments.push_back (arg1); 184*405fe67fSCaroline Tice m_arguments.push_back (arg2); 18530fdc8d8SChris Lattner } 18630fdc8d8SChris Lattner 18730fdc8d8SChris Lattner virtual 18830fdc8d8SChris Lattner ~CommandObjectRegisterWrite () 18930fdc8d8SChris Lattner { 19030fdc8d8SChris Lattner } 19130fdc8d8SChris Lattner 19230fdc8d8SChris Lattner virtual bool 1936611103cSGreg Clayton Execute 1946611103cSGreg Clayton ( 1956611103cSGreg Clayton Args& command, 1966611103cSGreg Clayton CommandReturnObject &result 1976611103cSGreg Clayton ) 19830fdc8d8SChris Lattner { 19930fdc8d8SChris Lattner DataExtractor reg_data; 200a7015092SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext()); 20130fdc8d8SChris Lattner RegisterContext *reg_context = exe_ctx.GetRegisterContext (); 20230fdc8d8SChris Lattner 20330fdc8d8SChris Lattner if (reg_context) 20430fdc8d8SChris Lattner { 20530fdc8d8SChris Lattner if (command.GetArgumentCount() != 2) 20630fdc8d8SChris Lattner { 20730fdc8d8SChris Lattner result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>"); 20830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 20930fdc8d8SChris Lattner } 21030fdc8d8SChris Lattner else 21130fdc8d8SChris Lattner { 21230fdc8d8SChris Lattner const char *reg_name = command.GetArgumentAtIndex(0); 21330fdc8d8SChris Lattner const char *value_str = command.GetArgumentAtIndex(1); 21430fdc8d8SChris Lattner const RegisterInfo *reg_info = reg_context->GetRegisterInfoByName(reg_name); 21530fdc8d8SChris Lattner 21630fdc8d8SChris Lattner if (reg_info) 21730fdc8d8SChris Lattner { 21830fdc8d8SChris Lattner Scalar scalar; 21930fdc8d8SChris Lattner Error error(scalar.SetValueFromCString (value_str, reg_info->encoding, reg_info->byte_size)); 22030fdc8d8SChris Lattner if (error.Success()) 22130fdc8d8SChris Lattner { 222fbcb7f2cSJason Molenda if (reg_context->WriteRegisterValue(reg_info->kinds[eRegisterKindLLDB], scalar)) 22330fdc8d8SChris Lattner { 22430fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 22530fdc8d8SChris Lattner return true; 22630fdc8d8SChris Lattner } 22730fdc8d8SChris Lattner } 22830fdc8d8SChris Lattner else 22930fdc8d8SChris Lattner { 23030fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n", 23130fdc8d8SChris Lattner reg_name, 23230fdc8d8SChris Lattner value_str, 23330fdc8d8SChris Lattner error.AsCString()); 23430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 23530fdc8d8SChris Lattner } 23630fdc8d8SChris Lattner } 23730fdc8d8SChris Lattner else 23830fdc8d8SChris Lattner { 23930fdc8d8SChris Lattner result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name); 24030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 24130fdc8d8SChris Lattner } 24230fdc8d8SChris Lattner } 24330fdc8d8SChris Lattner } 24430fdc8d8SChris Lattner else 24530fdc8d8SChris Lattner { 24630fdc8d8SChris Lattner result.AppendError ("no current frame"); 24730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 24830fdc8d8SChris Lattner } 24930fdc8d8SChris Lattner return result.Succeeded(); 25030fdc8d8SChris Lattner } 25130fdc8d8SChris Lattner }; 25230fdc8d8SChris Lattner 25330fdc8d8SChris Lattner 25430fdc8d8SChris Lattner //---------------------------------------------------------------------- 25530fdc8d8SChris Lattner // CommandObjectRegister constructor 25630fdc8d8SChris Lattner //---------------------------------------------------------------------- 2576611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) : 258a7015092SGreg Clayton CommandObjectMultiword (interpreter, 259a7015092SGreg Clayton "register", 2603f4c09c1SCaroline Tice "A set of commands to access thread registers.", 26130fdc8d8SChris Lattner "register [read|write] ...") 26230fdc8d8SChris Lattner { 263a7015092SGreg Clayton LoadSubCommand ("read", CommandObjectSP (new CommandObjectRegisterRead (interpreter))); 264a7015092SGreg Clayton LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter))); 26530fdc8d8SChris Lattner } 26630fdc8d8SChris Lattner 26730fdc8d8SChris Lattner 26830fdc8d8SChris Lattner //---------------------------------------------------------------------- 26930fdc8d8SChris Lattner // Destructor 27030fdc8d8SChris Lattner //---------------------------------------------------------------------- 27130fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister() 27230fdc8d8SChris Lattner { 27330fdc8d8SChris Lattner } 274