1232922Stheraven/* 2232922Stheraven * Copyright 2012 David Chisnall. All rights reserved. 3232922Stheraven * 4232922Stheraven * Permission is hereby granted, free of charge, to any person obtaining a copy 5232922Stheraven * of this software and associated documentation files (the "Software"), to 6232922Stheraven * deal in the Software without restriction, including without limitation the 7232922Stheraven * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8232922Stheraven * sell copies of the Software, and to permit persons to whom the Software is 9232922Stheraven * furnished to do so, subject to the following conditions: 10232922Stheraven * 11232922Stheraven * The above copyright notice and this permission notice shall be 12232922Stheraven * included in all copies or substantial portions of the Software. 13232922Stheraven * 14232922Stheraven * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15232922Stheraven * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16232922Stheraven * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17232922Stheraven * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18232922Stheraven * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19232922Stheraven * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20232922Stheraven * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21232922Stheraven */ 22232922Stheraven 23227825Stheraven#ifndef __CXXABI_H_ 24227825Stheraven#define __CXXABI_H_ 25276375Sdim#include <stddef.h> 26227825Stheraven#include <stdint.h> 27227972Stheraven#include "unwind.h" 28227825Stheravennamespace std 29227825Stheraven{ 30227825Stheraven class type_info; 31227825Stheraven} 32227825Stheraven/* 33227825Stheraven * The cxxabi.h header provides a set of public definitions for types and 34227825Stheraven * functions defined by the Itanium C++ ABI specification. For reference, see 35227825Stheraven * the ABI specification here: 36227825Stheraven * 37227825Stheraven * http://sourcery.mentor.com/public/cxx-abi/abi.html 38227825Stheraven * 39227825Stheraven * All deviations from this specification, unless otherwise noted, are 40227825Stheraven * accidental. 41227825Stheraven */ 42227825Stheraven 43227825Stheraven#ifdef __cplusplus 44227825Stheravennamespace __cxxabiv1 { 45227825Stheravenextern "C" { 46227825Stheraven#endif 47227825Stheraven/** 48227825Stheraven * Function type to call when an unexpected exception is encountered. 49227825Stheraven */ 50227825Stheraventypedef void (*unexpected_handler)(); 51227825Stheraven/** 52227825Stheraven * Function type to call when an unrecoverable condition is encountered. 53227825Stheraven */ 54227825Stheraventypedef void (*terminate_handler)(); 55227825Stheraven 56227825Stheraven 57227825Stheraven/** 58227825Stheraven * Structure used as a header on thrown exceptions. This is the same layout as 59227825Stheraven * defined by the Itanium ABI spec, so should be interoperable with any other 60227825Stheraven * implementation of this spec, such as GNU libsupc++. 61227825Stheraven * 62227825Stheraven * This structure is allocated when an exception is thrown. Unwinding happens 63227825Stheraven * in two phases, the first looks for a handler and the second installs the 64227825Stheraven * context. This structure stores a cache of the handler location between 65227825Stheraven * phase 1 and phase 2. Unfortunately, cleanup information is not cached, so 66227825Stheraven * must be looked up in both phases. This happens for two reasons. The first 67227825Stheraven * is that we don't know how many frames containing cleanups there will be, and 68227825Stheraven * we should avoid dynamic allocation during unwinding (the exception may be 69227825Stheraven * reporting that we've run out of memory). The second is that finding 70227825Stheraven * cleanups is much cheaper than finding handlers, because we don't have to 71227825Stheraven * look at the type table at all. 72227825Stheraven * 73227825Stheraven * Note: Several fields of this structure have not-very-informative names. 74227825Stheraven * These are taken from the ABI spec and have not been changed to make it 75227825Stheraven * easier for people referring to to the spec while reading this code. 76227825Stheraven */ 77227825Stheravenstruct __cxa_exception 78227825Stheraven{ 79227825Stheraven#if __LP64__ 80227825Stheraven /** 81227825Stheraven * Reference count. Used to support the C++11 exception_ptr class. This 82227825Stheraven * is prepended to the structure in 64-bit mode and squeezed in to the 83227825Stheraven * padding left before the 64-bit aligned _Unwind_Exception at the end in 84227825Stheraven * 32-bit mode. 85227825Stheraven * 86227825Stheraven * Note that it is safe to extend this structure at the beginning, rather 87227825Stheraven * than the end, because the public API for creating it returns the address 88227825Stheraven * of the end (where the exception object can be stored). 89227825Stheraven */ 90227825Stheraven uintptr_t referenceCount; 91227825Stheraven#endif 92227825Stheraven /** Type info for the thrown object. */ 93227825Stheraven std::type_info *exceptionType; 94227825Stheraven /** Destructor for the object, if one exists. */ 95227825Stheraven void (*exceptionDestructor) (void *); 96227825Stheraven /** Handler called when an exception specification is violated. */ 97227825Stheraven unexpected_handler unexpectedHandler; 98227825Stheraven /** Hander called to terminate. */ 99227825Stheraven terminate_handler terminateHandler; 100227825Stheraven /** 101227825Stheraven * Next exception in the list. If an exception is thrown inside a catch 102227825Stheraven * block and caught in a nested catch, this points to the exception that 103227825Stheraven * will be handled after the inner catch block completes. 104227825Stheraven */ 105227825Stheraven __cxa_exception *nextException; 106227825Stheraven /** 107227825Stheraven * The number of handlers that currently have references to this 108227825Stheraven * exception. The top (non-sign) bit of this is used as a flag to indicate 109227825Stheraven * that the exception is being rethrown, so should not be deleted when its 110227825Stheraven * handler count reaches 0 (which it doesn't with the top bit set). 111227825Stheraven */ 112227825Stheraven int handlerCount; 113276375Sdim#if defined(__arm__) && !defined(__ARM_DWARF_EH__) 114227825Stheraven /** 115227972Stheraven * The ARM EH ABI requires the unwind library to keep track of exceptions 116227972Stheraven * during cleanups. These support nesting, so we need to keep a list of 117227972Stheraven * them. 118227972Stheraven */ 119227972Stheraven _Unwind_Exception *nextCleanup; 120227972Stheraven /** 121227972Stheraven * The number of cleanups that are currently being run on this exception. 122227972Stheraven */ 123227972Stheraven int cleanupCount; 124227972Stheraven#endif 125227972Stheraven /** 126227825Stheraven * The selector value to be returned when installing the catch handler. 127227825Stheraven * Used at the call site to determine which catch() block should execute. 128227825Stheraven * This is found in phase 1 of unwinding then installed in phase 2. 129227825Stheraven */ 130227825Stheraven int handlerSwitchValue; 131227825Stheraven /** 132227825Stheraven * The action record for the catch. This is cached during phase 1 133227825Stheraven * unwinding. 134227825Stheraven */ 135227825Stheraven const char *actionRecord; 136227825Stheraven /** 137227825Stheraven * Pointer to the language-specific data area (LSDA) for the handler 138227825Stheraven * frame. This is unused in this implementation, but set for ABI 139227825Stheraven * compatibility in case we want to mix code in very weird ways. 140227825Stheraven */ 141227825Stheraven const char *languageSpecificData; 142227825Stheraven /** The cached landing pad for the catch handler.*/ 143227825Stheraven void *catchTemp; 144227825Stheraven /** 145227825Stheraven * The pointer that will be returned as the pointer to the object. When 146227825Stheraven * throwing a class and catching a virtual superclass (for example), we 147227825Stheraven * need to adjust the thrown pointer to make it all work correctly. 148227825Stheraven */ 149227825Stheraven void *adjustedPtr; 150227825Stheraven#if !__LP64__ 151227825Stheraven /** 152227825Stheraven * Reference count. Used to support the C++11 exception_ptr class. This 153227825Stheraven * is prepended to the structure in 64-bit mode and squeezed in to the 154227825Stheraven * padding left before the 64-bit aligned _Unwind_Exception at the end in 155227825Stheraven * 32-bit mode. 156227825Stheraven * 157227825Stheraven * Note that it is safe to extend this structure at the beginning, rather 158227825Stheraven * than the end, because the public API for creating it returns the address 159227825Stheraven * of the end (where the exception object can be stored) 160227825Stheraven */ 161227825Stheraven uintptr_t referenceCount; 162227825Stheraven#endif 163227825Stheraven /** The language-agnostic part of the exception header. */ 164227825Stheraven _Unwind_Exception unwindHeader; 165227825Stheraven}; 166227825Stheraven 167227825Stheraven/** 168227825Stheraven * ABI-specified globals structure. Returned by the __cxa_get_globals() 169227825Stheraven * function and its fast variant. This is a per-thread structure - every 170227825Stheraven * thread will have one lazily allocated. 171227825Stheraven * 172227825Stheraven * This structure is defined by the ABI, so may be used outside of this 173227825Stheraven * library. 174227825Stheraven */ 175227825Stheravenstruct __cxa_eh_globals 176227825Stheraven{ 177227825Stheraven /** 178227825Stheraven * A linked list of exceptions that are currently caught. There may be 179227825Stheraven * several of these in nested catch() blocks. 180227825Stheraven */ 181227825Stheraven __cxa_exception *caughtExceptions; 182227825Stheraven /** 183227825Stheraven * The number of uncaught exceptions. 184227825Stheraven */ 185227825Stheraven unsigned int uncaughtExceptions; 186227825Stheraven}; 187227825Stheraven/** 188227825Stheraven * ABI function returning the __cxa_eh_globals structure. 189227825Stheraven */ 190227825Stheraven__cxa_eh_globals *__cxa_get_globals(void); 191227825Stheraven/** 192227825Stheraven * Version of __cxa_get_globals() assuming that __cxa_get_globals() has already 193227825Stheraven * been called at least once by this thread. 194227825Stheraven */ 195227825Stheraven__cxa_eh_globals *__cxa_get_globals_fast(void); 196227825Stheraven 197253145Stheravenstd::type_info * __cxa_current_exception_type(); 198253145Stheraven 199227825Stheraven/** 200227825Stheraven * Throws an exception returned by __cxa_current_primary_exception(). This 201227825Stheraven * exception may have been caught in another thread. 202227825Stheraven */ 203227825Stheravenvoid __cxa_rethrow_primary_exception(void* thrown_exception); 204227825Stheraven/** 205227825Stheraven * Returns the current exception in a form that can be stored in an 206227825Stheraven * exception_ptr object and then rethrown by a call to 207227825Stheraven * __cxa_rethrow_primary_exception(). 208227825Stheraven */ 209227825Stheravenvoid *__cxa_current_primary_exception(void); 210227825Stheraven/** 211227825Stheraven * Increments the reference count of an exception. Called when an 212227825Stheraven * exception_ptr is copied. 213227825Stheraven */ 214227825Stheravenvoid __cxa_increment_exception_refcount(void* thrown_exception); 215227825Stheraven/** 216227825Stheraven * Decrements the reference count of an exception. Called when an 217227825Stheraven * exception_ptr is deleted. 218227825Stheraven */ 219227825Stheravenvoid __cxa_decrement_exception_refcount(void* thrown_exception); 220227825Stheraven/** 221227825Stheraven * Demangles a C++ symbol or type name. The buffer, if non-NULL, must be 222227825Stheraven * allocated with malloc() and must be *n bytes or more long. This function 223227825Stheraven * may call realloc() on the value pointed to by buf, and will return the 224227825Stheraven * length of the string via *n. 225227825Stheraven * 226227825Stheraven * The value pointed to by status is set to one of the following: 227227825Stheraven * 228227825Stheraven * 0: success 229227825Stheraven * -1: memory allocation failure 230227825Stheraven * -2: invalid mangled name 231227825Stheraven * -3: invalid arguments 232227825Stheraven */ 233227825Stheravenchar* __cxa_demangle(const char* mangled_name, 234227825Stheraven char* buf, 235227825Stheraven size_t* n, 236227825Stheraven int* status); 237227825Stheraven#ifdef __cplusplus 238227825Stheraven} // extern "C" 239227825Stheraven} // namespace 240227825Stheraven 241227825Stheravennamespace abi = __cxxabiv1; 242227825Stheraven 243227825Stheraven#endif /* __cplusplus */ 244227825Stheraven#endif /* __CXXABI_H_ */ 245