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/Interpreter/Options.h" 23 #include "lldb/Target/ExecutionContext.h" 24 #include "lldb/Target/RegisterContext.h" 25 26 using namespace lldb; 27 using namespace lldb_private; 28 29 //---------------------------------------------------------------------- 30 // "register read" 31 //---------------------------------------------------------------------- 32 class CommandObjectRegisterRead : public CommandObject 33 { 34 public: 35 CommandObjectRegisterRead (CommandInterpreter &interpreter) : 36 CommandObject (interpreter, 37 "register read", 38 "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.", 39 //"register read [<reg-name1> [<reg-name2> [...]]]", 40 NULL, 41 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), 42 m_options (interpreter) 43 { 44 CommandArgumentEntry arg; 45 CommandArgumentData register_arg; 46 47 // Define the first (and only) variant of this arg. 48 register_arg.arg_type = eArgTypeRegisterName; 49 register_arg.arg_repetition = eArgRepeatStar; 50 51 // There is only one variant this argument could be; put it into the argument entry. 52 arg.push_back (register_arg); 53 54 // Push the data for the first argument into the m_arguments vector. 55 m_arguments.push_back (arg); 56 } 57 58 virtual 59 ~CommandObjectRegisterRead () 60 { 61 } 62 63 Options * 64 GetOptions () 65 { 66 return &m_options; 67 } 68 69 virtual bool 70 Execute 71 ( 72 Args& command, 73 CommandReturnObject &result 74 ) 75 { 76 Stream &output_stream = result.GetOutputStream(); 77 DataExtractor reg_data; 78 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 79 RegisterContext *reg_context = exe_ctx.GetRegisterContext (); 80 81 if (reg_context) 82 { 83 const RegisterInfo *reg_info = NULL; 84 if (command.GetArgumentCount() == 0) 85 { 86 uint32_t set_idx; 87 const uint32_t num_register_sets = reg_context->GetRegisterSetCount(); 88 for (set_idx = 0; set_idx < num_register_sets; ++set_idx) 89 { 90 uint32_t unavailable_count = 0; 91 const RegisterSet * const reg_set = reg_context->GetRegisterSet(set_idx); 92 output_stream.Printf ("%s:\n", reg_set->name); 93 output_stream.IndentMore (); 94 const uint32_t num_registers = reg_set->num_registers; 95 for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) 96 { 97 uint32_t reg = reg_set->registers[reg_idx]; 98 reg_info = reg_context->GetRegisterInfoAtIndex(reg); 99 if (reg_context->ReadRegisterBytes(reg, reg_data)) 100 { 101 output_stream.Indent (); 102 output_stream.Printf ("%-12s = ", reg_info ? reg_info->name : "<INVALID REGINFO>"); 103 reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); 104 output_stream.EOL(); 105 } 106 else 107 { 108 ++unavailable_count; 109 } 110 } 111 if (unavailable_count) 112 { 113 output_stream.Indent (); 114 output_stream.Printf("%u registers were unavailable.\n", unavailable_count); 115 } 116 output_stream.IndentLess (); 117 output_stream.EOL(); 118 } 119 } 120 else 121 { 122 const char *arg_cstr; 123 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 124 { 125 reg_info = reg_context->GetRegisterInfoByName(arg_cstr); 126 127 if (reg_info) 128 { 129 output_stream.Printf("%-12s = ", reg_info->name); 130 if (reg_context->ReadRegisterBytes(reg_info->kinds[eRegisterKindLLDB], reg_data)) 131 { 132 reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); 133 } 134 else 135 { 136 output_stream.PutCString ("error: unavailable"); 137 } 138 output_stream.EOL(); 139 } 140 else 141 { 142 result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); 143 } 144 } 145 } 146 } 147 else 148 { 149 result.AppendError ("no current frame"); 150 result.SetStatus (eReturnStatusFailed); 151 } 152 return result.Succeeded(); 153 } 154 155 protected: 156 class CommandOptions : public Options 157 { 158 public: 159 CommandOptions (CommandInterpreter &interpreter) : 160 Options(interpreter) 161 { 162 OptionParsingStarting(); 163 } 164 165 virtual 166 ~CommandOptions () 167 { 168 } 169 170 virtual Error 171 SetOptionValue (uint32_t option_idx, const char *option_arg) 172 { 173 Error error; 174 char short_option = (char) m_getopt_table[option_idx].val; 175 switch (short_option) 176 { 177 case 'f': 178 error = Args::StringToFormat (option_arg, m_format); 179 break; 180 181 default: 182 error.SetErrorStringWithFormat("Unrecognized short option '%c'\n", short_option); 183 break; 184 } 185 return error; 186 } 187 188 void 189 OptionParsingStarting () 190 { 191 m_format = eFormatBytes; 192 } 193 194 const OptionDefinition* 195 GetDefinitions () 196 { 197 return g_option_table; 198 } 199 200 // Options table: Required for subclasses of Options. 201 202 static OptionDefinition g_option_table[]; 203 204 // Instance variables to hold the values for command options. 205 lldb::Format m_format; 206 }; 207 208 CommandOptions m_options; 209 }; 210 211 OptionDefinition 212 CommandObjectRegisterRead::CommandOptions::g_option_table[] = 213 { 214 //{ LLDB_OPT_SET_ALL, false, "language", 'l', required_argument, NULL, 0, "[c|c++|objc|objc++]", "Sets the language to use when parsing the expression."}, 215 //{ LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, "[ [bool|b] | [bin] | [char|c] | [oct|o] | [dec|i|d|u] | [hex|x] | [float|f] | [cstr|s] ]", "Specify the format that the expression output should use."}, 216 { LLDB_OPT_SET_1, false, "format", 'f', required_argument, NULL, 0, eArgTypeExprFormat, "Specify the format that the expression output should use."}, 217 { LLDB_OPT_SET_2, false, "object-description", 'o', no_argument, NULL, 0, eArgTypeNone, "Print the object description of the value resulting from the expression."}, 218 { LLDB_OPT_SET_ALL, false, "unwind-on-error", 'u', required_argument, NULL, 0, eArgTypeBoolean, "Clean up program state if the expression causes a crash, breakpoint hit or signal."}, 219 { LLDB_OPT_SET_ALL, false, "debug", 'g', no_argument, NULL, 0, eArgTypeNone, "Enable verbose debug logging of the expression parsing and evaluation."}, 220 { LLDB_OPT_SET_ALL, false, "use-ir", 'i', no_argument, NULL, 0, eArgTypeNone, "[Temporary] Instructs the expression evaluator to use IR instead of ASTs."}, 221 { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL } 222 }; 223 224 225 226 //---------------------------------------------------------------------- 227 // "register write" 228 //---------------------------------------------------------------------- 229 class CommandObjectRegisterWrite : public CommandObject 230 { 231 public: 232 CommandObjectRegisterWrite (CommandInterpreter &interpreter) : 233 CommandObject (interpreter, 234 "register write", 235 "Modify a single register value.", 236 //"register write <reg-name> <value>", 237 NULL, 238 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 239 { 240 CommandArgumentEntry arg1; 241 CommandArgumentEntry arg2; 242 CommandArgumentData register_arg; 243 CommandArgumentData value_arg; 244 245 // Define the first (and only) variant of this arg. 246 register_arg.arg_type = eArgTypeRegisterName; 247 register_arg.arg_repetition = eArgRepeatPlain; 248 249 // There is only one variant this argument could be; put it into the argument entry. 250 arg1.push_back (register_arg); 251 252 // Define the first (and only) variant of this arg. 253 value_arg.arg_type = eArgTypeValue; 254 value_arg.arg_repetition = eArgRepeatPlain; 255 256 // There is only one variant this argument could be; put it into the argument entry. 257 arg2.push_back (value_arg); 258 259 // Push the data for the first argument into the m_arguments vector. 260 m_arguments.push_back (arg1); 261 m_arguments.push_back (arg2); 262 } 263 264 virtual 265 ~CommandObjectRegisterWrite () 266 { 267 } 268 269 virtual bool 270 Execute 271 ( 272 Args& command, 273 CommandReturnObject &result 274 ) 275 { 276 DataExtractor reg_data; 277 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 278 RegisterContext *reg_context = exe_ctx.GetRegisterContext (); 279 280 if (reg_context) 281 { 282 if (command.GetArgumentCount() != 2) 283 { 284 result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>"); 285 result.SetStatus (eReturnStatusFailed); 286 } 287 else 288 { 289 const char *reg_name = command.GetArgumentAtIndex(0); 290 const char *value_str = command.GetArgumentAtIndex(1); 291 const RegisterInfo *reg_info = reg_context->GetRegisterInfoByName(reg_name); 292 293 if (reg_info) 294 { 295 Scalar scalar; 296 Error error(scalar.SetValueFromCString (value_str, reg_info->encoding, reg_info->byte_size)); 297 if (error.Success()) 298 { 299 if (reg_context->WriteRegisterValue(reg_info->kinds[eRegisterKindLLDB], scalar)) 300 { 301 result.SetStatus (eReturnStatusSuccessFinishNoResult); 302 return true; 303 } 304 } 305 else 306 { 307 result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n", 308 reg_name, 309 value_str, 310 error.AsCString()); 311 result.SetStatus (eReturnStatusFailed); 312 } 313 } 314 else 315 { 316 result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name); 317 result.SetStatus (eReturnStatusFailed); 318 } 319 } 320 } 321 else 322 { 323 result.AppendError ("no current frame"); 324 result.SetStatus (eReturnStatusFailed); 325 } 326 return result.Succeeded(); 327 } 328 }; 329 330 331 //---------------------------------------------------------------------- 332 // CommandObjectRegister constructor 333 //---------------------------------------------------------------------- 334 CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) : 335 CommandObjectMultiword (interpreter, 336 "register", 337 "A set of commands to access thread registers.", 338 "register [read|write] ...") 339 { 340 LoadSubCommand ("read", CommandObjectSP (new CommandObjectRegisterRead (interpreter))); 341 LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter))); 342 } 343 344 345 //---------------------------------------------------------------------- 346 // Destructor 347 //---------------------------------------------------------------------- 348 CommandObjectRegister::~CommandObjectRegister() 349 { 350 } 351