1675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool//===-------------------------- DwarfInstructions.hpp ---------------------===// 2675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// 3675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// The LLVM Compiler Infrastructure 4675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// 5675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// This file is dual licensed under the MIT and the University of Illinois Open 6675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// Source Licenses. See LICENSE.TXT for details. 7675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// 8675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// 963469ffb83da03e4fd54185bf14384221dc3b1c5Ed Maste// Processor specific interpretation of DWARF unwind info. 10675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// 11675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool//===----------------------------------------------------------------------===// 12675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 13675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifndef __DWARF_INSTRUCTIONS_HPP__ 14675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#define __DWARF_INSTRUCTIONS_HPP__ 15675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 16675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <stdint.h> 17675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <stdio.h> 18675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <stdlib.h> 19675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 20675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include "dwarf2.h" 21675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include "Registers.hpp" 22675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include "DwarfParser.hpp" 23675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include "config.h" 24675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 25675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 26675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolnamespace libunwind { 27675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 28675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 2963469ffb83da03e4fd54185bf14384221dc3b1c5Ed Maste/// DwarfInstructions maps abtract DWARF unwind instructions to a particular 30675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// architecture 31675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename A, typename R> 32675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolclass DwarfInstructions { 33675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolpublic: 34675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool typedef typename A::pint_t pint_t; 35675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool typedef typename A::sint_t sint_t; 36675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 37675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool static int stepWithDwarf(A &addressSpace, pint_t pc, pint_t fdeStart, 38675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool R ®isters); 39675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 40675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolprivate: 41675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 42675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool enum { 43675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool DW_X86_64_RET_ADDR = 16 44675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool }; 45675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 46675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool enum { 47675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool DW_X86_RET_ADDR = 8 48675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool }; 49675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 50675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool typedef typename CFI_Parser<A>::RegisterLocation RegisterLocation; 51675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool typedef typename CFI_Parser<A>::PrologInfo PrologInfo; 52675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool typedef typename CFI_Parser<A>::FDE_Info FDE_Info; 53675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool typedef typename CFI_Parser<A>::CIE_Info CIE_Info; 54675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 55675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool static pint_t evaluateExpression(pint_t expression, A &addressSpace, 56675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const R ®isters, 57675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t initialStackValue); 58675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool static pint_t getSavedRegister(A &addressSpace, const R ®isters, 59675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t cfa, const RegisterLocation &savedReg); 60675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool static double getSavedFloatRegister(A &addressSpace, const R ®isters, 61675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t cfa, const RegisterLocation &savedReg); 62675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool static v128 getSavedVectorRegister(A &addressSpace, const R ®isters, 63675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t cfa, const RegisterLocation &savedReg); 64675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 65675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool static pint_t getCFA(A &addressSpace, const PrologInfo &prolog, 66675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const R ®isters) { 67675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (prolog.cfaRegister != 0) 68675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) + 69675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool prolog.cfaRegisterOffset); 70675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (prolog.cfaExpression != 0) 71675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace, 72675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool registers, 0); 73675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool assert(0 && "getCFA(): unknown location"); 74675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool __builtin_unreachable(); 75675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 76675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}; 77675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 78675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 79675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename A, typename R> 80675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltypename A::pint_t DwarfInstructions<A, R>::getSavedRegister( 81675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool A &addressSpace, const R ®isters, pint_t cfa, 82675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const RegisterLocation &savedReg) { 83675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool switch (savedReg.location) { 84675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterInCFA: 85675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return addressSpace.getP(cfa + (pint_t)savedReg.value); 86675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 87675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterAtExpression: 88675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return addressSpace.getP( 89675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool evaluateExpression((pint_t)savedReg.value, addressSpace, 90675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool registers, cfa)); 91675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 92675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterIsExpression: 93675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return evaluateExpression((pint_t)savedReg.value, addressSpace, 94675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool registers, cfa); 95675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 96675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterInRegister: 97675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return registers.getRegister((int)savedReg.value); 98675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 99675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterUnused: 100675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterOffsetFromCFA: 101675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // FIX ME 102675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 103675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 104675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_ABORT("unsupported restore location for register"); 105675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 106675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 107675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename A, typename R> 108675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooldouble DwarfInstructions<A, R>::getSavedFloatRegister( 109675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool A &addressSpace, const R ®isters, pint_t cfa, 110675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const RegisterLocation &savedReg) { 111675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool switch (savedReg.location) { 112675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterInCFA: 113675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return addressSpace.getDouble(cfa + (pint_t)savedReg.value); 114675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 115675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterAtExpression: 116675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return addressSpace.getDouble( 117675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool evaluateExpression((pint_t)savedReg.value, addressSpace, 118675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool registers, cfa)); 119675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 120675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterIsExpression: 121675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterUnused: 122675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterOffsetFromCFA: 123675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterInRegister: 124675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // FIX ME 125675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 126675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 127675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_ABORT("unsupported restore location for float register"); 128675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 129675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 130675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename A, typename R> 131675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolv128 DwarfInstructions<A, R>::getSavedVectorRegister( 132675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool A &addressSpace, const R ®isters, pint_t cfa, 133675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const RegisterLocation &savedReg) { 134675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool switch (savedReg.location) { 135675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterInCFA: 136675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return addressSpace.getVector(cfa + (pint_t)savedReg.value); 137675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 138675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterAtExpression: 139675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return addressSpace.getVector( 140675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool evaluateExpression((pint_t)savedReg.value, addressSpace, 141675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool registers, cfa)); 142675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 143675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterIsExpression: 144675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterUnused: 145675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterOffsetFromCFA: 146675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case CFI_Parser<A>::kRegisterInRegister: 147675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // FIX ME 148675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 149675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 150675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_ABORT("unsupported restore location for vector register"); 151675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 152675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 153675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename A, typename R> 154675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolint DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc, 155675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t fdeStart, R ®isters) { 156675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool FDE_Info fdeInfo; 157675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool CIE_Info cieInfo; 158675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo, 159675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool &cieInfo) == NULL) { 160675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool PrologInfo prolog; 161675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc, 162675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool &prolog)) { 163675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // get pointer to cfa (architecture specific) 164675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t cfa = getCFA(addressSpace, prolog, registers); 165675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 16663469ffb83da03e4fd54185bf14384221dc3b1c5Ed Maste // restore registers that DWARF says were saved 167675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool R newRegisters = registers; 168675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t returnAddress = 0; 169675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const int lastReg = R::lastDwarfRegNum(); 170af4b7dd015efae2d12d7387c39eab470d981113aMartin Storsjo assert(static_cast<int>(CFI_Parser<A>::kMaxRegisterNumber) >= lastReg && 171675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool "register range too large"); 172632aa38f313c507ce3aec732dc2a6d2259502731Ed Maste assert(lastReg >= (int)cieInfo.returnAddressRegister && 173675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool "register range does not contain return address register"); 174675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool for (int i = 0; i <= lastReg; ++i) { 1757cb3a4078892fac76919812ab31ad35ccc764f1eLogan Chien if (prolog.savedRegisters[i].location != 1767cb3a4078892fac76919812ab31ad35ccc764f1eLogan Chien CFI_Parser<A>::kRegisterUnused) { 1777cb3a4078892fac76919812ab31ad35ccc764f1eLogan Chien if (registers.validFloatRegister(i)) 178675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool newRegisters.setFloatRegister( 179675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool i, getSavedFloatRegister(addressSpace, registers, cfa, 180675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool prolog.savedRegisters[i])); 181675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool else if (registers.validVectorRegister(i)) 182675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool newRegisters.setVectorRegister( 183675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool i, getSavedVectorRegister(addressSpace, registers, cfa, 184675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool prolog.savedRegisters[i])); 185675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool else if (i == (int)cieInfo.returnAddressRegister) 186675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool returnAddress = getSavedRegister(addressSpace, registers, cfa, 187675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool prolog.savedRegisters[i]); 188675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool else if (registers.validRegister(i)) 189675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool newRegisters.setRegister( 190675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool i, getSavedRegister(addressSpace, registers, cfa, 191675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool prolog.savedRegisters[i])); 192675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool else 193675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return UNW_EBADREG; 194675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 195675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 196675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 197675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // By definition, the CFA is the stack pointer at the call site, so 198675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // restoring SP means setting it to CFA. 199675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool newRegisters.setSP(cfa); 200675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 201675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // Return address is address after call site instruction, so setting IP to 202675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // that does simualates a return. 203675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool newRegisters.setIP(returnAddress); 204675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 205675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // Simulate the step by replacing the register set with the new ones. 206675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool registers = newRegisters; 207675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 208675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return UNW_STEP_SUCCESS; 209675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 210675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 211675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return UNW_EBADFRAME; 212675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 213675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 214675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename A, typename R> 215675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltypename A::pint_t 216675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem AbdulrasoolDwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace, 217675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const R ®isters, 218675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t initialStackValue) { 219675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const bool log = false; 220675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t p = expression; 221675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t expressionEnd = expression + 20; // temp, until len read 222675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t length = (pint_t)addressSpace.getULEB128(p, expressionEnd); 223675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool expressionEnd = p + length; 224675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 225675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "evaluateExpression(): length=%" PRIu64 "\n", 226675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool (uint64_t)length); 227675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t stack[100]; 228675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t *sp = stack; 229675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = initialStackValue; 230675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 231675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool while (p < expressionEnd) { 232675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) { 233675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool for (pint_t *t = sp; t > stack; --t) { 234675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "sp[] = 0x%" PRIx64 "\n", (uint64_t)(*t)); 235675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 236675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 237675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint8_t opcode = addressSpace.get8(p++); 238675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool sint_t svalue, svalue2; 239675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t value; 240675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint32_t reg; 241675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool switch (opcode) { 242675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_addr: 243675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // push immediate address sized value 244675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = addressSpace.getP(p); 245675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += sizeof(pint_t); 246675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = value; 247675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 248675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 249675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 250675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 251675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_deref: 252675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // pop stack, dereference, push result 253675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 254675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = addressSpace.getP(value); 255675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 256675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "dereference 0x%" PRIx64 "\n", (uint64_t)value); 257675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 258675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 259675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_const1u: 260675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // push immediate 1 byte value 261675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = addressSpace.get8(p); 262675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 1; 263675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = value; 264675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 265675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 266675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 267675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 268675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_const1s: 269675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // push immediate 1 byte signed value 270675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue = (int8_t) addressSpace.get8(p); 271675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 1; 272675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = (pint_t)svalue; 273675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 274675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); 275675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 276675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 277675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_const2u: 278675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // push immediate 2 byte value 279675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = addressSpace.get16(p); 280675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 2; 281675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = value; 282675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 283675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 284675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 285675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 286675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_const2s: 287675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // push immediate 2 byte signed value 288675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue = (int16_t) addressSpace.get16(p); 289675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 2; 290675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = (pint_t)svalue; 291675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 292675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); 293675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 294675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 295675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_const4u: 296675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // push immediate 4 byte value 297675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = addressSpace.get32(p); 298675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 4; 299675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = value; 300675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 301675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 302675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 303675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 304675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_const4s: 305675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // push immediate 4 byte signed value 306675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue = (int32_t)addressSpace.get32(p); 307675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 4; 308675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = (pint_t)svalue; 309675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 310675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); 311675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 312675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 313675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_const8u: 314675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // push immediate 8 byte value 315675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = (pint_t)addressSpace.get64(p); 316675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 8; 317675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = value; 318675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 319675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 320675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 321675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 322675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_const8s: 323675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // push immediate 8 byte signed value 324675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = (pint_t)addressSpace.get64(p); 325675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 8; 326675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = value; 327675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 328675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 329675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 330675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 331675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_constu: 332675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // push immediate ULEB128 value 333675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = (pint_t)addressSpace.getULEB128(p, expressionEnd); 334675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = value; 335675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 336675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value); 337675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 338675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 339675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_consts: 340675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // push immediate SLEB128 value 341675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd); 342675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = (pint_t)svalue; 343675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 344675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue); 345675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 346675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 347675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_dup: 348675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // push top of stack 349675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp; 350675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = value; 351675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 352675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "duplicate top of stack\n"); 353675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 354675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 355675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_drop: 356675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // pop 357675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool --sp; 358675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 359675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "pop top of stack\n"); 360675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 361675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 362675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_over: 363675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // dup second 364675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = sp[-1]; 365675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = value; 366675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 367675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "duplicate second in stack\n"); 368675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 369675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 370675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_pick: 371675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // pick from 372675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool reg = addressSpace.get8(p); 373675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 1; 374675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = sp[-reg]; 375675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = value; 376675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 377675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "duplicate %d in stack\n", reg); 378675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 379675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 380675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_swap: 381675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // swap top two 382675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = sp[0]; 383675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool sp[0] = sp[-1]; 384675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool sp[-1] = value; 385675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 386675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "swap top of stack\n"); 387675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 388675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 389675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_rot: 390675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // rotate top three 391675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = sp[0]; 392675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool sp[0] = sp[-1]; 393675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool sp[-1] = sp[-2]; 394675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool sp[-2] = value; 395675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 396675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "rotate top three of stack\n"); 397675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 398675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 399675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_xderef: 400675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // pop stack, dereference, push result 401675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 402675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = *((pint_t*)value); 403675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 404675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "x-dereference 0x%" PRIx64 "\n", (uint64_t)value); 405675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 406675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 407675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_abs: 408675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue = (sint_t)*sp; 409675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (svalue < 0) 410675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = (pint_t)(-svalue); 411675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 412675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "abs\n"); 413675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 414675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 415675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_and: 416675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 417675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp &= value; 418675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 419675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "and\n"); 420675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 421675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 422675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_div: 423675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue = (sint_t)(*sp--); 424675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue2 = (sint_t)*sp; 425675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = (pint_t)(svalue2 / svalue); 426675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 427675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "div\n"); 428675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 429675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 430675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_minus: 431675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 432675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = *sp - value; 433675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 434675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "minus\n"); 435675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 436675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 437675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_mod: 438675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue = (sint_t)(*sp--); 439675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue2 = (sint_t)*sp; 440675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = (pint_t)(svalue2 % svalue); 441675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 442675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "module\n"); 443675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 444675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 445675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_mul: 446675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue = (sint_t)(*sp--); 447675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue2 = (sint_t)*sp; 448675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = (pint_t)(svalue2 * svalue); 449675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 450675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "mul\n"); 451675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 452675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 453675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_neg: 454675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = 0 - *sp; 455675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 456675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "neg\n"); 457675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 458675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 459675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_not: 460675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue = (sint_t)(*sp); 461675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = (pint_t)(~svalue); 462675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 463675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "not\n"); 464675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 465675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 466675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_or: 467675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 468675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp |= value; 469675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 470675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "or\n"); 471675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 472675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 473675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_plus: 474675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 475675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp += value; 476675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 477675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "plus\n"); 478675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 479675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 480675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_plus_uconst: 481675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // pop stack, add uelb128 constant, push result 4822fd2d585a530d0564a5ef4b1184e0767c84c93b0Saleem Abdulrasool *sp += static_cast<pint_t>(addressSpace.getULEB128(p, expressionEnd)); 483675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 484675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "add constant\n"); 485675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 486675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 487675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_shl: 488675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 489675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = *sp << value; 490675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 491675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "shift left\n"); 492675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 493675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 494675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_shr: 495675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 496675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = *sp >> value; 497675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 498675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "shift left\n"); 499675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 500675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 501675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_shra: 502675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 503675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue = (sint_t)*sp; 504675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = (pint_t)(svalue >> value); 505675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 506675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "shift left arithmetric\n"); 507675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 508675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 509675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_xor: 510675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 511675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp ^= value; 512675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 513675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "xor\n"); 514675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 515675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 516675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_skip: 517675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue = (int16_t) addressSpace.get16(p); 518675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 2; 519675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p = (pint_t)((sint_t)p + svalue); 520675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 521675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "skip %" PRIu64 "\n", (uint64_t)svalue); 522675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 523675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 524675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_bra: 525675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue = (int16_t) addressSpace.get16(p); 526675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 2; 527675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (*sp--) 528675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p = (pint_t)((sint_t)p + svalue); 529675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 530675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "bra %" PRIu64 "\n", (uint64_t)svalue); 531675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 532675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 533675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_eq: 534675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 535675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = (*sp == value); 536675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 537675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "eq\n"); 538675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 539675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 540675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_ge: 541675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 542675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = (*sp >= value); 543675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 544675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "ge\n"); 545675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 546675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 547675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_gt: 548675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 549675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = (*sp > value); 550675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 551675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "gt\n"); 552675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 553675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 554675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_le: 555675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 556675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = (*sp <= value); 557675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 558675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "le\n"); 559675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 560675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 561675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lt: 562675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 563675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = (*sp < value); 564675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 565675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "lt\n"); 566675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 567675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 568675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_ne: 569675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 570675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *sp = (*sp != value); 571675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 572675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "ne\n"); 573675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 574675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 575675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit0: 576675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit1: 577675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit2: 578675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit3: 579675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit4: 580675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit5: 581675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit6: 582675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit7: 583675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit8: 584675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit9: 585675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit10: 586675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit11: 587675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit12: 588675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit13: 589675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit14: 590675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit15: 591675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit16: 592675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit17: 593675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit18: 594675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit19: 595675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit20: 596675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit21: 597675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit22: 598675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit23: 599675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit24: 600675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit25: 601675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit26: 602675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit27: 603675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit28: 604675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit29: 605675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit30: 606675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_lit31: 607675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = static_cast<pint_t>(opcode - DW_OP_lit0); 608675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = value; 609675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 610675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push literal 0x%" PRIx64 "\n", (uint64_t)value); 611675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 612675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 613675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg0: 614675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg1: 615675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg2: 616675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg3: 617675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg4: 618675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg5: 619675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg6: 620675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg7: 621675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg8: 622675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg9: 623675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg10: 624675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg11: 625675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg12: 626675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg13: 627675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg14: 628675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg15: 629675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg16: 630675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg17: 631675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg18: 632675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg19: 633675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg20: 634675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg21: 635675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg22: 636675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg23: 637675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg24: 638675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg25: 639675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg26: 640675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg27: 641675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg28: 642675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg29: 643675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg30: 644675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_reg31: 645675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool reg = static_cast<uint32_t>(opcode - DW_OP_reg0); 646675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = registers.getRegister((int)reg); 647675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 648675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push reg %d\n", reg); 649675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 650675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 651675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_regx: 652675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool reg = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd)); 653675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = registers.getRegister((int)reg); 654675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 655675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue); 656675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 657675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 658675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg0: 659675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg1: 660675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg2: 661675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg3: 662675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg4: 663675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg5: 664675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg6: 665675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg7: 666675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg8: 667675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg9: 668675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg10: 669675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg11: 670675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg12: 671675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg13: 672675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg14: 673675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg15: 674675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg16: 675675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg17: 676675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg18: 677675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg19: 678675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg20: 679675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg21: 680675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg22: 681675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg23: 682675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg24: 683675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg25: 684675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg26: 685675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg27: 686675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg28: 687675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg29: 688675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg30: 689675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_breg31: 690675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool reg = static_cast<uint32_t>(opcode - DW_OP_breg0); 691675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd); 692675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue += static_cast<sint_t>(registers.getRegister((int)reg)); 693675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = (pint_t)(svalue); 694675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 695675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue); 696675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 697675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 698675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_bregx: 699675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool reg = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd)); 700675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd); 701675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool svalue += static_cast<sint_t>(registers.getRegister((int)reg)); 702675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = (pint_t)(svalue); 703675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 704675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue); 705675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 706675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 707675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_fbreg: 708675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_ABORT("DW_OP_fbreg not implemented"); 709675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 710675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 711675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_piece: 712675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_ABORT("DW_OP_piece not implemented"); 713675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 714675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 715675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_deref_size: 716675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // pop stack, dereference, push result 717675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = *sp--; 718675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool switch (addressSpace.get8(p++)) { 719675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case 1: 720675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = addressSpace.get8(value); 721675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 722675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case 2: 723675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = addressSpace.get16(value); 724675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 725675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case 4: 726675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = addressSpace.get32(value); 727675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 728675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case 8: 729675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool value = (pint_t)addressSpace.get64(value); 730675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 731675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool default: 732675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_ABORT("DW_OP_deref_size with bad size"); 733675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 734675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *(++sp) = value; 735675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 736675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "sized dereference 0x%" PRIx64 "\n", (uint64_t)value); 737675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 738675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 739675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_xderef_size: 740675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_nop: 741675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_push_object_addres: 742675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_call2: 743675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_call4: 744675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_OP_call_ref: 745675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool default: 74663469ffb83da03e4fd54185bf14384221dc3b1c5Ed Maste _LIBUNWIND_ABORT("DWARF opcode not implemented"); 747675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 748675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 749675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 750675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (log) 751675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool fprintf(stderr, "expression evaluates to 0x%" PRIx64 "\n", (uint64_t)*sp); 752675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return *sp; 753675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 754675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 755675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 756675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 757675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} // namespace libunwind 758675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 759675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif // __DWARF_INSTRUCTIONS_HPP__ 760