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"
3430fdc8d8SChris Lattner 
3530fdc8d8SChris Lattner using namespace lldb;
3630fdc8d8SChris Lattner using namespace lldb_private;
3730fdc8d8SChris Lattner 
3830fdc8d8SChris Lattner //----------------------------------------------------------------------
3930fdc8d8SChris Lattner // "register read"
4030fdc8d8SChris Lattner //----------------------------------------------------------------------
415a988416SJim Ingham class CommandObjectRegisterRead : public CommandObjectParsed
4230fdc8d8SChris Lattner {
4330fdc8d8SChris Lattner public:
44a7015092SGreg Clayton     CommandObjectRegisterRead (CommandInterpreter &interpreter) :
455a988416SJim Ingham         CommandObjectParsed (interpreter,
46a7015092SGreg Clayton                              "register read",
47405fe67fSCaroline Tice                              "Dump the contents of one or more register values from the current frame.  If no register is specified, dumps them all.",
48405fe67fSCaroline Tice                              NULL,
49f9fc609fSGreg Clayton                              eFlagRequiresFrame         |
50f9fc609fSGreg Clayton                              eFlagRequiresRegContext    |
51f9fc609fSGreg Clayton                              eFlagProcessMustBeLaunched |
52f9fc609fSGreg Clayton                              eFlagProcessMustBePaused   ),
531deb7962SGreg Clayton         m_option_group (interpreter),
541deb7962SGreg Clayton         m_format_options (eFormatDefault),
551deb7962SGreg Clayton         m_command_options ()
5630fdc8d8SChris Lattner     {
57405fe67fSCaroline Tice         CommandArgumentEntry arg;
58405fe67fSCaroline Tice         CommandArgumentData register_arg;
59405fe67fSCaroline Tice 
60405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
61405fe67fSCaroline Tice         register_arg.arg_type = eArgTypeRegisterName;
62405fe67fSCaroline Tice         register_arg.arg_repetition = eArgRepeatStar;
63405fe67fSCaroline Tice 
64405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
65405fe67fSCaroline Tice         arg.push_back (register_arg);
66405fe67fSCaroline Tice 
67405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
68405fe67fSCaroline Tice         m_arguments.push_back (arg);
691deb7962SGreg Clayton 
701deb7962SGreg Clayton         // Add the "--format"
715009f9d5SGreg Clayton         m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_ALL);
721deb7962SGreg Clayton         m_option_group.Append (&m_command_options);
731deb7962SGreg Clayton         m_option_group.Finalize();
741deb7962SGreg Clayton 
7530fdc8d8SChris Lattner     }
7630fdc8d8SChris Lattner 
7730fdc8d8SChris Lattner     virtual
7830fdc8d8SChris Lattner     ~CommandObjectRegisterRead ()
7930fdc8d8SChris Lattner     {
8030fdc8d8SChris Lattner     }
8130fdc8d8SChris Lattner 
8232e0a750SGreg Clayton     Options *
8332e0a750SGreg Clayton     GetOptions ()
8432e0a750SGreg Clayton     {
851deb7962SGreg Clayton         return &m_option_group;
8632e0a750SGreg Clayton     }
8732e0a750SGreg Clayton 
88385aa28cSGreg Clayton     bool
89385aa28cSGreg Clayton     DumpRegister (const ExecutionContext &exe_ctx,
90385aa28cSGreg Clayton                   Stream &strm,
91385aa28cSGreg Clayton                   RegisterContext *reg_ctx,
92385aa28cSGreg Clayton                   const RegisterInfo *reg_info)
93385aa28cSGreg Clayton     {
94385aa28cSGreg Clayton         if (reg_info)
95385aa28cSGreg Clayton         {
967349bd90SGreg Clayton             RegisterValue reg_value;
97385aa28cSGreg Clayton 
987349bd90SGreg Clayton             if (reg_ctx->ReadRegister (reg_info, reg_value))
99385aa28cSGreg Clayton             {
100385aa28cSGreg Clayton                 strm.Indent ();
101385aa28cSGreg Clayton 
1029076c0ffSSean Callanan                 bool prefix_with_altname = (bool)m_command_options.alternate_name;
1039a8fa916SGreg Clayton                 bool prefix_with_name = !prefix_with_altname;
104c4392d2aSJohnny Chen                 reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname, m_format_options.GetFormat(), 8);
1051ac04c30SGreg Clayton                 if ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint))
1061ac04c30SGreg Clayton                 {
1071ac04c30SGreg Clayton                     Process *process = exe_ctx.GetProcessPtr();
1081ac04c30SGreg Clayton                     if (process && reg_info->byte_size == process->GetAddressByteSize())
109385aa28cSGreg Clayton                     {
1107349bd90SGreg Clayton                         addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS);
1117349bd90SGreg Clayton                         if (reg_addr != LLDB_INVALID_ADDRESS)
112385aa28cSGreg Clayton                         {
113385aa28cSGreg Clayton                             Address so_reg_addr;
114c14ee32dSGreg Clayton                             if (exe_ctx.GetTargetRef().GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr))
115385aa28cSGreg Clayton                             {
116385aa28cSGreg Clayton                                 strm.PutCString ("  ");
117385aa28cSGreg Clayton                                 so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
118385aa28cSGreg Clayton                             }
119385aa28cSGreg Clayton                         }
120385aa28cSGreg Clayton                     }
1211ac04c30SGreg Clayton                 }
122385aa28cSGreg Clayton                 strm.EOL();
123385aa28cSGreg Clayton                 return true;
124385aa28cSGreg Clayton             }
125385aa28cSGreg Clayton         }
126385aa28cSGreg Clayton         return false;
127385aa28cSGreg Clayton     }
128385aa28cSGreg Clayton 
129385aa28cSGreg Clayton     bool
130385aa28cSGreg Clayton     DumpRegisterSet (const ExecutionContext &exe_ctx,
131385aa28cSGreg Clayton                      Stream &strm,
132385aa28cSGreg Clayton                      RegisterContext *reg_ctx,
133c7bece56SGreg Clayton                      size_t set_idx,
1346d4d4f7dSJohnny Chen                      bool primitive_only=false)
135385aa28cSGreg Clayton     {
136385aa28cSGreg Clayton         uint32_t unavailable_count = 0;
137385aa28cSGreg Clayton         uint32_t available_count = 0;
1384f5f39acSAshok Thirumurthi 
1394f5f39acSAshok Thirumurthi         if (!reg_ctx)
1404f5f39acSAshok Thirumurthi             return false; // thread has no registers (i.e. core files are corrupt, incomplete crash logs...)
1414f5f39acSAshok Thirumurthi 
142385aa28cSGreg Clayton         const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx);
143385aa28cSGreg Clayton         if (reg_set)
144385aa28cSGreg Clayton         {
145385aa28cSGreg Clayton             strm.Printf ("%s:\n", reg_set->name);
146385aa28cSGreg Clayton             strm.IndentMore ();
147c7bece56SGreg Clayton             const size_t num_registers = reg_set->num_registers;
148c7bece56SGreg Clayton             for (size_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
149385aa28cSGreg Clayton             {
150385aa28cSGreg Clayton                 const uint32_t reg = reg_set->registers[reg_idx];
1516d4d4f7dSJohnny Chen                 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg);
1526d4d4f7dSJohnny Chen                 // Skip the dumping of derived register if primitive_only is true.
1536d4d4f7dSJohnny Chen                 if (primitive_only && reg_info && reg_info->value_regs)
1546d4d4f7dSJohnny Chen                     continue;
1554f5f39acSAshok Thirumurthi 
1566d4d4f7dSJohnny Chen                 if (DumpRegister (exe_ctx, strm, reg_ctx, reg_info))
157385aa28cSGreg Clayton                     ++available_count;
158385aa28cSGreg Clayton                 else
159385aa28cSGreg Clayton                     ++unavailable_count;
160385aa28cSGreg Clayton             }
161385aa28cSGreg Clayton             strm.IndentLess ();
162385aa28cSGreg Clayton             if (unavailable_count)
163385aa28cSGreg Clayton             {
164385aa28cSGreg Clayton                 strm.Indent ();
165385aa28cSGreg Clayton                 strm.Printf("%u registers were unavailable.\n", unavailable_count);
166385aa28cSGreg Clayton             }
167385aa28cSGreg Clayton             strm.EOL();
168385aa28cSGreg Clayton         }
169385aa28cSGreg Clayton         return available_count > 0;
170385aa28cSGreg Clayton     }
171385aa28cSGreg Clayton 
1725a988416SJim Ingham protected:
17330fdc8d8SChris Lattner     virtual bool
1745a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
17530fdc8d8SChris Lattner     {
176385aa28cSGreg Clayton         Stream &strm = result.GetOutputStream();
177f9fc609fSGreg Clayton         RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext ();
17830fdc8d8SChris Lattner 
17930fdc8d8SChris Lattner         const RegisterInfo *reg_info = NULL;
18030fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
18130fdc8d8SChris Lattner         {
182c7bece56SGreg Clayton             size_t set_idx;
183385aa28cSGreg Clayton 
184c7bece56SGreg Clayton             size_t num_register_sets = 1;
185c7bece56SGreg Clayton             const size_t set_array_size = m_command_options.set_indexes.GetSize();
186385aa28cSGreg Clayton             if (set_array_size > 0)
18730fdc8d8SChris Lattner             {
188c7bece56SGreg Clayton                 for (size_t i=0; i<set_array_size; ++i)
18930fdc8d8SChris Lattner                 {
1901deb7962SGreg Clayton                     set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL);
1914f5f39acSAshok Thirumurthi                     if (set_idx < reg_ctx->GetRegisterSetCount())
19230fdc8d8SChris Lattner                     {
193f9fc609fSGreg Clayton                         if (!DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx))
194385aa28cSGreg Clayton                         {
1954f5f39acSAshok Thirumurthi                             if (errno)
196789cefb8SSylvestre Ledru                                 result.AppendErrorWithFormat ("register read failed: %s\n", strerror(errno));
1974f5f39acSAshok Thirumurthi                             else
1984f5f39acSAshok Thirumurthi                                 result.AppendError ("unknown error while reading registers.\n");
199385aa28cSGreg Clayton                             result.SetStatus (eReturnStatusFailed);
200385aa28cSGreg Clayton                             break;
201385aa28cSGreg Clayton                         }
20230fdc8d8SChris Lattner                     }
20330fdc8d8SChris Lattner                     else
20430fdc8d8SChris Lattner                     {
205*99fbc076SDeepak Panickal                         result.AppendErrorWithFormat("invalid register set index: %" PRIu64 "\n", (uint64_t)set_idx);
206385aa28cSGreg Clayton                         result.SetStatus (eReturnStatusFailed);
207385aa28cSGreg Clayton                         break;
20830fdc8d8SChris Lattner                     }
20930fdc8d8SChris Lattner                 }
210385aa28cSGreg Clayton             }
211385aa28cSGreg Clayton             else
21230fdc8d8SChris Lattner             {
2131deb7962SGreg Clayton                 if (m_command_options.dump_all_sets)
214385aa28cSGreg Clayton                     num_register_sets = reg_ctx->GetRegisterSetCount();
215385aa28cSGreg Clayton 
216385aa28cSGreg Clayton                 for (set_idx = 0; set_idx < num_register_sets; ++set_idx)
217385aa28cSGreg Clayton                 {
2186d4d4f7dSJohnny Chen                     // When dump_all_sets option is set, dump primitive as well as derived registers.
219f9fc609fSGreg Clayton                     DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx, !m_command_options.dump_all_sets.GetCurrentValue());
22030fdc8d8SChris Lattner                 }
22130fdc8d8SChris Lattner             }
22230fdc8d8SChris Lattner         }
22330fdc8d8SChris Lattner         else
22430fdc8d8SChris Lattner         {
2251deb7962SGreg Clayton             if (m_command_options.dump_all_sets)
226385aa28cSGreg Clayton             {
227385aa28cSGreg Clayton                 result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n");
228385aa28cSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
229385aa28cSGreg Clayton             }
2301deb7962SGreg Clayton             else if (m_command_options.set_indexes.GetSize() > 0)
231385aa28cSGreg Clayton             {
232385aa28cSGreg Clayton                 result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n");
233385aa28cSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
234385aa28cSGreg Clayton             }
235385aa28cSGreg Clayton             else
236385aa28cSGreg Clayton             {
23730fdc8d8SChris Lattner                 const char *arg_cstr;
23830fdc8d8SChris Lattner                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
23930fdc8d8SChris Lattner                 {
2402f59302cSEnrico Granata                     // in most LLDB commands we accept $rbx as the name for register RBX - and here we would
2412f59302cSEnrico Granata                     // reject it and non-existant. we should be more consistent towards the user and allow them
2422f59302cSEnrico Granata                     // to say reg read $rbx - internally, however, we should be strict and not allow ourselves
2432f59302cSEnrico Granata                     // to call our registers $rbx in our own API
2442f59302cSEnrico Granata                     if (*arg_cstr == '$')
2452f59302cSEnrico Granata                         arg_cstr = arg_cstr+1;
246385aa28cSGreg Clayton                     reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr);
24730fdc8d8SChris Lattner 
24830fdc8d8SChris Lattner                     if (reg_info)
24930fdc8d8SChris Lattner                     {
250f9fc609fSGreg Clayton                         if (!DumpRegister (m_exe_ctx, strm, reg_ctx, reg_info))
251385aa28cSGreg Clayton                             strm.Printf("%-12s = error: unavailable\n", reg_info->name);
25230fdc8d8SChris Lattner                     }
25330fdc8d8SChris Lattner                     else
25430fdc8d8SChris Lattner                     {
25530fdc8d8SChris Lattner                         result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr);
25630fdc8d8SChris Lattner                     }
25730fdc8d8SChris Lattner                 }
25830fdc8d8SChris Lattner             }
25930fdc8d8SChris Lattner         }
26030fdc8d8SChris Lattner         return result.Succeeded();
26130fdc8d8SChris Lattner     }
26232e0a750SGreg Clayton 
2631deb7962SGreg Clayton     class CommandOptions : public OptionGroup
26432e0a750SGreg Clayton     {
26532e0a750SGreg Clayton     public:
2661deb7962SGreg Clayton         CommandOptions () :
2671deb7962SGreg Clayton             OptionGroup(),
268385aa28cSGreg Clayton             set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)),
2699a8fa916SGreg Clayton             dump_all_sets (false, false), // Initial and default values are false
2709a8fa916SGreg Clayton             alternate_name (false, false)
27132e0a750SGreg Clayton         {
27232e0a750SGreg Clayton         }
27332e0a750SGreg Clayton 
27432e0a750SGreg Clayton         virtual
27532e0a750SGreg Clayton         ~CommandOptions ()
27632e0a750SGreg Clayton         {
27732e0a750SGreg Clayton         }
27832e0a750SGreg Clayton 
2791deb7962SGreg Clayton 
2801deb7962SGreg Clayton         virtual uint32_t
2811deb7962SGreg Clayton         GetNumDefinitions ();
2821deb7962SGreg Clayton 
2831deb7962SGreg Clayton         virtual const OptionDefinition*
2841deb7962SGreg Clayton         GetDefinitions ()
2851deb7962SGreg Clayton         {
2861deb7962SGreg Clayton             return g_option_table;
2871deb7962SGreg Clayton         }
2881deb7962SGreg Clayton 
2891deb7962SGreg Clayton         virtual void
2901deb7962SGreg Clayton         OptionParsingStarting (CommandInterpreter &interpreter)
2911deb7962SGreg Clayton         {
2921deb7962SGreg Clayton             set_indexes.Clear();
2931deb7962SGreg Clayton             dump_all_sets.Clear();
2941deb7962SGreg Clayton             alternate_name.Clear();
2951deb7962SGreg Clayton         }
2961deb7962SGreg Clayton 
29732e0a750SGreg Clayton         virtual Error
2981deb7962SGreg Clayton         SetOptionValue (CommandInterpreter &interpreter,
2991deb7962SGreg Clayton                         uint32_t option_idx,
3001deb7962SGreg Clayton                         const char *option_value)
30132e0a750SGreg Clayton         {
30232e0a750SGreg Clayton             Error error;
3033bcdfc0eSGreg Clayton             const int short_option = g_option_table[option_idx].short_option;
30432e0a750SGreg Clayton             switch (short_option)
30532e0a750SGreg Clayton             {
306385aa28cSGreg Clayton                 case 's':
307385aa28cSGreg Clayton                     {
3081deb7962SGreg Clayton                         OptionValueSP value_sp (OptionValueUInt64::Create (option_value, error));
309385aa28cSGreg Clayton                         if (value_sp)
310385aa28cSGreg Clayton                             set_indexes.AppendValue (value_sp);
311385aa28cSGreg Clayton                     }
312385aa28cSGreg Clayton                     break;
313385aa28cSGreg Clayton 
314385aa28cSGreg Clayton                 case 'a':
3159a8fa916SGreg Clayton                     // When we don't use OptionValue::SetValueFromCString(const char *) to
3169a8fa916SGreg Clayton                     // set an option value, it won't be marked as being set in the options
3179a8fa916SGreg Clayton                     // so we make a call to let users know the value was set via option
318385aa28cSGreg Clayton                     dump_all_sets.SetCurrentValue (true);
3199a8fa916SGreg Clayton                     dump_all_sets.SetOptionWasSet ();
3209a8fa916SGreg Clayton                     break;
3219a8fa916SGreg Clayton 
3229a8fa916SGreg Clayton                 case 'A':
3239a8fa916SGreg Clayton                     // When we don't use OptionValue::SetValueFromCString(const char *) to
3249a8fa916SGreg Clayton                     // set an option value, it won't be marked as being set in the options
3259a8fa916SGreg Clayton                     // so we make a call to let users know the value was set via option
3269a8fa916SGreg Clayton                     alternate_name.SetCurrentValue (true);
3279a8fa916SGreg Clayton                     dump_all_sets.SetOptionWasSet ();
328385aa28cSGreg Clayton                     break;
329385aa28cSGreg Clayton 
33032e0a750SGreg Clayton                 default:
33186edbf41SGreg Clayton                     error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
33232e0a750SGreg Clayton                     break;
33332e0a750SGreg Clayton             }
33432e0a750SGreg Clayton             return error;
33532e0a750SGreg Clayton         }
33632e0a750SGreg Clayton 
33732e0a750SGreg Clayton         // Options table: Required for subclasses of Options.
33832e0a750SGreg Clayton 
3391deb7962SGreg Clayton         static const OptionDefinition g_option_table[];
34032e0a750SGreg Clayton 
34132e0a750SGreg Clayton         // Instance variables to hold the values for command options.
342385aa28cSGreg Clayton         OptionValueArray set_indexes;
343385aa28cSGreg Clayton         OptionValueBoolean dump_all_sets;
3449a8fa916SGreg Clayton         OptionValueBoolean alternate_name;
34530fdc8d8SChris Lattner     };
34630fdc8d8SChris Lattner 
3471deb7962SGreg Clayton     OptionGroupOptions m_option_group;
3481deb7962SGreg Clayton     OptionGroupFormat m_format_options;
3491deb7962SGreg Clayton     CommandOptions m_command_options;
35032e0a750SGreg Clayton };
35132e0a750SGreg Clayton 
3523d0fcf5eSJohnny Chen const OptionDefinition
35332e0a750SGreg Clayton CommandObjectRegisterRead::CommandOptions::g_option_table[] =
35432e0a750SGreg Clayton {
355e2607b50SVirgile 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."},
356e2607b50SVirgile Bello     { LLDB_OPT_SET_1  , false, "set"      , 's', OptionParser::eRequiredArgument, NULL, 0, eArgTypeIndex     , "Specify which register sets to dump by index."},
357e2607b50SVirgile Bello     { LLDB_OPT_SET_2  , false, "all"      , 'a', OptionParser::eNoArgument      , NULL, 0, eArgTypeNone      , "Show all register sets."},
35832e0a750SGreg Clayton };
35932e0a750SGreg Clayton 
3601deb7962SGreg Clayton uint32_t
3611deb7962SGreg Clayton CommandObjectRegisterRead::CommandOptions::GetNumDefinitions ()
3621deb7962SGreg Clayton {
3631deb7962SGreg Clayton     return sizeof(g_option_table)/sizeof(OptionDefinition);
3641deb7962SGreg Clayton }
36532e0a750SGreg Clayton 
36630fdc8d8SChris Lattner 
36730fdc8d8SChris Lattner //----------------------------------------------------------------------
36830fdc8d8SChris Lattner // "register write"
36930fdc8d8SChris Lattner //----------------------------------------------------------------------
3705a988416SJim Ingham class CommandObjectRegisterWrite : public CommandObjectParsed
37130fdc8d8SChris Lattner {
37230fdc8d8SChris Lattner public:
373a7015092SGreg Clayton     CommandObjectRegisterWrite (CommandInterpreter &interpreter) :
3745a988416SJim Ingham         CommandObjectParsed (interpreter,
375a7015092SGreg Clayton                              "register write",
37630fdc8d8SChris Lattner                              "Modify a single register value.",
377405fe67fSCaroline Tice                              NULL,
378f9fc609fSGreg Clayton                              eFlagRequiresFrame         |
379f9fc609fSGreg Clayton                              eFlagRequiresRegContext    |
380f9fc609fSGreg Clayton                              eFlagProcessMustBeLaunched |
381f9fc609fSGreg Clayton                              eFlagProcessMustBePaused)
38230fdc8d8SChris Lattner     {
383405fe67fSCaroline Tice         CommandArgumentEntry arg1;
384405fe67fSCaroline Tice         CommandArgumentEntry arg2;
385405fe67fSCaroline Tice         CommandArgumentData register_arg;
386405fe67fSCaroline Tice         CommandArgumentData value_arg;
387405fe67fSCaroline Tice 
388405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
389405fe67fSCaroline Tice         register_arg.arg_type = eArgTypeRegisterName;
390405fe67fSCaroline Tice         register_arg.arg_repetition = eArgRepeatPlain;
391405fe67fSCaroline Tice 
392405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
393405fe67fSCaroline Tice         arg1.push_back (register_arg);
394405fe67fSCaroline Tice 
395405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
396405fe67fSCaroline Tice         value_arg.arg_type = eArgTypeValue;
397405fe67fSCaroline Tice         value_arg.arg_repetition = eArgRepeatPlain;
398405fe67fSCaroline Tice 
399405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
400405fe67fSCaroline Tice         arg2.push_back (value_arg);
401405fe67fSCaroline Tice 
402405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
403405fe67fSCaroline Tice         m_arguments.push_back (arg1);
404405fe67fSCaroline Tice         m_arguments.push_back (arg2);
40530fdc8d8SChris Lattner     }
40630fdc8d8SChris Lattner 
40730fdc8d8SChris Lattner     virtual
40830fdc8d8SChris Lattner     ~CommandObjectRegisterWrite ()
40930fdc8d8SChris Lattner     {
41030fdc8d8SChris Lattner     }
41130fdc8d8SChris Lattner 
4125a988416SJim Ingham protected:
41330fdc8d8SChris Lattner     virtual bool
4145a988416SJim Ingham     DoExecute(Args& command, CommandReturnObject &result)
41530fdc8d8SChris Lattner     {
41630fdc8d8SChris Lattner         DataExtractor reg_data;
417f9fc609fSGreg Clayton         RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext ();
41830fdc8d8SChris Lattner 
41930fdc8d8SChris Lattner         if (command.GetArgumentCount() != 2)
42030fdc8d8SChris Lattner         {
42130fdc8d8SChris Lattner             result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>");
42230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
42330fdc8d8SChris Lattner         }
42430fdc8d8SChris Lattner         else
42530fdc8d8SChris Lattner         {
42630fdc8d8SChris Lattner             const char *reg_name = command.GetArgumentAtIndex(0);
42730fdc8d8SChris Lattner             const char *value_str = command.GetArgumentAtIndex(1);
4282f59302cSEnrico Granata 
4292f59302cSEnrico Granata 
4302f59302cSEnrico Granata             // in most LLDB commands we accept $rbx as the name for register RBX - and here we would
4312f59302cSEnrico Granata             // reject it and non-existant. we should be more consistent towards the user and allow them
4322f59302cSEnrico Granata             // to say reg write $rbx - internally, however, we should be strict and not allow ourselves
4332f59302cSEnrico Granata             // to call our registers $rbx in our own API
4342f59302cSEnrico Granata             if (reg_name && *reg_name == '$')
4352f59302cSEnrico Granata                 reg_name = reg_name+1;
4362f59302cSEnrico Granata 
437385aa28cSGreg Clayton             const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
43830fdc8d8SChris Lattner 
43930fdc8d8SChris Lattner             if (reg_info)
44030fdc8d8SChris Lattner             {
4417349bd90SGreg Clayton                 RegisterValue reg_value;
4427349bd90SGreg Clayton 
4437349bd90SGreg Clayton                 Error error (reg_value.SetValueFromCString (reg_info, value_str));
44430fdc8d8SChris Lattner                 if (error.Success())
44530fdc8d8SChris Lattner                 {
4467349bd90SGreg Clayton                     if (reg_ctx->WriteRegister (reg_info, reg_value))
44730fdc8d8SChris Lattner                     {
448fa559e5cSGreg Clayton                         // Toss all frames and anything else in the thread
449fa559e5cSGreg Clayton                         // after a register has been written.
450f9fc609fSGreg Clayton                         m_exe_ctx.GetThreadRef().Flush();
45130fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
45230fdc8d8SChris Lattner                         return true;
45330fdc8d8SChris Lattner                     }
45430fdc8d8SChris Lattner                 }
455b1ad65c5SJason Molenda                 if (error.AsCString())
45630fdc8d8SChris Lattner                 {
45730fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n",
45830fdc8d8SChris Lattner                                                  reg_name,
45930fdc8d8SChris Lattner                                                  value_str,
46030fdc8d8SChris Lattner                                                  error.AsCString());
46130fdc8d8SChris Lattner                 }
462b1ad65c5SJason Molenda                 else
463b1ad65c5SJason Molenda                 {
464b1ad65c5SJason Molenda                     result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'",
465b1ad65c5SJason Molenda                                                  reg_name,
466b1ad65c5SJason Molenda                                                  value_str);
467b1ad65c5SJason Molenda                 }
468b1ad65c5SJason Molenda                 result.SetStatus (eReturnStatusFailed);
46930fdc8d8SChris Lattner             }
47030fdc8d8SChris Lattner             else
47130fdc8d8SChris Lattner             {
47230fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name);
47330fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
47430fdc8d8SChris Lattner             }
47530fdc8d8SChris Lattner         }
47630fdc8d8SChris Lattner         return result.Succeeded();
47730fdc8d8SChris Lattner     }
47830fdc8d8SChris Lattner };
47930fdc8d8SChris Lattner 
48030fdc8d8SChris Lattner 
48130fdc8d8SChris Lattner //----------------------------------------------------------------------
48230fdc8d8SChris Lattner // CommandObjectRegister constructor
48330fdc8d8SChris Lattner //----------------------------------------------------------------------
4846611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) :
485a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
486a7015092SGreg Clayton                             "register",
4873f4c09c1SCaroline Tice                             "A set of commands to access thread registers.",
48830fdc8d8SChris Lattner                             "register [read|write] ...")
48930fdc8d8SChris Lattner {
490a7015092SGreg Clayton     LoadSubCommand ("read",  CommandObjectSP (new CommandObjectRegisterRead (interpreter)));
491a7015092SGreg Clayton     LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter)));
49230fdc8d8SChris Lattner }
49330fdc8d8SChris Lattner 
49430fdc8d8SChris Lattner 
49530fdc8d8SChris Lattner //----------------------------------------------------------------------
49630fdc8d8SChris Lattner // Destructor
49730fdc8d8SChris Lattner //----------------------------------------------------------------------
49830fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister()
49930fdc8d8SChris Lattner {
50030fdc8d8SChris Lattner }
501