1ccec91a1Sjoerg /* 2ccec91a1Sjoerg * Copyright 2012 David Chisnall. All rights reserved. 3ccec91a1Sjoerg * 4ccec91a1Sjoerg * Permission is hereby granted, free of charge, to any person obtaining a copy 5ccec91a1Sjoerg * of this software and associated documentation files (the "Software"), to 6ccec91a1Sjoerg * deal in the Software without restriction, including without limitation the 7ccec91a1Sjoerg * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 8ccec91a1Sjoerg * sell copies of the Software, and to permit persons to whom the Software is 9ccec91a1Sjoerg * furnished to do so, subject to the following conditions: 10ccec91a1Sjoerg * 11ccec91a1Sjoerg * The above copyright notice and this permission notice shall be 12ccec91a1Sjoerg * included in all copies or substantial portions of the Software. 13ccec91a1Sjoerg * 14ccec91a1Sjoerg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15ccec91a1Sjoerg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16ccec91a1Sjoerg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17ccec91a1Sjoerg * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18ccec91a1Sjoerg * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19ccec91a1Sjoerg * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20ccec91a1Sjoerg * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21ccec91a1Sjoerg */ 22ccec91a1Sjoerg 23ccec91a1Sjoerg #ifndef __CXXABI_H_ 24ccec91a1Sjoerg #define __CXXABI_H_ 25d0b6b5d5Sjoerg #include <stddef.h> 26ccec91a1Sjoerg #include <stdint.h> 27ccec91a1Sjoerg #include "unwind.h" 28ccec91a1Sjoerg namespace std 29ccec91a1Sjoerg { 30ccec91a1Sjoerg class type_info; 31ccec91a1Sjoerg } 32ccec91a1Sjoerg /* 33ccec91a1Sjoerg * The cxxabi.h header provides a set of public definitions for types and 34ccec91a1Sjoerg * functions defined by the Itanium C++ ABI specification. For reference, see 35ccec91a1Sjoerg * the ABI specification here: 36ccec91a1Sjoerg * 37ccec91a1Sjoerg * http://sourcery.mentor.com/public/cxx-abi/abi.html 38ccec91a1Sjoerg * 39ccec91a1Sjoerg * All deviations from this specification, unless otherwise noted, are 40ccec91a1Sjoerg * accidental. 41ccec91a1Sjoerg */ 42ccec91a1Sjoerg 43ccec91a1Sjoerg #ifdef __cplusplus 44ccec91a1Sjoerg namespace __cxxabiv1 { 45ccec91a1Sjoerg extern "C" { 46ccec91a1Sjoerg #endif 47ccec91a1Sjoerg /** 48ccec91a1Sjoerg * Function type to call when an unexpected exception is encountered. 49ccec91a1Sjoerg */ 50ccec91a1Sjoerg typedef void (*unexpected_handler)(); 51ccec91a1Sjoerg /** 52ccec91a1Sjoerg * Function type to call when an unrecoverable condition is encountered. 53ccec91a1Sjoerg */ 54ccec91a1Sjoerg typedef void (*terminate_handler)(); 55ccec91a1Sjoerg 56ccec91a1Sjoerg 57ccec91a1Sjoerg /** 58ccec91a1Sjoerg * Structure used as a header on thrown exceptions. This is the same layout as 59ccec91a1Sjoerg * defined by the Itanium ABI spec, so should be interoperable with any other 60ccec91a1Sjoerg * implementation of this spec, such as GNU libsupc++. 61ccec91a1Sjoerg * 62ccec91a1Sjoerg * This structure is allocated when an exception is thrown. Unwinding happens 63ccec91a1Sjoerg * in two phases, the first looks for a handler and the second installs the 64ccec91a1Sjoerg * context. This structure stores a cache of the handler location between 65ccec91a1Sjoerg * phase 1 and phase 2. Unfortunately, cleanup information is not cached, so 66ccec91a1Sjoerg * must be looked up in both phases. This happens for two reasons. The first 67ccec91a1Sjoerg * is that we don't know how many frames containing cleanups there will be, and 68ccec91a1Sjoerg * we should avoid dynamic allocation during unwinding (the exception may be 69ccec91a1Sjoerg * reporting that we've run out of memory). The second is that finding 70ccec91a1Sjoerg * cleanups is much cheaper than finding handlers, because we don't have to 71ccec91a1Sjoerg * look at the type table at all. 72ccec91a1Sjoerg * 73ccec91a1Sjoerg * Note: Several fields of this structure have not-very-informative names. 74ccec91a1Sjoerg * These are taken from the ABI spec and have not been changed to make it 75ccec91a1Sjoerg * easier for people referring to to the spec while reading this code. 76ccec91a1Sjoerg */ 77ccec91a1Sjoerg struct __cxa_exception 78ccec91a1Sjoerg { 79ccec91a1Sjoerg #if __LP64__ 80ccec91a1Sjoerg /** 81ccec91a1Sjoerg * Reference count. Used to support the C++11 exception_ptr class. This 82ccec91a1Sjoerg * is prepended to the structure in 64-bit mode and squeezed in to the 83ccec91a1Sjoerg * padding left before the 64-bit aligned _Unwind_Exception at the end in 84ccec91a1Sjoerg * 32-bit mode. 85ccec91a1Sjoerg * 86ccec91a1Sjoerg * Note that it is safe to extend this structure at the beginning, rather 87ccec91a1Sjoerg * than the end, because the public API for creating it returns the address 88ccec91a1Sjoerg * of the end (where the exception object can be stored). 89ccec91a1Sjoerg */ 90ccec91a1Sjoerg uintptr_t referenceCount; 91ccec91a1Sjoerg #endif 92ccec91a1Sjoerg /** Type info for the thrown object. */ 93ccec91a1Sjoerg std::type_info *exceptionType; 94ccec91a1Sjoerg /** Destructor for the object, if one exists. */ 95ccec91a1Sjoerg void (*exceptionDestructor) (void *); 96ccec91a1Sjoerg /** Handler called when an exception specification is violated. */ 97ccec91a1Sjoerg unexpected_handler unexpectedHandler; 98ccec91a1Sjoerg /** Hander called to terminate. */ 99ccec91a1Sjoerg terminate_handler terminateHandler; 100ccec91a1Sjoerg /** 101ccec91a1Sjoerg * Next exception in the list. If an exception is thrown inside a catch 102ccec91a1Sjoerg * block and caught in a nested catch, this points to the exception that 103ccec91a1Sjoerg * will be handled after the inner catch block completes. 104ccec91a1Sjoerg */ 105ccec91a1Sjoerg __cxa_exception *nextException; 106ccec91a1Sjoerg /** 107ccec91a1Sjoerg * The number of handlers that currently have references to this 108ccec91a1Sjoerg * exception. The top (non-sign) bit of this is used as a flag to indicate 109ccec91a1Sjoerg * that the exception is being rethrown, so should not be deleted when its 110ccec91a1Sjoerg * handler count reaches 0 (which it doesn't with the top bit set). 111ccec91a1Sjoerg */ 112ccec91a1Sjoerg int handlerCount; 113*534cb174Sjoerg #if defined(__arm__) && !defined(__ARM_DWARF_EH__) 114ccec91a1Sjoerg /** 115ccec91a1Sjoerg * The ARM EH ABI requires the unwind library to keep track of exceptions 116ccec91a1Sjoerg * during cleanups. These support nesting, so we need to keep a list of 117ccec91a1Sjoerg * them. 118ccec91a1Sjoerg */ 119ccec91a1Sjoerg _Unwind_Exception *nextCleanup; 120ccec91a1Sjoerg /** 121ccec91a1Sjoerg * The number of cleanups that are currently being run on this exception. 122ccec91a1Sjoerg */ 123ccec91a1Sjoerg int cleanupCount; 124ccec91a1Sjoerg #endif 125ccec91a1Sjoerg /** 126ccec91a1Sjoerg * The selector value to be returned when installing the catch handler. 127ccec91a1Sjoerg * Used at the call site to determine which catch() block should execute. 128ccec91a1Sjoerg * This is found in phase 1 of unwinding then installed in phase 2. 129ccec91a1Sjoerg */ 130ccec91a1Sjoerg int handlerSwitchValue; 131ccec91a1Sjoerg /** 132ccec91a1Sjoerg * The action record for the catch. This is cached during phase 1 133ccec91a1Sjoerg * unwinding. 134ccec91a1Sjoerg */ 135ccec91a1Sjoerg const char *actionRecord; 136ccec91a1Sjoerg /** 137ccec91a1Sjoerg * Pointer to the language-specific data area (LSDA) for the handler 138ccec91a1Sjoerg * frame. This is unused in this implementation, but set for ABI 139ccec91a1Sjoerg * compatibility in case we want to mix code in very weird ways. 140ccec91a1Sjoerg */ 141ccec91a1Sjoerg const char *languageSpecificData; 142ccec91a1Sjoerg /** The cached landing pad for the catch handler.*/ 143ccec91a1Sjoerg void *catchTemp; 144ccec91a1Sjoerg /** 145ccec91a1Sjoerg * The pointer that will be returned as the pointer to the object. When 146ccec91a1Sjoerg * throwing a class and catching a virtual superclass (for example), we 147ccec91a1Sjoerg * need to adjust the thrown pointer to make it all work correctly. 148ccec91a1Sjoerg */ 149ccec91a1Sjoerg void *adjustedPtr; 150ccec91a1Sjoerg #if !__LP64__ 151ccec91a1Sjoerg /** 152ccec91a1Sjoerg * Reference count. Used to support the C++11 exception_ptr class. This 153ccec91a1Sjoerg * is prepended to the structure in 64-bit mode and squeezed in to the 154ccec91a1Sjoerg * padding left before the 64-bit aligned _Unwind_Exception at the end in 155ccec91a1Sjoerg * 32-bit mode. 156ccec91a1Sjoerg * 157ccec91a1Sjoerg * Note that it is safe to extend this structure at the beginning, rather 158ccec91a1Sjoerg * than the end, because the public API for creating it returns the address 159ccec91a1Sjoerg * of the end (where the exception object can be stored) 160ccec91a1Sjoerg */ 161ccec91a1Sjoerg uintptr_t referenceCount; 162ccec91a1Sjoerg #endif 163ccec91a1Sjoerg /** The language-agnostic part of the exception header. */ 164ccec91a1Sjoerg _Unwind_Exception unwindHeader; 165ccec91a1Sjoerg }; 166ccec91a1Sjoerg 167ccec91a1Sjoerg /** 168ccec91a1Sjoerg * ABI-specified globals structure. Returned by the __cxa_get_globals() 169ccec91a1Sjoerg * function and its fast variant. This is a per-thread structure - every 170ccec91a1Sjoerg * thread will have one lazily allocated. 171ccec91a1Sjoerg * 172ccec91a1Sjoerg * This structure is defined by the ABI, so may be used outside of this 173ccec91a1Sjoerg * library. 174ccec91a1Sjoerg */ 175ccec91a1Sjoerg struct __cxa_eh_globals 176ccec91a1Sjoerg { 177ccec91a1Sjoerg /** 178ccec91a1Sjoerg * A linked list of exceptions that are currently caught. There may be 179ccec91a1Sjoerg * several of these in nested catch() blocks. 180ccec91a1Sjoerg */ 181ccec91a1Sjoerg __cxa_exception *caughtExceptions; 182ccec91a1Sjoerg /** 183ccec91a1Sjoerg * The number of uncaught exceptions. 184ccec91a1Sjoerg */ 185ccec91a1Sjoerg unsigned int uncaughtExceptions; 186ccec91a1Sjoerg }; 187ccec91a1Sjoerg /** 188ccec91a1Sjoerg * ABI function returning the __cxa_eh_globals structure. 189ccec91a1Sjoerg */ 190ccec91a1Sjoerg __cxa_eh_globals *__cxa_get_globals(void); 191ccec91a1Sjoerg /** 192ccec91a1Sjoerg * Version of __cxa_get_globals() assuming that __cxa_get_globals() has already 193ccec91a1Sjoerg * been called at least once by this thread. 194ccec91a1Sjoerg */ 195ccec91a1Sjoerg __cxa_eh_globals *__cxa_get_globals_fast(void); 196ccec91a1Sjoerg 197ccec91a1Sjoerg std::type_info * __cxa_current_exception_type(); 198ccec91a1Sjoerg 199ccec91a1Sjoerg /** 200ccec91a1Sjoerg * Throws an exception returned by __cxa_current_primary_exception(). This 201ccec91a1Sjoerg * exception may have been caught in another thread. 202ccec91a1Sjoerg */ 203ccec91a1Sjoerg void __cxa_rethrow_primary_exception(void* thrown_exception); 204ccec91a1Sjoerg /** 205ccec91a1Sjoerg * Returns the current exception in a form that can be stored in an 206ccec91a1Sjoerg * exception_ptr object and then rethrown by a call to 207ccec91a1Sjoerg * __cxa_rethrow_primary_exception(). 208ccec91a1Sjoerg */ 209ccec91a1Sjoerg void *__cxa_current_primary_exception(void); 210ccec91a1Sjoerg /** 211ccec91a1Sjoerg * Increments the reference count of an exception. Called when an 212ccec91a1Sjoerg * exception_ptr is copied. 213ccec91a1Sjoerg */ 214ccec91a1Sjoerg void __cxa_increment_exception_refcount(void* thrown_exception); 215ccec91a1Sjoerg /** 216ccec91a1Sjoerg * Decrements the reference count of an exception. Called when an 217ccec91a1Sjoerg * exception_ptr is deleted. 218ccec91a1Sjoerg */ 219ccec91a1Sjoerg void __cxa_decrement_exception_refcount(void* thrown_exception); 220ccec91a1Sjoerg /** 221ccec91a1Sjoerg * Demangles a C++ symbol or type name. The buffer, if non-NULL, must be 222ccec91a1Sjoerg * allocated with malloc() and must be *n bytes or more long. This function 223ccec91a1Sjoerg * may call realloc() on the value pointed to by buf, and will return the 224ccec91a1Sjoerg * length of the string via *n. 225ccec91a1Sjoerg * 226ccec91a1Sjoerg * The value pointed to by status is set to one of the following: 227ccec91a1Sjoerg * 228ccec91a1Sjoerg * 0: success 229ccec91a1Sjoerg * -1: memory allocation failure 230ccec91a1Sjoerg * -2: invalid mangled name 231ccec91a1Sjoerg * -3: invalid arguments 232ccec91a1Sjoerg */ 233ccec91a1Sjoerg char* __cxa_demangle(const char* mangled_name, 234ccec91a1Sjoerg char* buf, 235ccec91a1Sjoerg size_t* n, 236ccec91a1Sjoerg int* status); 237ccec91a1Sjoerg #ifdef __cplusplus 238ccec91a1Sjoerg } // extern "C" 239ccec91a1Sjoerg } // namespace 240ccec91a1Sjoerg 241ccec91a1Sjoerg namespace abi = __cxxabiv1; 242ccec91a1Sjoerg 243ccec91a1Sjoerg #endif /* __cplusplus */ 244ccec91a1Sjoerg #endif /* __CXXABI_H_ */ 245