OLD | NEW |
(Empty) | |
| 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 |
| 26 typedef 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 |
| 38 typedef 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 |
| 46 struct _Unwind_Context; // opaque |
| 47 struct _Unwind_Exception; // forward declaration |
| 48 |
| 49 struct _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 |
| 64 typedef _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 |
| 72 typedef _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 |
| 80 extern "C" { |
| 81 #endif |
| 82 |
| 83 // |
| 84 // The following are the base functions documented by the C++ ABI |
| 85 // |
| 86 #if __arm__ |
| 87 extern _Unwind_Reason_Code |
| 88 _Unwind_SjLj_RaiseException(struct _Unwind_Exception *exception_object); |
| 89 extern void _Unwind_SjLj_Resume(struct _Unwind_Exception *exception_object); |
| 90 #else |
| 91 extern _Unwind_Reason_Code |
| 92 _Unwind_RaiseException(struct _Unwind_Exception *exception_object); |
| 93 extern void _Unwind_Resume(struct _Unwind_Exception *exception_object); |
| 94 #endif |
| 95 extern void _Unwind_DeleteException(struct _Unwind_Exception *exception_object); |
| 96 extern uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index); |
| 97 extern void _Unwind_SetGR(struct _Unwind_Context *context, int index, |
| 98 uintptr_t new_value); |
| 99 extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context); |
| 100 extern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t new_value); |
| 101 extern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context); |
| 102 extern uintptr_t |
| 103 _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context); |
| 104 #if __arm__ |
| 105 extern _Unwind_Reason_Code |
| 106 _Unwind_SjLj_ForcedUnwind(struct _Unwind_Exception *exception_object, |
| 107 _Unwind_Stop_Fn stop, void *stop_parameter); |
| 108 #else |
| 109 extern _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__ |
| 115 typedef struct _Unwind_FunctionContext *_Unwind_FunctionContext_t; |
| 116 extern void _Unwind_SjLj_Register(_Unwind_FunctionContext_t fc); |
| 117 extern 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__ |
| 128 extern _Unwind_Reason_Code |
| 129 _Unwind_SjLj_Resume_or_Rethrow(struct _Unwind_Exception *exception_object); |
| 130 #else |
| 131 extern _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. |
| 138 typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *, |
| 139 void *); |
| 140 extern _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. |
| 145 extern 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. |
| 154 extern 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. |
| 164 extern void __register_frame(const void *fde); |
| 165 extern 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. |
| 172 struct dwarf_eh_bases { |
| 173 uintptr_t tbase; |
| 174 uintptr_t dbase; |
| 175 uintptr_t func; |
| 176 }; |
| 177 extern 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. |
| 185 extern 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 |
| 189 extern uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *context) |
| 190 LIBUNWIND_UNAVAIL; |
| 191 extern 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. |
| 197 extern void __register_frame_info_bases(const void *fde, void *ob, void *tb, |
| 198 void *db) LIBUNWIND_UNAVAIL; |
| 199 extern void __register_frame_info(const void *fde, void *ob) |
| 200 LIBUNWIND_UNAVAIL; |
| 201 extern void __register_frame_info_table_bases(const void *fde, void *ob, |
| 202 void *tb, void *db) |
| 203 LIBUNWIND_UNAVAIL; |
| 204 extern void __register_frame_info_table(const void *fde, void *ob) |
| 205 LIBUNWIND_UNAVAIL; |
| 206 extern void __register_frame_table(const void *fde) |
| 207 LIBUNWIND_UNAVAIL; |
| 208 extern void *__deregister_frame_info(const void *fde) |
| 209 LIBUNWIND_UNAVAIL; |
| 210 extern void *__deregister_frame_info_bases(const void *fde) |
| 211 LIBUNWIND_UNAVAIL; |
| 212 |
| 213 #ifdef __cplusplus |
| 214 } |
| 215 #endif |
| 216 |
| 217 #endif // __UNWIND_H__ |
OLD | NEW |