blob: 335baa3ad397cf55d57938534485e337a2400616 [file] [log] [blame]
// Copyright (C) 2013 The Android Open Source Project
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions
// are met:
// 1. Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// 3. Neither the name of the project nor the names of its contributors
// may be used to endorse or promote products derived from this software
// without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
// SUCH DAMAGE.
#ifndef _GABIXX_CXXABI_DEFINES_H
#define _GABIXX_CXXABI_DEFINES_H
#include <cxxabi.h>
#include <stdint.h>
// Internal declarations for the implementation of <cxxabi.h> and
// related headers.
namespace __cxxabiv1 {
// Derived types of type_info below are based on 2.9.5 of C++ ABI.
class __shim_type_info : public std::type_info
{
public:
virtual ~__shim_type_info();
virtual bool can_catch(const __shim_type_info* thrown_type,
void*& adjustedPtr) const = 0;
};
// Typeinfo for fundamental types.
class __fundamental_type_info : public __shim_type_info
{
public:
virtual ~__fundamental_type_info();
virtual bool can_catch(const __shim_type_info* thrown_type,
void*& adjustedPtr) const;
};
// Typeinfo for array types.
class __array_type_info : public __shim_type_info
{
public:
virtual ~__array_type_info();
virtual bool can_catch(const __shim_type_info* thrown_type,
void*& adjustedPtr) const;
};
// Typeinfo for function types.
class __function_type_info : public __shim_type_info
{
public:
virtual ~__function_type_info();
virtual bool can_catch(const __shim_type_info* thrown_type,
void*& adjustedPtr) const;
};
// Typeinfo for enum types.
class __enum_type_info : public __shim_type_info
{
public:
virtual ~__enum_type_info();
virtual bool can_catch(const __shim_type_info* thrown_type,
void*& adjustedPtr) const;
};
class __class_type_info;
// Used in __vmi_class_type_info
struct __base_class_type_info
{
public:
const __class_type_info *__base_type;
long __offset_flags;
enum __offset_flags_masks {
__virtual_mask = 0x1,
__public_mask = 0x2,
__offset_shift = 8 // lower 8 bits are flags
};
bool is_virtual() const {
return (__offset_flags & __virtual_mask) != 0;
}
bool is_public() const {
return (__offset_flags & __public_mask) != 0;
}
// FIXME: Right-shift of signed integer is implementation dependent.
// GCC Implements it as signed (as we expect)
long offset() const {
return __offset_flags >> __offset_shift;
}
long flags() const {
return __offset_flags & ((1 << __offset_shift) - 1);
}
};
// Helper struct to support catch-clause match
struct __UpcastInfo {
enum ContainedStatus {
unknown = 0,
has_public_contained,
has_ambig_or_not_public
};
ContainedStatus status;
const __class_type_info* base_type;
void* adjustedPtr;
unsigned int premier_flags;
bool nullobj_may_conflict;
__UpcastInfo(const __class_type_info* type);
};
// Typeinfo for classes with no bases.
class __class_type_info : public __shim_type_info
{
public:
virtual ~__class_type_info();
virtual bool can_catch(const __shim_type_info* thrown_type,
void*& adjustedPtr) const;
enum class_type_info_code {
CLASS_TYPE_INFO_CODE,
SI_CLASS_TYPE_INFO_CODE,
VMI_CLASS_TYPE_INFO_CODE
};
virtual class_type_info_code
code() const { return CLASS_TYPE_INFO_CODE; }
virtual bool walk_to(const __class_type_info* base_type,
void*& adjustedPtr,
__UpcastInfo& info) const;
protected:
bool self_class_type_match(const __class_type_info* base_type,
void*& adjustedPtr,
__UpcastInfo& info) const;
};
// Typeinfo for classes containing only a single, public, non-virtual base at
// offset zero.
class __si_class_type_info : public __class_type_info
{
public:
virtual ~__si_class_type_info();
const __class_type_info *__base_type;
virtual __class_type_info::class_type_info_code
code() const { return SI_CLASS_TYPE_INFO_CODE; }
virtual bool walk_to(const __class_type_info* base_type,
void*& adjustedPtr,
__UpcastInfo& info) const;
};
// Typeinfo for classes with bases that do not satisfy the
// __si_class_type_info constraints.
class __vmi_class_type_info : public __class_type_info
{
public:
virtual ~__vmi_class_type_info();
unsigned int __flags;
unsigned int __base_count;
__base_class_type_info __base_info[1];
enum __flags_masks {
__non_diamond_repeat_mask = 0x1,
__diamond_shaped_mask = 0x2,
};
virtual __class_type_info::class_type_info_code
code() const { return VMI_CLASS_TYPE_INFO_CODE; }
virtual bool walk_to(const __class_type_info* base_type,
void*& adjustedPtr,
__UpcastInfo& info) const;
};
class __pbase_type_info : public __shim_type_info
{
public:
virtual ~__pbase_type_info();
virtual bool can_catch(const __shim_type_info* thrown_type,
void*& adjustedPtr) const;
unsigned int __flags;
const __shim_type_info* __pointee;
enum __masks {
__const_mask = 0x1,
__volatile_mask = 0x2,
__restrict_mask = 0x4,
__incomplete_mask = 0x8,
__incomplete_class_mask = 0x10
};
virtual bool can_catch_typeinfo_wrapper(const __shim_type_info* thrown_type,
void*& adjustedPtr,
unsigned tracker) const;
protected:
enum __constness_tracker_status {
first_time_init = 0x1,
keep_constness = 0x2,
after_gap = 0x4 // after one non-const qualified,
// we cannot face const again in future
};
private:
bool can_catch_ptr(const __pbase_type_info *thrown_type,
void *&adjustedPtr,
unsigned tracker) const;
// Return true if making decision done.
virtual bool do_can_catch_ptr(const __pbase_type_info* thrown_type,
void*& adjustedPtr,
unsigned tracker,
bool& result) const = 0;
};
class __pointer_type_info : public __pbase_type_info
{
public:
virtual ~__pointer_type_info();
private:
virtual bool do_can_catch_ptr(const __pbase_type_info* thrown_type,
void*& adjustedPtr,
unsigned tracker,
bool& result) const;
};
class __pointer_to_member_type_info : public __pbase_type_info
{
public:
__class_type_info* __context;
virtual ~__pointer_to_member_type_info();
private:
virtual bool do_can_catch_ptr(const __pbase_type_info* thrown_type,
void*& adjustedPtr,
unsigned tracker,
bool& result) const;
};
extern "C" {
// Compatible with GNU C++
const uint64_t __gxx_exception_class = 0x474E5543432B2B00LL; // GNUCC++\0
struct __cxa_exception {
size_t referenceCount;
std::type_info* exceptionType;
void (*exceptionDestructor)(void*);
std::unexpected_handler unexpectedHandler;
std::terminate_handler terminateHandler;
__cxa_exception* nextException;
int handlerCount;
#ifdef __arm__
/**
* ARM EHABI requires the unwind library to keep track of exceptions
* during cleanups. These support nesting, so we need to keep a list of
* them.
*/
__cxa_exception* nextCleanup;
int cleanupCount;
#endif
int handlerSwitchValue;
const uint8_t* actionRecord;
const uint8_t* languageSpecificData;
void* catchTemp;
void* adjustedPtr;
_Unwind_Exception unwindHeader; // must be last
};
struct __cxa_eh_globals {
__cxa_exception* caughtExceptions;
unsigned int uncaughtExceptions;
#ifdef __arm__
__cxa_exception* cleanupExceptions;
#endif
};
} // extern "C"
} // namespace __cxxabiv1
namespace __gabixx {
// Default unexpected handler.
_GABIXX_NORETURN void __default_unexpected(void) _GABIXX_HIDDEN;
// Default terminate handler.
_GABIXX_NORETURN void __default_terminate(void) _GABIXX_HIDDEN;
// Call |handler| and if it returns, call __default_terminate.
_GABIXX_NORETURN void __terminate(std::terminate_handler handler)
_GABIXX_HIDDEN;
// Print a fatal error message to the log+stderr, then call
// std::terminate().
_GABIXX_NORETURN void __fatal_error(const char* message) _GABIXX_HIDDEN;
} // __gabixx
#endif // _GABIXX_CXXABI_DEFINES_H