1*0faf1914Srobert //===----------------------------------------------------------------------===// 2f6c50668Spatrick // 3f6c50668Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4f6c50668Spatrick // See https://llvm.org/LICENSE.txt for license information. 5f6c50668Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6f6c50668Spatrick // 7f6c50668Spatrick // 8f6c50668Spatrick // C++ ABI Level 1 ABI documented at: 9f6c50668Spatrick // https://itanium-cxx-abi.github.io/cxx-abi/abi-eh.html 10f6c50668Spatrick // 11f6c50668Spatrick //===----------------------------------------------------------------------===// 12f6c50668Spatrick 13f6c50668Spatrick #ifndef __UNWIND_H__ 14f6c50668Spatrick #define __UNWIND_H__ 15f6c50668Spatrick 16f6c50668Spatrick #include <__libunwind_config.h> 17f6c50668Spatrick 18f6c50668Spatrick #include <stdint.h> 19f6c50668Spatrick #include <stddef.h> 20f6c50668Spatrick 21f6c50668Spatrick #if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) && defined(_WIN32) 22f6c50668Spatrick #include <windows.h> 23f6c50668Spatrick #include <ntverp.h> 24f6c50668Spatrick #endif 25f6c50668Spatrick 26f6c50668Spatrick #if defined(__APPLE__) 27f6c50668Spatrick #define LIBUNWIND_UNAVAIL __attribute__ (( unavailable )) 28f6c50668Spatrick #else 29f6c50668Spatrick #define LIBUNWIND_UNAVAIL 30f6c50668Spatrick #endif 31f6c50668Spatrick 32f6c50668Spatrick typedef enum { 33f6c50668Spatrick _URC_NO_REASON = 0, 34f6c50668Spatrick _URC_OK = 0, 35f6c50668Spatrick _URC_FOREIGN_EXCEPTION_CAUGHT = 1, 36f6c50668Spatrick _URC_FATAL_PHASE2_ERROR = 2, 37f6c50668Spatrick _URC_FATAL_PHASE1_ERROR = 3, 38f6c50668Spatrick _URC_NORMAL_STOP = 4, 39f6c50668Spatrick _URC_END_OF_STACK = 5, 40f6c50668Spatrick _URC_HANDLER_FOUND = 6, 41f6c50668Spatrick _URC_INSTALL_CONTEXT = 7, 42f6c50668Spatrick _URC_CONTINUE_UNWIND = 8, 43f6c50668Spatrick #if defined(_LIBUNWIND_ARM_EHABI) 44f6c50668Spatrick _URC_FAILURE = 9 45f6c50668Spatrick #endif 46f6c50668Spatrick } _Unwind_Reason_Code; 47f6c50668Spatrick 48f6c50668Spatrick typedef enum { 49f6c50668Spatrick _UA_SEARCH_PHASE = 1, 50f6c50668Spatrick _UA_CLEANUP_PHASE = 2, 51f6c50668Spatrick _UA_HANDLER_FRAME = 4, 52f6c50668Spatrick _UA_FORCE_UNWIND = 8, 53f6c50668Spatrick _UA_END_OF_STACK = 16 // gcc extension to C++ ABI 54f6c50668Spatrick } _Unwind_Action; 55f6c50668Spatrick 56f6c50668Spatrick typedef struct _Unwind_Context _Unwind_Context; // opaque 57f6c50668Spatrick 58f6c50668Spatrick #if defined(_LIBUNWIND_ARM_EHABI) 59*0faf1914Srobert #include <unwind_arm_ehabi.h> 60f6c50668Spatrick #else 61*0faf1914Srobert #include <unwind_itanium.h> 62f6c50668Spatrick #endif 63f6c50668Spatrick 64f6c50668Spatrick typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) 65f6c50668Spatrick (int version, 66f6c50668Spatrick _Unwind_Action actions, 67*0faf1914Srobert _Unwind_Exception_Class exceptionClass, 68f6c50668Spatrick _Unwind_Exception* exceptionObject, 69f6c50668Spatrick struct _Unwind_Context* context, 70f6c50668Spatrick void* stop_parameter); 71f6c50668Spatrick 72f6c50668Spatrick #ifdef __cplusplus 73f6c50668Spatrick extern "C" { 74f6c50668Spatrick #endif 75f6c50668Spatrick 76f6c50668Spatrick extern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context); 77f6c50668Spatrick extern uintptr_t 78f6c50668Spatrick _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context); 79f6c50668Spatrick #ifdef __USING_SJLJ_EXCEPTIONS__ 80f6c50668Spatrick extern _Unwind_Reason_Code 81f6c50668Spatrick _Unwind_SjLj_ForcedUnwind(_Unwind_Exception *exception_object, 82f6c50668Spatrick _Unwind_Stop_Fn stop, void *stop_parameter); 83f6c50668Spatrick #else 84f6c50668Spatrick extern _Unwind_Reason_Code 85f6c50668Spatrick _Unwind_ForcedUnwind(_Unwind_Exception *exception_object, 86f6c50668Spatrick _Unwind_Stop_Fn stop, void *stop_parameter); 87f6c50668Spatrick #endif 88f6c50668Spatrick 89f6c50668Spatrick #ifdef __USING_SJLJ_EXCEPTIONS__ 90f6c50668Spatrick typedef struct _Unwind_FunctionContext *_Unwind_FunctionContext_t; 91f6c50668Spatrick extern void _Unwind_SjLj_Register(_Unwind_FunctionContext_t fc); 92f6c50668Spatrick extern void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t fc); 93f6c50668Spatrick #endif 94f6c50668Spatrick 95f6c50668Spatrick // 96*0faf1914Srobert // The following are semi-supported extensions to the C++ ABI 97f6c50668Spatrick // 98f6c50668Spatrick 99f6c50668Spatrick // 100f6c50668Spatrick // called by __cxa_rethrow(). 101f6c50668Spatrick // 102f6c50668Spatrick #ifdef __USING_SJLJ_EXCEPTIONS__ 103f6c50668Spatrick extern _Unwind_Reason_Code 104f6c50668Spatrick _Unwind_SjLj_Resume_or_Rethrow(_Unwind_Exception *exception_object); 105f6c50668Spatrick #else 106f6c50668Spatrick extern _Unwind_Reason_Code 107f6c50668Spatrick _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object); 108f6c50668Spatrick #endif 109f6c50668Spatrick 110f6c50668Spatrick // _Unwind_Backtrace() is a gcc extension that walks the stack and calls the 111f6c50668Spatrick // _Unwind_Trace_Fn once per frame until it reaches the bottom of the stack 112f6c50668Spatrick // or the _Unwind_Trace_Fn function returns something other than _URC_NO_REASON. 113f6c50668Spatrick typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *, 114f6c50668Spatrick void *); 115f6c50668Spatrick extern _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void *); 116f6c50668Spatrick 117f6c50668Spatrick // _Unwind_GetCFA is a gcc extension that can be called from within a 118f6c50668Spatrick // personality handler to get the CFA (stack pointer before call) of 119f6c50668Spatrick // current frame. 120f6c50668Spatrick extern uintptr_t _Unwind_GetCFA(struct _Unwind_Context *); 121f6c50668Spatrick 122f6c50668Spatrick 123f6c50668Spatrick // _Unwind_GetIPInfo is a gcc extension that can be called from within a 124f6c50668Spatrick // personality handler. Similar to _Unwind_GetIP() but also returns in 125f6c50668Spatrick // *ipBefore a non-zero value if the instruction pointer is at or before the 126f6c50668Spatrick // instruction causing the unwind. Normally, in a function call, the IP returned 127f6c50668Spatrick // is the return address which is after the call instruction and may be past the 128f6c50668Spatrick // end of the function containing the call instruction. 129f6c50668Spatrick extern uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, 130f6c50668Spatrick int *ipBefore); 131f6c50668Spatrick 132f6c50668Spatrick 133f6c50668Spatrick // __register_frame() is used with dynamically generated code to register the 134f6c50668Spatrick // FDE for a generated (JIT) code. The FDE must use pc-rel addressing to point 135f6c50668Spatrick // to its function and optional LSDA. 136f6c50668Spatrick // __register_frame() has existed in all versions of Mac OS X, but in 10.4 and 137f6c50668Spatrick // 10.5 it was buggy and did not actually register the FDE with the unwinder. 138f6c50668Spatrick // In 10.6 and later it does register properly. 139f6c50668Spatrick extern void __register_frame(const void *fde); 140f6c50668Spatrick extern void __deregister_frame(const void *fde); 141f6c50668Spatrick 142f6c50668Spatrick // _Unwind_Find_FDE() will locate the FDE if the pc is in some function that has 143f6c50668Spatrick // an associated FDE. Note, Mac OS X 10.6 and later, introduces "compact unwind 144f6c50668Spatrick // info" which the runtime uses in preference to DWARF unwind info. This 145f6c50668Spatrick // function will only work if the target function has an FDE but no compact 146f6c50668Spatrick // unwind info. 147f6c50668Spatrick struct dwarf_eh_bases { 148f6c50668Spatrick uintptr_t tbase; 149f6c50668Spatrick uintptr_t dbase; 150f6c50668Spatrick uintptr_t func; 151f6c50668Spatrick }; 152f6c50668Spatrick extern const void *_Unwind_Find_FDE(const void *pc, struct dwarf_eh_bases *); 153f6c50668Spatrick 154f6c50668Spatrick 155f6c50668Spatrick // This function attempts to find the start (address of first instruction) of 156f6c50668Spatrick // a function given an address inside the function. It only works if the 157f6c50668Spatrick // function has an FDE (DWARF unwind info). 158f6c50668Spatrick // This function is unimplemented on Mac OS X 10.6 and later. Instead, use 159f6c50668Spatrick // _Unwind_Find_FDE() and look at the dwarf_eh_bases.func result. 160f6c50668Spatrick extern void *_Unwind_FindEnclosingFunction(void *pc); 161f6c50668Spatrick 162f6c50668Spatrick // Mac OS X does not support text-rel and data-rel addressing so these functions 163*0faf1914Srobert // are unimplemented. 164f6c50668Spatrick extern uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *context) 165f6c50668Spatrick LIBUNWIND_UNAVAIL; 166f6c50668Spatrick extern uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context *context) 167f6c50668Spatrick LIBUNWIND_UNAVAIL; 168f6c50668Spatrick 169f6c50668Spatrick // Mac OS X 10.4 and 10.5 had implementations of these functions in 170f6c50668Spatrick // libgcc_s.dylib, but they never worked. 171f6c50668Spatrick /// These functions are no longer available on Mac OS X. 172f6c50668Spatrick extern void __register_frame_info_bases(const void *fde, void *ob, void *tb, 173f6c50668Spatrick void *db) LIBUNWIND_UNAVAIL; 174f6c50668Spatrick extern void __register_frame_info(const void *fde, void *ob) 175f6c50668Spatrick LIBUNWIND_UNAVAIL; 176f6c50668Spatrick extern void __register_frame_info_table_bases(const void *fde, void *ob, 177f6c50668Spatrick void *tb, void *db) 178f6c50668Spatrick LIBUNWIND_UNAVAIL; 179f6c50668Spatrick extern void __register_frame_info_table(const void *fde, void *ob) 180f6c50668Spatrick LIBUNWIND_UNAVAIL; 181f6c50668Spatrick extern void __register_frame_table(const void *fde) 182f6c50668Spatrick LIBUNWIND_UNAVAIL; 183f6c50668Spatrick extern void *__deregister_frame_info(const void *fde) 184f6c50668Spatrick LIBUNWIND_UNAVAIL; 185f6c50668Spatrick extern void *__deregister_frame_info_bases(const void *fde) 186f6c50668Spatrick LIBUNWIND_UNAVAIL; 187f6c50668Spatrick 188f6c50668Spatrick #if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) 189f6c50668Spatrick #ifndef _WIN32 190f6c50668Spatrick typedef struct _EXCEPTION_RECORD EXCEPTION_RECORD; 191f6c50668Spatrick typedef struct _CONTEXT CONTEXT; 192f6c50668Spatrick typedef struct _DISPATCHER_CONTEXT DISPATCHER_CONTEXT; 193f6c50668Spatrick #elif !defined(__MINGW32__) && VER_PRODUCTBUILD < 8000 194f6c50668Spatrick typedef struct _DISPATCHER_CONTEXT DISPATCHER_CONTEXT; 195f6c50668Spatrick #endif 196f6c50668Spatrick // This is the common wrapper for GCC-style personality functions with SEH. 197f6c50668Spatrick extern EXCEPTION_DISPOSITION _GCC_specific_handler(EXCEPTION_RECORD *exc, 198f6c50668Spatrick void *frame, CONTEXT *ctx, 199f6c50668Spatrick DISPATCHER_CONTEXT *disp, 200f6c50668Spatrick _Unwind_Personality_Fn pers); 201f6c50668Spatrick #endif 202f6c50668Spatrick 203f6c50668Spatrick #ifdef __cplusplus 204f6c50668Spatrick } 205f6c50668Spatrick #endif 206f6c50668Spatrick 207f6c50668Spatrick #endif // __UNWIND_H__ 208