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"
2530fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h"
268f7770f8SGreg Clayton #include "lldb/Target/Process.h"
2730fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
288f7770f8SGreg Clayton #include "lldb/Target/Thread.h"
2930fdc8d8SChris Lattner 
3030fdc8d8SChris Lattner using namespace lldb;
3130fdc8d8SChris Lattner using namespace lldb_private;
3230fdc8d8SChris Lattner 
3330fdc8d8SChris Lattner //----------------------------------------------------------------------
3430fdc8d8SChris Lattner // "register read"
3530fdc8d8SChris Lattner //----------------------------------------------------------------------
3630fdc8d8SChris Lattner class CommandObjectRegisterRead : public CommandObject
3730fdc8d8SChris Lattner {
3830fdc8d8SChris Lattner public:
39a7015092SGreg Clayton     CommandObjectRegisterRead (CommandInterpreter &interpreter) :
40a7015092SGreg Clayton         CommandObject (interpreter,
41a7015092SGreg Clayton                        "register read",
42405fe67fSCaroline Tice                        "Dump the contents of one or more register values from the current frame.  If no register is specified, dumps them all.",
43405fe67fSCaroline Tice                        //"register read [<reg-name1> [<reg-name2> [...]]]",
44405fe67fSCaroline Tice                        NULL,
45eb0103f2SGreg Clayton                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
46eb0103f2SGreg Clayton         m_options (interpreter)
4730fdc8d8SChris Lattner     {
48405fe67fSCaroline Tice         CommandArgumentEntry arg;
49405fe67fSCaroline Tice         CommandArgumentData register_arg;
50405fe67fSCaroline Tice 
51405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
52405fe67fSCaroline Tice         register_arg.arg_type = eArgTypeRegisterName;
53405fe67fSCaroline Tice         register_arg.arg_repetition = eArgRepeatStar;
54405fe67fSCaroline Tice 
55405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
56405fe67fSCaroline Tice         arg.push_back (register_arg);
57405fe67fSCaroline Tice 
58405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
59405fe67fSCaroline Tice         m_arguments.push_back (arg);
6030fdc8d8SChris Lattner     }
6130fdc8d8SChris Lattner 
6230fdc8d8SChris Lattner     virtual
6330fdc8d8SChris Lattner     ~CommandObjectRegisterRead ()
6430fdc8d8SChris Lattner     {
6530fdc8d8SChris Lattner     }
6630fdc8d8SChris Lattner 
6732e0a750SGreg Clayton     Options *
6832e0a750SGreg Clayton     GetOptions ()
6932e0a750SGreg Clayton     {
7032e0a750SGreg Clayton         return &m_options;
7132e0a750SGreg Clayton     }
7232e0a750SGreg Clayton 
73385aa28cSGreg Clayton     bool
74385aa28cSGreg Clayton     DumpRegister (const ExecutionContext &exe_ctx,
75385aa28cSGreg Clayton                   Stream &strm,
76385aa28cSGreg Clayton                   RegisterContext *reg_ctx,
77385aa28cSGreg Clayton                   const RegisterInfo *reg_info)
78385aa28cSGreg Clayton     {
79385aa28cSGreg Clayton         if (reg_info)
80385aa28cSGreg Clayton         {
817349bd90SGreg Clayton             RegisterValue reg_value;
82385aa28cSGreg Clayton 
837349bd90SGreg Clayton             if (reg_ctx->ReadRegister (reg_info, reg_value))
84385aa28cSGreg Clayton             {
85385aa28cSGreg Clayton                 strm.Indent ();
86385aa28cSGreg Clayton                 Format format;
87385aa28cSGreg Clayton                 if (m_options.format == eFormatDefault)
88385aa28cSGreg Clayton                     format = reg_info->format;
89385aa28cSGreg Clayton                 else
90385aa28cSGreg Clayton                     format = m_options.format;
91385aa28cSGreg Clayton 
929a8fa916SGreg Clayton                 bool prefix_with_altname = m_options.alternate_name;
939a8fa916SGreg Clayton                 bool prefix_with_name = !prefix_with_altname;
949a8fa916SGreg Clayton                 reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname, m_options.format);
958f7770f8SGreg Clayton                 if (((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint)) &&
968f7770f8SGreg Clayton                     (reg_info->byte_size == reg_ctx->GetThread().GetProcess().GetAddressByteSize()))
97385aa28cSGreg Clayton                 {
987349bd90SGreg Clayton                     addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS);
997349bd90SGreg Clayton                     if (reg_addr != LLDB_INVALID_ADDRESS)
100385aa28cSGreg Clayton                     {
101385aa28cSGreg Clayton                         Address so_reg_addr;
102*c14ee32dSGreg Clayton                         if (exe_ctx.GetTargetRef().GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr))
103385aa28cSGreg Clayton                         {
104385aa28cSGreg Clayton                             strm.PutCString ("  ");
105385aa28cSGreg Clayton                             so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
106385aa28cSGreg Clayton                         }
107385aa28cSGreg Clayton                     }
108385aa28cSGreg Clayton                 }
109385aa28cSGreg Clayton                 strm.EOL();
110385aa28cSGreg Clayton                 return true;
111385aa28cSGreg Clayton             }
112385aa28cSGreg Clayton         }
113385aa28cSGreg Clayton         return false;
114385aa28cSGreg Clayton     }
115385aa28cSGreg Clayton 
116385aa28cSGreg Clayton     bool
117385aa28cSGreg Clayton     DumpRegisterSet (const ExecutionContext &exe_ctx,
118385aa28cSGreg Clayton                      Stream &strm,
119385aa28cSGreg Clayton                      RegisterContext *reg_ctx,
120385aa28cSGreg Clayton                      uint32_t set_idx)
121385aa28cSGreg Clayton     {
122385aa28cSGreg Clayton         uint32_t unavailable_count = 0;
123385aa28cSGreg Clayton         uint32_t available_count = 0;
124385aa28cSGreg Clayton         const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx);
125385aa28cSGreg Clayton         if (reg_set)
126385aa28cSGreg Clayton         {
127385aa28cSGreg Clayton             strm.Printf ("%s:\n", reg_set->name);
128385aa28cSGreg Clayton             strm.IndentMore ();
129385aa28cSGreg Clayton             const uint32_t num_registers = reg_set->num_registers;
130385aa28cSGreg Clayton             for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
131385aa28cSGreg Clayton             {
132385aa28cSGreg Clayton                 const uint32_t reg = reg_set->registers[reg_idx];
133385aa28cSGreg Clayton                 if (DumpRegister (exe_ctx, strm, reg_ctx, reg_ctx->GetRegisterInfoAtIndex(reg)))
134385aa28cSGreg Clayton                     ++available_count;
135385aa28cSGreg Clayton                 else
136385aa28cSGreg Clayton                     ++unavailable_count;
137385aa28cSGreg Clayton             }
138385aa28cSGreg Clayton             strm.IndentLess ();
139385aa28cSGreg Clayton             if (unavailable_count)
140385aa28cSGreg Clayton             {
141385aa28cSGreg Clayton                 strm.Indent ();
142385aa28cSGreg Clayton                 strm.Printf("%u registers were unavailable.\n", unavailable_count);
143385aa28cSGreg Clayton             }
144385aa28cSGreg Clayton             strm.EOL();
145385aa28cSGreg Clayton         }
146385aa28cSGreg Clayton         return available_count > 0;
147385aa28cSGreg Clayton     }
148385aa28cSGreg Clayton 
14930fdc8d8SChris Lattner     virtual bool
1506611103cSGreg Clayton     Execute
1516611103cSGreg Clayton     (
1526611103cSGreg Clayton         Args& command,
1536611103cSGreg Clayton         CommandReturnObject &result
1546611103cSGreg Clayton     )
15530fdc8d8SChris Lattner     {
156385aa28cSGreg Clayton         Stream &strm = result.GetOutputStream();
1578b82f087SGreg Clayton         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
158385aa28cSGreg Clayton         RegisterContext *reg_ctx = exe_ctx.GetRegisterContext ();
15930fdc8d8SChris Lattner 
160385aa28cSGreg Clayton         if (reg_ctx)
16130fdc8d8SChris Lattner         {
16230fdc8d8SChris Lattner             const RegisterInfo *reg_info = NULL;
16330fdc8d8SChris Lattner             if (command.GetArgumentCount() == 0)
16430fdc8d8SChris Lattner             {
16530fdc8d8SChris Lattner                 uint32_t set_idx;
166385aa28cSGreg Clayton 
167385aa28cSGreg Clayton                 uint32_t num_register_sets = 1;
168385aa28cSGreg Clayton                 const uint32_t set_array_size = m_options.set_indexes.GetSize();
169385aa28cSGreg Clayton                 if (set_array_size > 0)
17030fdc8d8SChris Lattner                 {
171385aa28cSGreg Clayton                     for (uint32_t i=0; i<set_array_size; ++i)
17230fdc8d8SChris Lattner                     {
1737e14f91dSGreg Clayton                         set_idx = m_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL);
174385aa28cSGreg Clayton                         if (set_idx != UINT32_MAX)
17530fdc8d8SChris Lattner                         {
176385aa28cSGreg Clayton                             if (!DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx))
177385aa28cSGreg Clayton                             {
178385aa28cSGreg Clayton                                 result.AppendErrorWithFormat ("invalid register set index: %u\n", set_idx);
179385aa28cSGreg Clayton                                 result.SetStatus (eReturnStatusFailed);
180385aa28cSGreg Clayton                                 break;
181385aa28cSGreg Clayton                             }
18230fdc8d8SChris Lattner                         }
18330fdc8d8SChris Lattner                         else
18430fdc8d8SChris Lattner                         {
185385aa28cSGreg Clayton                             result.AppendError ("invalid register set index\n");
186385aa28cSGreg Clayton                             result.SetStatus (eReturnStatusFailed);
187385aa28cSGreg Clayton                             break;
18830fdc8d8SChris Lattner                         }
18930fdc8d8SChris Lattner                     }
190385aa28cSGreg Clayton                 }
191385aa28cSGreg Clayton                 else
19230fdc8d8SChris Lattner                 {
193385aa28cSGreg Clayton                     if (m_options.dump_all_sets)
194385aa28cSGreg Clayton                         num_register_sets = reg_ctx->GetRegisterSetCount();
195385aa28cSGreg Clayton 
196385aa28cSGreg Clayton                     for (set_idx = 0; set_idx < num_register_sets; ++set_idx)
197385aa28cSGreg Clayton                     {
198385aa28cSGreg Clayton                         DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx);
19930fdc8d8SChris Lattner                     }
20030fdc8d8SChris Lattner                 }
20130fdc8d8SChris Lattner             }
20230fdc8d8SChris Lattner             else
20330fdc8d8SChris Lattner             {
204385aa28cSGreg Clayton                 if (m_options.dump_all_sets)
205385aa28cSGreg Clayton                 {
206385aa28cSGreg Clayton                     result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n");
207385aa28cSGreg Clayton                     result.SetStatus (eReturnStatusFailed);
208385aa28cSGreg Clayton                 }
209385aa28cSGreg Clayton                 else if (m_options.set_indexes.GetSize() > 0)
210385aa28cSGreg Clayton                 {
211385aa28cSGreg Clayton                     result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n");
212385aa28cSGreg Clayton                     result.SetStatus (eReturnStatusFailed);
213385aa28cSGreg Clayton                 }
214385aa28cSGreg Clayton                 else
215385aa28cSGreg Clayton                 {
21630fdc8d8SChris Lattner                     const char *arg_cstr;
21730fdc8d8SChris Lattner                     for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
21830fdc8d8SChris Lattner                     {
219385aa28cSGreg Clayton                         reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr);
22030fdc8d8SChris Lattner 
22130fdc8d8SChris Lattner                         if (reg_info)
22230fdc8d8SChris Lattner                         {
223385aa28cSGreg Clayton                             if (!DumpRegister (exe_ctx, strm, reg_ctx, reg_info))
224385aa28cSGreg Clayton                                 strm.Printf("%-12s = error: unavailable\n", reg_info->name);
22530fdc8d8SChris Lattner                         }
22630fdc8d8SChris Lattner                         else
22730fdc8d8SChris Lattner                         {
22830fdc8d8SChris Lattner                             result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr);
22930fdc8d8SChris Lattner                         }
23030fdc8d8SChris Lattner                     }
23130fdc8d8SChris Lattner                 }
23230fdc8d8SChris Lattner             }
233385aa28cSGreg Clayton         }
23430fdc8d8SChris Lattner         else
23530fdc8d8SChris Lattner         {
23630fdc8d8SChris Lattner             result.AppendError ("no current frame");
23730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
23830fdc8d8SChris Lattner         }
23930fdc8d8SChris Lattner         return result.Succeeded();
24030fdc8d8SChris Lattner     }
24132e0a750SGreg Clayton 
24232e0a750SGreg Clayton protected:
24332e0a750SGreg Clayton     class CommandOptions : public Options
24432e0a750SGreg Clayton     {
24532e0a750SGreg Clayton     public:
246eb0103f2SGreg Clayton         CommandOptions (CommandInterpreter &interpreter) :
247385aa28cSGreg Clayton             Options(interpreter),
248385aa28cSGreg Clayton             set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)),
2499a8fa916SGreg Clayton             dump_all_sets (false, false), // Initial and default values are false
2509a8fa916SGreg Clayton             alternate_name (false, false)
25132e0a750SGreg Clayton         {
252f6b8b581SGreg Clayton             OptionParsingStarting();
25332e0a750SGreg Clayton         }
25432e0a750SGreg Clayton 
25532e0a750SGreg Clayton         virtual
25632e0a750SGreg Clayton         ~CommandOptions ()
25732e0a750SGreg Clayton         {
25832e0a750SGreg Clayton         }
25932e0a750SGreg Clayton 
26032e0a750SGreg Clayton         virtual Error
261f6b8b581SGreg Clayton         SetOptionValue (uint32_t option_idx, const char *option_arg)
26232e0a750SGreg Clayton         {
26332e0a750SGreg Clayton             Error error;
26432e0a750SGreg Clayton             char short_option = (char) m_getopt_table[option_idx].val;
26532e0a750SGreg Clayton             switch (short_option)
26632e0a750SGreg Clayton             {
26732e0a750SGreg Clayton                 case 'f':
26868ebae61SGreg Clayton                     error = Args::StringToFormat (option_arg, format, NULL);
269385aa28cSGreg Clayton                     break;
270385aa28cSGreg Clayton 
271385aa28cSGreg Clayton                 case 's':
272385aa28cSGreg Clayton                     {
273385aa28cSGreg Clayton                         OptionValueSP value_sp (OptionValueUInt64::Create (option_arg, error));
274385aa28cSGreg Clayton                         if (value_sp)
275385aa28cSGreg Clayton                             set_indexes.AppendValue (value_sp);
276385aa28cSGreg Clayton                     }
277385aa28cSGreg Clayton                     break;
278385aa28cSGreg Clayton 
279385aa28cSGreg Clayton                 case 'a':
2809a8fa916SGreg Clayton                     // When we don't use OptionValue::SetValueFromCString(const char *) to
2819a8fa916SGreg Clayton                     // set an option value, it won't be marked as being set in the options
2829a8fa916SGreg Clayton                     // so we make a call to let users know the value was set via option
283385aa28cSGreg Clayton                     dump_all_sets.SetCurrentValue (true);
2849a8fa916SGreg Clayton                     dump_all_sets.SetOptionWasSet ();
2859a8fa916SGreg Clayton                     break;
2869a8fa916SGreg Clayton 
2879a8fa916SGreg Clayton                 case 'A':
2889a8fa916SGreg Clayton                     // When we don't use OptionValue::SetValueFromCString(const char *) to
2899a8fa916SGreg Clayton                     // set an option value, it won't be marked as being set in the options
2909a8fa916SGreg Clayton                     // so we make a call to let users know the value was set via option
2919a8fa916SGreg Clayton                     alternate_name.SetCurrentValue (true);
2929a8fa916SGreg Clayton                     dump_all_sets.SetOptionWasSet ();
293385aa28cSGreg Clayton                     break;
294385aa28cSGreg Clayton 
29532e0a750SGreg Clayton                 default:
29632e0a750SGreg Clayton                     error.SetErrorStringWithFormat("Unrecognized short option '%c'\n", short_option);
29732e0a750SGreg Clayton                     break;
29832e0a750SGreg Clayton             }
29932e0a750SGreg Clayton             return error;
30032e0a750SGreg Clayton         }
30132e0a750SGreg Clayton 
30232e0a750SGreg Clayton         void
303f6b8b581SGreg Clayton         OptionParsingStarting ()
30432e0a750SGreg Clayton         {
305385aa28cSGreg Clayton             format = eFormatDefault;
306385aa28cSGreg Clayton             set_indexes.Clear();
307385aa28cSGreg Clayton             dump_all_sets.Clear();
3089a8fa916SGreg Clayton             alternate_name.Clear();
30932e0a750SGreg Clayton         }
31032e0a750SGreg Clayton 
31132e0a750SGreg Clayton         const OptionDefinition*
31232e0a750SGreg Clayton         GetDefinitions ()
31332e0a750SGreg Clayton         {
31432e0a750SGreg Clayton             return g_option_table;
31532e0a750SGreg Clayton         }
31632e0a750SGreg Clayton 
31732e0a750SGreg Clayton         // Options table: Required for subclasses of Options.
31832e0a750SGreg Clayton 
31932e0a750SGreg Clayton         static OptionDefinition g_option_table[];
32032e0a750SGreg Clayton 
32132e0a750SGreg Clayton         // Instance variables to hold the values for command options.
322385aa28cSGreg Clayton         lldb::Format format;
323385aa28cSGreg Clayton         OptionValueArray set_indexes;
324385aa28cSGreg Clayton         OptionValueBoolean dump_all_sets;
3259a8fa916SGreg Clayton         OptionValueBoolean alternate_name;
32630fdc8d8SChris Lattner     };
32730fdc8d8SChris Lattner 
32832e0a750SGreg Clayton     CommandOptions m_options;
32932e0a750SGreg Clayton };
33032e0a750SGreg Clayton 
33132e0a750SGreg Clayton OptionDefinition
33232e0a750SGreg Clayton CommandObjectRegisterRead::CommandOptions::g_option_table[] =
33332e0a750SGreg Clayton {
334385aa28cSGreg Clayton     { LLDB_OPT_SET_ALL, false, "format"   , 'f', required_argument, NULL, 0, eArgTypeExprFormat, "Specify the format to use when dumping register values."},
3359a8fa916SGreg 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."},
336385aa28cSGreg Clayton     { LLDB_OPT_SET_1  , false, "set"      , 's', required_argument, NULL, 0, eArgTypeIndex     , "Specify which register sets to dump by index."},
337385aa28cSGreg Clayton     { LLDB_OPT_SET_2  , false, "all"      , 'a', no_argument      , NULL, 0, eArgTypeNone      , "Show all register sets."},
33832e0a750SGreg Clayton     { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL }
33932e0a750SGreg Clayton };
34032e0a750SGreg Clayton 
34132e0a750SGreg Clayton 
34230fdc8d8SChris Lattner 
34330fdc8d8SChris Lattner //----------------------------------------------------------------------
34430fdc8d8SChris Lattner // "register write"
34530fdc8d8SChris Lattner //----------------------------------------------------------------------
34630fdc8d8SChris Lattner class CommandObjectRegisterWrite : public CommandObject
34730fdc8d8SChris Lattner {
34830fdc8d8SChris Lattner public:
349a7015092SGreg Clayton     CommandObjectRegisterWrite (CommandInterpreter &interpreter) :
350a7015092SGreg Clayton         CommandObject (interpreter,
351a7015092SGreg Clayton                        "register write",
35230fdc8d8SChris Lattner                        "Modify a single register value.",
353405fe67fSCaroline Tice                        //"register write <reg-name> <value>",
354405fe67fSCaroline Tice                        NULL,
35530fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
35630fdc8d8SChris Lattner     {
357405fe67fSCaroline Tice         CommandArgumentEntry arg1;
358405fe67fSCaroline Tice         CommandArgumentEntry arg2;
359405fe67fSCaroline Tice         CommandArgumentData register_arg;
360405fe67fSCaroline Tice         CommandArgumentData value_arg;
361405fe67fSCaroline Tice 
362405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
363405fe67fSCaroline Tice         register_arg.arg_type = eArgTypeRegisterName;
364405fe67fSCaroline Tice         register_arg.arg_repetition = eArgRepeatPlain;
365405fe67fSCaroline Tice 
366405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
367405fe67fSCaroline Tice         arg1.push_back (register_arg);
368405fe67fSCaroline Tice 
369405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
370405fe67fSCaroline Tice         value_arg.arg_type = eArgTypeValue;
371405fe67fSCaroline Tice         value_arg.arg_repetition = eArgRepeatPlain;
372405fe67fSCaroline Tice 
373405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
374405fe67fSCaroline Tice         arg2.push_back (value_arg);
375405fe67fSCaroline Tice 
376405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
377405fe67fSCaroline Tice         m_arguments.push_back (arg1);
378405fe67fSCaroline Tice         m_arguments.push_back (arg2);
37930fdc8d8SChris Lattner     }
38030fdc8d8SChris Lattner 
38130fdc8d8SChris Lattner     virtual
38230fdc8d8SChris Lattner     ~CommandObjectRegisterWrite ()
38330fdc8d8SChris Lattner     {
38430fdc8d8SChris Lattner     }
38530fdc8d8SChris Lattner 
38630fdc8d8SChris Lattner     virtual bool
3876611103cSGreg Clayton     Execute
3886611103cSGreg Clayton     (
3896611103cSGreg Clayton         Args& command,
3906611103cSGreg Clayton         CommandReturnObject &result
3916611103cSGreg Clayton     )
39230fdc8d8SChris Lattner     {
39330fdc8d8SChris Lattner         DataExtractor reg_data;
3948b82f087SGreg Clayton         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
395385aa28cSGreg Clayton         RegisterContext *reg_ctx = exe_ctx.GetRegisterContext ();
39630fdc8d8SChris Lattner 
397385aa28cSGreg Clayton         if (reg_ctx)
39830fdc8d8SChris Lattner         {
39930fdc8d8SChris Lattner             if (command.GetArgumentCount() != 2)
40030fdc8d8SChris Lattner             {
40130fdc8d8SChris Lattner                 result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>");
40230fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
40330fdc8d8SChris Lattner             }
40430fdc8d8SChris Lattner             else
40530fdc8d8SChris Lattner             {
40630fdc8d8SChris Lattner                 const char *reg_name = command.GetArgumentAtIndex(0);
40730fdc8d8SChris Lattner                 const char *value_str = command.GetArgumentAtIndex(1);
408385aa28cSGreg Clayton                 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
40930fdc8d8SChris Lattner 
41030fdc8d8SChris Lattner                 if (reg_info)
41130fdc8d8SChris Lattner                 {
4127349bd90SGreg Clayton                     RegisterValue reg_value;
4137349bd90SGreg Clayton 
4147349bd90SGreg Clayton                     Error error (reg_value.SetValueFromCString (reg_info, value_str));
41530fdc8d8SChris Lattner                     if (error.Success())
41630fdc8d8SChris Lattner                     {
4177349bd90SGreg Clayton                         if (reg_ctx->WriteRegister (reg_info, reg_value))
41830fdc8d8SChris Lattner                         {
41930fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusSuccessFinishNoResult);
42030fdc8d8SChris Lattner                             return true;
42130fdc8d8SChris Lattner                         }
42230fdc8d8SChris Lattner                     }
423b1ad65c5SJason Molenda                     if (error.AsCString())
42430fdc8d8SChris Lattner                     {
42530fdc8d8SChris Lattner                         result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n",
42630fdc8d8SChris Lattner                                                      reg_name,
42730fdc8d8SChris Lattner                                                      value_str,
42830fdc8d8SChris Lattner                                                      error.AsCString());
42930fdc8d8SChris Lattner                     }
430b1ad65c5SJason Molenda                     else
431b1ad65c5SJason Molenda                     {
432b1ad65c5SJason Molenda                         result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'",
433b1ad65c5SJason Molenda                                                      reg_name,
434b1ad65c5SJason Molenda                                                      value_str);
435b1ad65c5SJason Molenda                     }
436b1ad65c5SJason Molenda                     result.SetStatus (eReturnStatusFailed);
43730fdc8d8SChris Lattner                 }
43830fdc8d8SChris Lattner                 else
43930fdc8d8SChris Lattner                 {
44030fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name);
44130fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
44230fdc8d8SChris Lattner                 }
44330fdc8d8SChris Lattner             }
44430fdc8d8SChris Lattner         }
44530fdc8d8SChris Lattner         else
44630fdc8d8SChris Lattner         {
44730fdc8d8SChris Lattner             result.AppendError ("no current frame");
44830fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
44930fdc8d8SChris Lattner         }
45030fdc8d8SChris Lattner         return result.Succeeded();
45130fdc8d8SChris Lattner     }
45230fdc8d8SChris Lattner };
45330fdc8d8SChris Lattner 
45430fdc8d8SChris Lattner 
45530fdc8d8SChris Lattner //----------------------------------------------------------------------
45630fdc8d8SChris Lattner // CommandObjectRegister constructor
45730fdc8d8SChris Lattner //----------------------------------------------------------------------
4586611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) :
459a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
460a7015092SGreg Clayton                             "register",
4613f4c09c1SCaroline Tice                             "A set of commands to access thread registers.",
46230fdc8d8SChris Lattner                             "register [read|write] ...")
46330fdc8d8SChris Lattner {
464a7015092SGreg Clayton     LoadSubCommand ("read",  CommandObjectSP (new CommandObjectRegisterRead (interpreter)));
465a7015092SGreg Clayton     LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter)));
46630fdc8d8SChris Lattner }
46730fdc8d8SChris Lattner 
46830fdc8d8SChris Lattner 
46930fdc8d8SChris Lattner //----------------------------------------------------------------------
47030fdc8d8SChris Lattner // Destructor
47130fdc8d8SChris Lattner //----------------------------------------------------------------------
47230fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister()
47330fdc8d8SChris Lattner {
47430fdc8d8SChris Lattner }
475