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:
3430fdc8d8SChris Lattner     CommandObjectRegisterRead () :
3530fdc8d8SChris Lattner         CommandObject ("register read",
3630fdc8d8SChris Lattner                        "Dump the one or more register values from the current frame.",
3730fdc8d8SChris Lattner                        "register read [<reg-name1> [<reg-name2> [...]]]",
3830fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
3930fdc8d8SChris Lattner     {
4030fdc8d8SChris Lattner     }
4130fdc8d8SChris Lattner 
4230fdc8d8SChris Lattner     virtual
4330fdc8d8SChris Lattner     ~CommandObjectRegisterRead ()
4430fdc8d8SChris Lattner     {
4530fdc8d8SChris Lattner     }
4630fdc8d8SChris Lattner 
4730fdc8d8SChris Lattner     virtual bool
486611103cSGreg Clayton     Execute
496611103cSGreg Clayton     (
506611103cSGreg Clayton         CommandInterpreter &interpreter,
516611103cSGreg Clayton         Args& command,
526611103cSGreg Clayton         CommandReturnObject &result
536611103cSGreg Clayton     )
5430fdc8d8SChris Lattner     {
5530fdc8d8SChris Lattner         StreamString &output_stream = result.GetOutputStream();
5630fdc8d8SChris Lattner         DataExtractor reg_data;
576611103cSGreg Clayton         ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext());
5830fdc8d8SChris Lattner         RegisterContext *reg_context = exe_ctx.GetRegisterContext ();
5930fdc8d8SChris Lattner 
6030fdc8d8SChris Lattner         if (reg_context)
6130fdc8d8SChris Lattner         {
6230fdc8d8SChris Lattner             const RegisterInfo *reg_info = NULL;
6330fdc8d8SChris Lattner             if (command.GetArgumentCount() == 0)
6430fdc8d8SChris Lattner             {
6530fdc8d8SChris Lattner                 uint32_t set_idx;
6630fdc8d8SChris Lattner                 const uint32_t num_register_sets = reg_context->GetRegisterSetCount();
6730fdc8d8SChris Lattner                 for (set_idx = 0; set_idx < num_register_sets; ++set_idx)
6830fdc8d8SChris Lattner                 {
6930fdc8d8SChris Lattner                     uint32_t unavailable_count = 0;
7030fdc8d8SChris Lattner                     const RegisterSet * const reg_set = reg_context->GetRegisterSet(set_idx);
7130fdc8d8SChris Lattner                     output_stream.Printf ("%s:\n", reg_set->name);
7230fdc8d8SChris Lattner                     output_stream.IndentMore ();
7330fdc8d8SChris Lattner                     const uint32_t num_registers = reg_set->num_registers;
7430fdc8d8SChris Lattner                     for (uint32_t reg_idx = 0; reg_idx < num_registers; ++reg_idx)
7530fdc8d8SChris Lattner                     {
7630fdc8d8SChris Lattner                         uint32_t reg = reg_set->registers[reg_idx];
7730fdc8d8SChris Lattner                         reg_info = reg_context->GetRegisterInfoAtIndex(reg);
7830fdc8d8SChris Lattner                         if (reg_context->ReadRegisterBytes(reg, reg_data))
7930fdc8d8SChris Lattner                         {
8030fdc8d8SChris Lattner                             output_stream.Indent ();
8130fdc8d8SChris Lattner                             output_stream.Printf ("%-12s = ", reg_info ? reg_info->name : "<INVALID REGINFO>");
8230fdc8d8SChris Lattner                             reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
8330fdc8d8SChris Lattner                             output_stream.EOL();
8430fdc8d8SChris Lattner                         }
8530fdc8d8SChris Lattner                         else
8630fdc8d8SChris Lattner                         {
8730fdc8d8SChris Lattner                             ++unavailable_count;
8830fdc8d8SChris Lattner                         }
8930fdc8d8SChris Lattner                     }
9030fdc8d8SChris Lattner                     if (unavailable_count)
9130fdc8d8SChris Lattner                     {
9230fdc8d8SChris Lattner                         output_stream.Indent ();
9330fdc8d8SChris Lattner                         output_stream.Printf("%u registers were unavailable.\n", unavailable_count);
9430fdc8d8SChris Lattner                     }
9530fdc8d8SChris Lattner                     output_stream.IndentLess ();
9630fdc8d8SChris Lattner                     output_stream.EOL();
9730fdc8d8SChris Lattner                 }
9830fdc8d8SChris Lattner             }
9930fdc8d8SChris Lattner             else
10030fdc8d8SChris Lattner             {
10130fdc8d8SChris Lattner                 const char *arg_cstr;
10230fdc8d8SChris Lattner                 for (int arg_idx = 0; (arg_cstr = command.GetArgumentAtIndex(arg_idx)) != NULL; ++arg_idx)
10330fdc8d8SChris Lattner                 {
10430fdc8d8SChris Lattner                     reg_info = reg_context->GetRegisterInfoByName(arg_cstr);
10530fdc8d8SChris Lattner 
10630fdc8d8SChris Lattner                     if (reg_info)
10730fdc8d8SChris Lattner                     {
10830fdc8d8SChris Lattner                         output_stream.Printf("%-12s = ", reg_info->name);
10930fdc8d8SChris Lattner                         if (reg_context->ReadRegisterBytes(reg_info->reg, reg_data))
11030fdc8d8SChris Lattner                         {
11130fdc8d8SChris Lattner                             reg_data.Dump(&output_stream, 0, reg_info->format, reg_info->byte_size, 1, UINT32_MAX, LLDB_INVALID_ADDRESS, 0, 0);
11230fdc8d8SChris Lattner                         }
11330fdc8d8SChris Lattner                         else
11430fdc8d8SChris Lattner                         {
11530fdc8d8SChris Lattner                             output_stream.PutCString ("error: unavailable");
11630fdc8d8SChris Lattner                         }
11730fdc8d8SChris Lattner                         output_stream.EOL();
11830fdc8d8SChris Lattner                     }
11930fdc8d8SChris Lattner                     else
12030fdc8d8SChris Lattner                     {
12130fdc8d8SChris Lattner                         result.AppendErrorWithFormat ("Invalid register name '%s'.\n", arg_cstr);
12230fdc8d8SChris Lattner                     }
12330fdc8d8SChris Lattner                 }
12430fdc8d8SChris Lattner             }
12530fdc8d8SChris Lattner         }
12630fdc8d8SChris Lattner         else
12730fdc8d8SChris Lattner         {
12830fdc8d8SChris Lattner             result.AppendError ("no current frame");
12930fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
13030fdc8d8SChris Lattner         }
13130fdc8d8SChris Lattner         return result.Succeeded();
13230fdc8d8SChris Lattner     }
13330fdc8d8SChris Lattner };
13430fdc8d8SChris Lattner 
13530fdc8d8SChris Lattner 
13630fdc8d8SChris Lattner //----------------------------------------------------------------------
13730fdc8d8SChris Lattner // "register write"
13830fdc8d8SChris Lattner //----------------------------------------------------------------------
13930fdc8d8SChris Lattner class CommandObjectRegisterWrite : public CommandObject
14030fdc8d8SChris Lattner {
14130fdc8d8SChris Lattner public:
14230fdc8d8SChris Lattner     CommandObjectRegisterWrite () :
14330fdc8d8SChris Lattner         CommandObject ("register write",
14430fdc8d8SChris Lattner                        "Modify a single register value.",
14530fdc8d8SChris Lattner                        "register write <reg-name> <value>",
14630fdc8d8SChris Lattner                        eFlagProcessMustBeLaunched | eFlagProcessMustBePaused)
14730fdc8d8SChris Lattner     {
14830fdc8d8SChris Lattner     }
14930fdc8d8SChris Lattner 
15030fdc8d8SChris Lattner     virtual
15130fdc8d8SChris Lattner     ~CommandObjectRegisterWrite ()
15230fdc8d8SChris Lattner     {
15330fdc8d8SChris Lattner     }
15430fdc8d8SChris Lattner 
15530fdc8d8SChris Lattner     virtual bool
1566611103cSGreg Clayton     Execute
1576611103cSGreg Clayton     (
1586611103cSGreg Clayton         CommandInterpreter &interpreter,
1596611103cSGreg Clayton         Args& command,
1606611103cSGreg Clayton         CommandReturnObject &result
1616611103cSGreg Clayton     )
16230fdc8d8SChris Lattner     {
16330fdc8d8SChris Lattner         DataExtractor reg_data;
1646611103cSGreg Clayton         ExecutionContext exe_ctx(interpreter.GetDebugger().GetExecutionContext());
16530fdc8d8SChris Lattner         RegisterContext *reg_context = exe_ctx.GetRegisterContext ();
16630fdc8d8SChris Lattner 
16730fdc8d8SChris Lattner         if (reg_context)
16830fdc8d8SChris Lattner         {
16930fdc8d8SChris Lattner             if (command.GetArgumentCount() != 2)
17030fdc8d8SChris Lattner             {
17130fdc8d8SChris Lattner                 result.AppendError ("register write takes exactly 2 arguments: <reg-name> <value>");
17230fdc8d8SChris Lattner                 result.SetStatus (eReturnStatusFailed);
17330fdc8d8SChris Lattner             }
17430fdc8d8SChris Lattner             else
17530fdc8d8SChris Lattner             {
17630fdc8d8SChris Lattner                 const char *reg_name = command.GetArgumentAtIndex(0);
17730fdc8d8SChris Lattner                 const char *value_str = command.GetArgumentAtIndex(1);
17830fdc8d8SChris Lattner                 const RegisterInfo *reg_info = reg_context->GetRegisterInfoByName(reg_name);
17930fdc8d8SChris Lattner 
18030fdc8d8SChris Lattner                 if (reg_info)
18130fdc8d8SChris Lattner                 {
18230fdc8d8SChris Lattner                     Scalar scalar;
18330fdc8d8SChris Lattner                     Error error(scalar.SetValueFromCString (value_str, reg_info->encoding, reg_info->byte_size));
18430fdc8d8SChris Lattner                     if (error.Success())
18530fdc8d8SChris Lattner                     {
18630fdc8d8SChris Lattner                         if (reg_context->WriteRegisterValue(reg_info->reg, scalar))
18730fdc8d8SChris Lattner                         {
18830fdc8d8SChris Lattner                             result.SetStatus (eReturnStatusSuccessFinishNoResult);
18930fdc8d8SChris Lattner                             return true;
19030fdc8d8SChris Lattner                         }
19130fdc8d8SChris Lattner                     }
19230fdc8d8SChris Lattner                     else
19330fdc8d8SChris Lattner                     {
19430fdc8d8SChris Lattner                         result.AppendErrorWithFormat ("Failed to write register '%s' with value '%s': %s\n",
19530fdc8d8SChris Lattner                                                      reg_name,
19630fdc8d8SChris Lattner                                                      value_str,
19730fdc8d8SChris Lattner                                                      error.AsCString());
19830fdc8d8SChris Lattner                         result.SetStatus (eReturnStatusFailed);
19930fdc8d8SChris Lattner                     }
20030fdc8d8SChris Lattner                 }
20130fdc8d8SChris Lattner                 else
20230fdc8d8SChris Lattner                 {
20330fdc8d8SChris Lattner                     result.AppendErrorWithFormat ("Register not found for '%s'.\n", reg_name);
20430fdc8d8SChris Lattner                     result.SetStatus (eReturnStatusFailed);
20530fdc8d8SChris Lattner                 }
20630fdc8d8SChris Lattner             }
20730fdc8d8SChris Lattner         }
20830fdc8d8SChris Lattner         else
20930fdc8d8SChris Lattner         {
21030fdc8d8SChris Lattner             result.AppendError ("no current frame");
21130fdc8d8SChris Lattner             result.SetStatus (eReturnStatusFailed);
21230fdc8d8SChris Lattner         }
21330fdc8d8SChris Lattner         return result.Succeeded();
21430fdc8d8SChris Lattner     }
21530fdc8d8SChris Lattner };
21630fdc8d8SChris Lattner 
21730fdc8d8SChris Lattner 
21830fdc8d8SChris Lattner //----------------------------------------------------------------------
21930fdc8d8SChris Lattner // CommandObjectRegister constructor
22030fdc8d8SChris Lattner //----------------------------------------------------------------------
2216611103cSGreg Clayton CommandObjectRegister::CommandObjectRegister(CommandInterpreter &interpreter) :
22230fdc8d8SChris Lattner     CommandObjectMultiword ("register",
223*3f4c09c1SCaroline Tice                             "A set of commands to access thread registers.",
22430fdc8d8SChris Lattner                             "register [read|write] ...")
22530fdc8d8SChris Lattner {
2266611103cSGreg Clayton     LoadSubCommand (interpreter, "read",  CommandObjectSP (new CommandObjectRegisterRead ()));
2276611103cSGreg Clayton     LoadSubCommand (interpreter, "write", CommandObjectSP (new CommandObjectRegisterWrite ()));
22830fdc8d8SChris Lattner }
22930fdc8d8SChris Lattner 
23030fdc8d8SChris Lattner 
23130fdc8d8SChris Lattner //----------------------------------------------------------------------
23230fdc8d8SChris Lattner // Destructor
23330fdc8d8SChris Lattner //----------------------------------------------------------------------
23430fdc8d8SChris Lattner CommandObjectRegister::~CommandObjectRegister()
23530fdc8d8SChris Lattner {
23630fdc8d8SChris Lattner }
237