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