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 
10*93a64300SDaniel Malea #include "lldb/lldb-python.h"
11*93a64300SDaniel 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,
48eb0103f2SGreg Clayton                              eFlagProcessMustBeLaunched | eFlagProcessMustBePaused),
491deb7962SGreg Clayton         m_option_group (interpreter),
501deb7962SGreg Clayton         m_format_options (eFormatDefault),
511deb7962SGreg Clayton         m_command_options ()
5230fdc8d8SChris Lattner     {
53405fe67fSCaroline Tice         CommandArgumentEntry arg;
54405fe67fSCaroline Tice         CommandArgumentData register_arg;
55405fe67fSCaroline Tice 
56405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
57405fe67fSCaroline Tice         register_arg.arg_type = eArgTypeRegisterName;
58405fe67fSCaroline Tice         register_arg.arg_repetition = eArgRepeatStar;
59405fe67fSCaroline Tice 
60405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
61405fe67fSCaroline Tice         arg.push_back (register_arg);
62405fe67fSCaroline Tice 
63405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
64405fe67fSCaroline Tice         m_arguments.push_back (arg);
651deb7962SGreg Clayton 
661deb7962SGreg Clayton         // Add the "--format"
675009f9d5SGreg Clayton         m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, LLDB_OPT_SET_ALL);
681deb7962SGreg Clayton         m_option_group.Append (&m_command_options);
691deb7962SGreg Clayton         m_option_group.Finalize();
701deb7962SGreg Clayton 
7130fdc8d8SChris Lattner     }
7230fdc8d8SChris Lattner 
7330fdc8d8SChris Lattner     virtual
7430fdc8d8SChris Lattner     ~CommandObjectRegisterRead ()
7530fdc8d8SChris Lattner     {
7630fdc8d8SChris Lattner     }
7730fdc8d8SChris Lattner 
7832e0a750SGreg Clayton     Options *
7932e0a750SGreg Clayton     GetOptions ()
8032e0a750SGreg Clayton     {
811deb7962SGreg Clayton         return &m_option_group;
8232e0a750SGreg Clayton     }
8332e0a750SGreg Clayton 
84385aa28cSGreg Clayton     bool
85385aa28cSGreg Clayton     DumpRegister (const ExecutionContext &exe_ctx,
86385aa28cSGreg Clayton                   Stream &strm,
87385aa28cSGreg Clayton                   RegisterContext *reg_ctx,
88385aa28cSGreg Clayton                   const RegisterInfo *reg_info)
89385aa28cSGreg Clayton     {
90385aa28cSGreg Clayton         if (reg_info)
91385aa28cSGreg Clayton         {
927349bd90SGreg Clayton             RegisterValue reg_value;
93385aa28cSGreg Clayton 
947349bd90SGreg Clayton             if (reg_ctx->ReadRegister (reg_info, reg_value))
95385aa28cSGreg Clayton             {
96385aa28cSGreg Clayton                 strm.Indent ();
97385aa28cSGreg Clayton 
981deb7962SGreg Clayton                 bool prefix_with_altname = m_command_options.alternate_name;
999a8fa916SGreg Clayton                 bool prefix_with_name = !prefix_with_altname;
100c4392d2aSJohnny Chen                 reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname, m_format_options.GetFormat(), 8);
1011ac04c30SGreg Clayton                 if ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint))
1021ac04c30SGreg Clayton                 {
1031ac04c30SGreg Clayton                     Process *process = exe_ctx.GetProcessPtr();
1041ac04c30SGreg Clayton                     if (process && reg_info->byte_size == process->GetAddressByteSize())
105385aa28cSGreg Clayton                     {
1067349bd90SGreg Clayton                         addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS);
1077349bd90SGreg Clayton                         if (reg_addr != LLDB_INVALID_ADDRESS)
108385aa28cSGreg Clayton                         {
109385aa28cSGreg Clayton                             Address so_reg_addr;
110c14ee32dSGreg Clayton                             if (exe_ctx.GetTargetRef().GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr))
111385aa28cSGreg Clayton                             {
112385aa28cSGreg Clayton                                 strm.PutCString ("  ");
113385aa28cSGreg Clayton                                 so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
114385aa28cSGreg Clayton                             }
115385aa28cSGreg Clayton                         }
116385aa28cSGreg Clayton                     }
1171ac04c30SGreg Clayton                 }
118385aa28cSGreg Clayton                 strm.EOL();
119385aa28cSGreg Clayton                 return true;
120385aa28cSGreg Clayton             }
121385aa28cSGreg Clayton         }
122385aa28cSGreg Clayton         return false;
123385aa28cSGreg Clayton     }
124385aa28cSGreg Clayton 
125385aa28cSGreg Clayton     bool
126385aa28cSGreg Clayton     DumpRegisterSet (const ExecutionContext &exe_ctx,
127385aa28cSGreg Clayton                      Stream &strm,
128385aa28cSGreg Clayton                      RegisterContext *reg_ctx,
1296d4d4f7dSJohnny Chen                      uint32_t set_idx,
1306d4d4f7dSJohnny Chen                      bool primitive_only=false)
131385aa28cSGreg Clayton     {
132385aa28cSGreg Clayton         uint32_t unavailable_count = 0;
133385aa28cSGreg Clayton         uint32_t available_count = 0;
134385aa28cSGreg Clayton         const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx);
135385aa28cSGreg Clayton         if (reg_set)
136385aa28cSGreg Clayton         {
137385aa28cSGreg Clayton             strm.Printf ("%s:\n", reg_set->name);
138385aa28cSGreg Clayton             strm.IndentMore ();
139385aa28cSGreg Clayton             const uint32_t num_registers = reg_set->num_registers;
140385aa28cSGreg Clayton             for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
141385aa28cSGreg Clayton             {
142385aa28cSGreg Clayton                 const uint32_t reg = reg_set->registers[reg_idx];
1436d4d4f7dSJohnny Chen                 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg);
1446d4d4f7dSJohnny Chen                 // Skip the dumping of derived register if primitive_only is true.
1456d4d4f7dSJohnny Chen                 if (primitive_only && reg_info && reg_info->value_regs)
1466d4d4f7dSJohnny Chen                     continue;
1476d4d4f7dSJohnny Chen                 if (DumpRegister (exe_ctx, strm, reg_ctx, reg_info))
148385aa28cSGreg Clayton                     ++available_count;
149385aa28cSGreg Clayton                 else
150385aa28cSGreg Clayton                     ++unavailable_count;
151385aa28cSGreg Clayton             }
152385aa28cSGreg Clayton             strm.IndentLess ();
153385aa28cSGreg Clayton             if (unavailable_count)
154385aa28cSGreg Clayton             {
155385aa28cSGreg Clayton                 strm.Indent ();
156385aa28cSGreg Clayton                 strm.Printf("%u registers were unavailable.\n", unavailable_count);
157385aa28cSGreg Clayton             }
158385aa28cSGreg Clayton             strm.EOL();
159385aa28cSGreg Clayton         }
160385aa28cSGreg Clayton         return available_count > 0;
161385aa28cSGreg Clayton     }
162385aa28cSGreg Clayton 
1635a988416SJim Ingham protected:
16430fdc8d8SChris Lattner     virtual bool
1655a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
16630fdc8d8SChris Lattner     {
167385aa28cSGreg Clayton         Stream &strm = result.GetOutputStream();
1688b82f087SGreg Clayton         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
169385aa28cSGreg Clayton         RegisterContext *reg_ctx = exe_ctx.GetRegisterContext ();
17030fdc8d8SChris Lattner 
171385aa28cSGreg Clayton         if (reg_ctx)
17230fdc8d8SChris Lattner         {
17330fdc8d8SChris Lattner             const RegisterInfo *reg_info = NULL;
17430fdc8d8SChris Lattner             if (command.GetArgumentCount() == 0)
17530fdc8d8SChris Lattner             {
17630fdc8d8SChris Lattner                 uint32_t set_idx;
177385aa28cSGreg Clayton 
178385aa28cSGreg Clayton                 uint32_t num_register_sets = 1;
1791deb7962SGreg Clayton                 const uint32_t set_array_size = m_command_options.set_indexes.GetSize();
180385aa28cSGreg Clayton                 if (set_array_size > 0)
18130fdc8d8SChris Lattner                 {
182385aa28cSGreg Clayton                     for (uint32_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                         {
187385aa28cSGreg Clayton                             if (!DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx))
188385aa28cSGreg Clayton                             {
189385aa28cSGreg Clayton                                 result.AppendErrorWithFormat ("invalid register set index: %u\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.
2106d4d4f7dSJohnny Chen                         DumpRegisterSet (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                         {
235385aa28cSGreg Clayton                             if (!DumpRegister (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             }
245385aa28cSGreg Clayton         }
24630fdc8d8SChris Lattner         else
24730fdc8d8SChris Lattner         {
24830fdc8d8SChris Lattner             result.AppendError ("no current frame");
24930fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
25030fdc8d8SChris Lattner         }
25130fdc8d8SChris Lattner         return result.Succeeded();
25230fdc8d8SChris Lattner     }
25332e0a750SGreg Clayton 
2541deb7962SGreg Clayton     class CommandOptions : public OptionGroup
25532e0a750SGreg Clayton     {
25632e0a750SGreg Clayton     public:
2571deb7962SGreg Clayton         CommandOptions () :
2581deb7962SGreg Clayton             OptionGroup(),
259385aa28cSGreg Clayton             set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)),
2609a8fa916SGreg Clayton             dump_all_sets (false, false), // Initial and default values are false
2619a8fa916SGreg Clayton             alternate_name (false, false)
26232e0a750SGreg Clayton         {
26332e0a750SGreg Clayton         }
26432e0a750SGreg Clayton 
26532e0a750SGreg Clayton         virtual
26632e0a750SGreg Clayton         ~CommandOptions ()
26732e0a750SGreg Clayton         {
26832e0a750SGreg Clayton         }
26932e0a750SGreg Clayton 
2701deb7962SGreg Clayton 
2711deb7962SGreg Clayton         virtual uint32_t
2721deb7962SGreg Clayton         GetNumDefinitions ();
2731deb7962SGreg Clayton 
2741deb7962SGreg Clayton         virtual const OptionDefinition*
2751deb7962SGreg Clayton         GetDefinitions ()
2761deb7962SGreg Clayton         {
2771deb7962SGreg Clayton             return g_option_table;
2781deb7962SGreg Clayton         }
2791deb7962SGreg Clayton 
2801deb7962SGreg Clayton         virtual void
2811deb7962SGreg Clayton         OptionParsingStarting (CommandInterpreter &interpreter)
2821deb7962SGreg Clayton         {
2831deb7962SGreg Clayton             set_indexes.Clear();
2841deb7962SGreg Clayton             dump_all_sets.Clear();
2851deb7962SGreg Clayton             alternate_name.Clear();
2861deb7962SGreg Clayton         }
2871deb7962SGreg Clayton 
28832e0a750SGreg Clayton         virtual Error
2891deb7962SGreg Clayton         SetOptionValue (CommandInterpreter &interpreter,
2901deb7962SGreg Clayton                         uint32_t option_idx,
2911deb7962SGreg Clayton                         const char *option_value)
29232e0a750SGreg Clayton         {
29332e0a750SGreg Clayton             Error error;
2943bcdfc0eSGreg Clayton             const int short_option = g_option_table[option_idx].short_option;
29532e0a750SGreg Clayton             switch (short_option)
29632e0a750SGreg Clayton             {
297385aa28cSGreg Clayton                 case 's':
298385aa28cSGreg Clayton                     {
2991deb7962SGreg Clayton                         OptionValueSP value_sp (OptionValueUInt64::Create (option_value, error));
300385aa28cSGreg Clayton                         if (value_sp)
301385aa28cSGreg Clayton                             set_indexes.AppendValue (value_sp);
302385aa28cSGreg Clayton                     }
303385aa28cSGreg Clayton                     break;
304385aa28cSGreg Clayton 
305385aa28cSGreg 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
309385aa28cSGreg Clayton                     dump_all_sets.SetCurrentValue (true);
3109a8fa916SGreg Clayton                     dump_all_sets.SetOptionWasSet ();
3119a8fa916SGreg Clayton                     break;
3129a8fa916SGreg Clayton 
3139a8fa916SGreg Clayton                 case 'A':
3149a8fa916SGreg Clayton                     // When we don't use OptionValue::SetValueFromCString(const char *) to
3159a8fa916SGreg Clayton                     // set an option value, it won't be marked as being set in the options
3169a8fa916SGreg Clayton                     // so we make a call to let users know the value was set via option
3179a8fa916SGreg Clayton                     alternate_name.SetCurrentValue (true);
3189a8fa916SGreg Clayton                     dump_all_sets.SetOptionWasSet ();
319385aa28cSGreg Clayton                     break;
320385aa28cSGreg Clayton 
32132e0a750SGreg Clayton                 default:
32286edbf41SGreg Clayton                     error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
32332e0a750SGreg Clayton                     break;
32432e0a750SGreg Clayton             }
32532e0a750SGreg Clayton             return error;
32632e0a750SGreg Clayton         }
32732e0a750SGreg Clayton 
32832e0a750SGreg Clayton         // Options table: Required for subclasses of Options.
32932e0a750SGreg Clayton 
3301deb7962SGreg Clayton         static const OptionDefinition g_option_table[];
33132e0a750SGreg Clayton 
33232e0a750SGreg Clayton         // Instance variables to hold the values for command options.
333385aa28cSGreg Clayton         OptionValueArray set_indexes;
334385aa28cSGreg Clayton         OptionValueBoolean dump_all_sets;
3359a8fa916SGreg Clayton         OptionValueBoolean alternate_name;
33630fdc8d8SChris Lattner     };
33730fdc8d8SChris Lattner 
3381deb7962SGreg Clayton     OptionGroupOptions m_option_group;
3391deb7962SGreg Clayton     OptionGroupFormat m_format_options;
3401deb7962SGreg Clayton     CommandOptions m_command_options;
34132e0a750SGreg Clayton };
34232e0a750SGreg Clayton 
3433d0fcf5eSJohnny Chen const OptionDefinition
34432e0a750SGreg Clayton CommandObjectRegisterRead::CommandOptions::g_option_table[] =
34532e0a750SGreg Clayton {
3469a8fa916SGreg 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."},
347385aa28cSGreg Clayton     { LLDB_OPT_SET_1  , false, "set"      , 's', required_argument, NULL, 0, eArgTypeIndex     , "Specify which register sets to dump by index."},
348385aa28cSGreg Clayton     { LLDB_OPT_SET_2  , false, "all"      , 'a', no_argument      , NULL, 0, eArgTypeNone      , "Show all register sets."},
34932e0a750SGreg Clayton };
35032e0a750SGreg Clayton 
3511deb7962SGreg Clayton uint32_t
3521deb7962SGreg Clayton CommandObjectRegisterRead::CommandOptions::GetNumDefinitions ()
3531deb7962SGreg Clayton {
3541deb7962SGreg Clayton     return sizeof(g_option_table)/sizeof(OptionDefinition);
3551deb7962SGreg Clayton }
35632e0a750SGreg Clayton 
35730fdc8d8SChris Lattner 
35830fdc8d8SChris Lattner //----------------------------------------------------------------------
35930fdc8d8SChris Lattner // "register write"
36030fdc8d8SChris Lattner //----------------------------------------------------------------------
3615a988416SJim Ingham class CommandObjectRegisterWrite : public CommandObjectParsed
36230fdc8d8SChris Lattner {
36330fdc8d8SChris Lattner public:
364a7015092SGreg Clayton     CommandObjectRegisterWrite (CommandInterpreter &interpreter) :
3655a988416SJim Ingham         CommandObjectParsed (interpreter,
366a7015092SGreg Clayton                              "register write",
36730fdc8d8SChris Lattner                              "Modify a single register value.",
368405fe67fSCaroline Tice                              NULL,
36930fdc8d8SChris Lattner                              eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
37030fdc8d8SChris Lattner     {
371405fe67fSCaroline Tice         CommandArgumentEntry arg1;
372405fe67fSCaroline Tice         CommandArgumentEntry arg2;
373405fe67fSCaroline Tice         CommandArgumentData register_arg;
374405fe67fSCaroline Tice         CommandArgumentData value_arg;
375405fe67fSCaroline Tice 
376405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
377405fe67fSCaroline Tice         register_arg.arg_type = eArgTypeRegisterName;
378405fe67fSCaroline Tice         register_arg.arg_repetition = eArgRepeatPlain;
379405fe67fSCaroline Tice 
380405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
381405fe67fSCaroline Tice         arg1.push_back (register_arg);
382405fe67fSCaroline Tice 
383405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
384405fe67fSCaroline Tice         value_arg.arg_type = eArgTypeValue;
385405fe67fSCaroline Tice         value_arg.arg_repetition = eArgRepeatPlain;
386405fe67fSCaroline Tice 
387405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
388405fe67fSCaroline Tice         arg2.push_back (value_arg);
389405fe67fSCaroline Tice 
390405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
391405fe67fSCaroline Tice         m_arguments.push_back (arg1);
392405fe67fSCaroline Tice         m_arguments.push_back (arg2);
39330fdc8d8SChris Lattner     }
39430fdc8d8SChris Lattner 
39530fdc8d8SChris Lattner     virtual
39630fdc8d8SChris Lattner     ~CommandObjectRegisterWrite ()
39730fdc8d8SChris Lattner     {
39830fdc8d8SChris Lattner     }
39930fdc8d8SChris Lattner 
4005a988416SJim Ingham protected:
40130fdc8d8SChris Lattner     virtual bool
4025a988416SJim Ingham     DoExecute(Args& command, CommandReturnObject &result)
40330fdc8d8SChris Lattner     {
40430fdc8d8SChris Lattner         DataExtractor reg_data;
4058b82f087SGreg Clayton         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
406385aa28cSGreg Clayton         RegisterContext *reg_ctx = exe_ctx.GetRegisterContext ();
40730fdc8d8SChris Lattner 
408385aa28cSGreg Clayton         if (reg_ctx)
40930fdc8d8SChris Lattner         {
41030fdc8d8SChris Lattner             if (command.GetArgumentCount() != 2)
41130fdc8d8SChris Lattner             {
41230fdc8d8SChris Lattner                 result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>");
41330fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
41430fdc8d8SChris Lattner             }
41530fdc8d8SChris Lattner             else
41630fdc8d8SChris Lattner             {
41730fdc8d8SChris Lattner                 const char *reg_name = command.GetArgumentAtIndex(0);
41830fdc8d8SChris Lattner                 const char *value_str = command.GetArgumentAtIndex(1);
419385aa28cSGreg Clayton                 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
42030fdc8d8SChris Lattner 
42130fdc8d8SChris Lattner                 if (reg_info)
42230fdc8d8SChris Lattner                 {
4237349bd90SGreg Clayton                     RegisterValue reg_value;
4247349bd90SGreg Clayton 
4257349bd90SGreg Clayton                     Error error (reg_value.SetValueFromCString (reg_info, value_str));
42630fdc8d8SChris Lattner                     if (error.Success())
42730fdc8d8SChris Lattner                     {
4287349bd90SGreg Clayton                         if (reg_ctx->WriteRegister (reg_info, reg_value))
42930fdc8d8SChris Lattner                         {
430fa559e5cSGreg Clayton                             // Toss all frames and anything else in the thread
431fa559e5cSGreg Clayton                             // after a register has been written.
432fa559e5cSGreg Clayton                             exe_ctx.GetThreadRef().Flush();
43330fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusSuccessFinishNoResult);
43430fdc8d8SChris Lattner                             return true;
43530fdc8d8SChris Lattner                         }
43630fdc8d8SChris Lattner                     }
437b1ad65c5SJason Molenda                     if (error.AsCString())
43830fdc8d8SChris Lattner                     {
43930fdc8d8SChris Lattner                         result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n",
44030fdc8d8SChris Lattner                                                      reg_name,
44130fdc8d8SChris Lattner                                                      value_str,
44230fdc8d8SChris Lattner                                                      error.AsCString());
44330fdc8d8SChris Lattner                     }
444b1ad65c5SJason Molenda                     else
445b1ad65c5SJason Molenda                     {
446b1ad65c5SJason Molenda                         result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'",
447b1ad65c5SJason Molenda                                                      reg_name,
448b1ad65c5SJason Molenda                                                      value_str);
449b1ad65c5SJason Molenda                     }
450b1ad65c5SJason Molenda                     result.SetStatus (eReturnStatusFailed);
45130fdc8d8SChris Lattner                 }
45230fdc8d8SChris Lattner                 else
45330fdc8d8SChris Lattner                 {
45430fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name);
45530fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
45630fdc8d8SChris Lattner                 }
45730fdc8d8SChris Lattner             }
45830fdc8d8SChris Lattner         }
45930fdc8d8SChris Lattner         else
46030fdc8d8SChris Lattner         {
46130fdc8d8SChris Lattner             result.AppendError ("no current frame");
46230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
46330fdc8d8SChris Lattner         }
46430fdc8d8SChris Lattner         return result.Succeeded();
46530fdc8d8SChris Lattner     }
46630fdc8d8SChris Lattner };
46730fdc8d8SChris Lattner 
46830fdc8d8SChris Lattner 
46930fdc8d8SChris Lattner //----------------------------------------------------------------------
47030fdc8d8SChris Lattner // CommandObjectRegister constructor
47130fdc8d8SChris Lattner //----------------------------------------------------------------------
4726611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) :
473a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
474a7015092SGreg Clayton                             "register",
4753f4c09c1SCaroline Tice                             "A set of commands to access thread registers.",
47630fdc8d8SChris Lattner                             "register [read|write] ...")
47730fdc8d8SChris Lattner {
478a7015092SGreg Clayton     LoadSubCommand ("read",  CommandObjectSP (new CommandObjectRegisterRead (interpreter)));
479a7015092SGreg Clayton     LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter)));
48030fdc8d8SChris Lattner }
48130fdc8d8SChris Lattner 
48230fdc8d8SChris Lattner 
48330fdc8d8SChris Lattner //----------------------------------------------------------------------
48430fdc8d8SChris Lattner // Destructor
48530fdc8d8SChris Lattner //----------------------------------------------------------------------
48630fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister()
48730fdc8d8SChris Lattner {
48830fdc8d8SChris Lattner }
489