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