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: 3430fdc8d8SChris Lattner CommandObjectRegisterRead () : 3530fdc8d8SChris Lattner CommandObject ("register read", 3630fdc8d8SChris Lattner "Dump the one or more register values from the current frame.", 3730fdc8d8SChris Lattner "register read [<reg-name1> [<reg-name2> [...]]]", 3830fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 3930fdc8d8SChris Lattner { 4030fdc8d8SChris Lattner } 4130fdc8d8SChris Lattner 4230fdc8d8SChris Lattner virtual 4330fdc8d8SChris Lattner ~CommandObjectRegisterRead () 4430fdc8d8SChris Lattner { 4530fdc8d8SChris Lattner } 4630fdc8d8SChris Lattner 4730fdc8d8SChris Lattner virtual bool 486611103cSGreg Clayton Execute 496611103cSGreg Clayton ( 506611103cSGreg Clayton CommandInterpreter &interpreter, 516611103cSGreg Clayton Args& command, 526611103cSGreg Clayton CommandReturnObject &result 536611103cSGreg Clayton ) 5430fdc8d8SChris Lattner { 5530fdc8d8SChris Lattner StreamString &output_stream = result.GetOutputStream(); 5630fdc8d8SChris Lattner DataExtractor reg_data; 576611103cSGreg Clayton ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext()); 5830fdc8d8SChris Lattner RegisterContext *reg_context = exe_ctx.GetRegisterContext (); 5930fdc8d8SChris Lattner 6030fdc8d8SChris Lattner if (reg_context) 6130fdc8d8SChris Lattner { 6230fdc8d8SChris Lattner const RegisterInfo *reg_info = NULL; 6330fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 6430fdc8d8SChris Lattner { 6530fdc8d8SChris Lattner uint32_t set_idx; 6630fdc8d8SChris Lattner const uint32_t num_register_sets = reg_context->GetRegisterSetCount(); 6730fdc8d8SChris Lattner for (set_idx = 0; set_idx < num_register_sets; ++set_idx) 6830fdc8d8SChris Lattner { 6930fdc8d8SChris Lattner uint32_t unavailable_count = 0; 7030fdc8d8SChris Lattner const RegisterSet * const reg_set = reg_context->GetRegisterSet(set_idx); 7130fdc8d8SChris Lattner output_stream.Printf ("%s:\n", reg_set->name); 7230fdc8d8SChris Lattner output_stream.IndentMore (); 7330fdc8d8SChris Lattner const uint32_t num_registers = reg_set->num_registers; 7430fdc8d8SChris Lattner for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) 7530fdc8d8SChris Lattner { 7630fdc8d8SChris Lattner uint32_t reg = reg_set->registers[reg_idx]; 7730fdc8d8SChris Lattner reg_info = reg_context->GetRegisterInfoAtIndex(reg); 7830fdc8d8SChris Lattner if (reg_context->ReadRegisterBytes(reg, reg_data)) 7930fdc8d8SChris Lattner { 8030fdc8d8SChris Lattner output_stream.Indent (); 8130fdc8d8SChris Lattner output_stream.Printf ("%-12s = ", reg_info ? reg_info->name : "<INVALID REGINFO>"); 8230fdc8d8SChris Lattner reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); 8330fdc8d8SChris Lattner output_stream.EOL(); 8430fdc8d8SChris Lattner } 8530fdc8d8SChris Lattner else 8630fdc8d8SChris Lattner { 8730fdc8d8SChris Lattner ++unavailable_count; 8830fdc8d8SChris Lattner } 8930fdc8d8SChris Lattner } 9030fdc8d8SChris Lattner if (unavailable_count) 9130fdc8d8SChris Lattner { 9230fdc8d8SChris Lattner output_stream.Indent (); 9330fdc8d8SChris Lattner output_stream.Printf("%u registers were unavailable.\n", unavailable_count); 9430fdc8d8SChris Lattner } 9530fdc8d8SChris Lattner output_stream.IndentLess (); 9630fdc8d8SChris Lattner output_stream.EOL(); 9730fdc8d8SChris Lattner } 9830fdc8d8SChris Lattner } 9930fdc8d8SChris Lattner else 10030fdc8d8SChris Lattner { 10130fdc8d8SChris Lattner const char *arg_cstr; 10230fdc8d8SChris Lattner for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 10330fdc8d8SChris Lattner { 10430fdc8d8SChris Lattner reg_info = reg_context->GetRegisterInfoByName(arg_cstr); 10530fdc8d8SChris Lattner 10630fdc8d8SChris Lattner if (reg_info) 10730fdc8d8SChris Lattner { 10830fdc8d8SChris Lattner output_stream.Printf("%-12s = ", reg_info->name); 10930fdc8d8SChris Lattner if (reg_context->ReadRegisterBytes(reg_info->reg, reg_data)) 11030fdc8d8SChris Lattner { 11130fdc8d8SChris Lattner reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); 11230fdc8d8SChris Lattner } 11330fdc8d8SChris Lattner else 11430fdc8d8SChris Lattner { 11530fdc8d8SChris Lattner output_stream.PutCString ("error: unavailable"); 11630fdc8d8SChris Lattner } 11730fdc8d8SChris Lattner output_stream.EOL(); 11830fdc8d8SChris Lattner } 11930fdc8d8SChris Lattner else 12030fdc8d8SChris Lattner { 12130fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); 12230fdc8d8SChris Lattner } 12330fdc8d8SChris Lattner } 12430fdc8d8SChris Lattner } 12530fdc8d8SChris Lattner } 12630fdc8d8SChris Lattner else 12730fdc8d8SChris Lattner { 12830fdc8d8SChris Lattner result.AppendError ("no current frame"); 12930fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 13030fdc8d8SChris Lattner } 13130fdc8d8SChris Lattner return result.Succeeded(); 13230fdc8d8SChris Lattner } 13330fdc8d8SChris Lattner }; 13430fdc8d8SChris Lattner 13530fdc8d8SChris Lattner 13630fdc8d8SChris Lattner //---------------------------------------------------------------------- 13730fdc8d8SChris Lattner // "register write" 13830fdc8d8SChris Lattner //---------------------------------------------------------------------- 13930fdc8d8SChris Lattner class CommandObjectRegisterWrite : public CommandObject 14030fdc8d8SChris Lattner { 14130fdc8d8SChris Lattner public: 14230fdc8d8SChris Lattner CommandObjectRegisterWrite () : 14330fdc8d8SChris Lattner CommandObject ("register write", 14430fdc8d8SChris Lattner "Modify a single register value.", 14530fdc8d8SChris Lattner "register write <reg-name> <value>", 14630fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 14730fdc8d8SChris Lattner { 14830fdc8d8SChris Lattner } 14930fdc8d8SChris Lattner 15030fdc8d8SChris Lattner virtual 15130fdc8d8SChris Lattner ~CommandObjectRegisterWrite () 15230fdc8d8SChris Lattner { 15330fdc8d8SChris Lattner } 15430fdc8d8SChris Lattner 15530fdc8d8SChris Lattner virtual bool 1566611103cSGreg Clayton Execute 1576611103cSGreg Clayton ( 1586611103cSGreg Clayton CommandInterpreter &interpreter, 1596611103cSGreg Clayton Args& command, 1606611103cSGreg Clayton CommandReturnObject &result 1616611103cSGreg Clayton ) 16230fdc8d8SChris Lattner { 16330fdc8d8SChris Lattner DataExtractor reg_data; 1646611103cSGreg Clayton ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext()); 16530fdc8d8SChris Lattner RegisterContext *reg_context = exe_ctx.GetRegisterContext (); 16630fdc8d8SChris Lattner 16730fdc8d8SChris Lattner if (reg_context) 16830fdc8d8SChris Lattner { 16930fdc8d8SChris Lattner if (command.GetArgumentCount() != 2) 17030fdc8d8SChris Lattner { 17130fdc8d8SChris Lattner result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>"); 17230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 17330fdc8d8SChris Lattner } 17430fdc8d8SChris Lattner else 17530fdc8d8SChris Lattner { 17630fdc8d8SChris Lattner const char *reg_name = command.GetArgumentAtIndex(0); 17730fdc8d8SChris Lattner const char *value_str = command.GetArgumentAtIndex(1); 17830fdc8d8SChris Lattner const RegisterInfo *reg_info = reg_context->GetRegisterInfoByName(reg_name); 17930fdc8d8SChris Lattner 18030fdc8d8SChris Lattner if (reg_info) 18130fdc8d8SChris Lattner { 18230fdc8d8SChris Lattner Scalar scalar; 18330fdc8d8SChris Lattner Error error(scalar.SetValueFromCString (value_str, reg_info->encoding, reg_info->byte_size)); 18430fdc8d8SChris Lattner if (error.Success()) 18530fdc8d8SChris Lattner { 18630fdc8d8SChris Lattner if (reg_context->WriteRegisterValue(reg_info->reg, scalar)) 18730fdc8d8SChris Lattner { 18830fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 18930fdc8d8SChris Lattner return true; 19030fdc8d8SChris Lattner } 19130fdc8d8SChris Lattner } 19230fdc8d8SChris Lattner else 19330fdc8d8SChris Lattner { 19430fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n", 19530fdc8d8SChris Lattner reg_name, 19630fdc8d8SChris Lattner value_str, 19730fdc8d8SChris Lattner error.AsCString()); 19830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 19930fdc8d8SChris Lattner } 20030fdc8d8SChris Lattner } 20130fdc8d8SChris Lattner else 20230fdc8d8SChris Lattner { 20330fdc8d8SChris Lattner result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name); 20430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 20530fdc8d8SChris Lattner } 20630fdc8d8SChris Lattner } 20730fdc8d8SChris Lattner } 20830fdc8d8SChris Lattner else 20930fdc8d8SChris Lattner { 21030fdc8d8SChris Lattner result.AppendError ("no current frame"); 21130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 21230fdc8d8SChris Lattner } 21330fdc8d8SChris Lattner return result.Succeeded(); 21430fdc8d8SChris Lattner } 21530fdc8d8SChris Lattner }; 21630fdc8d8SChris Lattner 21730fdc8d8SChris Lattner 21830fdc8d8SChris Lattner //---------------------------------------------------------------------- 21930fdc8d8SChris Lattner // CommandObjectRegister constructor 22030fdc8d8SChris Lattner //---------------------------------------------------------------------- 2216611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) : 22230fdc8d8SChris Lattner CommandObjectMultiword ("register", 223*3f4c09c1SCaroline Tice "A set of commands to access thread registers.", 22430fdc8d8SChris Lattner "register [read|write] ...") 22530fdc8d8SChris Lattner { 2266611103cSGreg Clayton LoadSubCommand (interpreter, "read", CommandObjectSP (new CommandObjectRegisterRead ())); 2276611103cSGreg Clayton LoadSubCommand (interpreter, "write", CommandObjectSP (new CommandObjectRegisterWrite ())); 22830fdc8d8SChris Lattner } 22930fdc8d8SChris Lattner 23030fdc8d8SChris Lattner 23130fdc8d8SChris Lattner //---------------------------------------------------------------------- 23230fdc8d8SChris Lattner // Destructor 23330fdc8d8SChris Lattner //---------------------------------------------------------------------- 23430fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister() 23530fdc8d8SChris Lattner { 23630fdc8d8SChris Lattner } 237