1*30fdc8d8SChris Lattner //===-- CommandObjectRegister.cpp -------------------------------*- C++ -*-===// 2*30fdc8d8SChris Lattner // 3*30fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 4*30fdc8d8SChris Lattner // 5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 7*30fdc8d8SChris Lattner // 8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 9*30fdc8d8SChris Lattner 10*30fdc8d8SChris Lattner #include "CommandObjectRegister.h" 11*30fdc8d8SChris Lattner 12*30fdc8d8SChris Lattner // C Includes 13*30fdc8d8SChris Lattner // C++ Includes 14*30fdc8d8SChris Lattner // Other libraries and framework includes 15*30fdc8d8SChris Lattner // Project includes 16*30fdc8d8SChris Lattner #include "lldb/Core/Args.h" 17*30fdc8d8SChris Lattner #include "lldb/Core/DataExtractor.h" 18*30fdc8d8SChris Lattner #include "lldb/Core/Scalar.h" 19*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandContext.h" 20*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 21*30fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h" 22*30fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 23*30fdc8d8SChris Lattner 24*30fdc8d8SChris Lattner using namespace lldb; 25*30fdc8d8SChris Lattner using namespace lldb_private; 26*30fdc8d8SChris Lattner 27*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 28*30fdc8d8SChris Lattner // "register read" 29*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 30*30fdc8d8SChris Lattner class CommandObjectRegisterRead : public CommandObject 31*30fdc8d8SChris Lattner { 32*30fdc8d8SChris Lattner public: 33*30fdc8d8SChris Lattner CommandObjectRegisterRead () : 34*30fdc8d8SChris Lattner CommandObject ("register read", 35*30fdc8d8SChris Lattner "Dump the one or more register values from the current frame.", 36*30fdc8d8SChris Lattner "register read [<reg-name1> [<reg-name2> [...]]]", 37*30fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 38*30fdc8d8SChris Lattner { 39*30fdc8d8SChris Lattner } 40*30fdc8d8SChris Lattner 41*30fdc8d8SChris Lattner virtual 42*30fdc8d8SChris Lattner ~CommandObjectRegisterRead () 43*30fdc8d8SChris Lattner { 44*30fdc8d8SChris Lattner } 45*30fdc8d8SChris Lattner 46*30fdc8d8SChris Lattner virtual bool 47*30fdc8d8SChris Lattner Execute (Args& command, 48*30fdc8d8SChris Lattner CommandContext *context, 49*30fdc8d8SChris Lattner CommandInterpreter *interpreter, 50*30fdc8d8SChris Lattner CommandReturnObject &result) 51*30fdc8d8SChris Lattner { 52*30fdc8d8SChris Lattner StreamString &output_stream = result.GetOutputStream(); 53*30fdc8d8SChris Lattner DataExtractor reg_data; 54*30fdc8d8SChris Lattner ExecutionContext exe_ctx(context->GetExecutionContext()); 55*30fdc8d8SChris Lattner RegisterContext *reg_context = exe_ctx.GetRegisterContext (); 56*30fdc8d8SChris Lattner 57*30fdc8d8SChris Lattner if (reg_context) 58*30fdc8d8SChris Lattner { 59*30fdc8d8SChris Lattner const RegisterInfo *reg_info = NULL; 60*30fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 61*30fdc8d8SChris Lattner { 62*30fdc8d8SChris Lattner uint32_t set_idx; 63*30fdc8d8SChris Lattner const uint32_t num_register_sets = reg_context->GetRegisterSetCount(); 64*30fdc8d8SChris Lattner for (set_idx = 0; set_idx < num_register_sets; ++set_idx) 65*30fdc8d8SChris Lattner { 66*30fdc8d8SChris Lattner uint32_t unavailable_count = 0; 67*30fdc8d8SChris Lattner const RegisterSet * const reg_set = reg_context->GetRegisterSet(set_idx); 68*30fdc8d8SChris Lattner output_stream.Printf ("%s:\n", reg_set->name); 69*30fdc8d8SChris Lattner output_stream.IndentMore (); 70*30fdc8d8SChris Lattner const uint32_t num_registers = reg_set->num_registers; 71*30fdc8d8SChris Lattner for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) 72*30fdc8d8SChris Lattner { 73*30fdc8d8SChris Lattner uint32_t reg = reg_set->registers[reg_idx]; 74*30fdc8d8SChris Lattner reg_info = reg_context->GetRegisterInfoAtIndex(reg); 75*30fdc8d8SChris Lattner if (reg_context->ReadRegisterBytes(reg, reg_data)) 76*30fdc8d8SChris Lattner { 77*30fdc8d8SChris Lattner output_stream.Indent (); 78*30fdc8d8SChris Lattner output_stream.Printf ("%-12s = ", reg_info ? reg_info->name : "<INVALID REGINFO>"); 79*30fdc8d8SChris Lattner reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); 80*30fdc8d8SChris Lattner output_stream.EOL(); 81*30fdc8d8SChris Lattner } 82*30fdc8d8SChris Lattner else 83*30fdc8d8SChris Lattner { 84*30fdc8d8SChris Lattner ++unavailable_count; 85*30fdc8d8SChris Lattner } 86*30fdc8d8SChris Lattner } 87*30fdc8d8SChris Lattner if (unavailable_count) 88*30fdc8d8SChris Lattner { 89*30fdc8d8SChris Lattner output_stream.Indent (); 90*30fdc8d8SChris Lattner output_stream.Printf("%u registers were unavailable.\n", unavailable_count); 91*30fdc8d8SChris Lattner } 92*30fdc8d8SChris Lattner output_stream.IndentLess (); 93*30fdc8d8SChris Lattner output_stream.EOL(); 94*30fdc8d8SChris Lattner } 95*30fdc8d8SChris Lattner } 96*30fdc8d8SChris Lattner else 97*30fdc8d8SChris Lattner { 98*30fdc8d8SChris Lattner const char *arg_cstr; 99*30fdc8d8SChris Lattner for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 100*30fdc8d8SChris Lattner { 101*30fdc8d8SChris Lattner reg_info = reg_context->GetRegisterInfoByName(arg_cstr); 102*30fdc8d8SChris Lattner 103*30fdc8d8SChris Lattner if (reg_info) 104*30fdc8d8SChris Lattner { 105*30fdc8d8SChris Lattner output_stream.Printf("%-12s = ", reg_info->name); 106*30fdc8d8SChris Lattner if (reg_context->ReadRegisterBytes(reg_info->reg, reg_data)) 107*30fdc8d8SChris Lattner { 108*30fdc8d8SChris Lattner reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); 109*30fdc8d8SChris Lattner } 110*30fdc8d8SChris Lattner else 111*30fdc8d8SChris Lattner { 112*30fdc8d8SChris Lattner output_stream.PutCString ("error: unavailable"); 113*30fdc8d8SChris Lattner } 114*30fdc8d8SChris Lattner output_stream.EOL(); 115*30fdc8d8SChris Lattner } 116*30fdc8d8SChris Lattner else 117*30fdc8d8SChris Lattner { 118*30fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); 119*30fdc8d8SChris Lattner } 120*30fdc8d8SChris Lattner } 121*30fdc8d8SChris Lattner } 122*30fdc8d8SChris Lattner } 123*30fdc8d8SChris Lattner else 124*30fdc8d8SChris Lattner { 125*30fdc8d8SChris Lattner result.AppendError ("no current frame"); 126*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 127*30fdc8d8SChris Lattner } 128*30fdc8d8SChris Lattner return result.Succeeded(); 129*30fdc8d8SChris Lattner } 130*30fdc8d8SChris Lattner }; 131*30fdc8d8SChris Lattner 132*30fdc8d8SChris Lattner 133*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 134*30fdc8d8SChris Lattner // "register write" 135*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 136*30fdc8d8SChris Lattner class CommandObjectRegisterWrite : public CommandObject 137*30fdc8d8SChris Lattner { 138*30fdc8d8SChris Lattner public: 139*30fdc8d8SChris Lattner CommandObjectRegisterWrite () : 140*30fdc8d8SChris Lattner CommandObject ("register write", 141*30fdc8d8SChris Lattner "Modify a single register value.", 142*30fdc8d8SChris Lattner "register write <reg-name> <value>", 143*30fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 144*30fdc8d8SChris Lattner { 145*30fdc8d8SChris Lattner } 146*30fdc8d8SChris Lattner 147*30fdc8d8SChris Lattner virtual 148*30fdc8d8SChris Lattner ~CommandObjectRegisterWrite () 149*30fdc8d8SChris Lattner { 150*30fdc8d8SChris Lattner } 151*30fdc8d8SChris Lattner 152*30fdc8d8SChris Lattner virtual bool 153*30fdc8d8SChris Lattner Execute (Args& command, 154*30fdc8d8SChris Lattner CommandContext *context, 155*30fdc8d8SChris Lattner CommandInterpreter *interpreter, 156*30fdc8d8SChris Lattner CommandReturnObject &result) 157*30fdc8d8SChris Lattner { 158*30fdc8d8SChris Lattner DataExtractor reg_data; 159*30fdc8d8SChris Lattner ExecutionContext exe_ctx(context->GetExecutionContext()); 160*30fdc8d8SChris Lattner RegisterContext *reg_context = exe_ctx.GetRegisterContext (); 161*30fdc8d8SChris Lattner 162*30fdc8d8SChris Lattner if (reg_context) 163*30fdc8d8SChris Lattner { 164*30fdc8d8SChris Lattner if (command.GetArgumentCount() != 2) 165*30fdc8d8SChris Lattner { 166*30fdc8d8SChris Lattner result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>"); 167*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 168*30fdc8d8SChris Lattner } 169*30fdc8d8SChris Lattner else 170*30fdc8d8SChris Lattner { 171*30fdc8d8SChris Lattner const char *reg_name = command.GetArgumentAtIndex(0); 172*30fdc8d8SChris Lattner const char *value_str = command.GetArgumentAtIndex(1); 173*30fdc8d8SChris Lattner const RegisterInfo *reg_info = reg_context->GetRegisterInfoByName(reg_name); 174*30fdc8d8SChris Lattner 175*30fdc8d8SChris Lattner if (reg_info) 176*30fdc8d8SChris Lattner { 177*30fdc8d8SChris Lattner Scalar scalar; 178*30fdc8d8SChris Lattner Error error(scalar.SetValueFromCString (value_str, reg_info->encoding, reg_info->byte_size)); 179*30fdc8d8SChris Lattner if (error.Success()) 180*30fdc8d8SChris Lattner { 181*30fdc8d8SChris Lattner if (reg_context->WriteRegisterValue(reg_info->reg, scalar)) 182*30fdc8d8SChris Lattner { 183*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 184*30fdc8d8SChris Lattner return true; 185*30fdc8d8SChris Lattner } 186*30fdc8d8SChris Lattner } 187*30fdc8d8SChris Lattner else 188*30fdc8d8SChris Lattner { 189*30fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n", 190*30fdc8d8SChris Lattner reg_name, 191*30fdc8d8SChris Lattner value_str, 192*30fdc8d8SChris Lattner error.AsCString()); 193*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 194*30fdc8d8SChris Lattner } 195*30fdc8d8SChris Lattner } 196*30fdc8d8SChris Lattner else 197*30fdc8d8SChris Lattner { 198*30fdc8d8SChris Lattner result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name); 199*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 200*30fdc8d8SChris Lattner } 201*30fdc8d8SChris Lattner } 202*30fdc8d8SChris Lattner } 203*30fdc8d8SChris Lattner else 204*30fdc8d8SChris Lattner { 205*30fdc8d8SChris Lattner result.AppendError ("no current frame"); 206*30fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 207*30fdc8d8SChris Lattner } 208*30fdc8d8SChris Lattner return result.Succeeded(); 209*30fdc8d8SChris Lattner } 210*30fdc8d8SChris Lattner }; 211*30fdc8d8SChris Lattner 212*30fdc8d8SChris Lattner 213*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 214*30fdc8d8SChris Lattner // CommandObjectRegister constructor 215*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 216*30fdc8d8SChris Lattner CommandObjectRegister::CommandObjectRegister(CommandInterpreter *interpreter) : 217*30fdc8d8SChris Lattner CommandObjectMultiword ("register", 218*30fdc8d8SChris Lattner "Access thread registers.", 219*30fdc8d8SChris Lattner "register [read|write] ...") 220*30fdc8d8SChris Lattner { 221*30fdc8d8SChris Lattner LoadSubCommand (CommandObjectSP (new CommandObjectRegisterRead ()), "read", interpreter); 222*30fdc8d8SChris Lattner LoadSubCommand (CommandObjectSP (new CommandObjectRegisterWrite ()), "write", interpreter); 223*30fdc8d8SChris Lattner } 224*30fdc8d8SChris Lattner 225*30fdc8d8SChris Lattner 226*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 227*30fdc8d8SChris Lattner // Destructor 228*30fdc8d8SChris Lattner //---------------------------------------------------------------------- 229*30fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister() 230*30fdc8d8SChris Lattner { 231*30fdc8d8SChris Lattner } 232