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 83namespace __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 219namespace 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 228namespace __aeabiv1 { 229extern "C" { 230 231using __cxxabiv1::__cxa_vec_constructor; 232using __cxxabiv1::__cxa_vec_copy_constructor; 233using __cxxabiv1::__cxa_vec_destructor; 234 235void* __aeabi_vec_ctor_nocookie_nodtor(void* array_address, 236 __cxa_vec_constructor constructor, 237 size_t element_size, 238 size_t element_count); 239 240void* __aeabi_vec_ctor_cookie_nodtor(void* array_address, 241 __cxa_vec_constructor constructor, 242 size_t element_size, 243 size_t element_count); 244 245void* __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 252void* __aeabi_vec_new_nocookie_noctor(size_t element_size, 253 size_t element_count); 254 255void* __aeabi_vec_new_nocookie(size_t element_size, 256 size_t element_count, 257 __cxa_vec_constructor constructor); 258 259void* __aeabi_vec_new_cookie_nodtor(size_t element_size, 260 size_t element_count, 261 __cxa_vec_constructor constructor); 262 263void* __aeabi_vec_new_cookie(size_t element_size, 264 size_t element_count, 265 __cxa_vec_constructor constructor, 266 __cxa_vec_destructor destructor); 267 268void* __aeabi_vec_dtor(void* array_address, 269 __cxa_vec_destructor destructor, 270 size_t element_size, 271 size_t element_count); 272 273void* __aeabi_vec_dtor_cookie(void* array_address, 274 __cxa_vec_destructor destructor); 275 276void __aeabi_vec_delete(void* array_address, 277 __cxa_vec_destructor destructor); 278 279void __aeabi_vec_delete3(void* array_address, 280 __cxa_vec_destructor destructor, 281 void (*dealloc)(void*, size_t)); 282 283void __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