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"
1730fdc8d8SChris Lattner #include "lldb/Core/Scalar.h"
186611103cSGreg Clayton #include "lldb/Core/Debugger.h"
196611103cSGreg Clayton #include "lldb/Interpreter/Args.h"
206611103cSGreg Clayton #include "lldb/Interpreter/CommandInterpreter.h"
2130fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
22385aa28cSGreg Clayton #include "lldb/Interpreter/NamedOptionValue.h"
23eb0103f2SGreg Clayton #include "lldb/Interpreter/Options.h"
2430fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h"
2530fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
2630fdc8d8SChris Lattner 
2730fdc8d8SChris Lattner using namespace lldb;
2830fdc8d8SChris Lattner using namespace lldb_private;
2930fdc8d8SChris Lattner 
3030fdc8d8SChris Lattner //----------------------------------------------------------------------
3130fdc8d8SChris Lattner // "register read"
3230fdc8d8SChris Lattner //----------------------------------------------------------------------
3330fdc8d8SChris Lattner class CommandObjectRegisterRead : public CommandObject
3430fdc8d8SChris Lattner {
3530fdc8d8SChris Lattner public:
36a7015092SGreg Clayton     CommandObjectRegisterRead (CommandInterpreter &interpreter) :
37a7015092SGreg Clayton         CommandObject (interpreter,
38a7015092SGreg Clayton                        "register read",
39405fe67fSCaroline Tice                        "Dump the contents of one or more register values from the current frame.  If no register is specified, dumps them all.",
40405fe67fSCaroline Tice                        //"register read [<reg-name1> [<reg-name2> [...]]]",
41405fe67fSCaroline Tice                        NULL,
42eb0103f2SGreg Clayton                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
43eb0103f2SGreg Clayton         m_options (interpreter)
4430fdc8d8SChris Lattner     {
45405fe67fSCaroline Tice         CommandArgumentEntry arg;
46405fe67fSCaroline Tice         CommandArgumentData register_arg;
47405fe67fSCaroline Tice 
48405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
49405fe67fSCaroline Tice         register_arg.arg_type = eArgTypeRegisterName;
50405fe67fSCaroline Tice         register_arg.arg_repetition = eArgRepeatStar;
51405fe67fSCaroline Tice 
52405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
53405fe67fSCaroline Tice         arg.push_back (register_arg);
54405fe67fSCaroline Tice 
55405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
56405fe67fSCaroline Tice         m_arguments.push_back (arg);
5730fdc8d8SChris Lattner     }
5830fdc8d8SChris Lattner 
5930fdc8d8SChris Lattner     virtual
6030fdc8d8SChris Lattner     ~CommandObjectRegisterRead ()
6130fdc8d8SChris Lattner     {
6230fdc8d8SChris Lattner     }
6330fdc8d8SChris Lattner 
6432e0a750SGreg Clayton     Options *
6532e0a750SGreg Clayton     GetOptions ()
6632e0a750SGreg Clayton     {
6732e0a750SGreg Clayton         return &m_options;
6832e0a750SGreg Clayton     }
6932e0a750SGreg Clayton 
70385aa28cSGreg Clayton     bool
71385aa28cSGreg Clayton     DumpRegister (const ExecutionContext &exe_ctx,
72385aa28cSGreg Clayton                   Stream &strm,
73385aa28cSGreg Clayton                   RegisterContext *reg_ctx,
74385aa28cSGreg Clayton                   const RegisterInfo *reg_info)
75385aa28cSGreg Clayton     {
76385aa28cSGreg Clayton         if (reg_info)
77385aa28cSGreg Clayton         {
78385aa28cSGreg Clayton             uint32_t reg = reg_info->kinds[eRegisterKindLLDB];
79385aa28cSGreg Clayton 
80385aa28cSGreg Clayton             DataExtractor reg_data;
81385aa28cSGreg Clayton 
82385aa28cSGreg Clayton             if (reg_ctx->ReadRegisterBytes(reg, reg_data))
83385aa28cSGreg Clayton             {
84385aa28cSGreg Clayton                 strm.Indent ();
85385aa28cSGreg Clayton                 strm.Printf ("%-12s = ", reg_info ? reg_info->name : "<INVALID REGINFO>");
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 
92385aa28cSGreg Clayton                 reg_data.Dump(&strm, 0, format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
93385aa28cSGreg Clayton                 if (m_options.lookup_addresses && ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint)))
94385aa28cSGreg Clayton                 {
95385aa28cSGreg Clayton                     addr_t reg_addr = reg_ctx->ReadRegisterAsUnsigned (reg, 0);
96385aa28cSGreg Clayton                     if (reg_addr)
97385aa28cSGreg Clayton                     {
98385aa28cSGreg Clayton                         Address so_reg_addr;
99385aa28cSGreg Clayton                         if (exe_ctx.target->GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr))
100385aa28cSGreg Clayton                         {
101385aa28cSGreg Clayton                             strm.PutCString ("  ");
102385aa28cSGreg Clayton                             so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
103385aa28cSGreg Clayton                         }
104385aa28cSGreg Clayton                         else
105385aa28cSGreg Clayton                         {
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)),
249385aa28cSGreg Clayton             dump_all_sets (false, false), // Initial and default values are false
250385aa28cSGreg Clayton             lookup_addresses (false, false)         // Initial and default values are 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':
268*68ebae61SGreg 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':
280385aa28cSGreg Clayton                     dump_all_sets.SetCurrentValue(true);
281385aa28cSGreg Clayton                     break;
282385aa28cSGreg Clayton 
283385aa28cSGreg Clayton                 case 'l':
284385aa28cSGreg Clayton                     lookup_addresses.SetCurrentValue(true);
28532e0a750SGreg Clayton                     break;
28632e0a750SGreg Clayton 
28732e0a750SGreg Clayton                 default:
28832e0a750SGreg Clayton                     error.SetErrorStringWithFormat("Unrecognized short option '%c'\n", short_option);
28932e0a750SGreg Clayton                     break;
29032e0a750SGreg Clayton             }
29132e0a750SGreg Clayton             return error;
29232e0a750SGreg Clayton         }
29332e0a750SGreg Clayton 
29432e0a750SGreg Clayton         void
295f6b8b581SGreg Clayton         OptionParsingStarting ()
29632e0a750SGreg Clayton         {
297385aa28cSGreg Clayton             format = eFormatDefault;
298385aa28cSGreg Clayton             set_indexes.Clear();
299385aa28cSGreg Clayton             dump_all_sets.Clear();
300385aa28cSGreg Clayton             lookup_addresses.Clear();
30132e0a750SGreg Clayton         }
30232e0a750SGreg Clayton 
30332e0a750SGreg Clayton         const OptionDefinition*
30432e0a750SGreg Clayton         GetDefinitions ()
30532e0a750SGreg Clayton         {
30632e0a750SGreg Clayton             return g_option_table;
30732e0a750SGreg Clayton         }
30832e0a750SGreg Clayton 
30932e0a750SGreg Clayton         // Options table: Required for subclasses of Options.
31032e0a750SGreg Clayton 
31132e0a750SGreg Clayton         static OptionDefinition g_option_table[];
31232e0a750SGreg Clayton 
31332e0a750SGreg Clayton         // Instance variables to hold the values for command options.
314385aa28cSGreg Clayton         lldb::Format format;
315385aa28cSGreg Clayton         OptionValueArray set_indexes;
316385aa28cSGreg Clayton         OptionValueBoolean dump_all_sets;
317385aa28cSGreg Clayton         OptionValueBoolean lookup_addresses;
31830fdc8d8SChris Lattner     };
31930fdc8d8SChris Lattner 
32032e0a750SGreg Clayton     CommandOptions m_options;
32132e0a750SGreg Clayton };
32232e0a750SGreg Clayton 
32332e0a750SGreg Clayton OptionDefinition
32432e0a750SGreg Clayton CommandObjectRegisterRead::CommandOptions::g_option_table[] =
32532e0a750SGreg Clayton {
326385aa28cSGreg Clayton     { LLDB_OPT_SET_ALL, false, "format", 'f', required_argument, NULL, 0, eArgTypeExprFormat,  "Specify the format to use when dumping register values."},
327385aa28cSGreg Clayton     { LLDB_OPT_SET_ALL, false, "lookup", 'l', no_argument      , NULL, 0, eArgTypeNone      , "Lookup the register values as addresses and show that each value maps to in the address space."},
328385aa28cSGreg Clayton     { LLDB_OPT_SET_1  , false, "set"   , 's', required_argument, NULL, 0, eArgTypeIndex     , "Specify which register sets to dump by index."},
329385aa28cSGreg Clayton     { LLDB_OPT_SET_2  , false, "all"   , 'a', no_argument      , NULL, 0, eArgTypeNone      , "Show all register sets."},
33032e0a750SGreg Clayton     { 0, false, NULL, 0, 0, NULL, NULL, eArgTypeNone, NULL }
33132e0a750SGreg Clayton };
33232e0a750SGreg Clayton 
33332e0a750SGreg Clayton 
33430fdc8d8SChris Lattner 
33530fdc8d8SChris Lattner //----------------------------------------------------------------------
33630fdc8d8SChris Lattner // "register write"
33730fdc8d8SChris Lattner //----------------------------------------------------------------------
33830fdc8d8SChris Lattner class CommandObjectRegisterWrite : public CommandObject
33930fdc8d8SChris Lattner {
34030fdc8d8SChris Lattner public:
341a7015092SGreg Clayton     CommandObjectRegisterWrite (CommandInterpreter &interpreter) :
342a7015092SGreg Clayton         CommandObject (interpreter,
343a7015092SGreg Clayton                        "register write",
34430fdc8d8SChris Lattner                        "Modify a single register value.",
345405fe67fSCaroline Tice                        //"register write <reg-name> <value>",
346405fe67fSCaroline Tice                        NULL,
34730fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
34830fdc8d8SChris Lattner     {
349405fe67fSCaroline Tice         CommandArgumentEntry arg1;
350405fe67fSCaroline Tice         CommandArgumentEntry arg2;
351405fe67fSCaroline Tice         CommandArgumentData register_arg;
352405fe67fSCaroline Tice         CommandArgumentData value_arg;
353405fe67fSCaroline Tice 
354405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
355405fe67fSCaroline Tice         register_arg.arg_type = eArgTypeRegisterName;
356405fe67fSCaroline Tice         register_arg.arg_repetition = eArgRepeatPlain;
357405fe67fSCaroline Tice 
358405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
359405fe67fSCaroline Tice         arg1.push_back (register_arg);
360405fe67fSCaroline Tice 
361405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
362405fe67fSCaroline Tice         value_arg.arg_type = eArgTypeValue;
363405fe67fSCaroline Tice         value_arg.arg_repetition = eArgRepeatPlain;
364405fe67fSCaroline Tice 
365405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
366405fe67fSCaroline Tice         arg2.push_back (value_arg);
367405fe67fSCaroline Tice 
368405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
369405fe67fSCaroline Tice         m_arguments.push_back (arg1);
370405fe67fSCaroline Tice         m_arguments.push_back (arg2);
37130fdc8d8SChris Lattner     }
37230fdc8d8SChris Lattner 
37330fdc8d8SChris Lattner     virtual
37430fdc8d8SChris Lattner     ~CommandObjectRegisterWrite ()
37530fdc8d8SChris Lattner     {
37630fdc8d8SChris Lattner     }
37730fdc8d8SChris Lattner 
37830fdc8d8SChris Lattner     virtual bool
3796611103cSGreg Clayton     Execute
3806611103cSGreg Clayton     (
3816611103cSGreg Clayton         Args& command,
3826611103cSGreg Clayton         CommandReturnObject &result
3836611103cSGreg Clayton     )
38430fdc8d8SChris Lattner     {
38530fdc8d8SChris Lattner         DataExtractor reg_data;
3868b82f087SGreg Clayton         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
387385aa28cSGreg Clayton         RegisterContext *reg_ctx = exe_ctx.GetRegisterContext ();
38830fdc8d8SChris Lattner 
389385aa28cSGreg Clayton         if (reg_ctx)
39030fdc8d8SChris Lattner         {
39130fdc8d8SChris Lattner             if (command.GetArgumentCount() != 2)
39230fdc8d8SChris Lattner             {
39330fdc8d8SChris Lattner                 result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>");
39430fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
39530fdc8d8SChris Lattner             }
39630fdc8d8SChris Lattner             else
39730fdc8d8SChris Lattner             {
39830fdc8d8SChris Lattner                 const char *reg_name = command.GetArgumentAtIndex(0);
39930fdc8d8SChris Lattner                 const char *value_str = command.GetArgumentAtIndex(1);
400385aa28cSGreg Clayton                 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
40130fdc8d8SChris Lattner 
40230fdc8d8SChris Lattner                 if (reg_info)
40330fdc8d8SChris Lattner                 {
40430fdc8d8SChris Lattner                     Scalar scalar;
40530fdc8d8SChris Lattner                     Error error(scalar.SetValueFromCString (value_str, reg_info->encoding, reg_info->byte_size));
40630fdc8d8SChris Lattner                     if (error.Success())
40730fdc8d8SChris Lattner                     {
408385aa28cSGreg Clayton                         if (reg_ctx->WriteRegisterValue(reg_info->kinds[eRegisterKindLLDB], scalar))
40930fdc8d8SChris Lattner                         {
41030fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusSuccessFinishNoResult);
41130fdc8d8SChris Lattner                             return true;
41230fdc8d8SChris Lattner                         }
41330fdc8d8SChris Lattner                     }
41430fdc8d8SChris Lattner                     else
41530fdc8d8SChris Lattner                     {
41630fdc8d8SChris Lattner                         result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n",
41730fdc8d8SChris Lattner                                                      reg_name,
41830fdc8d8SChris Lattner                                                      value_str,
41930fdc8d8SChris Lattner                                                      error.AsCString());
42030fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
42130fdc8d8SChris Lattner                     }
42230fdc8d8SChris Lattner                 }
42330fdc8d8SChris Lattner                 else
42430fdc8d8SChris Lattner                 {
42530fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name);
42630fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
42730fdc8d8SChris Lattner                 }
42830fdc8d8SChris Lattner             }
42930fdc8d8SChris Lattner         }
43030fdc8d8SChris Lattner         else
43130fdc8d8SChris Lattner         {
43230fdc8d8SChris Lattner             result.AppendError ("no current frame");
43330fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
43430fdc8d8SChris Lattner         }
43530fdc8d8SChris Lattner         return result.Succeeded();
43630fdc8d8SChris Lattner     }
43730fdc8d8SChris Lattner };
43830fdc8d8SChris Lattner 
43930fdc8d8SChris Lattner 
44030fdc8d8SChris Lattner //----------------------------------------------------------------------
44130fdc8d8SChris Lattner // CommandObjectRegister constructor
44230fdc8d8SChris Lattner //----------------------------------------------------------------------
4436611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) :
444a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
445a7015092SGreg Clayton                             "register",
4463f4c09c1SCaroline Tice                             "A set of commands to access thread registers.",
44730fdc8d8SChris Lattner                             "register [read|write] ...")
44830fdc8d8SChris Lattner {
449a7015092SGreg Clayton     LoadSubCommand ("read",  CommandObjectSP (new CommandObjectRegisterRead (interpreter)));
450a7015092SGreg Clayton     LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter)));
45130fdc8d8SChris Lattner }
45230fdc8d8SChris Lattner 
45330fdc8d8SChris Lattner 
45430fdc8d8SChris Lattner //----------------------------------------------------------------------
45530fdc8d8SChris Lattner // Destructor
45630fdc8d8SChris Lattner //----------------------------------------------------------------------
45730fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister()
45830fdc8d8SChris Lattner {
45930fdc8d8SChris Lattner }
460