/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp
Line | Count | Source (jump to first uncovered line) |
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/BinaryFormat/Dwarf.h" |
12 | | #include "llvm/MC/MCRegisterInfo.h" |
13 | | #include "llvm/Support/Format.h" |
14 | | #include <cassert> |
15 | | #include <cstdint> |
16 | | #include <vector> |
17 | | |
18 | | using namespace llvm; |
19 | | using namespace dwarf; |
20 | | |
21 | | namespace llvm { |
22 | | |
23 | | typedef std::vector<DWARFExpression::Operation::Description> DescVector; |
24 | | |
25 | 779 | static DescVector getDescriptions() { |
26 | 779 | DescVector Descriptions; |
27 | 779 | typedef DWARFExpression::Operation Op; |
28 | 779 | typedef Op::Description Desc; |
29 | 779 | |
30 | 779 | Descriptions.resize(0xff); |
31 | 779 | Descriptions[DW_OP_addr] = Desc(Op::Dwarf2, Op::SizeAddr); |
32 | 779 | Descriptions[DW_OP_deref] = Desc(Op::Dwarf2); |
33 | 779 | Descriptions[DW_OP_const1u] = Desc(Op::Dwarf2, Op::Size1); |
34 | 779 | Descriptions[DW_OP_const1s] = Desc(Op::Dwarf2, Op::SignedSize1); |
35 | 779 | Descriptions[DW_OP_const2u] = Desc(Op::Dwarf2, Op::Size2); |
36 | 779 | Descriptions[DW_OP_const2s] = Desc(Op::Dwarf2, Op::SignedSize2); |
37 | 779 | Descriptions[DW_OP_const4u] = Desc(Op::Dwarf2, Op::Size4); |
38 | 779 | Descriptions[DW_OP_const4s] = Desc(Op::Dwarf2, Op::SignedSize4); |
39 | 779 | Descriptions[DW_OP_const8u] = Desc(Op::Dwarf2, Op::Size8); |
40 | 779 | Descriptions[DW_OP_const8s] = Desc(Op::Dwarf2, Op::SignedSize8); |
41 | 779 | Descriptions[DW_OP_constu] = Desc(Op::Dwarf2, Op::SizeLEB); |
42 | 779 | Descriptions[DW_OP_consts] = Desc(Op::Dwarf2, Op::SignedSizeLEB); |
43 | 779 | Descriptions[DW_OP_dup] = Desc(Op::Dwarf2); |
44 | 779 | Descriptions[DW_OP_drop] = Desc(Op::Dwarf2); |
45 | 779 | Descriptions[DW_OP_over] = Desc(Op::Dwarf2); |
46 | 779 | Descriptions[DW_OP_pick] = Desc(Op::Dwarf2, Op::Size1); |
47 | 779 | Descriptions[DW_OP_swap] = Desc(Op::Dwarf2); |
48 | 779 | Descriptions[DW_OP_rot] = Desc(Op::Dwarf2); |
49 | 779 | Descriptions[DW_OP_xderef] = Desc(Op::Dwarf2); |
50 | 779 | Descriptions[DW_OP_abs] = Desc(Op::Dwarf2); |
51 | 779 | Descriptions[DW_OP_and] = Desc(Op::Dwarf2); |
52 | 779 | Descriptions[DW_OP_div] = Desc(Op::Dwarf2); |
53 | 779 | Descriptions[DW_OP_minus] = Desc(Op::Dwarf2); |
54 | 779 | Descriptions[DW_OP_mod] = Desc(Op::Dwarf2); |
55 | 779 | Descriptions[DW_OP_mul] = Desc(Op::Dwarf2); |
56 | 779 | Descriptions[DW_OP_neg] = Desc(Op::Dwarf2); |
57 | 779 | Descriptions[DW_OP_not] = Desc(Op::Dwarf2); |
58 | 779 | Descriptions[DW_OP_or] = Desc(Op::Dwarf2); |
59 | 779 | Descriptions[DW_OP_plus] = Desc(Op::Dwarf2); |
60 | 779 | Descriptions[DW_OP_plus_uconst] = Desc(Op::Dwarf2, Op::SizeLEB); |
61 | 779 | Descriptions[DW_OP_shl] = Desc(Op::Dwarf2); |
62 | 779 | Descriptions[DW_OP_shr] = Desc(Op::Dwarf2); |
63 | 779 | Descriptions[DW_OP_shra] = Desc(Op::Dwarf2); |
64 | 779 | Descriptions[DW_OP_xor] = Desc(Op::Dwarf2); |
65 | 779 | Descriptions[DW_OP_skip] = Desc(Op::Dwarf2, Op::SignedSize2); |
66 | 779 | Descriptions[DW_OP_bra] = Desc(Op::Dwarf2, Op::SignedSize2); |
67 | 779 | Descriptions[DW_OP_eq] = Desc(Op::Dwarf2); |
68 | 779 | Descriptions[DW_OP_ge] = Desc(Op::Dwarf2); |
69 | 779 | Descriptions[DW_OP_gt] = Desc(Op::Dwarf2); |
70 | 779 | Descriptions[DW_OP_le] = Desc(Op::Dwarf2); |
71 | 779 | Descriptions[DW_OP_lt] = Desc(Op::Dwarf2); |
72 | 779 | Descriptions[DW_OP_ne] = Desc(Op::Dwarf2); |
73 | 25.7k | for (uint16_t LA = DW_OP_lit0; LA <= DW_OP_lit31; ++LA24.9k ) |
74 | 24.9k | Descriptions[LA] = Desc(Op::Dwarf2); |
75 | 25.7k | for (uint16_t LA = DW_OP_reg0; LA <= DW_OP_reg31; ++LA24.9k ) |
76 | 24.9k | Descriptions[LA] = Desc(Op::Dwarf2); |
77 | 25.7k | for (uint16_t LA = DW_OP_breg0; LA <= DW_OP_breg31; ++LA24.9k ) |
78 | 24.9k | Descriptions[LA] = Desc(Op::Dwarf2, Op::SignedSizeLEB); |
79 | 779 | Descriptions[DW_OP_regx] = Desc(Op::Dwarf2, Op::SizeLEB); |
80 | 779 | Descriptions[DW_OP_fbreg] = Desc(Op::Dwarf2, Op::SignedSizeLEB); |
81 | 779 | Descriptions[DW_OP_bregx] = Desc(Op::Dwarf2, Op::SizeLEB, Op::SignedSizeLEB); |
82 | 779 | Descriptions[DW_OP_piece] = Desc(Op::Dwarf2, Op::SizeLEB); |
83 | 779 | Descriptions[DW_OP_deref_size] = Desc(Op::Dwarf2, Op::Size1); |
84 | 779 | Descriptions[DW_OP_xderef_size] = Desc(Op::Dwarf2, Op::Size1); |
85 | 779 | Descriptions[DW_OP_nop] = Desc(Op::Dwarf2); |
86 | 779 | Descriptions[DW_OP_push_object_address] = Desc(Op::Dwarf3); |
87 | 779 | Descriptions[DW_OP_call2] = Desc(Op::Dwarf3, Op::Size2); |
88 | 779 | Descriptions[DW_OP_call4] = Desc(Op::Dwarf3, Op::Size4); |
89 | 779 | Descriptions[DW_OP_call_ref] = Desc(Op::Dwarf3, Op::SizeRefAddr); |
90 | 779 | Descriptions[DW_OP_form_tls_address] = Desc(Op::Dwarf3); |
91 | 779 | Descriptions[DW_OP_call_frame_cfa] = Desc(Op::Dwarf3); |
92 | 779 | Descriptions[DW_OP_bit_piece] = Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeLEB); |
93 | 779 | Descriptions[DW_OP_implicit_value] = |
94 | 779 | Desc(Op::Dwarf3, Op::SizeLEB, Op::SizeBlock); |
95 | 779 | Descriptions[DW_OP_stack_value] = Desc(Op::Dwarf3); |
96 | 779 | Descriptions[DW_OP_GNU_push_tls_address] = Desc(Op::Dwarf3); |
97 | 779 | Descriptions[DW_OP_addrx] = Desc(Op::Dwarf4, Op::SizeLEB); |
98 | 779 | Descriptions[DW_OP_GNU_addr_index] = Desc(Op::Dwarf4, Op::SizeLEB); |
99 | 779 | Descriptions[DW_OP_GNU_const_index] = Desc(Op::Dwarf4, Op::SizeLEB); |
100 | 779 | Descriptions[DW_OP_GNU_entry_value] = Desc(Op::Dwarf4, Op::SizeLEB); |
101 | 779 | |
102 | 779 | Descriptions[DW_OP_convert] = Desc(Op::Dwarf5, Op::BaseTypeRef); |
103 | 779 | Descriptions[DW_OP_entry_value] = Desc(Op::Dwarf5, Op::SizeLEB); |
104 | 779 | |
105 | 779 | return Descriptions; |
106 | 779 | } |
107 | | |
108 | 5.46k | static DWARFExpression::Operation::Description getOpDesc(unsigned OpCode) { |
109 | 5.46k | // FIXME: Make this constexpr once all compilers are smart enough to do it. |
110 | 5.46k | static DescVector Descriptions = getDescriptions(); |
111 | 5.46k | // Handle possible corrupted or unsupported operation. |
112 | 5.46k | if (OpCode >= Descriptions.size()) |
113 | 3 | return {}; |
114 | 5.46k | return Descriptions[OpCode]; |
115 | 5.46k | } |
116 | | |
117 | 0 | static uint8_t getRefAddrSize(uint8_t AddrSize, uint16_t Version) { |
118 | 0 | return (Version == 2) ? AddrSize : 4; |
119 | 0 | } |
120 | | |
121 | | bool DWARFExpression::Operation::extract(DataExtractor Data, uint16_t Version, |
122 | 5.46k | uint8_t AddressSize, uint32_t Offset) { |
123 | 5.46k | Opcode = Data.getU8(&Offset); |
124 | 5.46k | |
125 | 5.46k | Desc = getOpDesc(Opcode); |
126 | 5.46k | if (Desc.Version == Operation::DwarfNA) { |
127 | 3 | EndOffset = Offset; |
128 | 3 | return false; |
129 | 3 | } |
130 | 5.46k | |
131 | 8.48k | for (unsigned Operand = 0; 5.46k Operand < 2; ++Operand3.02k ) { |
132 | 8.45k | unsigned Size = Desc.Op[Operand]; |
133 | 8.45k | unsigned Signed = Size & Operation::SignBit; |
134 | 8.45k | |
135 | 8.45k | if (Size == Operation::SizeNA) |
136 | 5.42k | break; |
137 | 3.02k | |
138 | 3.02k | switch (Size & ~Operation::SignBit) { |
139 | 3.02k | case Operation::Size1: |
140 | 0 | Operands[Operand] = Data.getU8(&Offset); |
141 | 0 | if (Signed) |
142 | 0 | Operands[Operand] = (int8_t)Operands[Operand]; |
143 | 0 | break; |
144 | 3.02k | case Operation::Size2: |
145 | 0 | Operands[Operand] = Data.getU16(&Offset); |
146 | 0 | if (Signed) |
147 | 0 | Operands[Operand] = (int16_t)Operands[Operand]; |
148 | 0 | break; |
149 | 3.02k | case Operation::Size4: |
150 | 1 | Operands[Operand] = Data.getU32(&Offset); |
151 | 1 | if (Signed) |
152 | 0 | Operands[Operand] = (int32_t)Operands[Operand]; |
153 | 1 | break; |
154 | 3.02k | case Operation::Size8: |
155 | 8 | Operands[Operand] = Data.getU64(&Offset); |
156 | 8 | break; |
157 | 3.02k | case Operation::SizeAddr: |
158 | 840 | if (AddressSize == 8) { |
159 | 810 | Operands[Operand] = Data.getU64(&Offset); |
160 | 810 | } else if (30 AddressSize == 430 ) { |
161 | 30 | Operands[Operand] = Data.getU32(&Offset); |
162 | 30 | } else { |
163 | 0 | assert(AddressSize == 2); |
164 | 0 | Operands[Operand] = Data.getU16(&Offset); |
165 | 0 | } |
166 | 840 | break; |
167 | 3.02k | case Operation::SizeRefAddr: |
168 | 0 | if (getRefAddrSize(AddressSize, Version) == 8) { |
169 | 0 | Operands[Operand] = Data.getU64(&Offset); |
170 | 0 | } else if (getRefAddrSize(AddressSize, Version) == 4) { |
171 | 0 | Operands[Operand] = Data.getU32(&Offset); |
172 | 0 | } else { |
173 | 0 | assert(getRefAddrSize(AddressSize, Version) == 2); |
174 | 0 | Operands[Operand] = Data.getU16(&Offset); |
175 | 0 | } |
176 | 0 | break; |
177 | 3.02k | case Operation::SizeLEB: |
178 | 2.14k | if (Signed) |
179 | 1.43k | Operands[Operand] = Data.getSLEB128(&Offset); |
180 | 707 | else |
181 | 707 | Operands[Operand] = Data.getULEB128(&Offset); |
182 | 2.14k | break; |
183 | 3.02k | case Operation::BaseTypeRef: |
184 | 35 | Operands[Operand] = Data.getULEB128(&Offset); |
185 | 35 | break; |
186 | 3.02k | case Operation::SizeBlock: |
187 | 0 | // We need a size, so this cannot be the first operand |
188 | 0 | if (Operand == 0) |
189 | 0 | return false; |
190 | 0 | // Store the offset of the block as the value. |
191 | 0 | Operands[Operand] = Offset; |
192 | 0 | Offset += Operands[Operand - 1]; |
193 | 0 | break; |
194 | 0 | default: |
195 | 0 | llvm_unreachable("Unknown DWARFExpression Op size"); |
196 | 3.02k | } |
197 | 3.02k | |
198 | 3.02k | OperandEndOffsets[Operand] = Offset; |
199 | 3.02k | } |
200 | 5.46k | |
201 | 5.46k | EndOffset = Offset; |
202 | 5.46k | return true; |
203 | 5.46k | } |
204 | | |
205 | | static bool prettyPrintRegisterOp(raw_ostream &OS, uint8_t Opcode, |
206 | | uint64_t Operands[2], |
207 | 1.30k | const MCRegisterInfo *MRI, bool isEH) { |
208 | 1.30k | if (!MRI) |
209 | 53 | return false; |
210 | 1.25k | |
211 | 1.25k | uint64_t DwarfRegNum; |
212 | 1.25k | unsigned OpNum = 0; |
213 | 1.25k | |
214 | 1.25k | if (Opcode == DW_OP_bregx || Opcode == DW_OP_regx) |
215 | 14 | DwarfRegNum = Operands[OpNum++]; |
216 | 1.24k | else if (Opcode >= DW_OP_breg0 && Opcode < DW_OP_bregx214 ) |
217 | 214 | DwarfRegNum = Opcode - DW_OP_breg0; |
218 | 1.02k | else |
219 | 1.02k | DwarfRegNum = Opcode - DW_OP_reg0; |
220 | 1.25k | |
221 | 1.25k | int LLVMRegNum = MRI->getLLVMRegNum(DwarfRegNum, isEH); |
222 | 1.25k | if (LLVMRegNum >= 0) { |
223 | 1.25k | if (const char *RegName = MRI->getName(LLVMRegNum)) { |
224 | 1.25k | if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg31228 ) || |
225 | 1.25k | Opcode == DW_OP_bregx1.04k ) |
226 | 214 | OS << format(" %s%+" PRId64, RegName, Operands[OpNum]); |
227 | 1.04k | else |
228 | 1.04k | OS << ' ' << RegName; |
229 | 1.25k | return true; |
230 | 1.25k | } |
231 | 0 | } |
232 | 0 | |
233 | 0 | return false; |
234 | 0 | } |
235 | | |
236 | | bool DWARFExpression::Operation::print(raw_ostream &OS, |
237 | | const DWARFExpression *Expr, |
238 | | const MCRegisterInfo *RegInfo, |
239 | | DWARFUnit *U, |
240 | 2.94k | bool isEH) { |
241 | 2.94k | if (Error) { |
242 | 2 | OS << "<decoding error>"; |
243 | 2 | return false; |
244 | 2 | } |
245 | 2.94k | |
246 | 2.94k | StringRef Name = OperationEncodingString(Opcode); |
247 | 2.94k | assert(!Name.empty() && "DW_OP has no name!"); |
248 | 2.94k | OS << Name; |
249 | 2.94k | |
250 | 2.94k | if ((Opcode >= DW_OP_breg0 && Opcode <= DW_OP_breg311.12k ) || |
251 | 2.94k | (2.72k Opcode >= DW_OP_reg02.72k && Opcode <= DW_OP_reg311.98k ) || |
252 | 2.94k | Opcode == DW_OP_bregx1.65k || Opcode == DW_OP_regx1.65k ) |
253 | 1.30k | if (prettyPrintRegisterOp(OS, Opcode, Operands, RegInfo, isEH)) |
254 | 1.25k | return true; |
255 | 1.68k | |
256 | 3.03k | for (unsigned Operand = 0; 1.68k Operand < 2; ++Operand1.34k ) { |
257 | 3.02k | unsigned Size = Desc.Op[Operand]; |
258 | 3.02k | unsigned Signed = Size & Operation::SignBit; |
259 | 3.02k | |
260 | 3.02k | if (Size == Operation::SizeNA) |
261 | 1.68k | break; |
262 | 1.34k | |
263 | 1.34k | if (Size == Operation::BaseTypeRef && U17 ) { |
264 | 17 | auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]); |
265 | 17 | if (Die && Die.getTag() == dwarf::DW_TAG_base_type15 ) { |
266 | 15 | OS << format(" (0x%08x)", U->getOffset() + Operands[Operand]); |
267 | 15 | if (auto Name = Die.find(dwarf::DW_AT_name)) |
268 | 15 | OS << " \"" << Name->getAsCString() << "\""; |
269 | 15 | } else { |
270 | 2 | OS << format(" <invalid base_type ref: 0x%" PRIx64 ">", |
271 | 2 | Operands[Operand]); |
272 | 2 | } |
273 | 1.32k | } else if (Size == Operation::SizeBlock) { |
274 | 0 | uint32_t Offset = Operands[Operand]; |
275 | 0 | for (unsigned i = 0; i < Operands[Operand - 1]; ++i) |
276 | 0 | OS << format(" 0x%02x", Expr->Data.getU8(&Offset)); |
277 | 1.32k | } else { |
278 | 1.32k | if (Signed) |
279 | 616 | OS << format(" %+" PRId64, (int64_t)Operands[Operand]); |
280 | 711 | else if (Opcode != DW_OP_entry_value && |
281 | 711 | Opcode != DW_OP_GNU_entry_value709 ) |
282 | 708 | OS << format(" 0x%" PRIx64, Operands[Operand]); |
283 | 1.32k | } |
284 | 1.34k | } |
285 | 1.68k | return true; |
286 | 1.68k | } |
287 | | |
288 | | void DWARFExpression::print(raw_ostream &OS, const MCRegisterInfo *RegInfo, |
289 | 2.44k | DWARFUnit *U, bool IsEH) const { |
290 | 2.44k | uint32_t EntryValExprSize = 0; |
291 | 2.94k | for (auto &Op : *this) { |
292 | 2.94k | if (!Op.print(OS, this, RegInfo, U, IsEH)) { |
293 | 2 | uint32_t FailOffset = Op.getEndOffset(); |
294 | 2 | while (FailOffset < Data.getData().size()) |
295 | 0 | OS << format(" %02x", Data.getU8(&FailOffset)); |
296 | 2 | return; |
297 | 2 | } |
298 | 2.94k | |
299 | 2.94k | if (Op.getCode() == DW_OP_entry_value || |
300 | 2.94k | Op.getCode() == DW_OP_GNU_entry_value2.94k ) { |
301 | 3 | OS << "("; |
302 | 3 | EntryValExprSize = Op.getRawOperand(0); |
303 | 3 | continue; |
304 | 3 | } |
305 | 2.94k | |
306 | 2.94k | if (EntryValExprSize) { |
307 | 3 | EntryValExprSize--; |
308 | 3 | if (EntryValExprSize == 0) |
309 | 3 | OS << ")"; |
310 | 3 | } |
311 | 2.94k | |
312 | 2.94k | if (Op.getEndOffset() < Data.getData().size()) |
313 | 500 | OS << ", "; |
314 | 2.94k | } |
315 | 2.44k | } |
316 | | |
317 | 186 | bool DWARFExpression::Operation::verify(DWARFUnit *U) { |
318 | 186 | |
319 | 338 | for (unsigned Operand = 0; Operand < 2; ++Operand152 ) { |
320 | 338 | unsigned Size = Desc.Op[Operand]; |
321 | 338 | |
322 | 338 | if (Size == Operation::SizeNA) |
323 | 185 | break; |
324 | 153 | |
325 | 153 | if (Size == Operation::BaseTypeRef) { |
326 | 6 | auto Die = U->getDIEForOffset(U->getOffset() + Operands[Operand]); |
327 | 6 | if (!Die || Die.getTag() != dwarf::DW_TAG_base_type5 ) { |
328 | 1 | Error = true; |
329 | 1 | return false; |
330 | 1 | } |
331 | 6 | } |
332 | 153 | } |
333 | 186 | |
334 | 186 | return true185 ; |
335 | 186 | } |
336 | | |
337 | 157 | bool DWARFExpression::verify(DWARFUnit *U) { |
338 | 157 | for (auto &Op : *this) |
339 | 186 | if (!Op.verify(U)) |
340 | 1 | return false; |
341 | 157 | |
342 | 157 | return true156 ; |
343 | 157 | } |
344 | | |
345 | | } // namespace llvm |