annotate llvm/lib/DebugInfo/DWARF/DWARFExpression.cpp @ 180:680fa57a2f20

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