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