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