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 1030fdc8d8SChris Lattner #include "CommandObjectRegister.h" 1130fdc8d8SChris Lattner 1230fdc8d8SChris Lattner // C Includes 1330fdc8d8SChris Lattner // C++ Includes 1430fdc8d8SChris Lattner // Other libraries and framework includes 1530fdc8d8SChris Lattner // Project includes 1630fdc8d8SChris Lattner #include "lldb/Core/DataExtractor.h" 177349bd90SGreg Clayton #include "lldb/Core/RegisterValue.h" 1830fdc8d8SChris Lattner #include "lldb/Core/Scalar.h" 196611103cSGreg Clayton #include "lldb/Core/Debugger.h" 206611103cSGreg Clayton #include "lldb/Interpreter/Args.h" 216611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h" 2230fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h" 23385aa28cSGreg Clayton #include "lldb/Interpreter/NamedOptionValue.h" 24eb0103f2SGreg Clayton #include "lldb/Interpreter/Options.h" 2530fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h" 268f7770f8SGreg Clayton #include "lldb/Target/Process.h" 2730fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 288f7770f8SGreg Clayton #include "lldb/Target/Thread.h" 2930fdc8d8SChris Lattner 3030fdc8d8SChris Lattner using namespace lldb; 3130fdc8d8SChris Lattner using namespace lldb_private; 3230fdc8d8SChris Lattner 3330fdc8d8SChris Lattner //---------------------------------------------------------------------- 3430fdc8d8SChris Lattner // "register read" 3530fdc8d8SChris Lattner //---------------------------------------------------------------------- 3630fdc8d8SChris Lattner class CommandObjectRegisterRead : public CommandObject 3730fdc8d8SChris Lattner { 3830fdc8d8SChris Lattner public: 39a7015092SGreg Clayton CommandObjectRegisterRead (CommandInterpreter &interpreter) : 40a7015092SGreg Clayton CommandObject (interpreter, 41a7015092SGreg Clayton "register read", 42405fe67fSCaroline Tice "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.", 43405fe67fSCaroline Tice //"register read [<reg-name1> [<reg-name2> [...]]]", 44405fe67fSCaroline Tice NULL, 45eb0103f2SGreg Clayton eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), 46eb0103f2SGreg Clayton m_options (interpreter) 4730fdc8d8SChris Lattner { 48405fe67fSCaroline Tice CommandArgumentEntry arg; 49405fe67fSCaroline Tice CommandArgumentData register_arg; 50405fe67fSCaroline Tice 51405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 52405fe67fSCaroline Tice register_arg.arg_type = eArgTypeRegisterName; 53405fe67fSCaroline Tice register_arg.arg_repetition = eArgRepeatStar; 54405fe67fSCaroline Tice 55405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 56405fe67fSCaroline Tice arg.push_back (register_arg); 57405fe67fSCaroline Tice 58405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 59405fe67fSCaroline Tice m_arguments.push_back (arg); 6030fdc8d8SChris Lattner } 6130fdc8d8SChris Lattner 6230fdc8d8SChris Lattner virtual 6330fdc8d8SChris Lattner ~CommandObjectRegisterRead () 6430fdc8d8SChris Lattner { 6530fdc8d8SChris Lattner } 6630fdc8d8SChris Lattner 6732e0a750SGreg Clayton Options * 6832e0a750SGreg Clayton GetOptions () 6932e0a750SGreg Clayton { 7032e0a750SGreg Clayton return &m_options; 7132e0a750SGreg Clayton } 7232e0a750SGreg Clayton 73385aa28cSGreg Clayton bool 74385aa28cSGreg Clayton DumpRegister (const ExecutionContext &exe_ctx, 75385aa28cSGreg Clayton Stream &strm, 76385aa28cSGreg Clayton RegisterContext *reg_ctx, 77385aa28cSGreg Clayton const RegisterInfo *reg_info) 78385aa28cSGreg Clayton { 79385aa28cSGreg Clayton if (reg_info) 80385aa28cSGreg Clayton { 817349bd90SGreg Clayton RegisterValue reg_value; 82385aa28cSGreg Clayton 837349bd90SGreg Clayton if (reg_ctx->ReadRegister (reg_info, reg_value)) 84385aa28cSGreg Clayton { 85385aa28cSGreg Clayton strm.Indent (); 86385aa28cSGreg Clayton Format format; 87385aa28cSGreg Clayton if (m_options.format == eFormatDefault) 88385aa28cSGreg Clayton format = reg_info->format; 89385aa28cSGreg Clayton else 90385aa28cSGreg Clayton format = m_options.format; 91385aa28cSGreg Clayton 929a8fa916SGreg Clayton bool prefix_with_altname = m_options.alternate_name; 939a8fa916SGreg Clayton bool prefix_with_name = !prefix_with_altname; 949a8fa916SGreg Clayton reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname, m_options.format); 958f7770f8SGreg Clayton if (((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint)) && 968f7770f8SGreg Clayton (reg_info->byte_size == reg_ctx->GetThread().GetProcess().GetAddressByteSize())) 97385aa28cSGreg Clayton { 987349bd90SGreg Clayton addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS); 997349bd90SGreg Clayton if (reg_addr != LLDB_INVALID_ADDRESS) 100385aa28cSGreg Clayton { 101385aa28cSGreg Clayton Address so_reg_addr; 102*c14ee32dSGreg Clayton if (exe_ctx.GetTargetRef().GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr)) 103385aa28cSGreg Clayton { 104385aa28cSGreg Clayton strm.PutCString (" "); 105385aa28cSGreg Clayton so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription); 106385aa28cSGreg Clayton } 107385aa28cSGreg Clayton } 108385aa28cSGreg Clayton } 109385aa28cSGreg Clayton strm.EOL(); 110385aa28cSGreg Clayton return true; 111385aa28cSGreg Clayton } 112385aa28cSGreg Clayton } 113385aa28cSGreg Clayton return false; 114385aa28cSGreg Clayton } 115385aa28cSGreg Clayton 116385aa28cSGreg Clayton bool 117385aa28cSGreg Clayton DumpRegisterSet (const ExecutionContext &exe_ctx, 118385aa28cSGreg Clayton Stream &strm, 119385aa28cSGreg Clayton RegisterContext *reg_ctx, 120385aa28cSGreg Clayton uint32_t set_idx) 121385aa28cSGreg Clayton { 122385aa28cSGreg Clayton uint32_t unavailable_count = 0; 123385aa28cSGreg Clayton uint32_t available_count = 0; 124385aa28cSGreg Clayton const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx); 125385aa28cSGreg Clayton if (reg_set) 126385aa28cSGreg Clayton { 127385aa28cSGreg Clayton strm.Printf ("%s:\n", reg_set->name); 128385aa28cSGreg Clayton strm.IndentMore (); 129385aa28cSGreg Clayton const uint32_t num_registers = reg_set->num_registers; 130385aa28cSGreg Clayton for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) 131385aa28cSGreg Clayton { 132385aa28cSGreg Clayton const uint32_t reg = reg_set->registers[reg_idx]; 133385aa28cSGreg Clayton if (DumpRegister (exe_ctx, strm, reg_ctx, reg_ctx->GetRegisterInfoAtIndex(reg))) 134385aa28cSGreg Clayton ++available_count; 135385aa28cSGreg Clayton else 136385aa28cSGreg Clayton ++unavailable_count; 137385aa28cSGreg Clayton } 138385aa28cSGreg Clayton strm.IndentLess (); 139385aa28cSGreg Clayton if (unavailable_count) 140385aa28cSGreg Clayton { 141385aa28cSGreg Clayton strm.Indent (); 142385aa28cSGreg Clayton strm.Printf("%u registers were unavailable.\n", unavailable_count); 143385aa28cSGreg Clayton } 144385aa28cSGreg Clayton strm.EOL(); 145385aa28cSGreg Clayton } 146385aa28cSGreg Clayton return available_count > 0; 147385aa28cSGreg Clayton } 148385aa28cSGreg Clayton 14930fdc8d8SChris Lattner virtual bool 1506611103cSGreg Clayton Execute 1516611103cSGreg Clayton ( 1526611103cSGreg Clayton Args& command, 1536611103cSGreg Clayton CommandReturnObject &result 1546611103cSGreg Clayton ) 15530fdc8d8SChris Lattner { 156385aa28cSGreg Clayton Stream &strm = result.GetOutputStream(); 1578b82f087SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 158385aa28cSGreg Clayton RegisterContext *reg_ctx = exe_ctx.GetRegisterContext (); 15930fdc8d8SChris Lattner 160385aa28cSGreg Clayton if (reg_ctx) 16130fdc8d8SChris Lattner { 16230fdc8d8SChris Lattner const RegisterInfo *reg_info = NULL; 16330fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 16430fdc8d8SChris Lattner { 16530fdc8d8SChris Lattner uint32_t set_idx; 166385aa28cSGreg Clayton 167385aa28cSGreg Clayton uint32_t num_register_sets = 1; 168385aa28cSGreg Clayton const uint32_t set_array_size = m_options.set_indexes.GetSize(); 169385aa28cSGreg Clayton if (set_array_size > 0) 17030fdc8d8SChris Lattner { 171385aa28cSGreg Clayton for (uint32_t i=0; i<set_array_size; ++i) 17230fdc8d8SChris Lattner { 1737e14f91dSGreg Clayton set_idx = m_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL); 174385aa28cSGreg Clayton if (set_idx != UINT32_MAX) 17530fdc8d8SChris Lattner { 176385aa28cSGreg Clayton if (!DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx)) 177385aa28cSGreg Clayton { 178385aa28cSGreg Clayton result.AppendErrorWithFormat ("invalid register set index: %u\n", set_idx); 179385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 180385aa28cSGreg Clayton break; 181385aa28cSGreg Clayton } 18230fdc8d8SChris Lattner } 18330fdc8d8SChris Lattner else 18430fdc8d8SChris Lattner { 185385aa28cSGreg Clayton result.AppendError ("invalid register set index\n"); 186385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 187385aa28cSGreg Clayton break; 18830fdc8d8SChris Lattner } 18930fdc8d8SChris Lattner } 190385aa28cSGreg Clayton } 191385aa28cSGreg Clayton else 19230fdc8d8SChris Lattner { 193385aa28cSGreg Clayton if (m_options.dump_all_sets) 194385aa28cSGreg Clayton num_register_sets = reg_ctx->GetRegisterSetCount(); 195385aa28cSGreg Clayton 196385aa28cSGreg Clayton for (set_idx = 0; set_idx < num_register_sets; ++set_idx) 197385aa28cSGreg Clayton { 198385aa28cSGreg Clayton DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx); 19930fdc8d8SChris Lattner } 20030fdc8d8SChris Lattner } 20130fdc8d8SChris Lattner } 20230fdc8d8SChris Lattner else 20330fdc8d8SChris Lattner { 204385aa28cSGreg Clayton if (m_options.dump_all_sets) 205385aa28cSGreg Clayton { 206385aa28cSGreg Clayton result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n"); 207385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 208385aa28cSGreg Clayton } 209385aa28cSGreg Clayton else if (m_options.set_indexes.GetSize() > 0) 210385aa28cSGreg Clayton { 211385aa28cSGreg Clayton result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n"); 212385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 213385aa28cSGreg Clayton } 214385aa28cSGreg Clayton else 215385aa28cSGreg Clayton { 21630fdc8d8SChris Lattner const char *arg_cstr; 21730fdc8d8SChris Lattner for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 21830fdc8d8SChris Lattner { 219385aa28cSGreg Clayton reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr); 22030fdc8d8SChris Lattner 22130fdc8d8SChris Lattner if (reg_info) 22230fdc8d8SChris Lattner { 223385aa28cSGreg Clayton if (!DumpRegister (exe_ctx, strm, reg_ctx, reg_info)) 224385aa28cSGreg Clayton strm.Printf("%-12s = error: unavailable\n", reg_info->name); 22530fdc8d8SChris Lattner } 22630fdc8d8SChris Lattner else 22730fdc8d8SChris Lattner { 22830fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); 22930fdc8d8SChris Lattner } 23030fdc8d8SChris Lattner } 23130fdc8d8SChris Lattner } 23230fdc8d8SChris Lattner } 233385aa28cSGreg Clayton } 23430fdc8d8SChris Lattner else 23530fdc8d8SChris Lattner { 23630fdc8d8SChris Lattner result.AppendError ("no current frame"); 23730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 23830fdc8d8SChris Lattner } 23930fdc8d8SChris Lattner return result.Succeeded(); 24030fdc8d8SChris Lattner } 24132e0a750SGreg Clayton 24232e0a750SGreg Clayton protected: 24332e0a750SGreg Clayton class CommandOptions : public Options 24432e0a750SGreg Clayton { 24532e0a750SGreg Clayton public: 246eb0103f2SGreg Clayton CommandOptions (CommandInterpreter &interpreter) : 247385aa28cSGreg Clayton Options(interpreter), 248385aa28cSGreg Clayton set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)), 2499a8fa916SGreg Clayton dump_all_sets (false, false), // Initial and default values are false 2509a8fa916SGreg Clayton alternate_name (false, false) 25132e0a750SGreg Clayton { 252f6b8b581SGreg Clayton OptionParsingStarting(); 25332e0a750SGreg Clayton } 25432e0a750SGreg Clayton 25532e0a750SGreg Clayton virtual 25632e0a750SGreg Clayton ~CommandOptions () 25732e0a750SGreg Clayton { 25832e0a750SGreg Clayton } 25932e0a750SGreg Clayton 26032e0a750SGreg Clayton virtual Error 261f6b8b581SGreg Clayton SetOptionValue (uint32_t option_idx, const char *option_arg) 26232e0a750SGreg Clayton { 26332e0a750SGreg Clayton Error error; 26432e0a750SGreg Clayton char short_option = (char) m_getopt_table[option_idx].val; 26532e0a750SGreg Clayton switch (short_option) 26632e0a750SGreg Clayton { 26732e0a750SGreg Clayton case 'f': 26868ebae61SGreg Clayton error = Args::StringToFormat (option_arg, format, NULL); 269385aa28cSGreg Clayton break; 270385aa28cSGreg Clayton 271385aa28cSGreg Clayton case 's': 272385aa28cSGreg Clayton { 273385aa28cSGreg Clayton OptionValueSP value_sp (OptionValueUInt64::Create (option_arg, error)); 274385aa28cSGreg Clayton if (value_sp) 275385aa28cSGreg Clayton set_indexes.AppendValue (value_sp); 276385aa28cSGreg Clayton } 277385aa28cSGreg Clayton break; 278385aa28cSGreg Clayton 279385aa28cSGreg Clayton case 'a': 2809a8fa916SGreg Clayton // When we don't use OptionValue::SetValueFromCString(const char *) to 2819a8fa916SGreg Clayton // set an option value, it won't be marked as being set in the options 2829a8fa916SGreg Clayton // so we make a call to let users know the value was set via option 283385aa28cSGreg Clayton dump_all_sets.SetCurrentValue (true); 2849a8fa916SGreg Clayton dump_all_sets.SetOptionWasSet (); 2859a8fa916SGreg Clayton break; 2869a8fa916SGreg Clayton 2879a8fa916SGreg Clayton case 'A': 2889a8fa916SGreg Clayton // When we don't use OptionValue::SetValueFromCString(const char *) to 2899a8fa916SGreg Clayton // set an option value, it won't be marked as being set in the options 2909a8fa916SGreg Clayton // so we make a call to let users know the value was set via option 2919a8fa916SGreg Clayton alternate_name.SetCurrentValue (true); 2929a8fa916SGreg Clayton dump_all_sets.SetOptionWasSet (); 293385aa28cSGreg Clayton break; 294385aa28cSGreg Clayton 29532e0a750SGreg Clayton default: 29632e0a750SGreg Clayton error.SetErrorStringWithFormat("Unrecognized short option '%c'\n", short_option); 29732e0a750SGreg Clayton break; 29832e0a750SGreg Clayton } 29932e0a750SGreg Clayton return error; 30032e0a750SGreg Clayton } 30132e0a750SGreg Clayton 30232e0a750SGreg Clayton void 303f6b8b581SGreg Clayton OptionParsingStarting () 30432e0a750SGreg Clayton { 305385aa28cSGreg Clayton format = eFormatDefault; 306385aa28cSGreg Clayton set_indexes.Clear(); 307385aa28cSGreg Clayton dump_all_sets.Clear(); 3089a8fa916SGreg Clayton alternate_name.Clear(); 30932e0a750SGreg Clayton } 31032e0a750SGreg Clayton 31132e0a750SGreg Clayton const OptionDefinition* 31232e0a750SGreg Clayton GetDefinitions () 31332e0a750SGreg Clayton { 31432e0a750SGreg Clayton return g_option_table; 31532e0a750SGreg Clayton } 31632e0a750SGreg Clayton 31732e0a750SGreg Clayton // Options table: Required for subclasses of Options. 31832e0a750SGreg Clayton 31932e0a750SGreg Clayton static OptionDefinition g_option_table[]; 32032e0a750SGreg Clayton 32132e0a750SGreg Clayton // Instance variables to hold the values for command options. 322385aa28cSGreg Clayton lldb::Format format; 323385aa28cSGreg Clayton OptionValueArray set_indexes; 324385aa28cSGreg Clayton OptionValueBoolean dump_all_sets; 3259a8fa916SGreg Clayton OptionValueBoolean alternate_name; 32630fdc8d8SChris Lattner }; 32730fdc8d8SChris Lattner 32832e0a750SGreg Clayton CommandOptions m_options; 32932e0a750SGreg Clayton }; 33032e0a750SGreg Clayton 33132e0a750SGreg Clayton OptionDefinition 33232e0a750SGreg Clayton CommandObjectRegisterRead::CommandOptions::g_option_table[] = 33332e0a750SGreg Clayton { 334385aa28cSGreg Clayton { LLDB_OPT_SET_ALL, false, "format" , 'f', required_argument, NULL, 0, eArgTypeExprFormat, "Specify the format to use when dumping register values."}, 3359a8fa916SGreg Clayton { LLDB_OPT_SET_ALL, false, "alternate", 'A', no_argument , NULL, 0, eArgTypeNone , "Display register names using the alternate register name if there is one."}, 336385aa28cSGreg Clayton { LLDB_OPT_SET_1 , false, "set" , 's', required_argument, NULL, 0, eArgTypeIndex , "Specify which register sets to dump by index."}, 337385aa28cSGreg Clayton { LLDB_OPT_SET_2 , false, "all" , 'a', no_argument , NULL, 0, eArgTypeNone , "Show all register sets."}, 33832e0a750SGreg Clayton { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL } 33932e0a750SGreg Clayton }; 34032e0a750SGreg Clayton 34132e0a750SGreg Clayton 34230fdc8d8SChris Lattner 34330fdc8d8SChris Lattner //---------------------------------------------------------------------- 34430fdc8d8SChris Lattner // "register write" 34530fdc8d8SChris Lattner //---------------------------------------------------------------------- 34630fdc8d8SChris Lattner class CommandObjectRegisterWrite : public CommandObject 34730fdc8d8SChris Lattner { 34830fdc8d8SChris Lattner public: 349a7015092SGreg Clayton CommandObjectRegisterWrite (CommandInterpreter &interpreter) : 350a7015092SGreg Clayton CommandObject (interpreter, 351a7015092SGreg Clayton "register write", 35230fdc8d8SChris Lattner "Modify a single register value.", 353405fe67fSCaroline Tice //"register write <reg-name> <value>", 354405fe67fSCaroline Tice NULL, 35530fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 35630fdc8d8SChris Lattner { 357405fe67fSCaroline Tice CommandArgumentEntry arg1; 358405fe67fSCaroline Tice CommandArgumentEntry arg2; 359405fe67fSCaroline Tice CommandArgumentData register_arg; 360405fe67fSCaroline Tice CommandArgumentData value_arg; 361405fe67fSCaroline Tice 362405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 363405fe67fSCaroline Tice register_arg.arg_type = eArgTypeRegisterName; 364405fe67fSCaroline Tice register_arg.arg_repetition = eArgRepeatPlain; 365405fe67fSCaroline Tice 366405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 367405fe67fSCaroline Tice arg1.push_back (register_arg); 368405fe67fSCaroline Tice 369405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 370405fe67fSCaroline Tice value_arg.arg_type = eArgTypeValue; 371405fe67fSCaroline Tice value_arg.arg_repetition = eArgRepeatPlain; 372405fe67fSCaroline Tice 373405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 374405fe67fSCaroline Tice arg2.push_back (value_arg); 375405fe67fSCaroline Tice 376405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 377405fe67fSCaroline Tice m_arguments.push_back (arg1); 378405fe67fSCaroline Tice m_arguments.push_back (arg2); 37930fdc8d8SChris Lattner } 38030fdc8d8SChris Lattner 38130fdc8d8SChris Lattner virtual 38230fdc8d8SChris Lattner ~CommandObjectRegisterWrite () 38330fdc8d8SChris Lattner { 38430fdc8d8SChris Lattner } 38530fdc8d8SChris Lattner 38630fdc8d8SChris Lattner virtual bool 3876611103cSGreg Clayton Execute 3886611103cSGreg Clayton ( 3896611103cSGreg Clayton Args& command, 3906611103cSGreg Clayton CommandReturnObject &result 3916611103cSGreg Clayton ) 39230fdc8d8SChris Lattner { 39330fdc8d8SChris Lattner DataExtractor reg_data; 3948b82f087SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 395385aa28cSGreg Clayton RegisterContext *reg_ctx = exe_ctx.GetRegisterContext (); 39630fdc8d8SChris Lattner 397385aa28cSGreg Clayton if (reg_ctx) 39830fdc8d8SChris Lattner { 39930fdc8d8SChris Lattner if (command.GetArgumentCount() != 2) 40030fdc8d8SChris Lattner { 40130fdc8d8SChris Lattner result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>"); 40230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 40330fdc8d8SChris Lattner } 40430fdc8d8SChris Lattner else 40530fdc8d8SChris Lattner { 40630fdc8d8SChris Lattner const char *reg_name = command.GetArgumentAtIndex(0); 40730fdc8d8SChris Lattner const char *value_str = command.GetArgumentAtIndex(1); 408385aa28cSGreg Clayton const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); 40930fdc8d8SChris Lattner 41030fdc8d8SChris Lattner if (reg_info) 41130fdc8d8SChris Lattner { 4127349bd90SGreg Clayton RegisterValue reg_value; 4137349bd90SGreg Clayton 4147349bd90SGreg Clayton Error error (reg_value.SetValueFromCString (reg_info, value_str)); 41530fdc8d8SChris Lattner if (error.Success()) 41630fdc8d8SChris Lattner { 4177349bd90SGreg Clayton if (reg_ctx->WriteRegister (reg_info, reg_value)) 41830fdc8d8SChris Lattner { 41930fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 42030fdc8d8SChris Lattner return true; 42130fdc8d8SChris Lattner } 42230fdc8d8SChris Lattner } 423b1ad65c5SJason Molenda if (error.AsCString()) 42430fdc8d8SChris Lattner { 42530fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n", 42630fdc8d8SChris Lattner reg_name, 42730fdc8d8SChris Lattner value_str, 42830fdc8d8SChris Lattner error.AsCString()); 42930fdc8d8SChris Lattner } 430b1ad65c5SJason Molenda else 431b1ad65c5SJason Molenda { 432b1ad65c5SJason Molenda result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'", 433b1ad65c5SJason Molenda reg_name, 434b1ad65c5SJason Molenda value_str); 435b1ad65c5SJason Molenda } 436b1ad65c5SJason Molenda result.SetStatus (eReturnStatusFailed); 43730fdc8d8SChris Lattner } 43830fdc8d8SChris Lattner else 43930fdc8d8SChris Lattner { 44030fdc8d8SChris Lattner result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name); 44130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 44230fdc8d8SChris Lattner } 44330fdc8d8SChris Lattner } 44430fdc8d8SChris Lattner } 44530fdc8d8SChris Lattner else 44630fdc8d8SChris Lattner { 44730fdc8d8SChris Lattner result.AppendError ("no current frame"); 44830fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 44930fdc8d8SChris Lattner } 45030fdc8d8SChris Lattner return result.Succeeded(); 45130fdc8d8SChris Lattner } 45230fdc8d8SChris Lattner }; 45330fdc8d8SChris Lattner 45430fdc8d8SChris Lattner 45530fdc8d8SChris Lattner //---------------------------------------------------------------------- 45630fdc8d8SChris Lattner // CommandObjectRegister constructor 45730fdc8d8SChris Lattner //---------------------------------------------------------------------- 4586611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) : 459a7015092SGreg Clayton CommandObjectMultiword (interpreter, 460a7015092SGreg Clayton "register", 4613f4c09c1SCaroline Tice "A set of commands to access thread registers.", 46230fdc8d8SChris Lattner "register [read|write] ...") 46330fdc8d8SChris Lattner { 464a7015092SGreg Clayton LoadSubCommand ("read", CommandObjectSP (new CommandObjectRegisterRead (interpreter))); 465a7015092SGreg Clayton LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter))); 46630fdc8d8SChris Lattner } 46730fdc8d8SChris Lattner 46830fdc8d8SChris Lattner 46930fdc8d8SChris Lattner //---------------------------------------------------------------------- 47030fdc8d8SChris Lattner // Destructor 47130fdc8d8SChris Lattner //---------------------------------------------------------------------- 47230fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister() 47330fdc8d8SChris Lattner { 47430fdc8d8SChris Lattner } 475