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"
2230fdc8d8SChris Lattner #include "lldb/Target/ExecutionContext.h"
2330fdc8d8SChris Lattner #include "lldb/Target/RegisterContext.h"
2430fdc8d8SChris Lattner 
2530fdc8d8SChris Lattner using namespace lldb;
2630fdc8d8SChris Lattner using namespace lldb_private;
2730fdc8d8SChris Lattner 
2830fdc8d8SChris Lattner //----------------------------------------------------------------------
2930fdc8d8SChris Lattner // "register read"
3030fdc8d8SChris Lattner //----------------------------------------------------------------------
3130fdc8d8SChris Lattner class CommandObjectRegisterRead : public CommandObject
3230fdc8d8SChris Lattner {
3330fdc8d8SChris Lattner public:
34a7015092SGreg Clayton     CommandObjectRegisterRead (CommandInterpreter &interpreter) :
35a7015092SGreg Clayton         CommandObject (interpreter,
36a7015092SGreg Clayton                        "register read",
37*405fe67fSCaroline Tice                        "Dump the contents of one or more register values from the current frame.  If no register is specified, dumps them all.",
38*405fe67fSCaroline Tice                        //"register read [<reg-name1> [<reg-name2> [...]]]",
39*405fe67fSCaroline Tice                        NULL,
4030fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
4130fdc8d8SChris Lattner     {
42*405fe67fSCaroline Tice         CommandArgumentEntry arg;
43*405fe67fSCaroline Tice         CommandArgumentData register_arg;
44*405fe67fSCaroline Tice 
45*405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
46*405fe67fSCaroline Tice         register_arg.arg_type = eArgTypeRegisterName;
47*405fe67fSCaroline Tice         register_arg.arg_repetition = eArgRepeatStar;
48*405fe67fSCaroline Tice 
49*405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
50*405fe67fSCaroline Tice         arg.push_back (register_arg);
51*405fe67fSCaroline Tice 
52*405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
53*405fe67fSCaroline Tice         m_arguments.push_back (arg);
5430fdc8d8SChris Lattner     }
5530fdc8d8SChris Lattner 
5630fdc8d8SChris Lattner     virtual
5730fdc8d8SChris Lattner     ~CommandObjectRegisterRead ()
5830fdc8d8SChris Lattner     {
5930fdc8d8SChris Lattner     }
6030fdc8d8SChris Lattner 
6130fdc8d8SChris Lattner     virtual bool
626611103cSGreg Clayton     Execute
636611103cSGreg Clayton     (
646611103cSGreg Clayton         Args& command,
656611103cSGreg Clayton         CommandReturnObject &result
666611103cSGreg Clayton     )
6730fdc8d8SChris Lattner     {
6830fdc8d8SChris Lattner         StreamString &output_stream = result.GetOutputStream();
6930fdc8d8SChris Lattner         DataExtractor reg_data;
70a7015092SGreg Clayton         ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
7130fdc8d8SChris Lattner         RegisterContext *reg_context = exe_ctx.GetRegisterContext ();
7230fdc8d8SChris Lattner 
7330fdc8d8SChris Lattner         if (reg_context)
7430fdc8d8SChris Lattner         {
7530fdc8d8SChris Lattner             const RegisterInfo *reg_info = NULL;
7630fdc8d8SChris Lattner             if (command.GetArgumentCount() == 0)
7730fdc8d8SChris Lattner             {
7830fdc8d8SChris Lattner                 uint32_t set_idx;
7930fdc8d8SChris Lattner                 const uint32_t num_register_sets = reg_context->GetRegisterSetCount();
8030fdc8d8SChris Lattner                 for (set_idx = 0; set_idx < num_register_sets; ++set_idx)
8130fdc8d8SChris Lattner                 {
8230fdc8d8SChris Lattner                     uint32_t unavailable_count = 0;
8330fdc8d8SChris Lattner                     const RegisterSet * const reg_set = reg_context->GetRegisterSet(set_idx);
8430fdc8d8SChris Lattner                     output_stream.Printf ("%s:\n", reg_set->name);
8530fdc8d8SChris Lattner                     output_stream.IndentMore ();
8630fdc8d8SChris Lattner                     const uint32_t num_registers = reg_set->num_registers;
8730fdc8d8SChris Lattner                     for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
8830fdc8d8SChris Lattner                     {
8930fdc8d8SChris Lattner                         uint32_t reg = reg_set->registers[reg_idx];
9030fdc8d8SChris Lattner                         reg_info = reg_context->GetRegisterInfoAtIndex(reg);
9130fdc8d8SChris Lattner                         if (reg_context->ReadRegisterBytes(reg, reg_data))
9230fdc8d8SChris Lattner                         {
9330fdc8d8SChris Lattner                             output_stream.Indent ();
9430fdc8d8SChris Lattner                             output_stream.Printf ("%-12s = ", reg_info ? reg_info->name : "<INVALID REGINFO>");
9530fdc8d8SChris Lattner                             reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
9630fdc8d8SChris Lattner                             output_stream.EOL();
9730fdc8d8SChris Lattner                         }
9830fdc8d8SChris Lattner                         else
9930fdc8d8SChris Lattner                         {
10030fdc8d8SChris Lattner                             ++unavailable_count;
10130fdc8d8SChris Lattner                         }
10230fdc8d8SChris Lattner                     }
10330fdc8d8SChris Lattner                     if (unavailable_count)
10430fdc8d8SChris Lattner                     {
10530fdc8d8SChris Lattner                         output_stream.Indent ();
10630fdc8d8SChris Lattner                         output_stream.Printf("%u registers were unavailable.\n", unavailable_count);
10730fdc8d8SChris Lattner                     }
10830fdc8d8SChris Lattner                     output_stream.IndentLess ();
10930fdc8d8SChris Lattner                     output_stream.EOL();
11030fdc8d8SChris Lattner                 }
11130fdc8d8SChris Lattner             }
11230fdc8d8SChris Lattner             else
11330fdc8d8SChris Lattner             {
11430fdc8d8SChris Lattner                 const char *arg_cstr;
11530fdc8d8SChris Lattner                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
11630fdc8d8SChris Lattner                 {
11730fdc8d8SChris Lattner                     reg_info = reg_context->GetRegisterInfoByName(arg_cstr);
11830fdc8d8SChris Lattner 
11930fdc8d8SChris Lattner                     if (reg_info)
12030fdc8d8SChris Lattner                     {
12130fdc8d8SChris Lattner                         output_stream.Printf("%-12s = ", reg_info->name);
122fbcb7f2cSJason Molenda                         if (reg_context->ReadRegisterBytes(reg_info->kinds[eRegisterKindLLDB], reg_data))
12330fdc8d8SChris Lattner                         {
12430fdc8d8SChris Lattner                             reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
12530fdc8d8SChris Lattner                         }
12630fdc8d8SChris Lattner                         else
12730fdc8d8SChris Lattner                         {
12830fdc8d8SChris Lattner                             output_stream.PutCString ("error: unavailable");
12930fdc8d8SChris Lattner                         }
13030fdc8d8SChris Lattner                         output_stream.EOL();
13130fdc8d8SChris Lattner                     }
13230fdc8d8SChris Lattner                     else
13330fdc8d8SChris Lattner                     {
13430fdc8d8SChris Lattner                         result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr);
13530fdc8d8SChris Lattner                     }
13630fdc8d8SChris Lattner                 }
13730fdc8d8SChris Lattner             }
13830fdc8d8SChris Lattner         }
13930fdc8d8SChris Lattner         else
14030fdc8d8SChris Lattner         {
14130fdc8d8SChris Lattner             result.AppendError ("no current frame");
14230fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
14330fdc8d8SChris Lattner         }
14430fdc8d8SChris Lattner         return result.Succeeded();
14530fdc8d8SChris Lattner     }
14630fdc8d8SChris Lattner };
14730fdc8d8SChris Lattner 
14830fdc8d8SChris Lattner 
14930fdc8d8SChris Lattner //----------------------------------------------------------------------
15030fdc8d8SChris Lattner // "register write"
15130fdc8d8SChris Lattner //----------------------------------------------------------------------
15230fdc8d8SChris Lattner class CommandObjectRegisterWrite : public CommandObject
15330fdc8d8SChris Lattner {
15430fdc8d8SChris Lattner public:
155a7015092SGreg Clayton     CommandObjectRegisterWrite (CommandInterpreter &interpreter) :
156a7015092SGreg Clayton         CommandObject (interpreter,
157a7015092SGreg Clayton                        "register write",
15830fdc8d8SChris Lattner                        "Modify a single register value.",
159*405fe67fSCaroline Tice                        //"register write <reg-name> <value>",
160*405fe67fSCaroline Tice                        NULL,
16130fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
16230fdc8d8SChris Lattner     {
163*405fe67fSCaroline Tice         CommandArgumentEntry arg1;
164*405fe67fSCaroline Tice         CommandArgumentEntry arg2;
165*405fe67fSCaroline Tice         CommandArgumentData register_arg;
166*405fe67fSCaroline Tice         CommandArgumentData value_arg;
167*405fe67fSCaroline Tice 
168*405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
169*405fe67fSCaroline Tice         register_arg.arg_type = eArgTypeRegisterName;
170*405fe67fSCaroline Tice         register_arg.arg_repetition = eArgRepeatPlain;
171*405fe67fSCaroline Tice 
172*405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
173*405fe67fSCaroline Tice         arg1.push_back (register_arg);
174*405fe67fSCaroline Tice 
175*405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
176*405fe67fSCaroline Tice         value_arg.arg_type = eArgTypeValue;
177*405fe67fSCaroline Tice         value_arg.arg_repetition = eArgRepeatPlain;
178*405fe67fSCaroline Tice 
179*405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
180*405fe67fSCaroline Tice         arg2.push_back (value_arg);
181*405fe67fSCaroline Tice 
182*405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
183*405fe67fSCaroline Tice         m_arguments.push_back (arg1);
184*405fe67fSCaroline Tice         m_arguments.push_back (arg2);
18530fdc8d8SChris Lattner     }
18630fdc8d8SChris Lattner 
18730fdc8d8SChris Lattner     virtual
18830fdc8d8SChris Lattner     ~CommandObjectRegisterWrite ()
18930fdc8d8SChris Lattner     {
19030fdc8d8SChris Lattner     }
19130fdc8d8SChris Lattner 
19230fdc8d8SChris Lattner     virtual bool
1936611103cSGreg Clayton     Execute
1946611103cSGreg Clayton     (
1956611103cSGreg Clayton         Args& command,
1966611103cSGreg Clayton         CommandReturnObject &result
1976611103cSGreg Clayton     )
19830fdc8d8SChris Lattner     {
19930fdc8d8SChris Lattner         DataExtractor reg_data;
200a7015092SGreg Clayton         ExecutionContext exe_ctx(m_interpreter.GetDebugger().GetExecutionContext());
20130fdc8d8SChris Lattner         RegisterContext *reg_context = exe_ctx.GetRegisterContext ();
20230fdc8d8SChris Lattner 
20330fdc8d8SChris Lattner         if (reg_context)
20430fdc8d8SChris Lattner         {
20530fdc8d8SChris Lattner             if (command.GetArgumentCount() != 2)
20630fdc8d8SChris Lattner             {
20730fdc8d8SChris Lattner                 result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>");
20830fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
20930fdc8d8SChris Lattner             }
21030fdc8d8SChris Lattner             else
21130fdc8d8SChris Lattner             {
21230fdc8d8SChris Lattner                 const char *reg_name = command.GetArgumentAtIndex(0);
21330fdc8d8SChris Lattner                 const char *value_str = command.GetArgumentAtIndex(1);
21430fdc8d8SChris Lattner                 const RegisterInfo *reg_info = reg_context->GetRegisterInfoByName(reg_name);
21530fdc8d8SChris Lattner 
21630fdc8d8SChris Lattner                 if (reg_info)
21730fdc8d8SChris Lattner                 {
21830fdc8d8SChris Lattner                     Scalar scalar;
21930fdc8d8SChris Lattner                     Error error(scalar.SetValueFromCString (value_str, reg_info->encoding, reg_info->byte_size));
22030fdc8d8SChris Lattner                     if (error.Success())
22130fdc8d8SChris Lattner                     {
222fbcb7f2cSJason Molenda                         if (reg_context->WriteRegisterValue(reg_info->kinds[eRegisterKindLLDB], scalar))
22330fdc8d8SChris Lattner                         {
22430fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusSuccessFinishNoResult);
22530fdc8d8SChris Lattner                             return true;
22630fdc8d8SChris Lattner                         }
22730fdc8d8SChris Lattner                     }
22830fdc8d8SChris Lattner                     else
22930fdc8d8SChris Lattner                     {
23030fdc8d8SChris Lattner                         result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n",
23130fdc8d8SChris Lattner                                                      reg_name,
23230fdc8d8SChris Lattner                                                      value_str,
23330fdc8d8SChris Lattner                                                      error.AsCString());
23430fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
23530fdc8d8SChris Lattner                     }
23630fdc8d8SChris Lattner                 }
23730fdc8d8SChris Lattner                 else
23830fdc8d8SChris Lattner                 {
23930fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name);
24030fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
24130fdc8d8SChris Lattner                 }
24230fdc8d8SChris Lattner             }
24330fdc8d8SChris Lattner         }
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     }
25130fdc8d8SChris Lattner };
25230fdc8d8SChris Lattner 
25330fdc8d8SChris Lattner 
25430fdc8d8SChris Lattner //----------------------------------------------------------------------
25530fdc8d8SChris Lattner // CommandObjectRegister constructor
25630fdc8d8SChris Lattner //----------------------------------------------------------------------
2576611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) :
258a7015092SGreg Clayton     CommandObjectMultiword (interpreter,
259a7015092SGreg Clayton                             "register",
2603f4c09c1SCaroline Tice                             "A set of commands to access thread registers.",
26130fdc8d8SChris Lattner                             "register [read|write] ...")
26230fdc8d8SChris Lattner {
263a7015092SGreg Clayton     LoadSubCommand ("read",  CommandObjectSP (new CommandObjectRegisterRead (interpreter)));
264a7015092SGreg Clayton     LoadSubCommand ("write", CommandObjectSP (new CommandObjectRegisterWrite (interpreter)));
26530fdc8d8SChris Lattner }
26630fdc8d8SChris Lattner 
26730fdc8d8SChris Lattner 
26830fdc8d8SChris Lattner //----------------------------------------------------------------------
26930fdc8d8SChris Lattner // Destructor
27030fdc8d8SChris Lattner //----------------------------------------------------------------------
27130fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister()
27230fdc8d8SChris Lattner {
27330fdc8d8SChris Lattner }
274