1675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool//===------------------------- AddressSpace.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// 9675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// Abstracts accessing local vs remote address spaces. 10675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// 11675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool//===----------------------------------------------------------------------===// 12675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 13675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifndef __ADDRESSSPACE_HPP__ 14675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#define __ADDRESSSPACE_HPP__ 15675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 16675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <stdint.h> 17675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <stdio.h> 18675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <stdlib.h> 19675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <string.h> 20675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 21675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifndef _LIBUNWIND_IS_BAREMETAL 22675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <dlfcn.h> 23675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 24675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 25675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef __APPLE__ 26675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <mach-o/getsect.h> 27675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolnamespace libunwind { 28675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool bool checkKeyMgrRegisteredFDEs(uintptr_t targetAddr, void *&fde); 29675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 30675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 31675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 32675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include "libunwind.h" 33675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include "config.h" 34675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include "dwarf2.h" 35675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include "Registers.hpp" 36675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 3761278584b5c84c422ff5da10f46c3235c54636c9Logan Chien#if _LIBUNWIND_ARM_EHABI 38675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef __linux__ 39675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 40675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltypedef long unsigned int *_Unwind_Ptr; 41675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolextern "C" _Unwind_Ptr __gnu_Unwind_Find_exidx(_Unwind_Ptr addr, int *len); 42675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 43675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// Emulate the BSD dl_unwind_find_exidx API when on a GNU libdl system. 44675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#define dl_unwind_find_exidx __gnu_Unwind_Find_exidx 45675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 46675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#elif !defined(_LIBUNWIND_IS_BAREMETAL) 47675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <link.h> 48675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#else // !defined(_LIBUNWIND_IS_BAREMETAL) 49675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// When statically linked on bare-metal, the symbols for the EH table are looked 50675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool// up without going through the dynamic loader. 51675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolstruct EHTEntry { 52675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint32_t functionOffset; 53675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint32_t unwindOpcodes; 54675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}; 55675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolextern EHTEntry __exidx_start; 56675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolextern EHTEntry __exidx_end; 57675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif // !defined(_LIBUNWIND_IS_BAREMETAL) 5861278584b5c84c422ff5da10f46c3235c54636c9Logan Chien#endif // _LIBUNWIND_ARM_EHABI 59675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 60f67c63591cb6509181f74987578699c51c440b2eEd Schouten#if defined(__CloudABI__) || defined(__FreeBSD__) || defined(__linux__) 61675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#if _LIBUNWIND_SUPPORT_DWARF_UNWIND && _LIBUNWIND_SUPPORT_DWARF_INDEX 62675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include <link.h> 63f67c63591cb6509181f74987578699c51c440b2eEd Schouten// Macro for machine-independent access to the ELF program headers. This 64f67c63591cb6509181f74987578699c51c440b2eEd Schouten// macro is not available on some systems (e.g., FreeBSD). On these 65f67c63591cb6509181f74987578699c51c440b2eEd Schouten// systems the data structures are just called Elf_XXX. Define ElfW() 66f67c63591cb6509181f74987578699c51c440b2eEd Schouten// locally. 67f67c63591cb6509181f74987578699c51c440b2eEd Schouten#if !defined(ElfW) 68f67c63591cb6509181f74987578699c51c440b2eEd Schouten#define ElfW(type) Elf_##type 69f67c63591cb6509181f74987578699c51c440b2eEd Schouten#endif 70675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#include "EHHeaderParser.hpp" 71675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 72675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 73675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 74675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolnamespace libunwind { 75675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 76675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// Used by findUnwindSections() to return info about needed sections. 77675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolstruct UnwindInfoSections { 78675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#if _LIBUNWIND_SUPPORT_DWARF_UNWIND || _LIBUNWIND_SUPPORT_DWARF_INDEX || \ 79675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_SUPPORT_COMPACT_UNWIND 80675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // No dso_base for ARM EHABI. 81675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t dso_base; 82675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 83675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#if _LIBUNWIND_SUPPORT_DWARF_UNWIND 84675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t dwarf_section; 85675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t dwarf_section_length; 86675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 87675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#if _LIBUNWIND_SUPPORT_DWARF_INDEX 88675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t dwarf_index_section; 89675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t dwarf_index_section_length; 90675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 91675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#if _LIBUNWIND_SUPPORT_COMPACT_UNWIND 92675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t compact_unwind_section; 93675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t compact_unwind_section_length; 94675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 9561278584b5c84c422ff5da10f46c3235c54636c9Logan Chien#if _LIBUNWIND_ARM_EHABI 96675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t arm_section; 97675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t arm_section_length; 98675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 99675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}; 100675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 101675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 102675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// LocalAddressSpace is used as a template parameter to UnwindCursor when 103675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// unwinding a thread in the same process. The wrappers compile away, 104675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// making local unwinds fast. 105675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolclass __attribute__((visibility("hidden"))) LocalAddressSpace { 106675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolpublic: 107675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef __LP64__ 108675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool typedef uint64_t pint_t; 109675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool typedef int64_t sint_t; 110675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#else 111675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool typedef uint32_t pint_t; 112675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool typedef int32_t sint_t; 113675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 114675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint8_t get8(pint_t addr) { 115675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint8_t val; 116675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool memcpy(&val, (void *)addr, sizeof(val)); 117675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return val; 118675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 119675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint16_t get16(pint_t addr) { 120675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint16_t val; 121675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool memcpy(&val, (void *)addr, sizeof(val)); 122675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return val; 123675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 124675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint32_t get32(pint_t addr) { 125675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint32_t val; 126675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool memcpy(&val, (void *)addr, sizeof(val)); 127675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return val; 128675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 129675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint64_t get64(pint_t addr) { 130675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint64_t val; 131675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool memcpy(&val, (void *)addr, sizeof(val)); 132675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return val; 133675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 134675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool double getDouble(pint_t addr) { 135675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool double val; 136675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool memcpy(&val, (void *)addr, sizeof(val)); 137675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return val; 138675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 139675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool v128 getVector(pint_t addr) { 140675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool v128 val; 141675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool memcpy(&val, (void *)addr, sizeof(val)); 142675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return val; 143675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 144675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t getP(pint_t addr); 145675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool static uint64_t getULEB128(pint_t &addr, pint_t end); 146675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool static int64_t getSLEB128(pint_t &addr, pint_t end); 147675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 148675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding, 149675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t datarelBase = 0); 150675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool bool findFunctionName(pint_t addr, char *buf, size_t bufLen, 151675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool unw_word_t *offset); 152675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info); 153675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool bool findOtherFDE(pint_t targetAddr, pint_t &fde); 154675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 155675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool static LocalAddressSpace sThisAddressSpace; 156675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}; 157675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 158675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolinline uintptr_t LocalAddressSpace::getP(pint_t addr) { 159675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef __LP64__ 160675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return get64(addr); 161675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#else 162675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return get32(addr); 163675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 164675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 165675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 166675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// Read a ULEB128 into a 64-bit word. 167675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolinline uint64_t LocalAddressSpace::getULEB128(pint_t &addr, pint_t end) { 168675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const uint8_t *p = (uint8_t *)addr; 169675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const uint8_t *pend = (uint8_t *)end; 170675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint64_t result = 0; 171675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool int bit = 0; 172675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool do { 173675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint64_t b; 174675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 175675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (p == pend) 176675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_ABORT("truncated uleb128 expression"); 177675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 178675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool b = *p & 0x7f; 179675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 180675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (bit >= 64 || b << bit >> bit != b) { 181675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_ABORT("malformed uleb128 expression"); 182675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } else { 183675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool result |= b << bit; 184675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool bit += 7; 185675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 186675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } while (*p++ >= 0x80); 187675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool addr = (pint_t) p; 188675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return result; 189675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 190675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 191675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// Read a SLEB128 into a 64-bit word. 192675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolinline int64_t LocalAddressSpace::getSLEB128(pint_t &addr, pint_t end) { 193675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const uint8_t *p = (uint8_t *)addr; 194675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const uint8_t *pend = (uint8_t *)end; 195675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool int64_t result = 0; 196675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool int bit = 0; 197675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint8_t byte; 198675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool do { 199675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (p == pend) 200675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_ABORT("truncated sleb128 expression"); 201675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool byte = *p++; 202675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool result |= ((byte & 0x7f) << bit); 203675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool bit += 7; 204675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } while (byte & 0x80); 205675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // sign extend negative numbers 206675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if ((byte & 0x40) != 0) 207675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool result |= (-1LL) << bit; 208675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool addr = (pint_t) p; 209675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return result; 210675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 211675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 212675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolinline LocalAddressSpace::pint_t 213675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem AbdulrasoolLocalAddressSpace::getEncodedP(pint_t &addr, pint_t end, uint8_t encoding, 214675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t datarelBase) { 215675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t startAddr = addr; 216675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const uint8_t *p = (uint8_t *)addr; 217675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t result; 218675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 219675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // first get value 220675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool switch (encoding & 0x0F) { 221675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_EH_PE_ptr: 222675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool result = getP(addr); 223675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += sizeof(pint_t); 224675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool addr = (pint_t) p; 225675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 226675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_EH_PE_uleb128: 227675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool result = (pint_t)getULEB128(addr, end); 228675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 229675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_EH_PE_udata2: 230675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool result = get16(addr); 231675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 2; 232675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool addr = (pint_t) p; 233675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 234675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_EH_PE_udata4: 235675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool result = get32(addr); 236675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 4; 237675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool addr = (pint_t) p; 238675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 239675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_EH_PE_udata8: 240675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool result = (pint_t)get64(addr); 241675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 8; 242675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool addr = (pint_t) p; 243675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 244675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_EH_PE_sleb128: 245675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool result = (pint_t)getSLEB128(addr, end); 246675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 247675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_EH_PE_sdata2: 248675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // Sign extend from signed 16-bit value. 249675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool result = (pint_t)(int16_t)get16(addr); 250675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 2; 251675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool addr = (pint_t) p; 252675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 253675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_EH_PE_sdata4: 254675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // Sign extend from signed 32-bit value. 255675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool result = (pint_t)(int32_t)get32(addr); 256675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 4; 257675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool addr = (pint_t) p; 258675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 259675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_EH_PE_sdata8: 260675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool result = (pint_t)get64(addr); 261675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool p += 8; 262675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool addr = (pint_t) p; 263675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 264675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool default: 265675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_ABORT("unknown pointer encoding"); 266675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 267675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 268675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // then add relative offset 269675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool switch (encoding & 0x70) { 270675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_EH_PE_absptr: 271675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // do nothing 272675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 273675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_EH_PE_pcrel: 274675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool result += startAddr; 275675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 276675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_EH_PE_textrel: 277675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_ABORT("DW_EH_PE_textrel pointer encoding not supported"); 278675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 279675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_EH_PE_datarel: 280675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // DW_EH_PE_datarel is only valid in a few places, so the parameter has a 281675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // default value of 0, and we abort in the event that someone calls this 282675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // function with a datarelBase of 0 and DW_EH_PE_datarel encoding. 283675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (datarelBase == 0) 284675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_ABORT("DW_EH_PE_datarel is invalid with a datarelBase of 0"); 285675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool result += datarelBase; 286675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 287675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_EH_PE_funcrel: 288675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_ABORT("DW_EH_PE_funcrel pointer encoding not supported"); 289675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 290675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool case DW_EH_PE_aligned: 291675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_ABORT("DW_EH_PE_aligned pointer encoding not supported"); 292675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 293675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool default: 294675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_ABORT("unknown pointer encoding"); 295675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool break; 296675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 297675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 298675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (encoding & DW_EH_PE_indirect) 299675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool result = getP(result); 300675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 301675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return result; 302675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 303675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 304675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef __APPLE__ 305675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool struct dyld_unwind_sections 306675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool { 307675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const struct mach_header* mh; 308675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const void* dwarf_section; 309675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t dwarf_section_length; 310675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const void* compact_unwind_section; 311675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t compact_unwind_section_length; 312675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool }; 313675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool #if (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) \ 314675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool && (__MAC_OS_X_VERSION_MIN_REQUIRED >= 1070)) \ 315675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool || defined(__IPHONE_OS_VERSION_MIN_REQUIRED) 316675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // In 10.7.0 or later, libSystem.dylib implements this function. 317675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool extern "C" bool _dyld_find_unwind_sections(void *, dyld_unwind_sections *); 318675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool #else 319675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // In 10.6.x and earlier, we need to implement this functionality. 320675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool static inline bool _dyld_find_unwind_sections(void* addr, 321675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool dyld_unwind_sections* info) { 322675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // Find mach-o image containing address. 323675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool Dl_info dlinfo; 324675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (!dladdr(addr, &dlinfo)) 325675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return false; 326675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const mach_header *mh = (const mach_header *)dlinfo.dli_saddr; 327675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 328675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // Find dwarf unwind section in that image. 329675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool unsigned long size; 330675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool const uint8_t *p = getsectiondata(mh, "__TEXT", "__eh_frame", &size); 331675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (!p) 332675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return false; 333675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 334675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // Fill in return struct. 335675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool info->mh = mh; 336675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool info->dwarf_section = p; 337675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool info->dwarf_section_length = size; 338675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool info->compact_unwind_section = 0; 339675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool info->compact_unwind_section_length = 0; 340675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 341675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return true; 342675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 343675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool #endif 344675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 345675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 346675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolinline bool LocalAddressSpace::findUnwindSections(pint_t targetAddr, 347675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool UnwindInfoSections &info) { 348675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef __APPLE__ 349675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool dyld_unwind_sections dyldInfo; 350675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (_dyld_find_unwind_sections((void *)targetAddr, &dyldInfo)) { 351675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool info.dso_base = (uintptr_t)dyldInfo.mh; 352675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool #if _LIBUNWIND_SUPPORT_DWARF_UNWIND 353675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool info.dwarf_section = (uintptr_t)dyldInfo.dwarf_section; 354675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool info.dwarf_section_length = dyldInfo.dwarf_section_length; 355675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool #endif 356675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool info.compact_unwind_section = (uintptr_t)dyldInfo.compact_unwind_section; 357675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool info.compact_unwind_section_length = dyldInfo.compact_unwind_section_length; 358675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return true; 359675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 36061278584b5c84c422ff5da10f46c3235c54636c9Logan Chien#elif _LIBUNWIND_ARM_EHABI 361675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool #ifdef _LIBUNWIND_IS_BAREMETAL 362675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // Bare metal is statically linked, so no need to ask the dynamic loader 363675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool info.arm_section = (uintptr_t)(&__exidx_start); 364675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool info.arm_section_length = (uintptr_t)(&__exidx_end - &__exidx_start); 365675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool #else 366675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool int length = 0; 367675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool info.arm_section = (uintptr_t) dl_unwind_find_exidx( 368675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool (_Unwind_Ptr) targetAddr, &length); 369675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool info.arm_section_length = (uintptr_t)length; 370675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool #endif 371675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool _LIBUNWIND_TRACE_UNWINDING("findUnwindSections: section %X length %x\n", 372675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool info.arm_section, info.arm_section_length); 373675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (info.arm_section && info.arm_section_length) 374675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return true; 375675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#elif _LIBUNWIND_SUPPORT_DWARF_UNWIND 376675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#if _LIBUNWIND_SUPPORT_DWARF_INDEX 377675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool struct dl_iterate_cb_data { 378675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool LocalAddressSpace *addressSpace; 379675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool UnwindInfoSections *sects; 380675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t targetAddr; 381675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool }; 382675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 383675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool dl_iterate_cb_data cb_data = {this, &info, targetAddr}; 384675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool int found = dl_iterate_phdr( 385675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool [](struct dl_phdr_info *pinfo, size_t, void *data) -> int { 386675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool auto cbdata = static_cast<dl_iterate_cb_data *>(data); 387675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool size_t object_length; 388675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool bool found_obj = false; 389675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool bool found_hdr = false; 390675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 391675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool assert(cbdata); 392675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool assert(cbdata->sects); 393675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 394675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (cbdata->targetAddr < pinfo->dlpi_addr) { 395675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return false; 396675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 397675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 3989ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov#if !defined(Elf_Half) 3999ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov typedef ElfW(Half) Elf_Half; 4009ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov#endif 4019ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov#if !defined(Elf_Phdr) 4029ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov typedef ElfW(Phdr) Elf_Phdr; 4039ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov#endif 4049ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov 4059ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov for (Elf_Half i = 0; i < pinfo->dlpi_phnum; i++) { 4069ed9c3b5e5e94033adf149e7493997e31b9a44ddViktor Kutuzov const Elf_Phdr *phdr = &pinfo->dlpi_phdr[i]; 407675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (phdr->p_type == PT_LOAD) { 408675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t begin = pinfo->dlpi_addr + phdr->p_vaddr; 409675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t end = begin + phdr->p_memsz; 410675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (cbdata->targetAddr >= begin && cbdata->targetAddr < end) { 411675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool cbdata->sects->dso_base = begin; 412675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool object_length = phdr->p_memsz; 413675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool found_obj = true; 414675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 415675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } else if (phdr->p_type == PT_GNU_EH_FRAME) { 416675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool EHHeaderParser<LocalAddressSpace>::EHHeaderInfo hdrInfo; 417675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t eh_frame_hdr_start = pinfo->dlpi_addr + phdr->p_vaddr; 418675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool cbdata->sects->dwarf_index_section = eh_frame_hdr_start; 419675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool cbdata->sects->dwarf_index_section_length = phdr->p_memsz; 420675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool EHHeaderParser<LocalAddressSpace>::decodeEHHdr( 421675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *cbdata->addressSpace, eh_frame_hdr_start, phdr->p_memsz, 422675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool hdrInfo); 423675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool cbdata->sects->dwarf_section = hdrInfo.eh_frame_ptr; 424675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool found_hdr = true; 425675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 426675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 427675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 428675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (found_obj && found_hdr) { 429675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool cbdata->sects->dwarf_section_length = object_length; 430675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return true; 431675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } else { 432675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return false; 433675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 434675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool }, 435675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool &cb_data); 436675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return static_cast<bool>(found); 437675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#else 438675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#error "_LIBUNWIND_SUPPORT_DWARF_UNWIND requires _LIBUNWIND_SUPPORT_DWARF_INDEX on this platform." 439675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 440675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 441675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 442675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return false; 443675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 444675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 445675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 446675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolinline bool LocalAddressSpace::findOtherFDE(pint_t targetAddr, pint_t &fde) { 447675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef __APPLE__ 448675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return checkKeyMgrRegisteredFDEs(targetAddr, *((void**)&fde)); 449675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#else 450675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // TO DO: if OS has way to dynamically register FDEs, check that. 451675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool (void)targetAddr; 452675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool (void)fde; 453675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return false; 454675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 455675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 456675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 457675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolinline bool LocalAddressSpace::findFunctionName(pint_t addr, char *buf, 458675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool size_t bufLen, 459675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool unw_word_t *offset) { 460675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifndef _LIBUNWIND_IS_BAREMETAL 461675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool Dl_info dyldInfo; 462675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (dladdr((void *)addr, &dyldInfo)) { 463675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool if (dyldInfo.dli_sname != NULL) { 464675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool snprintf(buf, bufLen, "%s", dyldInfo.dli_sname); 465675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool *offset = (addr - (pint_t) dyldInfo.dli_saddr); 466675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return true; 467675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 468675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool } 469675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif 470675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return false; 471675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 472675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 473675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 474675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 475675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#ifdef UNW_REMOTE 476675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 477675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// OtherAddressSpace is used as a template parameter to UnwindCursor when 478675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// unwinding a thread in the another process. The other process can be a 479675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// different endianness and a different pointer size which is handled by 480675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// the P template parameter. 481675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P> 482675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolclass OtherAddressSpace { 483675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolpublic: 484675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool OtherAddressSpace(task_t task) : fTask(task) {} 485675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 486675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool typedef typename P::uint_t pint_t; 487675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 488675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint8_t get8(pint_t addr); 489675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint16_t get16(pint_t addr); 490675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint32_t get32(pint_t addr); 491675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint64_t get64(pint_t addr); 492675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t getP(pint_t addr); 493675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint64_t getULEB128(pint_t &addr, pint_t end); 494675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool int64_t getSLEB128(pint_t &addr, pint_t end); 495675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t getEncodedP(pint_t &addr, pint_t end, uint8_t encoding, 496675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool pint_t datarelBase = 0); 497675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool bool findFunctionName(pint_t addr, char *buf, size_t bufLen, 498675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool unw_word_t *offset); 499675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool bool findUnwindSections(pint_t targetAddr, UnwindInfoSections &info); 500675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool bool findOtherFDE(pint_t targetAddr, pint_t &fde); 501675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolprivate: 502675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool void *localCopy(pint_t addr); 503675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 504675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool task_t fTask; 505675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}; 506675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 507675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P> uint8_t OtherAddressSpace<P>::get8(pint_t addr) { 508675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return *((uint8_t *)localCopy(addr)); 509675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 510675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 511675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P> uint16_t OtherAddressSpace<P>::get16(pint_t addr) { 512675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return P::E::get16(*(uint16_t *)localCopy(addr)); 513675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 514675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 515675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P> uint32_t OtherAddressSpace<P>::get32(pint_t addr) { 516675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return P::E::get32(*(uint32_t *)localCopy(addr)); 517675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 518675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 519675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P> uint64_t OtherAddressSpace<P>::get64(pint_t addr) { 520675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return P::E::get64(*(uint64_t *)localCopy(addr)); 521675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 522675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 523675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P> 524675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltypename P::uint_t OtherAddressSpace<P>::getP(pint_t addr) { 525675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return P::getP(*(uint64_t *)localCopy(addr)); 526675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 527675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 528675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P> 529675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooluint64_t OtherAddressSpace<P>::getULEB128(pint_t &addr, pint_t end) { 530675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t size = (end - addr); 531675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); 532675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool LocalAddressSpace::pint_t sladdr = laddr; 533675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint64_t result = LocalAddressSpace::getULEB128(laddr, laddr + size); 534675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool addr += (laddr - sladdr); 535675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return result; 536675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 537675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 538675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P> 539675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolint64_t OtherAddressSpace<P>::getSLEB128(pint_t &addr, pint_t end) { 540675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uintptr_t size = (end - addr); 541675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool LocalAddressSpace::pint_t laddr = (LocalAddressSpace::pint_t) localCopy(addr); 542675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool LocalAddressSpace::pint_t sladdr = laddr; 543675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool uint64_t result = LocalAddressSpace::getSLEB128(laddr, laddr + size); 544675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool addr += (laddr - sladdr); 545675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool return result; 546675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 547675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 548675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P> void *OtherAddressSpace<P>::localCopy(pint_t addr) { 549675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // FIX ME 550675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 551675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 552675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasooltemplate <typename P> 553675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolbool OtherAddressSpace<P>::findFunctionName(pint_t addr, char *buf, 554675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool size_t bufLen, unw_word_t *offset) { 555675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool // FIX ME 556675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} 557675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 558675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// unw_addr_space is the base class that abstract unw_addr_space_t type in 559675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// libunwind.h points to. 560675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolstruct unw_addr_space { 561675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool cpu_type_t cpuType; 562675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool task_t taskPort; 563675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}; 564675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 565675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// unw_addr_space_i386 is the concrete instance that a unw_addr_space_t points 566675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// to when examining 567675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// a 32-bit intel process. 568675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolstruct unw_addr_space_i386 : public unw_addr_space { 569675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool unw_addr_space_i386(task_t task) : oas(task) {} 570675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool OtherAddressSpace<Pointer32<LittleEndian> > oas; 571675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}; 572675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 573675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// unw_addr_space_x86_64 is the concrete instance that a unw_addr_space_t 574675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// points to when examining 575675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// a 64-bit intel process. 576675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolstruct unw_addr_space_x86_64 : public unw_addr_space { 577675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool unw_addr_space_x86_64(task_t task) : oas(task) {} 578675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool OtherAddressSpace<Pointer64<LittleEndian> > oas; 579675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}; 580675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 581675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// unw_addr_space_ppc is the concrete instance that a unw_addr_space_t points 582675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// to when examining 583675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool/// a 32-bit PowerPC process. 584675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasoolstruct unw_addr_space_ppc : public unw_addr_space { 585675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool unw_addr_space_ppc(task_t task) : oas(task) {} 586675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool OtherAddressSpace<Pointer32<BigEndian> > oas; 587675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool}; 588675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 589675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif // UNW_REMOTE 590675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 591675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool} // namespace libunwind 592675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool 593675df58e9b2f6c4218ef7d19bfe405772ada5444Saleem Abdulrasool#endif // __ADDRESSSPACE_HPP__ 594