Home | History | Annotate | Download | only in src
      1 //===------------------------- cxa_exception.hpp --------------------------===//
      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 //  This file implements the "Exception Handling APIs"
     10 //  http://mentorembedded.github.io/cxx-abi/abi-eh.html
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef _CXA_EXCEPTION_H
     15 #define _CXA_EXCEPTION_H
     16 
     17 #include <exception> // for std::unexpected_handler and std::terminate_handler
     18 #include "cxxabi.h"
     19 #include "unwind.h"
     20 
     21 namespace __cxxabiv1 {
     22 
     23 static const uint64_t kOurExceptionClass          = 0x434C4E47432B2B00; // CLNGC++\0
     24 static const uint64_t kOurDependentExceptionClass = 0x434C4E47432B2B01; // CLNGC++\1
     25 static const uint64_t get_vendor_and_language     = 0xFFFFFFFFFFFFFF00; // mask for CLNGC++
     26 
     27 struct _LIBCXXABI_HIDDEN __cxa_exception {
     28 #if defined(__LP64__) || defined(_LIBCXXABI_ARM_EHABI)
     29     // This is a new field to support C++ 0x exception_ptr.
     30     // For binary compatibility it is at the start of this
     31     // struct which is prepended to the object thrown in
     32     // __cxa_allocate_exception.
     33     size_t referenceCount;
     34 #endif
     35 
     36     //  Manage the exception object itself.
     37     std::type_info *exceptionType;
     38     void (*exceptionDestructor)(void *);
     39     std::unexpected_handler unexpectedHandler;
     40     std::terminate_handler  terminateHandler;
     41 
     42     __cxa_exception *nextException;
     43 
     44     int handlerCount;
     45 
     46 #if defined(_LIBCXXABI_ARM_EHABI)
     47     __cxa_exception* nextPropagatingException;
     48     int propagationCount;
     49 #else
     50     int handlerSwitchValue;
     51     const unsigned char *actionRecord;
     52     const unsigned char *languageSpecificData;
     53     void *catchTemp;
     54     void *adjustedPtr;
     55 #endif
     56 
     57 #if !defined(__LP64__) && !defined(_LIBCXXABI_ARM_EHABI)
     58     // This is a new field to support C++ 0x exception_ptr.
     59     // For binary compatibility it is placed where the compiler
     60     // previously adding padded to 64-bit align unwindHeader.
     61     size_t referenceCount;
     62 #endif
     63 
     64     // This field is annotated with attribute aligned so that the exception
     65     // object following the field is sufficiently aligned and there is no
     66     // gap between the field and the exception object. r276215 made a change to
     67     // annotate _Unwind_Exception in unwind.h with __attribute__((aligned)), but
     68     // we cannot incorporate the fix on Darwin since it is an ABI-breaking
     69     // change, which is why we need the attribute on this field.
     70     //
     71     // For ARM EHABI, we do not align this field since _Unwind_Exception is an
     72     // alias of _Unwind_Control_Block, which is not annotated with
     73     // __attribute__((aligned).
     74 #if defined(_LIBCXXABI_ARM_EHABI)
     75     _Unwind_Exception unwindHeader;
     76 #else
     77     _Unwind_Exception unwindHeader __attribute__((aligned));
     78 #endif
     79 };
     80 
     81 // http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html
     82 // The layout of this structure MUST match the layout of __cxa_exception, with
     83 // primaryException instead of referenceCount.
     84 struct _LIBCXXABI_HIDDEN __cxa_dependent_exception {
     85 #if defined(__LP64__) || defined(_LIBCXXABI_ARM_EHABI)
     86     void* primaryException;
     87 #endif
     88 
     89     std::type_info *exceptionType;
     90     void (*exceptionDestructor)(void *);
     91     std::unexpected_handler unexpectedHandler;
     92     std::terminate_handler terminateHandler;
     93 
     94     __cxa_exception *nextException;
     95 
     96     int handlerCount;
     97 
     98 #if defined(_LIBCXXABI_ARM_EHABI)
     99     __cxa_exception* nextPropagatingException;
    100     int propagationCount;
    101 #else
    102     int handlerSwitchValue;
    103     const unsigned char *actionRecord;
    104     const unsigned char *languageSpecificData;
    105     void * catchTemp;
    106     void *adjustedPtr;
    107 #endif
    108 
    109 #if !defined(__LP64__) && !defined(_LIBCXXABI_ARM_EHABI)
    110     void* primaryException;
    111 #endif
    112 
    113     // See the comment in __cxa_exception as to why this field has attribute
    114     // aligned.
    115 #if defined(_LIBCXXABI_ARM_EHABI)
    116     _Unwind_Exception unwindHeader;
    117 #else
    118     _Unwind_Exception unwindHeader __attribute__((aligned));
    119 #endif
    120 };
    121 
    122 struct _LIBCXXABI_HIDDEN __cxa_eh_globals {
    123     __cxa_exception *   caughtExceptions;
    124     unsigned int        uncaughtExceptions;
    125 #if defined(_LIBCXXABI_ARM_EHABI)
    126     __cxa_exception* propagatingExceptions;
    127 #endif
    128 };
    129 
    130 extern "C" _LIBCXXABI_FUNC_VIS __cxa_eh_globals * __cxa_get_globals      ();
    131 extern "C" _LIBCXXABI_FUNC_VIS __cxa_eh_globals * __cxa_get_globals_fast ();
    132 
    133 extern "C" _LIBCXXABI_FUNC_VIS void * __cxa_allocate_dependent_exception ();
    134 extern "C" _LIBCXXABI_FUNC_VIS void __cxa_free_dependent_exception (void * dependent_exception);
    135 
    136 }  // namespace __cxxabiv1
    137 
    138 #endif  // _CXA_EXCEPTION_H
    139