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