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