1 //===-- DWARFExpression.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 "llvm/DebugInfo/DWARF/DWARFExpression.h"
10 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
11 #include "llvm/BinaryFormat/Dwarf.h"
12 #include "llvm/MC/MCRegisterInfo.h"
13 #include "llvm/Support/Format.h"
19 using namespace dwarf
;
23 typedef std::vector
<DWARFExpression::Operation::Description
> DescVector
;
25 static DescVector
getDescriptions() {
26 DescVector Descriptions
;
27 typedef DWARFExpression::Operation Op
;
28 typedef Op::Description Desc
;
30 Descriptions
.resize(0xff);
31 Descriptions
[DW_OP_addr
] = Desc(Op::Dwarf2
, Op::SizeAddr
);
32 Descriptions
[DW_OP_deref
] = Desc(Op::Dwarf2
);
33 Descriptions
[DW_OP_const1u
] = Desc(Op::Dwarf2
, Op::Size1
);
34 Descriptions
[DW_OP_const1s
] = Desc(Op::Dwarf2
, Op::SignedSize1
);
35 Descriptions
[DW_OP_const2u
] = Desc(Op::Dwarf2
, Op::Size2
);
36 Descriptions
[DW_OP_const2s
] = Desc(Op::Dwarf2
, Op::SignedSize2
);
37 Descriptions
[DW_OP_const4u
] = Desc(Op::Dwarf2
, Op::Size4
);
38 Descriptions
[DW_OP_const4s
] = Desc(Op::Dwarf2
, Op::SignedSize4
);
39 Descriptions
[DW_OP_const8u
] = Desc(Op::Dwarf2
, Op::Size8
);
40 Descriptions
[DW_OP_const8s
] = Desc(Op::Dwarf2
, Op::SignedSize8
);
41 Descriptions
[DW_OP_constu
] = Desc(Op::Dwarf2
, Op::SizeLEB
);
42 Descriptions
[DW_OP_consts
] = Desc(Op::Dwarf2
, Op::SignedSizeLEB
);
43 Descriptions
[DW_OP_dup
] = Desc(Op::Dwarf2
);
44 Descriptions
[DW_OP_drop
] = Desc(Op::Dwarf2
);
45 Descriptions
[DW_OP_over
] = Desc(Op::Dwarf2
);
46 Descriptions
[DW_OP_pick
] = Desc(Op::Dwarf2
, Op::Size1
);
47 Descriptions
[DW_OP_swap
] = Desc(Op::Dwarf2
);
48 Descriptions
[DW_OP_rot
] = Desc(Op::Dwarf2
);
49 Descriptions
[DW_OP_xderef
] = Desc(Op::Dwarf2
);
50 Descriptions
[DW_OP_abs
] = Desc(Op::Dwarf2
);
51 Descriptions
[DW_OP_and
] = Desc(Op::Dwarf2
);
52 Descriptions
[DW_OP_div
] = Desc(Op::Dwarf2
);
53 Descriptions
[DW_OP_minus
] = Desc(Op::Dwarf2
);
54 Descriptions
[DW_OP_mod
] = Desc(Op::Dwarf2
);
55 Descriptions
[DW_OP_mul
] = Desc(Op::Dwarf2
);
56 Descriptions
[DW_OP_neg
] = Desc(Op::Dwarf2
);
57 Descriptions
[DW_OP_not
] = Desc(Op::Dwarf2
);
58 Descriptions
[DW_OP_or
] = Desc(Op::Dwarf2
);
59 Descriptions
[DW_OP_plus
] = Desc(Op::Dwarf2
);
60 Descriptions
[DW_OP_plus_uconst
] = Desc(Op::Dwarf2
, Op::SizeLEB
);
61 Descriptions
[DW_OP_shl
] = Desc(Op::Dwarf2
);
62 Descriptions
[DW_OP_shr
] = Desc(Op::Dwarf2
);
63 Descriptions
[DW_OP_shra
] = Desc(Op::Dwarf2
);
64 Descriptions
[DW_OP_xor
] = Desc(Op::Dwarf2
);
65 Descriptions
[DW_OP_skip
] = Desc(Op::Dwarf2
, Op::SignedSize2
);
66 Descriptions
[DW_OP_bra
] = Desc(Op::Dwarf2
, Op::SignedSize2
);
67 Descriptions
[DW_OP_eq
] = Desc(Op::Dwarf2
);
68 Descriptions
[DW_OP_ge
] = Desc(Op::Dwarf2
);
69 Descriptions
[DW_OP_gt
] = Desc(Op::Dwarf2
);
70 Descriptions
[DW_OP_le
] = Desc(Op::Dwarf2
);
71 Descriptions
[DW_OP_lt
] = Desc(Op::Dwarf2
);
72 Descriptions
[DW_OP_ne
] = Desc(Op::Dwarf2
);
73 for (uint16_t LA
= DW_OP_lit0
; LA
<= DW_OP_lit31
; ++LA
)
74 Descriptions
[LA
] = Desc(Op::Dwarf2
);
75 for (uint16_t LA
= DW_OP_reg0
; LA
<= DW_OP_reg31
; ++LA
)
76 Descriptions
[LA
] = Desc(Op::Dwarf2
);
77 for (uint16_t LA
= DW_OP_breg0
; LA
<= DW_OP_breg31
; ++LA
)
78 Descriptions
[LA
] = Desc(Op::Dwarf2
, Op::SignedSizeLEB
);
79 Descriptions
[DW_OP_regx
] = Desc(Op::Dwarf2
, Op::SizeLEB
);
80 Descriptions
[DW_OP_fbreg
] = Desc(Op::Dwarf2
, Op::SignedSizeLEB
);
81 Descriptions
[DW_OP_bregx
] = Desc(Op::Dwarf2
, Op::SizeLEB
, Op::SignedSizeLEB
);
82 Descriptions
[DW_OP_piece
] = Desc(Op::Dwarf2
, Op::SizeLEB
);
83 Descriptions
[DW_OP_deref_size
] = Desc(Op::Dwarf2
, Op::Size1
);
84 Descriptions
[DW_OP_xderef_size
] = Desc(Op::Dwarf2
, Op::Size1
);
85 Descriptions
[DW_OP_nop
] = Desc(Op::Dwarf2
);
86 Descriptions
[DW_OP_push_object_address
] = Desc(Op::Dwarf3
);
87 Descriptions
[DW_OP_call2
] = Desc(Op::Dwarf3
, Op::Size2
);
88 Descriptions
[DW_OP_call4
] = Desc(Op::Dwarf3
, Op::Size4
);
89 Descriptions
[DW_OP_call_ref
] = Desc(Op::Dwarf3
, Op::SizeRefAddr
);
90 Descriptions
[DW_OP_form_tls_address
] = Desc(Op::Dwarf3
);
91 Descriptions
[DW_OP_call_frame_cfa
] = Desc(Op::Dwarf3
);
92 Descriptions
[DW_OP_bit_piece
] = Desc(Op::Dwarf3
, Op::SizeLEB
, Op::SizeLEB
);
93 Descriptions
[DW_OP_implicit_value
] =
94 Desc(Op::Dwarf3
, Op::SizeLEB
, Op::SizeBlock
);
95 Descriptions
[DW_OP_stack_value
] = Desc(Op::Dwarf3
);
96 Descriptions
[DW_OP_GNU_push_tls_address
] = Desc(Op::Dwarf3
);
97 Descriptions
[DW_OP_addrx
] = Desc(Op::Dwarf4
, Op::SizeLEB
);
98 Descriptions
[DW_OP_GNU_addr_index
] = Desc(Op::Dwarf4
, Op::SizeLEB
);
99 Descriptions
[DW_OP_GNU_const_index
] = Desc(Op::Dwarf4
, Op::SizeLEB
);
100 Descriptions
[DW_OP_GNU_entry_value
] = Desc(Op::Dwarf4
, Op::SizeLEB
);
102 Descriptions
[DW_OP_convert
] = Desc(Op::Dwarf5
, Op::BaseTypeRef
);
103 Descriptions
[DW_OP_entry_value
] = Desc(Op::Dwarf5
, Op::SizeLEB
);
108 static DWARFExpression::Operation::Description
getOpDesc(unsigned OpCode
) {
109 // FIXME: Make this constexpr once all compilers are smart enough to do it.
110 static DescVector Descriptions
= getDescriptions();
111 // Handle possible corrupted or unsupported operation.
112 if (OpCode
>= Descriptions
.size())
114 return Descriptions
[OpCode
];
117 static uint8_t getRefAddrSize(uint8_t AddrSize
, uint16_t Version
) {
118 return (Version
== 2) ? AddrSize
: 4;
121 bool DWARFExpression::Operation::extract(DataExtractor Data
, uint16_t Version
,
122 uint8_t AddressSize
, uint64_t Offset
) {
123 Opcode
= Data
.getU8(&Offset
);
125 Desc
= getOpDesc(Opcode
);
126 if (Desc
.Version
== Operation::DwarfNA
) {
131 for (unsigned Operand
= 0; Operand
< 2; ++Operand
) {
132 unsigned Size
= Desc
.Op
[Operand
];
133 unsigned Signed
= Size
& Operation::SignBit
;
135 if (Size
== Operation::SizeNA
)
138 switch (Size
& ~Operation::SignBit
) {
139 case Operation::Size1
:
140 Operands
[Operand
] = Data
.getU8(&Offset
);
142 Operands
[Operand
] = (int8_t)Operands
[Operand
];
144 case Operation::Size2
:
145 Operands
[Operand
] = Data
.getU16(&Offset
);
147 Operands
[Operand
] = (int16_t)Operands
[Operand
];
149 case Operation::Size4
:
150 Operands
[Operand
] = Data
.getU32(&Offset
);
152 Operands
[Operand
] = (int32_t)Operands
[Operand
];
154 case Operation::Size8
:
155 Operands
[Operand
] = Data
.getU64(&Offset
);
157 case Operation::SizeAddr
:
158 if (AddressSize
== 8) {
159 Operands
[Operand
] = Data
.getU64(&Offset
);
160 } else if (AddressSize
== 4) {
161 Operands
[Operand
] = Data
.getU32(&Offset
);
163 assert(AddressSize
== 2);
164 Operands
[Operand
] = Data
.getU16(&Offset
);
167 case Operation::SizeRefAddr
:
168 if (getRefAddrSize(AddressSize
, Version
) == 8) {
169 Operands
[Operand
] = Data
.getU64(&Offset
);
170 } else if (getRefAddrSize(AddressSize
, Version
) == 4) {
171 Operands
[Operand
] = Data
.getU32(&Offset
);
173 assert(getRefAddrSize(AddressSize
, Version
) == 2);
174 Operands
[Operand
] = Data
.getU16(&Offset
);
177 case Operation::SizeLEB
:
179 Operands
[Operand
] = Data
.getSLEB128(&Offset
);
181 Operands
[Operand
] = Data
.getULEB128(&Offset
);
183 case Operation::BaseTypeRef
:
184 Operands
[Operand
] = Data
.getULEB128(&Offset
);
186 case Operation::SizeBlock
:
187 // We need a size, so this cannot be the first operand
190 // Store the offset of the block as the value.
191 Operands
[Operand
] = Offset
;
192 Offset
+= Operands
[Operand
- 1];
195 llvm_unreachable("Unknown DWARFExpression Op size");
198 OperandEndOffsets
[Operand
] = Offset
;
205 static bool prettyPrintRegisterOp(raw_ostream
&OS
, uint8_t Opcode
,
206 uint64_t Operands
[2],
207 const MCRegisterInfo
*MRI
, bool isEH
) {
211 uint64_t DwarfRegNum
;
214 if (Opcode
== DW_OP_bregx
|| Opcode
== DW_OP_regx
)
215 DwarfRegNum
= Operands
[OpNum
++];
216 else if (Opcode
>= DW_OP_breg0
&& Opcode
< DW_OP_bregx
)
217 DwarfRegNum
= Opcode
- DW_OP_breg0
;
219 DwarfRegNum
= Opcode
- DW_OP_reg0
;
221 if (Optional
<unsigned> LLVMRegNum
= MRI
->getLLVMRegNum(DwarfRegNum
, isEH
)) {
222 if (const char *RegName
= MRI
->getName(*LLVMRegNum
)) {
223 if ((Opcode
>= DW_OP_breg0
&& Opcode
<= DW_OP_breg31
) ||
224 Opcode
== DW_OP_bregx
)
225 OS
<< format(" %s%+" PRId64
, RegName
, Operands
[OpNum
]);
227 OS
<< ' ' << RegName
;
235 bool DWARFExpression::Operation::print(raw_ostream
&OS
,
236 const DWARFExpression
*Expr
,
237 const MCRegisterInfo
*RegInfo
,
241 OS
<< "<decoding error>";
245 StringRef Name
= OperationEncodingString(Opcode
);
246 assert(!Name
.empty() && "DW_OP has no name!");
249 if ((Opcode
>= DW_OP_breg0
&& Opcode
<= DW_OP_breg31
) ||
250 (Opcode
>= DW_OP_reg0
&& Opcode
<= DW_OP_reg31
) ||
251 Opcode
== DW_OP_bregx
|| Opcode
== DW_OP_regx
)
252 if (prettyPrintRegisterOp(OS
, Opcode
, Operands
, RegInfo
, isEH
))
255 for (unsigned Operand
= 0; Operand
< 2; ++Operand
) {
256 unsigned Size
= Desc
.Op
[Operand
];
257 unsigned Signed
= Size
& Operation::SignBit
;
259 if (Size
== Operation::SizeNA
)
262 if (Size
== Operation::BaseTypeRef
&& U
) {
263 auto Die
= U
->getDIEForOffset(U
->getOffset() + Operands
[Operand
]);
264 if (Die
&& Die
.getTag() == dwarf::DW_TAG_base_type
) {
265 OS
<< format(" (0x%08" PRIx64
")", U
->getOffset() + Operands
[Operand
]);
266 if (auto Name
= Die
.find(dwarf::DW_AT_name
))
267 OS
<< " \"" << Name
->getAsCString() << "\"";
269 OS
<< format(" <invalid base_type ref: 0x%" PRIx64
">",
272 } else if (Size
== Operation::SizeBlock
) {
273 uint64_t Offset
= Operands
[Operand
];
274 for (unsigned i
= 0; i
< Operands
[Operand
- 1]; ++i
)
275 OS
<< format(" 0x%02x", Expr
->Data
.getU8(&Offset
));
278 OS
<< format(" %+" PRId64
, (int64_t)Operands
[Operand
]);
279 else if (Opcode
!= DW_OP_entry_value
&&
280 Opcode
!= DW_OP_GNU_entry_value
)
281 OS
<< format(" 0x%" PRIx64
, Operands
[Operand
]);
287 void DWARFExpression::print(raw_ostream
&OS
, const MCRegisterInfo
*RegInfo
,
288 DWARFUnit
*U
, bool IsEH
) const {
289 uint32_t EntryValExprSize
= 0;
290 for (auto &Op
: *this) {
291 if (!Op
.print(OS
, this, RegInfo
, U
, IsEH
)) {
292 uint64_t FailOffset
= Op
.getEndOffset();
293 while (FailOffset
< Data
.getData().size())
294 OS
<< format(" %02x", Data
.getU8(&FailOffset
));
298 if (Op
.getCode() == DW_OP_entry_value
||
299 Op
.getCode() == DW_OP_GNU_entry_value
) {
301 EntryValExprSize
= Op
.getRawOperand(0);
305 if (EntryValExprSize
) {
307 if (EntryValExprSize
== 0)
311 if (Op
.getEndOffset() < Data
.getData().size())
316 bool DWARFExpression::Operation::verify(DWARFUnit
*U
) {
318 for (unsigned Operand
= 0; Operand
< 2; ++Operand
) {
319 unsigned Size
= Desc
.Op
[Operand
];
321 if (Size
== Operation::SizeNA
)
324 if (Size
== Operation::BaseTypeRef
) {
325 auto Die
= U
->getDIEForOffset(U
->getOffset() + Operands
[Operand
]);
326 if (!Die
|| Die
.getTag() != dwarf::DW_TAG_base_type
) {
336 bool DWARFExpression::verify(DWARFUnit
*U
) {
337 for (auto &Op
: *this)