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