LLVM: lib/DebugInfo/DWARF/LowLevel/DWARFUnwindTable.cpp Source File (original) (raw)
41 std::optional<uint32_t> AddrSpace) {
42 return {RegPlusOffset, RegNum, Offset, AddrSpace, false};
43}
47 std::optional<uint32_t> AddrSpace) {
48 return {RegPlusOffset, RegNum, Offset, AddrSpace, true};
49}
52 return {Expr, false};
53}
56 return {Expr, true};
57}
60 if (Kind != RHS.Kind)
61 return false;
62 switch (Kind) {
66 return true;
68 return Offset == RHS.Offset && Dereference == RHS.Dereference;
70 return RegNum == RHS.RegNum && Offset == RHS.Offset &&
71 Dereference == RHS.Dereference;
73 return *Expr == *RHS.Expr && Dereference == RHS.Dereference;
75 return Offset == RHS.Offset;
76 }
77 return false;
78}
83
85
86
87 std::vector<std::pair<UnwindLocation, RegisterLocations>> States;
89 switch (Inst.Opcode) {
90 case dwarf::DW_CFA_set_loc: {
91
92
93
94
95
96
97
99 if (!NewAddress)
101 if (*NewAddress <= Row.getAddress())
104 "%s with adrress 0x%" PRIx64 " which must be greater than the "
105 "current row address 0x%" PRIx64,
107 Row.getAddress());
108 Rows.push_back(Row);
109 Row.setAddress(*NewAddress);
110 break;
111 }
112
113 case dwarf::DW_CFA_advance_loc:
114 case dwarf::DW_CFA_advance_loc1:
115 case dwarf::DW_CFA_advance_loc2:
116 case dwarf::DW_CFA_advance_loc4: {
117
118
119
120
121
122
123 Rows.push_back(Row);
126 return Offset.takeError();
127 Row.slideAddress(*Offset);
128 break;
129 }
130
131 case dwarf::DW_CFA_restore:
132 case dwarf::DW_CFA_restore_extended: {
133
134
135
136
137 if (InitialLocs == nullptr)
142 if (!RegNum)
144 if (std::optional O =
146 Row.getRegisterLocations().setRegisterLocation(*RegNum, *O);
147 else
148 Row.getRegisterLocations().removeRegisterLocation(*RegNum);
149 break;
150 }
151
152 case dwarf::DW_CFA_offset:
153 case dwarf::DW_CFA_offset_extended:
154 case dwarf::DW_CFA_offset_extended_sf: {
156 if (!RegNum)
160 return Offset.takeError();
161 Row.getRegisterLocations().setRegisterLocation(
163 break;
164 }
165
166 case dwarf::DW_CFA_nop:
167 break;
168
169 case dwarf::DW_CFA_remember_state:
170 States.push_back(
171 std::make_pair(Row.getCFAValue(), Row.getRegisterLocations()));
172 break;
173
174 case dwarf::DW_CFA_restore_state:
175 if (States.empty())
177 "DW_CFA_restore_state without a matching "
178 "previous DW_CFA_remember_state");
179 Row.getCFAValue() = States.back().first;
180 Row.getRegisterLocations() = States.back().second;
181 States.pop_back();
182 break;
183
184 case dwarf::DW_CFA_GNU_window_save:
185 switch (CFIP.triple()) {
189
190
191
192
193
194
195 constexpr uint32_t AArch64DWARFPAuthRaState = 34;
196 auto LRLoc = Row.getRegisterLocations().getRegisterLocation(
197 AArch64DWARFPAuthRaState);
198 if (LRLoc) {
200
201 LRLoc->setConstant(LRLoc->getConstant() ^ 1);
202 Row.getRegisterLocations().setRegisterLocation(
203 AArch64DWARFPAuthRaState, *LRLoc);
204 } else {
207 "%s encountered when existing rule for this register is not "
208 "a constant",
210 }
211 } else {
212 Row.getRegisterLocations().setRegisterLocation(
214 }
215 break;
216 }
217
221 for (uint32_t RegNum = 16; RegNum < 32; ++RegNum) {
222 Row.getRegisterLocations().setRegisterLocation(
224 }
225 break;
226
227 default: {
230 "DW_CFA opcode %#x is not supported for architecture %s",
232
233 break;
234 }
235 }
236 break;
237
238 case dwarf::DW_CFA_AARCH64_negate_ra_state_with_pc: {
239 constexpr uint32_t AArch64DWARFPAuthRaState = 34;
240 auto LRLoc = Row.getRegisterLocations().getRegisterLocation(
241 AArch64DWARFPAuthRaState);
242 if (LRLoc) {
244
245 LRLoc->setConstant(LRLoc->getConstant() ^ 0x3);
246 } else {
249 "%s encountered when existing rule for this register is not "
250 "a constant",
252 }
253 } else {
254 Row.getRegisterLocations().setRegisterLocation(
256 }
257 break;
258 }
259
260 case dwarf::DW_CFA_undefined: {
262 if (!RegNum)
264 Row.getRegisterLocations().setRegisterLocation(
266 break;
267 }
268
269 case dwarf::DW_CFA_same_value: {
271 if (!RegNum)
273 Row.getRegisterLocations().setRegisterLocation(
275 break;
276 }
277
278 case dwarf::DW_CFA_GNU_args_size:
279 break;
280
281 case dwarf::DW_CFA_register: {
283 if (!RegNum)
286 if (!NewRegNum)
288 Row.getRegisterLocations().setRegisterLocation(
290 break;
291 }
292
293 case dwarf::DW_CFA_val_offset:
294 case dwarf::DW_CFA_val_offset_sf: {
296 if (!RegNum)
300 return Offset.takeError();
301 Row.getRegisterLocations().setRegisterLocation(
303 break;
304 }
305
306 case dwarf::DW_CFA_expression: {
308 if (!RegNum)
310 Row.getRegisterLocations().setRegisterLocation(
312 break;
313 }
314
315 case dwarf::DW_CFA_val_expression: {
317 if (!RegNum)
319 Row.getRegisterLocations().setRegisterLocation(
321 break;
322 }
323
324 case dwarf::DW_CFA_def_cfa_register: {
326 if (!RegNum)
329 Row.getCFAValue() =
331 else
332 Row.getCFAValue().setRegister(*RegNum);
333 break;
334 }
335
336 case dwarf::DW_CFA_def_cfa_offset:
337 case dwarf::DW_CFA_def_cfa_offset_sf: {
340 return Offset.takeError();
344 "%s found when CFA rule was not RegPlusOffset",
346 }
347 Row.getCFAValue().setOffset(*Offset);
348 break;
349 }
350
351 case dwarf::DW_CFA_def_cfa:
352 case dwarf::DW_CFA_def_cfa_sf: {
354 if (!RegNum)
358 return Offset.takeError();
359 Row.getCFAValue() =
361 break;
362 }
363
364 case dwarf::DW_CFA_LLVM_def_aspace_cfa:
365 case dwarf::DW_CFA_LLVM_def_aspace_cfa_sf: {
367 if (!RegNum)
371 return Offset.takeError();
373 Inst.getOperandAsUnsigned(CFIP, 2);
374 if (!CFAAddrSpace)
377 *RegNum, *Offset, *CFAAddrSpace);
378 break;
379 }
380
381 case dwarf::DW_CFA_def_cfa_expression:
382 Row.getCFAValue() =
384 break;
385 }
386 }
387 return Rows;
388}