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" 251deb7962SGreg Clayton #include "lldb/Interpreter/OptionGroupFormat.h" 2630fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h" 278f7770f8SGreg Clayton #include "lldb/Target/Process.h" 2830fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h" 298f7770f8SGreg Clayton #include "lldb/Target/Thread.h" 3030fdc8d8SChris Lattner 3130fdc8d8SChris Lattner using namespace lldb; 3230fdc8d8SChris Lattner using namespace lldb_private; 3330fdc8d8SChris Lattner 3430fdc8d8SChris Lattner //---------------------------------------------------------------------- 3530fdc8d8SChris Lattner // "register read" 3630fdc8d8SChris Lattner //---------------------------------------------------------------------- 3730fdc8d8SChris Lattner class CommandObjectRegisterRead : public CommandObject 3830fdc8d8SChris Lattner { 3930fdc8d8SChris Lattner public: 40a7015092SGreg Clayton CommandObjectRegisterRead (CommandInterpreter &interpreter) : 41a7015092SGreg Clayton CommandObject (interpreter, 42a7015092SGreg Clayton "register read", 43405fe67fSCaroline Tice "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.", 44405fe67fSCaroline Tice //"register read [<reg-name1> [<reg-name2> [...]]]", 45405fe67fSCaroline Tice NULL, 46eb0103f2SGreg Clayton eFlagProcessMustBeLaunched | eFlagProcessMustBePaused), 471deb7962SGreg Clayton m_option_group (interpreter), 481deb7962SGreg Clayton m_format_options (eFormatDefault), 491deb7962SGreg Clayton m_command_options () 5030fdc8d8SChris Lattner { 51405fe67fSCaroline Tice CommandArgumentEntry arg; 52405fe67fSCaroline Tice CommandArgumentData register_arg; 53405fe67fSCaroline Tice 54405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 55405fe67fSCaroline Tice register_arg.arg_type = eArgTypeRegisterName; 56405fe67fSCaroline Tice register_arg.arg_repetition = eArgRepeatStar; 57405fe67fSCaroline Tice 58405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 59405fe67fSCaroline Tice arg.push_back (register_arg); 60405fe67fSCaroline Tice 61405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 62405fe67fSCaroline Tice m_arguments.push_back (arg); 631deb7962SGreg Clayton 641deb7962SGreg Clayton // Add the "--format" 655009f9d5SGreg Clayton m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_ALL); 661deb7962SGreg Clayton m_option_group.Append (&m_command_options); 671deb7962SGreg Clayton m_option_group.Finalize(); 681deb7962SGreg Clayton 6930fdc8d8SChris Lattner } 7030fdc8d8SChris Lattner 7130fdc8d8SChris Lattner virtual 7230fdc8d8SChris Lattner ~CommandObjectRegisterRead () 7330fdc8d8SChris Lattner { 7430fdc8d8SChris Lattner } 7530fdc8d8SChris Lattner 7632e0a750SGreg Clayton Options * 7732e0a750SGreg Clayton GetOptions () 7832e0a750SGreg Clayton { 791deb7962SGreg Clayton return &m_option_group; 8032e0a750SGreg Clayton } 8132e0a750SGreg Clayton 82385aa28cSGreg Clayton bool 83385aa28cSGreg Clayton DumpRegister (const ExecutionContext &exe_ctx, 84385aa28cSGreg Clayton Stream &strm, 85385aa28cSGreg Clayton RegisterContext *reg_ctx, 86385aa28cSGreg Clayton const RegisterInfo *reg_info) 87385aa28cSGreg Clayton { 88385aa28cSGreg Clayton if (reg_info) 89385aa28cSGreg Clayton { 907349bd90SGreg Clayton RegisterValue reg_value; 91385aa28cSGreg Clayton 927349bd90SGreg Clayton if (reg_ctx->ReadRegister (reg_info, reg_value)) 93385aa28cSGreg Clayton { 94385aa28cSGreg Clayton strm.Indent (); 95385aa28cSGreg Clayton 961deb7962SGreg Clayton bool prefix_with_altname = m_command_options.alternate_name; 979a8fa916SGreg Clayton bool prefix_with_name = !prefix_with_altname; 981deb7962SGreg Clayton reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname, m_format_options.GetFormat()); 99*1ac04c30SGreg Clayton if ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint)) 100*1ac04c30SGreg Clayton { 101*1ac04c30SGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 102*1ac04c30SGreg Clayton if (process && reg_info->byte_size == process->GetAddressByteSize()) 103385aa28cSGreg Clayton { 1047349bd90SGreg Clayton addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS); 1057349bd90SGreg Clayton if (reg_addr != LLDB_INVALID_ADDRESS) 106385aa28cSGreg Clayton { 107385aa28cSGreg Clayton Address so_reg_addr; 108c14ee32dSGreg Clayton if (exe_ctx.GetTargetRef().GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr)) 109385aa28cSGreg Clayton { 110385aa28cSGreg Clayton strm.PutCString (" "); 111385aa28cSGreg Clayton so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription); 112385aa28cSGreg Clayton } 113385aa28cSGreg Clayton } 114385aa28cSGreg Clayton } 115*1ac04c30SGreg Clayton } 116385aa28cSGreg Clayton strm.EOL(); 117385aa28cSGreg Clayton return true; 118385aa28cSGreg Clayton } 119385aa28cSGreg Clayton } 120385aa28cSGreg Clayton return false; 121385aa28cSGreg Clayton } 122385aa28cSGreg Clayton 123385aa28cSGreg Clayton bool 124385aa28cSGreg Clayton DumpRegisterSet (const ExecutionContext &exe_ctx, 125385aa28cSGreg Clayton Stream &strm, 126385aa28cSGreg Clayton RegisterContext *reg_ctx, 127385aa28cSGreg Clayton uint32_t set_idx) 128385aa28cSGreg Clayton { 129385aa28cSGreg Clayton uint32_t unavailable_count = 0; 130385aa28cSGreg Clayton uint32_t available_count = 0; 131385aa28cSGreg Clayton const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx); 132385aa28cSGreg Clayton if (reg_set) 133385aa28cSGreg Clayton { 134385aa28cSGreg Clayton strm.Printf ("%s:\n", reg_set->name); 135385aa28cSGreg Clayton strm.IndentMore (); 136385aa28cSGreg Clayton const uint32_t num_registers = reg_set->num_registers; 137385aa28cSGreg Clayton for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) 138385aa28cSGreg Clayton { 139385aa28cSGreg Clayton const uint32_t reg = reg_set->registers[reg_idx]; 140385aa28cSGreg Clayton if (DumpRegister (exe_ctx, strm, reg_ctx, reg_ctx->GetRegisterInfoAtIndex(reg))) 141385aa28cSGreg Clayton ++available_count; 142385aa28cSGreg Clayton else 143385aa28cSGreg Clayton ++unavailable_count; 144385aa28cSGreg Clayton } 145385aa28cSGreg Clayton strm.IndentLess (); 146385aa28cSGreg Clayton if (unavailable_count) 147385aa28cSGreg Clayton { 148385aa28cSGreg Clayton strm.Indent (); 149385aa28cSGreg Clayton strm.Printf("%u registers were unavailable.\n", unavailable_count); 150385aa28cSGreg Clayton } 151385aa28cSGreg Clayton strm.EOL(); 152385aa28cSGreg Clayton } 153385aa28cSGreg Clayton return available_count > 0; 154385aa28cSGreg Clayton } 155385aa28cSGreg Clayton 15630fdc8d8SChris Lattner virtual bool 1576611103cSGreg Clayton Execute 1586611103cSGreg Clayton ( 1596611103cSGreg Clayton Args& command, 1606611103cSGreg Clayton CommandReturnObject &result 1616611103cSGreg Clayton ) 16230fdc8d8SChris Lattner { 163385aa28cSGreg Clayton Stream &strm = result.GetOutputStream(); 1648b82f087SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 165385aa28cSGreg Clayton RegisterContext *reg_ctx = exe_ctx.GetRegisterContext (); 16630fdc8d8SChris Lattner 167385aa28cSGreg Clayton if (reg_ctx) 16830fdc8d8SChris Lattner { 16930fdc8d8SChris Lattner const RegisterInfo *reg_info = NULL; 17030fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 17130fdc8d8SChris Lattner { 17230fdc8d8SChris Lattner uint32_t set_idx; 173385aa28cSGreg Clayton 174385aa28cSGreg Clayton uint32_t num_register_sets = 1; 1751deb7962SGreg Clayton const uint32_t set_array_size = m_command_options.set_indexes.GetSize(); 176385aa28cSGreg Clayton if (set_array_size > 0) 17730fdc8d8SChris Lattner { 178385aa28cSGreg Clayton for (uint32_t i=0; i<set_array_size; ++i) 17930fdc8d8SChris Lattner { 1801deb7962SGreg Clayton set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL); 181385aa28cSGreg Clayton if (set_idx != UINT32_MAX) 18230fdc8d8SChris Lattner { 183385aa28cSGreg Clayton if (!DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx)) 184385aa28cSGreg Clayton { 185385aa28cSGreg Clayton result.AppendErrorWithFormat ("invalid register set index: %u\n", set_idx); 186385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 187385aa28cSGreg Clayton break; 188385aa28cSGreg Clayton } 18930fdc8d8SChris Lattner } 19030fdc8d8SChris Lattner else 19130fdc8d8SChris Lattner { 192385aa28cSGreg Clayton result.AppendError ("invalid register set index\n"); 193385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 194385aa28cSGreg Clayton break; 19530fdc8d8SChris Lattner } 19630fdc8d8SChris Lattner } 197385aa28cSGreg Clayton } 198385aa28cSGreg Clayton else 19930fdc8d8SChris Lattner { 2001deb7962SGreg Clayton if (m_command_options.dump_all_sets) 201385aa28cSGreg Clayton num_register_sets = reg_ctx->GetRegisterSetCount(); 202385aa28cSGreg Clayton 203385aa28cSGreg Clayton for (set_idx = 0; set_idx < num_register_sets; ++set_idx) 204385aa28cSGreg Clayton { 205385aa28cSGreg Clayton DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx); 20630fdc8d8SChris Lattner } 20730fdc8d8SChris Lattner } 20830fdc8d8SChris Lattner } 20930fdc8d8SChris Lattner else 21030fdc8d8SChris Lattner { 2111deb7962SGreg Clayton if (m_command_options.dump_all_sets) 212385aa28cSGreg Clayton { 213385aa28cSGreg Clayton result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n"); 214385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 215385aa28cSGreg Clayton } 2161deb7962SGreg Clayton else if (m_command_options.set_indexes.GetSize() > 0) 217385aa28cSGreg Clayton { 218385aa28cSGreg Clayton result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n"); 219385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 220385aa28cSGreg Clayton } 221385aa28cSGreg Clayton else 222385aa28cSGreg Clayton { 22330fdc8d8SChris Lattner const char *arg_cstr; 22430fdc8d8SChris Lattner for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 22530fdc8d8SChris Lattner { 226385aa28cSGreg Clayton reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr); 22730fdc8d8SChris Lattner 22830fdc8d8SChris Lattner if (reg_info) 22930fdc8d8SChris Lattner { 230385aa28cSGreg Clayton if (!DumpRegister (exe_ctx, strm, reg_ctx, reg_info)) 231385aa28cSGreg Clayton strm.Printf("%-12s = error: unavailable\n", reg_info->name); 23230fdc8d8SChris Lattner } 23330fdc8d8SChris Lattner else 23430fdc8d8SChris Lattner { 23530fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); 23630fdc8d8SChris Lattner } 23730fdc8d8SChris Lattner } 23830fdc8d8SChris Lattner } 23930fdc8d8SChris Lattner } 240385aa28cSGreg Clayton } 24130fdc8d8SChris Lattner else 24230fdc8d8SChris Lattner { 24330fdc8d8SChris Lattner result.AppendError ("no current frame"); 24430fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 24530fdc8d8SChris Lattner } 24630fdc8d8SChris Lattner return result.Succeeded(); 24730fdc8d8SChris Lattner } 24832e0a750SGreg Clayton 2491deb7962SGreg Clayton class CommandOptions : public OptionGroup 25032e0a750SGreg Clayton { 25132e0a750SGreg Clayton public: 2521deb7962SGreg Clayton CommandOptions () : 2531deb7962SGreg Clayton OptionGroup(), 254385aa28cSGreg Clayton set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)), 2559a8fa916SGreg Clayton dump_all_sets (false, false), // Initial and default values are false 2569a8fa916SGreg Clayton alternate_name (false, false) 25732e0a750SGreg Clayton { 25832e0a750SGreg Clayton } 25932e0a750SGreg Clayton 26032e0a750SGreg Clayton virtual 26132e0a750SGreg Clayton ~CommandOptions () 26232e0a750SGreg Clayton { 26332e0a750SGreg Clayton } 26432e0a750SGreg Clayton 2651deb7962SGreg Clayton 2661deb7962SGreg Clayton virtual uint32_t 2671deb7962SGreg Clayton GetNumDefinitions (); 2681deb7962SGreg Clayton 2691deb7962SGreg Clayton virtual const OptionDefinition* 2701deb7962SGreg Clayton GetDefinitions () 2711deb7962SGreg Clayton { 2721deb7962SGreg Clayton return g_option_table; 2731deb7962SGreg Clayton } 2741deb7962SGreg Clayton 2751deb7962SGreg Clayton virtual void 2761deb7962SGreg Clayton OptionParsingStarting (CommandInterpreter &interpreter) 2771deb7962SGreg Clayton { 2781deb7962SGreg Clayton set_indexes.Clear(); 2791deb7962SGreg Clayton dump_all_sets.Clear(); 2801deb7962SGreg Clayton alternate_name.Clear(); 2811deb7962SGreg Clayton } 2821deb7962SGreg Clayton 28332e0a750SGreg Clayton virtual Error 2841deb7962SGreg Clayton SetOptionValue (CommandInterpreter &interpreter, 2851deb7962SGreg Clayton uint32_t option_idx, 2861deb7962SGreg Clayton const char *option_value) 28732e0a750SGreg Clayton { 28832e0a750SGreg Clayton Error error; 2891deb7962SGreg Clayton const char short_option = (char) g_option_table[option_idx].short_option; 29032e0a750SGreg Clayton switch (short_option) 29132e0a750SGreg Clayton { 292385aa28cSGreg Clayton case 's': 293385aa28cSGreg Clayton { 2941deb7962SGreg Clayton OptionValueSP value_sp (OptionValueUInt64::Create (option_value, error)); 295385aa28cSGreg Clayton if (value_sp) 296385aa28cSGreg Clayton set_indexes.AppendValue (value_sp); 297385aa28cSGreg Clayton } 298385aa28cSGreg Clayton break; 299385aa28cSGreg Clayton 300385aa28cSGreg Clayton case 'a': 3019a8fa916SGreg Clayton // When we don't use OptionValue::SetValueFromCString(const char *) to 3029a8fa916SGreg Clayton // set an option value, it won't be marked as being set in the options 3039a8fa916SGreg Clayton // so we make a call to let users know the value was set via option 304385aa28cSGreg Clayton dump_all_sets.SetCurrentValue (true); 3059a8fa916SGreg Clayton dump_all_sets.SetOptionWasSet (); 3069a8fa916SGreg Clayton break; 3079a8fa916SGreg Clayton 3089a8fa916SGreg Clayton case 'A': 3099a8fa916SGreg Clayton // When we don't use OptionValue::SetValueFromCString(const char *) to 3109a8fa916SGreg Clayton // set an option value, it won't be marked as being set in the options 3119a8fa916SGreg Clayton // so we make a call to let users know the value was set via option 3129a8fa916SGreg Clayton alternate_name.SetCurrentValue (true); 3139a8fa916SGreg Clayton dump_all_sets.SetOptionWasSet (); 314385aa28cSGreg Clayton break; 315385aa28cSGreg Clayton 31632e0a750SGreg Clayton default: 31786edbf41SGreg Clayton error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); 31832e0a750SGreg Clayton break; 31932e0a750SGreg Clayton } 32032e0a750SGreg Clayton return error; 32132e0a750SGreg Clayton } 32232e0a750SGreg Clayton 32332e0a750SGreg Clayton // Options table: Required for subclasses of Options. 32432e0a750SGreg Clayton 3251deb7962SGreg Clayton static const OptionDefinition g_option_table[]; 32632e0a750SGreg Clayton 32732e0a750SGreg Clayton // Instance variables to hold the values for command options. 328385aa28cSGreg Clayton OptionValueArray set_indexes; 329385aa28cSGreg Clayton OptionValueBoolean dump_all_sets; 3309a8fa916SGreg Clayton OptionValueBoolean alternate_name; 33130fdc8d8SChris Lattner }; 33230fdc8d8SChris Lattner 3331deb7962SGreg Clayton OptionGroupOptions m_option_group; 3341deb7962SGreg Clayton OptionGroupFormat m_format_options; 3351deb7962SGreg Clayton CommandOptions m_command_options; 33632e0a750SGreg Clayton }; 33732e0a750SGreg Clayton 3383d0fcf5eSJohnny Chen const OptionDefinition 33932e0a750SGreg Clayton CommandObjectRegisterRead::CommandOptions::g_option_table[] = 34032e0a750SGreg Clayton { 3419a8fa916SGreg 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."}, 342385aa28cSGreg Clayton { LLDB_OPT_SET_1 , false, "set" , 's', required_argument, NULL, 0, eArgTypeIndex , "Specify which register sets to dump by index."}, 343385aa28cSGreg Clayton { LLDB_OPT_SET_2 , false, "all" , 'a', no_argument , NULL, 0, eArgTypeNone , "Show all register sets."}, 34432e0a750SGreg Clayton }; 34532e0a750SGreg Clayton 3461deb7962SGreg Clayton uint32_t 3471deb7962SGreg Clayton CommandObjectRegisterRead::CommandOptions::GetNumDefinitions () 3481deb7962SGreg Clayton { 3491deb7962SGreg Clayton return sizeof(g_option_table)/sizeof(OptionDefinition); 3501deb7962SGreg Clayton } 35132e0a750SGreg Clayton 35230fdc8d8SChris Lattner 35330fdc8d8SChris Lattner //---------------------------------------------------------------------- 35430fdc8d8SChris Lattner // "register write" 35530fdc8d8SChris Lattner //---------------------------------------------------------------------- 35630fdc8d8SChris Lattner class CommandObjectRegisterWrite : public CommandObject 35730fdc8d8SChris Lattner { 35830fdc8d8SChris Lattner public: 359a7015092SGreg Clayton CommandObjectRegisterWrite (CommandInterpreter &interpreter) : 360a7015092SGreg Clayton CommandObject (interpreter, 361a7015092SGreg Clayton "register write", 36230fdc8d8SChris Lattner "Modify a single register value.", 363405fe67fSCaroline Tice NULL, 36430fdc8d8SChris Lattner eFlagProcessMustBeLaunched | eFlagProcessMustBePaused) 36530fdc8d8SChris Lattner { 366405fe67fSCaroline Tice CommandArgumentEntry arg1; 367405fe67fSCaroline Tice CommandArgumentEntry arg2; 368405fe67fSCaroline Tice CommandArgumentData register_arg; 369405fe67fSCaroline Tice CommandArgumentData value_arg; 370405fe67fSCaroline Tice 371405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 372405fe67fSCaroline Tice register_arg.arg_type = eArgTypeRegisterName; 373405fe67fSCaroline Tice register_arg.arg_repetition = eArgRepeatPlain; 374405fe67fSCaroline Tice 375405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 376405fe67fSCaroline Tice arg1.push_back (register_arg); 377405fe67fSCaroline Tice 378405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 379405fe67fSCaroline Tice value_arg.arg_type = eArgTypeValue; 380405fe67fSCaroline Tice value_arg.arg_repetition = eArgRepeatPlain; 381405fe67fSCaroline Tice 382405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 383405fe67fSCaroline Tice arg2.push_back (value_arg); 384405fe67fSCaroline Tice 385405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 386405fe67fSCaroline Tice m_arguments.push_back (arg1); 387405fe67fSCaroline Tice m_arguments.push_back (arg2); 38830fdc8d8SChris Lattner } 38930fdc8d8SChris Lattner 39030fdc8d8SChris Lattner virtual 39130fdc8d8SChris Lattner ~CommandObjectRegisterWrite () 39230fdc8d8SChris Lattner { 39330fdc8d8SChris Lattner } 39430fdc8d8SChris Lattner 39530fdc8d8SChris Lattner virtual bool 3966611103cSGreg Clayton Execute 3976611103cSGreg Clayton ( 3986611103cSGreg Clayton Args& command, 3996611103cSGreg Clayton CommandReturnObject &result 4006611103cSGreg Clayton ) 40130fdc8d8SChris Lattner { 40230fdc8d8SChris Lattner DataExtractor reg_data; 4038b82f087SGreg Clayton ExecutionContext exe_ctx(m_interpreter.GetExecutionContext()); 404385aa28cSGreg Clayton RegisterContext *reg_ctx = exe_ctx.GetRegisterContext (); 40530fdc8d8SChris Lattner 406385aa28cSGreg Clayton if (reg_ctx) 40730fdc8d8SChris Lattner { 40830fdc8d8SChris Lattner if (command.GetArgumentCount() != 2) 40930fdc8d8SChris Lattner { 41030fdc8d8SChris Lattner result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>"); 41130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 41230fdc8d8SChris Lattner } 41330fdc8d8SChris Lattner else 41430fdc8d8SChris Lattner { 41530fdc8d8SChris Lattner const char *reg_name = command.GetArgumentAtIndex(0); 41630fdc8d8SChris Lattner const char *value_str = command.GetArgumentAtIndex(1); 417385aa28cSGreg Clayton const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); 41830fdc8d8SChris Lattner 41930fdc8d8SChris Lattner if (reg_info) 42030fdc8d8SChris Lattner { 4217349bd90SGreg Clayton RegisterValue reg_value; 4227349bd90SGreg Clayton 4237349bd90SGreg Clayton Error error (reg_value.SetValueFromCString (reg_info, value_str)); 42430fdc8d8SChris Lattner if (error.Success()) 42530fdc8d8SChris Lattner { 4267349bd90SGreg Clayton if (reg_ctx->WriteRegister (reg_info, reg_value)) 42730fdc8d8SChris Lattner { 42830fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 42930fdc8d8SChris Lattner return true; 43030fdc8d8SChris Lattner } 43130fdc8d8SChris Lattner } 432b1ad65c5SJason Molenda if (error.AsCString()) 43330fdc8d8SChris Lattner { 43430fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n", 43530fdc8d8SChris Lattner reg_name, 43630fdc8d8SChris Lattner value_str, 43730fdc8d8SChris Lattner error.AsCString()); 43830fdc8d8SChris Lattner } 439b1ad65c5SJason Molenda else 440b1ad65c5SJason Molenda { 441b1ad65c5SJason Molenda result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'", 442b1ad65c5SJason Molenda reg_name, 443b1ad65c5SJason Molenda value_str); 444b1ad65c5SJason Molenda } 445b1ad65c5SJason Molenda result.SetStatus (eReturnStatusFailed); 44630fdc8d8SChris Lattner } 44730fdc8d8SChris Lattner else 44830fdc8d8SChris Lattner { 44930fdc8d8SChris Lattner result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name); 45030fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 45130fdc8d8SChris Lattner } 45230fdc8d8SChris Lattner } 45330fdc8d8SChris Lattner } 45430fdc8d8SChris Lattner else 45530fdc8d8SChris Lattner { 45630fdc8d8SChris Lattner result.AppendError ("no current frame"); 45730fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 45830fdc8d8SChris Lattner } 45930fdc8d8SChris Lattner return result.Succeeded(); 46030fdc8d8SChris Lattner } 46130fdc8d8SChris Lattner }; 46230fdc8d8SChris Lattner 46330fdc8d8SChris Lattner 46430fdc8d8SChris Lattner //---------------------------------------------------------------------- 46530fdc8d8SChris Lattner // CommandObjectRegister constructor 46630fdc8d8SChris Lattner //---------------------------------------------------------------------- 4676611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) : 468a7015092SGreg Clayton CommandObjectMultiword (interpreter, 469a7015092SGreg Clayton "register", 4703f4c09c1SCaroline Tice "A set of commands to access thread registers.", 47130fdc8d8SChris Lattner "register [read|write] ...") 47230fdc8d8SChris Lattner { 473a7015092SGreg Clayton LoadSubCommand ("read", CommandObjectSP (new CommandObjectRegisterRead (interpreter))); 474a7015092SGreg Clayton LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter))); 47530fdc8d8SChris Lattner } 47630fdc8d8SChris Lattner 47730fdc8d8SChris Lattner 47830fdc8d8SChris Lattner //---------------------------------------------------------------------- 47930fdc8d8SChris Lattner // Destructor 48030fdc8d8SChris Lattner //---------------------------------------------------------------------- 48130fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister() 48230fdc8d8SChris Lattner { 48330fdc8d8SChris Lattner } 484