Home | History | Annotate | Download | only in src
      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 
    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
    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
    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
    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
    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