1254721Semaste//===-- CommandObjectRegister.cpp -------------------------------*- C++ -*-===// 2254721Semaste// 3254721Semaste// The LLVM Compiler Infrastructure 4254721Semaste// 5254721Semaste// This file is distributed under the University of Illinois Open Source 6254721Semaste// License. See LICENSE.TXT for details. 7254721Semaste// 8254721Semaste//===----------------------------------------------------------------------===// 9254721Semaste 10254721Semaste#include "lldb/lldb-python.h" 11254721Semaste 12254721Semaste#include "CommandObjectRegister.h" 13254721Semaste 14254721Semaste// C Includes 15254721Semaste// C++ Includes 16254721Semaste// Other libraries and framework includes 17254721Semaste// Project includes 18254721Semaste#include "lldb/Core/DataExtractor.h" 19254721Semaste#include "lldb/Core/RegisterValue.h" 20254721Semaste#include "lldb/Core/Scalar.h" 21254721Semaste#include "lldb/Core/Debugger.h" 22254721Semaste#include "lldb/Interpreter/Args.h" 23254721Semaste#include "lldb/Interpreter/CommandInterpreter.h" 24254721Semaste#include "lldb/Interpreter/CommandReturnObject.h" 25254721Semaste#include "lldb/Interpreter/Options.h" 26254721Semaste#include "lldb/Interpreter/OptionGroupFormat.h" 27254721Semaste#include "lldb/Interpreter/OptionValueArray.h" 28254721Semaste#include "lldb/Interpreter/OptionValueUInt64.h" 29254721Semaste#include "lldb/Target/ExecutionContext.h" 30254721Semaste#include "lldb/Target/Process.h" 31254721Semaste#include "lldb/Target/RegisterContext.h" 32269024Semaste#include "lldb/Target/SectionLoadList.h" 33254721Semaste#include "lldb/Target/Thread.h" 34254721Semaste 35254721Semasteusing namespace lldb; 36254721Semasteusing namespace lldb_private; 37254721Semaste 38254721Semaste//---------------------------------------------------------------------- 39254721Semaste// "register read" 40254721Semaste//---------------------------------------------------------------------- 41254721Semasteclass CommandObjectRegisterRead : public CommandObjectParsed 42254721Semaste{ 43254721Semastepublic: 44254721Semaste CommandObjectRegisterRead (CommandInterpreter &interpreter) : 45254721Semaste CommandObjectParsed (interpreter, 46254721Semaste "register read", 47254721Semaste "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.", 48254721Semaste NULL, 49254721Semaste eFlagRequiresFrame | 50254721Semaste eFlagRequiresRegContext | 51254721Semaste eFlagProcessMustBeLaunched | 52254721Semaste eFlagProcessMustBePaused ), 53254721Semaste m_option_group (interpreter), 54254721Semaste m_format_options (eFormatDefault), 55254721Semaste m_command_options () 56254721Semaste { 57254721Semaste CommandArgumentEntry arg; 58254721Semaste CommandArgumentData register_arg; 59254721Semaste 60254721Semaste // Define the first (and only) variant of this arg. 61254721Semaste register_arg.arg_type = eArgTypeRegisterName; 62254721Semaste register_arg.arg_repetition = eArgRepeatStar; 63254721Semaste 64254721Semaste // There is only one variant this argument could be; put it into the argument entry. 65254721Semaste arg.push_back (register_arg); 66254721Semaste 67254721Semaste // Push the data for the first argument into the m_arguments vector. 68254721Semaste m_arguments.push_back (arg); 69254721Semaste 70254721Semaste // Add the "--format" 71254721Semaste m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_ALL); 72254721Semaste m_option_group.Append (&m_command_options); 73254721Semaste m_option_group.Finalize(); 74254721Semaste 75254721Semaste } 76254721Semaste 77254721Semaste virtual 78254721Semaste ~CommandObjectRegisterRead () 79254721Semaste { 80254721Semaste } 81254721Semaste 82254721Semaste Options * 83254721Semaste GetOptions () 84254721Semaste { 85254721Semaste return &m_option_group; 86254721Semaste } 87254721Semaste 88254721Semaste bool 89254721Semaste DumpRegister (const ExecutionContext &exe_ctx, 90254721Semaste Stream &strm, 91254721Semaste RegisterContext *reg_ctx, 92254721Semaste const RegisterInfo *reg_info) 93254721Semaste { 94254721Semaste if (reg_info) 95254721Semaste { 96254721Semaste RegisterValue reg_value; 97254721Semaste 98254721Semaste if (reg_ctx->ReadRegister (reg_info, reg_value)) 99254721Semaste { 100254721Semaste strm.Indent (); 101254721Semaste 102263363Semaste bool prefix_with_altname = (bool)m_command_options.alternate_name; 103254721Semaste bool prefix_with_name = !prefix_with_altname; 104254721Semaste reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname, m_format_options.GetFormat(), 8); 105254721Semaste if ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint)) 106254721Semaste { 107254721Semaste Process *process = exe_ctx.GetProcessPtr(); 108254721Semaste if (process && reg_info->byte_size == process->GetAddressByteSize()) 109254721Semaste { 110254721Semaste addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS); 111254721Semaste if (reg_addr != LLDB_INVALID_ADDRESS) 112254721Semaste { 113254721Semaste Address so_reg_addr; 114254721Semaste if (exe_ctx.GetTargetRef().GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr)) 115254721Semaste { 116254721Semaste strm.PutCString (" "); 117254721Semaste so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription); 118254721Semaste } 119254721Semaste } 120254721Semaste } 121254721Semaste } 122254721Semaste strm.EOL(); 123254721Semaste return true; 124254721Semaste } 125254721Semaste } 126254721Semaste return false; 127254721Semaste } 128254721Semaste 129254721Semaste bool 130254721Semaste DumpRegisterSet (const ExecutionContext &exe_ctx, 131254721Semaste Stream &strm, 132254721Semaste RegisterContext *reg_ctx, 133254721Semaste size_t set_idx, 134254721Semaste bool primitive_only=false) 135254721Semaste { 136254721Semaste uint32_t unavailable_count = 0; 137254721Semaste uint32_t available_count = 0; 138254721Semaste 139254721Semaste if (!reg_ctx) 140254721Semaste return false; // thread has no registers (i.e. core files are corrupt, incomplete crash logs...) 141254721Semaste 142254721Semaste const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx); 143254721Semaste if (reg_set) 144254721Semaste { 145254721Semaste strm.Printf ("%s:\n", reg_set->name); 146254721Semaste strm.IndentMore (); 147254721Semaste const size_t num_registers = reg_set->num_registers; 148254721Semaste for (size_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) 149254721Semaste { 150254721Semaste const uint32_t reg = reg_set->registers[reg_idx]; 151254721Semaste const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg); 152254721Semaste // Skip the dumping of derived register if primitive_only is true. 153254721Semaste if (primitive_only && reg_info && reg_info->value_regs) 154254721Semaste continue; 155254721Semaste 156254721Semaste if (DumpRegister (exe_ctx, strm, reg_ctx, reg_info)) 157254721Semaste ++available_count; 158254721Semaste else 159254721Semaste ++unavailable_count; 160254721Semaste } 161254721Semaste strm.IndentLess (); 162254721Semaste if (unavailable_count) 163254721Semaste { 164254721Semaste strm.Indent (); 165254721Semaste strm.Printf("%u registers were unavailable.\n", unavailable_count); 166254721Semaste } 167254721Semaste strm.EOL(); 168254721Semaste } 169254721Semaste return available_count > 0; 170254721Semaste } 171254721Semaste 172254721Semasteprotected: 173254721Semaste virtual bool 174254721Semaste DoExecute (Args& command, CommandReturnObject &result) 175254721Semaste { 176254721Semaste Stream &strm = result.GetOutputStream(); 177254721Semaste RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext (); 178254721Semaste 179254721Semaste const RegisterInfo *reg_info = NULL; 180254721Semaste if (command.GetArgumentCount() == 0) 181254721Semaste { 182254721Semaste size_t set_idx; 183254721Semaste 184254721Semaste size_t num_register_sets = 1; 185254721Semaste const size_t set_array_size = m_command_options.set_indexes.GetSize(); 186254721Semaste if (set_array_size > 0) 187254721Semaste { 188254721Semaste for (size_t i=0; i<set_array_size; ++i) 189254721Semaste { 190254721Semaste set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL); 191254721Semaste if (set_idx < reg_ctx->GetRegisterSetCount()) 192254721Semaste { 193254721Semaste if (!DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx)) 194254721Semaste { 195254721Semaste if (errno) 196263363Semaste result.AppendErrorWithFormat ("register read failed: %s\n", strerror(errno)); 197254721Semaste else 198254721Semaste result.AppendError ("unknown error while reading registers.\n"); 199254721Semaste result.SetStatus (eReturnStatusFailed); 200254721Semaste break; 201254721Semaste } 202254721Semaste } 203254721Semaste else 204254721Semaste { 205254721Semaste result.AppendErrorWithFormat ("invalid register set index: %zu\n", set_idx); 206254721Semaste result.SetStatus (eReturnStatusFailed); 207254721Semaste break; 208254721Semaste } 209254721Semaste } 210254721Semaste } 211254721Semaste else 212254721Semaste { 213254721Semaste if (m_command_options.dump_all_sets) 214254721Semaste num_register_sets = reg_ctx->GetRegisterSetCount(); 215254721Semaste 216254721Semaste for (set_idx = 0; set_idx < num_register_sets; ++set_idx) 217254721Semaste { 218254721Semaste // When dump_all_sets option is set, dump primitive as well as derived registers. 219254721Semaste DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx, !m_command_options.dump_all_sets.GetCurrentValue()); 220254721Semaste } 221254721Semaste } 222254721Semaste } 223254721Semaste else 224254721Semaste { 225254721Semaste if (m_command_options.dump_all_sets) 226254721Semaste { 227254721Semaste result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n"); 228254721Semaste result.SetStatus (eReturnStatusFailed); 229254721Semaste } 230254721Semaste else if (m_command_options.set_indexes.GetSize() > 0) 231254721Semaste { 232254721Semaste result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n"); 233254721Semaste result.SetStatus (eReturnStatusFailed); 234254721Semaste } 235254721Semaste else 236254721Semaste { 237254721Semaste const char *arg_cstr; 238254721Semaste for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 239254721Semaste { 240254721Semaste // in most LLDB commands we accept $rbx as the name for register RBX - and here we would 241254721Semaste // reject it and non-existant. we should be more consistent towards the user and allow them 242254721Semaste // to say reg read $rbx - internally, however, we should be strict and not allow ourselves 243254721Semaste // to call our registers $rbx in our own API 244254721Semaste if (*arg_cstr == '$') 245254721Semaste arg_cstr = arg_cstr+1; 246254721Semaste reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr); 247254721Semaste 248254721Semaste if (reg_info) 249254721Semaste { 250254721Semaste if (!DumpRegister (m_exe_ctx, strm, reg_ctx, reg_info)) 251254721Semaste strm.Printf("%-12s = error: unavailable\n", reg_info->name); 252254721Semaste } 253254721Semaste else 254254721Semaste { 255254721Semaste result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); 256254721Semaste } 257254721Semaste } 258254721Semaste } 259254721Semaste } 260254721Semaste return result.Succeeded(); 261254721Semaste } 262254721Semaste 263254721Semaste class CommandOptions : public OptionGroup 264254721Semaste { 265254721Semaste public: 266254721Semaste CommandOptions () : 267254721Semaste OptionGroup(), 268254721Semaste set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)), 269254721Semaste dump_all_sets (false, false), // Initial and default values are false 270254721Semaste alternate_name (false, false) 271254721Semaste { 272254721Semaste } 273254721Semaste 274254721Semaste virtual 275254721Semaste ~CommandOptions () 276254721Semaste { 277254721Semaste } 278254721Semaste 279254721Semaste 280254721Semaste virtual uint32_t 281254721Semaste GetNumDefinitions (); 282254721Semaste 283254721Semaste virtual const OptionDefinition* 284254721Semaste GetDefinitions () 285254721Semaste { 286254721Semaste return g_option_table; 287254721Semaste } 288254721Semaste 289254721Semaste virtual void 290254721Semaste OptionParsingStarting (CommandInterpreter &interpreter) 291254721Semaste { 292254721Semaste set_indexes.Clear(); 293254721Semaste dump_all_sets.Clear(); 294254721Semaste alternate_name.Clear(); 295254721Semaste } 296254721Semaste 297254721Semaste virtual Error 298254721Semaste SetOptionValue (CommandInterpreter &interpreter, 299254721Semaste uint32_t option_idx, 300254721Semaste const char *option_value) 301254721Semaste { 302254721Semaste Error error; 303254721Semaste const int short_option = g_option_table[option_idx].short_option; 304254721Semaste switch (short_option) 305254721Semaste { 306254721Semaste case 's': 307254721Semaste { 308254721Semaste OptionValueSP value_sp (OptionValueUInt64::Create (option_value, error)); 309254721Semaste if (value_sp) 310254721Semaste set_indexes.AppendValue (value_sp); 311254721Semaste } 312254721Semaste break; 313254721Semaste 314254721Semaste case 'a': 315254721Semaste // When we don't use OptionValue::SetValueFromCString(const char *) to 316254721Semaste // set an option value, it won't be marked as being set in the options 317254721Semaste // so we make a call to let users know the value was set via option 318254721Semaste dump_all_sets.SetCurrentValue (true); 319254721Semaste dump_all_sets.SetOptionWasSet (); 320254721Semaste break; 321254721Semaste 322254721Semaste case 'A': 323254721Semaste // When we don't use OptionValue::SetValueFromCString(const char *) to 324254721Semaste // set an option value, it won't be marked as being set in the options 325254721Semaste // so we make a call to let users know the value was set via option 326254721Semaste alternate_name.SetCurrentValue (true); 327254721Semaste dump_all_sets.SetOptionWasSet (); 328254721Semaste break; 329254721Semaste 330254721Semaste default: 331254721Semaste error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); 332254721Semaste break; 333254721Semaste } 334254721Semaste return error; 335254721Semaste } 336254721Semaste 337254721Semaste // Options table: Required for subclasses of Options. 338254721Semaste 339254721Semaste static const OptionDefinition g_option_table[]; 340254721Semaste 341254721Semaste // Instance variables to hold the values for command options. 342254721Semaste OptionValueArray set_indexes; 343254721Semaste OptionValueBoolean dump_all_sets; 344254721Semaste OptionValueBoolean alternate_name; 345254721Semaste }; 346254721Semaste 347254721Semaste OptionGroupOptions m_option_group; 348254721Semaste OptionGroupFormat m_format_options; 349254721Semaste CommandOptions m_command_options; 350254721Semaste}; 351254721Semaste 352254721Semasteconst OptionDefinition 353254721SemasteCommandObjectRegisterRead::CommandOptions::g_option_table[] = 354254721Semaste{ 355263363Semaste { LLDB_OPT_SET_ALL, false, "alternate", 'A', OptionParser::eNoArgument , NULL, 0, eArgTypeNone , "Display register names using the alternate register name if there is one."}, 356263363Semaste { LLDB_OPT_SET_1 , false, "set" , 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeIndex , "Specify which register sets to dump by index."}, 357263363Semaste { LLDB_OPT_SET_2 , false, "all" , 'a', OptionParser::eNoArgument , NULL, 0, eArgTypeNone , "Show all register sets."}, 358254721Semaste}; 359254721Semaste 360254721Semasteuint32_t 361254721SemasteCommandObjectRegisterRead::CommandOptions::GetNumDefinitions () 362254721Semaste{ 363254721Semaste return sizeof(g_option_table)/sizeof(OptionDefinition); 364254721Semaste} 365254721Semaste 366254721Semaste 367254721Semaste//---------------------------------------------------------------------- 368254721Semaste// "register write" 369254721Semaste//---------------------------------------------------------------------- 370254721Semasteclass CommandObjectRegisterWrite : public CommandObjectParsed 371254721Semaste{ 372254721Semastepublic: 373254721Semaste CommandObjectRegisterWrite (CommandInterpreter &interpreter) : 374254721Semaste CommandObjectParsed (interpreter, 375254721Semaste "register write", 376254721Semaste "Modify a single register value.", 377254721Semaste NULL, 378254721Semaste eFlagRequiresFrame | 379254721Semaste eFlagRequiresRegContext | 380254721Semaste eFlagProcessMustBeLaunched | 381254721Semaste eFlagProcessMustBePaused) 382254721Semaste { 383254721Semaste CommandArgumentEntry arg1; 384254721Semaste CommandArgumentEntry arg2; 385254721Semaste CommandArgumentData register_arg; 386254721Semaste CommandArgumentData value_arg; 387254721Semaste 388254721Semaste // Define the first (and only) variant of this arg. 389254721Semaste register_arg.arg_type = eArgTypeRegisterName; 390254721Semaste register_arg.arg_repetition = eArgRepeatPlain; 391254721Semaste 392254721Semaste // There is only one variant this argument could be; put it into the argument entry. 393254721Semaste arg1.push_back (register_arg); 394254721Semaste 395254721Semaste // Define the first (and only) variant of this arg. 396254721Semaste value_arg.arg_type = eArgTypeValue; 397254721Semaste value_arg.arg_repetition = eArgRepeatPlain; 398254721Semaste 399254721Semaste // There is only one variant this argument could be; put it into the argument entry. 400254721Semaste arg2.push_back (value_arg); 401254721Semaste 402254721Semaste // Push the data for the first argument into the m_arguments vector. 403254721Semaste m_arguments.push_back (arg1); 404254721Semaste m_arguments.push_back (arg2); 405254721Semaste } 406254721Semaste 407254721Semaste virtual 408254721Semaste ~CommandObjectRegisterWrite () 409254721Semaste { 410254721Semaste } 411254721Semaste 412254721Semasteprotected: 413254721Semaste virtual bool 414254721Semaste DoExecute(Args& command, CommandReturnObject &result) 415254721Semaste { 416254721Semaste DataExtractor reg_data; 417254721Semaste RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext (); 418254721Semaste 419254721Semaste if (command.GetArgumentCount() != 2) 420254721Semaste { 421254721Semaste result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>"); 422254721Semaste result.SetStatus (eReturnStatusFailed); 423254721Semaste } 424254721Semaste else 425254721Semaste { 426254721Semaste const char *reg_name = command.GetArgumentAtIndex(0); 427254721Semaste const char *value_str = command.GetArgumentAtIndex(1); 428254721Semaste 429254721Semaste 430254721Semaste // in most LLDB commands we accept $rbx as the name for register RBX - and here we would 431254721Semaste // reject it and non-existant. we should be more consistent towards the user and allow them 432254721Semaste // to say reg write $rbx - internally, however, we should be strict and not allow ourselves 433254721Semaste // to call our registers $rbx in our own API 434254721Semaste if (reg_name && *reg_name == '$') 435254721Semaste reg_name = reg_name+1; 436254721Semaste 437254721Semaste const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); 438254721Semaste 439254721Semaste if (reg_info) 440254721Semaste { 441254721Semaste RegisterValue reg_value; 442254721Semaste 443254721Semaste Error error (reg_value.SetValueFromCString (reg_info, value_str)); 444254721Semaste if (error.Success()) 445254721Semaste { 446254721Semaste if (reg_ctx->WriteRegister (reg_info, reg_value)) 447254721Semaste { 448254721Semaste // Toss all frames and anything else in the thread 449254721Semaste // after a register has been written. 450254721Semaste m_exe_ctx.GetThreadRef().Flush(); 451254721Semaste result.SetStatus (eReturnStatusSuccessFinishNoResult); 452254721Semaste return true; 453254721Semaste } 454254721Semaste } 455254721Semaste if (error.AsCString()) 456254721Semaste { 457254721Semaste result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n", 458254721Semaste reg_name, 459254721Semaste value_str, 460254721Semaste error.AsCString()); 461254721Semaste } 462254721Semaste else 463254721Semaste { 464254721Semaste result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'", 465254721Semaste reg_name, 466254721Semaste value_str); 467254721Semaste } 468254721Semaste result.SetStatus (eReturnStatusFailed); 469254721Semaste } 470254721Semaste else 471254721Semaste { 472254721Semaste result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name); 473254721Semaste result.SetStatus (eReturnStatusFailed); 474254721Semaste } 475254721Semaste } 476254721Semaste return result.Succeeded(); 477254721Semaste } 478254721Semaste}; 479254721Semaste 480254721Semaste 481254721Semaste//---------------------------------------------------------------------- 482254721Semaste// CommandObjectRegister constructor 483254721Semaste//---------------------------------------------------------------------- 484254721SemasteCommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) : 485254721Semaste CommandObjectMultiword (interpreter, 486254721Semaste "register", 487254721Semaste "A set of commands to access thread registers.", 488254721Semaste "register [read|write] ...") 489254721Semaste{ 490254721Semaste LoadSubCommand ("read", CommandObjectSP (new CommandObjectRegisterRead (interpreter))); 491254721Semaste LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter))); 492254721Semaste} 493254721Semaste 494254721Semaste 495254721Semaste//---------------------------------------------------------------------- 496254721Semaste// Destructor 497254721Semaste//---------------------------------------------------------------------- 498254721SemasteCommandObjectRegister::~CommandObjectRegister() 499254721Semaste{ 500254721Semaste} 501