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