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