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" 328f7770f8SGreg Clayton #include "lldb/Target/Thread.h" 3330fdc8d8SChris Lattner 3430fdc8d8SChris Lattner using namespace lldb; 3530fdc8d8SChris Lattner using namespace lldb_private; 3630fdc8d8SChris Lattner 3730fdc8d8SChris Lattner //---------------------------------------------------------------------- 3830fdc8d8SChris Lattner // "register read" 3930fdc8d8SChris Lattner //---------------------------------------------------------------------- 405a988416SJim Ingham class CommandObjectRegisterRead : public CommandObjectParsed 4130fdc8d8SChris Lattner { 4230fdc8d8SChris Lattner public: 43a7015092SGreg Clayton CommandObjectRegisterRead (CommandInterpreter &interpreter) : 445a988416SJim Ingham CommandObjectParsed (interpreter, 45a7015092SGreg Clayton "register read", 46405fe67fSCaroline Tice "Dump the contents of one or more register values from the current frame. If no register is specified, dumps them all.", 47405fe67fSCaroline Tice NULL, 48f9fc609fSGreg Clayton eFlagRequiresFrame | 49f9fc609fSGreg Clayton eFlagRequiresRegContext | 50f9fc609fSGreg Clayton eFlagProcessMustBeLaunched | 51f9fc609fSGreg Clayton eFlagProcessMustBePaused ), 521deb7962SGreg Clayton m_option_group (interpreter), 531deb7962SGreg Clayton m_format_options (eFormatDefault), 541deb7962SGreg Clayton m_command_options () 5530fdc8d8SChris Lattner { 56405fe67fSCaroline Tice CommandArgumentEntry arg; 57405fe67fSCaroline Tice CommandArgumentData register_arg; 58405fe67fSCaroline Tice 59405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 60405fe67fSCaroline Tice register_arg.arg_type = eArgTypeRegisterName; 61405fe67fSCaroline Tice register_arg.arg_repetition = eArgRepeatStar; 62405fe67fSCaroline Tice 63405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 64405fe67fSCaroline Tice arg.push_back (register_arg); 65405fe67fSCaroline Tice 66405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 67405fe67fSCaroline Tice m_arguments.push_back (arg); 681deb7962SGreg Clayton 691deb7962SGreg Clayton // Add the "--format" 705009f9d5SGreg Clayton m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_ALL); 711deb7962SGreg Clayton m_option_group.Append (&m_command_options); 721deb7962SGreg Clayton m_option_group.Finalize(); 731deb7962SGreg Clayton 7430fdc8d8SChris Lattner } 7530fdc8d8SChris Lattner 7630fdc8d8SChris Lattner virtual 7730fdc8d8SChris Lattner ~CommandObjectRegisterRead () 7830fdc8d8SChris Lattner { 7930fdc8d8SChris Lattner } 8030fdc8d8SChris Lattner 8132e0a750SGreg Clayton Options * 8232e0a750SGreg Clayton GetOptions () 8332e0a750SGreg Clayton { 841deb7962SGreg Clayton return &m_option_group; 8532e0a750SGreg Clayton } 8632e0a750SGreg Clayton 87385aa28cSGreg Clayton bool 88385aa28cSGreg Clayton DumpRegister (const ExecutionContext &exe_ctx, 89385aa28cSGreg Clayton Stream &strm, 90385aa28cSGreg Clayton RegisterContext *reg_ctx, 91385aa28cSGreg Clayton const RegisterInfo *reg_info) 92385aa28cSGreg Clayton { 93385aa28cSGreg Clayton if (reg_info) 94385aa28cSGreg Clayton { 957349bd90SGreg Clayton RegisterValue reg_value; 96385aa28cSGreg Clayton 977349bd90SGreg Clayton if (reg_ctx->ReadRegister (reg_info, reg_value)) 98385aa28cSGreg Clayton { 99385aa28cSGreg Clayton strm.Indent (); 100385aa28cSGreg Clayton 1011deb7962SGreg Clayton bool prefix_with_altname = m_command_options.alternate_name; 1029a8fa916SGreg Clayton bool prefix_with_name = !prefix_with_altname; 103c4392d2aSJohnny Chen reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname, m_format_options.GetFormat(), 8); 1041ac04c30SGreg Clayton if ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint)) 1051ac04c30SGreg Clayton { 1061ac04c30SGreg Clayton Process *process = exe_ctx.GetProcessPtr(); 1071ac04c30SGreg Clayton if (process && reg_info->byte_size == process->GetAddressByteSize()) 108385aa28cSGreg Clayton { 1097349bd90SGreg Clayton addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS); 1107349bd90SGreg Clayton if (reg_addr != LLDB_INVALID_ADDRESS) 111385aa28cSGreg Clayton { 112385aa28cSGreg Clayton Address so_reg_addr; 113c14ee32dSGreg Clayton if (exe_ctx.GetTargetRef().GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr)) 114385aa28cSGreg Clayton { 115385aa28cSGreg Clayton strm.PutCString (" "); 116385aa28cSGreg Clayton so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription); 117385aa28cSGreg Clayton } 118385aa28cSGreg Clayton } 119385aa28cSGreg Clayton } 1201ac04c30SGreg Clayton } 121385aa28cSGreg Clayton strm.EOL(); 122385aa28cSGreg Clayton return true; 123385aa28cSGreg Clayton } 124385aa28cSGreg Clayton } 125385aa28cSGreg Clayton return false; 126385aa28cSGreg Clayton } 127385aa28cSGreg Clayton 128385aa28cSGreg Clayton bool 129385aa28cSGreg Clayton DumpRegisterSet (const ExecutionContext &exe_ctx, 130385aa28cSGreg Clayton Stream &strm, 131385aa28cSGreg Clayton RegisterContext *reg_ctx, 132c7bece56SGreg Clayton size_t set_idx, 1336d4d4f7dSJohnny Chen bool primitive_only=false) 134385aa28cSGreg Clayton { 135385aa28cSGreg Clayton uint32_t unavailable_count = 0; 136385aa28cSGreg Clayton uint32_t available_count = 0; 1374f5f39acSAshok Thirumurthi 1384f5f39acSAshok Thirumurthi if (!reg_ctx) 1394f5f39acSAshok Thirumurthi return false; // thread has no registers (i.e. core files are corrupt, incomplete crash logs...) 1404f5f39acSAshok Thirumurthi 141385aa28cSGreg Clayton const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx); 142385aa28cSGreg Clayton if (reg_set) 143385aa28cSGreg Clayton { 144385aa28cSGreg Clayton strm.Printf ("%s:\n", reg_set->name); 145385aa28cSGreg Clayton strm.IndentMore (); 146c7bece56SGreg Clayton const size_t num_registers = reg_set->num_registers; 147c7bece56SGreg Clayton for (size_t reg_idx = 0; reg_idx < num_registers; ++reg_idx) 148385aa28cSGreg Clayton { 149385aa28cSGreg Clayton const uint32_t reg = reg_set->registers[reg_idx]; 1506d4d4f7dSJohnny Chen const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg); 1516d4d4f7dSJohnny Chen // Skip the dumping of derived register if primitive_only is true. 1526d4d4f7dSJohnny Chen if (primitive_only && reg_info && reg_info->value_regs) 1536d4d4f7dSJohnny Chen continue; 1544f5f39acSAshok Thirumurthi 1556d4d4f7dSJohnny Chen if (DumpRegister (exe_ctx, strm, reg_ctx, reg_info)) 156385aa28cSGreg Clayton ++available_count; 157385aa28cSGreg Clayton else 158385aa28cSGreg Clayton ++unavailable_count; 159385aa28cSGreg Clayton } 160385aa28cSGreg Clayton strm.IndentLess (); 161385aa28cSGreg Clayton if (unavailable_count) 162385aa28cSGreg Clayton { 163385aa28cSGreg Clayton strm.Indent (); 164385aa28cSGreg Clayton strm.Printf("%u registers were unavailable.\n", unavailable_count); 165385aa28cSGreg Clayton } 166385aa28cSGreg Clayton strm.EOL(); 167385aa28cSGreg Clayton } 168385aa28cSGreg Clayton return available_count > 0; 169385aa28cSGreg Clayton } 170385aa28cSGreg Clayton 1715a988416SJim Ingham protected: 17230fdc8d8SChris Lattner virtual bool 1735a988416SJim Ingham DoExecute (Args& command, CommandReturnObject &result) 17430fdc8d8SChris Lattner { 175385aa28cSGreg Clayton Stream &strm = result.GetOutputStream(); 176f9fc609fSGreg Clayton RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext (); 17730fdc8d8SChris Lattner 17830fdc8d8SChris Lattner const RegisterInfo *reg_info = NULL; 17930fdc8d8SChris Lattner if (command.GetArgumentCount() == 0) 18030fdc8d8SChris Lattner { 181c7bece56SGreg Clayton size_t set_idx; 182385aa28cSGreg Clayton 183c7bece56SGreg Clayton size_t num_register_sets = 1; 184c7bece56SGreg Clayton const size_t set_array_size = m_command_options.set_indexes.GetSize(); 185385aa28cSGreg Clayton if (set_array_size > 0) 18630fdc8d8SChris Lattner { 187c7bece56SGreg Clayton for (size_t i=0; i<set_array_size; ++i) 18830fdc8d8SChris Lattner { 1891deb7962SGreg Clayton set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL); 1904f5f39acSAshok Thirumurthi if (set_idx < reg_ctx->GetRegisterSetCount()) 19130fdc8d8SChris Lattner { 192f9fc609fSGreg Clayton if (!DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx)) 193385aa28cSGreg Clayton { 1944f5f39acSAshok Thirumurthi if (errno) 195*789cefb8SSylvestre Ledru result.AppendErrorWithFormat ("register read failed: %s\n", strerror(errno)); 1964f5f39acSAshok Thirumurthi else 1974f5f39acSAshok Thirumurthi result.AppendError ("unknown error while reading registers.\n"); 198385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 199385aa28cSGreg Clayton break; 200385aa28cSGreg Clayton } 20130fdc8d8SChris Lattner } 20230fdc8d8SChris Lattner else 20330fdc8d8SChris Lattner { 2044f5f39acSAshok Thirumurthi result.AppendErrorWithFormat ("invalid register set index: %zu\n", set_idx); 205385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 206385aa28cSGreg Clayton break; 20730fdc8d8SChris Lattner } 20830fdc8d8SChris Lattner } 209385aa28cSGreg Clayton } 210385aa28cSGreg Clayton else 21130fdc8d8SChris Lattner { 2121deb7962SGreg Clayton if (m_command_options.dump_all_sets) 213385aa28cSGreg Clayton num_register_sets = reg_ctx->GetRegisterSetCount(); 214385aa28cSGreg Clayton 215385aa28cSGreg Clayton for (set_idx = 0; set_idx < num_register_sets; ++set_idx) 216385aa28cSGreg Clayton { 2176d4d4f7dSJohnny Chen // When dump_all_sets option is set, dump primitive as well as derived registers. 218f9fc609fSGreg Clayton DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx, !m_command_options.dump_all_sets.GetCurrentValue()); 21930fdc8d8SChris Lattner } 22030fdc8d8SChris Lattner } 22130fdc8d8SChris Lattner } 22230fdc8d8SChris Lattner else 22330fdc8d8SChris Lattner { 2241deb7962SGreg Clayton if (m_command_options.dump_all_sets) 225385aa28cSGreg Clayton { 226385aa28cSGreg Clayton result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n"); 227385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 228385aa28cSGreg Clayton } 2291deb7962SGreg Clayton else if (m_command_options.set_indexes.GetSize() > 0) 230385aa28cSGreg Clayton { 231385aa28cSGreg Clayton result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n"); 232385aa28cSGreg Clayton result.SetStatus (eReturnStatusFailed); 233385aa28cSGreg Clayton } 234385aa28cSGreg Clayton else 235385aa28cSGreg Clayton { 23630fdc8d8SChris Lattner const char *arg_cstr; 23730fdc8d8SChris Lattner for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx) 23830fdc8d8SChris Lattner { 2392f59302cSEnrico Granata // in most LLDB commands we accept $rbx as the name for register RBX - and here we would 2402f59302cSEnrico Granata // reject it and non-existant. we should be more consistent towards the user and allow them 2412f59302cSEnrico Granata // to say reg read $rbx - internally, however, we should be strict and not allow ourselves 2422f59302cSEnrico Granata // to call our registers $rbx in our own API 2432f59302cSEnrico Granata if (*arg_cstr == '$') 2442f59302cSEnrico Granata arg_cstr = arg_cstr+1; 245385aa28cSGreg Clayton reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr); 24630fdc8d8SChris Lattner 24730fdc8d8SChris Lattner if (reg_info) 24830fdc8d8SChris Lattner { 249f9fc609fSGreg Clayton if (!DumpRegister (m_exe_ctx, strm, reg_ctx, reg_info)) 250385aa28cSGreg Clayton strm.Printf("%-12s = error: unavailable\n", reg_info->name); 25130fdc8d8SChris Lattner } 25230fdc8d8SChris Lattner else 25330fdc8d8SChris Lattner { 25430fdc8d8SChris Lattner result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr); 25530fdc8d8SChris Lattner } 25630fdc8d8SChris Lattner } 25730fdc8d8SChris Lattner } 25830fdc8d8SChris Lattner } 25930fdc8d8SChris Lattner return result.Succeeded(); 26030fdc8d8SChris Lattner } 26132e0a750SGreg Clayton 2621deb7962SGreg Clayton class CommandOptions : public OptionGroup 26332e0a750SGreg Clayton { 26432e0a750SGreg Clayton public: 2651deb7962SGreg Clayton CommandOptions () : 2661deb7962SGreg Clayton OptionGroup(), 267385aa28cSGreg Clayton set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)), 2689a8fa916SGreg Clayton dump_all_sets (false, false), // Initial and default values are false 2699a8fa916SGreg Clayton alternate_name (false, false) 27032e0a750SGreg Clayton { 27132e0a750SGreg Clayton } 27232e0a750SGreg Clayton 27332e0a750SGreg Clayton virtual 27432e0a750SGreg Clayton ~CommandOptions () 27532e0a750SGreg Clayton { 27632e0a750SGreg Clayton } 27732e0a750SGreg Clayton 2781deb7962SGreg Clayton 2791deb7962SGreg Clayton virtual uint32_t 2801deb7962SGreg Clayton GetNumDefinitions (); 2811deb7962SGreg Clayton 2821deb7962SGreg Clayton virtual const OptionDefinition* 2831deb7962SGreg Clayton GetDefinitions () 2841deb7962SGreg Clayton { 2851deb7962SGreg Clayton return g_option_table; 2861deb7962SGreg Clayton } 2871deb7962SGreg Clayton 2881deb7962SGreg Clayton virtual void 2891deb7962SGreg Clayton OptionParsingStarting (CommandInterpreter &interpreter) 2901deb7962SGreg Clayton { 2911deb7962SGreg Clayton set_indexes.Clear(); 2921deb7962SGreg Clayton dump_all_sets.Clear(); 2931deb7962SGreg Clayton alternate_name.Clear(); 2941deb7962SGreg Clayton } 2951deb7962SGreg Clayton 29632e0a750SGreg Clayton virtual Error 2971deb7962SGreg Clayton SetOptionValue (CommandInterpreter &interpreter, 2981deb7962SGreg Clayton uint32_t option_idx, 2991deb7962SGreg Clayton const char *option_value) 30032e0a750SGreg Clayton { 30132e0a750SGreg Clayton Error error; 3023bcdfc0eSGreg Clayton const int short_option = g_option_table[option_idx].short_option; 30332e0a750SGreg Clayton switch (short_option) 30432e0a750SGreg Clayton { 305385aa28cSGreg Clayton case 's': 306385aa28cSGreg Clayton { 3071deb7962SGreg Clayton OptionValueSP value_sp (OptionValueUInt64::Create (option_value, error)); 308385aa28cSGreg Clayton if (value_sp) 309385aa28cSGreg Clayton set_indexes.AppendValue (value_sp); 310385aa28cSGreg Clayton } 311385aa28cSGreg Clayton break; 312385aa28cSGreg Clayton 313385aa28cSGreg Clayton case 'a': 3149a8fa916SGreg Clayton // When we don't use OptionValue::SetValueFromCString(const char *) to 3159a8fa916SGreg Clayton // set an option value, it won't be marked as being set in the options 3169a8fa916SGreg Clayton // so we make a call to let users know the value was set via option 317385aa28cSGreg Clayton dump_all_sets.SetCurrentValue (true); 3189a8fa916SGreg Clayton dump_all_sets.SetOptionWasSet (); 3199a8fa916SGreg Clayton break; 3209a8fa916SGreg Clayton 3219a8fa916SGreg Clayton case 'A': 3229a8fa916SGreg Clayton // When we don't use OptionValue::SetValueFromCString(const char *) to 3239a8fa916SGreg Clayton // set an option value, it won't be marked as being set in the options 3249a8fa916SGreg Clayton // so we make a call to let users know the value was set via option 3259a8fa916SGreg Clayton alternate_name.SetCurrentValue (true); 3269a8fa916SGreg Clayton dump_all_sets.SetOptionWasSet (); 327385aa28cSGreg Clayton break; 328385aa28cSGreg Clayton 32932e0a750SGreg Clayton default: 33086edbf41SGreg Clayton error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option); 33132e0a750SGreg Clayton break; 33232e0a750SGreg Clayton } 33332e0a750SGreg Clayton return error; 33432e0a750SGreg Clayton } 33532e0a750SGreg Clayton 33632e0a750SGreg Clayton // Options table: Required for subclasses of Options. 33732e0a750SGreg Clayton 3381deb7962SGreg Clayton static const OptionDefinition g_option_table[]; 33932e0a750SGreg Clayton 34032e0a750SGreg Clayton // Instance variables to hold the values for command options. 341385aa28cSGreg Clayton OptionValueArray set_indexes; 342385aa28cSGreg Clayton OptionValueBoolean dump_all_sets; 3439a8fa916SGreg Clayton OptionValueBoolean alternate_name; 34430fdc8d8SChris Lattner }; 34530fdc8d8SChris Lattner 3461deb7962SGreg Clayton OptionGroupOptions m_option_group; 3471deb7962SGreg Clayton OptionGroupFormat m_format_options; 3481deb7962SGreg Clayton CommandOptions m_command_options; 34932e0a750SGreg Clayton }; 35032e0a750SGreg Clayton 3513d0fcf5eSJohnny Chen const OptionDefinition 35232e0a750SGreg Clayton CommandObjectRegisterRead::CommandOptions::g_option_table[] = 35332e0a750SGreg Clayton { 354e2607b50SVirgile Bello { LLDB_OPT_SET_ALL, false, "alternate", 'A', OptionParser::eNoArgument , NULL, 0, eArgTypeNone , "Display register names using the alternate register name if there is one."}, 355e2607b50SVirgile Bello { LLDB_OPT_SET_1 , false, "set" , 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeIndex , "Specify which register sets to dump by index."}, 356e2607b50SVirgile Bello { LLDB_OPT_SET_2 , false, "all" , 'a', OptionParser::eNoArgument , NULL, 0, eArgTypeNone , "Show all register sets."}, 35732e0a750SGreg Clayton }; 35832e0a750SGreg Clayton 3591deb7962SGreg Clayton uint32_t 3601deb7962SGreg Clayton CommandObjectRegisterRead::CommandOptions::GetNumDefinitions () 3611deb7962SGreg Clayton { 3621deb7962SGreg Clayton return sizeof(g_option_table)/sizeof(OptionDefinition); 3631deb7962SGreg Clayton } 36432e0a750SGreg Clayton 36530fdc8d8SChris Lattner 36630fdc8d8SChris Lattner //---------------------------------------------------------------------- 36730fdc8d8SChris Lattner // "register write" 36830fdc8d8SChris Lattner //---------------------------------------------------------------------- 3695a988416SJim Ingham class CommandObjectRegisterWrite : public CommandObjectParsed 37030fdc8d8SChris Lattner { 37130fdc8d8SChris Lattner public: 372a7015092SGreg Clayton CommandObjectRegisterWrite (CommandInterpreter &interpreter) : 3735a988416SJim Ingham CommandObjectParsed (interpreter, 374a7015092SGreg Clayton "register write", 37530fdc8d8SChris Lattner "Modify a single register value.", 376405fe67fSCaroline Tice NULL, 377f9fc609fSGreg Clayton eFlagRequiresFrame | 378f9fc609fSGreg Clayton eFlagRequiresRegContext | 379f9fc609fSGreg Clayton eFlagProcessMustBeLaunched | 380f9fc609fSGreg Clayton eFlagProcessMustBePaused) 38130fdc8d8SChris Lattner { 382405fe67fSCaroline Tice CommandArgumentEntry arg1; 383405fe67fSCaroline Tice CommandArgumentEntry arg2; 384405fe67fSCaroline Tice CommandArgumentData register_arg; 385405fe67fSCaroline Tice CommandArgumentData value_arg; 386405fe67fSCaroline Tice 387405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 388405fe67fSCaroline Tice register_arg.arg_type = eArgTypeRegisterName; 389405fe67fSCaroline Tice register_arg.arg_repetition = eArgRepeatPlain; 390405fe67fSCaroline Tice 391405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 392405fe67fSCaroline Tice arg1.push_back (register_arg); 393405fe67fSCaroline Tice 394405fe67fSCaroline Tice // Define the first (and only) variant of this arg. 395405fe67fSCaroline Tice value_arg.arg_type = eArgTypeValue; 396405fe67fSCaroline Tice value_arg.arg_repetition = eArgRepeatPlain; 397405fe67fSCaroline Tice 398405fe67fSCaroline Tice // There is only one variant this argument could be; put it into the argument entry. 399405fe67fSCaroline Tice arg2.push_back (value_arg); 400405fe67fSCaroline Tice 401405fe67fSCaroline Tice // Push the data for the first argument into the m_arguments vector. 402405fe67fSCaroline Tice m_arguments.push_back (arg1); 403405fe67fSCaroline Tice m_arguments.push_back (arg2); 40430fdc8d8SChris Lattner } 40530fdc8d8SChris Lattner 40630fdc8d8SChris Lattner virtual 40730fdc8d8SChris Lattner ~CommandObjectRegisterWrite () 40830fdc8d8SChris Lattner { 40930fdc8d8SChris Lattner } 41030fdc8d8SChris Lattner 4115a988416SJim Ingham protected: 41230fdc8d8SChris Lattner virtual bool 4135a988416SJim Ingham DoExecute(Args& command, CommandReturnObject &result) 41430fdc8d8SChris Lattner { 41530fdc8d8SChris Lattner DataExtractor reg_data; 416f9fc609fSGreg Clayton RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext (); 41730fdc8d8SChris Lattner 41830fdc8d8SChris Lattner if (command.GetArgumentCount() != 2) 41930fdc8d8SChris Lattner { 42030fdc8d8SChris Lattner result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>"); 42130fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 42230fdc8d8SChris Lattner } 42330fdc8d8SChris Lattner else 42430fdc8d8SChris Lattner { 42530fdc8d8SChris Lattner const char *reg_name = command.GetArgumentAtIndex(0); 42630fdc8d8SChris Lattner const char *value_str = command.GetArgumentAtIndex(1); 4272f59302cSEnrico Granata 4282f59302cSEnrico Granata 4292f59302cSEnrico Granata // in most LLDB commands we accept $rbx as the name for register RBX - and here we would 4302f59302cSEnrico Granata // reject it and non-existant. we should be more consistent towards the user and allow them 4312f59302cSEnrico Granata // to say reg write $rbx - internally, however, we should be strict and not allow ourselves 4322f59302cSEnrico Granata // to call our registers $rbx in our own API 4332f59302cSEnrico Granata if (reg_name && *reg_name == '$') 4342f59302cSEnrico Granata reg_name = reg_name+1; 4352f59302cSEnrico Granata 436385aa28cSGreg Clayton const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name); 43730fdc8d8SChris Lattner 43830fdc8d8SChris Lattner if (reg_info) 43930fdc8d8SChris Lattner { 4407349bd90SGreg Clayton RegisterValue reg_value; 4417349bd90SGreg Clayton 4427349bd90SGreg Clayton Error error (reg_value.SetValueFromCString (reg_info, value_str)); 44330fdc8d8SChris Lattner if (error.Success()) 44430fdc8d8SChris Lattner { 4457349bd90SGreg Clayton if (reg_ctx->WriteRegister (reg_info, reg_value)) 44630fdc8d8SChris Lattner { 447fa559e5cSGreg Clayton // Toss all frames and anything else in the thread 448fa559e5cSGreg Clayton // after a register has been written. 449f9fc609fSGreg Clayton m_exe_ctx.GetThreadRef().Flush(); 45030fdc8d8SChris Lattner result.SetStatus (eReturnStatusSuccessFinishNoResult); 45130fdc8d8SChris Lattner return true; 45230fdc8d8SChris Lattner } 45330fdc8d8SChris Lattner } 454b1ad65c5SJason Molenda if (error.AsCString()) 45530fdc8d8SChris Lattner { 45630fdc8d8SChris Lattner result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n", 45730fdc8d8SChris Lattner reg_name, 45830fdc8d8SChris Lattner value_str, 45930fdc8d8SChris Lattner error.AsCString()); 46030fdc8d8SChris Lattner } 461b1ad65c5SJason Molenda else 462b1ad65c5SJason Molenda { 463b1ad65c5SJason Molenda result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'", 464b1ad65c5SJason Molenda reg_name, 465b1ad65c5SJason Molenda value_str); 466b1ad65c5SJason Molenda } 467b1ad65c5SJason Molenda result.SetStatus (eReturnStatusFailed); 46830fdc8d8SChris Lattner } 46930fdc8d8SChris Lattner else 47030fdc8d8SChris Lattner { 47130fdc8d8SChris Lattner result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name); 47230fdc8d8SChris Lattner result.SetStatus (eReturnStatusFailed); 47330fdc8d8SChris Lattner } 47430fdc8d8SChris Lattner } 47530fdc8d8SChris Lattner return result.Succeeded(); 47630fdc8d8SChris Lattner } 47730fdc8d8SChris Lattner }; 47830fdc8d8SChris Lattner 47930fdc8d8SChris Lattner 48030fdc8d8SChris Lattner //---------------------------------------------------------------------- 48130fdc8d8SChris Lattner // CommandObjectRegister constructor 48230fdc8d8SChris Lattner //---------------------------------------------------------------------- 4836611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) : 484a7015092SGreg Clayton CommandObjectMultiword (interpreter, 485a7015092SGreg Clayton "register", 4863f4c09c1SCaroline Tice "A set of commands to access thread registers.", 48730fdc8d8SChris Lattner "register [read|write] ...") 48830fdc8d8SChris Lattner { 489a7015092SGreg Clayton LoadSubCommand ("read", CommandObjectSP (new CommandObjectRegisterRead (interpreter))); 490a7015092SGreg Clayton LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter))); 49130fdc8d8SChris Lattner } 49230fdc8d8SChris Lattner 49330fdc8d8SChris Lattner 49430fdc8d8SChris Lattner //---------------------------------------------------------------------- 49530fdc8d8SChris Lattner // Destructor 49630fdc8d8SChris Lattner //---------------------------------------------------------------------- 49730fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister() 49830fdc8d8SChris Lattner { 49930fdc8d8SChris Lattner } 500