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"
651deb7962SGreg Clayton         m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT, 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());
998f7770f8SGreg Clayton                 if (((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint)) &&
1008f7770f8SGreg Clayton                     (reg_info->byte_size == reg_ctx->GetThread().GetProcess().GetAddressByteSize()))
101385aa28cSGreg Clayton                 {
1027349bd90SGreg Clayton                     addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS);
1037349bd90SGreg Clayton                     if (reg_addr != LLDB_INVALID_ADDRESS)
104385aa28cSGreg Clayton                     {
105385aa28cSGreg Clayton                         Address so_reg_addr;
106c14ee32dSGreg Clayton                         if (exe_ctx.GetTargetRef().GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr))
107385aa28cSGreg Clayton                         {
108385aa28cSGreg Clayton                             strm.PutCString ("  ");
109385aa28cSGreg Clayton                             so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
110385aa28cSGreg Clayton                         }
111385aa28cSGreg Clayton                     }
112385aa28cSGreg Clayton                 }
113385aa28cSGreg Clayton                 strm.EOL();
114385aa28cSGreg Clayton                 return true;
115385aa28cSGreg Clayton             }
116385aa28cSGreg Clayton         }
117385aa28cSGreg Clayton         return false;
118385aa28cSGreg Clayton     }
119385aa28cSGreg Clayton 
120385aa28cSGreg Clayton     bool
121385aa28cSGreg Clayton     DumpRegisterSet (const ExecutionContext &exe_ctx,
122385aa28cSGreg Clayton                      Stream &strm,
123385aa28cSGreg Clayton                      RegisterContext *reg_ctx,
124385aa28cSGreg Clayton                      uint32_t set_idx)
125385aa28cSGreg Clayton     {
126385aa28cSGreg Clayton         uint32_t unavailable_count = 0;
127385aa28cSGreg Clayton         uint32_t available_count = 0;
128385aa28cSGreg Clayton         const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx);
129385aa28cSGreg Clayton         if (reg_set)
130385aa28cSGreg Clayton         {
131385aa28cSGreg Clayton             strm.Printf ("%s:\n", reg_set->name);
132385aa28cSGreg Clayton             strm.IndentMore ();
133385aa28cSGreg Clayton             const uint32_t num_registers = reg_set->num_registers;
134385aa28cSGreg Clayton             for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
135385aa28cSGreg Clayton             {
136385aa28cSGreg Clayton                 const uint32_t reg = reg_set->registers[reg_idx];
137385aa28cSGreg Clayton                 if (DumpRegister (exe_ctx, strm, reg_ctx, reg_ctx->GetRegisterInfoAtIndex(reg)))
138385aa28cSGreg Clayton                     ++available_count;
139385aa28cSGreg Clayton                 else
140385aa28cSGreg Clayton                     ++unavailable_count;
141385aa28cSGreg Clayton             }
142385aa28cSGreg Clayton             strm.IndentLess ();
143385aa28cSGreg Clayton             if (unavailable_count)
144385aa28cSGreg Clayton             {
145385aa28cSGreg Clayton                 strm.Indent ();
146385aa28cSGreg Clayton                 strm.Printf("%u registers were unavailable.\n", unavailable_count);
147385aa28cSGreg Clayton             }
148385aa28cSGreg Clayton             strm.EOL();
149385aa28cSGreg Clayton         }
150385aa28cSGreg Clayton         return available_count > 0;
151385aa28cSGreg Clayton     }
152385aa28cSGreg Clayton 
15330fdc8d8SChris Lattner     virtual bool
1546611103cSGreg Clayton     Execute
1556611103cSGreg Clayton     (
1566611103cSGreg Clayton         Args& command,
1576611103cSGreg Clayton         CommandReturnObject &result
1586611103cSGreg Clayton     )
15930fdc8d8SChris Lattner     {
160385aa28cSGreg Clayton         Stream &strm = result.GetOutputStream();
1618b82f087SGreg Clayton         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
162385aa28cSGreg Clayton         RegisterContext *reg_ctx = exe_ctx.GetRegisterContext ();
16330fdc8d8SChris Lattner 
164385aa28cSGreg Clayton         if (reg_ctx)
16530fdc8d8SChris Lattner         {
16630fdc8d8SChris Lattner             const RegisterInfo *reg_info = NULL;
16730fdc8d8SChris Lattner             if (command.GetArgumentCount() == 0)
16830fdc8d8SChris Lattner             {
16930fdc8d8SChris Lattner                 uint32_t set_idx;
170385aa28cSGreg Clayton 
171385aa28cSGreg Clayton                 uint32_t num_register_sets = 1;
1721deb7962SGreg Clayton                 const uint32_t set_array_size = m_command_options.set_indexes.GetSize();
173385aa28cSGreg Clayton                 if (set_array_size > 0)
17430fdc8d8SChris Lattner                 {
175385aa28cSGreg Clayton                     for (uint32_t i=0; i<set_array_size; ++i)
17630fdc8d8SChris Lattner                     {
1771deb7962SGreg Clayton                         set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL);
178385aa28cSGreg Clayton                         if (set_idx != UINT32_MAX)
17930fdc8d8SChris Lattner                         {
180385aa28cSGreg Clayton                             if (!DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx))
181385aa28cSGreg Clayton                             {
182385aa28cSGreg Clayton                                 result.AppendErrorWithFormat ("invalid register set index: %u\n", set_idx);
183385aa28cSGreg Clayton                                 result.SetStatus (eReturnStatusFailed);
184385aa28cSGreg Clayton                                 break;
185385aa28cSGreg Clayton                             }
18630fdc8d8SChris Lattner                         }
18730fdc8d8SChris Lattner                         else
18830fdc8d8SChris Lattner                         {
189385aa28cSGreg Clayton                             result.AppendError ("invalid register set index\n");
190385aa28cSGreg Clayton                             result.SetStatus (eReturnStatusFailed);
191385aa28cSGreg Clayton                             break;
19230fdc8d8SChris Lattner                         }
19330fdc8d8SChris Lattner                     }
194385aa28cSGreg Clayton                 }
195385aa28cSGreg Clayton                 else
19630fdc8d8SChris Lattner                 {
1971deb7962SGreg Clayton                     if (m_command_options.dump_all_sets)
198385aa28cSGreg Clayton                         num_register_sets = reg_ctx->GetRegisterSetCount();
199385aa28cSGreg Clayton 
200385aa28cSGreg Clayton                     for (set_idx = 0; set_idx < num_register_sets; ++set_idx)
201385aa28cSGreg Clayton                     {
202385aa28cSGreg Clayton                         DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx);
20330fdc8d8SChris Lattner                     }
20430fdc8d8SChris Lattner                 }
20530fdc8d8SChris Lattner             }
20630fdc8d8SChris Lattner             else
20730fdc8d8SChris Lattner             {
2081deb7962SGreg Clayton                 if (m_command_options.dump_all_sets)
209385aa28cSGreg Clayton                 {
210385aa28cSGreg Clayton                     result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n");
211385aa28cSGreg Clayton                     result.SetStatus (eReturnStatusFailed);
212385aa28cSGreg Clayton                 }
2131deb7962SGreg Clayton                 else if (m_command_options.set_indexes.GetSize() > 0)
214385aa28cSGreg Clayton                 {
215385aa28cSGreg Clayton                     result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n");
216385aa28cSGreg Clayton                     result.SetStatus (eReturnStatusFailed);
217385aa28cSGreg Clayton                 }
218385aa28cSGreg Clayton                 else
219385aa28cSGreg Clayton                 {
22030fdc8d8SChris Lattner                     const char *arg_cstr;
22130fdc8d8SChris Lattner                     for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
22230fdc8d8SChris Lattner                     {
223385aa28cSGreg Clayton                         reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr);
22430fdc8d8SChris Lattner 
22530fdc8d8SChris Lattner                         if (reg_info)
22630fdc8d8SChris Lattner                         {
227385aa28cSGreg Clayton                             if (!DumpRegister (exe_ctx, strm, reg_ctx, reg_info))
228385aa28cSGreg Clayton                                 strm.Printf("%-12s = error: unavailable\n", reg_info->name);
22930fdc8d8SChris Lattner                         }
23030fdc8d8SChris Lattner                         else
23130fdc8d8SChris Lattner                         {
23230fdc8d8SChris Lattner                             result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr);
23330fdc8d8SChris Lattner                         }
23430fdc8d8SChris Lattner                     }
23530fdc8d8SChris Lattner                 }
23630fdc8d8SChris Lattner             }
237385aa28cSGreg Clayton         }
23830fdc8d8SChris Lattner         else
23930fdc8d8SChris Lattner         {
24030fdc8d8SChris Lattner             result.AppendError ("no current frame");
24130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
24230fdc8d8SChris Lattner         }
24330fdc8d8SChris Lattner         return result.Succeeded();
24430fdc8d8SChris Lattner     }
24532e0a750SGreg Clayton 
2461deb7962SGreg Clayton     class CommandOptions : public OptionGroup
24732e0a750SGreg Clayton     {
24832e0a750SGreg Clayton     public:
2491deb7962SGreg Clayton         CommandOptions () :
2501deb7962SGreg Clayton             OptionGroup(),
251385aa28cSGreg Clayton             set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)),
2529a8fa916SGreg Clayton             dump_all_sets (false, false), // Initial and default values are false
2539a8fa916SGreg Clayton             alternate_name (false, false)
25432e0a750SGreg Clayton         {
25532e0a750SGreg Clayton         }
25632e0a750SGreg Clayton 
25732e0a750SGreg Clayton         virtual
25832e0a750SGreg Clayton         ~CommandOptions ()
25932e0a750SGreg Clayton         {
26032e0a750SGreg Clayton         }
26132e0a750SGreg Clayton 
2621deb7962SGreg Clayton 
2631deb7962SGreg Clayton         virtual uint32_t
2641deb7962SGreg Clayton         GetNumDefinitions ();
2651deb7962SGreg Clayton 
2661deb7962SGreg Clayton         virtual const OptionDefinition*
2671deb7962SGreg Clayton         GetDefinitions ()
2681deb7962SGreg Clayton         {
2691deb7962SGreg Clayton             return g_option_table;
2701deb7962SGreg Clayton         }
2711deb7962SGreg Clayton 
2721deb7962SGreg Clayton         virtual void
2731deb7962SGreg Clayton         OptionParsingStarting (CommandInterpreter &interpreter)
2741deb7962SGreg Clayton         {
2751deb7962SGreg Clayton             set_indexes.Clear();
2761deb7962SGreg Clayton             dump_all_sets.Clear();
2771deb7962SGreg Clayton             alternate_name.Clear();
2781deb7962SGreg Clayton         }
2791deb7962SGreg Clayton 
28032e0a750SGreg Clayton         virtual Error
2811deb7962SGreg Clayton         SetOptionValue (CommandInterpreter &interpreter,
2821deb7962SGreg Clayton                         uint32_t option_idx,
2831deb7962SGreg Clayton                         const char *option_value)
28432e0a750SGreg Clayton         {
28532e0a750SGreg Clayton             Error error;
2861deb7962SGreg Clayton             const char short_option = (char) g_option_table[option_idx].short_option;
28732e0a750SGreg Clayton             switch (short_option)
28832e0a750SGreg Clayton             {
289385aa28cSGreg Clayton                 case 's':
290385aa28cSGreg Clayton                     {
2911deb7962SGreg Clayton                         OptionValueSP value_sp (OptionValueUInt64::Create (option_value, error));
292385aa28cSGreg Clayton                         if (value_sp)
293385aa28cSGreg Clayton                             set_indexes.AppendValue (value_sp);
294385aa28cSGreg Clayton                     }
295385aa28cSGreg Clayton                     break;
296385aa28cSGreg Clayton 
297385aa28cSGreg Clayton                 case 'a':
2989a8fa916SGreg Clayton                     // When we don't use OptionValue::SetValueFromCString(const char *) to
2999a8fa916SGreg Clayton                     // set an option value, it won't be marked as being set in the options
3009a8fa916SGreg Clayton                     // so we make a call to let users know the value was set via option
301385aa28cSGreg Clayton                     dump_all_sets.SetCurrentValue (true);
3029a8fa916SGreg Clayton                     dump_all_sets.SetOptionWasSet ();
3039a8fa916SGreg Clayton                     break;
3049a8fa916SGreg Clayton 
3059a8fa916SGreg Clayton                 case 'A':
3069a8fa916SGreg Clayton                     // When we don't use OptionValue::SetValueFromCString(const char *) to
3079a8fa916SGreg Clayton                     // set an option value, it won't be marked as being set in the options
3089a8fa916SGreg Clayton                     // so we make a call to let users know the value was set via option
3099a8fa916SGreg Clayton                     alternate_name.SetCurrentValue (true);
3109a8fa916SGreg Clayton                     dump_all_sets.SetOptionWasSet ();
311385aa28cSGreg Clayton                     break;
312385aa28cSGreg Clayton 
31332e0a750SGreg Clayton                 default:
314*86edbf41SGreg Clayton                     error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
31532e0a750SGreg Clayton                     break;
31632e0a750SGreg Clayton             }
31732e0a750SGreg Clayton             return error;
31832e0a750SGreg Clayton         }
31932e0a750SGreg Clayton 
32032e0a750SGreg Clayton         // Options table: Required for subclasses of Options.
32132e0a750SGreg Clayton 
3221deb7962SGreg Clayton         static const OptionDefinition g_option_table[];
32332e0a750SGreg Clayton 
32432e0a750SGreg Clayton         // Instance variables to hold the values for command options.
325385aa28cSGreg Clayton         OptionValueArray set_indexes;
326385aa28cSGreg Clayton         OptionValueBoolean dump_all_sets;
3279a8fa916SGreg Clayton         OptionValueBoolean alternate_name;
32830fdc8d8SChris Lattner     };
32930fdc8d8SChris Lattner 
3301deb7962SGreg Clayton     OptionGroupOptions m_option_group;
3311deb7962SGreg Clayton     OptionGroupFormat m_format_options;
3321deb7962SGreg Clayton     CommandOptions m_command_options;
33332e0a750SGreg Clayton };
33432e0a750SGreg Clayton 
3353d0fcf5eSJohnny Chen const OptionDefinition
33632e0a750SGreg Clayton CommandObjectRegisterRead::CommandOptions::g_option_table[] =
33732e0a750SGreg Clayton {
3389a8fa916SGreg 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."},
339385aa28cSGreg Clayton     { LLDB_OPT_SET_1  , false, "set"      , 's', required_argument, NULL, 0, eArgTypeIndex     , "Specify which register sets to dump by index."},
340385aa28cSGreg Clayton     { LLDB_OPT_SET_2  , false, "all"      , 'a', no_argument      , NULL, 0, eArgTypeNone      , "Show all register sets."},
34132e0a750SGreg Clayton };
34232e0a750SGreg Clayton 
3431deb7962SGreg Clayton uint32_t
3441deb7962SGreg Clayton CommandObjectRegisterRead::CommandOptions::GetNumDefinitions ()
3451deb7962SGreg Clayton {
3461deb7962SGreg Clayton     return sizeof(g_option_table)/sizeof(OptionDefinition);
3471deb7962SGreg Clayton }
34832e0a750SGreg Clayton 
34930fdc8d8SChris Lattner 
35030fdc8d8SChris Lattner //----------------------------------------------------------------------
35130fdc8d8SChris Lattner // "register write"
35230fdc8d8SChris Lattner //----------------------------------------------------------------------
35330fdc8d8SChris Lattner class CommandObjectRegisterWrite : public CommandObject
35430fdc8d8SChris Lattner {
35530fdc8d8SChris Lattner public:
356a7015092SGreg Clayton     CommandObjectRegisterWrite (CommandInterpreter &interpreter) :
357a7015092SGreg Clayton         CommandObject (interpreter,
358a7015092SGreg Clayton                        "register write",
35930fdc8d8SChris Lattner                        "Modify a single register value.",
360405fe67fSCaroline Tice                        NULL,
36130fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
36230fdc8d8SChris Lattner     {
363405fe67fSCaroline Tice         CommandArgumentEntry arg1;
364405fe67fSCaroline Tice         CommandArgumentEntry arg2;
365405fe67fSCaroline Tice         CommandArgumentData register_arg;
366405fe67fSCaroline Tice         CommandArgumentData value_arg;
367405fe67fSCaroline Tice 
368405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
369405fe67fSCaroline Tice         register_arg.arg_type = eArgTypeRegisterName;
370405fe67fSCaroline Tice         register_arg.arg_repetition = eArgRepeatPlain;
371405fe67fSCaroline Tice 
372405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
373405fe67fSCaroline Tice         arg1.push_back (register_arg);
374405fe67fSCaroline Tice 
375405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
376405fe67fSCaroline Tice         value_arg.arg_type = eArgTypeValue;
377405fe67fSCaroline Tice         value_arg.arg_repetition = eArgRepeatPlain;
378405fe67fSCaroline Tice 
379405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
380405fe67fSCaroline Tice         arg2.push_back (value_arg);
381405fe67fSCaroline Tice 
382405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
383405fe67fSCaroline Tice         m_arguments.push_back (arg1);
384405fe67fSCaroline Tice         m_arguments.push_back (arg2);
38530fdc8d8SChris Lattner     }
38630fdc8d8SChris Lattner 
38730fdc8d8SChris Lattner     virtual
38830fdc8d8SChris Lattner     ~CommandObjectRegisterWrite ()
38930fdc8d8SChris Lattner     {
39030fdc8d8SChris Lattner     }
39130fdc8d8SChris Lattner 
39230fdc8d8SChris Lattner     virtual bool
3936611103cSGreg Clayton     Execute
3946611103cSGreg Clayton     (
3956611103cSGreg Clayton         Args& command,
3966611103cSGreg Clayton         CommandReturnObject &result
3976611103cSGreg Clayton     )
39830fdc8d8SChris Lattner     {
39930fdc8d8SChris Lattner         DataExtractor reg_data;
4008b82f087SGreg Clayton         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
401385aa28cSGreg Clayton         RegisterContext *reg_ctx = exe_ctx.GetRegisterContext ();
40230fdc8d8SChris Lattner 
403385aa28cSGreg Clayton         if (reg_ctx)
40430fdc8d8SChris Lattner         {
40530fdc8d8SChris Lattner             if (command.GetArgumentCount() != 2)
40630fdc8d8SChris Lattner             {
40730fdc8d8SChris Lattner                 result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>");
40830fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
40930fdc8d8SChris Lattner             }
41030fdc8d8SChris Lattner             else
41130fdc8d8SChris Lattner             {
41230fdc8d8SChris Lattner                 const char *reg_name = command.GetArgumentAtIndex(0);
41330fdc8d8SChris Lattner                 const char *value_str = command.GetArgumentAtIndex(1);
414385aa28cSGreg Clayton                 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
41530fdc8d8SChris Lattner 
41630fdc8d8SChris Lattner                 if (reg_info)
41730fdc8d8SChris Lattner                 {
4187349bd90SGreg Clayton                     RegisterValue reg_value;
4197349bd90SGreg Clayton 
4207349bd90SGreg Clayton                     Error error (reg_value.SetValueFromCString (reg_info, value_str));
42130fdc8d8SChris Lattner                     if (error.Success())
42230fdc8d8SChris Lattner                     {
4237349bd90SGreg Clayton                         if (reg_ctx->WriteRegister (reg_info, reg_value))
42430fdc8d8SChris Lattner                         {
42530fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusSuccessFinishNoResult);
42630fdc8d8SChris Lattner                             return true;
42730fdc8d8SChris Lattner                         }
42830fdc8d8SChris Lattner                     }
429b1ad65c5SJason Molenda                     if (error.AsCString())
43030fdc8d8SChris Lattner                     {
43130fdc8d8SChris Lattner                         result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n",
43230fdc8d8SChris Lattner                                                      reg_name,
43330fdc8d8SChris Lattner                                                      value_str,
43430fdc8d8SChris Lattner                                                      error.AsCString());
43530fdc8d8SChris Lattner                     }
436b1ad65c5SJason Molenda                     else
437b1ad65c5SJason Molenda                     {
438b1ad65c5SJason Molenda                         result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'",
439b1ad65c5SJason Molenda                                                      reg_name,
440b1ad65c5SJason Molenda                                                      value_str);
441b1ad65c5SJason Molenda                     }
442b1ad65c5SJason Molenda                     result.SetStatus (eReturnStatusFailed);
44330fdc8d8SChris Lattner                 }
44430fdc8d8SChris Lattner                 else
44530fdc8d8SChris Lattner                 {
44630fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name);
44730fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
44830fdc8d8SChris Lattner                 }
44930fdc8d8SChris Lattner             }
45030fdc8d8SChris Lattner         }
45130fdc8d8SChris Lattner         else
45230fdc8d8SChris Lattner         {
45330fdc8d8SChris Lattner             result.AppendError ("no current frame");
45430fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
45530fdc8d8SChris Lattner         }
45630fdc8d8SChris Lattner         return result.Succeeded();
45730fdc8d8SChris Lattner     }
45830fdc8d8SChris Lattner };
45930fdc8d8SChris Lattner 
46030fdc8d8SChris Lattner 
46130fdc8d8SChris Lattner //----------------------------------------------------------------------
46230fdc8d8SChris Lattner // CommandObjectRegister constructor
46330fdc8d8SChris Lattner //----------------------------------------------------------------------
4646611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) :
465a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
466a7015092SGreg Clayton                             "register",
4673f4c09c1SCaroline Tice                             "A set of commands to access thread registers.",
46830fdc8d8SChris Lattner                             "register [read|write] ...")
46930fdc8d8SChris Lattner {
470a7015092SGreg Clayton     LoadSubCommand ("read",  CommandObjectSP (new CommandObjectRegisterRead (interpreter)));
471a7015092SGreg Clayton     LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter)));
47230fdc8d8SChris Lattner }
47330fdc8d8SChris Lattner 
47430fdc8d8SChris Lattner 
47530fdc8d8SChris Lattner //----------------------------------------------------------------------
47630fdc8d8SChris Lattner // Destructor
47730fdc8d8SChris Lattner //----------------------------------------------------------------------
47830fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister()
47930fdc8d8SChris Lattner {
48030fdc8d8SChris Lattner }
481