| // Copyright (C) 2011 The Android Open Source Project |
| // All rights reserved. |
| // |
| // Redistribution and use in source and binary forms, with or without |
| // modification, are permitted provided that the following conditions |
| // are met: |
| // 1. Redistributions of source code must retain the above copyright |
| // notice, this list of conditions and the following disclaimer. |
| // 2. Redistributions in binary form must reproduce the above copyright |
| // notice, this list of conditions and the following disclaimer in the |
| // documentation and/or other materials provided with the distribution. |
| // 3. Neither the name of the project nor the names of its contributors |
| // may be used to endorse or promote products derived from this software |
| // without specific prior written permission. |
| // |
| // THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND |
| // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| // ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE |
| // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| // SUCH DAMAGE. |
| // |
| |
| #ifndef __GABIXX_CXXABI_H__ |
| #define __GABIXX_CXXABI_H__ |
| |
| // The specifications for the declarations found in this header are |
| // the following: |
| // |
| // - Itanium C++ ABI [1] |
| // Used on about every CPU architecture, _except_ ARM, this |
| // is also commonly referred as the "generic C++ ABI". |
| // |
| // NOTE: This document seems to only covers C++98 |
| // |
| // - Itanium C++ ABI: Exception Handling. [2] |
| // Supplement to the above document describing how exception |
| // handle works with the generic C++ ABI. Again, this only |
| // seems to support C++98. |
| // |
| // - C++ ABI for the ARM architecture [3] |
| // Describes the ARM C++ ABI, mainly as a set of differences from |
| // the generic one. |
| // |
| // - Exception Handling for the ARM Architecture [4] |
| // Describes exception handling for ARM in detail. There are rather |
| // important differences in the stack unwinding process and |
| // exception cleanup. |
| // |
| // There are also no freely availabel documentation about certain |
| // features introduced in C++0x or later. In this case, the best |
| // source for information are the GNU and LLVM C++ runtime libraries |
| // (libcxxabi, libsupc++ and even libc++ sources), as well as a few |
| // proposals, for example: |
| // |
| // - For exception propagation: |
| // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2007/n2179.html |
| // But the paper only describs the high-level language feature, not |
| // the low-level runtime support required to implement it. |
| // |
| // - For nested exceptions: |
| // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2008/n2559.html |
| // Yet another high-level description without low-level details. |
| // |
| #include <gabixx_config.h> |
| |
| #include <exception> |
| #include <stdint.h> |
| #include <typeinfo> |
| #include <unwind.h> |
| |
| // When LIBCXXABI, gabi++ should emulate libc++abi. _LIBCPPABI_VERSION must |
| // be defined in cxxabi.h to complete this abstraction for libc++. |
| #if defined(LIBCXXABI) |
| #define _LIBCPPABI_VERSION 1001 |
| #endif |
| |
| namespace __cxxabiv1 |
| { |
| extern "C" { |
| |
| // TODO: Support dependent exception |
| // TODO: Support C++0x exception propagation |
| // http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html |
| struct __cxa_exception; |
| struct __cxa_eh_globals; |
| |
| __cxa_eh_globals* __cxa_get_globals() _GABIXX_NOEXCEPT ; |
| __cxa_eh_globals* __cxa_get_globals_fast() _GABIXX_NOEXCEPT; |
| |
| void* __cxa_allocate_exception(size_t thrown_size) _GABIXX_NOEXCEPT; |
| void __cxa_free_exception(void* thrown_exception) _GABIXX_NOEXCEPT; |
| |
| void __cxa_throw(void* thrown_exception, |
| std::type_info* tinfo, |
| void (*dest)(void*)) _GABIXX_NORETURN; |
| |
| void __cxa_rethrow() _GABIXX_NORETURN; |
| |
| void* __cxa_begin_catch(void* exceptionObject) _GABIXX_NOEXCEPT; |
| void __cxa_end_catch() _GABIXX_NOEXCEPT; |
| |
| #ifdef __arm__ |
| bool __cxa_begin_cleanup(_Unwind_Exception*); |
| void __cxa_end_cleanup(); |
| #endif |
| |
| void __cxa_bad_cast() _GABIXX_NORETURN; |
| void __cxa_bad_typeid() _GABIXX_NORETURN; |
| |
| void* __cxa_get_exception_ptr(void* exceptionObject) _GABIXX_NOEXCEPT; |
| |
| void __cxa_pure_virtual() _GABIXX_NORETURN; |
| void __cxa_deleted_virtual() _GABIXX_NORETURN; |
| |
| // Missing libcxxabi functions. |
| bool __cxa_uncaught_exception() _GABIXX_NOEXCEPT; |
| |
| void __cxa_decrement_exception_refcount(void* exceptionObject) |
| _GABIXX_NOEXCEPT; |
| |
| void __cxa_increment_exception_refcount(void* exceptionObject) |
| _GABIXX_NOEXCEPT; |
| |
| void __cxa_rethrow_primary_exception(void* exceptionObject); |
| |
| void* __cxa_current_primary_exception() _GABIXX_NOEXCEPT; |
| |
| // The ARM ABI mandates that constructors and destructors |
| // must return 'this', i.e. their first parameter. This is |
| // also true for __cxa_vec_ctor and __cxa_vec_cctor. |
| #ifdef __arm__ |
| typedef void* __cxa_vec_ctor_return_type; |
| #else |
| typedef void __cxa_vec_ctor_return_type; |
| #endif |
| |
| typedef __cxa_vec_ctor_return_type |
| (*__cxa_vec_constructor)(void *); |
| |
| typedef __cxa_vec_constructor __cxa_vec_destructor; |
| |
| typedef __cxa_vec_ctor_return_type |
| (*__cxa_vec_copy_constructor)(void*, void*); |
| |
| void* __cxa_vec_new(size_t element_count, |
| size_t element_size, |
| size_t padding_size, |
| __cxa_vec_constructor constructor, |
| __cxa_vec_destructor destructor); |
| |
| void* __cxa_vec_new2(size_t element_count, |
| size_t element_size, |
| size_t padding_size, |
| __cxa_vec_constructor constructor, |
| __cxa_vec_destructor destructor, |
| void* (*alloc)(size_t), |
| void (*dealloc)(void*)); |
| |
| void* __cxa_vec_new3(size_t element_count, |
| size_t element_size, |
| size_t padding_size, |
| __cxa_vec_constructor constructor, |
| __cxa_vec_destructor destructor, |
| void* (*alloc)(size_t), |
| void (*dealloc)(void*, size_t)); |
| |
| __cxa_vec_ctor_return_type |
| __cxa_vec_ctor(void* array_address, |
| size_t element_count, |
| size_t element_size, |
| __cxa_vec_constructor constructor, |
| __cxa_vec_destructor destructor); |
| |
| void __cxa_vec_dtor(void* array_address, |
| size_t element_count, |
| size_t element_size, |
| __cxa_vec_destructor destructor); |
| |
| void __cxa_vec_cleanup(void* array_address, |
| size_t element_count, |
| size_t element_size, |
| __cxa_vec_destructor destructor); |
| |
| void __cxa_vec_delete(void* array_address, |
| size_t element_size, |
| size_t padding_size, |
| __cxa_vec_destructor destructor); |
| |
| void __cxa_vec_delete2(void* array_address, |
| size_t element_size, |
| size_t padding_size, |
| __cxa_vec_destructor destructor, |
| void (*dealloc)(void*)); |
| |
| void __cxa_vec_delete3(void* array_address, |
| size_t element_size, |
| size_t padding_size, |
| __cxa_vec_destructor destructor, |
| void (*dealloc) (void*, size_t)); |
| |
| __cxa_vec_ctor_return_type |
| __cxa_vec_cctor(void* dest_array, |
| void* src_array, |
| size_t element_count, |
| size_t element_size, |
| __cxa_vec_copy_constructor constructor, |
| __cxa_vec_destructor destructor ); |
| |
| } // extern "C" |
| |
| } // namespace __cxxabiv1 |
| |
| namespace abi = __cxxabiv1; |
| |
| #if _GABIXX_ARM_ABI |
| // ARM-specific ABI additions. They must be provided by the |
| // C++ runtime to simplify calling code generated by the compiler. |
| // Note that neither GCC nor Clang seem to use these, but this can |
| // happen when using machine code generated with other ocmpilers |
| // like RCVT. |
| |
| namespace __aeabiv1 { |
| extern "C" { |
| |
| using __cxxabiv1::__cxa_vec_constructor; |
| using __cxxabiv1::__cxa_vec_copy_constructor; |
| using __cxxabiv1::__cxa_vec_destructor; |
| |
| void* __aeabi_vec_ctor_nocookie_nodtor(void* array_address, |
| __cxa_vec_constructor constructor, |
| size_t element_size, |
| size_t element_count); |
| |
| void* __aeabi_vec_ctor_cookie_nodtor(void* array_address, |
| __cxa_vec_constructor constructor, |
| size_t element_size, |
| size_t element_count); |
| |
| void* __aeabi_vec_cctor_nocookie_nodtor( |
| void* dst_array, |
| void* src_array, |
| size_t element_size, |
| size_t element_count, |
| __cxa_vec_copy_constructor constructor); |
| |
| void* __aeabi_vec_new_nocookie_noctor(size_t element_size, |
| size_t element_count); |
| |
| void* __aeabi_vec_new_nocookie(size_t element_size, |
| size_t element_count, |
| __cxa_vec_constructor constructor); |
| |
| void* __aeabi_vec_new_cookie_nodtor(size_t element_size, |
| size_t element_count, |
| __cxa_vec_constructor constructor); |
| |
| void* __aeabi_vec_new_cookie(size_t element_size, |
| size_t element_count, |
| __cxa_vec_constructor constructor, |
| __cxa_vec_destructor destructor); |
| |
| void* __aeabi_vec_dtor(void* array_address, |
| __cxa_vec_destructor destructor, |
| size_t element_size, |
| size_t element_count); |
| |
| void* __aeabi_vec_dtor_cookie(void* array_address, |
| __cxa_vec_destructor destructor); |
| |
| void __aeabi_vec_delete(void* array_address, |
| __cxa_vec_destructor destructor); |
| |
| void __aeabi_vec_delete3(void* array_address, |
| __cxa_vec_destructor destructor, |
| void (*dealloc)(void*, size_t)); |
| |
| void __aeabi_vec_delete3_nodtor(void* array_address, |
| void (*dealloc)(void*, size_t)); |
| |
| } // extern "C" |
| } // namespace __ |
| |
| #endif // _GABIXX_ARM_ABI == 1 |
| |
| #endif /* defined(__GABIXX_CXXABI_H__) */ |
| |