unwind.h revision 29180116e559ead2486c5cf6b4fefe8a6f6443fc
1//===------------------------------- unwind.h -----------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is dual licensed under the MIT and the University of Illinois Open 6// Source Licenses. See LICENSE.TXT for details. 7// 8// 9// C++ ABI Level 1 ABI documented at: 10// http://mentorembedded.github.io/cxx-abi/abi-eh.html 11// 12//===----------------------------------------------------------------------===// 13 14#ifndef __UNWIND_H__ 15#define __UNWIND_H__ 16 17#include <stdint.h> 18#include <stddef.h> 19 20#if defined(__APPLE__) 21#define LIBUNWIND_UNAVAIL __attribute__ (( unavailable )) 22#else 23#define LIBUNWIND_UNAVAIL 24#endif 25 26typedef enum { 27 _URC_NO_REASON = 0, 28 _URC_FOREIGN_EXCEPTION_CAUGHT = 1, 29 _URC_FATAL_PHASE2_ERROR = 2, 30 _URC_FATAL_PHASE1_ERROR = 3, 31 _URC_NORMAL_STOP = 4, 32 _URC_END_OF_STACK = 5, 33 _URC_HANDLER_FOUND = 6, 34 _URC_INSTALL_CONTEXT = 7, 35 _URC_CONTINUE_UNWIND = 8 36} _Unwind_Reason_Code; 37 38typedef enum { 39 _UA_SEARCH_PHASE = 1, 40 _UA_CLEANUP_PHASE = 2, 41 _UA_HANDLER_FRAME = 4, 42 _UA_FORCE_UNWIND = 8, 43 _UA_END_OF_STACK = 16 // gcc extension to C++ ABI 44} _Unwind_Action; 45 46struct _Unwind_Context; // opaque 47struct _Unwind_Exception; // forward declaration 48 49struct _Unwind_Exception { 50 uint64_t exception_class; 51 void (*exception_cleanup)(_Unwind_Reason_Code reason, 52 struct _Unwind_Exception *exc); 53 uintptr_t private_1; // non-zero means forced unwind 54 uintptr_t private_2; // holds sp that phase1 found for phase2 to use 55#if !__LP64__ 56 // The gcc implementation of _Unwind_Exception used attribute mode on the 57 // above fields which had the side effect of causing this whole struct to 58 // round up to 32 bytes in size. To be more explicit, we add pad fields 59 // added for binary compatibility. 60 uint32_t reserved[3]; 61#endif 62}; 63 64typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) 65 (int version, 66 _Unwind_Action actions, 67 uint64_t exceptionClass, 68 struct _Unwind_Exception* exceptionObject, 69 struct _Unwind_Context* context, 70 void* stop_parameter ); 71 72typedef _Unwind_Reason_Code (*__personality_routine) 73 (int version, 74 _Unwind_Action actions, 75 uint64_t exceptionClass, 76 struct _Unwind_Exception* exceptionObject, 77 struct _Unwind_Context* context); 78 79#ifdef __cplusplus 80extern "C" { 81#endif 82 83// 84// The following are the base functions documented by the C++ ABI 85// 86#if __arm__ 87extern _Unwind_Reason_Code 88 _Unwind_SjLj_RaiseException(struct _Unwind_Exception *exception_object); 89extern void _Unwind_SjLj_Resume(struct _Unwind_Exception *exception_object); 90#else 91extern _Unwind_Reason_Code 92 _Unwind_RaiseException(struct _Unwind_Exception *exception_object); 93extern void _Unwind_Resume(struct _Unwind_Exception *exception_object); 94#endif 95extern void _Unwind_DeleteException(struct _Unwind_Exception *exception_object); 96extern uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index); 97extern void _Unwind_SetGR(struct _Unwind_Context *context, int index, 98 uintptr_t new_value); 99extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context); 100extern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t new_value); 101extern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context); 102extern uintptr_t 103 _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context); 104#if __arm__ 105extern _Unwind_Reason_Code 106 _Unwind_SjLj_ForcedUnwind(struct _Unwind_Exception *exception_object, 107 _Unwind_Stop_Fn stop, void *stop_parameter); 108#else 109extern _Unwind_Reason_Code 110 _Unwind_ForcedUnwind(struct _Unwind_Exception *exception_object, 111 _Unwind_Stop_Fn stop, void *stop_parameter); 112#endif 113 114#if __arm__ 115typedef struct _Unwind_FunctionContext *_Unwind_FunctionContext_t; 116extern void _Unwind_SjLj_Register(_Unwind_FunctionContext_t fc); 117extern void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t fc); 118#endif 119 120// 121// The following are semi-suppoted extensions to the C++ ABI 122// 123 124// 125// called by __cxa_rethrow(). 126// 127#if __arm__ 128extern _Unwind_Reason_Code 129 _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *exception_object); 130#else 131extern _Unwind_Reason_Code 132 _Unwind_Resume_or_Rethrow(struct _Unwind_Exception *exception_object); 133#endif 134 135// _Unwind_Backtrace() is a gcc extension that walks the stack and calls the 136// _Unwind_Trace_Fn once per frame until it reaches the bottom of the stack 137// or the _Unwind_Trace_Fn function returns something other than _URC_NO_REASON. 138typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *, 139 void *); 140extern _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void *); 141 142// _Unwind_GetCFA is a gcc extension that can be called from within a 143// personality handler to get the CFA (stack pointer before call) of 144// current frame. 145extern uintptr_t _Unwind_GetCFA(struct _Unwind_Context *); 146 147 148// _Unwind_GetIPInfo is a gcc extension that can be called from within a 149// personality handler. Similar to _Unwind_GetIP() but also returns in 150// *ipBefore a non-zero value if the instruction pointer is at or before the 151// instruction causing the unwind. Normally, in a function call, the IP returned 152// is the return address which is after the call instruction and may be past the 153// end of the function containing the call instruction. 154extern uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, 155 int *ipBefore); 156 157 158// __register_frame() is used with dynamically generated code to register the 159// FDE for a generated (JIT) code. The FDE must use pc-rel addressing to point 160// to its function and optional LSDA. 161// __register_frame() has existed in all versions of Mac OS X, but in 10.4 and 162// 10.5 it was buggy and did not actually register the FDE with the unwinder. 163// In 10.6 and later it does register properly. 164extern void __register_frame(const void *fde); 165extern void __deregister_frame(const void *fde); 166 167// _Unwind_Find_FDE() will locate the FDE if the pc is in some function that has 168// an associated FDE. Note, Mac OS X 10.6 and later, introduces "compact unwind 169// info" which the runtime uses in preference to dwarf unwind info. This 170// function will only work if the target function has an FDE but no compact 171// unwind info. 172struct dwarf_eh_bases { 173 uintptr_t tbase; 174 uintptr_t dbase; 175 uintptr_t func; 176}; 177extern const void *_Unwind_Find_FDE(const void *pc, struct dwarf_eh_bases *); 178 179 180// This function attempts to find the start (address of first instruction) of 181// a function given an address inside the function. It only works if the 182// function has an FDE (dwarf unwind info). 183// This function is unimplemented on Mac OS X 10.6 and later. Instead, use 184// _Unwind_Find_FDE() and look at the dwarf_eh_bases.func result. 185extern void *_Unwind_FindEnclosingFunction(void *pc); 186 187// Mac OS X does not support text-rel and data-rel addressing so these functions 188// are unimplemented 189extern uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *context) 190 LIBUNWIND_UNAVAIL; 191extern uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context *context) 192 LIBUNWIND_UNAVAIL; 193 194// Mac OS X 10.4 and 10.5 had implementations of these functions in 195// libgcc_s.dylib, but they never worked. 196/// These functions are no longer available on Mac OS X. 197extern void __register_frame_info_bases(const void *fde, void *ob, void *tb, 198 void *db) LIBUNWIND_UNAVAIL; 199extern void __register_frame_info(const void *fde, void *ob) 200 LIBUNWIND_UNAVAIL; 201extern void __register_frame_info_table_bases(const void *fde, void *ob, 202 void *tb, void *db) 203 LIBUNWIND_UNAVAIL; 204extern void __register_frame_info_table(const void *fde, void *ob) 205 LIBUNWIND_UNAVAIL; 206extern void __register_frame_table(const void *fde) 207 LIBUNWIND_UNAVAIL; 208extern void *__deregister_frame_info(const void *fde) 209 LIBUNWIND_UNAVAIL; 210extern void *__deregister_frame_info_bases(const void *fde) 211 LIBUNWIND_UNAVAIL; 212 213#ifdef __cplusplus 214} 215#endif 216 217#endif // __UNWIND_H__ 218