1 //===-- CommandObjectRegister.cpp -----------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "CommandObjectRegister.h"
10 #include "lldb/Core/Debugger.h"
11 #include "lldb/Core/DumpRegisterInfo.h"
12 #include "lldb/Core/DumpRegisterValue.h"
13 #include "lldb/Host/OptionParser.h"
14 #include "lldb/Interpreter/CommandInterpreter.h"
15 #include "lldb/Interpreter/CommandOptionArgumentTable.h"
16 #include "lldb/Interpreter/CommandReturnObject.h"
17 #include "lldb/Interpreter/OptionGroupFormat.h"
18 #include "lldb/Interpreter/OptionValueArray.h"
19 #include "lldb/Interpreter/OptionValueBoolean.h"
20 #include "lldb/Interpreter/OptionValueUInt64.h"
21 #include "lldb/Interpreter/Options.h"
22 #include "lldb/Target/ExecutionContext.h"
23 #include "lldb/Target/Process.h"
24 #include "lldb/Target/RegisterContext.h"
25 #include "lldb/Target/SectionLoadList.h"
26 #include "lldb/Target/Thread.h"
27 #include "lldb/Utility/Args.h"
28 #include "lldb/Utility/DataExtractor.h"
29 #include "lldb/Utility/RegisterValue.h"
30 #include "llvm/Support/Errno.h"
33 using namespace lldb_private
;
36 #define LLDB_OPTIONS_register_read
37 #include "CommandOptions.inc"
39 class CommandObjectRegisterRead
: public CommandObjectParsed
{
41 CommandObjectRegisterRead(CommandInterpreter
&interpreter
)
42 : CommandObjectParsed(
43 interpreter
, "register read",
44 "Dump the contents of one or more register values from the current "
45 "frame. If no register is specified, dumps them all.",
47 eCommandRequiresFrame
| eCommandRequiresRegContext
|
48 eCommandProcessMustBeLaunched
| eCommandProcessMustBePaused
),
49 m_format_options(eFormatDefault
, UINT64_MAX
, UINT64_MAX
,
50 {{CommandArgumentType::eArgTypeFormat
,
51 "Specify a format to be used for display. If this "
52 "is set, register fields will not be displayed."}}) {
53 AddSimpleArgumentList(eArgTypeRegisterName
, eArgRepeatStar
);
56 m_option_group
.Append(&m_format_options
,
57 OptionGroupFormat::OPTION_GROUP_FORMAT
|
58 OptionGroupFormat::OPTION_GROUP_GDB_FMT
,
60 m_option_group
.Append(&m_command_options
);
61 m_option_group
.Finalize();
64 ~CommandObjectRegisterRead() override
= default;
67 HandleArgumentCompletion(CompletionRequest
&request
,
68 OptionElementVector
&opt_element_vector
) override
{
69 if (!m_exe_ctx
.HasProcessScope())
71 CommandObject::HandleArgumentCompletion(request
, opt_element_vector
);
74 Options
*GetOptions() override
{ return &m_option_group
; }
76 bool DumpRegister(const ExecutionContext
&exe_ctx
, Stream
&strm
,
77 RegisterContext
®_ctx
, const RegisterInfo
®_info
,
79 RegisterValue reg_value
;
80 if (!reg_ctx
.ReadRegister(®_info
, reg_value
))
85 bool prefix_with_altname
= (bool)m_command_options
.alternate_name
;
86 bool prefix_with_name
= !prefix_with_altname
;
87 DumpRegisterValue(reg_value
, strm
, reg_info
, prefix_with_name
,
88 prefix_with_altname
, m_format_options
.GetFormat(), 8,
89 exe_ctx
.GetBestExecutionContextScope(), print_flags
,
90 exe_ctx
.GetTargetSP());
91 if ((reg_info
.encoding
== eEncodingUint
) ||
92 (reg_info
.encoding
== eEncodingSint
)) {
93 Process
*process
= exe_ctx
.GetProcessPtr();
94 if (process
&& reg_info
.byte_size
== process
->GetAddressByteSize()) {
95 addr_t reg_addr
= reg_value
.GetAsUInt64(LLDB_INVALID_ADDRESS
);
96 if (reg_addr
!= LLDB_INVALID_ADDRESS
) {
98 if (exe_ctx
.GetTargetRef().GetSectionLoadList().ResolveLoadAddress(
99 reg_addr
, so_reg_addr
)) {
100 strm
.PutCString(" ");
101 so_reg_addr
.Dump(&strm
, exe_ctx
.GetBestExecutionContextScope(),
102 Address::DumpStyleResolvedDescription
);
111 bool DumpRegisterSet(const ExecutionContext
&exe_ctx
, Stream
&strm
,
112 RegisterContext
*reg_ctx
, size_t set_idx
,
113 bool primitive_only
= false) {
114 uint32_t unavailable_count
= 0;
115 uint32_t available_count
= 0;
118 return false; // thread has no registers (i.e. core files are corrupt,
119 // incomplete crash logs...)
121 const RegisterSet
*const reg_set
= reg_ctx
->GetRegisterSet(set_idx
);
123 strm
.Printf("%s:\n", (reg_set
->name
? reg_set
->name
: "unknown"));
125 const size_t num_registers
= reg_set
->num_registers
;
126 for (size_t reg_idx
= 0; reg_idx
< num_registers
; ++reg_idx
) {
127 const uint32_t reg
= reg_set
->registers
[reg_idx
];
128 const RegisterInfo
*reg_info
= reg_ctx
->GetRegisterInfoAtIndex(reg
);
129 // Skip the dumping of derived register if primitive_only is true.
130 if (primitive_only
&& reg_info
&& reg_info
->value_regs
)
133 if (reg_info
&& DumpRegister(exe_ctx
, strm
, *reg_ctx
, *reg_info
,
134 /*print_flags=*/false))
140 if (unavailable_count
) {
142 strm
.Printf("%u registers were unavailable.\n", unavailable_count
);
146 return available_count
> 0;
150 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
151 Stream
&strm
= result
.GetOutputStream();
152 RegisterContext
*reg_ctx
= m_exe_ctx
.GetRegisterContext();
154 if (command
.GetArgumentCount() == 0) {
157 size_t num_register_sets
= 1;
158 const size_t set_array_size
= m_command_options
.set_indexes
.GetSize();
159 if (set_array_size
> 0) {
160 for (size_t i
= 0; i
< set_array_size
; ++i
) {
162 m_command_options
.set_indexes
[i
]->GetValueAs
<uint64_t>().value_or(
164 if (set_idx
< reg_ctx
->GetRegisterSetCount()) {
165 if (!DumpRegisterSet(m_exe_ctx
, strm
, reg_ctx
, set_idx
)) {
167 result
.AppendErrorWithFormatv("register read failed: {0}\n",
168 llvm::sys::StrError());
170 result
.AppendError("unknown error while reading registers.\n");
174 result
.AppendErrorWithFormat(
175 "invalid register set index: %" PRIu64
"\n", (uint64_t)set_idx
);
180 if (m_command_options
.dump_all_sets
)
181 num_register_sets
= reg_ctx
->GetRegisterSetCount();
183 for (set_idx
= 0; set_idx
< num_register_sets
; ++set_idx
) {
184 // When dump_all_sets option is set, dump primitive as well as
185 // derived registers.
186 DumpRegisterSet(m_exe_ctx
, strm
, reg_ctx
, set_idx
,
187 !m_command_options
.dump_all_sets
.GetCurrentValue());
191 if (m_command_options
.dump_all_sets
) {
192 result
.AppendError("the --all option can't be used when registers "
193 "names are supplied as arguments\n");
194 } else if (m_command_options
.set_indexes
.GetSize() > 0) {
195 result
.AppendError("the --set <set> option can't be used when "
196 "registers names are supplied as arguments\n");
198 for (auto &entry
: command
) {
199 // in most LLDB commands we accept $rbx as the name for register RBX
200 // - and here we would reject it and non-existant. we should be more
201 // consistent towards the user and allow them to say reg read $rbx -
202 // internally, however, we should be strict and not allow ourselves
203 // to call our registers $rbx in our own API
204 auto arg_str
= entry
.ref();
205 arg_str
.consume_front("$");
207 if (const RegisterInfo
*reg_info
=
208 reg_ctx
->GetRegisterInfoByName(arg_str
)) {
209 // If they have asked for a specific format don't obscure that by
210 // printing flags afterwards.
212 !m_format_options
.GetFormatValue().OptionWasSet();
213 if (!DumpRegister(m_exe_ctx
, strm
, *reg_ctx
, *reg_info
,
215 strm
.Printf("%-12s = error: unavailable\n", reg_info
->name
);
217 result
.AppendErrorWithFormat("Invalid register name '%s'.\n",
218 arg_str
.str().c_str());
225 class CommandOptions
: public OptionGroup
{
228 : set_indexes(OptionValue::ConvertTypeToMask(OptionValue::eTypeUInt64
)),
229 dump_all_sets(false, false), // Initial and default values are false
230 alternate_name(false, false) {}
232 ~CommandOptions() override
= default;
234 llvm::ArrayRef
<OptionDefinition
> GetDefinitions() override
{
235 return llvm::ArrayRef(g_register_read_options
);
238 void OptionParsingStarting(ExecutionContext
*execution_context
) override
{
240 dump_all_sets
.Clear();
241 alternate_name
.Clear();
244 Status
SetOptionValue(uint32_t option_idx
, llvm::StringRef option_value
,
245 ExecutionContext
*execution_context
) override
{
247 const int short_option
= GetDefinitions()[option_idx
].short_option
;
248 switch (short_option
) {
250 OptionValueSP
value_sp(OptionValueUInt64::Create(option_value
, error
));
252 set_indexes
.AppendValue(value_sp
);
256 // When we don't use OptionValue::SetValueFromCString(const char *) to
257 // set an option value, it won't be marked as being set in the options
258 // so we make a call to let users know the value was set via option
259 dump_all_sets
.SetCurrentValue(true);
260 dump_all_sets
.SetOptionWasSet();
264 // When we don't use OptionValue::SetValueFromCString(const char *) to
265 // set an option value, it won't be marked as being set in the options
266 // so we make a call to let users know the value was set via option
267 alternate_name
.SetCurrentValue(true);
268 dump_all_sets
.SetOptionWasSet();
272 llvm_unreachable("Unimplemented option");
277 // Instance variables to hold the values for command options.
278 OptionValueArray set_indexes
;
279 OptionValueBoolean dump_all_sets
;
280 OptionValueBoolean alternate_name
;
283 OptionGroupOptions m_option_group
;
284 OptionGroupFormat m_format_options
;
285 CommandOptions m_command_options
;
289 class CommandObjectRegisterWrite
: public CommandObjectParsed
{
291 CommandObjectRegisterWrite(CommandInterpreter
&interpreter
)
292 : CommandObjectParsed(interpreter
, "register write",
293 "Modify a single register value.", nullptr,
294 eCommandRequiresFrame
| eCommandRequiresRegContext
|
295 eCommandProcessMustBeLaunched
|
296 eCommandProcessMustBePaused
) {
297 CommandArgumentEntry arg1
;
298 CommandArgumentEntry arg2
;
299 CommandArgumentData register_arg
;
300 CommandArgumentData value_arg
;
302 // Define the first (and only) variant of this arg.
303 register_arg
.arg_type
= eArgTypeRegisterName
;
304 register_arg
.arg_repetition
= eArgRepeatPlain
;
306 // There is only one variant this argument could be; put it into the
308 arg1
.push_back(register_arg
);
310 // Define the first (and only) variant of this arg.
311 value_arg
.arg_type
= eArgTypeValue
;
312 value_arg
.arg_repetition
= eArgRepeatPlain
;
314 // There is only one variant this argument could be; put it into the
316 arg2
.push_back(value_arg
);
318 // Push the data for the first argument into the m_arguments vector.
319 m_arguments
.push_back(arg1
);
320 m_arguments
.push_back(arg2
);
323 ~CommandObjectRegisterWrite() override
= default;
326 HandleArgumentCompletion(CompletionRequest
&request
,
327 OptionElementVector
&opt_element_vector
) override
{
328 if (!m_exe_ctx
.HasProcessScope() || request
.GetCursorIndex() != 0)
331 lldb_private::CommandCompletions::InvokeCommonCompletionCallbacks(
332 GetCommandInterpreter(), lldb::eRegisterCompletion
, request
, nullptr);
336 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
337 DataExtractor reg_data
;
338 RegisterContext
*reg_ctx
= m_exe_ctx
.GetRegisterContext();
340 if (command
.GetArgumentCount() != 2) {
342 "register write takes exactly 2 arguments: <reg-name> <value>");
344 auto reg_name
= command
[0].ref();
345 auto value_str
= command
[1].ref();
347 // in most LLDB commands we accept $rbx as the name for register RBX -
348 // and here we would reject it and non-existant. we should be more
349 // consistent towards the user and allow them to say reg write $rbx -
350 // internally, however, we should be strict and not allow ourselves to
351 // call our registers $rbx in our own API
352 reg_name
.consume_front("$");
354 const RegisterInfo
*reg_info
= reg_ctx
->GetRegisterInfoByName(reg_name
);
357 RegisterValue reg_value
;
359 Status
error(reg_value
.SetValueFromString(reg_info
, value_str
));
360 if (error
.Success()) {
361 if (reg_ctx
->WriteRegister(reg_info
, reg_value
)) {
362 // Toss all frames and anything else in the thread after a register
364 m_exe_ctx
.GetThreadRef().Flush();
365 result
.SetStatus(eReturnStatusSuccessFinishNoResult
);
369 if (error
.AsCString()) {
370 result
.AppendErrorWithFormat(
371 "Failed to write register '%s' with value '%s': %s\n",
372 reg_name
.str().c_str(), value_str
.str().c_str(),
375 result
.AppendErrorWithFormat(
376 "Failed to write register '%s' with value '%s'",
377 reg_name
.str().c_str(), value_str
.str().c_str());
380 result
.AppendErrorWithFormat("Register not found for '%s'.\n",
381 reg_name
.str().c_str());
388 class CommandObjectRegisterInfo
: public CommandObjectParsed
{
390 CommandObjectRegisterInfo(CommandInterpreter
&interpreter
)
391 : CommandObjectParsed(interpreter
, "register info",
392 "View information about a register.", nullptr,
393 eCommandRequiresFrame
| eCommandRequiresRegContext
|
394 eCommandProcessMustBeLaunched
|
395 eCommandProcessMustBePaused
) {
397 Name The name lldb uses for the register, optionally with an alias.
398 Size The size of the register in bytes and again in bits.
399 Invalidates (*) The registers that would be changed if you wrote this
400 register. For example, writing to a narrower alias of a wider
401 register would change the value of the wider register.
402 Read from (*) The registers that the value of this register is constructed
403 from. For example, a narrower alias of a wider register will be
404 read from the wider register.
405 In sets (*) The register sets that contain this register. For example the
406 PC will be in the "General Purpose Register
" set.
407 Fields (*) A table of the names and bit positions of the values contained
410 Fields marked with (*) may not always be present. Some information may be
411 different for the same register when connected to different debug servers.)");
413 AddSimpleArgumentList(eArgTypeRegisterName
);
416 ~CommandObjectRegisterInfo() override
= default;
419 HandleArgumentCompletion(CompletionRequest
&request
,
420 OptionElementVector
&opt_element_vector
) override
{
421 if (!m_exe_ctx
.HasProcessScope() || request
.GetCursorIndex() != 0)
423 CommandObject::HandleArgumentCompletion(request
, opt_element_vector
);
427 void DoExecute(Args
&command
, CommandReturnObject
&result
) override
{
428 if (command
.GetArgumentCount() != 1) {
429 result
.AppendError("register info takes exactly 1 argument: <reg-name>");
433 llvm::StringRef reg_name
= command
[0].ref();
434 RegisterContext
*reg_ctx
= m_exe_ctx
.GetRegisterContext();
435 const RegisterInfo
*reg_info
= reg_ctx
->GetRegisterInfoByName(reg_name
);
438 result
.GetOutputStream(), *reg_ctx
, *reg_info
,
439 GetCommandInterpreter().GetDebugger().GetTerminalWidth());
440 result
.SetStatus(eReturnStatusSuccessFinishResult
);
442 result
.AppendErrorWithFormat("No register found with name '%s'.\n",
443 reg_name
.str().c_str());
447 // CommandObjectRegister constructor
448 CommandObjectRegister::CommandObjectRegister(CommandInterpreter
&interpreter
)
449 : CommandObjectMultiword(interpreter
, "register",
450 "Commands to access registers for the current "
451 "thread and stack frame.",
452 "register [read|write|info] ...") {
453 LoadSubCommand("read",
454 CommandObjectSP(new CommandObjectRegisterRead(interpreter
)));
455 LoadSubCommand("write",
456 CommandObjectSP(new CommandObjectRegisterWrite(interpreter
)));
457 LoadSubCommand("info",
458 CommandObjectSP(new CommandObjectRegisterInfo(interpreter
)));
461 CommandObjectRegister::~CommandObjectRegister() = default;