1//===----------------------------------------------------------------------===//
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// Processor specific interpretation of DWARF unwind info.
9//
10//===----------------------------------------------------------------------===//
11
12#ifndef __DWARF_INSTRUCTIONS_HPP__
13#define __DWARF_INSTRUCTIONS_HPP__
14
15#include <stdint.h>
16#include <stdio.h>
17#include <stdlib.h>
18
19#include "DwarfParser.hpp"
20#include "Registers.hpp"
21#include "config.h"
22#include "dwarf2.h"
23#include "libunwind_ext.h"
24
25namespace libunwind {
26
27
28/// DwarfInstructions maps abstract DWARF unwind instructions to a particular
29/// architecture
30template <typename A, typename R>
31class DwarfInstructions {
32public:
33 typedef typename A::pint_t pint_t;
34 typedef typename A::sint_t sint_t;
35
36 static int stepWithDwarf(A &addressSpace,
37 typename R::link_hardened_reg_arg_t pc,
38 pint_t fdeStart, R &registers, bool &isSignalFrame,
39 bool stage2);
40
41private:
42
43 enum {
44 DW_X86_64_RET_ADDR = 16
45 };
46
47 enum {
48 DW_X86_RET_ADDR = 8
49 };
50
51 typedef typename CFI_Parser<A>::RegisterLocation RegisterLocation;
52 typedef typename CFI_Parser<A>::PrologInfo PrologInfo;
53 typedef typename CFI_Parser<A>::FDE_Info FDE_Info;
54 typedef typename CFI_Parser<A>::CIE_Info CIE_Info;
55
56 static pint_t evaluateExpression(pint_t expression, A &addressSpace,
57 const R &registers,
58 pint_t initialStackValue);
59 static pint_t getSavedRegister(A &addressSpace, const R &registers,
60 pint_t cfa, const RegisterLocation &savedReg);
61 static double getSavedFloatRegister(A &addressSpace, const R &registers,
62 pint_t cfa, const RegisterLocation &savedReg);
63 static v128 getSavedVectorRegister(A &addressSpace, const R &registers,
64 pint_t cfa, const RegisterLocation &savedReg);
65
66 static pint_t getCFA(A &addressSpace, const PrologInfo &prolog,
67 const R &registers) {
68 if (prolog.cfaRegister != 0) {
69 uintptr_t cfaRegister = registers.getRegister((int)prolog.cfaRegister);
70 return (pint_t)(cfaRegister + prolog.cfaRegisterOffset);
71 }
72 if (prolog.cfaExpression != 0)
73 return evaluateExpression(expression: (pint_t)prolog.cfaExpression, addressSpace,
74 registers, initialStackValue: 0);
75 assert(0 && "getCFA(): unknown location");
76 __builtin_unreachable();
77 }
78#if defined(_LIBUNWIND_TARGET_AARCH64)
79 enum RASignStatus {
80 RANotSigned = 0,
81 RASigned = 1,
82 RASignedWithPC = 2,
83 };
84 static RASignStatus getReturnAddressSignStatus(A &addressSpace, R registers,
85 pint_t cfa,
86 PrologInfo &prolog);
87#endif
88};
89
90template <typename R>
91auto getSparcWCookie(const R &r, int) -> decltype(r.getWCookie()) {
92 return r.getWCookie();
93}
94template <typename R> uint64_t getSparcWCookie(const R &, long) {
95 return 0;
96}
97
98template <typename A, typename R>
99typename A::pint_t DwarfInstructions<A, R>::getSavedRegister(
100 A &addressSpace, const R &registers, pint_t cfa,
101 const RegisterLocation &savedReg) {
102 switch (savedReg.location) {
103 case CFI_Parser<A>::kRegisterInCFA:
104 return (pint_t)addressSpace.getRegister(cfa + (pint_t)savedReg.value);
105
106 case CFI_Parser<A>::kRegisterInCFADecrypt: // sparc64 specific
107 return (pint_t)(addressSpace.getP(cfa + (pint_t)savedReg.value) ^
108 getSparcWCookie(registers, 0));
109
110 case CFI_Parser<A>::kRegisterAtExpression:
111 return (pint_t)addressSpace.getRegister(evaluateExpression(
112 expression: (pint_t)savedReg.value, addressSpace, registers, initialStackValue: cfa));
113
114 case CFI_Parser<A>::kRegisterIsExpression:
115 return evaluateExpression(expression: (pint_t)savedReg.value, addressSpace,
116 registers, initialStackValue: cfa);
117
118 case CFI_Parser<A>::kRegisterInRegister:
119 return registers.getRegister((int)savedReg.value);
120
121 case CFI_Parser<A>::kRegisterUndefined:
122 return 0;
123
124 case CFI_Parser<A>::kRegisterIsPseudo:
125#if defined(_LIBUNWIND_TARGET_AARCH64)
126 return savedReg.value;
127#endif
128 case CFI_Parser<A>::kRegisterUnused:
129 case CFI_Parser<A>::kRegisterOffsetFromCFA:
130 // FIX ME
131 break;
132 }
133 _LIBUNWIND_ABORT("unsupported restore location for register");
134}
135
136template <typename A, typename R>
137double DwarfInstructions<A, R>::getSavedFloatRegister(
138 A &addressSpace, const R &registers, pint_t cfa,
139 const RegisterLocation &savedReg) {
140 switch (savedReg.location) {
141 case CFI_Parser<A>::kRegisterInCFA:
142 return addressSpace.getDouble(cfa + (pint_t)savedReg.value);
143
144 case CFI_Parser<A>::kRegisterAtExpression:
145 return addressSpace.getDouble(
146 evaluateExpression(expression: (pint_t)savedReg.value, addressSpace,
147 registers, initialStackValue: cfa));
148 case CFI_Parser<A>::kRegisterUndefined:
149 return 0.0;
150 case CFI_Parser<A>::kRegisterInRegister:
151#ifndef _LIBUNWIND_TARGET_ARM
152 return registers.getFloatRegister((int)savedReg.value);
153#endif
154 case CFI_Parser<A>::kRegisterIsPseudo:
155 case CFI_Parser<A>::kRegisterIsExpression:
156 case CFI_Parser<A>::kRegisterUnused:
157 case CFI_Parser<A>::kRegisterOffsetFromCFA:
158 case CFI_Parser<A>::kRegisterInCFADecrypt:
159 // FIX ME
160 break;
161 }
162 _LIBUNWIND_ABORT("unsupported restore location for float register");
163}
164
165template <typename A, typename R>
166v128 DwarfInstructions<A, R>::getSavedVectorRegister(
167 A &addressSpace, const R &registers, pint_t cfa,
168 const RegisterLocation &savedReg) {
169 switch (savedReg.location) {
170 case CFI_Parser<A>::kRegisterInCFA:
171 return addressSpace.getVector(cfa + (pint_t)savedReg.value);
172
173 case CFI_Parser<A>::kRegisterAtExpression:
174 return addressSpace.getVector(
175 evaluateExpression(expression: (pint_t)savedReg.value, addressSpace,
176 registers, initialStackValue: cfa));
177
178 case CFI_Parser<A>::kRegisterIsPseudo:
179 case CFI_Parser<A>::kRegisterIsExpression:
180 case CFI_Parser<A>::kRegisterUnused:
181 case CFI_Parser<A>::kRegisterUndefined:
182 case CFI_Parser<A>::kRegisterOffsetFromCFA:
183 case CFI_Parser<A>::kRegisterInRegister:
184 case CFI_Parser<A>::kRegisterInCFADecrypt:
185 // FIX ME
186 break;
187 }
188 _LIBUNWIND_ABORT("unsupported restore location for vector register");
189}
190#if defined(_LIBUNWIND_TARGET_AARCH64)
191template <typename A, typename R>
192typename DwarfInstructions<A, R>::RASignStatus
193DwarfInstructions<A, R>::getReturnAddressSignStatus(A &addressSpace,
194 R registers, pint_t cfa,
195 PrologInfo &prolog) {
196 pint_t raSignState;
197 auto regloc = prolog.savedRegisters[UNW_AARCH64_RA_SIGN_STATE];
198 if (regloc.location == CFI_Parser<A>::kRegisterUnused)
199 raSignState = static_cast<pint_t>(regloc.value);
200 else
201 raSignState = getSavedRegister(addressSpace, registers, cfa, regloc);
202
203 // bits[1:0] describe how RA is signed.
204 assert((raSignState & 0x3) != 3 && "unexpected RA sign state");
205 return static_cast<RASignStatus>(raSignState & 0x3);
206}
207#endif
208
209template <typename A, typename R>
210int DwarfInstructions<A, R>::stepWithDwarf(
211 A &addressSpace, typename R::link_hardened_reg_arg_t pc, pint_t fdeStart,
212 R &registers, bool &isSignalFrame, bool stage2) {
213 FDE_Info fdeInfo;
214 CIE_Info cieInfo;
215 if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo,
216 &cieInfo) == NULL) {
217 PrologInfo prolog;
218 if (CFI_Parser<A>::template parseFDEInstructions<R>(
219 addressSpace, fdeInfo, cieInfo, pc, R::getArch(), &prolog)) {
220 // get pointer to cfa (architecture specific)
221 pint_t cfa = getCFA(addressSpace, prolog, registers);
222
223 (void)stage2;
224 // __unw_step_stage2 is not used for cross unwinding, so we use
225 // __aarch64__ rather than LIBUNWIND_TARGET_AARCH64 to make sure we are
226 // building for AArch64 natively.
227#if defined(__aarch64__) && !defined(__LFI__)
228 if (stage2 && cieInfo.mteTaggedFrame) {
229 pint_t sp = registers.getSP();
230 pint_t p = sp;
231 // AArch64 doesn't require the value of SP to be 16-byte aligned at
232 // all times, only at memory accesses and public interfaces [1]. Thus,
233 // a signal could arrive at a point where SP is not aligned properly.
234 // In that case, the kernel fixes up [2] the signal frame, but we
235 // still have a misaligned SP in the previous frame. If that signal
236 // handler caused stack unwinding, we would have an unaligned SP.
237 // We do not need to fix up the CFA, as that is the SP at a "public
238 // interface".
239 // [1]:
240 // https://github.com/ARM-software/abi-aa/blob/main/aapcs64/aapcs64.rst#622the-stack
241 // [2]:
242 // https://github.com/torvalds/linux/blob/1930a6e739c4b4a654a69164dbe39e554d228915/arch/arm64/kernel/signal.c#L718
243 p &= ~0xfULL;
244 // CFA is the bottom of the current stack frame.
245 for (; p < cfa; p += 16) {
246 __asm__ __volatile__(".arch armv8.5-a\n"
247 ".arch_extension memtag\n"
248 "stg %[Ptr], [%[Ptr]]\n"
249 :
250 : [Ptr] "r"(p)
251 : "memory");
252 }
253 }
254#endif
255 // restore registers that DWARF says were saved
256 R newRegisters = registers;
257
258 // Typically, the CFA is the stack pointer at the call site in
259 // the previous frame. However, there are scenarios in which this is not
260 // true. For example, if we switched to a new stack. In that case, the
261 // value of the previous SP might be indicated by a CFI directive.
262 //
263 // We set the SP here to the CFA, allowing for it to be overridden
264 // by a CFI directive later on.
265 newRegisters.setSP(cfa);
266
267 typename R::reg_t returnAddress = 0;
268 constexpr int lastReg = R::lastDwarfRegNum();
269 static_assert(static_cast<int>(CFI_Parser<A>::kMaxRegisterNumber) >=
270 lastReg,
271 "register range too large");
272 assert(lastReg >= (int)cieInfo.returnAddressRegister &&
273 "register range does not contain return address register");
274 for (int i = 0; i <= lastReg; ++i) {
275 if (prolog.savedRegisters[i].location !=
276 CFI_Parser<A>::kRegisterUnused) {
277 if (registers.validFloatRegister(i))
278 newRegisters.setFloatRegister(
279 i, getSavedFloatRegister(addressSpace, registers, cfa,
280 savedReg: prolog.savedRegisters[i]));
281 else if (registers.validVectorRegister(i))
282 newRegisters.setVectorRegister(
283 i, getSavedVectorRegister(addressSpace, registers, cfa,
284 savedReg: prolog.savedRegisters[i]));
285 else if (i == (int)cieInfo.returnAddressRegister)
286 returnAddress = getSavedRegister(addressSpace, registers, cfa,
287 savedReg: prolog.savedRegisters[i]);
288 else if (registers.validRegister(i))
289 newRegisters.setRegister(
290 i, getSavedRegister(addressSpace, registers, cfa,
291 savedReg: prolog.savedRegisters[i]));
292 else
293 return UNW_EBADREG;
294 } else if (i == (int)cieInfo.returnAddressRegister) {
295 // Leaf function keeps the return address in register and there is no
296 // explicit instructions how to restore it.
297 returnAddress = registers.getRegister(cieInfo.returnAddressRegister);
298 }
299 }
300
301 isSignalFrame = cieInfo.isSignalFrame;
302
303#if defined(_LIBUNWIND_TARGET_AARCH64)
304 // There are two ways of return address signing: pac-ret (enabled via
305 // -mbranch-protection=pac-ret) and ptrauth-returns (enabled as part of
306 // Apple's arm64e or experimental pauthtest ABI on Linux). The code
307 // below handles signed RA for ptrauth-returns, while pac-ret uses pacm
308 // instructions from the hint space.
309 //
310 // TODO: unify logic for both cases, see
311 // https://github.com/llvm/llvm-project/issues/160110
312#if defined(_LIBUNWIND_TARGET_AARCH64_AUTHENTICATED_UNWINDING)
313 if (getReturnAddressSignStatus(addressSpace, registers, cfa, prolog) ==
314 RASignedWithPC) {
315 newRegisters.setIPPAuthLR(returnAddress, prolog.ptrAuthDiversifier);
316 } else {
317 newRegisters.setIP(returnAddress);
318 }
319
320 // Simulate the step by replacing the register set with the new ones.
321 registers = newRegisters;
322
323 return UNW_STEP_SUCCESS;
324#else
325 // If the target is aarch64 then the return address may have been signed
326 // using the v8.3 pointer authentication extensions. The original
327 // return address needs to be authenticated before the return address is
328 // restored. autia1716 is used instead of autia as autia1716 assembles
329 // to a NOP on pre-v8.3a architectures.
330 RASignStatus RAState =
331 getReturnAddressSignStatus(addressSpace, registers, cfa, prolog);
332 if ((R::getArch() == REGISTERS_ARM64) && RAState != RANotSigned &&
333 returnAddress != 0) {
334#if !defined(_LIBUNWIND_IS_NATIVE_ONLY)
335 return UNW_ECROSSRASIGNING;
336#else
337 register unsigned long long x17 __asm("x17") = returnAddress;
338 register unsigned long long x16 __asm("x16") = cfa;
339
340 // We use the hint versions of the authentication instructions below to
341 // ensure they're assembled by the compiler even for targets with no
342 // FEAT_PAuth/FEAT_PAuth_LR support.
343 if (RAState == RASignedWithPC) {
344 register unsigned long long x15 __asm("x15") =
345 prolog.ptrAuthDiversifier;
346 if (cieInfo.addressesSignedWithBKey) {
347 asm("hint 0x27\n\t" // pacm
348 "hint 0xe"
349 : "+r"(x17)
350 : "r"(x16), "r"(x15)); // autib1716
351 } else {
352 asm("hint 0x27\n\t" // pacm
353 "hint 0xc"
354 : "+r"(x17)
355 : "r"(x16), "r"(x15)); // autia1716
356 }
357 } else {
358 if (cieInfo.addressesSignedWithBKey)
359 asm("hint 0xe" : "+r"(x17) : "r"(x16)); // autib1716
360 else
361 asm("hint 0xc" : "+r"(x17) : "r"(x16)); // autia1716
362 }
363 returnAddress = x17;
364#endif
365 }
366#endif
367#endif
368
369#if defined(_LIBUNWIND_IS_NATIVE_ONLY) && defined(_LIBUNWIND_TARGET_ARM) && \
370 defined(__ARM_FEATURE_PAUTH)
371 if ((R::getArch() == REGISTERS_ARM) &&
372 prolog.savedRegisters[UNW_ARM_RA_AUTH_CODE].value) {
373 pint_t pac =
374 getSavedRegister(addressSpace, registers, cfa,
375 prolog.savedRegisters[UNW_ARM_RA_AUTH_CODE]);
376 __asm__ __volatile__("autg %0, %1, %2"
377 :
378 : "r"(pac), "r"(returnAddress), "r"(cfa)
379 :);
380 }
381#endif
382
383#if defined(_LIBUNWIND_TARGET_SPARC)
384 if (R::getArch() == REGISTERS_SPARC) {
385 // Skip call site instruction and delay slot
386 returnAddress += 8;
387 // Skip unimp instruction if function returns a struct
388 if ((addressSpace.get32(returnAddress) & 0xC1C00000) == 0)
389 returnAddress += 4;
390 }
391#endif
392
393#if defined(_LIBUNWIND_TARGET_SPARC64)
394 // Skip call site instruction and delay slot.
395 if (R::getArch() == REGISTERS_SPARC64)
396 returnAddress += 8;
397#endif
398
399#if defined(_LIBUNWIND_TARGET_PPC64)
400#define PPC64_ELFV1_R2_LOAD_INST_ENCODING 0xe8410028u // ld r2,40(r1)
401#define PPC64_ELFV1_R2_OFFSET 40
402#define PPC64_ELFV2_R2_LOAD_INST_ENCODING 0xe8410018u // ld r2,24(r1)
403#define PPC64_ELFV2_R2_OFFSET 24
404 // If the instruction at return address is a TOC (r2) restore,
405 // then r2 was saved and needs to be restored.
406 // ELFv2 ABI specifies that the TOC Pointer must be saved at SP + 24,
407 // while in ELFv1 ABI it is saved at SP + 40.
408 if (R::getArch() == REGISTERS_PPC64 && returnAddress != 0) {
409 pint_t sp = newRegisters.getRegister(UNW_REG_SP);
410 pint_t r2 = 0;
411 switch (addressSpace.get32(returnAddress)) {
412 case PPC64_ELFV1_R2_LOAD_INST_ENCODING:
413 r2 = addressSpace.get64(sp + PPC64_ELFV1_R2_OFFSET);
414 break;
415 case PPC64_ELFV2_R2_LOAD_INST_ENCODING:
416 r2 = addressSpace.get64(sp + PPC64_ELFV2_R2_OFFSET);
417 break;
418 }
419 if (r2)
420 newRegisters.setRegister(UNW_PPC64_R2, r2);
421 }
422#endif
423
424 // Return address is address after call site instruction, so setting IP to
425 // that does simulates a return.
426 newRegisters.setIP(returnAddress);
427
428 // Simulate the step by replacing the register set with the new ones.
429 registers = newRegisters;
430
431 return UNW_STEP_SUCCESS;
432 }
433 }
434 return UNW_EBADFRAME;
435}
436
437template <typename A, typename R>
438typename A::pint_t
439DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
440 const R &registers,
441 pint_t initialStackValue) {
442 const bool log = false;
443 pint_t p = expression;
444 pint_t expressionEnd = expression + 20; // temp, until len read
445 pint_t length = (pint_t)addressSpace.getULEB128(p, expressionEnd);
446 expressionEnd = p + length;
447 if (log)
448 fprintf(stderr, format: "evaluateExpression(): length=%" PRIu64 "\n",
449 (uint64_t)length);
450 constexpr size_t kStackSize = 100;
451 pint_t stack[kStackSize];
452 pint_t *sp = stack;
453 *(++sp) = initialStackValue;
454
455 while (p < expressionEnd) {
456 // Bounds-check the operand stack. Every opcode below pushes at most one
457 // value (writing at most sp[1]) and, except for DW_OP_pick and DW_OP_rot
458 // (checked at their use), reads/writes no deeper than sp[-1]. Keeping sp
459 // within [&stack[1], &stack[kStackSize - 2]] here therefore bounds every
460 // access to the fixed-size array. Compiler-emitted CFI expressions use tiny
461 // stack depths; violating these bounds means corrupted or malicious unwind
462 // data (e.g. a hostile FDE registered via __register_frame()).
463 if (sp < &stack[1] || sp > &stack[kStackSize - 2])
464 _LIBUNWIND_ABORT("DWARF expression operand stack out of bounds");
465 if (log) {
466 for (pint_t *t = sp; t > stack; --t) {
467 fprintf(stderr, format: "sp[] = 0x%" PRIx64 "\n", (uint64_t)(*t));
468 }
469 }
470 uint8_t opcode = addressSpace.get8(p++);
471 sint_t svalue, svalue2;
472 pint_t value;
473 uint32_t reg;
474 switch (opcode) {
475 case DW_OP_addr:
476 // push immediate address sized value
477 value = addressSpace.getP(p);
478 p += sizeof(pint_t);
479 *(++sp) = value;
480 if (log)
481 fprintf(stderr, format: "push 0x%" PRIx64 "\n", (uint64_t)value);
482 break;
483
484 case DW_OP_deref:
485 // pop stack, dereference, push result
486 value = *sp--;
487 *(++sp) = addressSpace.getP(value);
488 if (log)
489 fprintf(stderr, format: "dereference 0x%" PRIx64 "\n", (uint64_t)value);
490 break;
491
492 case DW_OP_const1u:
493 // push immediate 1 byte value
494 value = addressSpace.get8(p);
495 p += 1;
496 *(++sp) = value;
497 if (log)
498 fprintf(stderr, format: "push 0x%" PRIx64 "\n", (uint64_t)value);
499 break;
500
501 case DW_OP_const1s:
502 // push immediate 1 byte signed value
503 svalue = (int8_t) addressSpace.get8(p);
504 p += 1;
505 *(++sp) = (pint_t)svalue;
506 if (log)
507 fprintf(stderr, format: "push 0x%" PRIx64 "\n", (uint64_t)svalue);
508 break;
509
510 case DW_OP_const2u:
511 // push immediate 2 byte value
512 value = addressSpace.get16(p);
513 p += 2;
514 *(++sp) = value;
515 if (log)
516 fprintf(stderr, format: "push 0x%" PRIx64 "\n", (uint64_t)value);
517 break;
518
519 case DW_OP_const2s:
520 // push immediate 2 byte signed value
521 svalue = (int16_t) addressSpace.get16(p);
522 p += 2;
523 *(++sp) = (pint_t)svalue;
524 if (log)
525 fprintf(stderr, format: "push 0x%" PRIx64 "\n", (uint64_t)svalue);
526 break;
527
528 case DW_OP_const4u:
529 // push immediate 4 byte value
530 value = addressSpace.get32(p);
531 p += 4;
532 *(++sp) = value;
533 if (log)
534 fprintf(stderr, format: "push 0x%" PRIx64 "\n", (uint64_t)value);
535 break;
536
537 case DW_OP_const4s:
538 // push immediate 4 byte signed value
539 svalue = (int32_t)addressSpace.get32(p);
540 p += 4;
541 *(++sp) = (pint_t)svalue;
542 if (log)
543 fprintf(stderr, format: "push 0x%" PRIx64 "\n", (uint64_t)svalue);
544 break;
545
546 case DW_OP_const8u:
547 // push immediate 8 byte value
548 value = (pint_t)addressSpace.get64(p);
549 p += 8;
550 *(++sp) = value;
551 if (log)
552 fprintf(stderr, format: "push 0x%" PRIx64 "\n", (uint64_t)value);
553 break;
554
555 case DW_OP_const8s:
556 // push immediate 8 byte signed value
557 value = (pint_t)addressSpace.get64(p);
558 p += 8;
559 *(++sp) = value;
560 if (log)
561 fprintf(stderr, format: "push 0x%" PRIx64 "\n", (uint64_t)value);
562 break;
563
564 case DW_OP_constu:
565 // push immediate ULEB128 value
566 value = (pint_t)addressSpace.getULEB128(p, expressionEnd);
567 *(++sp) = value;
568 if (log)
569 fprintf(stderr, format: "push 0x%" PRIx64 "\n", (uint64_t)value);
570 break;
571
572 case DW_OP_consts:
573 // push immediate SLEB128 value
574 svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
575 *(++sp) = (pint_t)svalue;
576 if (log)
577 fprintf(stderr, format: "push 0x%" PRIx64 "\n", (uint64_t)svalue);
578 break;
579
580 case DW_OP_dup:
581 // push top of stack
582 value = *sp;
583 *(++sp) = value;
584 if (log)
585 fprintf(stderr, format: "duplicate top of stack\n");
586 break;
587
588 case DW_OP_drop:
589 // pop
590 --sp;
591 if (log)
592 fprintf(stderr, format: "pop top of stack\n");
593 break;
594
595 case DW_OP_over:
596 // dup second
597 value = sp[-1];
598 *(++sp) = value;
599 if (log)
600 fprintf(stderr, format: "duplicate second in stack\n");
601 break;
602
603 case DW_OP_pick:
604 // pick from
605 reg = addressSpace.get8(p);
606 p += 1;
607 if (sp - (int)reg < &stack[1])
608 _LIBUNWIND_ABORT("DW_OP_pick index out of bounds");
609 value = sp[-(int)reg];
610 *(++sp) = value;
611 if (log)
612 fprintf(stderr, format: "duplicate %d in stack\n", reg);
613 break;
614
615 case DW_OP_swap:
616 // swap top two
617 value = sp[0];
618 sp[0] = sp[-1];
619 sp[-1] = value;
620 if (log)
621 fprintf(stderr, format: "swap top of stack\n");
622 break;
623
624 case DW_OP_rot:
625 // rotate top three
626 if (sp < &stack[3])
627 _LIBUNWIND_ABORT("DW_OP_rot with fewer than three stack entries");
628 value = sp[0];
629 sp[0] = sp[-1];
630 sp[-1] = sp[-2];
631 sp[-2] = value;
632 if (log)
633 fprintf(stderr, format: "rotate top three of stack\n");
634 break;
635
636 case DW_OP_xderef:
637 // pop stack, dereference, push result
638 value = *sp--;
639 *sp = *((pint_t*)value);
640 if (log)
641 fprintf(stderr, format: "x-dereference 0x%" PRIx64 "\n", (uint64_t)value);
642 break;
643
644 case DW_OP_abs:
645 svalue = (sint_t)*sp;
646 if (svalue < 0)
647 *sp = (pint_t)(-svalue);
648 if (log)
649 fprintf(stderr, format: "abs\n");
650 break;
651
652 case DW_OP_and:
653 value = *sp--;
654 *sp &= value;
655 if (log)
656 fprintf(stderr, format: "and\n");
657 break;
658
659 case DW_OP_div:
660 svalue = (sint_t)(*sp--);
661 svalue2 = (sint_t)*sp;
662 *sp = (pint_t)(svalue2 / svalue);
663 if (log)
664 fprintf(stderr, format: "div\n");
665 break;
666
667 case DW_OP_minus:
668 value = *sp--;
669 *sp = *sp - value;
670 if (log)
671 fprintf(stderr, format: "minus\n");
672 break;
673
674 case DW_OP_mod:
675 svalue = (sint_t)(*sp--);
676 svalue2 = (sint_t)*sp;
677 *sp = (pint_t)(svalue2 % svalue);
678 if (log)
679 fprintf(stderr, format: "module\n");
680 break;
681
682 case DW_OP_mul:
683 svalue = (sint_t)(*sp--);
684 svalue2 = (sint_t)*sp;
685 *sp = (pint_t)(svalue2 * svalue);
686 if (log)
687 fprintf(stderr, format: "mul\n");
688 break;
689
690 case DW_OP_neg:
691 *sp = 0 - *sp;
692 if (log)
693 fprintf(stderr, format: "neg\n");
694 break;
695
696 case DW_OP_not:
697 svalue = (sint_t)(*sp);
698 *sp = (pint_t)(~svalue);
699 if (log)
700 fprintf(stderr, format: "not\n");
701 break;
702
703 case DW_OP_or:
704 value = *sp--;
705 *sp |= value;
706 if (log)
707 fprintf(stderr, format: "or\n");
708 break;
709
710 case DW_OP_plus:
711 value = *sp--;
712 *sp += value;
713 if (log)
714 fprintf(stderr, format: "plus\n");
715 break;
716
717 case DW_OP_plus_uconst:
718 // pop stack, add uelb128 constant, push result
719 *sp += static_cast<pint_t>(addressSpace.getULEB128(p, expressionEnd));
720 if (log)
721 fprintf(stderr, format: "add constant\n");
722 break;
723
724 case DW_OP_shl:
725 value = *sp--;
726 *sp = *sp << value;
727 if (log)
728 fprintf(stderr, format: "shift left\n");
729 break;
730
731 case DW_OP_shr:
732 value = *sp--;
733 *sp = *sp >> value;
734 if (log)
735 fprintf(stderr, format: "shift left\n");
736 break;
737
738 case DW_OP_shra:
739 value = *sp--;
740 svalue = (sint_t)*sp;
741 *sp = (pint_t)(svalue >> value);
742 if (log)
743 fprintf(stderr, format: "shift left arithmetic\n");
744 break;
745
746 case DW_OP_xor:
747 value = *sp--;
748 *sp ^= value;
749 if (log)
750 fprintf(stderr, format: "xor\n");
751 break;
752
753 case DW_OP_skip:
754 svalue = (int16_t) addressSpace.get16(p);
755 p += 2;
756 p = (pint_t)((sint_t)p + svalue);
757 if (log)
758 fprintf(stderr, format: "skip %" PRIu64 "\n", (uint64_t)svalue);
759 break;
760
761 case DW_OP_bra:
762 svalue = (int16_t) addressSpace.get16(p);
763 p += 2;
764 if (*sp--)
765 p = (pint_t)((sint_t)p + svalue);
766 if (log)
767 fprintf(stderr, format: "bra %" PRIu64 "\n", (uint64_t)svalue);
768 break;
769
770 case DW_OP_eq:
771 value = *sp--;
772 *sp = (*sp == value);
773 if (log)
774 fprintf(stderr, format: "eq\n");
775 break;
776
777 case DW_OP_ge:
778 value = *sp--;
779 *sp = (*sp >= value);
780 if (log)
781 fprintf(stderr, format: "ge\n");
782 break;
783
784 case DW_OP_gt:
785 value = *sp--;
786 *sp = (*sp > value);
787 if (log)
788 fprintf(stderr, format: "gt\n");
789 break;
790
791 case DW_OP_le:
792 value = *sp--;
793 *sp = (*sp <= value);
794 if (log)
795 fprintf(stderr, format: "le\n");
796 break;
797
798 case DW_OP_lt:
799 value = *sp--;
800 *sp = (*sp < value);
801 if (log)
802 fprintf(stderr, format: "lt\n");
803 break;
804
805 case DW_OP_ne:
806 value = *sp--;
807 *sp = (*sp != value);
808 if (log)
809 fprintf(stderr, format: "ne\n");
810 break;
811
812 case DW_OP_lit0:
813 case DW_OP_lit1:
814 case DW_OP_lit2:
815 case DW_OP_lit3:
816 case DW_OP_lit4:
817 case DW_OP_lit5:
818 case DW_OP_lit6:
819 case DW_OP_lit7:
820 case DW_OP_lit8:
821 case DW_OP_lit9:
822 case DW_OP_lit10:
823 case DW_OP_lit11:
824 case DW_OP_lit12:
825 case DW_OP_lit13:
826 case DW_OP_lit14:
827 case DW_OP_lit15:
828 case DW_OP_lit16:
829 case DW_OP_lit17:
830 case DW_OP_lit18:
831 case DW_OP_lit19:
832 case DW_OP_lit20:
833 case DW_OP_lit21:
834 case DW_OP_lit22:
835 case DW_OP_lit23:
836 case DW_OP_lit24:
837 case DW_OP_lit25:
838 case DW_OP_lit26:
839 case DW_OP_lit27:
840 case DW_OP_lit28:
841 case DW_OP_lit29:
842 case DW_OP_lit30:
843 case DW_OP_lit31:
844 value = static_cast<pint_t>(opcode - DW_OP_lit0);
845 *(++sp) = value;
846 if (log)
847 fprintf(stderr, format: "push literal 0x%" PRIx64 "\n", (uint64_t)value);
848 break;
849
850 case DW_OP_reg0:
851 case DW_OP_reg1:
852 case DW_OP_reg2:
853 case DW_OP_reg3:
854 case DW_OP_reg4:
855 case DW_OP_reg5:
856 case DW_OP_reg6:
857 case DW_OP_reg7:
858 case DW_OP_reg8:
859 case DW_OP_reg9:
860 case DW_OP_reg10:
861 case DW_OP_reg11:
862 case DW_OP_reg12:
863 case DW_OP_reg13:
864 case DW_OP_reg14:
865 case DW_OP_reg15:
866 case DW_OP_reg16:
867 case DW_OP_reg17:
868 case DW_OP_reg18:
869 case DW_OP_reg19:
870 case DW_OP_reg20:
871 case DW_OP_reg21:
872 case DW_OP_reg22:
873 case DW_OP_reg23:
874 case DW_OP_reg24:
875 case DW_OP_reg25:
876 case DW_OP_reg26:
877 case DW_OP_reg27:
878 case DW_OP_reg28:
879 case DW_OP_reg29:
880 case DW_OP_reg30:
881 case DW_OP_reg31:
882 reg = static_cast<uint32_t>(opcode - DW_OP_reg0);
883 *(++sp) = registers.getRegister((int)reg);
884 if (log)
885 fprintf(stderr, format: "push reg %d\n", reg);
886 break;
887
888 case DW_OP_regx:
889 reg = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd));
890 *(++sp) = registers.getRegister((int)reg);
891 if (log)
892 fprintf(stderr, format: "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
893 break;
894
895 case DW_OP_breg0:
896 case DW_OP_breg1:
897 case DW_OP_breg2:
898 case DW_OP_breg3:
899 case DW_OP_breg4:
900 case DW_OP_breg5:
901 case DW_OP_breg6:
902 case DW_OP_breg7:
903 case DW_OP_breg8:
904 case DW_OP_breg9:
905 case DW_OP_breg10:
906 case DW_OP_breg11:
907 case DW_OP_breg12:
908 case DW_OP_breg13:
909 case DW_OP_breg14:
910 case DW_OP_breg15:
911 case DW_OP_breg16:
912 case DW_OP_breg17:
913 case DW_OP_breg18:
914 case DW_OP_breg19:
915 case DW_OP_breg20:
916 case DW_OP_breg21:
917 case DW_OP_breg22:
918 case DW_OP_breg23:
919 case DW_OP_breg24:
920 case DW_OP_breg25:
921 case DW_OP_breg26:
922 case DW_OP_breg27:
923 case DW_OP_breg28:
924 case DW_OP_breg29:
925 case DW_OP_breg30:
926 case DW_OP_breg31:
927 reg = static_cast<uint32_t>(opcode - DW_OP_breg0);
928 svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
929 svalue += static_cast<sint_t>(registers.getRegister((int)reg));
930 *(++sp) = (pint_t)(svalue);
931 if (log)
932 fprintf(stderr, format: "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
933 break;
934
935 case DW_OP_bregx:
936 reg = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd));
937 svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
938 svalue += static_cast<sint_t>(registers.getRegister((int)reg));
939 *(++sp) = (pint_t)(svalue);
940 if (log)
941 fprintf(stderr, format: "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
942 break;
943
944 case DW_OP_fbreg:
945 _LIBUNWIND_ABORT("DW_OP_fbreg not implemented");
946 break;
947
948 case DW_OP_piece:
949 _LIBUNWIND_ABORT("DW_OP_piece not implemented");
950 break;
951
952 case DW_OP_deref_size:
953 // pop stack, dereference, push result
954 value = *sp--;
955 switch (addressSpace.get8(p++)) {
956 case 1:
957 value = addressSpace.get8(value);
958 break;
959 case 2:
960 value = addressSpace.get16(value);
961 break;
962 case 4:
963 value = addressSpace.get32(value);
964 break;
965 case 8:
966 value = (pint_t)addressSpace.get64(value);
967 break;
968 default:
969 _LIBUNWIND_ABORT("DW_OP_deref_size with bad size");
970 }
971 *(++sp) = value;
972 if (log)
973 fprintf(stderr, format: "sized dereference 0x%" PRIx64 "\n", (uint64_t)value);
974 break;
975
976 case DW_OP_xderef_size:
977 case DW_OP_nop:
978 case DW_OP_push_object_addres:
979 case DW_OP_call2:
980 case DW_OP_call4:
981 case DW_OP_call_ref:
982 default:
983 _LIBUNWIND_ABORT("DWARF opcode not implemented");
984 }
985
986 }
987 if (sp < &stack[1])
988 _LIBUNWIND_ABORT("DWARF expression operand stack out of bounds");
989 if (log)
990 fprintf(stderr, format: "expression evaluates to 0x%" PRIx64 "\n", (uint64_t)*sp);
991 return *sp;
992}
993
994
995
996} // namespace libunwind
997
998#endif // __DWARF_INSTRUCTIONS_HPP__
999