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 namespace __cxxabiv1 78 { 79 extern "C" { 80 81 // TODO: Support dependent exception 82 // TODO: Support C++0x exception propagation 83 // http://sourcery.mentor.com/archives/cxx-abi-dev/msg01924.html 84 struct __cxa_exception; 85 struct __cxa_eh_globals; 86 87 __cxa_eh_globals* __cxa_get_globals(); 88 __cxa_eh_globals* __cxa_get_globals_fast(); 89 90 void* __cxa_allocate_exception(size_t thrown_size); 91 void __cxa_free_exception(void* thrown_exception); 92 93 void __cxa_throw(void* thrown_exception, std::type_info* tinfo, void (*dest)(void*)); 94 void __cxa_rethrow(); 95 96 void* __cxa_begin_catch(void* exceptionObject); 97 void __cxa_end_catch(); 98 99 bool __cxa_begin_cleanup(_Unwind_Exception*); 100 void __cxa_end_cleanup(); 101 102 void __cxa_bad_cast(); 103 void __cxa_bad_typeid(); 104 105 void* __cxa_get_exception_ptr(void* exceptionObject); 106 107 void __cxa_pure_virtual(); 108 109 // Missing libcxxabi functions. 110 bool __cxa_uncaught_exception() _GABIXX_NOEXCEPT; 111 void __cxa_decrement_exception_refcount(void* exceptionObject) _GABIXX_NOEXCEPT; 112 void __cxa_increment_exception_refcount(void* exceptionObject) _GABIXX_NOEXCEPT; 113 void __cxa_rethrow_primary_exception(void* exceptionObject); 114 void* __cxa_current_primary_exception() _GABIXX_NOEXCEPT; 115 116 // The ARM ABI mandates that constructors and destructors 117 // must return 'this', i.e. their first parameter. This is 118 // also true for __cxa_vec_ctor and __cxa_vec_cctor. 119 #ifdef __arm__ 120 typedef void* __cxa_vec_ctor_return_type; 121 #else 122 typedef void __cxa_vec_ctor_return_type; 123 #endif 124 125 typedef __cxa_vec_ctor_return_type 126 (*__cxa_vec_constructor)(void *); 127 128 typedef __cxa_vec_constructor __cxa_vec_destructor; 129 130 typedef __cxa_vec_ctor_return_type 131 (*__cxa_vec_copy_constructor)(void*, void*); 132 133 void* __cxa_vec_new(size_t element_count, 134 size_t element_size, 135 size_t padding_size, 136 __cxa_vec_constructor constructor, 137 __cxa_vec_destructor destructor); 138 139 void* __cxa_vec_new2(size_t element_count, 140 size_t element_size, 141 size_t padding_size, 142 __cxa_vec_constructor constructor, 143 __cxa_vec_destructor destructor, 144 void* (*alloc)(size_t), 145 void (*dealloc)(void*)); 146 147 void* __cxa_vec_new3(size_t element_count, 148 size_t element_size, 149 size_t padding_size, 150 __cxa_vec_constructor constructor, 151 __cxa_vec_destructor destructor, 152 void* (*alloc)(size_t), 153 void (*dealloc)(void*, size_t)); 154 155 __cxa_vec_ctor_return_type 156 __cxa_vec_ctor(void* array_address, 157 size_t element_count, 158 size_t element_size, 159 __cxa_vec_constructor constructor, 160 __cxa_vec_destructor destructor); 161 162 void __cxa_vec_dtor(void* array_address, 163 size_t element_count, 164 size_t element_size, 165 __cxa_vec_destructor destructor); 166 167 void __cxa_vec_cleanup(void* array_address, 168 size_t element_count, 169 size_t element_size, 170 __cxa_vec_destructor destructor); 171 172 void __cxa_vec_delete(void* array_address, 173 size_t element_size, 174 size_t padding_size, 175 __cxa_vec_destructor destructor); 176 177 void __cxa_vec_delete2(void* array_address, 178 size_t element_size, 179 size_t padding_size, 180 __cxa_vec_destructor destructor, 181 void (*dealloc)(void*)); 182 183 void __cxa_vec_delete3(void* array_address, 184 size_t element_size, 185 size_t padding_size, 186 __cxa_vec_destructor destructor, 187 void (*dealloc) (void*, size_t)); 188 189 __cxa_vec_ctor_return_type 190 __cxa_vec_cctor(void* dest_array, 191 void* src_array, 192 size_t element_count, 193 size_t element_size, 194 __cxa_vec_copy_constructor constructor, 195 __cxa_vec_destructor destructor ); 196 197 } // extern "C" 198 199 } // namespace __cxxabiv1 200 201 namespace abi = __cxxabiv1; 202 203 #if _GABIXX_ARM_ABI 204 // ARM-specific ABI additions. They must be provided by the 205 // C++ runtime to simplify calling code generated by the compiler. 206 // Note that neither GCC nor Clang seem to use these, but this can 207 // happen when using machine code generated with other ocmpilers 208 // like RCVT. 209 210 namespace __aeabiv1 { 211 extern "C" { 212 213 using __cxxabiv1::__cxa_vec_constructor; 214 using __cxxabiv1::__cxa_vec_copy_constructor; 215 using __cxxabiv1::__cxa_vec_destructor; 216 217 void* __aeabi_vec_ctor_nocookie_nodtor(void* array_address, 218 __cxa_vec_constructor constructor, 219 size_t element_size, 220 size_t element_count); 221 222 void* __aeabi_vec_ctor_cookie_nodtor(void* array_address, 223 __cxa_vec_constructor constructor, 224 size_t element_size, 225 size_t element_count); 226 227 void* __aeabi_vec_cctor_nocookie_nodtor( 228 void* dst_array, 229 void* src_array, 230 size_t element_size, 231 size_t element_count, 232 __cxa_vec_copy_constructor constructor); 233 234 void* __aeabi_vec_new_nocookie_noctor(size_t element_size, 235 size_t element_count); 236 237 void* __aeabi_vec_new_nocookie(size_t element_size, 238 size_t element_count, 239 __cxa_vec_constructor constructor); 240 241 void* __aeabi_vec_new_cookie_nodtor(size_t element_size, 242 size_t element_count, 243 __cxa_vec_constructor constructor); 244 245 void* __aeabi_vec_new_cookie(size_t element_size, 246 size_t element_count, 247 __cxa_vec_constructor constructor, 248 __cxa_vec_destructor destructor); 249 250 void* __aeabi_vec_dtor(void* array_address, 251 __cxa_vec_destructor destructor, 252 size_t element_size, 253 size_t element_count); 254 255 void* __aeabi_vec_dtor_cookie(void* array_address, 256 __cxa_vec_destructor destructor); 257 258 void __aeabi_vec_delete(void* array_address, 259 __cxa_vec_destructor destructor); 260 261 void __aeabi_vec_delete3(void* array_address, 262 __cxa_vec_destructor destructor, 263 void (*dealloc)(void*, size_t)); 264 265 void __aeabi_vec_delete3_nodtor(void* array_address, 266 void (*dealloc)(void*, size_t)); 267 268 } // extern "C" 269 } // namespace __ 270 271 #endif // _GABIXX_ARM_ABI == 1 272 273 #endif /* defined(__GABIXX_CXXABI_H__) */ 274 275