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 /*__thread*/ struct __cxa_eh_globals {
27 __cxa_exception *caughtExceptions;
28 unsigned int uncaughtExceptions;
34 } emergency_exception;
35 /*__thread*/ bool emergency_exception_used;
37 static bool TEST_AND_SET(bool& flag) {
44 extern "C" __cxa_eh_globals *__cxa_get_globals(void)
48 extern "C" __cxa_eh_globals *__cxa_get_globals_fast(void)
52 extern "C" void __cxa_call_unexpected(void *)
54 // An unexpected exception was thrown from a function that lists its possible exceptions
55 _SysDebug("__cxa_call_unexpected - TODO");
59 extern "C" void *__cxa_allocate_exception(size_t thrown_size)
61 ::_SysDebug("__cxa_allocate_exception(%i)", thrown_size);
62 __cxa_exception *ret = static_cast<__cxa_exception*>( malloc( sizeof(__cxa_exception) + thrown_size ) );
64 if( thrown_size <= sizeof(emergency_exception.buf) && TEST_AND_SET(emergency_exception_used) )
66 ret = &emergency_exception.info;
70 _SysDebug("__cxa_allocate_exception - No free space");
73 ::_SysDebug("__cxa_allocate_exception: return %p", ret+1);
77 extern "C" void __cxa_free_exception(void *thrown_exception)
79 ::_SysDebug("__cxa_free_exception(%p)", thrown_exception);
80 if(thrown_exception == &emergency_exception.buf) {
81 //assert(emergency_exception_used);
82 emergency_exception_used = false;
85 __cxa_exception *except = static_cast<__cxa_exception*>( thrown_exception ) - 1;
90 extern "C" void __cxa_throw(void *thrown_exception, std::type_info *tinfo, void (*dest)(void*))
92 ::_SysDebug("__cxa_throw(%p,%p,%p) '%s' by %p",
93 thrown_exception, tinfo, dest, tinfo->name(), __builtin_return_address(0)
96 const ::std::exception* e = reinterpret_cast<const ::std::exception*>(thrown_exception);
97 ::_SysDebug("- e.what() = '%s'", e->what());
100 __cxa_exception *except = static_cast<__cxa_exception*>( thrown_exception ) - 1;
102 except->unexpectedHandler = 0;
103 except->terminateHandler = 0;
104 except->exceptionType = tinfo;
105 except->exceptionDestructor = dest;
106 memcpy(&except->unwindHeader.exception_class, EXCEPTION_CLASS_ACESS, 8);
107 __cxa_get_globals()->uncaughtExceptions ++;
109 int rv = _Unwind_RaiseException( &except->unwindHeader );
111 ::_SysDebug("__cxa_throw(%p,%s) :: UNCAUGHT %i", thrown_exception, tinfo->name(), rv);
115 extern "C" void *__cxa_begin_catch(_Unwind_Exception *exceptionObject)
117 __cxa_exception *except = reinterpret_cast<__cxa_exception*>( exceptionObject+1 )-1;
118 ::_SysDebug("__cxa_begin_catch(%p) - except=%p", exceptionObject, except);
120 except->handlerCount ++;
122 except->nextException = __cxa_get_globals()->caughtExceptions;
123 __cxa_get_globals()->caughtExceptions = except;
125 __cxa_get_globals_fast()->uncaughtExceptions --;
130 extern "C" void __cxa_end_catch()
132 struct __cxa_exception *except = __cxa_get_globals()->caughtExceptions;
133 ::_SysDebug("__cxa_end_catch - %p", except);
134 except->handlerCount --;
135 __cxa_get_globals()->caughtExceptions = except->nextException;
137 if( except->handlerCount == 0 ) {
138 __cxa_free_exception(except+1);