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/Support/Format.h"
17 using namespace dwarf
;
21 typedef std::vector
<DWARFExpression::Operation::Description
> DescVector
;
23 static DescVector
getDescriptions() {
24 DescVector Descriptions
;
25 typedef DWARFExpression::Operation Op
;
26 typedef Op::Description Desc
;
28 Descriptions
.resize(0xff);
29 Descriptions
[DW_OP_addr
] = Desc(Op::Dwarf2
, Op::SizeAddr
);
30 Descriptions
[DW_OP_deref
] = Desc(Op::Dwarf2
);
31 Descriptions
[DW_OP_const1u
] = Desc(Op::Dwarf2
, Op::Size1
);
32 Descriptions
[DW_OP_const1s
] = Desc(Op::Dwarf2
, Op::SignedSize1
);
33 Descriptions
[DW_OP_const2u
] = Desc(Op::Dwarf2
, Op::Size2
);
34 Descriptions
[DW_OP_const2s
] = Desc(Op::Dwarf2
, Op::SignedSize2
);
35 Descriptions
[DW_OP_const4u
] = Desc(Op::Dwarf2
, Op::Size4
);
36 Descriptions
[DW_OP_const4s
] = Desc(Op::Dwarf2
, Op::SignedSize4
);
37 Descriptions
[DW_OP_const8u
] = Desc(Op::Dwarf2
, Op::Size8
);
38 Descriptions
[DW_OP_const8s
] = Desc(Op::Dwarf2
, Op::SignedSize8
);
39 Descriptions
[DW_OP_constu
] = Desc(Op::Dwarf2
, Op::SizeLEB
);
40 Descriptions
[DW_OP_consts
] = Desc(Op::Dwarf2
, Op::SignedSizeLEB
);
41 Descriptions
[DW_OP_dup
] = Desc(Op::Dwarf2
);
42 Descriptions
[DW_OP_drop
] = Desc(Op::Dwarf2
);
43 Descriptions
[DW_OP_over
] = Desc(Op::Dwarf2
);
44 Descriptions
[DW_OP_pick
] = Desc(Op::Dwarf2
, Op::Size1
);
45 Descriptions
[DW_OP_swap
] = Desc(Op::Dwarf2
);
46 Descriptions
[DW_OP_rot
] = Desc(Op::Dwarf2
);
47 Descriptions
[DW_OP_xderef
] = Desc(Op::Dwarf2
);
48 Descriptions
[DW_OP_abs
] = Desc(Op::Dwarf2
);
49 Descriptions
[DW_OP_and
] = Desc(Op::Dwarf2
);
50 Descriptions
[DW_OP_div
] = Desc(Op::Dwarf2
);
51 Descriptions
[DW_OP_minus
] = Desc(Op::Dwarf2
);
52 Descriptions
[DW_OP_mod
] = Desc(Op::Dwarf2
);
53 Descriptions
[DW_OP_mul
] = Desc(Op::Dwarf2
);
54 Descriptions
[DW_OP_neg
] = Desc(Op::Dwarf2
);
55 Descriptions
[DW_OP_not
] = Desc(Op::Dwarf2
);
56 Descriptions
[DW_OP_or
] = Desc(Op::Dwarf2
);
57 Descriptions
[DW_OP_plus
] = Desc(Op::Dwarf2
);
58 Descriptions
[DW_OP_plus_uconst
] = Desc(Op::Dwarf2
, Op::SizeLEB
);
59 Descriptions
[DW_OP_shl
] = Desc(Op::Dwarf2
);
60 Descriptions
[DW_OP_shr
] = Desc(Op::Dwarf2
);
61 Descriptions
[DW_OP_shra
] = Desc(Op::Dwarf2
);
62 Descriptions
[DW_OP_xor
] = Desc(Op::Dwarf2
);
63 Descriptions
[DW_OP_skip
] = Desc(Op::Dwarf2
, Op::SignedSize2
);
64 Descriptions
[DW_OP_bra
] = Desc(Op::Dwarf2
, Op::SignedSize2
);
65 Descriptions
[DW_OP_eq
] = Desc(Op::Dwarf2
);
66 Descriptions
[DW_OP_ge
] = Desc(Op::Dwarf2
);
67 Descriptions
[DW_OP_gt
] = Desc(Op::Dwarf2
);
68 Descriptions
[DW_OP_le
] = Desc(Op::Dwarf2
);
69 Descriptions
[DW_OP_lt
] = Desc(Op::Dwarf2
);
70 Descriptions
[DW_OP_ne
] = Desc(Op::Dwarf2
);
71 for (uint16_t LA
= DW_OP_lit0
; LA
<= DW_OP_lit31
; ++LA
)
72 Descriptions
[LA
] = Desc(Op::Dwarf2
);
73 for (uint16_t LA
= DW_OP_reg0
; LA
<= DW_OP_reg31
; ++LA
)
74 Descriptions
[LA
] = Desc(Op::Dwarf2
);
75 for (uint16_t LA
= DW_OP_breg0
; LA
<= DW_OP_breg31
; ++LA
)
76 Descriptions
[LA
] = Desc(Op::Dwarf2
, Op::SignedSizeLEB
);
77 Descriptions
[DW_OP_regx
] = Desc(Op::Dwarf2
, Op::SizeLEB
);
78 Descriptions
[DW_OP_fbreg
] = Desc(Op::Dwarf2
, Op::SignedSizeLEB
);
79 Descriptions
[DW_OP_bregx
] = Desc(Op::Dwarf2
, Op::SizeLEB
, Op::SignedSizeLEB
);
80 Descriptions
[DW_OP_piece
] = Desc(Op::Dwarf2
, Op::SizeLEB
);
81 Descriptions
[DW_OP_deref_size
] = Desc(Op::Dwarf2
, Op::Size1
);
82 Descriptions
[DW_OP_xderef_size
] = Desc(Op::Dwarf2
, Op::Size1
);
83 Descriptions
[DW_OP_nop
] = Desc(Op::Dwarf2
);
84 Descriptions
[DW_OP_push_object_address
] = Desc(Op::Dwarf3
);
85 Descriptions
[DW_OP_call2
] = Desc(Op::Dwarf3
, Op::Size2
);
86 Descriptions
[DW_OP_call4
] = Desc(Op::Dwarf3
, Op::Size4
);
87 Descriptions
[DW_OP_call_ref
] = Desc(Op::Dwarf3
, Op::SizeRefAddr
);
88 Descriptions
[DW_OP_form_tls_address
] = Desc(Op::Dwarf3
);
89 Descriptions
[DW_OP_call_frame_cfa
] = Desc(Op::Dwarf3
);
90 Descriptions
[DW_OP_bit_piece
] = Desc(Op::Dwarf3
, Op::SizeLEB
, Op::SizeLEB
);
91 Descriptions
[DW_OP_implicit_value
] =
92 Desc(Op::Dwarf3
, Op::SizeLEB
, Op::SizeBlock
);
93 Descriptions
[DW_OP_stack_value
] = Desc(Op::Dwarf3
);
94 Descriptions
[DW_OP_WASM_location
] =
95 Desc(Op::Dwarf4
, Op::SizeLEB
, Op::WasmLocationArg
);
96 Descriptions
[DW_OP_GNU_push_tls_address
] = Desc(Op::Dwarf3
);
97 Descriptions
[DW_OP_GNU_addr_index
] = Desc(Op::Dwarf4
, Op::SizeLEB
);
98 Descriptions
[DW_OP_GNU_const_index
] = Desc(Op::Dwarf4
, Op::SizeLEB
);
99 Descriptions
[DW_OP_GNU_entry_value
] = Desc(Op::Dwarf4
, Op::SizeLEB
);
101 Descriptions
[DW_OP_addrx
] = Desc(Op::Dwarf5
, Op::SizeLEB
);
102 Descriptions
[DW_OP_constx
] = Desc(Op::Dwarf5
, Op::SizeLEB
);
103 Descriptions
[DW_OP_convert
] = Desc(Op::Dwarf5
, Op::BaseTypeRef
);
104 Descriptions
[DW_OP_entry_value
] = Desc(Op::Dwarf5
, Op::SizeLEB
);
105 Descriptions
[DW_OP_regval_type
] =
106 Desc(Op::Dwarf5
, Op::SizeLEB
, Op::BaseTypeRef
);
111 static DWARFExpression::Operation::Description
getOpDesc(unsigned OpCode
) {
112 // FIXME: Make this constexpr once all compilers are smart enough to do it.
113 static DescVector Descriptions
= getDescriptions();
114 // Handle possible corrupted or unsupported operation.
115 if (OpCode
>= Descriptions
.size())
117 return Descriptions
[OpCode
];
120 bool DWARFExpression::Operation::extract(DataExtractor Data
,
121 uint8_t AddressSize
, uint64_t Offset
,
122 std::optional
<DwarfFormat
> Format
) {
124 Opcode
= Data
.getU8(&Offset
);
126 Desc
= getOpDesc(Opcode
);
127 if (Desc
.Version
== Operation::DwarfNA
)
130 for (unsigned Operand
= 0; Operand
< 2; ++Operand
) {
131 unsigned Size
= Desc
.Op
[Operand
];
132 unsigned Signed
= Size
& Operation::SignBit
;
134 if (Size
== Operation::SizeNA
)
137 switch (Size
& ~Operation::SignBit
) {
138 case Operation::Size1
:
139 Operands
[Operand
] = Data
.getU8(&Offset
);
141 Operands
[Operand
] = (int8_t)Operands
[Operand
];
143 case Operation::Size2
:
144 Operands
[Operand
] = Data
.getU16(&Offset
);
146 Operands
[Operand
] = (int16_t)Operands
[Operand
];
148 case Operation::Size4
:
149 Operands
[Operand
] = Data
.getU32(&Offset
);
151 Operands
[Operand
] = (int32_t)Operands
[Operand
];
153 case Operation::Size8
:
154 Operands
[Operand
] = Data
.getU64(&Offset
);
156 case Operation::SizeAddr
:
157 Operands
[Operand
] = Data
.getUnsigned(&Offset
, AddressSize
);
159 case Operation::SizeRefAddr
:
163 Data
.getUnsigned(&Offset
, dwarf::getDwarfOffsetByteSize(*Format
));
165 case Operation::SizeLEB
:
167 Operands
[Operand
] = Data
.getSLEB128(&Offset
);
169 Operands
[Operand
] = Data
.getULEB128(&Offset
);
171 case Operation::BaseTypeRef
:
172 Operands
[Operand
] = Data
.getULEB128(&Offset
);
174 case Operation::WasmLocationArg
:
175 assert(Operand
== 1);
176 switch (Operands
[0]) {
181 Operands
[Operand
] = Data
.getULEB128(&Offset
);
183 case 3: // global as uint32
184 Operands
[Operand
] = Data
.getU32(&Offset
);
187 return false; // Unknown Wasm location
190 case Operation::SizeBlock
:
191 // We need a size, so this cannot be the first operand
194 // Store the offset of the block as the value.
195 Operands
[Operand
] = Offset
;
196 Offset
+= Operands
[Operand
- 1];
199 llvm_unreachable("Unknown DWARFExpression Op size");
202 OperandEndOffsets
[Operand
] = Offset
;
209 static void prettyPrintBaseTypeRef(DWARFUnit
*U
, raw_ostream
&OS
,
210 DIDumpOptions DumpOpts
,
211 const uint64_t Operands
[2],
213 assert(Operand
< 2 && "operand out of bounds");
214 auto Die
= U
->getDIEForOffset(U
->getOffset() + Operands
[Operand
]);
215 if (Die
&& Die
.getTag() == dwarf::DW_TAG_base_type
) {
217 if (DumpOpts
.Verbose
)
218 OS
<< format("0x%08" PRIx64
" -> ", Operands
[Operand
]);
219 OS
<< format("0x%08" PRIx64
")", U
->getOffset() + Operands
[Operand
]);
220 if (auto Name
= dwarf::toString(Die
.find(dwarf::DW_AT_name
)))
221 OS
<< " \"" << *Name
<< "\"";
223 OS
<< format(" <invalid base_type ref: 0x%" PRIx64
">",
228 bool DWARFExpression::prettyPrintRegisterOp(DWARFUnit
*U
, raw_ostream
&OS
,
229 DIDumpOptions DumpOpts
,
231 const uint64_t Operands
[2]) {
232 if (!DumpOpts
.GetNameForDWARFReg
)
235 uint64_t DwarfRegNum
;
238 if (Opcode
== DW_OP_bregx
|| Opcode
== DW_OP_regx
||
239 Opcode
== DW_OP_regval_type
)
240 DwarfRegNum
= Operands
[OpNum
++];
241 else if (Opcode
>= DW_OP_breg0
&& Opcode
< DW_OP_bregx
)
242 DwarfRegNum
= Opcode
- DW_OP_breg0
;
244 DwarfRegNum
= Opcode
- DW_OP_reg0
;
246 auto RegName
= DumpOpts
.GetNameForDWARFReg(DwarfRegNum
, DumpOpts
.IsEH
);
247 if (!RegName
.empty()) {
248 if ((Opcode
>= DW_OP_breg0
&& Opcode
<= DW_OP_breg31
) ||
249 Opcode
== DW_OP_bregx
)
250 OS
<< ' ' << RegName
<< format("%+" PRId64
, Operands
[OpNum
]);
252 OS
<< ' ' << RegName
.data();
254 if (Opcode
== DW_OP_regval_type
)
255 prettyPrintBaseTypeRef(U
, OS
, DumpOpts
, Operands
, 1);
262 bool DWARFExpression::Operation::print(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
263 const DWARFExpression
*Expr
,
264 DWARFUnit
*U
) const {
266 OS
<< "<decoding error>";
270 StringRef Name
= OperationEncodingString(Opcode
);
271 assert(!Name
.empty() && "DW_OP has no name!");
274 if ((Opcode
>= DW_OP_breg0
&& Opcode
<= DW_OP_breg31
) ||
275 (Opcode
>= DW_OP_reg0
&& Opcode
<= DW_OP_reg31
) ||
276 Opcode
== DW_OP_bregx
|| Opcode
== DW_OP_regx
||
277 Opcode
== DW_OP_regval_type
)
278 if (prettyPrintRegisterOp(U
, OS
, DumpOpts
, Opcode
, Operands
))
281 for (unsigned Operand
= 0; Operand
< 2; ++Operand
) {
282 unsigned Size
= Desc
.Op
[Operand
];
283 unsigned Signed
= Size
& Operation::SignBit
;
285 if (Size
== Operation::SizeNA
)
288 if (Size
== Operation::BaseTypeRef
&& U
) {
289 // For DW_OP_convert the operand may be 0 to indicate that conversion to
290 // the generic type should be done. The same holds for DW_OP_reinterpret,
291 // which is currently not supported.
292 if (Opcode
== DW_OP_convert
&& Operands
[Operand
] == 0)
295 prettyPrintBaseTypeRef(U
, OS
, DumpOpts
, Operands
, Operand
);
296 } else if (Size
== Operation::WasmLocationArg
) {
297 assert(Operand
== 1);
298 switch (Operands
[0]) {
302 case 3: // global as uint32
304 OS
<< format(" 0x%" PRIx64
, Operands
[Operand
]);
306 default: assert(false);
308 } else if (Size
== Operation::SizeBlock
) {
309 uint64_t Offset
= Operands
[Operand
];
310 for (unsigned i
= 0; i
< Operands
[Operand
- 1]; ++i
)
311 OS
<< format(" 0x%02x", Expr
->Data
.getU8(&Offset
));
314 OS
<< format(" %+" PRId64
, (int64_t)Operands
[Operand
]);
315 else if (Opcode
!= DW_OP_entry_value
&&
316 Opcode
!= DW_OP_GNU_entry_value
)
317 OS
<< format(" 0x%" PRIx64
, Operands
[Operand
]);
323 void DWARFExpression::print(raw_ostream
&OS
, DIDumpOptions DumpOpts
,
324 DWARFUnit
*U
, bool IsEH
) const {
325 uint32_t EntryValExprSize
= 0;
326 uint64_t EntryValStartOffset
= 0;
327 if (Data
.getData().empty())
330 for (auto &Op
: *this) {
331 DumpOpts
.IsEH
= IsEH
;
332 if (!Op
.print(OS
, DumpOpts
, this, U
)) {
333 uint64_t FailOffset
= Op
.getEndOffset();
334 while (FailOffset
< Data
.getData().size())
335 OS
<< format(" %02x", Data
.getU8(&FailOffset
));
339 if (Op
.getCode() == DW_OP_entry_value
||
340 Op
.getCode() == DW_OP_GNU_entry_value
) {
342 EntryValExprSize
= Op
.getRawOperand(0);
343 EntryValStartOffset
= Op
.getEndOffset();
347 if (EntryValExprSize
) {
348 EntryValExprSize
-= Op
.getEndOffset() - EntryValStartOffset
;
349 if (EntryValExprSize
== 0)
353 if (Op
.getEndOffset() < Data
.getData().size())
358 bool DWARFExpression::Operation::verify(const Operation
&Op
, DWARFUnit
*U
) {
359 for (unsigned Operand
= 0; Operand
< 2; ++Operand
) {
360 unsigned Size
= Op
.Desc
.Op
[Operand
];
362 if (Size
== Operation::SizeNA
)
365 if (Size
== Operation::BaseTypeRef
) {
366 // For DW_OP_convert the operand may be 0 to indicate that conversion to
367 // the generic type should be done, so don't look up a base type in that
368 // case. The same holds for DW_OP_reinterpret, which is currently not
370 if (Op
.Opcode
== DW_OP_convert
&& Op
.Operands
[Operand
] == 0)
372 auto Die
= U
->getDIEForOffset(U
->getOffset() + Op
.Operands
[Operand
]);
373 if (!Die
|| Die
.getTag() != dwarf::DW_TAG_base_type
)
381 bool DWARFExpression::verify(DWARFUnit
*U
) {
382 for (auto &Op
: *this)
383 if (!Operation::verify(Op
, U
))
389 /// A user-facing string representation of a DWARF expression. This might be an
390 /// Address expression, in which case it will be implicitly dereferenced, or a
391 /// Value expression.
398 SmallString
<16> String
;
400 PrintedExpr(ExprKind K
= Address
) : Kind(K
) {}
403 static bool printCompactDWARFExpr(
404 raw_ostream
&OS
, DWARFExpression::iterator I
,
405 const DWARFExpression::iterator E
,
406 std::function
<StringRef(uint64_t RegNum
, bool IsEH
)> GetNameForDWARFReg
=
408 SmallVector
<PrintedExpr
, 4> Stack
;
411 const DWARFExpression::Operation
&Op
= *I
;
412 uint8_t Opcode
= Op
.getCode();
414 case dwarf::DW_OP_regx
: {
415 // DW_OP_regx: A register, with the register num given as an operand.
416 // Printed as the plain register name.
417 uint64_t DwarfRegNum
= Op
.getRawOperand(0);
418 auto RegName
= GetNameForDWARFReg(DwarfRegNum
, false);
421 raw_svector_ostream
S(Stack
.emplace_back(PrintedExpr::Value
).String
);
425 case dwarf::DW_OP_bregx
: {
426 int DwarfRegNum
= Op
.getRawOperand(0);
427 int64_t Offset
= Op
.getRawOperand(1);
428 auto RegName
= GetNameForDWARFReg(DwarfRegNum
, false);
431 raw_svector_ostream
S(Stack
.emplace_back().String
);
434 S
<< format("%+" PRId64
, Offset
);
437 case dwarf::DW_OP_entry_value
:
438 case dwarf::DW_OP_GNU_entry_value
: {
439 // DW_OP_entry_value contains a sub-expression which must be rendered
441 uint64_t SubExprLength
= Op
.getRawOperand(0);
442 DWARFExpression::iterator SubExprEnd
= I
.skipBytes(SubExprLength
);
444 raw_svector_ostream
S(Stack
.emplace_back().String
);
446 printCompactDWARFExpr(S
, I
, SubExprEnd
, GetNameForDWARFReg
);
451 case dwarf::DW_OP_stack_value
: {
452 // The top stack entry should be treated as the actual value of tne
453 // variable, rather than the address of the variable in memory.
454 assert(!Stack
.empty());
455 Stack
.back().Kind
= PrintedExpr::Value
;
458 case dwarf::DW_OP_nop
: {
462 if (Opcode
>= dwarf::DW_OP_reg0
&& Opcode
<= dwarf::DW_OP_reg31
) {
463 // DW_OP_reg<N>: A register, with the register num implied by the
464 // opcode. Printed as the plain register name.
465 uint64_t DwarfRegNum
= Opcode
- dwarf::DW_OP_reg0
;
466 auto RegName
= GetNameForDWARFReg(DwarfRegNum
, false);
469 raw_svector_ostream
S(Stack
.emplace_back(PrintedExpr::Value
).String
);
471 } else if (Opcode
>= dwarf::DW_OP_breg0
&&
472 Opcode
<= dwarf::DW_OP_breg31
) {
473 int DwarfRegNum
= Opcode
- dwarf::DW_OP_breg0
;
474 int64_t Offset
= Op
.getRawOperand(0);
475 auto RegName
= GetNameForDWARFReg(DwarfRegNum
, false);
478 raw_svector_ostream
S(Stack
.emplace_back().String
);
481 S
<< format("%+" PRId64
, Offset
);
483 // If we hit an unknown operand, we don't know its effect on the stack,
484 // so bail out on the whole expression.
485 OS
<< "<unknown op " << dwarf::OperationEncodingString(Opcode
) << " ("
486 << (int)Opcode
<< ")>";
494 if (Stack
.size() != 1) {
495 OS
<< "<stack of size " << Stack
.size() << ", expected 1>";
499 if (Stack
.front().Kind
== PrintedExpr::Address
)
500 OS
<< "[" << Stack
.front().String
<< "]";
502 OS
<< Stack
.front().String
;
507 bool DWARFExpression::printCompact(
509 std::function
<StringRef(uint64_t RegNum
, bool IsEH
)> GetNameForDWARFReg
) {
510 return printCompactDWARFExpr(OS
, begin(), end(), GetNameForDWARFReg
);
513 bool DWARFExpression::operator==(const DWARFExpression
&RHS
) const {
514 if (AddressSize
!= RHS
.AddressSize
|| Format
!= RHS
.Format
)
516 return Data
.getData() == RHS
.Data
.getData();