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", 37405fe67fSCaroline Tice "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.", 38405fe67fSCaroline Tice //"register read [<reg-name1> [<reg-name2> [...]]]", 39405fe67fSCaroline Tice NULL, 4030fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 4130fdc8d8SChris Lattner { 42405fe67fSCaroline Tice CommandArgumentEntry arg; 43405fe67fSCaroline Tice CommandArgumentData register_arg; 44405fe67fSCaroline Tice 45405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 46405fe67fSCaroline Tice register_arg.arg_type = eArgTypeRegisterName; 47405fe67fSCaroline Tice register_arg.arg_repetition = eArgRepeatStar; 48405fe67fSCaroline Tice 49405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 50405fe67fSCaroline Tice arg.push_back (register_arg); 51405fe67fSCaroline Tice 52405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 53405fe67fSCaroline 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 { 68*85e8b814SJim Ingham Stream &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.", 159405fe67fSCaroline Tice //"register write <reg-name> <value>", 160405fe67fSCaroline Tice NULL, 16130fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 16230fdc8d8SChris Lattner { 163405fe67fSCaroline Tice CommandArgumentEntry arg1; 164405fe67fSCaroline Tice CommandArgumentEntry arg2; 165405fe67fSCaroline Tice CommandArgumentData register_arg; 166405fe67fSCaroline Tice CommandArgumentData value_arg; 167405fe67fSCaroline Tice 168405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 169405fe67fSCaroline Tice register_arg.arg_type = eArgTypeRegisterName; 170405fe67fSCaroline Tice register_arg.arg_repetition = eArgRepeatPlain; 171405fe67fSCaroline Tice 172405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 173405fe67fSCaroline Tice arg1.push_back (register_arg); 174405fe67fSCaroline Tice 175405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 176405fe67fSCaroline Tice value_arg.arg_type = eArgTypeValue; 177405fe67fSCaroline Tice value_arg.arg_repetition = eArgRepeatPlain; 178405fe67fSCaroline Tice 179405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 180405fe67fSCaroline Tice arg2.push_back (value_arg); 181405fe67fSCaroline Tice 182405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 183405fe67fSCaroline Tice m_arguments.push_back (arg1); 184405fe67fSCaroline 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