1*30fdc8d8SChris Lattner //===-- CommandObjectRegister.cpp -------------------------------*- C++ -*-===//
2*30fdc8d8SChris Lattner //
3*30fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
4*30fdc8d8SChris Lattner //
5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
7*30fdc8d8SChris Lattner //
8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
9*30fdc8d8SChris Lattner 
10*30fdc8d8SChris Lattner #include "CommandObjectRegister.h"
11*30fdc8d8SChris Lattner 
12*30fdc8d8SChris Lattner // C Includes
13*30fdc8d8SChris Lattner // C++ Includes
14*30fdc8d8SChris Lattner // Other libraries and framework includes
15*30fdc8d8SChris Lattner // Project includes
16*30fdc8d8SChris Lattner #include "lldb/Core/Args.h"
17*30fdc8d8SChris Lattner #include "lldb/Core/DataExtractor.h"
18*30fdc8d8SChris Lattner #include "lldb/Core/Scalar.h"
19*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandContext.h"
20*30fdc8d8SChris Lattner #include "lldb/Interpreter/CommandReturnObject.h"
21*30fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h"
22*30fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
23*30fdc8d8SChris Lattner 
24*30fdc8d8SChris Lattner using namespace lldb;
25*30fdc8d8SChris Lattner using namespace lldb_private;
26*30fdc8d8SChris Lattner 
27*30fdc8d8SChris Lattner //----------------------------------------------------------------------
28*30fdc8d8SChris Lattner // "register read"
29*30fdc8d8SChris Lattner //----------------------------------------------------------------------
30*30fdc8d8SChris Lattner class CommandObjectRegisterRead : public CommandObject
31*30fdc8d8SChris Lattner {
32*30fdc8d8SChris Lattner public:
33*30fdc8d8SChris Lattner     CommandObjectRegisterRead () :
34*30fdc8d8SChris Lattner         CommandObject ("register read",
35*30fdc8d8SChris Lattner                        "Dump the one or more register values from the current frame.",
36*30fdc8d8SChris Lattner                        "register read [<reg-name1> [<reg-name2> [...]]]",
37*30fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
38*30fdc8d8SChris Lattner     {
39*30fdc8d8SChris Lattner     }
40*30fdc8d8SChris Lattner 
41*30fdc8d8SChris Lattner     virtual
42*30fdc8d8SChris Lattner     ~CommandObjectRegisterRead ()
43*30fdc8d8SChris Lattner     {
44*30fdc8d8SChris Lattner     }
45*30fdc8d8SChris Lattner 
46*30fdc8d8SChris Lattner     virtual bool
47*30fdc8d8SChris Lattner     Execute (Args& command,
48*30fdc8d8SChris Lattner              CommandContext *context,
49*30fdc8d8SChris Lattner              CommandInterpreter *interpreter,
50*30fdc8d8SChris Lattner              CommandReturnObject &result)
51*30fdc8d8SChris Lattner     {
52*30fdc8d8SChris Lattner         StreamString &output_stream = result.GetOutputStream();
53*30fdc8d8SChris Lattner         DataExtractor reg_data;
54*30fdc8d8SChris Lattner         ExecutionContext exe_ctx(context->GetExecutionContext());
55*30fdc8d8SChris Lattner         RegisterContext *reg_context = exe_ctx.GetRegisterContext ();
56*30fdc8d8SChris Lattner 
57*30fdc8d8SChris Lattner         if (reg_context)
58*30fdc8d8SChris Lattner         {
59*30fdc8d8SChris Lattner             const RegisterInfo *reg_info = NULL;
60*30fdc8d8SChris Lattner             if (command.GetArgumentCount() == 0)
61*30fdc8d8SChris Lattner             {
62*30fdc8d8SChris Lattner                 uint32_t set_idx;
63*30fdc8d8SChris Lattner                 const uint32_t num_register_sets = reg_context->GetRegisterSetCount();
64*30fdc8d8SChris Lattner                 for (set_idx = 0; set_idx < num_register_sets; ++set_idx)
65*30fdc8d8SChris Lattner                 {
66*30fdc8d8SChris Lattner                     uint32_t unavailable_count = 0;
67*30fdc8d8SChris Lattner                     const RegisterSet * const reg_set = reg_context->GetRegisterSet(set_idx);
68*30fdc8d8SChris Lattner                     output_stream.Printf ("%s:\n", reg_set->name);
69*30fdc8d8SChris Lattner                     output_stream.IndentMore ();
70*30fdc8d8SChris Lattner                     const uint32_t num_registers = reg_set->num_registers;
71*30fdc8d8SChris Lattner                     for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
72*30fdc8d8SChris Lattner                     {
73*30fdc8d8SChris Lattner                         uint32_t reg = reg_set->registers[reg_idx];
74*30fdc8d8SChris Lattner                         reg_info = reg_context->GetRegisterInfoAtIndex(reg);
75*30fdc8d8SChris Lattner                         if (reg_context->ReadRegisterBytes(reg, reg_data))
76*30fdc8d8SChris Lattner                         {
77*30fdc8d8SChris Lattner                             output_stream.Indent ();
78*30fdc8d8SChris Lattner                             output_stream.Printf ("%-12s = ", reg_info ? reg_info->name : "<INVALID REGINFO>");
79*30fdc8d8SChris Lattner                             reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
80*30fdc8d8SChris Lattner                             output_stream.EOL();
81*30fdc8d8SChris Lattner                         }
82*30fdc8d8SChris Lattner                         else
83*30fdc8d8SChris Lattner                         {
84*30fdc8d8SChris Lattner                             ++unavailable_count;
85*30fdc8d8SChris Lattner                         }
86*30fdc8d8SChris Lattner                     }
87*30fdc8d8SChris Lattner                     if (unavailable_count)
88*30fdc8d8SChris Lattner                     {
89*30fdc8d8SChris Lattner                         output_stream.Indent ();
90*30fdc8d8SChris Lattner                         output_stream.Printf("%u registers were unavailable.\n", unavailable_count);
91*30fdc8d8SChris Lattner                     }
92*30fdc8d8SChris Lattner                     output_stream.IndentLess ();
93*30fdc8d8SChris Lattner                     output_stream.EOL();
94*30fdc8d8SChris Lattner                 }
95*30fdc8d8SChris Lattner             }
96*30fdc8d8SChris Lattner             else
97*30fdc8d8SChris Lattner             {
98*30fdc8d8SChris Lattner                 const char *arg_cstr;
99*30fdc8d8SChris Lattner                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
100*30fdc8d8SChris Lattner                 {
101*30fdc8d8SChris Lattner                     reg_info = reg_context->GetRegisterInfoByName(arg_cstr);
102*30fdc8d8SChris Lattner 
103*30fdc8d8SChris Lattner                     if (reg_info)
104*30fdc8d8SChris Lattner                     {
105*30fdc8d8SChris Lattner                         output_stream.Printf("%-12s = ", reg_info->name);
106*30fdc8d8SChris Lattner                         if (reg_context->ReadRegisterBytes(reg_info->reg, reg_data))
107*30fdc8d8SChris Lattner                         {
108*30fdc8d8SChris Lattner                             reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
109*30fdc8d8SChris Lattner                         }
110*30fdc8d8SChris Lattner                         else
111*30fdc8d8SChris Lattner                         {
112*30fdc8d8SChris Lattner                             output_stream.PutCString ("error: unavailable");
113*30fdc8d8SChris Lattner                         }
114*30fdc8d8SChris Lattner                         output_stream.EOL();
115*30fdc8d8SChris Lattner                     }
116*30fdc8d8SChris Lattner                     else
117*30fdc8d8SChris Lattner                     {
118*30fdc8d8SChris Lattner                         result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr);
119*30fdc8d8SChris Lattner                     }
120*30fdc8d8SChris Lattner                 }
121*30fdc8d8SChris Lattner             }
122*30fdc8d8SChris Lattner         }
123*30fdc8d8SChris Lattner         else
124*30fdc8d8SChris Lattner         {
125*30fdc8d8SChris Lattner             result.AppendError ("no current frame");
126*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
127*30fdc8d8SChris Lattner         }
128*30fdc8d8SChris Lattner         return result.Succeeded();
129*30fdc8d8SChris Lattner     }
130*30fdc8d8SChris Lattner };
131*30fdc8d8SChris Lattner 
132*30fdc8d8SChris Lattner 
133*30fdc8d8SChris Lattner //----------------------------------------------------------------------
134*30fdc8d8SChris Lattner // "register write"
135*30fdc8d8SChris Lattner //----------------------------------------------------------------------
136*30fdc8d8SChris Lattner class CommandObjectRegisterWrite : public CommandObject
137*30fdc8d8SChris Lattner {
138*30fdc8d8SChris Lattner public:
139*30fdc8d8SChris Lattner     CommandObjectRegisterWrite () :
140*30fdc8d8SChris Lattner         CommandObject ("register write",
141*30fdc8d8SChris Lattner                        "Modify a single register value.",
142*30fdc8d8SChris Lattner                        "register write <reg-name> <value>",
143*30fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
144*30fdc8d8SChris Lattner     {
145*30fdc8d8SChris Lattner     }
146*30fdc8d8SChris Lattner 
147*30fdc8d8SChris Lattner     virtual
148*30fdc8d8SChris Lattner     ~CommandObjectRegisterWrite ()
149*30fdc8d8SChris Lattner     {
150*30fdc8d8SChris Lattner     }
151*30fdc8d8SChris Lattner 
152*30fdc8d8SChris Lattner     virtual bool
153*30fdc8d8SChris Lattner     Execute (Args& command,
154*30fdc8d8SChris Lattner              CommandContext *context,
155*30fdc8d8SChris Lattner              CommandInterpreter *interpreter,
156*30fdc8d8SChris Lattner              CommandReturnObject &result)
157*30fdc8d8SChris Lattner     {
158*30fdc8d8SChris Lattner         DataExtractor reg_data;
159*30fdc8d8SChris Lattner         ExecutionContext exe_ctx(context->GetExecutionContext());
160*30fdc8d8SChris Lattner         RegisterContext *reg_context = exe_ctx.GetRegisterContext ();
161*30fdc8d8SChris Lattner 
162*30fdc8d8SChris Lattner         if (reg_context)
163*30fdc8d8SChris Lattner         {
164*30fdc8d8SChris Lattner             if (command.GetArgumentCount() != 2)
165*30fdc8d8SChris Lattner             {
166*30fdc8d8SChris Lattner                 result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>");
167*30fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
168*30fdc8d8SChris Lattner             }
169*30fdc8d8SChris Lattner             else
170*30fdc8d8SChris Lattner             {
171*30fdc8d8SChris Lattner                 const char *reg_name = command.GetArgumentAtIndex(0);
172*30fdc8d8SChris Lattner                 const char *value_str = command.GetArgumentAtIndex(1);
173*30fdc8d8SChris Lattner                 const RegisterInfo *reg_info = reg_context->GetRegisterInfoByName(reg_name);
174*30fdc8d8SChris Lattner 
175*30fdc8d8SChris Lattner                 if (reg_info)
176*30fdc8d8SChris Lattner                 {
177*30fdc8d8SChris Lattner                     Scalar scalar;
178*30fdc8d8SChris Lattner                     Error error(scalar.SetValueFromCString (value_str, reg_info->encoding, reg_info->byte_size));
179*30fdc8d8SChris Lattner                     if (error.Success())
180*30fdc8d8SChris Lattner                     {
181*30fdc8d8SChris Lattner                         if (reg_context->WriteRegisterValue(reg_info->reg, scalar))
182*30fdc8d8SChris Lattner                         {
183*30fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusSuccessFinishNoResult);
184*30fdc8d8SChris Lattner                             return true;
185*30fdc8d8SChris Lattner                         }
186*30fdc8d8SChris Lattner                     }
187*30fdc8d8SChris Lattner                     else
188*30fdc8d8SChris Lattner                     {
189*30fdc8d8SChris Lattner                         result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n",
190*30fdc8d8SChris Lattner                                                      reg_name,
191*30fdc8d8SChris Lattner                                                      value_str,
192*30fdc8d8SChris Lattner                                                      error.AsCString());
193*30fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
194*30fdc8d8SChris Lattner                     }
195*30fdc8d8SChris Lattner                 }
196*30fdc8d8SChris Lattner                 else
197*30fdc8d8SChris Lattner                 {
198*30fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name);
199*30fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
200*30fdc8d8SChris Lattner                 }
201*30fdc8d8SChris Lattner             }
202*30fdc8d8SChris Lattner         }
203*30fdc8d8SChris Lattner         else
204*30fdc8d8SChris Lattner         {
205*30fdc8d8SChris Lattner             result.AppendError ("no current frame");
206*30fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
207*30fdc8d8SChris Lattner         }
208*30fdc8d8SChris Lattner         return result.Succeeded();
209*30fdc8d8SChris Lattner     }
210*30fdc8d8SChris Lattner };
211*30fdc8d8SChris Lattner 
212*30fdc8d8SChris Lattner 
213*30fdc8d8SChris Lattner //----------------------------------------------------------------------
214*30fdc8d8SChris Lattner // CommandObjectRegister constructor
215*30fdc8d8SChris Lattner //----------------------------------------------------------------------
216*30fdc8d8SChris Lattner CommandObjectRegister::CommandObjectRegister(CommandInterpreter *interpreter) :
217*30fdc8d8SChris Lattner     CommandObjectMultiword ("register",
218*30fdc8d8SChris Lattner                             "Access thread registers.",
219*30fdc8d8SChris Lattner                             "register [read|write] ...")
220*30fdc8d8SChris Lattner {
221*30fdc8d8SChris Lattner     LoadSubCommand (CommandObjectSP (new CommandObjectRegisterRead ()), "read", interpreter);
222*30fdc8d8SChris Lattner     LoadSubCommand (CommandObjectSP (new CommandObjectRegisterWrite ()), "write", interpreter);
223*30fdc8d8SChris Lattner }
224*30fdc8d8SChris Lattner 
225*30fdc8d8SChris Lattner 
226*30fdc8d8SChris Lattner //----------------------------------------------------------------------
227*30fdc8d8SChris Lattner // Destructor
228*30fdc8d8SChris Lattner //----------------------------------------------------------------------
229*30fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister()
230*30fdc8d8SChris Lattner {
231*30fdc8d8SChris Lattner }
232