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"
23eb0103f2SGreg Clayton #include "lldb/Interpreter/Options.h"
241deb7962SGreg Clayton #include "lldb/Interpreter/OptionGroupFormat.h"
2567cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueArray.h"
2667cc0636SGreg Clayton #include "lldb/Interpreter/OptionValueUInt64.h"
2730fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h"
288f7770f8SGreg Clayton #include "lldb/Target/Process.h"
2930fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
308f7770f8SGreg Clayton #include "lldb/Target/Thread.h"
3130fdc8d8SChris Lattner 
3230fdc8d8SChris Lattner using namespace lldb;
3330fdc8d8SChris Lattner using namespace lldb_private;
3430fdc8d8SChris Lattner 
3530fdc8d8SChris Lattner //----------------------------------------------------------------------
3630fdc8d8SChris Lattner // "register read"
3730fdc8d8SChris Lattner //----------------------------------------------------------------------
385a988416SJim Ingham class CommandObjectRegisterRead : public CommandObjectParsed
3930fdc8d8SChris Lattner {
4030fdc8d8SChris Lattner public:
41a7015092SGreg Clayton     CommandObjectRegisterRead (CommandInterpreter &interpreter) :
425a988416SJim Ingham         CommandObjectParsed (interpreter,
43a7015092SGreg Clayton                              "register read",
44405fe67fSCaroline Tice                              "Dump the contents of one or more register values from the current frame.  If no register is specified, dumps them all.",
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"
655009f9d5SGreg Clayton         m_option_group.Append (&m_format_options, OptionGroupFormat::OPTION_GROUP_FORMAT | OptionGroupFormat::OPTION_GROUP_GDB_FMT, 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;
98c4392d2aSJohnny Chen                 reg_value.Dump(&strm, reg_info, prefix_with_name, prefix_with_altname, m_format_options.GetFormat(), 8);
991ac04c30SGreg Clayton                 if ((reg_info->encoding == eEncodingUint) || (reg_info->encoding == eEncodingSint))
1001ac04c30SGreg Clayton                 {
1011ac04c30SGreg Clayton                     Process *process = exe_ctx.GetProcessPtr();
1021ac04c30SGreg Clayton                     if (process && reg_info->byte_size == process->GetAddressByteSize())
103385aa28cSGreg Clayton                     {
1047349bd90SGreg Clayton                         addr_t reg_addr = reg_value.GetAsUInt64(LLDB_INVALID_ADDRESS);
1057349bd90SGreg Clayton                         if (reg_addr != LLDB_INVALID_ADDRESS)
106385aa28cSGreg Clayton                         {
107385aa28cSGreg Clayton                             Address so_reg_addr;
108c14ee32dSGreg Clayton                             if (exe_ctx.GetTargetRef().GetSectionLoadList().ResolveLoadAddress(reg_addr, so_reg_addr))
109385aa28cSGreg Clayton                             {
110385aa28cSGreg Clayton                                 strm.PutCString ("  ");
111385aa28cSGreg Clayton                                 so_reg_addr.Dump(&strm, exe_ctx.GetBestExecutionContextScope(), Address::DumpStyleResolvedDescription);
112385aa28cSGreg Clayton                             }
113385aa28cSGreg Clayton                         }
114385aa28cSGreg Clayton                     }
1151ac04c30SGreg Clayton                 }
116385aa28cSGreg Clayton                 strm.EOL();
117385aa28cSGreg Clayton                 return true;
118385aa28cSGreg Clayton             }
119385aa28cSGreg Clayton         }
120385aa28cSGreg Clayton         return false;
121385aa28cSGreg Clayton     }
122385aa28cSGreg Clayton 
123385aa28cSGreg Clayton     bool
124385aa28cSGreg Clayton     DumpRegisterSet (const ExecutionContext &exe_ctx,
125385aa28cSGreg Clayton                      Stream &strm,
126385aa28cSGreg Clayton                      RegisterContext *reg_ctx,
1276d4d4f7dSJohnny Chen                      uint32_t set_idx,
1286d4d4f7dSJohnny Chen                      bool primitive_only=false)
129385aa28cSGreg Clayton     {
130385aa28cSGreg Clayton         uint32_t unavailable_count = 0;
131385aa28cSGreg Clayton         uint32_t available_count = 0;
132385aa28cSGreg Clayton         const RegisterSet * const reg_set = reg_ctx->GetRegisterSet(set_idx);
133385aa28cSGreg Clayton         if (reg_set)
134385aa28cSGreg Clayton         {
135385aa28cSGreg Clayton             strm.Printf ("%s:\n", reg_set->name);
136385aa28cSGreg Clayton             strm.IndentMore ();
137385aa28cSGreg Clayton             const uint32_t num_registers = reg_set->num_registers;
138385aa28cSGreg Clayton             for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
139385aa28cSGreg Clayton             {
140385aa28cSGreg Clayton                 const uint32_t reg = reg_set->registers[reg_idx];
1416d4d4f7dSJohnny Chen                 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoAtIndex(reg);
1426d4d4f7dSJohnny Chen                 // Skip the dumping of derived register if primitive_only is true.
1436d4d4f7dSJohnny Chen                 if (primitive_only && reg_info && reg_info->value_regs)
1446d4d4f7dSJohnny Chen                     continue;
1456d4d4f7dSJohnny Chen                 if (DumpRegister (exe_ctx, strm, reg_ctx, reg_info))
146385aa28cSGreg Clayton                     ++available_count;
147385aa28cSGreg Clayton                 else
148385aa28cSGreg Clayton                     ++unavailable_count;
149385aa28cSGreg Clayton             }
150385aa28cSGreg Clayton             strm.IndentLess ();
151385aa28cSGreg Clayton             if (unavailable_count)
152385aa28cSGreg Clayton             {
153385aa28cSGreg Clayton                 strm.Indent ();
154385aa28cSGreg Clayton                 strm.Printf("%u registers were unavailable.\n", unavailable_count);
155385aa28cSGreg Clayton             }
156385aa28cSGreg Clayton             strm.EOL();
157385aa28cSGreg Clayton         }
158385aa28cSGreg Clayton         return available_count > 0;
159385aa28cSGreg Clayton     }
160385aa28cSGreg Clayton 
1615a988416SJim Ingham protected:
16230fdc8d8SChris Lattner     virtual bool
1635a988416SJim Ingham     DoExecute (Args& command, CommandReturnObject &result)
16430fdc8d8SChris Lattner     {
165385aa28cSGreg Clayton         Stream &strm = result.GetOutputStream();
1668b82f087SGreg Clayton         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
167385aa28cSGreg Clayton         RegisterContext *reg_ctx = exe_ctx.GetRegisterContext ();
16830fdc8d8SChris Lattner 
169385aa28cSGreg Clayton         if (reg_ctx)
17030fdc8d8SChris Lattner         {
17130fdc8d8SChris Lattner             const RegisterInfo *reg_info = NULL;
17230fdc8d8SChris Lattner             if (command.GetArgumentCount() == 0)
17330fdc8d8SChris Lattner             {
17430fdc8d8SChris Lattner                 uint32_t set_idx;
175385aa28cSGreg Clayton 
176385aa28cSGreg Clayton                 uint32_t num_register_sets = 1;
1771deb7962SGreg Clayton                 const uint32_t set_array_size = m_command_options.set_indexes.GetSize();
178385aa28cSGreg Clayton                 if (set_array_size > 0)
17930fdc8d8SChris Lattner                 {
180385aa28cSGreg Clayton                     for (uint32_t i=0; i<set_array_size; ++i)
18130fdc8d8SChris Lattner                     {
1821deb7962SGreg Clayton                         set_idx = m_command_options.set_indexes[i]->GetUInt64Value (UINT32_MAX, NULL);
183385aa28cSGreg Clayton                         if (set_idx != UINT32_MAX)
18430fdc8d8SChris Lattner                         {
185385aa28cSGreg Clayton                             if (!DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx))
186385aa28cSGreg Clayton                             {
187385aa28cSGreg Clayton                                 result.AppendErrorWithFormat ("invalid register set index: %u\n", set_idx);
188385aa28cSGreg Clayton                                 result.SetStatus (eReturnStatusFailed);
189385aa28cSGreg Clayton                                 break;
190385aa28cSGreg Clayton                             }
19130fdc8d8SChris Lattner                         }
19230fdc8d8SChris Lattner                         else
19330fdc8d8SChris Lattner                         {
194385aa28cSGreg Clayton                             result.AppendError ("invalid register set index\n");
195385aa28cSGreg Clayton                             result.SetStatus (eReturnStatusFailed);
196385aa28cSGreg Clayton                             break;
19730fdc8d8SChris Lattner                         }
19830fdc8d8SChris Lattner                     }
199385aa28cSGreg Clayton                 }
200385aa28cSGreg Clayton                 else
20130fdc8d8SChris Lattner                 {
2021deb7962SGreg Clayton                     if (m_command_options.dump_all_sets)
203385aa28cSGreg Clayton                         num_register_sets = reg_ctx->GetRegisterSetCount();
204385aa28cSGreg Clayton 
205385aa28cSGreg Clayton                     for (set_idx = 0; set_idx < num_register_sets; ++set_idx)
206385aa28cSGreg Clayton                     {
2076d4d4f7dSJohnny Chen                         // When dump_all_sets option is set, dump primitive as well as derived registers.
2086d4d4f7dSJohnny Chen                         DumpRegisterSet (exe_ctx, strm, reg_ctx, set_idx, !m_command_options.dump_all_sets.GetCurrentValue());
20930fdc8d8SChris Lattner                     }
21030fdc8d8SChris Lattner                 }
21130fdc8d8SChris Lattner             }
21230fdc8d8SChris Lattner             else
21330fdc8d8SChris Lattner             {
2141deb7962SGreg Clayton                 if (m_command_options.dump_all_sets)
215385aa28cSGreg Clayton                 {
216385aa28cSGreg Clayton                     result.AppendError ("the --all option can't be used when registers names are supplied as arguments\n");
217385aa28cSGreg Clayton                     result.SetStatus (eReturnStatusFailed);
218385aa28cSGreg Clayton                 }
2191deb7962SGreg Clayton                 else if (m_command_options.set_indexes.GetSize() > 0)
220385aa28cSGreg Clayton                 {
221385aa28cSGreg Clayton                     result.AppendError ("the --set <set> option can't be used when registers names are supplied as arguments\n");
222385aa28cSGreg Clayton                     result.SetStatus (eReturnStatusFailed);
223385aa28cSGreg Clayton                 }
224385aa28cSGreg Clayton                 else
225385aa28cSGreg Clayton                 {
22630fdc8d8SChris Lattner                     const char *arg_cstr;
22730fdc8d8SChris Lattner                     for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
22830fdc8d8SChris Lattner                     {
229385aa28cSGreg Clayton                         reg_info = reg_ctx->GetRegisterInfoByName(arg_cstr);
23030fdc8d8SChris Lattner 
23130fdc8d8SChris Lattner                         if (reg_info)
23230fdc8d8SChris Lattner                         {
233385aa28cSGreg Clayton                             if (!DumpRegister (exe_ctx, strm, reg_ctx, reg_info))
234385aa28cSGreg Clayton                                 strm.Printf("%-12s = error: unavailable\n", reg_info->name);
23530fdc8d8SChris Lattner                         }
23630fdc8d8SChris Lattner                         else
23730fdc8d8SChris Lattner                         {
23830fdc8d8SChris Lattner                             result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr);
23930fdc8d8SChris Lattner                         }
24030fdc8d8SChris Lattner                     }
24130fdc8d8SChris Lattner                 }
24230fdc8d8SChris Lattner             }
243385aa28cSGreg Clayton         }
24430fdc8d8SChris Lattner         else
24530fdc8d8SChris Lattner         {
24630fdc8d8SChris Lattner             result.AppendError ("no current frame");
24730fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
24830fdc8d8SChris Lattner         }
24930fdc8d8SChris Lattner         return result.Succeeded();
25030fdc8d8SChris Lattner     }
25132e0a750SGreg Clayton 
2521deb7962SGreg Clayton     class CommandOptions : public OptionGroup
25332e0a750SGreg Clayton     {
25432e0a750SGreg Clayton     public:
2551deb7962SGreg Clayton         CommandOptions () :
2561deb7962SGreg Clayton             OptionGroup(),
257385aa28cSGreg Clayton             set_indexes (OptionValue::ConvertTypeToMask (OptionValue::eTypeUInt64)),
2589a8fa916SGreg Clayton             dump_all_sets (false, false), // Initial and default values are false
2599a8fa916SGreg Clayton             alternate_name (false, false)
26032e0a750SGreg Clayton         {
26132e0a750SGreg Clayton         }
26232e0a750SGreg Clayton 
26332e0a750SGreg Clayton         virtual
26432e0a750SGreg Clayton         ~CommandOptions ()
26532e0a750SGreg Clayton         {
26632e0a750SGreg Clayton         }
26732e0a750SGreg Clayton 
2681deb7962SGreg Clayton 
2691deb7962SGreg Clayton         virtual uint32_t
2701deb7962SGreg Clayton         GetNumDefinitions ();
2711deb7962SGreg Clayton 
2721deb7962SGreg Clayton         virtual const OptionDefinition*
2731deb7962SGreg Clayton         GetDefinitions ()
2741deb7962SGreg Clayton         {
2751deb7962SGreg Clayton             return g_option_table;
2761deb7962SGreg Clayton         }
2771deb7962SGreg Clayton 
2781deb7962SGreg Clayton         virtual void
2791deb7962SGreg Clayton         OptionParsingStarting (CommandInterpreter &interpreter)
2801deb7962SGreg Clayton         {
2811deb7962SGreg Clayton             set_indexes.Clear();
2821deb7962SGreg Clayton             dump_all_sets.Clear();
2831deb7962SGreg Clayton             alternate_name.Clear();
2841deb7962SGreg Clayton         }
2851deb7962SGreg Clayton 
28632e0a750SGreg Clayton         virtual Error
2871deb7962SGreg Clayton         SetOptionValue (CommandInterpreter &interpreter,
2881deb7962SGreg Clayton                         uint32_t option_idx,
2891deb7962SGreg Clayton                         const char *option_value)
29032e0a750SGreg Clayton         {
29132e0a750SGreg Clayton             Error error;
292*3bcdfc0eSGreg Clayton             const int short_option = g_option_table[option_idx].short_option;
29332e0a750SGreg Clayton             switch (short_option)
29432e0a750SGreg Clayton             {
295385aa28cSGreg Clayton                 case 's':
296385aa28cSGreg Clayton                     {
2971deb7962SGreg Clayton                         OptionValueSP value_sp (OptionValueUInt64::Create (option_value, error));
298385aa28cSGreg Clayton                         if (value_sp)
299385aa28cSGreg Clayton                             set_indexes.AppendValue (value_sp);
300385aa28cSGreg Clayton                     }
301385aa28cSGreg Clayton                     break;
302385aa28cSGreg Clayton 
303385aa28cSGreg Clayton                 case 'a':
3049a8fa916SGreg Clayton                     // When we don't use OptionValue::SetValueFromCString(const char *) to
3059a8fa916SGreg Clayton                     // set an option value, it won't be marked as being set in the options
3069a8fa916SGreg Clayton                     // so we make a call to let users know the value was set via option
307385aa28cSGreg Clayton                     dump_all_sets.SetCurrentValue (true);
3089a8fa916SGreg Clayton                     dump_all_sets.SetOptionWasSet ();
3099a8fa916SGreg Clayton                     break;
3109a8fa916SGreg Clayton 
3119a8fa916SGreg Clayton                 case 'A':
3129a8fa916SGreg Clayton                     // When we don't use OptionValue::SetValueFromCString(const char *) to
3139a8fa916SGreg Clayton                     // set an option value, it won't be marked as being set in the options
3149a8fa916SGreg Clayton                     // so we make a call to let users know the value was set via option
3159a8fa916SGreg Clayton                     alternate_name.SetCurrentValue (true);
3169a8fa916SGreg Clayton                     dump_all_sets.SetOptionWasSet ();
317385aa28cSGreg Clayton                     break;
318385aa28cSGreg Clayton 
31932e0a750SGreg Clayton                 default:
32086edbf41SGreg Clayton                     error.SetErrorStringWithFormat("unrecognized short option '%c'", short_option);
32132e0a750SGreg Clayton                     break;
32232e0a750SGreg Clayton             }
32332e0a750SGreg Clayton             return error;
32432e0a750SGreg Clayton         }
32532e0a750SGreg Clayton 
32632e0a750SGreg Clayton         // Options table: Required for subclasses of Options.
32732e0a750SGreg Clayton 
3281deb7962SGreg Clayton         static const OptionDefinition g_option_table[];
32932e0a750SGreg Clayton 
33032e0a750SGreg Clayton         // Instance variables to hold the values for command options.
331385aa28cSGreg Clayton         OptionValueArray set_indexes;
332385aa28cSGreg Clayton         OptionValueBoolean dump_all_sets;
3339a8fa916SGreg Clayton         OptionValueBoolean alternate_name;
33430fdc8d8SChris Lattner     };
33530fdc8d8SChris Lattner 
3361deb7962SGreg Clayton     OptionGroupOptions m_option_group;
3371deb7962SGreg Clayton     OptionGroupFormat m_format_options;
3381deb7962SGreg Clayton     CommandOptions m_command_options;
33932e0a750SGreg Clayton };
34032e0a750SGreg Clayton 
3413d0fcf5eSJohnny Chen const OptionDefinition
34232e0a750SGreg Clayton CommandObjectRegisterRead::CommandOptions::g_option_table[] =
34332e0a750SGreg Clayton {
3449a8fa916SGreg 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."},
345385aa28cSGreg Clayton     { LLDB_OPT_SET_1  , false, "set"      , 's', required_argument, NULL, 0, eArgTypeIndex     , "Specify which register sets to dump by index."},
346385aa28cSGreg Clayton     { LLDB_OPT_SET_2  , false, "all"      , 'a', no_argument      , NULL, 0, eArgTypeNone      , "Show all register sets."},
34732e0a750SGreg Clayton };
34832e0a750SGreg Clayton 
3491deb7962SGreg Clayton uint32_t
3501deb7962SGreg Clayton CommandObjectRegisterRead::CommandOptions::GetNumDefinitions ()
3511deb7962SGreg Clayton {
3521deb7962SGreg Clayton     return sizeof(g_option_table)/sizeof(OptionDefinition);
3531deb7962SGreg Clayton }
35432e0a750SGreg Clayton 
35530fdc8d8SChris Lattner 
35630fdc8d8SChris Lattner //----------------------------------------------------------------------
35730fdc8d8SChris Lattner // "register write"
35830fdc8d8SChris Lattner //----------------------------------------------------------------------
3595a988416SJim Ingham class CommandObjectRegisterWrite : public CommandObjectParsed
36030fdc8d8SChris Lattner {
36130fdc8d8SChris Lattner public:
362a7015092SGreg Clayton     CommandObjectRegisterWrite (CommandInterpreter &interpreter) :
3635a988416SJim Ingham         CommandObjectParsed (interpreter,
364a7015092SGreg Clayton                              "register write",
36530fdc8d8SChris Lattner                              "Modify a single register value.",
366405fe67fSCaroline Tice                              NULL,
36730fdc8d8SChris Lattner                              eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
36830fdc8d8SChris Lattner     {
369405fe67fSCaroline Tice         CommandArgumentEntry arg1;
370405fe67fSCaroline Tice         CommandArgumentEntry arg2;
371405fe67fSCaroline Tice         CommandArgumentData register_arg;
372405fe67fSCaroline Tice         CommandArgumentData value_arg;
373405fe67fSCaroline Tice 
374405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
375405fe67fSCaroline Tice         register_arg.arg_type = eArgTypeRegisterName;
376405fe67fSCaroline Tice         register_arg.arg_repetition = eArgRepeatPlain;
377405fe67fSCaroline Tice 
378405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
379405fe67fSCaroline Tice         arg1.push_back (register_arg);
380405fe67fSCaroline Tice 
381405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
382405fe67fSCaroline Tice         value_arg.arg_type = eArgTypeValue;
383405fe67fSCaroline Tice         value_arg.arg_repetition = eArgRepeatPlain;
384405fe67fSCaroline Tice 
385405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
386405fe67fSCaroline Tice         arg2.push_back (value_arg);
387405fe67fSCaroline Tice 
388405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
389405fe67fSCaroline Tice         m_arguments.push_back (arg1);
390405fe67fSCaroline Tice         m_arguments.push_back (arg2);
39130fdc8d8SChris Lattner     }
39230fdc8d8SChris Lattner 
39330fdc8d8SChris Lattner     virtual
39430fdc8d8SChris Lattner     ~CommandObjectRegisterWrite ()
39530fdc8d8SChris Lattner     {
39630fdc8d8SChris Lattner     }
39730fdc8d8SChris Lattner 
3985a988416SJim Ingham protected:
39930fdc8d8SChris Lattner     virtual bool
4005a988416SJim Ingham     DoExecute(Args& command, CommandReturnObject &result)
40130fdc8d8SChris Lattner     {
40230fdc8d8SChris Lattner         DataExtractor reg_data;
4038b82f087SGreg Clayton         ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
404385aa28cSGreg Clayton         RegisterContext *reg_ctx = exe_ctx.GetRegisterContext ();
40530fdc8d8SChris Lattner 
406385aa28cSGreg Clayton         if (reg_ctx)
40730fdc8d8SChris Lattner         {
40830fdc8d8SChris Lattner             if (command.GetArgumentCount() != 2)
40930fdc8d8SChris Lattner             {
41030fdc8d8SChris Lattner                 result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>");
41130fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
41230fdc8d8SChris Lattner             }
41330fdc8d8SChris Lattner             else
41430fdc8d8SChris Lattner             {
41530fdc8d8SChris Lattner                 const char *reg_name = command.GetArgumentAtIndex(0);
41630fdc8d8SChris Lattner                 const char *value_str = command.GetArgumentAtIndex(1);
417385aa28cSGreg Clayton                 const RegisterInfo *reg_info = reg_ctx->GetRegisterInfoByName(reg_name);
41830fdc8d8SChris Lattner 
41930fdc8d8SChris Lattner                 if (reg_info)
42030fdc8d8SChris Lattner                 {
4217349bd90SGreg Clayton                     RegisterValue reg_value;
4227349bd90SGreg Clayton 
4237349bd90SGreg Clayton                     Error error (reg_value.SetValueFromCString (reg_info, value_str));
42430fdc8d8SChris Lattner                     if (error.Success())
42530fdc8d8SChris Lattner                     {
4267349bd90SGreg Clayton                         if (reg_ctx->WriteRegister (reg_info, reg_value))
42730fdc8d8SChris Lattner                         {
428fa559e5cSGreg Clayton                             // Toss all frames and anything else in the thread
429fa559e5cSGreg Clayton                             // after a register has been written.
430fa559e5cSGreg Clayton                             exe_ctx.GetThreadRef().Flush();
43130fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusSuccessFinishNoResult);
43230fdc8d8SChris Lattner                             return true;
43330fdc8d8SChris Lattner                         }
43430fdc8d8SChris Lattner                     }
435b1ad65c5SJason Molenda                     if (error.AsCString())
43630fdc8d8SChris Lattner                     {
43730fdc8d8SChris Lattner                         result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n",
43830fdc8d8SChris Lattner                                                      reg_name,
43930fdc8d8SChris Lattner                                                      value_str,
44030fdc8d8SChris Lattner                                                      error.AsCString());
44130fdc8d8SChris Lattner                     }
442b1ad65c5SJason Molenda                     else
443b1ad65c5SJason Molenda                     {
444b1ad65c5SJason Molenda                         result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s'",
445b1ad65c5SJason Molenda                                                      reg_name,
446b1ad65c5SJason Molenda                                                      value_str);
447b1ad65c5SJason Molenda                     }
448b1ad65c5SJason Molenda                     result.SetStatus (eReturnStatusFailed);
44930fdc8d8SChris Lattner                 }
45030fdc8d8SChris Lattner                 else
45130fdc8d8SChris Lattner                 {
45230fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name);
45330fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
45430fdc8d8SChris Lattner                 }
45530fdc8d8SChris Lattner             }
45630fdc8d8SChris Lattner         }
45730fdc8d8SChris Lattner         else
45830fdc8d8SChris Lattner         {
45930fdc8d8SChris Lattner             result.AppendError ("no current frame");
46030fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
46130fdc8d8SChris Lattner         }
46230fdc8d8SChris Lattner         return result.Succeeded();
46330fdc8d8SChris Lattner     }
46430fdc8d8SChris Lattner };
46530fdc8d8SChris Lattner 
46630fdc8d8SChris Lattner 
46730fdc8d8SChris Lattner //----------------------------------------------------------------------
46830fdc8d8SChris Lattner // CommandObjectRegister constructor
46930fdc8d8SChris Lattner //----------------------------------------------------------------------
4706611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) :
471a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
472a7015092SGreg Clayton                             "register",
4733f4c09c1SCaroline Tice                             "A set of commands to access thread registers.",
47430fdc8d8SChris Lattner                             "register [read|write] ...")
47530fdc8d8SChris Lattner {
476a7015092SGreg Clayton     LoadSubCommand ("read",  CommandObjectSP (new CommandObjectRegisterRead (interpreter)));
477a7015092SGreg Clayton     LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter)));
47830fdc8d8SChris Lattner }
47930fdc8d8SChris Lattner 
48030fdc8d8SChris Lattner 
48130fdc8d8SChris Lattner //----------------------------------------------------------------------
48230fdc8d8SChris Lattner // Destructor
48330fdc8d8SChris Lattner //----------------------------------------------------------------------
48430fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister()
48530fdc8d8SChris Lattner {
48630fdc8d8SChris Lattner }
487