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; 159b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, 160b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik &fdeInfo, &cieInfo) == NULL) { 161b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik PrologInfo prolog; 162b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc, 163b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik &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(); 171e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert assert((int)CFI_Parser<A>::kMaxRegisterNumber > lastReg 172e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert && "register range too large"); 173e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert assert(lastReg <= (int)cieInfo.returnAddressRegister 174e45805f0d3f8dafef1297cc7dc49e610713f023bDan 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) 226b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "evaluateExpression(): length=%llu\n", (uint64_t)length); 227b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t stack[100]; 228b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t *sp = stack; 229b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = initialStackValue; 230b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 231b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik while (p < expressionEnd) { 232b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) { 233b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik for (pint_t *t = sp; t > stack; --t) { 234b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "sp[] = 0x%llX\n", (uint64_t)(*t)); 235b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 236b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 237b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint8_t opcode = addressSpace.get8(p++); 238b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sint_t svalue, svalue2; 239b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t value; 240b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t reg; 241b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik switch (opcode) { 242b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_addr: 243b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // push immediate address sized value 244b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = addressSpace.getP(p); 245b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += sizeof(pint_t); 246b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = value; 247b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 248b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push 0x%llX\n", (uint64_t) value); 249b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 250b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 251b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_deref: 252b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // pop stack, dereference, push result 253b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 254b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = addressSpace.getP(value); 255b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 256b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "dereference 0x%llX\n", (uint64_t) value); 257b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 258b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 259b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_const1u: 260b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // push immediate 1 byte value 261b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = addressSpace.get8(p); 262b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 1; 263b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = value; 264b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 265b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push 0x%llX\n", (uint64_t) value); 266b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 267b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 268b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_const1s: 269b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // push immediate 1 byte signed value 270b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue = (int8_t) addressSpace.get8(p); 271b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 1; 272b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = (pint_t)svalue; 273b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 274b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push 0x%llX\n", (uint64_t) svalue); 275b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 276b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 277b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_const2u: 278b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // push immediate 2 byte value 279b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = addressSpace.get16(p); 280b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 2; 281b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = value; 282b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 283b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push 0x%llX\n", (uint64_t) value); 284b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 285b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 286b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_const2s: 287b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // push immediate 2 byte signed value 288b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue = (int16_t) addressSpace.get16(p); 289b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 2; 290b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = (pint_t)svalue; 291b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 292b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push 0x%llX\n", (uint64_t) svalue); 293b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 294b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 295b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_const4u: 296b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // push immediate 4 byte value 297b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = addressSpace.get32(p); 298b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 4; 299b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = value; 300b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 301b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push 0x%llX\n", (uint64_t) value); 302b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 303b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 304b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_const4s: 305b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // push immediate 4 byte signed value 306b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue = (int32_t)addressSpace.get32(p); 307b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 4; 308b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = (pint_t)svalue; 309b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 310b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push 0x%llX\n", (uint64_t) svalue); 311b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 312b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 313b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_const8u: 314b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // push immediate 8 byte value 315b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = (pint_t)addressSpace.get64(p); 316b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 8; 317b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = value; 318b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 319b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push 0x%llX\n", (uint64_t) value); 320b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 321b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 322b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_const8s: 323b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // push immediate 8 byte signed value 324b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = (pint_t)addressSpace.get64(p); 325b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 8; 326b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = value; 327b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 328b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push 0x%llX\n", (uint64_t) value); 329b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 330b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 331b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_constu: 332b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // push immediate ULEB128 value 333b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = (pint_t)addressSpace.getULEB128(p, expressionEnd); 334b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = value; 335b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 336b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push 0x%llX\n", (uint64_t) value); 337b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 338b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 339b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_consts: 340b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // push immediate SLEB128 value 341b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd); 342b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = (pint_t)svalue; 343b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 344b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push 0x%llX\n", (uint64_t) svalue); 345b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 346b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 347b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_dup: 348b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // push top of stack 349b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp; 350b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = value; 351b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 352b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "duplicate top of stack\n"); 353b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 354b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 355b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_drop: 356b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // pop 357b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik --sp; 358b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 359b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "pop top of stack\n"); 360b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 361b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 362b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_over: 363b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // dup second 364b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = sp[-1]; 365b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = value; 366b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 367b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "duplicate second in stack\n"); 368b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 369b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 370b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_pick: 371b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // pick from 372b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik reg = addressSpace.get8(p); 373b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 1; 374b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = sp[-reg]; 375b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = value; 376b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 377b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "duplicate %d in stack\n", reg); 378b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 379b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 380b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_swap: 381b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // swap top two 382b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = sp[0]; 383b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sp[0] = sp[-1]; 384b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sp[-1] = value; 385b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 386b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "swap top of stack\n"); 387b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 388b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 389b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_rot: 390b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // rotate top three 391b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = sp[0]; 392b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sp[0] = sp[-1]; 393b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sp[-1] = sp[-2]; 394b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik sp[-2] = value; 395b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 396b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "rotate top three of stack\n"); 397b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 398b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 399b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_xderef: 400b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // pop stack, dereference, push result 401b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 402b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = *((pint_t*)value); 403b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 404b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "x-dereference 0x%llX\n", (uint64_t) value); 405b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 406b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 407b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_abs: 408b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue = (sint_t)*sp; 409b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (svalue < 0) 410b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = (pint_t)(-svalue); 411b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 412b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "abs\n"); 413b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 414b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 415b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_and: 416b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 417b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp &= value; 418b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 419b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "and\n"); 420b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 421b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 422b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_div: 423b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue = (sint_t)(*sp--); 424b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue2 = (sint_t)*sp; 425b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = (pint_t)(svalue2 / svalue); 426b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 427b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "div\n"); 428b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 429b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 430b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_minus: 431b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 432b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = *sp - value; 433b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 434b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "minus\n"); 435b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 436b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 437b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_mod: 438b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue = (sint_t)(*sp--); 439b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue2 = (sint_t)*sp; 440b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = (pint_t)(svalue2 % svalue); 441b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 442b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "module\n"); 443b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 444b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 445b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_mul: 446b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue = (sint_t)(*sp--); 447b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue2 = (sint_t)*sp; 448b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = (pint_t)(svalue2 * svalue); 449b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 450b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "mul\n"); 451b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 452b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 453b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_neg: 454b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = 0 - *sp; 455b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 456b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "neg\n"); 457b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 458b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 459b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_not: 460b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue = (sint_t)(*sp); 461b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = (pint_t)(~svalue); 462b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 463b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "not\n"); 464b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 465b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 466b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_or: 467b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 468b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp |= value; 469b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 470b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "or\n"); 471b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 472b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 473b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_plus: 474b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 475b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp += value; 476b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 477b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "plus\n"); 478b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 479b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 480b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_plus_uconst: 481b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // pop stack, add uelb128 constant, push result 482b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp += addressSpace.getULEB128(p, expressionEnd); 483b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 484b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "add constant\n"); 485b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 486b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 487b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_shl: 488b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 489b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = *sp << value; 490b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 491b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "shift left\n"); 492b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 493b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 494b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_shr: 495b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 496b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = *sp >> value; 497b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 498b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "shift left\n"); 499b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 500b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 501b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_shra: 502b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 503b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue = (sint_t)*sp; 504b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = (pint_t)(svalue >> value); 505b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 506b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "shift left arithmetric\n"); 507b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 508b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 509b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_xor: 510b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 511b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp ^= value; 512b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 513b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "xor\n"); 514b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 515b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 516b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_skip: 517b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue = (int16_t) addressSpace.get16(p); 518b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 2; 519b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p = (pint_t)((sint_t)p + svalue); 520b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 521b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "skip %lld\n", (uint64_t) svalue); 522b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 523b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 524b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_bra: 525b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue = (int16_t) addressSpace.get16(p); 526b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 2; 527b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (*sp--) 528b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p = (pint_t)((sint_t)p + svalue); 529b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 530b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "bra %lld\n", (uint64_t) svalue); 531b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 532b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 533b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_eq: 534b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 535b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = (*sp == value); 536b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 537b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "eq\n"); 538b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 539b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 540b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_ge: 541b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 542b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = (*sp >= value); 543b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 544b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "ge\n"); 545b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 546b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 547b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_gt: 548b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 549b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = (*sp > value); 550b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 551b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "gt\n"); 552b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 553b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 554b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_le: 555b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 556b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = (*sp <= value); 557b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 558b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "le\n"); 559b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 560b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 561b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lt: 562b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 563b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = (*sp < value); 564b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 565b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "lt\n"); 566b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 567b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 568b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_ne: 569b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 570b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *sp = (*sp != value); 571b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 572b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "ne\n"); 573b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 574b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 575b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit0: 576b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit1: 577b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit2: 578b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit3: 579b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit4: 580b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit5: 581b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit6: 582b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit7: 583b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit8: 584b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit9: 585b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit10: 586b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit11: 587b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit12: 588b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit13: 589b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit14: 590b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit15: 591b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit16: 592b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit17: 593b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit18: 594b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit19: 595b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit20: 596b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit21: 597b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit22: 598b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit23: 599b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit24: 600b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit25: 601b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit26: 602b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit27: 603b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit28: 604b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit29: 605b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit30: 606b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_lit31: 607b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = opcode - DW_OP_lit0; 608b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = value; 609b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 610b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push literal 0x%llX\n", (uint64_t) value); 611b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 612b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 613b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg0: 614b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg1: 615b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg2: 616b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg3: 617b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg4: 618b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg5: 619b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg6: 620b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg7: 621b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg8: 622b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg9: 623b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg10: 624b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg11: 625b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg12: 626b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg13: 627b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg14: 628b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg15: 629b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg16: 630b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg17: 631b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg18: 632b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg19: 633b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg20: 634b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg21: 635b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg22: 636b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg23: 637b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg24: 638b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg25: 639b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg26: 640b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg27: 641b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg28: 642b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg29: 643b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg30: 644b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_reg31: 645b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik reg = opcode - DW_OP_reg0; 646b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = registers.getRegister((int)reg); 647b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 648b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push reg %d\n", reg); 649b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 650b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 651b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_regx: 652b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik reg = (uint32_t)addressSpace.getULEB128(p, expressionEnd); 653b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = registers.getRegister((int)reg); 654b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 655b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push reg %d + 0x%llX\n", reg, (uint64_t) svalue); 656b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 657b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 658b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg0: 659b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg1: 660b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg2: 661b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg3: 662b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg4: 663b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg5: 664b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg6: 665b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg7: 666b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg8: 667b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg9: 668b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg10: 669b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg11: 670b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg12: 671b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg13: 672b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg14: 673b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg15: 674b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg16: 675b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg17: 676b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg18: 677b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg19: 678b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg20: 679b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg21: 680b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg22: 681b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg23: 682b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg24: 683b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg25: 684b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg26: 685b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg27: 686b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg28: 687b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg29: 688b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg30: 689b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_breg31: 690b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik reg = opcode - DW_OP_breg0; 691b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd); 692b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue += registers.getRegister((int)reg); 693b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = (pint_t)(svalue); 694b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 695b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push reg %d + 0x%llX\n", reg, (uint64_t) svalue); 696b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 697b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 698b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_bregx: 699b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik reg = (uint32_t)addressSpace.getULEB128(p, expressionEnd); 700b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd); 701b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik svalue += registers.getRegister((int)reg); 702b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = (pint_t)(svalue); 703b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 704b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "push reg %d + 0x%llX\n", reg, (uint64_t) svalue); 705b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 706b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 707b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_fbreg: 708b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_ABORT("DW_OP_fbreg not implemented"); 709b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 710b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 711b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_piece: 712b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_ABORT("DW_OP_piece not implemented"); 713b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 714b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 715b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_deref_size: 716b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // pop stack, dereference, push result 717b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = *sp--; 718b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik switch (addressSpace.get8(p++)) { 719b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case 1: 720b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = addressSpace.get8(value); 721b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 722b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case 2: 723b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = addressSpace.get16(value); 724b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 725b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case 4: 726b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = addressSpace.get32(value); 727b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 728b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case 8: 729b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik value = (pint_t)addressSpace.get64(value); 730b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 731b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik default: 732b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_ABORT("DW_OP_deref_size with bad size"); 733b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 734b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *(++sp) = value; 735b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 736b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "sized dereference 0x%llX\n", (uint64_t) value); 737b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 738b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 739b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_xderef_size: 740b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_nop: 741b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_push_object_addres: 742b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_call2: 743b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_call4: 744b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_OP_call_ref: 745b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik default: 746b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_ABORT("dwarf opcode not implemented"); 747b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 748b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 749b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 750b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (log) 751b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik fprintf(stderr, "expression evaluates to 0x%llX\n", (uint64_t) * sp); 752b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return *sp; 753b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 754b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 755b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 756b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 757b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} // namespace libunwind 758b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 759b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // __DWARF_INSTRUCTIONS_HPP__ 760