150
|
1 //===-- DWARFExpression.cpp -----------------------------------------------===//
|
|
2 //
|
|
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
|
|
6 //
|
|
7 //===----------------------------------------------------------------------===//
|
|
8
|
|
9 #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
|
|
10 #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
|
|
11 #include "llvm/MC/MCRegisterInfo.h"
|
|
12 #include "llvm/Support/Format.h"
|
|
13 #include <cassert>
|
|
14 #include <cstdint>
|
|
15 #include <vector>
|
|
16
|
|
17 using namespace llvm;
|
|
18 using namespace dwarf;
|
|
19
|
|
20 namespace llvm {
|
|
21
|
|
22 typedef std::vector<DWARFExpression::Operation::Description> DescVector;
|
|
23
|
|
24 static DescVector getDescriptions() {
|
|
25 DescVector Descriptions;
|
|
26 typedef DWARFExpression::Operation Op;
|
|
27 typedef Op::Description Desc;
|
|
28
|
|
29 Descriptions.resize(0xff);
|
|
30 Descriptions[DW_OP_addr] = Desc(Op::Dwarf2, Op::SizeAddr);
|
|
31 Descriptions[DW_OP_deref] = Desc(Op::Dwarf2);
|
|
32 Descriptions[DW_OP_const1u] = Desc(Op::Dwarf2, Op::Size1);
|
|
33 Descriptions[DW_OP_const1s] = Desc(Op::Dwarf2, Op::SignedSize1);
|
|
34 Descriptions[DW_OP_const2u] = Desc(Op::Dwarf2, Op::Size2);
|
|
35 Descriptions[DW_OP_const2s] = Desc(Op::Dwarf2, Op::SignedSize2);
|
|
36 Descriptions[DW_OP_const4u] = Desc(Op::Dwarf2, Op::Size4);
|
|
37 Descriptions[DW_OP_const4s] = Desc(Op::Dwarf2, Op::SignedSize4);
|
|
38 Descriptions[DW_OP_const8u] = Desc(Op::Dwarf2, Op::Size8);
|
|
39 Descriptions[DW_OP_const8s] = Desc(Op::Dwarf2, Op::SignedSize8);
|
|
40 Descriptions[DW_OP_constu] = Desc(Op::Dwarf2, Op::SizeLEB);
|
|
41 Descriptions[DW_OP_consts] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
|
|
42 Descriptions[DW_OP_dup] = Desc(Op::Dwarf2);
|
|
43 Descriptions[DW_OP_drop] = Desc(Op::Dwarf2);
|
|
44 Descriptions[DW_OP_over] = Desc(Op::Dwarf2);
|
|
45 Descriptions[DW_OP_pick] = Desc(Op::Dwarf2, Op::Size1);
|
|
46 Descriptions[DW_OP_swap] = Desc(Op::Dwarf2);
|
|
47 Descriptions[DW_OP_rot] = Desc(Op::Dwarf2);
|
|
48 Descriptions[DW_OP_xderef] = Desc(Op::Dwarf2);
|
|
49 Descriptions[DW_OP_abs] = Desc(Op::Dwarf2);
|
|
50 Descriptions[DW_OP_and] = Desc(Op::Dwarf2);
|
|
51 Descriptions[DW_OP_div] = Desc(Op::Dwarf2);
|
|
52 Descriptions[DW_OP_minus] = Desc(Op::Dwarf2);
|
|
53 Descriptions[DW_OP_mod] = Desc(Op::Dwarf2);
|
|
54 Descriptions[DW_OP_mul] = Desc(Op::Dwarf2);
|
|
55 Descriptions[DW_OP_neg] = Desc(Op::Dwarf2);
|
|
56 Descriptions[DW_OP_not] = Desc(Op::Dwarf2);
|
|
57 Descriptions[DW_OP_or] = Desc(Op::Dwarf2);
|
|
58 Descriptions[DW_OP_plus] = Desc(Op::Dwarf2);
|
|
59 Descriptions[DW_OP_plus_uconst] = Desc(Op::Dwarf2, Op::SizeLEB);
|
|
60 Descriptions[DW_OP_shl] = Desc(Op::Dwarf2);
|
|
61 Descriptions[DW_OP_shr] = Desc(Op::Dwarf2);
|
|
62 Descriptions[DW_OP_shra] = Desc(Op::Dwarf2);
|
|
63 Descriptions[DW_OP_xor] = Desc(Op::Dwarf2);
|
|
64 Descriptions[DW_OP_skip] = Desc(Op::Dwarf2, Op::SignedSize2);
|
|
65 Descriptions[DW_OP_bra] = Desc(Op::Dwarf2, Op::SignedSize2);
|
|
66 Descriptions[DW_OP_eq] = Desc(Op::Dwarf2);
|
|
67 Descriptions[DW_OP_ge] = Desc(Op::Dwarf2);
|
|
68 Descriptions[DW_OP_gt] = Desc(Op::Dwarf2);
|
|
69 Descriptions[DW_OP_le] = Desc(Op::Dwarf2);
|
|
70 Descriptions[DW_OP_lt] = Desc(Op::Dwarf2);
|
|
71 Descriptions[DW_OP_ne] = Desc(Op::Dwarf2);
|
|
72 for (uint16_t LA = DW_OP_lit0; LA <= DW_OP_lit31; ++LA)
|
|
73 Descriptions[LA] = Desc(Op::Dwarf2);
|
|
74 for (uint16_t LA = DW_OP_reg0; LA <= DW_OP_reg31; ++LA)
|
|
75 Descriptions[LA] = Desc(Op::Dwarf2);
|
|
76 for (uint16_t LA = DW_OP_breg0; LA <= DW_OP_breg31; ++LA)
|
|
77 Descriptions[LA] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
|
|
78 Descriptions[DW_OP_regx] = Desc(Op::Dwarf2, Op::SizeLEB);
|
|
79 Descriptions[DW_OP_fbreg] = Desc(Op::Dwarf2, Op::SignedSizeLEB);
|
|
80 Descriptions[DW_OP_bregx] = Desc(Op::Dwarf2, Op::SizeLEB, Op::SignedSizeLEB);
|
|
81 Descriptions[DW_OP_piece] = Desc(Op::Dwarf2, Op::SizeLEB);
|
|
82 Descriptions[DW_OP_deref_size] = Desc(Op::Dwarf2, Op::Size1);
|
|
83 Descriptions[DW_OP_xderef_size] = Desc(Op::Dwarf2, Op::Size1);
|
|
84 Descriptions[DW_OP_nop] = Desc(Op::Dwarf2);
|
|
85 Descriptions[DW_OP_push_object_address] = Desc(Op::Dwarf3);
|
|
86 Descriptions[DW_OP_call2] = Desc(Op::Dwarf3, Op::Size2);
|
|
87 Descriptions[DW_OP_call4] = Desc(Op::Dwarf3, Op::Size4);
|
|
88 Descriptions[DW_OP_call_ref] = Desc(Op::Dwarf3, Op::SizeRefAddr);
|
|
89 Descriptions[DW_OP_form_tls_address] = Desc(Op::Dwarf3);
|
|
90 Descriptions[DW_OP_call_frame_cfa] = Desc(Op::Dwarf3);
|
|
91 Descriptions[DW_OP_bit_piece] = Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeLEB);
|
|
92 Descriptions[DW_OP_implicit_value] =
|
|
93 Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeBlock);
|
|
94 Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf3);
|
|
95 Descriptions[DW_OP_WASM_location] =
|
173
|
96 Desc(Op::Dwarf4, Op::SizeLEB, Op::WasmLocationArg);
|
150
|
97 Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3);
|
|
98 Descriptions[DW_OP_addrx] = Desc(Op::Dwarf4, Op::SizeLEB);
|
|
99 Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB);
|
|
100 Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB);
|
|
101 Descriptions[DW_OP_GNU_entry_value] = Desc(Op::Dwarf4, Op::SizeLEB);
|
|
102
|
|
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);
|
|
107
|
|
108 return Descriptions;
|
|
109 }
|
|
110
|
|
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())
|
|
116 return {};
|
|
117 return Descriptions[OpCode];
|
|
118 }
|
|
119
|
|
120 bool DWARFExpression::Operation::extract(DataExtractor Data,
|
173
|
121 uint8_t AddressSize, uint64_t Offset,
|
|
122 Optional<DwarfFormat> Format) {
|
|
123 EndOffset = Offset;
|
150
|
124 Opcode = Data.getU8(&Offset);
|
|
125
|
|
126 Desc = getOpDesc(Opcode);
|
173
|
127 if (Desc.Version == Operation::DwarfNA)
|
150
|
128 return false;
|
|
129
|
|
130 for (unsigned Operand = 0; Operand < 2; ++Operand) {
|
|
131 unsigned Size = Desc.Op[Operand];
|
|
132 unsigned Signed = Size & Operation::SignBit;
|
|
133
|
|
134 if (Size == Operation::SizeNA)
|
|
135 break;
|
|
136
|
|
137 switch (Size & ~Operation::SignBit) {
|
|
138 case Operation::Size1:
|
|
139 Operands[Operand] = Data.getU8(&Offset);
|
|
140 if (Signed)
|
|
141 Operands[Operand] = (int8_t)Operands[Operand];
|
|
142 break;
|
|
143 case Operation::Size2:
|
|
144 Operands[Operand] = Data.getU16(&Offset);
|
|
145 if (Signed)
|
|
146 Operands[Operand] = (int16_t)Operands[Operand];
|
|
147 break;
|
|
148 case Operation::Size4:
|
|
149 Operands[Operand] = Data.getU32(&Offset);
|
|
150 if (Signed)
|
|
151 Operands[Operand] = (int32_t)Operands[Operand];
|
|
152 break;
|
|
153 case Operation::Size8:
|
|
154 Operands[Operand] = Data.getU64(&Offset);
|
|
155 break;
|
|
156 case Operation::SizeAddr:
|
|
157 Operands[Operand] = Data.getUnsigned(&Offset, AddressSize);
|
|
158 break;
|
|
159 case Operation::SizeRefAddr:
|
173
|
160 if (!Format)
|
|
161 return false;
|
|
162 Operands[Operand] =
|
|
163 Data.getUnsigned(&Offset, dwarf::getDwarfOffsetByteSize(*Format));
|
150
|
164 break;
|
|
165 case Operation::SizeLEB:
|
|
166 if (Signed)
|
|
167 Operands[Operand] = Data.getSLEB128(&Offset);
|
|
168 else
|
|
169 Operands[Operand] = Data.getULEB128(&Offset);
|
|
170 break;
|
|
171 case Operation::BaseTypeRef:
|
|
172 Operands[Operand] = Data.getULEB128(&Offset);
|
|
173 break;
|
173
|
174 case Operation::WasmLocationArg:
|
|
175 assert(Operand == 1);
|
|
176 switch (Operands[0]) {
|
|
177 case 0: case 1: case 2:
|
|
178 Operands[Operand] = Data.getULEB128(&Offset);
|
|
179 break;
|
|
180 case 3: // global as uint32
|
|
181 Operands[Operand] = Data.getU32(&Offset);
|
|
182 break;
|
|
183 default:
|
|
184 return false; // Unknown Wasm location
|
|
185 }
|
|
186 break;
|
150
|
187 case Operation::SizeBlock:
|
|
188 // We need a size, so this cannot be the first operand
|
|
189 if (Operand == 0)
|
|
190 return false;
|
|
191 // Store the offset of the block as the value.
|
|
192 Operands[Operand] = Offset;
|
|
193 Offset += Operands[Operand - 1];
|
|
194 break;
|
|
195 default:
|
|
196 llvm_unreachable("Unknown DWARFExpression Op size");
|
|
197 }
|
|
198
|
|
199 OperandEndOffsets[Operand] = Offset;
|
|
200 }
|
|
201
|
|
202 EndOffset = Offset;
|
|
203 return true;
|
|
204 }
|
|
205
|
|
206 static void prettyPrintBaseTypeRef(DWARFUnit *U, raw_ostream &OS,
|
|
207 uint64_t Operands[2], unsigned Operand) {
|
|
208 assert(Operand < 2 && "operand out of bounds");
|
|
209 auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
|
|
210 if (Die && Die.getTag() == dwarf::DW_TAG_base_type) {
|
|
211 OS << format(" (0x%08" PRIx64 ")", U->getOffset() + Operands[Operand]);
|
|
212 if (auto Name = Die.find(dwarf::DW_AT_name))
|
|
213 OS << " \"" << Name->getAsCString() << "\"";
|
|
214 } else {
|
|
215 OS << format(" <invalid base_type ref: 0x%" PRIx64 ">",
|
|
216 Operands[Operand]);
|
|
217 }
|
|
218 }
|
|
219
|
|
220 static bool prettyPrintRegisterOp(DWARFUnit *U, raw_ostream &OS, uint8_t Opcode,
|
|
221 uint64_t Operands[2],
|
|
222 const MCRegisterInfo *MRI, bool isEH) {
|
|
223 if (!MRI)
|
|
224 return false;
|
|
225
|
|
226 uint64_t DwarfRegNum;
|
|
227 unsigned OpNum = 0;
|
|
228
|
|
229 if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
|
|
230 Opcode == DW_OP_regval_type)
|
|
231 DwarfRegNum = Operands[OpNum++];
|
|
232 else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx)
|
|
233 DwarfRegNum = Opcode - DW_OP_breg0;
|
|
234 else
|
|
235 DwarfRegNum = Opcode - DW_OP_reg0;
|
|
236
|
|
237 if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH)) {
|
|
238 if (const char *RegName = MRI->getName(*LLVMRegNum)) {
|
|
239 if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
|
|
240 Opcode == DW_OP_bregx)
|
|
241 OS << format(" %s%+" PRId64, RegName, Operands[OpNum]);
|
|
242 else
|
|
243 OS << ' ' << RegName;
|
|
244
|
|
245 if (Opcode == DW_OP_regval_type)
|
|
246 prettyPrintBaseTypeRef(U, OS, Operands, 1);
|
|
247 return true;
|
|
248 }
|
|
249 }
|
|
250
|
|
251 return false;
|
|
252 }
|
|
253
|
|
254 bool DWARFExpression::Operation::print(raw_ostream &OS,
|
|
255 const DWARFExpression *Expr,
|
|
256 const MCRegisterInfo *RegInfo,
|
|
257 DWARFUnit *U,
|
|
258 bool isEH) {
|
|
259 if (Error) {
|
|
260 OS << "<decoding error>";
|
|
261 return false;
|
|
262 }
|
|
263
|
|
264 StringRef Name = OperationEncodingString(Opcode);
|
|
265 assert(!Name.empty() && "DW_OP has no name!");
|
|
266 OS << Name;
|
|
267
|
|
268 if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31) ||
|
|
269 (Opcode >= DW_OP_reg0 && Opcode <= DW_OP_reg31) ||
|
|
270 Opcode == DW_OP_bregx || Opcode == DW_OP_regx ||
|
|
271 Opcode == DW_OP_regval_type)
|
|
272 if (prettyPrintRegisterOp(U, OS, Opcode, Operands, RegInfo, isEH))
|
|
273 return true;
|
|
274
|
|
275 for (unsigned Operand = 0; Operand < 2; ++Operand) {
|
|
276 unsigned Size = Desc.Op[Operand];
|
|
277 unsigned Signed = Size & Operation::SignBit;
|
|
278
|
|
279 if (Size == Operation::SizeNA)
|
|
280 break;
|
|
281
|
|
282 if (Size == Operation::BaseTypeRef && U) {
|
173
|
283 // For DW_OP_convert the operand may be 0 to indicate that conversion to
|
|
284 // the generic type should be done. The same holds for DW_OP_reinterpret,
|
|
285 // which is currently not supported.
|
|
286 if (Opcode == DW_OP_convert && Operands[Operand] == 0)
|
|
287 OS << " 0x0";
|
|
288 else
|
|
289 prettyPrintBaseTypeRef(U, OS, Operands, Operand);
|
|
290 } else if (Size == Operation::WasmLocationArg) {
|
|
291 assert(Operand == 1);
|
|
292 switch (Operands[0]) {
|
|
293 case 0: case 1: case 2:
|
|
294 case 3: // global as uint32
|
|
295 OS << format(" 0x%" PRIx64, Operands[Operand]);
|
|
296 break;
|
|
297 default: assert(false);
|
|
298 }
|
150
|
299 } else if (Size == Operation::SizeBlock) {
|
|
300 uint64_t Offset = Operands[Operand];
|
|
301 for (unsigned i = 0; i < Operands[Operand - 1]; ++i)
|
|
302 OS << format(" 0x%02x", Expr->Data.getU8(&Offset));
|
|
303 } else {
|
|
304 if (Signed)
|
|
305 OS << format(" %+" PRId64, (int64_t)Operands[Operand]);
|
|
306 else if (Opcode != DW_OP_entry_value &&
|
|
307 Opcode != DW_OP_GNU_entry_value)
|
|
308 OS << format(" 0x%" PRIx64, Operands[Operand]);
|
|
309 }
|
|
310 }
|
|
311 return true;
|
|
312 }
|
|
313
|
|
314 void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo,
|
|
315 DWARFUnit *U, bool IsEH) const {
|
|
316 uint32_t EntryValExprSize = 0;
|
|
317 for (auto &Op : *this) {
|
|
318 if (!Op.print(OS, this, RegInfo, U, IsEH)) {
|
|
319 uint64_t FailOffset = Op.getEndOffset();
|
|
320 while (FailOffset < Data.getData().size())
|
|
321 OS << format(" %02x", Data.getU8(&FailOffset));
|
|
322 return;
|
|
323 }
|
|
324
|
|
325 if (Op.getCode() == DW_OP_entry_value ||
|
|
326 Op.getCode() == DW_OP_GNU_entry_value) {
|
|
327 OS << "(";
|
|
328 EntryValExprSize = Op.getRawOperand(0);
|
|
329 continue;
|
|
330 }
|
|
331
|
|
332 if (EntryValExprSize) {
|
|
333 EntryValExprSize--;
|
|
334 if (EntryValExprSize == 0)
|
|
335 OS << ")";
|
|
336 }
|
|
337
|
|
338 if (Op.getEndOffset() < Data.getData().size())
|
|
339 OS << ", ";
|
|
340 }
|
|
341 }
|
|
342
|
|
343 bool DWARFExpression::Operation::verify(DWARFUnit *U) {
|
|
344
|
|
345 for (unsigned Operand = 0; Operand < 2; ++Operand) {
|
|
346 unsigned Size = Desc.Op[Operand];
|
|
347
|
|
348 if (Size == Operation::SizeNA)
|
|
349 break;
|
|
350
|
|
351 if (Size == Operation::BaseTypeRef) {
|
173
|
352 // For DW_OP_convert the operand may be 0 to indicate that conversion to
|
|
353 // the generic type should be done, so don't look up a base type in that
|
|
354 // case. The same holds for DW_OP_reinterpret, which is currently not
|
|
355 // supported.
|
|
356 if (Opcode == DW_OP_convert && Operands[Operand] == 0)
|
|
357 continue;
|
150
|
358 auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]);
|
|
359 if (!Die || Die.getTag() != dwarf::DW_TAG_base_type) {
|
|
360 Error = true;
|
|
361 return false;
|
|
362 }
|
|
363 }
|
|
364 }
|
|
365
|
|
366 return true;
|
|
367 }
|
|
368
|
|
369 bool DWARFExpression::verify(DWARFUnit *U) {
|
|
370 for (auto &Op : *this)
|
|
371 if (!Op.verify(U))
|
|
372 return false;
|
|
373
|
|
374 return true;
|
|
375 }
|
|
376
|
|
377 } // namespace llvm
|