2 * Acess2 C++ Support Library
3 * - By John Hodge (thePowersGang)
5 * exception_handling.cc
6 * - Exception handling code (defined by C++ ABI)
9 * - LLVM Exception handling
10 * > http://llvm.org/docs/ExceptionHandling.html
12 * >http://mentorembedded.github.io/cxx-abi/abi-eh.html
13 * - HP's "aC++" Document, Ch 7 "Exception Handling Tables"
14 * > http://mentorembedded.github.io/cxx-abi/exceptions.pdf
22 #include "exception_handling_cxxabi.h"
24 #include <acess/sys.h>
26 #define DEBUG_ENABLED 1
29 # define DEBUG(v...) ::_SysDebug(v)
31 # define DEBUG(v...) do{}while(0)
34 /*__thread*/ struct __cxa_eh_globals {
35 __cxa_exception *caughtExceptions;
36 unsigned int uncaughtExceptions;
42 } emergency_exception;
43 /*__thread*/ bool emergency_exception_used;
45 static bool TEST_AND_SET(bool& flag) {
52 extern "C" __cxa_eh_globals *__cxa_get_globals(void)
56 extern "C" __cxa_eh_globals *__cxa_get_globals_fast(void)
60 extern "C" void __cxa_call_unexpected(void *)
62 // An unexpected exception was thrown from a function that lists its possible exceptions
63 _SysDebug("__cxa_call_unexpected - TODO");
67 extern "C" void *__cxa_allocate_exception(size_t thrown_size)
69 DEBUG("__cxa_allocate_exception(%i)", thrown_size);
70 __cxa_exception *ret = static_cast<__cxa_exception*>( malloc( sizeof(__cxa_exception) + thrown_size ) );
72 if( thrown_size <= sizeof(emergency_exception.buf) && TEST_AND_SET(emergency_exception_used) )
74 ret = &emergency_exception.info;
78 _SysDebug("__cxa_allocate_exception - No free space");
81 DEBUG("__cxa_allocate_exception: return %p", ret+1);
85 extern "C" void __cxa_free_exception(void *thrown_exception)
87 DEBUG("__cxa_free_exception(%p)", thrown_exception);
88 if(thrown_exception == &emergency_exception.buf) {
89 //assert(emergency_exception_used);
90 emergency_exception_used = false;
93 __cxa_exception *except = static_cast<__cxa_exception*>( thrown_exception ) - 1;
98 extern "C" void __cxa_throw(void *thrown_exception, std::type_info *tinfo, void (*dest)(void*))
101 DEBUG("__cxa_throw(%p,%p,%p) '%s' by %p",
102 thrown_exception, tinfo, dest, tinfo->name(), __builtin_return_address(0)
105 const ::std::exception* e = reinterpret_cast<const ::std::exception*>(thrown_exception);
106 DEBUG("- e.what() = '%s'", e->what());
110 __cxa_exception *except = static_cast<__cxa_exception*>( thrown_exception ) - 1;
112 except->unexpectedHandler = 0;
113 except->terminateHandler = 0;
114 except->exceptionType = tinfo;
115 except->exceptionDestructor = dest;
116 memcpy(&except->unwindHeader.exception_class, EXCEPTION_CLASS_ACESS, 8);
117 __cxa_get_globals()->uncaughtExceptions ++;
119 int rv = _Unwind_RaiseException( &except->unwindHeader );
121 ::_SysDebug("__cxa_throw(%p,%s) :: UNCAUGHT %i", thrown_exception, tinfo->name(), rv);
125 extern "C" void *__cxa_begin_catch(_Unwind_Exception *exceptionObject)
127 __cxa_exception *except = reinterpret_cast<__cxa_exception*>( exceptionObject+1 )-1;
128 DEBUG("__cxa_begin_catch(%p) - except=%p", exceptionObject, except);
130 except->handlerCount ++;
132 except->nextException = __cxa_get_globals()->caughtExceptions;
133 __cxa_get_globals()->caughtExceptions = except;
135 __cxa_get_globals_fast()->uncaughtExceptions --;
140 extern "C" void __cxa_end_catch()
142 struct __cxa_exception *except = __cxa_get_globals()->caughtExceptions;
143 DEBUG("__cxa_end_catch - %p", except);
144 except->handlerCount --;
145 __cxa_get_globals()->caughtExceptions = except->nextException;
147 if( except->handlerCount == 0 ) {
148 __cxa_free_exception(except+1);