1b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//===------------------------------- unwind.h -----------------------------===// 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// C++ ABI Level 1 ABI documented at: 10b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// http://mentorembedded.github.io/cxx-abi/abi-eh.html 11b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// 12b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik//===----------------------------------------------------------------------===// 13b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 14b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#ifndef __UNWIND_H__ 15b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#define __UNWIND_H__ 16b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 17b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stdint.h> 18b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#include <stddef.h> 19b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 20839f7f23c0a652e2b799345fc3112ae0c5a03098Saleem Abdulrasool#if defined(__APPLE__) 2129180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik#define LIBUNWIND_UNAVAIL __attribute__ (( unavailable )) 22839f7f23c0a652e2b799345fc3112ae0c5a03098Saleem Abdulrasool#else 2329180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik#define LIBUNWIND_UNAVAIL 24839f7f23c0a652e2b799345fc3112ae0c5a03098Saleem Abdulrasool#endif 25839f7f23c0a652e2b799345fc3112ae0c5a03098Saleem Abdulrasool 26e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert// FIXME: This is also in cxxabi.h and libunwind.h, can we consolidate? 27e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if !defined(__USING_SJLJ_EXCEPTIONS__) && defined(__arm__) && \ 28e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert !defined(__ARM_DWARF_EH__) && !defined(__APPLE__) 29e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#define LIBCXXABI_ARM_EHABI 1 30e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#else 31e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#define LIBCXXABI_ARM_EHABI 0 32e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 33e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 34b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypedef enum { 35b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _URC_NO_REASON = 0, 36e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _URC_OK = 0, 37b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _URC_FOREIGN_EXCEPTION_CAUGHT = 1, 38b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _URC_FATAL_PHASE2_ERROR = 2, 39b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _URC_FATAL_PHASE1_ERROR = 3, 40b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _URC_NORMAL_STOP = 4, 41b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _URC_END_OF_STACK = 5, 42b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _URC_HANDLER_FOUND = 6, 43b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _URC_INSTALL_CONTEXT = 7, 44e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _URC_CONTINUE_UNWIND = 8, 45e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_ARM_EHABI 46e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _URC_FAILURE = 9 47e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 48b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} _Unwind_Reason_Code; 49b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 50b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypedef enum { 51b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _UA_SEARCH_PHASE = 1, 52b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _UA_CLEANUP_PHASE = 2, 53b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _UA_HANDLER_FRAME = 4, 54b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _UA_FORCE_UNWIND = 8, 55b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _UA_END_OF_STACK = 16 // gcc extension to C++ ABI 56b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} _Unwind_Action; 57b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 58e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef struct _Unwind_Context _Unwind_Context; // opaque 59e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 60e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_ARM_EHABI 61e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef uint32_t _Unwind_State; 62e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 63e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstatic const _Unwind_State _US_VIRTUAL_UNWIND_FRAME = 0; 64e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstatic const _Unwind_State _US_UNWIND_FRAME_STARTING = 1; 65e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstatic const _Unwind_State _US_UNWIND_FRAME_RESUME = 2; 66e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 67e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef uint32_t _Unwind_EHT_Header; 68e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 69e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstruct _Unwind_Control_Block; 70e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef struct _Unwind_Control_Block _Unwind_Control_Block; 71e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef struct _Unwind_Control_Block _Unwind_Exception; /* Alias */ 72e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 73e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstruct _Unwind_Control_Block { 74e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint64_t exception_class; 75e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block*); 76e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 77e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert /* Unwinder cache, private fields for the unwinder's use */ 78e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert struct { 79e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t reserved1; /* init reserved1 to 0, then don't touch */ 80e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t reserved2; 81e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t reserved3; 82e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t reserved4; 83e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t reserved5; 84e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } unwinder_cache; 85e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 86e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert /* Propagation barrier cache (valid after phase 1): */ 87e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert struct { 88e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t sp; 89e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t bitpattern[5]; 90e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } barrier_cache; 91e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 92e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert /* Cleanup cache (preserved over cleanup): */ 93e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert struct { 94e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t bitpattern[4]; 95e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } cleanup_cache; 96e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 97e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert /* Pr cache (for pr's benefit): */ 98e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert struct { 99e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t fnstart; /* function start address */ 100e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_EHT_Header* ehtp; /* pointer to EHT entry header word */ 101e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t additional; 102e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t reserved1; 103e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert } pr_cache; 104e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 105e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert long long int :0; /* Enforce the 8-byte alignment */ 106e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert}; 107e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 108e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) 109e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert (_Unwind_State state, 110e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_Exception* exceptionObject, 111e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert struct _Unwind_Context* context); 112e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 113e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef _Unwind_Reason_Code (*__personality_routine) 114e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert (_Unwind_State state, 115e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_Exception* exceptionObject, 116e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert struct _Unwind_Context* context); 117e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#else 118b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct _Unwind_Context; // opaque 119b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct _Unwind_Exception; // forward declaration 120e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef struct _Unwind_Exception _Unwind_Exception; 121b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 122b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct _Unwind_Exception { 123b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint64_t exception_class; 124b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik void (*exception_cleanup)(_Unwind_Reason_Code reason, 125e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_Exception *exc); 126b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uintptr_t private_1; // non-zero means forced unwind 127b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uintptr_t private_2; // holds sp that phase1 found for phase2 to use 128b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#if !__LP64__ 129b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // The gcc implementation of _Unwind_Exception used attribute mode on the 130b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // above fields which had the side effect of causing this whole struct to 131b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // round up to 32 bytes in size. To be more explicit, we add pad fields 132b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik // added for binary compatibility. 133b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint32_t reserved[3]; 134b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 135b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 136b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 137b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) 138b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (int version, 139b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _Unwind_Action actions, 140b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint64_t exceptionClass, 141e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_Exception* exceptionObject, 142b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik struct _Unwind_Context* context, 143b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik void* stop_parameter ); 144b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 145b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypedef _Unwind_Reason_Code (*__personality_routine) 146b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik (int version, 147b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _Unwind_Action actions, 148b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uint64_t exceptionClass, 149e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_Exception* exceptionObject, 150b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik struct _Unwind_Context* context); 151e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 152b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 153b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#ifdef __cplusplus 154b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern "C" { 155b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 156b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 157b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// 158b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// The following are the base functions documented by the C++ ABI 159b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// 160c2e9313c38fdd56ecd50d7cd21e8a14d8f16a1b7Dan Albert#if __USING_SJLJ_EXCEPTIONS__ 161b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern _Unwind_Reason_Code 162e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_SjLj_RaiseException(_Unwind_Exception *exception_object); 163e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern void _Unwind_SjLj_Resume(_Unwind_Exception *exception_object); 164b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#else 165b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern _Unwind_Reason_Code 166e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_RaiseException(_Unwind_Exception *exception_object); 167e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern void _Unwind_Resume(_Unwind_Exception *exception_object); 168b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 169e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern void _Unwind_DeleteException(_Unwind_Exception *exception_object); 170e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 171e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if LIBCXXABI_ARM_EHABI 172e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef enum { 173e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _UVRSC_CORE = 0, /* integer register */ 174e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _UVRSC_VFP = 1, /* vfp */ 175e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _UVRSC_WMMXD = 3, /* Intel WMMX data register */ 176e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _UVRSC_WMMXC = 4 /* Intel WMMX control register */ 177e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert} _Unwind_VRS_RegClass; 178e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 179e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef enum { 180e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _UVRSD_UINT32 = 0, 181e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _UVRSD_VFPX = 1, 182e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _UVRSD_UINT64 = 3, 183e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _UVRSD_FLOAT = 4, 184e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _UVRSD_DOUBLE = 5 185e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert} _Unwind_VRS_DataRepresentation; 186e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 187e45805f0d3f8dafef1297cc7dc49e610713f023bDan Alberttypedef enum { 188e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _UVRSR_OK = 0, 189e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _UVRSR_NOT_IMPLEMENTED = 1, 190e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _UVRSR_FAILED = 2 191e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert} _Unwind_VRS_Result; 192e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 193e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern void _Unwind_Complete(_Unwind_Exception* exception_object); 194e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 195e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern _Unwind_VRS_Result 196e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert_Unwind_VRS_Get(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, 197e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t regno, _Unwind_VRS_DataRepresentation representation, 198e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert void *valuep); 199e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 200e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern _Unwind_VRS_Result 201e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert_Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, 202e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t regno, _Unwind_VRS_DataRepresentation representation, 203e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert void *valuep); 204e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 205e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertextern _Unwind_VRS_Result 206e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert_Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, 207e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uint32_t discriminator, 208e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_VRS_DataRepresentation representation); 209e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 210e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstatic inline uintptr_t _Unwind_GetGR(struct _Unwind_Context* context, 211e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert int index) { 212e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uintptr_t value = 0; 213e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_VRS_Get(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value); 214e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return value; 215e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert} 216e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 217e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstatic inline void _Unwind_SetGR(struct _Unwind_Context* context, int index, 218e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uintptr_t new_value) { 219e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index, 220e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _UVRSD_UINT32, &new_value); 221e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert} 222e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 223e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstatic inline uintptr_t _Unwind_GetIP(struct _Unwind_Context* context) { 224e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert // remove the thumb-bit before returning 225e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert return (_Unwind_GetGR(context, 15) & (~(uintptr_t)0x1)); 226e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert} 227e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 228e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albertstatic inline void _Unwind_SetIP(struct _Unwind_Context* context, 229e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uintptr_t new_value) { 230e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1); 231e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_SetGR(context, 15, new_value | thumb_bit); 232e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert} 233e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#else 234b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index); 235b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void _Unwind_SetGR(struct _Unwind_Context *context, int index, 236b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uintptr_t new_value); 237b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context); 238b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t new_value); 239e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#endif 240e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert 241b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context); 242b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t 243b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context); 244e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if __USING_SJLJ_EXCEPTIONS__ 245b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern _Unwind_Reason_Code 246e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_SjLj_ForcedUnwind(_Unwind_Exception *exception_object, 247b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _Unwind_Stop_Fn stop, void *stop_parameter); 248b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#else 249b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern _Unwind_Reason_Code 250e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_ForcedUnwind(_Unwind_Exception *exception_object, 251b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik _Unwind_Stop_Fn stop, void *stop_parameter); 252b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 253b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 254e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if __USING_SJLJ_EXCEPTIONS__ 255b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypedef struct _Unwind_FunctionContext *_Unwind_FunctionContext_t; 256b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void _Unwind_SjLj_Register(_Unwind_FunctionContext_t fc); 257b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t fc); 258b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 259b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 260b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// 261b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// The following are semi-suppoted extensions to the C++ ABI 262b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// 263b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 264b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// 265b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// called by __cxa_rethrow(). 266b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// 267e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert#if __USING_SJLJ_EXCEPTIONS__ 268b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern _Unwind_Reason_Code 269e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_SjLj_Resume_or_Rethrow(_Unwind_Exception *exception_object); 270b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#else 271b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern _Unwind_Reason_Code 272e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object); 273b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 274b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 275b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// _Unwind_Backtrace() is a gcc extension that walks the stack and calls the 276b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// _Unwind_Trace_Fn once per frame until it reaches the bottom of the stack 277b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// or the _Unwind_Trace_Fn function returns something other than _URC_NO_REASON. 278b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledziktypedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *, 279b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik void *); 280b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void *); 281b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 282b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// _Unwind_GetCFA is a gcc extension that can be called from within a 283b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// personality handler to get the CFA (stack pointer before call) of 284b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// current frame. 285b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t _Unwind_GetCFA(struct _Unwind_Context *); 286b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 287b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 288b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// _Unwind_GetIPInfo is a gcc extension that can be called from within a 289e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert// personality handler. Similar to _Unwind_GetIP() but also returns in 290e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert// *ipBefore a non-zero value if the instruction pointer is at or before the 291e45805f0d3f8dafef1297cc7dc49e610713f023bDan Albert// instruction causing the unwind. Normally, in a function call, the IP returned 292b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// is the return address which is after the call instruction and may be past the 293b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// end of the function containing the call instruction. 294b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, 295b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik int *ipBefore); 296b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 297b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 298b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// __register_frame() is used with dynamically generated code to register the 299b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// FDE for a generated (JIT) code. The FDE must use pc-rel addressing to point 300b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// to its function and optional LSDA. 301b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// __register_frame() has existed in all versions of Mac OS X, but in 10.4 and 302b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// 10.5 it was buggy and did not actually register the FDE with the unwinder. 303b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// In 10.6 and later it does register properly. 304b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void __register_frame(const void *fde); 305b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void __deregister_frame(const void *fde); 306b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 307b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// _Unwind_Find_FDE() will locate the FDE if the pc is in some function that has 308b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// an associated FDE. Note, Mac OS X 10.6 and later, introduces "compact unwind 309b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// info" which the runtime uses in preference to dwarf unwind info. This 310b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// function will only work if the target function has an FDE but no compact 311b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// unwind info. 312b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikstruct dwarf_eh_bases { 313b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uintptr_t tbase; 314b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uintptr_t dbase; 315b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik uintptr_t func; 316b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik}; 317b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern const void *_Unwind_Find_FDE(const void *pc, struct dwarf_eh_bases *); 318b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 319b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 320b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// This function attempts to find the start (address of first instruction) of 321b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// a function given an address inside the function. It only works if the 322b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// function has an FDE (dwarf unwind info). 323b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// This function is unimplemented on Mac OS X 10.6 and later. Instead, use 324b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// _Unwind_Find_FDE() and look at the dwarf_eh_bases.func result. 325b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void *_Unwind_FindEnclosingFunction(void *pc); 326b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 327b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// Mac OS X does not support text-rel and data-rel addressing so these functions 328b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// are unimplemented 329b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *context) 33029180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik LIBUNWIND_UNAVAIL; 331b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context *context) 33229180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik LIBUNWIND_UNAVAIL; 333b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 334b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// Mac OS X 10.4 and 10.5 had implementations of these functions in 335b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik// libgcc_s.dylib, but they never worked. 336b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik/// These functions are no longer available on Mac OS X. 337b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void __register_frame_info_bases(const void *fde, void *ob, void *tb, 33829180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik void *db) LIBUNWIND_UNAVAIL; 339b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void __register_frame_info(const void *fde, void *ob) 34029180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik LIBUNWIND_UNAVAIL; 341b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void __register_frame_info_table_bases(const void *fde, void *ob, 342b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik void *tb, void *db) 34329180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik LIBUNWIND_UNAVAIL; 344b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void __register_frame_info_table(const void *fde, void *ob) 34529180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik LIBUNWIND_UNAVAIL; 346b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void __register_frame_table(const void *fde) 34729180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik LIBUNWIND_UNAVAIL; 348b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void *__deregister_frame_info(const void *fde) 34929180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik LIBUNWIND_UNAVAIL; 350b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzikextern void *__deregister_frame_info_bases(const void *fde) 35129180116e559ead2486c5cf6b4fefe8a6f6443fcNick Kledzik LIBUNWIND_UNAVAIL; 352b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 353b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#ifdef __cplusplus 354b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik} 355b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif 356b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik 357b78da9875b6e35187b5d584746c78faaf3230a3dNick Kledzik#endif // __UNWIND_H__ 358