130fdc8d8SChris Lattner //===-- CommandObjectRegister.cpp -------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner 1093a64300SDaniel Malea #include "lldb/lldb-python.h" 1193a64300SDaniel Malea 1230fdc8d8SChris Lattner #include "CommandObjectRegister.h" 1330fdc8d8SChris Lattner 1430fdc8d8SChris Lattner // C Includes 1530fdc8d8SChris Lattner // C++ Includes 1630fdc8d8SChris Lattner // Other libraries and framework includes 1730fdc8d8SChris Lattner // Project includes 1830fdc8d8SChris Lattner #include "lldb/Core/DataExtractor.h" 197349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h" 2030fdc8d8SChris Lattner #include "lldb/Core/Scalar.h" 216611103cSGreg Clayton #include "lldb/Core/Debugger.h" 226611103cSGreg Clayton #include "lldb/Interpreter/Args.h" 236611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 2430fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 25eb0103f2SGreg Clayton #include "lldb/Interpreter/Options.h" 261deb7962SGreg Clayton #include "lldb/Interpreter/OptionGroupFormat.h" 2767cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueArray.h" 2867cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueUInt64.h" 2930fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h" 308f7770f8SGreg Clayton #include "lldb/Target/Process.h" 3130fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 32d5944cd1SGreg Clayton #include "lldb/Target/SectionLoadList.h" 338f7770f8SGreg Clayton #include "lldb/Target/Thread.h" 3428606954SSaleem Abdulrasool #include "llvm/ADT/STLExtras.h" 3530fdc8d8SChris Lattner 3630fdc8d8SChris Lattner using namespace lldb; 3730fdc8d8SChris Lattner using namespace lldb_private; 3830fdc8d8SChris Lattner 3930fdc8d8SChris Lattner //---------------------------------------------------------------------- 4030fdc8d8SChris Lattner // "register read" 4130fdc8d8SChris Lattner //---------------------------------------------------------------------- 425a988416SJim Ingham class CommandObjectRegisterRead : public CommandObjectParsed 4330fdc8d8SChris Lattner { 4430fdc8d8SChris Lattner public: 45a7015092SGreg Clayton CommandObjectRegisterRead (CommandInterpreter &interpreter) : 465a988416SJim Ingham CommandObjectParsed (interpreter, 47a7015092SGreg Clayton "register read", 48405fe67fSCaroline Tice "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.", 49405fe67fSCaroline Tice NULL, 50f9fc609fSGreg Clayton eFlagRequiresFrame | 51f9fc609fSGreg Clayton eFlagRequiresRegContext | 52f9fc609fSGreg Clayton eFlagProcessMustBeLaunched | 53f9fc609fSGreg Clayton eFlagProcessMustBePaused ), 541deb7962SGreg Clayton m_option_group (interpreter), 551deb7962SGreg Clayton m_format_options (eFormatDefault), 561deb7962SGreg Clayton m_command_options () 5730fdc8d8SChris Lattner { 58405fe67fSCaroline Tice CommandArgumentEntry arg; 59405fe67fSCaroline Tice CommandArgumentData register_arg; 60405fe67fSCaroline Tice 61405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 62405fe67fSCaroline Tice register_arg.arg_type = eArgTypeRegisterName; 63405fe67fSCaroline Tice register_arg.arg_repetition = eArgRepeatStar; 64405fe67fSCaroline Tice 65405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 66405fe67fSCaroline Tice arg.push_back (register_arg); 67405fe67fSCaroline Tice 68405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 69405fe67fSCaroline Tice m_arguments.push_back (arg); 701deb7962SGreg Clayton 711deb7962SGreg Clayton // Add the "--format" 725009f9d5SGreg Clayton m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_ALL); 731deb7962SGreg Clayton m_option_group.Append (&m_command_options); 741deb7962SGreg Clayton m_option_group.Finalize(); 751deb7962SGreg Clayton 7630fdc8d8SChris Lattner } 7730fdc8d8SChris Lattner 7830fdc8d8SChris Lattner virtual 7930fdc8d8SChris Lattner ~CommandObjectRegisterRead () 8030fdc8d8SChris Lattner { 8130fdc8d8SChris Lattner } 8230fdc8d8SChris Lattner 8332e0a750SGreg Clayton Options * 8432e0a750SGreg Clayton GetOptions () 8532e0a750SGreg Clayton { 861deb7962SGreg Clayton return &m_option_group; 8732e0a750SGreg Clayton } 8832e0a750SGreg Clayton 89385aa28cSGreg Clayton bool 90385aa28cSGreg Clayton DumpRegister (const ExecutionContext &exe_ctx, 91385aa28cSGreg Clayton Stream &strm, 92385aa28cSGreg Clayton RegisterContext *reg_ctx, 93385aa28cSGreg Clayton const RegisterInfo *reg_info) 94385aa28cSGreg Clayton { 95385aa28cSGreg Clayton if (reg_info) 96385aa28cSGreg Clayton { 977349bd90SGreg Clayton RegisterValue reg_value; 98385aa28cSGreg Clayton 997349bd90SGreg Clayton if (reg_ctx->ReadRegister (reg_info, reg_value)) 100385aa28cSGreg Clayton { 101385aa28cSGreg Clayton strm.Indent (); 102385aa28cSGreg Clayton 1039076c0ffSSean Callanan bool prefix_with_altname = (bool)m_command_options.alternate_name; 1049a8fa916SGreg Clayton bool prefix_with_name = !prefix_with_altname; 105c4392d2aSJohnny Chen reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname, m_format_options.GetFormat(), 8); 1061ac04c30SGreg Clayton if ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint)) 1071ac04c30SGreg Clayton { 1081ac04c30SGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 1091ac04c30SGreg Clayton if (process && reg_info->byte_size == process->GetAddressByteSize()) 110385aa28cSGreg Clayton { 1117349bd90SGreg Clayton addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS); 1127349bd90SGreg Clayton if (reg_addr != LLDB_INVALID_ADDRESS) 113385aa28cSGreg Clayton { 114385aa28cSGreg Clayton Address so_reg_addr; 115c14ee32dSGreg Clayton if (exe_ctx.GetTargetRef().GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr)) 116385aa28cSGreg Clayton { 117385aa28cSGreg Clayton strm.PutCString (" "); 118385aa28cSGreg Clayton so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription); 119385aa28cSGreg Clayton } 120385aa28cSGreg Clayton } 121385aa28cSGreg Clayton } 1221ac04c30SGreg Clayton } 123385aa28cSGreg Clayton strm.EOL(); 124385aa28cSGreg Clayton return true; 125385aa28cSGreg Clayton } 126385aa28cSGreg Clayton } 127385aa28cSGreg Clayton return false; 128385aa28cSGreg Clayton } 129385aa28cSGreg Clayton 130385aa28cSGreg Clayton bool 131385aa28cSGreg Clayton DumpRegisterSet (const ExecutionContext &exe_ctx, 132385aa28cSGreg Clayton Stream &strm, 133385aa28cSGreg Clayton RegisterContext *reg_ctx, 134c7bece56SGreg Clayton size_t set_idx, 1356d4d4f7dSJohnny Chen bool primitive_only=false) 136385aa28cSGreg Clayton { 137385aa28cSGreg Clayton uint32_t unavailable_count = 0; 138385aa28cSGreg Clayton uint32_t available_count = 0; 1394f5f39acSAshok Thirumurthi 1404f5f39acSAshok Thirumurthi if (!reg_ctx) 1414f5f39acSAshok Thirumurthi return false; // thread has no registers (i.e. core files are corrupt, incomplete crash logs...) 1424f5f39acSAshok Thirumurthi 143385aa28cSGreg Clayton const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx); 144385aa28cSGreg Clayton if (reg_set) 145385aa28cSGreg Clayton { 146385aa28cSGreg Clayton strm.Printf ("%s:\n", reg_set->name); 147385aa28cSGreg Clayton strm.IndentMore (); 148c7bece56SGreg Clayton const size_t num_registers = reg_set->num_registers; 149c7bece56SGreg Clayton for (size_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) 150385aa28cSGreg Clayton { 151385aa28cSGreg Clayton const uint32_t reg = reg_set->registers[reg_idx]; 1526d4d4f7dSJohnny Chen const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg); 1536d4d4f7dSJohnny Chen // Skip the dumping of derived register if primitive_only is true. 1546d4d4f7dSJohnny Chen if (primitive_only && reg_info && reg_info->value_regs) 1556d4d4f7dSJohnny Chen continue; 1564f5f39acSAshok Thirumurthi 1576d4d4f7dSJohnny Chen if (DumpRegister (exe_ctx, strm, reg_ctx, reg_info)) 158385aa28cSGreg Clayton ++available_count; 159385aa28cSGreg Clayton else 160385aa28cSGreg Clayton ++unavailable_count; 161385aa28cSGreg Clayton } 162385aa28cSGreg Clayton strm.IndentLess (); 163385aa28cSGreg Clayton if (unavailable_count) 164385aa28cSGreg Clayton { 165385aa28cSGreg Clayton strm.Indent (); 166385aa28cSGreg Clayton strm.Printf("%u registers were unavailable.\n", unavailable_count); 167385aa28cSGreg Clayton } 168385aa28cSGreg Clayton strm.EOL(); 169385aa28cSGreg Clayton } 170385aa28cSGreg Clayton return available_count > 0; 171385aa28cSGreg Clayton } 172385aa28cSGreg Clayton 1735a988416SJim Ingham protected: 17430fdc8d8SChris Lattner virtual bool 1755a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 17630fdc8d8SChris Lattner { 177385aa28cSGreg Clayton Stream &strm = result.GetOutputStream(); 178f9fc609fSGreg Clayton RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext (); 17930fdc8d8SChris Lattner 18030fdc8d8SChris Lattner const RegisterInfo *reg_info = NULL; 18130fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 18230fdc8d8SChris Lattner { 183c7bece56SGreg Clayton size_t set_idx; 184385aa28cSGreg Clayton 185c7bece56SGreg Clayton size_t num_register_sets = 1; 186c7bece56SGreg Clayton const size_t set_array_size = m_command_options.set_indexes.GetSize(); 187385aa28cSGreg Clayton if (set_array_size > 0) 18830fdc8d8SChris Lattner { 189c7bece56SGreg Clayton for (size_t i=0; i<set_array_size; ++i) 19030fdc8d8SChris Lattner { 1911deb7962SGreg Clayton set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL); 1924f5f39acSAshok Thirumurthi if (set_idx < reg_ctx->GetRegisterSetCount()) 19330fdc8d8SChris Lattner { 194f9fc609fSGreg Clayton if (!DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx)) 195385aa28cSGreg Clayton { 1964f5f39acSAshok Thirumurthi if (errno) 197789cefb8SSylvestre Ledru result.AppendErrorWithFormat ("register read failed: %s\n", strerror(errno)); 1984f5f39acSAshok Thirumurthi else 1994f5f39acSAshok Thirumurthi result.AppendError ("unknown error while reading registers.\n"); 200385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 201385aa28cSGreg Clayton break; 202385aa28cSGreg Clayton } 20330fdc8d8SChris Lattner } 20430fdc8d8SChris Lattner else 20530fdc8d8SChris Lattner { 20699fbc076SDeepak Panickal result.AppendErrorWithFormat("invalid register set index: %" PRIu64 "\n", (uint64_t)set_idx); 207385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 208385aa28cSGreg Clayton break; 20930fdc8d8SChris Lattner } 21030fdc8d8SChris Lattner } 211385aa28cSGreg Clayton } 212385aa28cSGreg Clayton else 21330fdc8d8SChris Lattner { 2141deb7962SGreg Clayton if (m_command_options.dump_all_sets) 215385aa28cSGreg Clayton num_register_sets = reg_ctx->GetRegisterSetCount(); 216385aa28cSGreg Clayton 217385aa28cSGreg Clayton for (set_idx = 0; set_idx < num_register_sets; ++set_idx) 218385aa28cSGreg Clayton { 2196d4d4f7dSJohnny Chen // When dump_all_sets option is set, dump primitive as well as derived registers. 220f9fc609fSGreg Clayton DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx, !m_command_options.dump_all_sets.GetCurrentValue()); 22130fdc8d8SChris Lattner } 22230fdc8d8SChris Lattner } 22330fdc8d8SChris Lattner } 22430fdc8d8SChris Lattner else 22530fdc8d8SChris Lattner { 2261deb7962SGreg Clayton if (m_command_options.dump_all_sets) 227385aa28cSGreg Clayton { 228385aa28cSGreg Clayton result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n"); 229385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 230385aa28cSGreg Clayton } 2311deb7962SGreg Clayton else if (m_command_options.set_indexes.GetSize() > 0) 232385aa28cSGreg Clayton { 233385aa28cSGreg Clayton result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n"); 234385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 235385aa28cSGreg Clayton } 236385aa28cSGreg Clayton else 237385aa28cSGreg Clayton { 23830fdc8d8SChris Lattner const char *arg_cstr; 23930fdc8d8SChris Lattner for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 24030fdc8d8SChris Lattner { 2412f59302cSEnrico Granata // in most LLDB commands we accept $rbx as the name for register RBX - and here we would 2422f59302cSEnrico Granata // reject it and non-existant. we should be more consistent towards the user and allow them 2432f59302cSEnrico Granata // to say reg read $rbx - internally, however, we should be strict and not allow ourselves 2442f59302cSEnrico Granata // to call our registers $rbx in our own API 2452f59302cSEnrico Granata if (*arg_cstr == '$') 2462f59302cSEnrico Granata arg_cstr = arg_cstr+1; 247385aa28cSGreg Clayton reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr); 24830fdc8d8SChris Lattner 24930fdc8d8SChris Lattner if (reg_info) 25030fdc8d8SChris Lattner { 251f9fc609fSGreg Clayton if (!DumpRegister (m_exe_ctx, strm, reg_ctx, reg_info)) 252385aa28cSGreg Clayton strm.Printf("%-12s = error: unavailable\n", reg_info->name); 25330fdc8d8SChris Lattner } 25430fdc8d8SChris Lattner else 25530fdc8d8SChris Lattner { 25630fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); 25730fdc8d8SChris Lattner } 25830fdc8d8SChris Lattner } 25930fdc8d8SChris Lattner } 26030fdc8d8SChris Lattner } 26130fdc8d8SChris Lattner return result.Succeeded(); 26230fdc8d8SChris Lattner } 26332e0a750SGreg Clayton 2641deb7962SGreg Clayton class CommandOptions : public OptionGroup 26532e0a750SGreg Clayton { 26632e0a750SGreg Clayton public: 2671deb7962SGreg Clayton CommandOptions () : 2681deb7962SGreg Clayton OptionGroup(), 269385aa28cSGreg Clayton set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)), 2709a8fa916SGreg Clayton dump_all_sets (false, false), // Initial and default values are false 2719a8fa916SGreg Clayton alternate_name (false, false) 27232e0a750SGreg Clayton { 27332e0a750SGreg Clayton } 27432e0a750SGreg Clayton 27532e0a750SGreg Clayton virtual 27632e0a750SGreg Clayton ~CommandOptions () 27732e0a750SGreg Clayton { 27832e0a750SGreg Clayton } 27932e0a750SGreg Clayton 2801deb7962SGreg Clayton 2811deb7962SGreg Clayton virtual uint32_t 2821deb7962SGreg Clayton GetNumDefinitions (); 2831deb7962SGreg Clayton 2841deb7962SGreg Clayton virtual const OptionDefinition* 2851deb7962SGreg Clayton GetDefinitions () 2861deb7962SGreg Clayton { 2871deb7962SGreg Clayton return g_option_table; 2881deb7962SGreg Clayton } 2891deb7962SGreg Clayton 2901deb7962SGreg Clayton virtual void 2911deb7962SGreg Clayton OptionParsingStarting (CommandInterpreter &interpreter) 2921deb7962SGreg Clayton { 2931deb7962SGreg Clayton set_indexes.Clear(); 2941deb7962SGreg Clayton dump_all_sets.Clear(); 2951deb7962SGreg Clayton alternate_name.Clear(); 2961deb7962SGreg Clayton } 2971deb7962SGreg Clayton 29832e0a750SGreg Clayton virtual Error 2991deb7962SGreg Clayton SetOptionValue (CommandInterpreter &interpreter, 3001deb7962SGreg Clayton uint32_t option_idx, 3011deb7962SGreg Clayton const char *option_value) 30232e0a750SGreg Clayton { 30332e0a750SGreg Clayton Error error; 3043bcdfc0eSGreg Clayton const int short_option = g_option_table[option_idx].short_option; 30532e0a750SGreg Clayton switch (short_option) 30632e0a750SGreg Clayton { 307385aa28cSGreg Clayton case 's': 308385aa28cSGreg Clayton { 3091deb7962SGreg Clayton OptionValueSP value_sp (OptionValueUInt64::Create (option_value, error)); 310385aa28cSGreg Clayton if (value_sp) 311385aa28cSGreg Clayton set_indexes.AppendValue (value_sp); 312385aa28cSGreg Clayton } 313385aa28cSGreg Clayton break; 314385aa28cSGreg Clayton 315385aa28cSGreg Clayton case 'a': 3169a8fa916SGreg Clayton // When we don't use OptionValue::SetValueFromCString(const char *) to 3179a8fa916SGreg Clayton // set an option value, it won't be marked as being set in the options 3189a8fa916SGreg Clayton // so we make a call to let users know the value was set via option 319385aa28cSGreg Clayton dump_all_sets.SetCurrentValue (true); 3209a8fa916SGreg Clayton dump_all_sets.SetOptionWasSet (); 3219a8fa916SGreg Clayton break; 3229a8fa916SGreg Clayton 3239a8fa916SGreg Clayton case 'A': 3249a8fa916SGreg Clayton // When we don't use OptionValue::SetValueFromCString(const char *) to 3259a8fa916SGreg Clayton // set an option value, it won't be marked as being set in the options 3269a8fa916SGreg Clayton // so we make a call to let users know the value was set via option 3279a8fa916SGreg Clayton alternate_name.SetCurrentValue (true); 3289a8fa916SGreg Clayton dump_all_sets.SetOptionWasSet (); 329385aa28cSGreg Clayton break; 330385aa28cSGreg Clayton 33132e0a750SGreg Clayton default: 33286edbf41SGreg Clayton error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); 33332e0a750SGreg Clayton break; 33432e0a750SGreg Clayton } 33532e0a750SGreg Clayton return error; 33632e0a750SGreg Clayton } 33732e0a750SGreg Clayton 33832e0a750SGreg Clayton // Options table: Required for subclasses of Options. 33932e0a750SGreg Clayton 3401deb7962SGreg Clayton static const OptionDefinition g_option_table[]; 34132e0a750SGreg Clayton 34232e0a750SGreg Clayton // Instance variables to hold the values for command options. 343385aa28cSGreg Clayton OptionValueArray set_indexes; 344385aa28cSGreg Clayton OptionValueBoolean dump_all_sets; 3459a8fa916SGreg Clayton OptionValueBoolean alternate_name; 34630fdc8d8SChris Lattner }; 34730fdc8d8SChris Lattner 3481deb7962SGreg Clayton OptionGroupOptions m_option_group; 3491deb7962SGreg Clayton OptionGroupFormat m_format_options; 3501deb7962SGreg Clayton CommandOptions m_command_options; 35132e0a750SGreg Clayton }; 35232e0a750SGreg Clayton 3533d0fcf5eSJohnny Chen const OptionDefinition 35432e0a750SGreg Clayton CommandObjectRegisterRead::CommandOptions::g_option_table[] = 35532e0a750SGreg Clayton { 356*d37221dcSZachary Turner { LLDB_OPT_SET_ALL, false, "alternate", 'A', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone , "Display register names using the alternate register name if there is one."}, 357*d37221dcSZachary Turner { LLDB_OPT_SET_1 , false, "set" , 's', OptionParser::eRequiredArgument, NULL, NULL, 0, eArgTypeIndex , "Specify which register sets to dump by index."}, 358*d37221dcSZachary Turner { LLDB_OPT_SET_2 , false, "all" , 'a', OptionParser::eNoArgument , NULL, NULL, 0, eArgTypeNone , "Show all register sets."}, 35932e0a750SGreg Clayton }; 36032e0a750SGreg Clayton 3611deb7962SGreg Clayton uint32_t 3621deb7962SGreg Clayton CommandObjectRegisterRead::CommandOptions::GetNumDefinitions () 3631deb7962SGreg Clayton { 36428606954SSaleem Abdulrasool return llvm::array_lengthof(g_option_table); 3651deb7962SGreg Clayton } 36632e0a750SGreg Clayton 36730fdc8d8SChris Lattner 36830fdc8d8SChris Lattner //---------------------------------------------------------------------- 36930fdc8d8SChris Lattner // "register write" 37030fdc8d8SChris Lattner //---------------------------------------------------------------------- 3715a988416SJim Ingham class CommandObjectRegisterWrite : public CommandObjectParsed 37230fdc8d8SChris Lattner { 37330fdc8d8SChris Lattner public: 374a7015092SGreg Clayton CommandObjectRegisterWrite (CommandInterpreter &interpreter) : 3755a988416SJim Ingham CommandObjectParsed (interpreter, 376a7015092SGreg Clayton "register write", 37730fdc8d8SChris Lattner "Modify a single register value.", 378405fe67fSCaroline Tice NULL, 379f9fc609fSGreg Clayton eFlagRequiresFrame | 380f9fc609fSGreg Clayton eFlagRequiresRegContext | 381f9fc609fSGreg Clayton eFlagProcessMustBeLaunched | 382f9fc609fSGreg Clayton eFlagProcessMustBePaused) 38330fdc8d8SChris Lattner { 384405fe67fSCaroline Tice CommandArgumentEntry arg1; 385405fe67fSCaroline Tice CommandArgumentEntry arg2; 386405fe67fSCaroline Tice CommandArgumentData register_arg; 387405fe67fSCaroline Tice CommandArgumentData value_arg; 388405fe67fSCaroline Tice 389405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 390405fe67fSCaroline Tice register_arg.arg_type = eArgTypeRegisterName; 391405fe67fSCaroline Tice register_arg.arg_repetition = eArgRepeatPlain; 392405fe67fSCaroline Tice 393405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 394405fe67fSCaroline Tice arg1.push_back (register_arg); 395405fe67fSCaroline Tice 396405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 397405fe67fSCaroline Tice value_arg.arg_type = eArgTypeValue; 398405fe67fSCaroline Tice value_arg.arg_repetition = eArgRepeatPlain; 399405fe67fSCaroline Tice 400405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 401405fe67fSCaroline Tice arg2.push_back (value_arg); 402405fe67fSCaroline Tice 403405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 404405fe67fSCaroline Tice m_arguments.push_back (arg1); 405405fe67fSCaroline Tice m_arguments.push_back (arg2); 40630fdc8d8SChris Lattner } 40730fdc8d8SChris Lattner 40830fdc8d8SChris Lattner virtual 40930fdc8d8SChris Lattner ~CommandObjectRegisterWrite () 41030fdc8d8SChris Lattner { 41130fdc8d8SChris Lattner } 41230fdc8d8SChris Lattner 4135a988416SJim Ingham protected: 41430fdc8d8SChris Lattner virtual bool 4155a988416SJim Ingham DoExecute(Args& command, CommandReturnObject &result) 41630fdc8d8SChris Lattner { 41730fdc8d8SChris Lattner DataExtractor reg_data; 418f9fc609fSGreg Clayton RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext (); 41930fdc8d8SChris Lattner 42030fdc8d8SChris Lattner if (command.GetArgumentCount() != 2) 42130fdc8d8SChris Lattner { 42230fdc8d8SChris Lattner result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>"); 42330fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 42430fdc8d8SChris Lattner } 42530fdc8d8SChris Lattner else 42630fdc8d8SChris Lattner { 42730fdc8d8SChris Lattner const char *reg_name = command.GetArgumentAtIndex(0); 42830fdc8d8SChris Lattner const char *value_str = command.GetArgumentAtIndex(1); 4292f59302cSEnrico Granata 4302f59302cSEnrico Granata 4312f59302cSEnrico Granata // in most LLDB commands we accept $rbx as the name for register RBX - and here we would 4322f59302cSEnrico Granata // reject it and non-existant. we should be more consistent towards the user and allow them 4332f59302cSEnrico Granata // to say reg write $rbx - internally, however, we should be strict and not allow ourselves 4342f59302cSEnrico Granata // to call our registers $rbx in our own API 4352f59302cSEnrico Granata if (reg_name && *reg_name == '$') 4362f59302cSEnrico Granata reg_name = reg_name+1; 4372f59302cSEnrico Granata 438385aa28cSGreg Clayton const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); 43930fdc8d8SChris Lattner 44030fdc8d8SChris Lattner if (reg_info) 44130fdc8d8SChris Lattner { 4427349bd90SGreg Clayton RegisterValue reg_value; 4437349bd90SGreg Clayton 4447349bd90SGreg Clayton Error error (reg_value.SetValueFromCString (reg_info, value_str)); 44530fdc8d8SChris Lattner if (error.Success()) 44630fdc8d8SChris Lattner { 4477349bd90SGreg Clayton if (reg_ctx->WriteRegister (reg_info, reg_value)) 44830fdc8d8SChris Lattner { 449fa559e5cSGreg Clayton // Toss all frames and anything else in the thread 450fa559e5cSGreg Clayton // after a register has been written. 451f9fc609fSGreg Clayton m_exe_ctx.GetThreadRef().Flush(); 45230fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 45330fdc8d8SChris Lattner return true; 45430fdc8d8SChris Lattner } 45530fdc8d8SChris Lattner } 456b1ad65c5SJason Molenda if (error.AsCString()) 45730fdc8d8SChris Lattner { 45830fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n", 45930fdc8d8SChris Lattner reg_name, 46030fdc8d8SChris Lattner value_str, 46130fdc8d8SChris Lattner error.AsCString()); 46230fdc8d8SChris Lattner } 463b1ad65c5SJason Molenda else 464b1ad65c5SJason Molenda { 465b1ad65c5SJason Molenda result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'", 466b1ad65c5SJason Molenda reg_name, 467b1ad65c5SJason Molenda value_str); 468b1ad65c5SJason Molenda } 469b1ad65c5SJason Molenda result.SetStatus (eReturnStatusFailed); 47030fdc8d8SChris Lattner } 47130fdc8d8SChris Lattner else 47230fdc8d8SChris Lattner { 47330fdc8d8SChris Lattner result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name); 47430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 47530fdc8d8SChris Lattner } 47630fdc8d8SChris Lattner } 47730fdc8d8SChris Lattner return result.Succeeded(); 47830fdc8d8SChris Lattner } 47930fdc8d8SChris Lattner }; 48030fdc8d8SChris Lattner 48130fdc8d8SChris Lattner 48230fdc8d8SChris Lattner //---------------------------------------------------------------------- 48330fdc8d8SChris Lattner // CommandObjectRegister constructor 48430fdc8d8SChris Lattner //---------------------------------------------------------------------- 4856611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) : 486a7015092SGreg Clayton CommandObjectMultiword (interpreter, 487a7015092SGreg Clayton "register", 4883f4c09c1SCaroline Tice "A set of commands to access thread registers.", 48930fdc8d8SChris Lattner "register [read|write] ...") 49030fdc8d8SChris Lattner { 491a7015092SGreg Clayton LoadSubCommand ("read", CommandObjectSP (new CommandObjectRegisterRead (interpreter))); 492a7015092SGreg Clayton LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter))); 49330fdc8d8SChris Lattner } 49430fdc8d8SChris Lattner 49530fdc8d8SChris Lattner 49630fdc8d8SChris Lattner //---------------------------------------------------------------------- 49730fdc8d8SChris Lattner // Destructor 49830fdc8d8SChris Lattner //---------------------------------------------------------------------- 49930fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister() 50030fdc8d8SChris Lattner { 50130fdc8d8SChris Lattner } 502