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