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,
132*c7bece56SGreg 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;
137385aa28cSGreg Clayton         const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx);
138385aa28cSGreg Clayton         if (reg_set)
139385aa28cSGreg Clayton         {
140385aa28cSGreg Clayton             strm.Printf ("%s:\n", reg_set->name);
141385aa28cSGreg Clayton             strm.IndentMore ();
142*c7bece56SGreg Clayton             const size_t num_registers = reg_set->num_registers;
143*c7bece56SGreg Clayton             for (size_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
144385aa28cSGreg Clayton             {
145385aa28cSGreg Clayton                 const uint32_t reg = reg_set->registers[reg_idx];
1466d4d4f7dSJohnny Chen                 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg);
1476d4d4f7dSJohnny Chen                 // Skip the dumping of derived register if primitive_only is true.
1486d4d4f7dSJohnny Chen                 if (primitive_only && reg_info && reg_info->value_regs)
1496d4d4f7dSJohnny Chen                     continue;
1506d4d4f7dSJohnny Chen                 if (DumpRegister (exe_ctx, strm, reg_ctx, reg_info))
151385aa28cSGreg Clayton                     ++available_count;
152385aa28cSGreg Clayton                 else
153385aa28cSGreg Clayton                     ++unavailable_count;
154385aa28cSGreg Clayton             }
155385aa28cSGreg Clayton             strm.IndentLess ();
156385aa28cSGreg Clayton             if (unavailable_count)
157385aa28cSGreg Clayton             {
158385aa28cSGreg Clayton                 strm.Indent ();
159385aa28cSGreg Clayton                 strm.Printf("%u registers were unavailable.\n", unavailable_count);
160385aa28cSGreg Clayton             }
161385aa28cSGreg Clayton             strm.EOL();
162385aa28cSGreg Clayton         }
163385aa28cSGreg Clayton         return available_count > 0;
164385aa28cSGreg Clayton     }
165385aa28cSGreg Clayton 
1665a988416SJim Ingham protected:
16730fdc8d8SChris Lattner     virtual bool
1685a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
16930fdc8d8SChris Lattner     {
170385aa28cSGreg Clayton         Stream &strm = result.GetOutputStream();
171f9fc609fSGreg Clayton         RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext ();
17230fdc8d8SChris Lattner 
17330fdc8d8SChris Lattner         const RegisterInfo *reg_info = NULL;
17430fdc8d8SChris Lattner         if (command.GetArgumentCount() == 0)
17530fdc8d8SChris Lattner         {
176*c7bece56SGreg Clayton             size_t set_idx;
177385aa28cSGreg Clayton 
178*c7bece56SGreg Clayton             size_t num_register_sets = 1;
179*c7bece56SGreg Clayton             const size_t set_array_size = m_command_options.set_indexes.GetSize();
180385aa28cSGreg Clayton             if (set_array_size > 0)
18130fdc8d8SChris Lattner             {
182*c7bece56SGreg Clayton                 for (size_t i=0; i<set_array_size; ++i)
18330fdc8d8SChris Lattner                 {
1841deb7962SGreg Clayton                     set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL);
185385aa28cSGreg Clayton                     if (set_idx != UINT32_MAX)
18630fdc8d8SChris Lattner                     {
187f9fc609fSGreg Clayton                         if (!DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx))
188385aa28cSGreg Clayton                         {
189*c7bece56SGreg Clayton                             result.AppendErrorWithFormat ("invalid register set index: %zu\n", set_idx);
190385aa28cSGreg Clayton                             result.SetStatus (eReturnStatusFailed);
191385aa28cSGreg Clayton                             break;
192385aa28cSGreg Clayton                         }
19330fdc8d8SChris Lattner                     }
19430fdc8d8SChris Lattner                     else
19530fdc8d8SChris Lattner                     {
196385aa28cSGreg Clayton                         result.AppendError ("invalid register set index\n");
197385aa28cSGreg Clayton                         result.SetStatus (eReturnStatusFailed);
198385aa28cSGreg Clayton                         break;
19930fdc8d8SChris Lattner                     }
20030fdc8d8SChris Lattner                 }
201385aa28cSGreg Clayton             }
202385aa28cSGreg Clayton             else
20330fdc8d8SChris Lattner             {
2041deb7962SGreg Clayton                 if (m_command_options.dump_all_sets)
205385aa28cSGreg Clayton                     num_register_sets = reg_ctx->GetRegisterSetCount();
206385aa28cSGreg Clayton 
207385aa28cSGreg Clayton                 for (set_idx = 0; set_idx < num_register_sets; ++set_idx)
208385aa28cSGreg Clayton                 {
2096d4d4f7dSJohnny Chen                     // When dump_all_sets option is set, dump primitive as well as derived registers.
210f9fc609fSGreg Clayton                     DumpRegisterSet (m_exe_ctx, strm, reg_ctx, set_idx, !m_command_options.dump_all_sets.GetCurrentValue());
21130fdc8d8SChris Lattner                 }
21230fdc8d8SChris Lattner             }
21330fdc8d8SChris Lattner         }
21430fdc8d8SChris Lattner         else
21530fdc8d8SChris Lattner         {
2161deb7962SGreg Clayton             if (m_command_options.dump_all_sets)
217385aa28cSGreg Clayton             {
218385aa28cSGreg Clayton                 result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n");
219385aa28cSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
220385aa28cSGreg Clayton             }
2211deb7962SGreg Clayton             else if (m_command_options.set_indexes.GetSize() > 0)
222385aa28cSGreg Clayton             {
223385aa28cSGreg Clayton                 result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n");
224385aa28cSGreg Clayton                 result.SetStatus (eReturnStatusFailed);
225385aa28cSGreg Clayton             }
226385aa28cSGreg Clayton             else
227385aa28cSGreg Clayton             {
22830fdc8d8SChris Lattner                 const char *arg_cstr;
22930fdc8d8SChris Lattner                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
23030fdc8d8SChris Lattner                 {
231385aa28cSGreg Clayton                     reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr);
23230fdc8d8SChris Lattner 
23330fdc8d8SChris Lattner                     if (reg_info)
23430fdc8d8SChris Lattner                     {
235f9fc609fSGreg Clayton                         if (!DumpRegister (m_exe_ctx, strm, reg_ctx, reg_info))
236385aa28cSGreg Clayton                             strm.Printf("%-12s = error: unavailable\n", reg_info->name);
23730fdc8d8SChris Lattner                     }
23830fdc8d8SChris Lattner                     else
23930fdc8d8SChris Lattner                     {
24030fdc8d8SChris Lattner                         result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr);
24130fdc8d8SChris Lattner                     }
24230fdc8d8SChris Lattner                 }
24330fdc8d8SChris Lattner             }
24430fdc8d8SChris Lattner         }
24530fdc8d8SChris Lattner         return result.Succeeded();
24630fdc8d8SChris Lattner     }
24732e0a750SGreg Clayton 
2481deb7962SGreg Clayton     class CommandOptions : public OptionGroup
24932e0a750SGreg Clayton     {
25032e0a750SGreg Clayton     public:
2511deb7962SGreg Clayton         CommandOptions () :
2521deb7962SGreg Clayton             OptionGroup(),
253385aa28cSGreg Clayton             set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)),
2549a8fa916SGreg Clayton             dump_all_sets (false, false), // Initial and default values are false
2559a8fa916SGreg Clayton             alternate_name (false, false)
25632e0a750SGreg Clayton         {
25732e0a750SGreg Clayton         }
25832e0a750SGreg Clayton 
25932e0a750SGreg Clayton         virtual
26032e0a750SGreg Clayton         ~CommandOptions ()
26132e0a750SGreg Clayton         {
26232e0a750SGreg Clayton         }
26332e0a750SGreg Clayton 
2641deb7962SGreg Clayton 
2651deb7962SGreg Clayton         virtual uint32_t
2661deb7962SGreg Clayton         GetNumDefinitions ();
2671deb7962SGreg Clayton 
2681deb7962SGreg Clayton         virtual const OptionDefinition*
2691deb7962SGreg Clayton         GetDefinitions ()
2701deb7962SGreg Clayton         {
2711deb7962SGreg Clayton             return g_option_table;
2721deb7962SGreg Clayton         }
2731deb7962SGreg Clayton 
2741deb7962SGreg Clayton         virtual void
2751deb7962SGreg Clayton         OptionParsingStarting (CommandInterpreter &interpreter)
2761deb7962SGreg Clayton         {
2771deb7962SGreg Clayton             set_indexes.Clear();
2781deb7962SGreg Clayton             dump_all_sets.Clear();
2791deb7962SGreg Clayton             alternate_name.Clear();
2801deb7962SGreg Clayton         }
2811deb7962SGreg Clayton 
28232e0a750SGreg Clayton         virtual Error
2831deb7962SGreg Clayton         SetOptionValue (CommandInterpreter &interpreter,
2841deb7962SGreg Clayton                         uint32_t option_idx,
2851deb7962SGreg Clayton                         const char *option_value)
28632e0a750SGreg Clayton         {
28732e0a750SGreg Clayton             Error error;
2883bcdfc0eSGreg Clayton             const int short_option = g_option_table[option_idx].short_option;
28932e0a750SGreg Clayton             switch (short_option)
29032e0a750SGreg Clayton             {
291385aa28cSGreg Clayton                 case 's':
292385aa28cSGreg Clayton                     {
2931deb7962SGreg Clayton                         OptionValueSP value_sp (OptionValueUInt64::Create (option_value, error));
294385aa28cSGreg Clayton                         if (value_sp)
295385aa28cSGreg Clayton                             set_indexes.AppendValue (value_sp);
296385aa28cSGreg Clayton                     }
297385aa28cSGreg Clayton                     break;
298385aa28cSGreg Clayton 
299385aa28cSGreg Clayton                 case 'a':
3009a8fa916SGreg Clayton                     // When we don't use OptionValue::SetValueFromCString(const char *) to
3019a8fa916SGreg Clayton                     // set an option value, it won't be marked as being set in the options
3029a8fa916SGreg Clayton                     // so we make a call to let users know the value was set via option
303385aa28cSGreg Clayton                     dump_all_sets.SetCurrentValue (true);
3049a8fa916SGreg Clayton                     dump_all_sets.SetOptionWasSet ();
3059a8fa916SGreg Clayton                     break;
3069a8fa916SGreg Clayton 
3079a8fa916SGreg Clayton                 case 'A':
3089a8fa916SGreg Clayton                     // When we don't use OptionValue::SetValueFromCString(const char *) to
3099a8fa916SGreg Clayton                     // set an option value, it won't be marked as being set in the options
3109a8fa916SGreg Clayton                     // so we make a call to let users know the value was set via option
3119a8fa916SGreg Clayton                     alternate_name.SetCurrentValue (true);
3129a8fa916SGreg Clayton                     dump_all_sets.SetOptionWasSet ();
313385aa28cSGreg Clayton                     break;
314385aa28cSGreg Clayton 
31532e0a750SGreg Clayton                 default:
31686edbf41SGreg Clayton                     error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
31732e0a750SGreg Clayton                     break;
31832e0a750SGreg Clayton             }
31932e0a750SGreg Clayton             return error;
32032e0a750SGreg Clayton         }
32132e0a750SGreg Clayton 
32232e0a750SGreg Clayton         // Options table: Required for subclasses of Options.
32332e0a750SGreg Clayton 
3241deb7962SGreg Clayton         static const OptionDefinition g_option_table[];
32532e0a750SGreg Clayton 
32632e0a750SGreg Clayton         // Instance variables to hold the values for command options.
327385aa28cSGreg Clayton         OptionValueArray set_indexes;
328385aa28cSGreg Clayton         OptionValueBoolean dump_all_sets;
3299a8fa916SGreg Clayton         OptionValueBoolean alternate_name;
33030fdc8d8SChris Lattner     };
33130fdc8d8SChris Lattner 
3321deb7962SGreg Clayton     OptionGroupOptions m_option_group;
3331deb7962SGreg Clayton     OptionGroupFormat m_format_options;
3341deb7962SGreg Clayton     CommandOptions m_command_options;
33532e0a750SGreg Clayton };
33632e0a750SGreg Clayton 
3373d0fcf5eSJohnny Chen const OptionDefinition
33832e0a750SGreg Clayton CommandObjectRegisterRead::CommandOptions::g_option_table[] =
33932e0a750SGreg Clayton {
3409a8fa916SGreg 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."},
341385aa28cSGreg Clayton     { LLDB_OPT_SET_1  , false, "set"      , 's', required_argument, NULL, 0, eArgTypeIndex     , "Specify which register sets to dump by index."},
342385aa28cSGreg Clayton     { LLDB_OPT_SET_2  , false, "all"      , 'a', no_argument      , NULL, 0, eArgTypeNone      , "Show all register sets."},
34332e0a750SGreg Clayton };
34432e0a750SGreg Clayton 
3451deb7962SGreg Clayton uint32_t
3461deb7962SGreg Clayton CommandObjectRegisterRead::CommandOptions::GetNumDefinitions ()
3471deb7962SGreg Clayton {
3481deb7962SGreg Clayton     return sizeof(g_option_table)/sizeof(OptionDefinition);
3491deb7962SGreg Clayton }
35032e0a750SGreg Clayton 
35130fdc8d8SChris Lattner 
35230fdc8d8SChris Lattner //----------------------------------------------------------------------
35330fdc8d8SChris Lattner // "register write"
35430fdc8d8SChris Lattner //----------------------------------------------------------------------
3555a988416SJim Ingham class CommandObjectRegisterWrite : public CommandObjectParsed
35630fdc8d8SChris Lattner {
35730fdc8d8SChris Lattner public:
358a7015092SGreg Clayton     CommandObjectRegisterWrite (CommandInterpreter &interpreter) :
3595a988416SJim Ingham         CommandObjectParsed (interpreter,
360a7015092SGreg Clayton                              "register write",
36130fdc8d8SChris Lattner                              "Modify a single register value.",
362405fe67fSCaroline Tice                              NULL,
363f9fc609fSGreg Clayton                              eFlagRequiresFrame         |
364f9fc609fSGreg Clayton                              eFlagRequiresRegContext    |
365f9fc609fSGreg Clayton                              eFlagProcessMustBeLaunched |
366f9fc609fSGreg Clayton                              eFlagProcessMustBePaused)
36730fdc8d8SChris Lattner     {
368405fe67fSCaroline Tice         CommandArgumentEntry arg1;
369405fe67fSCaroline Tice         CommandArgumentEntry arg2;
370405fe67fSCaroline Tice         CommandArgumentData register_arg;
371405fe67fSCaroline Tice         CommandArgumentData value_arg;
372405fe67fSCaroline Tice 
373405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
374405fe67fSCaroline Tice         register_arg.arg_type = eArgTypeRegisterName;
375405fe67fSCaroline Tice         register_arg.arg_repetition = eArgRepeatPlain;
376405fe67fSCaroline Tice 
377405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
378405fe67fSCaroline Tice         arg1.push_back (register_arg);
379405fe67fSCaroline Tice 
380405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
381405fe67fSCaroline Tice         value_arg.arg_type = eArgTypeValue;
382405fe67fSCaroline Tice         value_arg.arg_repetition = eArgRepeatPlain;
383405fe67fSCaroline Tice 
384405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
385405fe67fSCaroline Tice         arg2.push_back (value_arg);
386405fe67fSCaroline Tice 
387405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
388405fe67fSCaroline Tice         m_arguments.push_back (arg1);
389405fe67fSCaroline Tice         m_arguments.push_back (arg2);
39030fdc8d8SChris Lattner     }
39130fdc8d8SChris Lattner 
39230fdc8d8SChris Lattner     virtual
39330fdc8d8SChris Lattner     ~CommandObjectRegisterWrite ()
39430fdc8d8SChris Lattner     {
39530fdc8d8SChris Lattner     }
39630fdc8d8SChris Lattner 
3975a988416SJim Ingham protected:
39830fdc8d8SChris Lattner     virtual bool
3995a988416SJim Ingham     DoExecute(Args& command, CommandReturnObject &result)
40030fdc8d8SChris Lattner     {
40130fdc8d8SChris Lattner         DataExtractor reg_data;
402f9fc609fSGreg Clayton         RegisterContext *reg_ctx = m_exe_ctx.GetRegisterContext ();
40330fdc8d8SChris Lattner 
40430fdc8d8SChris Lattner         if (command.GetArgumentCount() != 2)
40530fdc8d8SChris Lattner         {
40630fdc8d8SChris Lattner             result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>");
40730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
40830fdc8d8SChris Lattner         }
40930fdc8d8SChris Lattner         else
41030fdc8d8SChris Lattner         {
41130fdc8d8SChris Lattner             const char *reg_name = command.GetArgumentAtIndex(0);
41230fdc8d8SChris Lattner             const char *value_str = command.GetArgumentAtIndex(1);
413385aa28cSGreg Clayton             const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
41430fdc8d8SChris Lattner 
41530fdc8d8SChris Lattner             if (reg_info)
41630fdc8d8SChris Lattner             {
4177349bd90SGreg Clayton                 RegisterValue reg_value;
4187349bd90SGreg Clayton 
4197349bd90SGreg Clayton                 Error error (reg_value.SetValueFromCString (reg_info, value_str));
42030fdc8d8SChris Lattner                 if (error.Success())
42130fdc8d8SChris Lattner                 {
4227349bd90SGreg Clayton                     if (reg_ctx->WriteRegister (reg_info, reg_value))
42330fdc8d8SChris Lattner                     {
424fa559e5cSGreg Clayton                         // Toss all frames and anything else in the thread
425fa559e5cSGreg Clayton                         // after a register has been written.
426f9fc609fSGreg Clayton                         m_exe_ctx.GetThreadRef().Flush();
42730fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusSuccessFinishNoResult);
42830fdc8d8SChris Lattner                         return true;
42930fdc8d8SChris Lattner                     }
43030fdc8d8SChris Lattner                 }
431b1ad65c5SJason Molenda                 if (error.AsCString())
43230fdc8d8SChris Lattner                 {
43330fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n",
43430fdc8d8SChris Lattner                                                  reg_name,
43530fdc8d8SChris Lattner                                                  value_str,
43630fdc8d8SChris Lattner                                                  error.AsCString());
43730fdc8d8SChris Lattner                 }
438b1ad65c5SJason Molenda                 else
439b1ad65c5SJason Molenda                 {
440b1ad65c5SJason Molenda                     result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'",
441b1ad65c5SJason Molenda                                                  reg_name,
442b1ad65c5SJason Molenda                                                  value_str);
443b1ad65c5SJason Molenda                 }
444b1ad65c5SJason Molenda                 result.SetStatus (eReturnStatusFailed);
44530fdc8d8SChris Lattner             }
44630fdc8d8SChris Lattner             else
44730fdc8d8SChris Lattner             {
44830fdc8d8SChris Lattner                 result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name);
44930fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
45030fdc8d8SChris Lattner             }
45130fdc8d8SChris Lattner         }
45230fdc8d8SChris Lattner         return result.Succeeded();
45330fdc8d8SChris Lattner     }
45430fdc8d8SChris Lattner };
45530fdc8d8SChris Lattner 
45630fdc8d8SChris Lattner 
45730fdc8d8SChris Lattner //----------------------------------------------------------------------
45830fdc8d8SChris Lattner // CommandObjectRegister constructor
45930fdc8d8SChris Lattner //----------------------------------------------------------------------
4606611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) :
461a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
462a7015092SGreg Clayton                             "register",
4633f4c09c1SCaroline Tice                             "A set of commands to access thread registers.",
46430fdc8d8SChris Lattner                             "register [read|write] ...")
46530fdc8d8SChris Lattner {
466a7015092SGreg Clayton     LoadSubCommand ("read",  CommandObjectSP (new CommandObjectRegisterRead (interpreter)));
467a7015092SGreg Clayton     LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter)));
46830fdc8d8SChris Lattner }
46930fdc8d8SChris Lattner 
47030fdc8d8SChris Lattner 
47130fdc8d8SChris Lattner //----------------------------------------------------------------------
47230fdc8d8SChris Lattner // Destructor
47330fdc8d8SChris Lattner //----------------------------------------------------------------------
47430fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister()
47530fdc8d8SChris Lattner {
47630fdc8d8SChris Lattner }
477