1b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//===------------------------- AddressSpace.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// Abstracts accessing local vs remote address spaces. 10b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// 11b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//===----------------------------------------------------------------------===// 12b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 13b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#ifndef __ADDRESSSPACE_HPP__ 14b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#define __ADDRESSSPACE_HPP__ 15b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 16b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stdint.h> 17b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stdio.h> 18b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stdlib.h> 19e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#include <string.h> 20b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <dlfcn.h> 21b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 22b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __APPLE__ 23034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik#include <mach-o/getsect.h> 24b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziknamespace libunwind { 25b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool checkKeyMgrRegisteredFDEs(uintptr_t targetAddr, void *&fde); 26b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 27b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 28b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 29b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "libunwind.h" 30b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "config.h" 31b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "dwarf2.h" 32b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include "Registers.hpp" 33b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 34e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_ARM_EHABI 35e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if __linux__ 36e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 37e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef long unsigned int *_Unwind_Ptr; 38e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern "C" _Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr addr, int *len); 39e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 40e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert// Emulate the BSD dl_unwind_find_exidx API when on a GNU libdl system. 41e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#define dl_unwind_find_exidx __gnu_Unwind_Find_exidx 42e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 43e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#else 44e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#include <link.h> 45e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 46e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif // LIBCXXABI_ARM_EHABI 47e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 48b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziknamespace libunwind { 49b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 50b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// Used by findUnwindSections() to return info about needed sections. 51b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct UnwindInfoSections { 52e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if _LIBUNWIND_SUPPORT_DWARF_UNWIND || _LIBUNWIND_SUPPORT_DWARF_INDEX || \ 53e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _LIBUNWIND_SUPPORT_COMPACT_UNWIND 54e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // No dso_base for ARM EHABI. 55e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uintptr_t dso_base; 56e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 57b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_UNWIND 58b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uintptr_t dwarf_section; 59b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uintptr_t dwarf_section_length; 60b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 61b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_DWARF_INDEX 62b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uintptr_t dwarf_index_section; 63b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uintptr_t dwarf_index_section_length; 64b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 65b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if _LIBUNWIND_SUPPORT_COMPACT_UNWIND 66b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uintptr_t compact_unwind_section; 67b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uintptr_t compact_unwind_section_length; 68b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 69e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_ARM_EHABI 70e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uintptr_t arm_section; 71e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uintptr_t arm_section_length; 72e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 73b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 74b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 75b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 76b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// LocalAddressSpace is used as a template parameter to UnwindCursor when 77b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// unwinding a thread in the same process. The wrappers compile away, 78b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// making local unwinds fast. 79b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikclass __attribute__((visibility("hidden"))) LocalAddressSpace { 80b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic: 81b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __LP64__ 82b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typedef uint64_t pint_t; 83b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typedef int64_t sint_t; 84b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#else 85b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typedef uint32_t pint_t; 86b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typedef int32_t sint_t; 87b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 88e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint8_t get8(pint_t addr) { 89e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint8_t val; 90e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert memcpy(&val, (void *)addr, sizeof(val)); 91e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return val; 92e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 93e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint16_t get16(pint_t addr) { 94e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint16_t val; 95e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert memcpy(&val, (void *)addr, sizeof(val)); 96e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return val; 97e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 98e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t get32(pint_t addr) { 99e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t val; 100e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert memcpy(&val, (void *)addr, sizeof(val)); 101e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return val; 102e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 103e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint64_t get64(pint_t addr) { 104e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint64_t val; 105e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert memcpy(&val, (void *)addr, sizeof(val)); 106e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return val; 107e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 108e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert double getDouble(pint_t addr) { 109e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert double val; 110e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert memcpy(&val, (void *)addr, sizeof(val)); 111e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return val; 112e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 113e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert v128 getVector(pint_t addr) { 114e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert v128 val; 115e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert memcpy(&val, (void *)addr, sizeof(val)); 116e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return val; 117e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } 118b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uintptr_t getP(pint_t addr); 119b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static uint64_t getULEB128(pint_t &addr, pint_t end); 120b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static int64_t getSLEB128(pint_t &addr, pint_t end); 121b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 122b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding); 123b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool findFunctionName(pint_t addr, char *buf, size_t bufLen, 124b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik unw_word_t *offset); 125b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info); 126b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool findOtherFDE(pint_t targetAddr, pint_t &fde); 127b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 128b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik static LocalAddressSpace sThisAddressSpace; 129b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 130b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 131b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikinline uintptr_t LocalAddressSpace::getP(pint_t addr) { 132b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __LP64__ 133b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return get64(addr); 134b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#else 135b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return get32(addr); 136b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 137b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 138b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 139b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// Read a ULEB128 into a 64-bit word. 140b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikinline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) { 141b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const uint8_t *p = (uint8_t *)addr; 142b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const uint8_t *pend = (uint8_t *)end; 143b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint64_t result = 0; 144b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik int bit = 0; 145b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik do { 146b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint64_t b; 147b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 148b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (p == pend) 149b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_ABORT("truncated uleb128 expression"); 150b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 151b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik b = *p & 0x7f; 152b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 153b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (bit >= 64 || b << bit >> bit != b) { 154b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_ABORT("malformed uleb128 expression"); 155b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } else { 156b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik result |= b << bit; 157b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bit += 7; 158b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 159b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } while (*p++ >= 0x80); 160b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik addr = (pint_t) p; 161b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return result; 162b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 163b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 164b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// Read a SLEB128 into a 64-bit word. 165b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikinline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) { 166b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const uint8_t *p = (uint8_t *)addr; 167b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const uint8_t *pend = (uint8_t *)end; 168b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik int64_t result = 0; 169b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik int bit = 0; 170b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint8_t byte; 171b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik do { 172b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (p == pend) 173b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_ABORT("truncated sleb128 expression"); 174b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik byte = *p++; 175b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik result |= ((byte & 0x7f) << bit); 176b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bit += 7; 177b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } while (byte & 0x80); 178b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // sign extend negative numbers 179b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if ((byte & 0x40) != 0) 180b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik result |= (-1LL) << bit; 181b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik addr = (pint_t) p; 182b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return result; 183b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 184b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 185b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikinline LocalAddressSpace::pint_t LocalAddressSpace::getEncodedP(pint_t &addr, 186b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t end, 187b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint8_t encoding) { 188b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t startAddr = addr; 189b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik const uint8_t *p = (uint8_t *)addr; 190b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t result; 191b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 192b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // first get value 193b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik switch (encoding & 0x0F) { 194b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_EH_PE_ptr: 195b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik result = getP(addr); 196b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += sizeof(pint_t); 197b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik addr = (pint_t) p; 198b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 199b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_EH_PE_uleb128: 200b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik result = (pint_t)getULEB128(addr, end); 201b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 202b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_EH_PE_udata2: 203b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik result = get16(addr); 204b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 2; 205b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik addr = (pint_t) p; 206b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 207b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_EH_PE_udata4: 208b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik result = get32(addr); 209b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 4; 210b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik addr = (pint_t) p; 211b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 212b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_EH_PE_udata8: 213b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik result = (pint_t)get64(addr); 214b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 8; 215b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik addr = (pint_t) p; 216b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 217b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_EH_PE_sleb128: 218b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik result = (pint_t)getSLEB128(addr, end); 219b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 220b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_EH_PE_sdata2: 221e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // Sign extend from signed 16-bit value. 222e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert result = (pint_t)(int16_t)get16(addr); 223b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 2; 224b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik addr = (pint_t) p; 225b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 226b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_EH_PE_sdata4: 227e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // Sign extend from signed 32-bit value. 228e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert result = (pint_t)(int32_t)get32(addr); 229b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 4; 230b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik addr = (pint_t) p; 231b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 232b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_EH_PE_sdata8: 233b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik result = (pint_t)get64(addr); 234b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik p += 8; 235b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik addr = (pint_t) p; 236b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 237b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik default: 238b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_ABORT("unknown pointer encoding"); 239b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 240b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 241b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // then add relative offset 242b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik switch (encoding & 0x70) { 243b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_EH_PE_absptr: 244b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // do nothing 245b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 246b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_EH_PE_pcrel: 247b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik result += startAddr; 248b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 249b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_EH_PE_textrel: 250b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_ABORT("DW_EH_PE_textrel pointer encoding not supported"); 251b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 252b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_EH_PE_datarel: 253b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_ABORT("DW_EH_PE_datarel pointer encoding not supported"); 254b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 255b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_EH_PE_funcrel: 256b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_ABORT("DW_EH_PE_funcrel pointer encoding not supported"); 257b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 258b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik case DW_EH_PE_aligned: 259b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_ABORT("DW_EH_PE_aligned pointer encoding not supported"); 260b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 261b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik default: 262b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _LIBUNWIND_ABORT("unknown pointer encoding"); 263b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik break; 264b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 265b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 266b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (encoding & DW_EH_PE_indirect) 267b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik result = getP(result); 268b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 269b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return result; 270b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 271b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 272034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik#if __APPLE__ 273034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik struct dyld_unwind_sections 274034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik { 275034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik const struct mach_header* mh; 276034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik const void* dwarf_section; 277034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik uintptr_t dwarf_section_length; 278034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik const void* compact_unwind_section; 279034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik uintptr_t compact_unwind_section_length; 280034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik }; 28165b726605835d1b3947d648497729a4be05deddeNick Kledzik #if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) \ 28265b726605835d1b3947d648497729a4be05deddeNick Kledzik && (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)) \ 28365b726605835d1b3947d648497729a4be05deddeNick Kledzik || defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 284034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik // In 10.7.0 or later, libSystem.dylib implements this function. 285034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *); 286034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik #else 287034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik // In 10.6.x and earlier, we need to implement this functionality. 288034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik static inline bool _dyld_find_unwind_sections(void* addr, 289034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik dyld_unwind_sections* info) { 290034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik // Find mach-o image containing address. 291034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik Dl_info dlinfo; 292034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik if (!dladdr(addr, &dlinfo)) 293034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik return false; 294034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik const mach_header *mh = (const mach_header *)dlinfo.dli_saddr; 295034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik 296034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik // Find dwarf unwind section in that image. 297034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik unsigned long size; 298034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik const uint8_t *p = getsectiondata(mh, "__TEXT", "__eh_frame", &size); 299034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik if (!p) 300034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik return false; 301034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik 302034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik // Fill in return struct. 303034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik info->mh = mh; 304034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik info->dwarf_section = p; 305034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik info->dwarf_section_length = size; 306034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik info->compact_unwind_section = 0; 307034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik info->compact_unwind_section_length = 0; 308034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik 309034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik return true; 310034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik } 311034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik #endif 312034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik#endif 313034e79a395bf7815fd94ad81d40609aa52f2f34cNick Kledzik 314b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikinline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, 315b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik UnwindInfoSections &info) { 316b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __APPLE__ 317b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik dyld_unwind_sections dyldInfo; 318b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (_dyld_find_unwind_sections((void *)targetAddr, &dyldInfo)) { 319b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik info.dso_base = (uintptr_t)dyldInfo.mh; 320b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik #if _LIBUNWIND_SUPPORT_DWARF_UNWIND 321b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik info.dwarf_section = (uintptr_t)dyldInfo.dwarf_section; 322b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik info.dwarf_section_length = dyldInfo.dwarf_section_length; 323b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik #endif 324b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik info.compact_unwind_section = (uintptr_t)dyldInfo.compact_unwind_section; 325b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik info.compact_unwind_section_length = dyldInfo.compact_unwind_section_length; 326b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return true; 327b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 328e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#elif LIBCXXABI_ARM_EHABI 329e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert int length = 0; 330e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert info.arm_section = (uintptr_t) dl_unwind_find_exidx( 331e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert (_Unwind_Ptr) targetAddr, &length); 332e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert info.arm_section_length = (uintptr_t)length; 333e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %X length %x\n", 334e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert info.arm_section, info.arm_section_length); 335e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert if (info.arm_section && info.arm_section_length) 336e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return true; 337b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 338b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 339b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return false; 340b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 341b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 342b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 343b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikinline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) { 344b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if __APPLE__ 345b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return checkKeyMgrRegisteredFDEs(targetAddr, *((void**)&fde)); 346b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#else 347b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // TO DO: if OS has way to dynamically register FDEs, check that. 348e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert (void)targetAddr; 349e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert (void)fde; 350b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return false; 351b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 352b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 353b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 354b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikinline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf, 355b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik size_t bufLen, 356b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik unw_word_t *offset) { 357e085735cbedc82b1064f05ff796e32e906a95036Dan Albert Dl_info dyldInfo; 358b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (dladdr((void *)addr, &dyldInfo)) { 359b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik if (dyldInfo.dli_sname != NULL) { 360e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert snprintf(buf, bufLen, "%s", dyldInfo.dli_sname); 361b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik *offset = (addr - (pint_t) dyldInfo.dli_saddr); 362b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return true; 363b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 364b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik } 365b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return false; 366b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 367b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 368b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 369b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 370b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if UNW_REMOTE 371b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 372b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// OtherAddressSpace is used as a template parameter to UnwindCursor when 373b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// unwinding a thread in the another process. The other process can be a 374b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// different endianness and a different pointer size which is handled by 375b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// the P template parameter. 376b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P> 377b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikclass OtherAddressSpace { 378b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikpublic: 379b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik OtherAddressSpace(task_t task) : fTask(task) {} 380b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 381b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik typedef typename P::uint_t pint_t; 382b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 383b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint8_t get8(pint_t addr); 384b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint16_t get16(pint_t addr); 385b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t get32(pint_t addr); 386b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint64_t get64(pint_t addr); 387b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t getP(pint_t addr); 388b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint64_t getULEB128(pint_t &addr, pint_t end); 389b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik int64_t getSLEB128(pint_t &addr, pint_t end); 390b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding); 391b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool findFunctionName(pint_t addr, char *buf, size_t bufLen, 392b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik unw_word_t *offset); 393b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info); 394b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik bool findOtherFDE(pint_t targetAddr, pint_t &fde); 395b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikprivate: 396b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik void *localCopy(pint_t addr); 397b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 398b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik task_t fTask; 399b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 400b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 401b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P> uint8_t OtherAddressSpace<P>::get8(pint_t addr) { 402b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return *((uint8_t *)localCopy(addr)); 403b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 404b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 405b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P> uint16_t OtherAddressSpace<P>::get16(pint_t addr) { 406b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return P::E::get16(*(uint16_t *)localCopy(addr)); 407b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 408b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 409b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P> uint32_t OtherAddressSpace<P>::get32(pint_t addr) { 410b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return P::E::get32(*(uint32_t *)localCopy(addr)); 411b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 412b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 413b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P> uint64_t OtherAddressSpace<P>::get64(pint_t addr) { 414b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return P::E::get64(*(uint64_t *)localCopy(addr)); 415b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 416b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 417b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P> 418b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypename P::uint_t OtherAddressSpace<P>::getP(pint_t addr) { 419b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return P::getP(*(uint64_t *)localCopy(addr)); 420b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 421b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 422b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P> 423b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikuint64_t OtherAddressSpace<P>::getULEB128(pint_t &addr, pint_t end) { 424b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uintptr_t size = (end - addr); 425b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); 426b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik LocalAddressSpace::pint_t sladdr = laddr; 427b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint64_t result = LocalAddressSpace::getULEB128(laddr, laddr + size); 428b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik addr += (laddr - sladdr); 429b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return result; 430b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 431b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 432b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P> 433b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikint64_t OtherAddressSpace<P>::getSLEB128(pint_t &addr, pint_t end) { 434b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uintptr_t size = (end - addr); 435b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); 436b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik LocalAddressSpace::pint_t sladdr = laddr; 437b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint64_t result = LocalAddressSpace::getSLEB128(laddr, laddr + size); 438b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik addr += (laddr - sladdr); 439b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik return result; 440b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 441b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 442b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P> void *OtherAddressSpace<P>::localCopy(pint_t addr) { 443b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // FIX ME 444b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 445b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 446b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktemplate <typename P> 447b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikbool OtherAddressSpace<P>::findFunctionName(pint_t addr, char *buf, 448b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik size_t bufLen, unw_word_t *offset) { 449b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // FIX ME 450b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 451b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 452b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// unw_addr_space is the base class that abstract unw_addr_space_t type in 453b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// libunwind.h points to. 454b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct unw_addr_space { 455b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik cpu_type_t cpuType; 456b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik task_t taskPort; 457b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 458b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 459b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// unw_addr_space_i386 is the concrete instance that a unw_addr_space_t points 460b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// to when examining 461b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// a 32-bit intel process. 462b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct unw_addr_space_i386 : public unw_addr_space { 463b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik unw_addr_space_i386(task_t task) : oas(task) {} 464b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik OtherAddressSpace<Pointer32<LittleEndian> > oas; 465b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 466b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 467b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// unw_addr_space_x86_64 is the concrete instance that a unw_addr_space_t 468b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// points to when examining 469b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// a 64-bit intel process. 470b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct unw_addr_space_x86_64 : public unw_addr_space { 471b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik unw_addr_space_x86_64(task_t task) : oas(task) {} 472b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik OtherAddressSpace<Pointer64<LittleEndian> > oas; 473b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 474b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 475b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// unw_addr_space_ppc is the concrete instance that a unw_addr_space_t points 476b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// to when examining 477b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// a 32-bit PowerPC process. 478b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct unw_addr_space_ppc : public unw_addr_space { 479b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik unw_addr_space_ppc(task_t task) : oas(task) {} 480b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik OtherAddressSpace<Pointer32<BigEndian> > oas; 481b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 482b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 483b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // UNW_REMOTE 484b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 485b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} // namespace libunwind 486b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 487b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // __ADDRESSSPACE_HPP__ 488