1//===-------------------------- DwarfInstructions.hpp ---------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is dual licensed under the MIT and the University of Illinois Open
6// Source Licenses. See LICENSE.TXT for details.
7//
8//
9//  Processor specific interpretation of dwarf unwind info.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef __DWARF_INSTRUCTIONS_HPP__
14#define __DWARF_INSTRUCTIONS_HPP__
15
16#include <stdint.h>
17#include <stdio.h>
18#include <stdlib.h>
19
20#include "dwarf2.h"
21#include "AddressSpace.hpp"
22#include "Registers.hpp"
23#include "DwarfParser.hpp"
24#include "config.h"
25
26
27namespace libunwind {
28
29
30/// DwarfInstructions maps abtract dwarf unwind instructions to a particular
31/// architecture
32template <typename A, typename R>
33class DwarfInstructions {
34public:
35  typedef typename A::pint_t pint_t;
36  typedef typename A::sint_t sint_t;
37
38  static int stepWithDwarf(A &addressSpace, pint_t pc, pint_t fdeStart,
39                           R &registers);
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      return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) +
70             prolog.cfaRegisterOffset);
71    if (prolog.cfaExpression != 0)
72      return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace,
73                                registers, 0);
74    assert(0 && "getCFA(): unknown location");
75    __builtin_unreachable();
76  }
77};
78
79
80template <typename A, typename R>
81typename A::pint_t DwarfInstructions<A, R>::getSavedRegister(
82    A &addressSpace, const R &registers, pint_t cfa,
83    const RegisterLocation &savedReg) {
84  switch (savedReg.location) {
85  case CFI_Parser<A>::kRegisterInCFA:
86    return addressSpace.getP(cfa + (pint_t)savedReg.value);
87
88  case CFI_Parser<A>::kRegisterAtExpression:
89    return addressSpace.getP(
90        evaluateExpression((pint_t)savedReg.value, addressSpace,
91                            registers, cfa));
92
93  case CFI_Parser<A>::kRegisterIsExpression:
94    return evaluateExpression((pint_t)savedReg.value, addressSpace,
95                              registers, cfa);
96
97  case CFI_Parser<A>::kRegisterInRegister:
98    return registers.getRegister((int)savedReg.value);
99
100  case CFI_Parser<A>::kRegisterUnused:
101  case CFI_Parser<A>::kRegisterOffsetFromCFA:
102    // FIX ME
103    break;
104  }
105  _LIBUNWIND_ABORT("unsupported restore location for register");
106}
107
108template <typename A, typename R>
109double DwarfInstructions<A, R>::getSavedFloatRegister(
110    A &addressSpace, const R &registers, pint_t cfa,
111    const RegisterLocation &savedReg) {
112  switch (savedReg.location) {
113  case CFI_Parser<A>::kRegisterInCFA:
114    return addressSpace.getDouble(cfa + (pint_t)savedReg.value);
115
116  case CFI_Parser<A>::kRegisterAtExpression:
117    return addressSpace.getDouble(
118        evaluateExpression((pint_t)savedReg.value, addressSpace,
119                            registers, cfa));
120
121  case CFI_Parser<A>::kRegisterIsExpression:
122  case CFI_Parser<A>::kRegisterUnused:
123  case CFI_Parser<A>::kRegisterOffsetFromCFA:
124  case CFI_Parser<A>::kRegisterInRegister:
125    // FIX ME
126    break;
127  }
128  _LIBUNWIND_ABORT("unsupported restore location for float register");
129}
130
131template <typename A, typename R>
132v128 DwarfInstructions<A, R>::getSavedVectorRegister(
133    A &addressSpace, const R &registers, pint_t cfa,
134    const RegisterLocation &savedReg) {
135  switch (savedReg.location) {
136  case CFI_Parser<A>::kRegisterInCFA:
137    return addressSpace.getVector(cfa + (pint_t)savedReg.value);
138
139  case CFI_Parser<A>::kRegisterAtExpression:
140    return addressSpace.getVector(
141        evaluateExpression((pint_t)savedReg.value, addressSpace,
142                            registers, cfa));
143
144  case CFI_Parser<A>::kRegisterIsExpression:
145  case CFI_Parser<A>::kRegisterUnused:
146  case CFI_Parser<A>::kRegisterOffsetFromCFA:
147  case CFI_Parser<A>::kRegisterInRegister:
148    // FIX ME
149    break;
150  }
151  _LIBUNWIND_ABORT("unsupported restore location for vector register");
152}
153
154template <typename A, typename R>
155int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
156                                           pint_t fdeStart, R &registers) {
157  FDE_Info fdeInfo;
158  CIE_Info cieInfo;
159  if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart,
160                                                  &fdeInfo, &cieInfo) == NULL) {
161    PrologInfo prolog;
162    if (CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc,
163                                                                     &prolog)) {
164      // get pointer to cfa (architecture specific)
165      pint_t cfa = getCFA(addressSpace, prolog, registers);
166
167       // restore registers that dwarf says were saved
168      R newRegisters = registers;
169      pint_t returnAddress = 0;
170      const int lastReg = R::lastDwarfRegNum();
171      assert((int)CFI_Parser<A>::kMaxRegisterNumber > lastReg
172                                                && "register range too large");
173      assert(lastReg <= (int)cieInfo.returnAddressRegister
174                 && "register range does not contain return address register");
175      for (int i = 0; i <= lastReg; ++i) {
176         if (prolog.savedRegisters[i].location !=
177             CFI_Parser<A>::kRegisterUnused) {
178           if (registers.validFloatRegister(i))
179            newRegisters.setFloatRegister(
180                i, getSavedFloatRegister(addressSpace, registers, cfa,
181                                         prolog.savedRegisters[i]));
182          else if (registers.validVectorRegister(i))
183            newRegisters.setVectorRegister(
184                i, getSavedVectorRegister(addressSpace, registers, cfa,
185                                          prolog.savedRegisters[i]));
186          else if (i == (int)cieInfo.returnAddressRegister)
187            returnAddress = getSavedRegister(addressSpace, registers, cfa,
188                                             prolog.savedRegisters[i]);
189          else if (registers.validRegister(i))
190            newRegisters.setRegister(
191                i, getSavedRegister(addressSpace, registers, cfa,
192                                    prolog.savedRegisters[i]));
193          else
194            return UNW_EBADREG;
195        }
196      }
197
198      // By definition, the CFA is the stack pointer at the call site, so
199      // restoring SP means setting it to CFA.
200      newRegisters.setSP(cfa);
201
202      // Return address is address after call site instruction, so setting IP to
203      // that does simualates a return.
204      newRegisters.setIP(returnAddress);
205
206      // Simulate the step by replacing the register set with the new ones.
207      registers = newRegisters;
208
209      return UNW_STEP_SUCCESS;
210    }
211  }
212  return UNW_EBADFRAME;
213}
214
215template <typename A, typename R>
216typename A::pint_t
217DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
218                                            const R &registers,
219                                            pint_t initialStackValue) {
220  const bool log = false;
221  pint_t p = expression;
222  pint_t expressionEnd = expression + 20; // temp, until len read
223  pint_t length = (pint_t)addressSpace.getULEB128(p, expressionEnd);
224  expressionEnd = p + length;
225  if (log)
226    fprintf(stderr, "evaluateExpression(): length=%llu\n", (uint64_t)length);
227  pint_t stack[100];
228  pint_t *sp = stack;
229  *(++sp) = initialStackValue;
230
231  while (p < expressionEnd) {
232    if (log) {
233      for (pint_t *t = sp; t > stack; --t) {
234        fprintf(stderr, "sp[] = 0x%llX\n", (uint64_t)(*t));
235      }
236    }
237    uint8_t opcode = addressSpace.get8(p++);
238    sint_t svalue, svalue2;
239    pint_t value;
240    uint32_t reg;
241    switch (opcode) {
242    case DW_OP_addr:
243      // push immediate address sized value
244      value = addressSpace.getP(p);
245      p += sizeof(pint_t);
246      *(++sp) = value;
247      if (log)
248        fprintf(stderr, "push 0x%llX\n", (uint64_t) value);
249      break;
250
251    case DW_OP_deref:
252      // pop stack, dereference, push result
253      value = *sp--;
254      *(++sp) = addressSpace.getP(value);
255      if (log)
256        fprintf(stderr, "dereference 0x%llX\n", (uint64_t) value);
257      break;
258
259    case DW_OP_const1u:
260      // push immediate 1 byte value
261      value = addressSpace.get8(p);
262      p += 1;
263      *(++sp) = value;
264      if (log)
265        fprintf(stderr, "push 0x%llX\n", (uint64_t) value);
266      break;
267
268    case DW_OP_const1s:
269      // push immediate 1 byte signed value
270      svalue = (int8_t) addressSpace.get8(p);
271      p += 1;
272      *(++sp) = (pint_t)svalue;
273      if (log)
274        fprintf(stderr, "push 0x%llX\n", (uint64_t) svalue);
275      break;
276
277    case DW_OP_const2u:
278      // push immediate 2 byte value
279      value = addressSpace.get16(p);
280      p += 2;
281      *(++sp) = value;
282      if (log)
283        fprintf(stderr, "push 0x%llX\n", (uint64_t) value);
284      break;
285
286    case DW_OP_const2s:
287      // push immediate 2 byte signed value
288      svalue = (int16_t) addressSpace.get16(p);
289      p += 2;
290      *(++sp) = (pint_t)svalue;
291      if (log)
292        fprintf(stderr, "push 0x%llX\n", (uint64_t) svalue);
293      break;
294
295    case DW_OP_const4u:
296      // push immediate 4 byte value
297      value = addressSpace.get32(p);
298      p += 4;
299      *(++sp) = value;
300      if (log)
301        fprintf(stderr, "push 0x%llX\n", (uint64_t) value);
302      break;
303
304    case DW_OP_const4s:
305      // push immediate 4 byte signed value
306      svalue = (int32_t)addressSpace.get32(p);
307      p += 4;
308      *(++sp) = (pint_t)svalue;
309      if (log)
310        fprintf(stderr, "push 0x%llX\n", (uint64_t) svalue);
311      break;
312
313    case DW_OP_const8u:
314      // push immediate 8 byte value
315      value = (pint_t)addressSpace.get64(p);
316      p += 8;
317      *(++sp) = value;
318      if (log)
319        fprintf(stderr, "push 0x%llX\n", (uint64_t) value);
320      break;
321
322    case DW_OP_const8s:
323      // push immediate 8 byte signed value
324      value = (pint_t)addressSpace.get64(p);
325      p += 8;
326      *(++sp) = value;
327      if (log)
328        fprintf(stderr, "push 0x%llX\n", (uint64_t) value);
329      break;
330
331    case DW_OP_constu:
332      // push immediate ULEB128 value
333      value = (pint_t)addressSpace.getULEB128(p, expressionEnd);
334      *(++sp) = value;
335      if (log)
336        fprintf(stderr, "push 0x%llX\n", (uint64_t) value);
337      break;
338
339    case DW_OP_consts:
340      // push immediate SLEB128 value
341      svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
342      *(++sp) = (pint_t)svalue;
343      if (log)
344        fprintf(stderr, "push 0x%llX\n", (uint64_t) svalue);
345      break;
346
347    case DW_OP_dup:
348      // push top of stack
349      value = *sp;
350      *(++sp) = value;
351      if (log)
352        fprintf(stderr, "duplicate top of stack\n");
353      break;
354
355    case DW_OP_drop:
356      // pop
357      --sp;
358      if (log)
359        fprintf(stderr, "pop top of stack\n");
360      break;
361
362    case DW_OP_over:
363      // dup second
364      value = sp[-1];
365      *(++sp) = value;
366      if (log)
367        fprintf(stderr, "duplicate second in stack\n");
368      break;
369
370    case DW_OP_pick:
371      // pick from
372      reg = addressSpace.get8(p);
373      p += 1;
374      value = sp[-reg];
375      *(++sp) = value;
376      if (log)
377        fprintf(stderr, "duplicate %d in stack\n", reg);
378      break;
379
380    case DW_OP_swap:
381      // swap top two
382      value = sp[0];
383      sp[0] = sp[-1];
384      sp[-1] = value;
385      if (log)
386        fprintf(stderr, "swap top of stack\n");
387      break;
388
389    case DW_OP_rot:
390      // rotate top three
391      value = sp[0];
392      sp[0] = sp[-1];
393      sp[-1] = sp[-2];
394      sp[-2] = value;
395      if (log)
396        fprintf(stderr, "rotate top three of stack\n");
397      break;
398
399    case DW_OP_xderef:
400      // pop stack, dereference, push result
401      value = *sp--;
402      *sp = *((pint_t*)value);
403      if (log)
404        fprintf(stderr, "x-dereference 0x%llX\n", (uint64_t) value);
405      break;
406
407    case DW_OP_abs:
408      svalue = (sint_t)*sp;
409      if (svalue < 0)
410        *sp = (pint_t)(-svalue);
411      if (log)
412        fprintf(stderr, "abs\n");
413      break;
414
415    case DW_OP_and:
416      value = *sp--;
417      *sp &= value;
418      if (log)
419        fprintf(stderr, "and\n");
420      break;
421
422    case DW_OP_div:
423      svalue = (sint_t)(*sp--);
424      svalue2 = (sint_t)*sp;
425      *sp = (pint_t)(svalue2 / svalue);
426      if (log)
427        fprintf(stderr, "div\n");
428      break;
429
430    case DW_OP_minus:
431      value = *sp--;
432      *sp = *sp - value;
433      if (log)
434        fprintf(stderr, "minus\n");
435      break;
436
437    case DW_OP_mod:
438      svalue = (sint_t)(*sp--);
439      svalue2 = (sint_t)*sp;
440      *sp = (pint_t)(svalue2 % svalue);
441      if (log)
442        fprintf(stderr, "module\n");
443      break;
444
445    case DW_OP_mul:
446      svalue = (sint_t)(*sp--);
447      svalue2 = (sint_t)*sp;
448      *sp = (pint_t)(svalue2 * svalue);
449      if (log)
450        fprintf(stderr, "mul\n");
451      break;
452
453    case DW_OP_neg:
454      *sp = 0 - *sp;
455      if (log)
456        fprintf(stderr, "neg\n");
457      break;
458
459    case DW_OP_not:
460      svalue = (sint_t)(*sp);
461      *sp = (pint_t)(~svalue);
462      if (log)
463        fprintf(stderr, "not\n");
464      break;
465
466    case DW_OP_or:
467      value = *sp--;
468      *sp |= value;
469      if (log)
470        fprintf(stderr, "or\n");
471      break;
472
473    case DW_OP_plus:
474      value = *sp--;
475      *sp += value;
476      if (log)
477        fprintf(stderr, "plus\n");
478      break;
479
480    case DW_OP_plus_uconst:
481      // pop stack, add uelb128 constant, push result
482      *sp += addressSpace.getULEB128(p, expressionEnd);
483      if (log)
484        fprintf(stderr, "add constant\n");
485      break;
486
487    case DW_OP_shl:
488      value = *sp--;
489      *sp = *sp << value;
490      if (log)
491        fprintf(stderr, "shift left\n");
492      break;
493
494    case DW_OP_shr:
495      value = *sp--;
496      *sp = *sp >> value;
497      if (log)
498        fprintf(stderr, "shift left\n");
499      break;
500
501    case DW_OP_shra:
502      value = *sp--;
503      svalue = (sint_t)*sp;
504      *sp = (pint_t)(svalue >> value);
505      if (log)
506        fprintf(stderr, "shift left arithmetric\n");
507      break;
508
509    case DW_OP_xor:
510      value = *sp--;
511      *sp ^= value;
512      if (log)
513        fprintf(stderr, "xor\n");
514      break;
515
516    case DW_OP_skip:
517      svalue = (int16_t) addressSpace.get16(p);
518      p += 2;
519      p = (pint_t)((sint_t)p + svalue);
520      if (log)
521        fprintf(stderr, "skip %lld\n", (uint64_t) svalue);
522      break;
523
524    case DW_OP_bra:
525      svalue = (int16_t) addressSpace.get16(p);
526      p += 2;
527      if (*sp--)
528        p = (pint_t)((sint_t)p + svalue);
529      if (log)
530        fprintf(stderr, "bra %lld\n", (uint64_t) svalue);
531      break;
532
533    case DW_OP_eq:
534      value = *sp--;
535      *sp = (*sp == value);
536      if (log)
537        fprintf(stderr, "eq\n");
538      break;
539
540    case DW_OP_ge:
541      value = *sp--;
542      *sp = (*sp >= value);
543      if (log)
544        fprintf(stderr, "ge\n");
545      break;
546
547    case DW_OP_gt:
548      value = *sp--;
549      *sp = (*sp > value);
550      if (log)
551        fprintf(stderr, "gt\n");
552      break;
553
554    case DW_OP_le:
555      value = *sp--;
556      *sp = (*sp <= value);
557      if (log)
558        fprintf(stderr, "le\n");
559      break;
560
561    case DW_OP_lt:
562      value = *sp--;
563      *sp = (*sp < value);
564      if (log)
565        fprintf(stderr, "lt\n");
566      break;
567
568    case DW_OP_ne:
569      value = *sp--;
570      *sp = (*sp != value);
571      if (log)
572        fprintf(stderr, "ne\n");
573      break;
574
575    case DW_OP_lit0:
576    case DW_OP_lit1:
577    case DW_OP_lit2:
578    case DW_OP_lit3:
579    case DW_OP_lit4:
580    case DW_OP_lit5:
581    case DW_OP_lit6:
582    case DW_OP_lit7:
583    case DW_OP_lit8:
584    case DW_OP_lit9:
585    case DW_OP_lit10:
586    case DW_OP_lit11:
587    case DW_OP_lit12:
588    case DW_OP_lit13:
589    case DW_OP_lit14:
590    case DW_OP_lit15:
591    case DW_OP_lit16:
592    case DW_OP_lit17:
593    case DW_OP_lit18:
594    case DW_OP_lit19:
595    case DW_OP_lit20:
596    case DW_OP_lit21:
597    case DW_OP_lit22:
598    case DW_OP_lit23:
599    case DW_OP_lit24:
600    case DW_OP_lit25:
601    case DW_OP_lit26:
602    case DW_OP_lit27:
603    case DW_OP_lit28:
604    case DW_OP_lit29:
605    case DW_OP_lit30:
606    case DW_OP_lit31:
607      value = opcode - DW_OP_lit0;
608      *(++sp) = value;
609      if (log)
610        fprintf(stderr, "push literal 0x%llX\n", (uint64_t) value);
611      break;
612
613    case DW_OP_reg0:
614    case DW_OP_reg1:
615    case DW_OP_reg2:
616    case DW_OP_reg3:
617    case DW_OP_reg4:
618    case DW_OP_reg5:
619    case DW_OP_reg6:
620    case DW_OP_reg7:
621    case DW_OP_reg8:
622    case DW_OP_reg9:
623    case DW_OP_reg10:
624    case DW_OP_reg11:
625    case DW_OP_reg12:
626    case DW_OP_reg13:
627    case DW_OP_reg14:
628    case DW_OP_reg15:
629    case DW_OP_reg16:
630    case DW_OP_reg17:
631    case DW_OP_reg18:
632    case DW_OP_reg19:
633    case DW_OP_reg20:
634    case DW_OP_reg21:
635    case DW_OP_reg22:
636    case DW_OP_reg23:
637    case DW_OP_reg24:
638    case DW_OP_reg25:
639    case DW_OP_reg26:
640    case DW_OP_reg27:
641    case DW_OP_reg28:
642    case DW_OP_reg29:
643    case DW_OP_reg30:
644    case DW_OP_reg31:
645      reg = opcode - DW_OP_reg0;
646      *(++sp) = registers.getRegister((int)reg);
647      if (log)
648        fprintf(stderr, "push reg %d\n", reg);
649      break;
650
651    case DW_OP_regx:
652      reg = (uint32_t)addressSpace.getULEB128(p, expressionEnd);
653      *(++sp) = registers.getRegister((int)reg);
654      if (log)
655        fprintf(stderr, "push reg %d + 0x%llX\n", reg, (uint64_t) svalue);
656      break;
657
658    case DW_OP_breg0:
659    case DW_OP_breg1:
660    case DW_OP_breg2:
661    case DW_OP_breg3:
662    case DW_OP_breg4:
663    case DW_OP_breg5:
664    case DW_OP_breg6:
665    case DW_OP_breg7:
666    case DW_OP_breg8:
667    case DW_OP_breg9:
668    case DW_OP_breg10:
669    case DW_OP_breg11:
670    case DW_OP_breg12:
671    case DW_OP_breg13:
672    case DW_OP_breg14:
673    case DW_OP_breg15:
674    case DW_OP_breg16:
675    case DW_OP_breg17:
676    case DW_OP_breg18:
677    case DW_OP_breg19:
678    case DW_OP_breg20:
679    case DW_OP_breg21:
680    case DW_OP_breg22:
681    case DW_OP_breg23:
682    case DW_OP_breg24:
683    case DW_OP_breg25:
684    case DW_OP_breg26:
685    case DW_OP_breg27:
686    case DW_OP_breg28:
687    case DW_OP_breg29:
688    case DW_OP_breg30:
689    case DW_OP_breg31:
690      reg = opcode - DW_OP_breg0;
691      svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
692      svalue += registers.getRegister((int)reg);
693      *(++sp) = (pint_t)(svalue);
694      if (log)
695        fprintf(stderr, "push reg %d + 0x%llX\n", reg, (uint64_t) svalue);
696      break;
697
698    case DW_OP_bregx:
699      reg = (uint32_t)addressSpace.getULEB128(p, expressionEnd);
700      svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
701      svalue += registers.getRegister((int)reg);
702      *(++sp) = (pint_t)(svalue);
703      if (log)
704        fprintf(stderr, "push reg %d + 0x%llX\n", reg, (uint64_t) svalue);
705      break;
706
707    case DW_OP_fbreg:
708      _LIBUNWIND_ABORT("DW_OP_fbreg not implemented");
709      break;
710
711    case DW_OP_piece:
712      _LIBUNWIND_ABORT("DW_OP_piece not implemented");
713      break;
714
715    case DW_OP_deref_size:
716      // pop stack, dereference, push result
717      value = *sp--;
718      switch (addressSpace.get8(p++)) {
719      case 1:
720        value = addressSpace.get8(value);
721        break;
722      case 2:
723        value = addressSpace.get16(value);
724        break;
725      case 4:
726        value = addressSpace.get32(value);
727        break;
728      case 8:
729        value = (pint_t)addressSpace.get64(value);
730        break;
731      default:
732        _LIBUNWIND_ABORT("DW_OP_deref_size with bad size");
733      }
734      *(++sp) = value;
735      if (log)
736        fprintf(stderr, "sized dereference 0x%llX\n", (uint64_t) value);
737      break;
738
739    case DW_OP_xderef_size:
740    case DW_OP_nop:
741    case DW_OP_push_object_addres:
742    case DW_OP_call2:
743    case DW_OP_call4:
744    case DW_OP_call_ref:
745    default:
746      _LIBUNWIND_ABORT("dwarf opcode not implemented");
747    }
748
749  }
750  if (log)
751    fprintf(stderr, "expression evaluates to 0x%llX\n", (uint64_t) * sp);
752  return *sp;
753}
754
755
756
757} // namespace libunwind
758
759#endif // __DWARF_INSTRUCTIONS_HPP__
760