1 // Copyright (C) 2013 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 #ifndef _GABIXX_CXXABI_DEFINES_H 29 #define _GABIXX_CXXABI_DEFINES_H 30 31 #include <cxxabi.h> 32 #include <stdint.h> 33 34 // Internal declarations for the implementation of <cxxabi.h> and 35 // related headers. 36 37 namespace __cxxabiv1 { 38 39 // Derived types of type_info below are based on 2.9.5 of C++ ABI. 40 41 class __shim_type_info : public std::type_info 42 { 43 public: 44 virtual ~__shim_type_info(); 45 virtual bool can_catch(const __shim_type_info* thrown_type, 46 void*& adjustedPtr) const = 0; 47 }; 48 49 // Typeinfo for fundamental types. 50 class __fundamental_type_info : public __shim_type_info 51 { 52 public: 53 virtual ~__fundamental_type_info(); 54 virtual bool can_catch(const __shim_type_info* thrown_type, 55 void*& adjustedPtr) const; 56 }; 57 58 // Typeinfo for array types. 59 class __array_type_info : public __shim_type_info 60 { 61 public: 62 virtual ~__array_type_info(); 63 virtual bool can_catch(const __shim_type_info* thrown_type, 64 void*& adjustedPtr) const; 65 }; 66 67 // Typeinfo for function types. 68 class __function_type_info : public __shim_type_info 69 { 70 public: 71 virtual ~__function_type_info(); 72 virtual bool can_catch(const __shim_type_info* thrown_type, 73 void*& adjustedPtr) const; 74 }; 75 76 // Typeinfo for enum types. 77 class __enum_type_info : public __shim_type_info 78 { 79 public: 80 virtual ~__enum_type_info(); 81 virtual bool can_catch(const __shim_type_info* thrown_type, 82 void*& adjustedPtr) const; 83 }; 84 85 86 class __class_type_info; 87 88 // Used in __vmi_class_type_info 89 struct __base_class_type_info 90 { 91 public: 92 const __class_type_info *__base_type; 93 94 long __offset_flags; 95 96 enum __offset_flags_masks { 97 __virtual_mask = 0x1, 98 __public_mask = 0x2, 99 __offset_shift = 8 // lower 8 bits are flags 100 }; 101 is_virtual__base_class_type_info102 bool is_virtual() const { 103 return (__offset_flags & __virtual_mask) != 0; 104 } 105 is_public__base_class_type_info106 bool is_public() const { 107 return (__offset_flags & __public_mask) != 0; 108 } 109 110 // FIXME: Right-shift of signed integer is implementation dependent. 111 // GCC Implements it as signed (as we expect) offset__base_class_type_info112 long offset() const { 113 return __offset_flags >> __offset_shift; 114 } 115 flags__base_class_type_info116 long flags() const { 117 return __offset_flags & ((1 << __offset_shift) - 1); 118 } 119 }; 120 121 // Helper struct to support catch-clause match 122 struct __UpcastInfo { 123 enum ContainedStatus { 124 unknown = 0, 125 has_public_contained, 126 has_ambig_or_not_public 127 }; 128 129 ContainedStatus status; 130 const __class_type_info* base_type; 131 void* adjustedPtr; 132 unsigned int premier_flags; 133 bool nullobj_may_conflict; 134 135 __UpcastInfo(const __class_type_info* type); 136 }; 137 138 // Typeinfo for classes with no bases. 139 class __class_type_info : public __shim_type_info 140 { 141 public: 142 virtual ~__class_type_info(); 143 virtual bool can_catch(const __shim_type_info* thrown_type, 144 void*& adjustedPtr) const; 145 146 enum class_type_info_code { 147 CLASS_TYPE_INFO_CODE, 148 SI_CLASS_TYPE_INFO_CODE, 149 VMI_CLASS_TYPE_INFO_CODE 150 }; 151 152 virtual class_type_info_code code()153 code() const { return CLASS_TYPE_INFO_CODE; } 154 155 virtual bool walk_to(const __class_type_info* base_type, 156 void*& adjustedPtr, 157 __UpcastInfo& info) const; 158 159 protected: 160 bool self_class_type_match(const __class_type_info* base_type, 161 void*& adjustedPtr, 162 __UpcastInfo& info) const; 163 }; 164 165 // Typeinfo for classes containing only a single, public, non-virtual base at 166 // offset zero. 167 class __si_class_type_info : public __class_type_info 168 { 169 public: 170 virtual ~__si_class_type_info(); 171 const __class_type_info *__base_type; 172 173 virtual __class_type_info::class_type_info_code code()174 code() const { return SI_CLASS_TYPE_INFO_CODE; } 175 176 virtual bool walk_to(const __class_type_info* base_type, 177 void*& adjustedPtr, 178 __UpcastInfo& info) const; 179 }; 180 181 182 // Typeinfo for classes with bases that do not satisfy the 183 // __si_class_type_info constraints. 184 class __vmi_class_type_info : public __class_type_info 185 { 186 public: 187 virtual ~__vmi_class_type_info(); 188 unsigned int __flags; 189 unsigned int __base_count; 190 __base_class_type_info __base_info[1]; 191 192 enum __flags_masks { 193 __non_diamond_repeat_mask = 0x1, 194 __diamond_shaped_mask = 0x2, 195 }; 196 197 virtual __class_type_info::class_type_info_code code()198 code() const { return VMI_CLASS_TYPE_INFO_CODE; } 199 200 virtual bool walk_to(const __class_type_info* base_type, 201 void*& adjustedPtr, 202 __UpcastInfo& info) const; 203 }; 204 205 class __pbase_type_info : public __shim_type_info 206 { 207 public: 208 virtual ~__pbase_type_info(); 209 virtual bool can_catch(const __shim_type_info* thrown_type, 210 void*& adjustedPtr) const; 211 unsigned int __flags; 212 const __shim_type_info* __pointee; 213 214 enum __masks { 215 __const_mask = 0x1, 216 __volatile_mask = 0x2, 217 __restrict_mask = 0x4, 218 __incomplete_mask = 0x8, 219 __incomplete_class_mask = 0x10 220 }; 221 222 223 virtual bool can_catch_typeinfo_wrapper(const __shim_type_info* thrown_type, 224 void*& adjustedPtr, 225 unsigned tracker) const; 226 227 protected: 228 enum __constness_tracker_status { 229 first_time_init = 0x1, 230 keep_constness = 0x2, 231 after_gap = 0x4 // after one non-const qualified, 232 // we cannot face const again in future 233 }; 234 235 private: 236 bool can_catch_ptr(const __pbase_type_info *thrown_type, 237 void *&adjustedPtr, 238 unsigned tracker) const; 239 240 // Return true if making decision done. 241 virtual bool do_can_catch_ptr(const __pbase_type_info* thrown_type, 242 void*& adjustedPtr, 243 unsigned tracker, 244 bool& result) const = 0; 245 }; 246 247 class __pointer_type_info : public __pbase_type_info 248 { 249 public: 250 virtual ~__pointer_type_info(); 251 252 private: 253 virtual bool do_can_catch_ptr(const __pbase_type_info* thrown_type, 254 void*& adjustedPtr, 255 unsigned tracker, 256 bool& result) const; 257 }; 258 259 class __pointer_to_member_type_info : public __pbase_type_info 260 { 261 public: 262 __class_type_info* __context; 263 264 virtual ~__pointer_to_member_type_info(); 265 266 private: 267 virtual bool do_can_catch_ptr(const __pbase_type_info* thrown_type, 268 void*& adjustedPtr, 269 unsigned tracker, 270 bool& result) const; 271 }; 272 273 extern "C" { 274 275 // Compatible with GNU C++ 276 const uint64_t __gxx_exception_class = 0x474E5543432B2B00LL; // GNUCC++\0 277 278 struct __cxa_exception { 279 size_t referenceCount; 280 281 std::type_info* exceptionType; 282 void (*exceptionDestructor)(void*); 283 std::unexpected_handler unexpectedHandler; 284 std::terminate_handler terminateHandler; 285 __cxa_exception* nextException; 286 287 int handlerCount; 288 #ifdef __arm__ 289 /** 290 * ARM EHABI requires the unwind library to keep track of exceptions 291 * during cleanups. These support nesting, so we need to keep a list of 292 * them. 293 */ 294 __cxa_exception* nextCleanup; 295 int cleanupCount; 296 #endif 297 int handlerSwitchValue; 298 const uint8_t* actionRecord; 299 const uint8_t* languageSpecificData; 300 void* catchTemp; 301 void* adjustedPtr; 302 303 _Unwind_Exception unwindHeader; // must be last 304 }; 305 306 struct __cxa_eh_globals { 307 __cxa_exception* caughtExceptions; 308 unsigned int uncaughtExceptions; 309 #ifdef __arm__ 310 __cxa_exception* cleanupExceptions; 311 #endif 312 }; 313 314 } // extern "C" 315 } // namespace __cxxabiv1 316 317 namespace __gabixx { 318 319 // Default unexpected handler. 320 _GABIXX_NORETURN void __default_unexpected(void) _GABIXX_HIDDEN; 321 322 // Default terminate handler. 323 _GABIXX_NORETURN void __default_terminate(void) _GABIXX_HIDDEN; 324 325 // Call |handler| and if it returns, call __default_terminate. 326 _GABIXX_NORETURN void __terminate(std::terminate_handler handler) 327 _GABIXX_HIDDEN; 328 329 // Print a fatal error message to the log+stderr, then call 330 // std::terminate(). 331 _GABIXX_NORETURN void __fatal_error(const char* message) _GABIXX_HIDDEN; 332 333 } // __gabixx 334 335 #endif // _GABIXX_CXXABI_DEFINES_H 336