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/NamedOptionValue.h" 23 #include "lldb/Interpreter/Options.h" 24 #include "lldb/Target/ExecutionContext.h" 25 #include "lldb/Target/RegisterContext.h" 26 27 using namespace lldb; 28 using namespace lldb_private; 29 30 //---------------------------------------------------------------------- 31 // "register read" 32 //---------------------------------------------------------------------- 33 class CommandObjectRegisterRead : public CommandObject 34 { 35 public: 36 CommandObjectRegisterRead (CommandInterpreter &interpreter) : 37 CommandObject (interpreter, 38 "register read", 39 "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.", 40 //"register read [<reg-name1> [<reg-name2> [...]]]", 41 NULL, 42 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), 43 m_options (interpreter) 44 { 45 CommandArgumentEntry arg; 46 CommandArgumentData register_arg; 47 48 // Define the first (and only) variant of this arg. 49 register_arg.arg_type = eArgTypeRegisterName; 50 register_arg.arg_repetition = eArgRepeatStar; 51 52 // There is only one variant this argument could be; put it into the argument entry. 53 arg.push_back (register_arg); 54 55 // Push the data for the first argument into the m_arguments vector. 56 m_arguments.push_back (arg); 57 } 58 59 virtual 60 ~CommandObjectRegisterRead () 61 { 62 } 63 64 Options * 65 GetOptions () 66 { 67 return &m_options; 68 } 69 70 bool 71 DumpRegister (const ExecutionContext &exe_ctx, 72 Stream &strm, 73 RegisterContext *reg_ctx, 74 const RegisterInfo *reg_info) 75 { 76 if (reg_info) 77 { 78 uint32_t reg = reg_info->kinds[eRegisterKindLLDB]; 79 80 DataExtractor reg_data; 81 82 if (reg_ctx->ReadRegisterBytes(reg, reg_data)) 83 { 84 strm.Indent (); 85 strm.Printf ("%-12s = ", reg_info ? reg_info->name : "<INVALID REGINFO>"); 86 Format format; 87 if (m_options.format == eFormatDefault) 88 format = reg_info->format; 89 else 90 format = m_options.format; 91 92 reg_data.Dump(&strm, 0, format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0); 93 if (m_options.lookup_addresses && ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint))) 94 { 95 addr_t reg_addr = reg_ctx->ReadRegisterAsUnsigned (reg, 0); 96 if (reg_addr) 97 { 98 Address so_reg_addr; 99 if (exe_ctx.target->GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr)) 100 { 101 strm.PutCString (" "); 102 so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription); 103 } 104 else 105 { 106 } 107 } 108 } 109 strm.EOL(); 110 return true; 111 } 112 } 113 return false; 114 } 115 116 bool 117 DumpRegisterSet (const ExecutionContext &exe_ctx, 118 Stream &strm, 119 RegisterContext *reg_ctx, 120 uint32_t set_idx) 121 { 122 uint32_t unavailable_count = 0; 123 uint32_t available_count = 0; 124 const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx); 125 if (reg_set) 126 { 127 strm.Printf ("%s:\n", reg_set->name); 128 strm.IndentMore (); 129 const uint32_t num_registers = reg_set->num_registers; 130 for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) 131 { 132 const uint32_t reg = reg_set->registers[reg_idx]; 133 if (DumpRegister (exe_ctx, strm, reg_ctx, reg_ctx->GetRegisterInfoAtIndex(reg))) 134 ++available_count; 135 else 136 ++unavailable_count; 137 } 138 strm.IndentLess (); 139 if (unavailable_count) 140 { 141 strm.Indent (); 142 strm.Printf("%u registers were unavailable.\n", unavailable_count); 143 } 144 strm.EOL(); 145 } 146 return available_count > 0; 147 } 148 149 virtual bool 150 Execute 151 ( 152 Args& command, 153 CommandReturnObject &result 154 ) 155 { 156 Stream &strm = result.GetOutputStream(); 157 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 158 RegisterContext *reg_ctx = exe_ctx.GetRegisterContext (); 159 160 if (reg_ctx) 161 { 162 const RegisterInfo *reg_info = NULL; 163 if (command.GetArgumentCount() == 0) 164 { 165 uint32_t set_idx; 166 167 uint32_t num_register_sets = 1; 168 const uint32_t set_array_size = m_options.set_indexes.GetSize(); 169 if (set_array_size > 0) 170 { 171 for (uint32_t i=0; i<set_array_size; ++i) 172 { 173 set_idx = m_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL); 174 if (set_idx != UINT32_MAX) 175 { 176 if (!DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx)) 177 { 178 result.AppendErrorWithFormat ("invalid register set index: %u\n", set_idx); 179 result.SetStatus (eReturnStatusFailed); 180 break; 181 } 182 } 183 else 184 { 185 result.AppendError ("invalid register set index\n"); 186 result.SetStatus (eReturnStatusFailed); 187 break; 188 } 189 } 190 } 191 else 192 { 193 if (m_options.dump_all_sets) 194 num_register_sets = reg_ctx->GetRegisterSetCount(); 195 196 for (set_idx = 0; set_idx < num_register_sets; ++set_idx) 197 { 198 DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx); 199 } 200 } 201 } 202 else 203 { 204 if (m_options.dump_all_sets) 205 { 206 result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n"); 207 result.SetStatus (eReturnStatusFailed); 208 } 209 else if (m_options.set_indexes.GetSize() > 0) 210 { 211 result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n"); 212 result.SetStatus (eReturnStatusFailed); 213 } 214 else 215 { 216 const char *arg_cstr; 217 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 218 { 219 reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr); 220 221 if (reg_info) 222 { 223 if (!DumpRegister (exe_ctx, strm, reg_ctx, reg_info)) 224 strm.Printf("%-12s = error: unavailable\n", reg_info->name); 225 } 226 else 227 { 228 result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); 229 } 230 } 231 } 232 } 233 } 234 else 235 { 236 result.AppendError ("no current frame"); 237 result.SetStatus (eReturnStatusFailed); 238 } 239 return result.Succeeded(); 240 } 241 242 protected: 243 class CommandOptions : public Options 244 { 245 public: 246 CommandOptions (CommandInterpreter &interpreter) : 247 Options(interpreter), 248 set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)), 249 dump_all_sets (false, false), // Initial and default values are false 250 lookup_addresses (false, false) // Initial and default values are false 251 { 252 OptionParsingStarting(); 253 } 254 255 virtual 256 ~CommandOptions () 257 { 258 } 259 260 virtual Error 261 SetOptionValue (uint32_t option_idx, const char *option_arg) 262 { 263 Error error; 264 char short_option = (char) m_getopt_table[option_idx].val; 265 switch (short_option) 266 { 267 case 'f': 268 error = Args::StringToFormat (option_arg, format, NULL); 269 break; 270 271 case 's': 272 { 273 OptionValueSP value_sp (OptionValueUInt64::Create (option_arg, error)); 274 if (value_sp) 275 set_indexes.AppendValue (value_sp); 276 } 277 break; 278 279 case 'a': 280 dump_all_sets.SetCurrentValue(true); 281 break; 282 283 case 'l': 284 lookup_addresses.SetCurrentValue(true); 285 break; 286 287 default: 288 error.SetErrorStringWithFormat("Unrecognized short option '%c'\n", short_option); 289 break; 290 } 291 return error; 292 } 293 294 void 295 OptionParsingStarting () 296 { 297 format = eFormatDefault; 298 set_indexes.Clear(); 299 dump_all_sets.Clear(); 300 lookup_addresses.Clear(); 301 } 302 303 const OptionDefinition* 304 GetDefinitions () 305 { 306 return g_option_table; 307 } 308 309 // Options table: Required for subclasses of Options. 310 311 static OptionDefinition g_option_table[]; 312 313 // Instance variables to hold the values for command options. 314 lldb::Format format; 315 OptionValueArray set_indexes; 316 OptionValueBoolean dump_all_sets; 317 OptionValueBoolean lookup_addresses; 318 }; 319 320 CommandOptions m_options; 321 }; 322 323 OptionDefinition 324 CommandObjectRegisterRead::CommandOptions::g_option_table[] = 325 { 326 { LLDB_OPT_SET_ALL, false, "format", 'f', required_argument, NULL, 0, eArgTypeExprFormat, "Specify the format to use when dumping register values."}, 327 { LLDB_OPT_SET_ALL, false, "lookup", 'l', no_argument , NULL, 0, eArgTypeNone , "Lookup the register values as addresses and show that each value maps to in the address space."}, 328 { LLDB_OPT_SET_1 , false, "set" , 's', required_argument, NULL, 0, eArgTypeIndex , "Specify which register sets to dump by index."}, 329 { LLDB_OPT_SET_2 , false, "all" , 'a', no_argument , NULL, 0, eArgTypeNone , "Show all register sets."}, 330 { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL } 331 }; 332 333 334 335 //---------------------------------------------------------------------- 336 // "register write" 337 //---------------------------------------------------------------------- 338 class CommandObjectRegisterWrite : public CommandObject 339 { 340 public: 341 CommandObjectRegisterWrite (CommandInterpreter &interpreter) : 342 CommandObject (interpreter, 343 "register write", 344 "Modify a single register value.", 345 //"register write <reg-name> <value>", 346 NULL, 347 eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 348 { 349 CommandArgumentEntry arg1; 350 CommandArgumentEntry arg2; 351 CommandArgumentData register_arg; 352 CommandArgumentData value_arg; 353 354 // Define the first (and only) variant of this arg. 355 register_arg.arg_type = eArgTypeRegisterName; 356 register_arg.arg_repetition = eArgRepeatPlain; 357 358 // There is only one variant this argument could be; put it into the argument entry. 359 arg1.push_back (register_arg); 360 361 // Define the first (and only) variant of this arg. 362 value_arg.arg_type = eArgTypeValue; 363 value_arg.arg_repetition = eArgRepeatPlain; 364 365 // There is only one variant this argument could be; put it into the argument entry. 366 arg2.push_back (value_arg); 367 368 // Push the data for the first argument into the m_arguments vector. 369 m_arguments.push_back (arg1); 370 m_arguments.push_back (arg2); 371 } 372 373 virtual 374 ~CommandObjectRegisterWrite () 375 { 376 } 377 378 virtual bool 379 Execute 380 ( 381 Args& command, 382 CommandReturnObject &result 383 ) 384 { 385 DataExtractor reg_data; 386 ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 387 RegisterContext *reg_ctx = exe_ctx.GetRegisterContext (); 388 389 if (reg_ctx) 390 { 391 if (command.GetArgumentCount() != 2) 392 { 393 result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>"); 394 result.SetStatus (eReturnStatusFailed); 395 } 396 else 397 { 398 const char *reg_name = command.GetArgumentAtIndex(0); 399 const char *value_str = command.GetArgumentAtIndex(1); 400 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); 401 402 if (reg_info) 403 { 404 Scalar scalar; 405 Error error(scalar.SetValueFromCString (value_str, reg_info->encoding, reg_info->byte_size)); 406 if (error.Success()) 407 { 408 if (reg_ctx->WriteRegisterValue(reg_info->kinds[eRegisterKindLLDB], scalar)) 409 { 410 result.SetStatus (eReturnStatusSuccessFinishNoResult); 411 return true; 412 } 413 } 414 else 415 { 416 result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n", 417 reg_name, 418 value_str, 419 error.AsCString()); 420 result.SetStatus (eReturnStatusFailed); 421 } 422 } 423 else 424 { 425 result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name); 426 result.SetStatus (eReturnStatusFailed); 427 } 428 } 429 } 430 else 431 { 432 result.AppendError ("no current frame"); 433 result.SetStatus (eReturnStatusFailed); 434 } 435 return result.Succeeded(); 436 } 437 }; 438 439 440 //---------------------------------------------------------------------- 441 // CommandObjectRegister constructor 442 //---------------------------------------------------------------------- 443 CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) : 444 CommandObjectMultiword (interpreter, 445 "register", 446 "A set of commands to access thread registers.", 447 "register [read|write] ...") 448 { 449 LoadSubCommand ("read", CommandObjectSP (new CommandObjectRegisterRead (interpreter))); 450 LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter))); 451 } 452 453 454 //---------------------------------------------------------------------- 455 // Destructor 456 //---------------------------------------------------------------------- 457 CommandObjectRegister::~CommandObjectRegister() 458 { 459 } 460