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