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 ®isters); 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 ®isters, 58b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t initialStackValue); 59b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static pint_t getSavedRegister(A &addressSpace, const R ®isters, 60b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t cfa, const RegisterLocation &savedReg); 61b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static double getSavedFloatRegister(A &addressSpace, const R ®isters, 62b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t cfa, const RegisterLocation &savedReg); 63b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static v128 getSavedVectorRegister(A &addressSpace, const R ®isters, 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 ®isters) { 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 ®isters, 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 ®isters, 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 ®isters, 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 ®isters) { 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 ®isters, 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