Home | History | Annotate | Download | only in include
      1 // Copyright (C) 2011 The Android Open Source Project
      2 // All rights reserved.
      3 //
      4 // Redistribution and use in source and binary forms, with or without
      5 // modification, are permitted provided that the following conditions
      6 // are met:
      7 // 1. Redistributions of source code must retain the above copyright
      8 //    notice, this list of conditions and the following disclaimer.
      9 // 2. Redistributions in binary form must reproduce the above copyright
     10 //    notice, this list of conditions and the following disclaimer in the
     11 //    documentation and/or other materials provided with the distribution.
     12 // 3. Neither the name of the project nor the names of its contributors
     13 //    may be used to endorse or promote products derived from this software
     14 //    without specific prior written permission.
     15 //
     16 // THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
     17 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     19 // ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
     20 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     21 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     22 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     23 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     24 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     25 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26 // SUCH DAMAGE.
     27 //
     28 
     29 #ifndef __GABIXX_CXXABI_H__
     30 #define __GABIXX_CXXABI_H__
     31 
     32 // The specifications for the declarations found in this header are
     33 // the following:
     34 //
     35 // - Itanium C++ ABI [1]
     36 //   Used on about every CPU architecture, _except_ ARM, this
     37 //   is also commonly referred as the "generic C++ ABI".
     38 //
     39 //   NOTE: This document seems to only covers C++98
     40 //
     41 // - Itanium C++ ABI: Exception Handling. [2]
     42 //   Supplement to the above document describing how exception
     43 //   handle works with the generic C++ ABI. Again, this only
     44 //   seems to support C++98.
     45 //
     46 // - C++ ABI for the ARM architecture [3]
     47 //   Describes the ARM C++ ABI, mainly as a set of differences from
     48 //   the generic one.
     49 //
     50 // - Exception Handling for the ARM Architecture [4]
     51 //   Describes exception handling for ARM in detail. There are rather
     52 //   important differences in the stack unwinding process and
     53 //   exception cleanup.
     54 //
     55 // There are also no freely availabel documentation about certain
     56 // features introduced in C++0x or later. In this case, the best
     57 // source for information are the GNU and LLVM C++ runtime libraries
     58 // (libcxxabi, libsupc++ and even libc++ sources), as well as a few
     59 // proposals, for example:
     60 //
     61 // - For exception propagation:
     62 //   http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2007/n2179.html
     63 //   But the paper only describs the high-level language feature, not
     64 //   the low-level runtime support required to implement it.
     65 //
     66 // - For nested exceptions:
     67 //   http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2559.html
     68 //   Yet another high-level description without low-level details.
     69 //
     70 #include <gabixx_config.h>
     71 
     72 #include <exception>
     73 #include <stdint.h>
     74 #include <typeinfo>
     75 #include <unwind.h>
     76 
     77 // When LIBCXXABI, gabi++ should emulate libc++abi. _LIBCPPABI_VERSION must
     78 // be defined in cxxabi.h to complete this abstraction for libc++.
     79 #if defined(LIBCXXABI)
     80 #define _LIBCPPABI_VERSION 1001
     81 #endif
     82 
     83 namespace __cxxabiv1
     84 {
     85   extern "C" {
     86 
     87     // TODO: Support dependent exception
     88     // TODO: Support C++0x exception propagation
     89     // http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html
     90     struct __cxa_exception;
     91     struct __cxa_eh_globals;
     92 
     93     __cxa_eh_globals* __cxa_get_globals() _GABIXX_NOEXCEPT ;
     94     __cxa_eh_globals* __cxa_get_globals_fast() _GABIXX_NOEXCEPT;
     95 
     96     void* __cxa_allocate_exception(size_t thrown_size) _GABIXX_NOEXCEPT;
     97     void __cxa_free_exception(void* thrown_exception) _GABIXX_NOEXCEPT;
     98 
     99     void __cxa_throw(void* thrown_exception,
    100                      std::type_info* tinfo,
    101                      void (*dest)(void*)) _GABIXX_NORETURN;
    102 
    103     void __cxa_rethrow() _GABIXX_NORETURN;
    104 
    105     void* __cxa_begin_catch(void* exceptionObject) _GABIXX_NOEXCEPT;
    106     void __cxa_end_catch() _GABIXX_NOEXCEPT;
    107 
    108 #ifdef __arm__
    109     bool __cxa_begin_cleanup(_Unwind_Exception*);
    110     void __cxa_end_cleanup();
    111 #endif
    112 
    113     void __cxa_bad_cast() _GABIXX_NORETURN;
    114     void __cxa_bad_typeid() _GABIXX_NORETURN;
    115 
    116     void* __cxa_get_exception_ptr(void* exceptionObject) _GABIXX_NOEXCEPT;
    117 
    118     void __cxa_pure_virtual() _GABIXX_NORETURN;
    119     void __cxa_deleted_virtual() _GABIXX_NORETURN;
    120 
    121     // Missing libcxxabi functions.
    122     bool __cxa_uncaught_exception() _GABIXX_NOEXCEPT;
    123 
    124     void __cxa_decrement_exception_refcount(void* exceptionObject)
    125         _GABIXX_NOEXCEPT;
    126 
    127     void __cxa_increment_exception_refcount(void* exceptionObject)
    128         _GABIXX_NOEXCEPT;
    129 
    130     void __cxa_rethrow_primary_exception(void* exceptionObject);
    131 
    132     void* __cxa_current_primary_exception() _GABIXX_NOEXCEPT;
    133 
    134     // The ARM ABI mandates that constructors and destructors
    135     // must return 'this', i.e. their first parameter. This is
    136     // also true for __cxa_vec_ctor and __cxa_vec_cctor.
    137 #ifdef __arm__
    138     typedef void* __cxa_vec_ctor_return_type;
    139 #else
    140     typedef void __cxa_vec_ctor_return_type;
    141 #endif
    142 
    143     typedef __cxa_vec_ctor_return_type
    144         (*__cxa_vec_constructor)(void *);
    145 
    146     typedef __cxa_vec_constructor __cxa_vec_destructor;
    147 
    148     typedef __cxa_vec_ctor_return_type
    149         (*__cxa_vec_copy_constructor)(void*, void*);
    150 
    151     void* __cxa_vec_new(size_t element_count,
    152                         size_t element_size,
    153                         size_t padding_size,
    154                         __cxa_vec_constructor constructor,
    155                         __cxa_vec_destructor destructor);
    156 
    157     void* __cxa_vec_new2(size_t element_count,
    158                          size_t element_size,
    159                          size_t padding_size,
    160                          __cxa_vec_constructor constructor,
    161                          __cxa_vec_destructor destructor,
    162                          void* (*alloc)(size_t),
    163                          void  (*dealloc)(void*));
    164 
    165     void* __cxa_vec_new3(size_t element_count,
    166                          size_t element_size,
    167                          size_t padding_size,
    168                          __cxa_vec_constructor constructor,
    169                          __cxa_vec_destructor destructor,
    170                          void* (*alloc)(size_t),
    171                          void  (*dealloc)(void*, size_t));
    172 
    173     __cxa_vec_ctor_return_type
    174     __cxa_vec_ctor(void*  array_address,
    175                    size_t element_count,
    176                    size_t element_size,
    177                    __cxa_vec_constructor constructor,
    178                    __cxa_vec_destructor destructor);
    179 
    180     void __cxa_vec_dtor(void*  array_address,
    181                         size_t element_count,
    182                         size_t element_size,
    183                         __cxa_vec_destructor destructor);
    184 
    185     void __cxa_vec_cleanup(void* array_address,
    186                            size_t element_count,
    187                            size_t element_size,
    188                            __cxa_vec_destructor destructor);
    189 
    190     void __cxa_vec_delete(void*  array_address,
    191                           size_t element_size,
    192                           size_t padding_size,
    193                           __cxa_vec_destructor destructor);
    194 
    195     void __cxa_vec_delete2(void* array_address,
    196                            size_t element_size,
    197                            size_t padding_size,
    198                            __cxa_vec_destructor destructor,
    199                            void  (*dealloc)(void*));
    200 
    201     void __cxa_vec_delete3(void* array_address,
    202                            size_t element_size,
    203                            size_t padding_size,
    204                            __cxa_vec_destructor destructor,
    205                            void  (*dealloc) (void*, size_t));
    206 
    207     __cxa_vec_ctor_return_type
    208     __cxa_vec_cctor(void*  dest_array,
    209                     void*  src_array,
    210                     size_t element_count,
    211                     size_t element_size,
    212                     __cxa_vec_copy_constructor constructor,
    213                     __cxa_vec_destructor destructor );
    214 
    215   } // extern "C"
    216 
    217 } // namespace __cxxabiv1
    218 
    219 namespace abi = __cxxabiv1;
    220 
    221 #if _GABIXX_ARM_ABI
    222 // ARM-specific ABI additions. They  must be provided by the
    223 // C++ runtime to simplify calling code generated by the compiler.
    224 // Note that neither GCC nor Clang seem to use these, but this can
    225 // happen when using machine code generated with other ocmpilers
    226 // like RCVT.
    227 
    228 namespace __aeabiv1 {
    229 extern "C" {
    230 
    231 using __cxxabiv1::__cxa_vec_constructor;
    232 using __cxxabiv1::__cxa_vec_copy_constructor;
    233 using __cxxabiv1::__cxa_vec_destructor;
    234 
    235 void* __aeabi_vec_ctor_nocookie_nodtor(void* array_address,
    236                                        __cxa_vec_constructor constructor,
    237                                        size_t element_size,
    238                                        size_t element_count);
    239 
    240 void* __aeabi_vec_ctor_cookie_nodtor(void* array_address,
    241                                      __cxa_vec_constructor constructor,
    242                                      size_t element_size,
    243                                      size_t element_count);
    244 
    245 void* __aeabi_vec_cctor_nocookie_nodtor(
    246     void* dst_array,
    247     void* src_array,
    248     size_t element_size,
    249     size_t element_count,
    250     __cxa_vec_copy_constructor constructor);
    251 
    252 void* __aeabi_vec_new_nocookie_noctor(size_t element_size,
    253                                       size_t element_count);
    254 
    255 void* __aeabi_vec_new_nocookie(size_t element_size,
    256                                size_t element_count,
    257                                __cxa_vec_constructor constructor);
    258 
    259 void* __aeabi_vec_new_cookie_nodtor(size_t element_size,
    260                                     size_t element_count,
    261                                     __cxa_vec_constructor constructor);
    262 
    263 void* __aeabi_vec_new_cookie(size_t element_size,
    264                              size_t element_count,
    265                              __cxa_vec_constructor constructor,
    266                              __cxa_vec_destructor destructor);
    267 
    268 void* __aeabi_vec_dtor(void* array_address,
    269                        __cxa_vec_destructor destructor,
    270                        size_t element_size,
    271                        size_t element_count);
    272 
    273 void* __aeabi_vec_dtor_cookie(void* array_address,
    274                               __cxa_vec_destructor destructor);
    275 
    276 void __aeabi_vec_delete(void* array_address,
    277                         __cxa_vec_destructor destructor);
    278 
    279 void __aeabi_vec_delete3(void* array_address,
    280                          __cxa_vec_destructor destructor,
    281                          void (*dealloc)(void*, size_t));
    282 
    283 void __aeabi_vec_delete3_nodtor(void* array_address,
    284                                 void (*dealloc)(void*, size_t));
    285 
    286 }  // extern "C"
    287 }  // namespace __
    288 
    289 #endif  // _GABIXX_ARM_ABI == 1
    290 
    291 #endif /* defined(__GABIXX_CXXABI_H__) */
    292 
    293