1 //===-- DumpRegisterValue.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 "lldb/Core/DumpRegisterValue.h"
10 #include "lldb/Core/DumpDataExtractor.h"
11 #include "lldb/DataFormatters/DumpValueObjectOptions.h"
12 #include "lldb/Target/RegisterFlags.h"
13 #include "lldb/Utility/DataExtractor.h"
14 #include "lldb/Utility/Endian.h"
15 #include "lldb/Utility/RegisterValue.h"
16 #include "lldb/Utility/StreamString.h"
17 #include "lldb/ValueObject/ValueObject.h"
18 #include "lldb/ValueObject/ValueObjectConstResult.h"
19 #include "lldb/lldb-private-types.h"
20 #include "llvm/ADT/bit.h"
25 static void dump_type_value(lldb_private::CompilerType
&fields_type
, T value
,
26 lldb_private::ExecutionContextScope
*exe_scope
,
27 const lldb_private::RegisterInfo
®_info
,
28 lldb_private::Stream
&strm
) {
29 lldb::ByteOrder target_order
= exe_scope
->CalculateProcess()->GetByteOrder();
31 // For the bitfield types we generate, it is expected that the fields are
32 // in what is usually a big endian order. Most significant field first.
33 // This is also clang's internal ordering and the order we want to print
34 // them. On a big endian host this all matches up, for a little endian
35 // host we have to swap the order of the fields before display.
36 if (target_order
== lldb::ByteOrder::eByteOrderLittle
) {
37 value
= reg_info
.flags_type
->ReverseFieldOrder(value
);
40 // Then we need to match the target's endian on a byte level as well.
41 if (lldb_private::endian::InlHostByteOrder() != target_order
)
42 value
= llvm::byteswap(value
);
44 lldb_private::DataExtractor data_extractor
{
45 &value
, sizeof(T
), lldb_private::endian::InlHostByteOrder(), 8};
47 lldb::ValueObjectSP vobj_sp
= lldb_private::ValueObjectConstResult::Create(
48 exe_scope
, fields_type
, lldb_private::ConstString(), data_extractor
);
49 lldb_private::DumpValueObjectOptions dump_options
;
50 lldb_private::DumpValueObjectOptions::ChildPrintingDecider decider
=
51 [](lldb_private::ConstString varname
) {
52 // Unnamed bit-fields are padding that we don't want to show.
53 return varname
.GetLength();
55 dump_options
.SetChildPrintingDecider(decider
).SetHideRootType(true);
57 if (llvm::Error error
= vobj_sp
->Dump(strm
, dump_options
))
58 strm
<< "error: " << toString(std::move(error
));
61 void lldb_private::DumpRegisterValue(const RegisterValue
®_val
, Stream
&s
,
62 const RegisterInfo
®_info
,
63 bool prefix_with_name
,
64 bool prefix_with_alt_name
, Format format
,
65 uint32_t reg_name_right_align_at
,
66 ExecutionContextScope
*exe_scope
,
67 bool print_flags
, TargetSP target_sp
) {
69 if (!reg_val
.GetData(data
))
72 bool name_printed
= false;
73 // For simplicity, alignment of the register name printing applies only in
74 // the most common case where:
76 // prefix_with_name^prefix_with_alt_name is true
78 StreamString format_string
;
79 if (reg_name_right_align_at
&& (prefix_with_name
^ prefix_with_alt_name
))
80 format_string
.Printf("%%%us", reg_name_right_align_at
);
82 format_string
.Printf("%%s");
83 std::string fmt
= std::string(format_string
.GetString());
84 if (prefix_with_name
) {
86 s
.Printf(fmt
.c_str(), reg_info
.name
);
88 } else if (reg_info
.alt_name
) {
89 s
.Printf(fmt
.c_str(), reg_info
.alt_name
);
90 prefix_with_alt_name
= false;
94 if (prefix_with_alt_name
) {
97 if (reg_info
.alt_name
) {
98 s
.Printf(fmt
.c_str(), reg_info
.alt_name
);
100 } else if (!name_printed
) {
101 // No alternate name but we were asked to display a name, so show the
103 s
.Printf(fmt
.c_str(), reg_info
.name
);
110 if (format
== eFormatDefault
)
111 format
= reg_info
.format
;
113 DumpDataExtractor(data
, &s
,
114 0, // Offset in "data"
115 format
, // Format to use when dumping
116 reg_info
.byte_size
, // item_byte_size
118 UINT32_MAX
, // num_per_line
119 LLDB_INVALID_ADDRESS
, // base_addr
121 0, // item_bit_offset
124 if (!print_flags
|| !reg_info
.flags_type
|| !exe_scope
|| !target_sp
||
125 (reg_info
.byte_size
!= 4 && reg_info
.byte_size
!= 8))
128 CompilerType fields_type
= target_sp
->GetRegisterType(
129 reg_info
.name
, *reg_info
.flags_type
, reg_info
.byte_size
);
131 // Use a new stream so we can remove a trailing newline later.
132 StreamString fields_stream
;
134 if (reg_info
.byte_size
== 4) {
135 dump_type_value(fields_type
, reg_val
.GetAsUInt32(), exe_scope
, reg_info
,
138 dump_type_value(fields_type
, reg_val
.GetAsUInt64(), exe_scope
, reg_info
,
142 // Registers are indented like:
143 // (lldb) register read foo
145 // So we need to indent to match that.
147 // First drop the extra newline that the value printer added. The register
148 // command will add one itself.
149 llvm::StringRef fields_str
= fields_stream
.GetString().drop_back();
151 // End the line that contains " foo = 0x12345678".
154 // Then split the value lines and indent each one.
156 while (fields_str
.size()) {
157 std::pair
<llvm::StringRef
, llvm::StringRef
> split
= fields_str
.split('\n');
158 fields_str
= split
.second
;
159 // Indent as far as the register name did.
160 s
.Printf(fmt
.c_str(), "");
162 // Lines after the first won't have " = " so compensate for that.
169 // On the last line we don't want a newline because the command will add
171 if (fields_str
.size())