Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 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 | |
Logan Chien | 5191fe9 | 2015-07-19 15:23:10 +0000 | [diff] [blame] | 17 | #include <__libunwind_config.h> |
| 18 | |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 19 | #include <stdint.h> |
| 20 | #include <stddef.h> |
| 21 | |
Charles Davis | a7e3a6d | 2018-08-30 21:29:00 +0000 | [diff] [blame^] | 22 | #if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) && defined(_WIN32) |
Charles Davis | 06acf1f | 2018-08-08 15:18:20 +0000 | [diff] [blame] | 23 | #include <windows.h> |
Charles Davis | a7e3a6d | 2018-08-30 21:29:00 +0000 | [diff] [blame^] | 24 | #include <ntverp.h> |
Charles Davis | 06acf1f | 2018-08-08 15:18:20 +0000 | [diff] [blame] | 25 | #endif |
| 26 | |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 27 | #if defined(__APPLE__) |
| 28 | #define LIBUNWIND_UNAVAIL __attribute__ (( unavailable )) |
| 29 | #else |
| 30 | #define LIBUNWIND_UNAVAIL |
| 31 | #endif |
| 32 | |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 33 | typedef enum { |
| 34 | _URC_NO_REASON = 0, |
| 35 | _URC_OK = 0, |
| 36 | _URC_FOREIGN_EXCEPTION_CAUGHT = 1, |
| 37 | _URC_FATAL_PHASE2_ERROR = 2, |
| 38 | _URC_FATAL_PHASE1_ERROR = 3, |
| 39 | _URC_NORMAL_STOP = 4, |
| 40 | _URC_END_OF_STACK = 5, |
| 41 | _URC_HANDLER_FOUND = 6, |
| 42 | _URC_INSTALL_CONTEXT = 7, |
| 43 | _URC_CONTINUE_UNWIND = 8, |
Ranjeet Singh | 5808011 | 2017-03-31 15:28:06 +0000 | [diff] [blame] | 44 | #if defined(_LIBUNWIND_ARM_EHABI) |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 45 | _URC_FAILURE = 9 |
| 46 | #endif |
| 47 | } _Unwind_Reason_Code; |
| 48 | |
| 49 | typedef enum { |
| 50 | _UA_SEARCH_PHASE = 1, |
| 51 | _UA_CLEANUP_PHASE = 2, |
| 52 | _UA_HANDLER_FRAME = 4, |
| 53 | _UA_FORCE_UNWIND = 8, |
| 54 | _UA_END_OF_STACK = 16 // gcc extension to C++ ABI |
| 55 | } _Unwind_Action; |
| 56 | |
| 57 | typedef struct _Unwind_Context _Unwind_Context; // opaque |
| 58 | |
Ranjeet Singh | 5808011 | 2017-03-31 15:28:06 +0000 | [diff] [blame] | 59 | #if defined(_LIBUNWIND_ARM_EHABI) |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 60 | typedef uint32_t _Unwind_State; |
| 61 | |
| 62 | static const _Unwind_State _US_VIRTUAL_UNWIND_FRAME = 0; |
| 63 | static const _Unwind_State _US_UNWIND_FRAME_STARTING = 1; |
| 64 | static const _Unwind_State _US_UNWIND_FRAME_RESUME = 2; |
Dimitry Andric | 84af6d1 | 2016-09-05 18:01:13 +0000 | [diff] [blame] | 65 | static const _Unwind_State _US_ACTION_MASK = 3; |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 66 | /* Undocumented flag for force unwinding. */ |
| 67 | static const _Unwind_State _US_FORCE_UNWIND = 8; |
| 68 | |
| 69 | typedef uint32_t _Unwind_EHT_Header; |
| 70 | |
| 71 | struct _Unwind_Control_Block; |
| 72 | typedef struct _Unwind_Control_Block _Unwind_Control_Block; |
| 73 | typedef struct _Unwind_Control_Block _Unwind_Exception; /* Alias */ |
| 74 | |
| 75 | struct _Unwind_Control_Block { |
| 76 | uint64_t exception_class; |
| 77 | void (*exception_cleanup)(_Unwind_Reason_Code, _Unwind_Control_Block*); |
| 78 | |
| 79 | /* Unwinder cache, private fields for the unwinder's use */ |
| 80 | struct { |
| 81 | uint32_t reserved1; /* init reserved1 to 0, then don't touch */ |
| 82 | uint32_t reserved2; |
| 83 | uint32_t reserved3; |
| 84 | uint32_t reserved4; |
| 85 | uint32_t reserved5; |
| 86 | } unwinder_cache; |
| 87 | |
| 88 | /* Propagation barrier cache (valid after phase 1): */ |
| 89 | struct { |
| 90 | uint32_t sp; |
| 91 | uint32_t bitpattern[5]; |
| 92 | } barrier_cache; |
| 93 | |
| 94 | /* Cleanup cache (preserved over cleanup): */ |
| 95 | struct { |
| 96 | uint32_t bitpattern[4]; |
| 97 | } cleanup_cache; |
| 98 | |
| 99 | /* Pr cache (for pr's benefit): */ |
| 100 | struct { |
| 101 | uint32_t fnstart; /* function start address */ |
| 102 | _Unwind_EHT_Header* ehtp; /* pointer to EHT entry header word */ |
| 103 | uint32_t additional; |
| 104 | uint32_t reserved1; |
| 105 | } pr_cache; |
| 106 | |
| 107 | long long int :0; /* Enforce the 8-byte alignment */ |
Saleem Abdulrasool | f8774f1 | 2017-08-23 16:50:27 +0000 | [diff] [blame] | 108 | } __attribute__((__aligned__(8))); |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 109 | |
| 110 | typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) |
| 111 | (_Unwind_State state, |
| 112 | _Unwind_Exception* exceptionObject, |
| 113 | struct _Unwind_Context* context); |
| 114 | |
| 115 | typedef _Unwind_Reason_Code (*__personality_routine) |
| 116 | (_Unwind_State state, |
| 117 | _Unwind_Exception* exceptionObject, |
| 118 | struct _Unwind_Context* context); |
| 119 | #else |
| 120 | struct _Unwind_Context; // opaque |
| 121 | struct _Unwind_Exception; // forward declaration |
| 122 | typedef struct _Unwind_Exception _Unwind_Exception; |
| 123 | |
| 124 | struct _Unwind_Exception { |
| 125 | uint64_t exception_class; |
| 126 | void (*exception_cleanup)(_Unwind_Reason_Code reason, |
| 127 | _Unwind_Exception *exc); |
Charles Davis | 06acf1f | 2018-08-08 15:18:20 +0000 | [diff] [blame] | 128 | #if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) |
| 129 | uintptr_t private_[6]; |
| 130 | #else |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 131 | uintptr_t private_1; // non-zero means forced unwind |
| 132 | uintptr_t private_2; // holds sp that phase1 found for phase2 to use |
Charles Davis | 06acf1f | 2018-08-08 15:18:20 +0000 | [diff] [blame] | 133 | #endif |
Martin Storsjo | 66bb841f | 2017-10-27 08:11:36 +0000 | [diff] [blame] | 134 | #if __SIZEOF_POINTER__ == 4 |
Eric Fiselier | 19f802f | 2016-07-20 23:56:42 +0000 | [diff] [blame] | 135 | // The implementation of _Unwind_Exception uses an attribute mode on the |
| 136 | // above fields which has the side effect of causing this whole struct to |
Charles Davis | 06acf1f | 2018-08-08 15:18:20 +0000 | [diff] [blame] | 137 | // round up to 32 bytes in size (48 with SEH). To be more explicit, we add |
| 138 | // pad fields added for binary compatibility. |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 139 | uint32_t reserved[3]; |
| 140 | #endif |
Eric Fiselier | 19f802f | 2016-07-20 23:56:42 +0000 | [diff] [blame] | 141 | // The Itanium ABI requires that _Unwind_Exception objects are "double-word |
| 142 | // aligned". GCC has interpreted this to mean "use the maximum useful |
| 143 | // alignment for the target"; so do we. |
| 144 | } __attribute__((__aligned__)); |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 145 | |
| 146 | typedef _Unwind_Reason_Code (*_Unwind_Stop_Fn) |
| 147 | (int version, |
| 148 | _Unwind_Action actions, |
| 149 | uint64_t exceptionClass, |
| 150 | _Unwind_Exception* exceptionObject, |
| 151 | struct _Unwind_Context* context, |
| 152 | void* stop_parameter ); |
| 153 | |
| 154 | typedef _Unwind_Reason_Code (*__personality_routine) |
| 155 | (int version, |
| 156 | _Unwind_Action actions, |
| 157 | uint64_t exceptionClass, |
| 158 | _Unwind_Exception* exceptionObject, |
| 159 | struct _Unwind_Context* context); |
| 160 | #endif |
| 161 | |
| 162 | #ifdef __cplusplus |
| 163 | extern "C" { |
| 164 | #endif |
| 165 | |
| 166 | // |
| 167 | // The following are the base functions documented by the C++ ABI |
| 168 | // |
| 169 | #ifdef __USING_SJLJ_EXCEPTIONS__ |
| 170 | extern _Unwind_Reason_Code |
| 171 | _Unwind_SjLj_RaiseException(_Unwind_Exception *exception_object); |
| 172 | extern void _Unwind_SjLj_Resume(_Unwind_Exception *exception_object); |
| 173 | #else |
| 174 | extern _Unwind_Reason_Code |
| 175 | _Unwind_RaiseException(_Unwind_Exception *exception_object); |
| 176 | extern void _Unwind_Resume(_Unwind_Exception *exception_object); |
| 177 | #endif |
| 178 | extern void _Unwind_DeleteException(_Unwind_Exception *exception_object); |
| 179 | |
Ranjeet Singh | 5808011 | 2017-03-31 15:28:06 +0000 | [diff] [blame] | 180 | #if defined(_LIBUNWIND_ARM_EHABI) |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 181 | typedef enum { |
| 182 | _UVRSC_CORE = 0, /* integer register */ |
| 183 | _UVRSC_VFP = 1, /* vfp */ |
| 184 | _UVRSC_WMMXD = 3, /* Intel WMMX data register */ |
| 185 | _UVRSC_WMMXC = 4 /* Intel WMMX control register */ |
| 186 | } _Unwind_VRS_RegClass; |
| 187 | |
| 188 | typedef enum { |
| 189 | _UVRSD_UINT32 = 0, |
| 190 | _UVRSD_VFPX = 1, |
| 191 | _UVRSD_UINT64 = 3, |
| 192 | _UVRSD_FLOAT = 4, |
| 193 | _UVRSD_DOUBLE = 5 |
| 194 | } _Unwind_VRS_DataRepresentation; |
| 195 | |
| 196 | typedef enum { |
| 197 | _UVRSR_OK = 0, |
| 198 | _UVRSR_NOT_IMPLEMENTED = 1, |
| 199 | _UVRSR_FAILED = 2 |
| 200 | } _Unwind_VRS_Result; |
| 201 | |
| 202 | extern void _Unwind_Complete(_Unwind_Exception* exception_object); |
| 203 | |
| 204 | extern _Unwind_VRS_Result |
| 205 | _Unwind_VRS_Get(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, |
| 206 | uint32_t regno, _Unwind_VRS_DataRepresentation representation, |
| 207 | void *valuep); |
| 208 | |
| 209 | extern _Unwind_VRS_Result |
| 210 | _Unwind_VRS_Set(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, |
| 211 | uint32_t regno, _Unwind_VRS_DataRepresentation representation, |
| 212 | void *valuep); |
| 213 | |
| 214 | extern _Unwind_VRS_Result |
| 215 | _Unwind_VRS_Pop(_Unwind_Context *context, _Unwind_VRS_RegClass regclass, |
| 216 | uint32_t discriminator, |
| 217 | _Unwind_VRS_DataRepresentation representation); |
| 218 | #endif |
| 219 | |
Ranjeet Singh | 5808011 | 2017-03-31 15:28:06 +0000 | [diff] [blame] | 220 | #if !defined(_LIBUNWIND_ARM_EHABI) |
Logan Chien | ff8fbf9 | 2015-07-24 00:16:48 +0000 | [diff] [blame] | 221 | |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 222 | extern uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index); |
| 223 | extern void _Unwind_SetGR(struct _Unwind_Context *context, int index, |
| 224 | uintptr_t new_value); |
| 225 | extern uintptr_t _Unwind_GetIP(struct _Unwind_Context *context); |
| 226 | extern void _Unwind_SetIP(struct _Unwind_Context *, uintptr_t new_value); |
| 227 | |
Ranjeet Singh | 5808011 | 2017-03-31 15:28:06 +0000 | [diff] [blame] | 228 | #else // defined(_LIBUNWIND_ARM_EHABI) |
Logan Chien | ff8fbf9 | 2015-07-24 00:16:48 +0000 | [diff] [blame] | 229 | |
| 230 | #if defined(_LIBUNWIND_UNWIND_LEVEL1_EXTERNAL_LINKAGE) |
| 231 | #define _LIBUNWIND_EXPORT_UNWIND_LEVEL1 extern |
| 232 | #else |
| 233 | #define _LIBUNWIND_EXPORT_UNWIND_LEVEL1 static __inline__ |
| 234 | #endif |
| 235 | |
| 236 | // These are de facto helper functions for ARM, which delegate the function |
| 237 | // calls to _Unwind_VRS_Get/Set(). These are not a part of ARM EHABI |
| 238 | // specification, thus these function MUST be inlined. Please don't replace |
| 239 | // these with the "extern" function declaration; otherwise, the program |
| 240 | // including this <unwind.h> header won't be ABI compatible and will result in |
| 241 | // link error when we are linking the program with libgcc. |
| 242 | |
| 243 | _LIBUNWIND_EXPORT_UNWIND_LEVEL1 |
| 244 | uintptr_t _Unwind_GetGR(struct _Unwind_Context *context, int index) { |
| 245 | uintptr_t value = 0; |
| 246 | _Unwind_VRS_Get(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value); |
| 247 | return value; |
| 248 | } |
| 249 | |
| 250 | _LIBUNWIND_EXPORT_UNWIND_LEVEL1 |
| 251 | void _Unwind_SetGR(struct _Unwind_Context *context, int index, |
| 252 | uintptr_t value) { |
| 253 | _Unwind_VRS_Set(context, _UVRSC_CORE, (uint32_t)index, _UVRSD_UINT32, &value); |
| 254 | } |
| 255 | |
| 256 | _LIBUNWIND_EXPORT_UNWIND_LEVEL1 |
| 257 | uintptr_t _Unwind_GetIP(struct _Unwind_Context *context) { |
| 258 | // remove the thumb-bit before returning |
| 259 | return _Unwind_GetGR(context, 15) & (~(uintptr_t)0x1); |
| 260 | } |
| 261 | |
| 262 | _LIBUNWIND_EXPORT_UNWIND_LEVEL1 |
| 263 | void _Unwind_SetIP(struct _Unwind_Context *context, uintptr_t value) { |
| 264 | uintptr_t thumb_bit = _Unwind_GetGR(context, 15) & ((uintptr_t)0x1); |
| 265 | _Unwind_SetGR(context, 15, value | thumb_bit); |
| 266 | } |
Ranjeet Singh | 5808011 | 2017-03-31 15:28:06 +0000 | [diff] [blame] | 267 | #endif // defined(_LIBUNWIND_ARM_EHABI) |
Logan Chien | ff8fbf9 | 2015-07-24 00:16:48 +0000 | [diff] [blame] | 268 | |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 269 | extern uintptr_t _Unwind_GetRegionStart(struct _Unwind_Context *context); |
| 270 | extern uintptr_t |
| 271 | _Unwind_GetLanguageSpecificData(struct _Unwind_Context *context); |
| 272 | #ifdef __USING_SJLJ_EXCEPTIONS__ |
| 273 | extern _Unwind_Reason_Code |
| 274 | _Unwind_SjLj_ForcedUnwind(_Unwind_Exception *exception_object, |
| 275 | _Unwind_Stop_Fn stop, void *stop_parameter); |
| 276 | #else |
| 277 | extern _Unwind_Reason_Code |
| 278 | _Unwind_ForcedUnwind(_Unwind_Exception *exception_object, |
| 279 | _Unwind_Stop_Fn stop, void *stop_parameter); |
| 280 | #endif |
| 281 | |
| 282 | #ifdef __USING_SJLJ_EXCEPTIONS__ |
| 283 | typedef struct _Unwind_FunctionContext *_Unwind_FunctionContext_t; |
| 284 | extern void _Unwind_SjLj_Register(_Unwind_FunctionContext_t fc); |
| 285 | extern void _Unwind_SjLj_Unregister(_Unwind_FunctionContext_t fc); |
| 286 | #endif |
| 287 | |
| 288 | // |
| 289 | // The following are semi-suppoted extensions to the C++ ABI |
| 290 | // |
| 291 | |
| 292 | // |
| 293 | // called by __cxa_rethrow(). |
| 294 | // |
| 295 | #ifdef __USING_SJLJ_EXCEPTIONS__ |
| 296 | extern _Unwind_Reason_Code |
| 297 | _Unwind_SjLj_Resume_or_Rethrow(_Unwind_Exception *exception_object); |
| 298 | #else |
| 299 | extern _Unwind_Reason_Code |
| 300 | _Unwind_Resume_or_Rethrow(_Unwind_Exception *exception_object); |
| 301 | #endif |
| 302 | |
| 303 | // _Unwind_Backtrace() is a gcc extension that walks the stack and calls the |
| 304 | // _Unwind_Trace_Fn once per frame until it reaches the bottom of the stack |
| 305 | // or the _Unwind_Trace_Fn function returns something other than _URC_NO_REASON. |
| 306 | typedef _Unwind_Reason_Code (*_Unwind_Trace_Fn)(struct _Unwind_Context *, |
| 307 | void *); |
| 308 | extern _Unwind_Reason_Code _Unwind_Backtrace(_Unwind_Trace_Fn, void *); |
| 309 | |
| 310 | // _Unwind_GetCFA is a gcc extension that can be called from within a |
| 311 | // personality handler to get the CFA (stack pointer before call) of |
| 312 | // current frame. |
| 313 | extern uintptr_t _Unwind_GetCFA(struct _Unwind_Context *); |
| 314 | |
| 315 | |
| 316 | // _Unwind_GetIPInfo is a gcc extension that can be called from within a |
| 317 | // personality handler. Similar to _Unwind_GetIP() but also returns in |
| 318 | // *ipBefore a non-zero value if the instruction pointer is at or before the |
| 319 | // instruction causing the unwind. Normally, in a function call, the IP returned |
| 320 | // is the return address which is after the call instruction and may be past the |
| 321 | // end of the function containing the call instruction. |
| 322 | extern uintptr_t _Unwind_GetIPInfo(struct _Unwind_Context *context, |
| 323 | int *ipBefore); |
| 324 | |
| 325 | |
| 326 | // __register_frame() is used with dynamically generated code to register the |
| 327 | // FDE for a generated (JIT) code. The FDE must use pc-rel addressing to point |
| 328 | // to its function and optional LSDA. |
| 329 | // __register_frame() has existed in all versions of Mac OS X, but in 10.4 and |
| 330 | // 10.5 it was buggy and did not actually register the FDE with the unwinder. |
| 331 | // In 10.6 and later it does register properly. |
| 332 | extern void __register_frame(const void *fde); |
| 333 | extern void __deregister_frame(const void *fde); |
| 334 | |
| 335 | // _Unwind_Find_FDE() will locate the FDE if the pc is in some function that has |
| 336 | // an associated FDE. Note, Mac OS X 10.6 and later, introduces "compact unwind |
Ed Maste | c073b1b | 2016-07-19 17:15:50 +0000 | [diff] [blame] | 337 | // info" which the runtime uses in preference to DWARF unwind info. This |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 338 | // function will only work if the target function has an FDE but no compact |
| 339 | // unwind info. |
| 340 | struct dwarf_eh_bases { |
| 341 | uintptr_t tbase; |
| 342 | uintptr_t dbase; |
| 343 | uintptr_t func; |
| 344 | }; |
| 345 | extern const void *_Unwind_Find_FDE(const void *pc, struct dwarf_eh_bases *); |
| 346 | |
| 347 | |
| 348 | // This function attempts to find the start (address of first instruction) of |
| 349 | // a function given an address inside the function. It only works if the |
Ed Maste | c073b1b | 2016-07-19 17:15:50 +0000 | [diff] [blame] | 350 | // function has an FDE (DWARF unwind info). |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 351 | // This function is unimplemented on Mac OS X 10.6 and later. Instead, use |
| 352 | // _Unwind_Find_FDE() and look at the dwarf_eh_bases.func result. |
| 353 | extern void *_Unwind_FindEnclosingFunction(void *pc); |
| 354 | |
| 355 | // Mac OS X does not support text-rel and data-rel addressing so these functions |
| 356 | // are unimplemented |
| 357 | extern uintptr_t _Unwind_GetDataRelBase(struct _Unwind_Context *context) |
| 358 | LIBUNWIND_UNAVAIL; |
| 359 | extern uintptr_t _Unwind_GetTextRelBase(struct _Unwind_Context *context) |
| 360 | LIBUNWIND_UNAVAIL; |
| 361 | |
| 362 | // Mac OS X 10.4 and 10.5 had implementations of these functions in |
| 363 | // libgcc_s.dylib, but they never worked. |
| 364 | /// These functions are no longer available on Mac OS X. |
| 365 | extern void __register_frame_info_bases(const void *fde, void *ob, void *tb, |
| 366 | void *db) LIBUNWIND_UNAVAIL; |
| 367 | extern void __register_frame_info(const void *fde, void *ob) |
| 368 | LIBUNWIND_UNAVAIL; |
| 369 | extern void __register_frame_info_table_bases(const void *fde, void *ob, |
| 370 | void *tb, void *db) |
| 371 | LIBUNWIND_UNAVAIL; |
| 372 | extern void __register_frame_info_table(const void *fde, void *ob) |
| 373 | LIBUNWIND_UNAVAIL; |
| 374 | extern void __register_frame_table(const void *fde) |
| 375 | LIBUNWIND_UNAVAIL; |
| 376 | extern void *__deregister_frame_info(const void *fde) |
| 377 | LIBUNWIND_UNAVAIL; |
| 378 | extern void *__deregister_frame_info_bases(const void *fde) |
| 379 | LIBUNWIND_UNAVAIL; |
| 380 | |
Charles Davis | 06acf1f | 2018-08-08 15:18:20 +0000 | [diff] [blame] | 381 | #if defined(__SEH__) && !defined(__USING_SJLJ_EXCEPTIONS__) |
Charles Davis | a7e3a6d | 2018-08-30 21:29:00 +0000 | [diff] [blame^] | 382 | #ifndef _WIN32 |
| 383 | typedef struct _EXCEPTION_RECORD EXCEPTION_RECORD; |
| 384 | typedef struct _CONTEXT CONTEXT; |
| 385 | typedef struct _DISPATCHER_CONTEXT DISPATCHER_CONTEXT; |
| 386 | #elif !defined(__MINGW32__) && VER_PRODUCTBUILD < 8000 |
| 387 | typedef struct _DISPATCHER_CONTEXT DISPATCHER_CONTEXT; |
| 388 | #endif |
Charles Davis | 06acf1f | 2018-08-08 15:18:20 +0000 | [diff] [blame] | 389 | // This is the common wrapper for GCC-style personality functions with SEH. |
Charles Davis | a7e3a6d | 2018-08-30 21:29:00 +0000 | [diff] [blame^] | 390 | extern EXCEPTION_DISPOSITION _GCC_specific_handler(EXCEPTION_RECORD *exc, |
| 391 | void *frame, |
| 392 | CONTEXT *ctx, |
| 393 | DISPATCHER_CONTEXT *disp, |
| 394 | __personality_routine pers); |
Charles Davis | 06acf1f | 2018-08-08 15:18:20 +0000 | [diff] [blame] | 395 | #endif |
| 396 | |
Saleem Abdulrasool | b1b1911 | 2015-04-24 19:39:17 +0000 | [diff] [blame] | 397 | #ifdef __cplusplus |
| 398 | } |
| 399 | #endif |
| 400 | |
| 401 | #endif // __UNWIND_H__ |