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 37namespace __cxxabiv1 { 38 39// Derived types of type_info below are based on 2.9.5 of C++ ABI. 40 41class __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. 50class __fundamental_type_info : public __shim_type_info 51{ 52public: 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. 59class __array_type_info : public __shim_type_info 60{ 61public: 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. 68class __function_type_info : public __shim_type_info 69{ 70public: 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. 77class __enum_type_info : public __shim_type_info 78{ 79public: 80 virtual ~__enum_type_info(); 81 virtual bool can_catch(const __shim_type_info* thrown_type, 82 void*& adjustedPtr) const; 83}; 84 85 86class __class_type_info; 87 88// Used in __vmi_class_type_info 89struct __base_class_type_info 90{ 91public: 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 102 bool is_virtual() const { 103 return (__offset_flags & __virtual_mask) != 0; 104 } 105 106 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) 112 long offset() const { 113 return __offset_flags >> __offset_shift; 114 } 115 116 long flags() const { 117 return __offset_flags & ((1 << __offset_shift) - 1); 118 } 119}; 120 121// Helper struct to support catch-clause match 122struct __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. 139class __class_type_info : public __shim_type_info 140{ 141public: 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 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 159protected: 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. 167class __si_class_type_info : public __class_type_info 168{ 169public: 170 virtual ~__si_class_type_info(); 171 const __class_type_info *__base_type; 172 173 virtual __class_type_info::class_type_info_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. 184class __vmi_class_type_info : public __class_type_info 185{ 186public: 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 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 205class __pbase_type_info : public __shim_type_info 206{ 207public: 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 227protected: 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 235private: 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 247class __pointer_type_info : public __pbase_type_info 248{ 249public: 250 virtual ~__pointer_type_info(); 251 252private: 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 259class __pointer_to_member_type_info : public __pbase_type_info 260{ 261public: 262 __class_type_info* __context; 263 264 virtual ~__pointer_to_member_type_info(); 265 266private: 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 273extern "C" { 274 275// Compatible with GNU C++ 276const uint64_t __gxx_exception_class = 0x474E5543432B2B00LL; // GNUCC++\0 277 278struct __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 306struct __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 317namespace __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