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",
37405fe67fSCaroline Tice                        "Dump the contents of one or more register values from the current frame.  If no register is specified, dumps them all.",
38405fe67fSCaroline Tice                        //"register read [<reg-name1> [<reg-name2> [...]]]",
39405fe67fSCaroline Tice                        NULL,
4030fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
4130fdc8d8SChris Lattner     {
42405fe67fSCaroline Tice         CommandArgumentEntry arg;
43405fe67fSCaroline Tice         CommandArgumentData register_arg;
44405fe67fSCaroline Tice 
45405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
46405fe67fSCaroline Tice         register_arg.arg_type = eArgTypeRegisterName;
47405fe67fSCaroline Tice         register_arg.arg_repetition = eArgRepeatStar;
48405fe67fSCaroline Tice 
49405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
50405fe67fSCaroline Tice         arg.push_back (register_arg);
51405fe67fSCaroline Tice 
52405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
53405fe67fSCaroline 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     {
68*85e8b814SJim Ingham         Stream &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.",
159405fe67fSCaroline Tice                        //"register write <reg-name> <value>",
160405fe67fSCaroline Tice                        NULL,
16130fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
16230fdc8d8SChris Lattner     {
163405fe67fSCaroline Tice         CommandArgumentEntry arg1;
164405fe67fSCaroline Tice         CommandArgumentEntry arg2;
165405fe67fSCaroline Tice         CommandArgumentData register_arg;
166405fe67fSCaroline Tice         CommandArgumentData value_arg;
167405fe67fSCaroline Tice 
168405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
169405fe67fSCaroline Tice         register_arg.arg_type = eArgTypeRegisterName;
170405fe67fSCaroline Tice         register_arg.arg_repetition = eArgRepeatPlain;
171405fe67fSCaroline Tice 
172405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
173405fe67fSCaroline Tice         arg1.push_back (register_arg);
174405fe67fSCaroline Tice 
175405fe67fSCaroline Tice         // Define the first (and only) variant of this arg.
176405fe67fSCaroline Tice         value_arg.arg_type = eArgTypeValue;
177405fe67fSCaroline Tice         value_arg.arg_repetition = eArgRepeatPlain;
178405fe67fSCaroline Tice 
179405fe67fSCaroline Tice         // There is only one variant this argument could be; put it into the argument entry.
180405fe67fSCaroline Tice         arg2.push_back (value_arg);
181405fe67fSCaroline Tice 
182405fe67fSCaroline Tice         // Push the data for the first argument into the m_arguments vector.
183405fe67fSCaroline Tice         m_arguments.push_back (arg1);
184405fe67fSCaroline 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