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