d5a221954937614daf69b5935fec2bcbef9a29f9
[tpg/acess2.git] / Usermode / Libraries / libc++.so_src / exception_handling.cc
1 /*
2  */
3 #include <typeinfo>
4 #include <cstdint>
5 #include <cstddef>
6 #include <cstdlib>
7 #include <cstring>
8 #include <exception>
9 #include "exception_handling.h"
10
11 #include <acess/sys.h>
12
13 /*__thread*/ struct __cxa_eh_globals {
14         __cxa_exception *caughtExceptions;
15         unsigned  int   uncaughtExceptions;
16 } eh_globals;
17
18 /*__thread*/ struct {
19         __cxa_exception info;
20         char    buf[32];
21 } emergency_exception;
22 /*__thread*/ bool       emergency_exception_used;
23
24 static bool TEST_AND_SET(bool& flag) {
25         bool ret = flag;
26         flag = true;
27         return ret;
28 }
29
30 // === CODE ===
31 extern "C" __cxa_eh_globals *__cxa_get_globals(void)
32 {
33         return &eh_globals;
34 }
35 extern "C" __cxa_eh_globals *__cxa_get_globals_fast(void)
36 {
37         return &eh_globals;
38 }
39 extern "C" void __cxa_call_unexpected(void *)
40 {
41         // An unexpected exception was thrown from a function that lists its possible exceptions
42         _SysDebug("__cxa_call_unexpected - TODO");
43         for(;;);
44 }
45
46 extern "C" void *__cxa_allocate_exception(size_t thrown_size)
47 {
48         ::_SysDebug("__cxa_allocate_exception(%i)", thrown_size);
49         __cxa_exception *ret = static_cast<__cxa_exception*>( malloc( sizeof(__cxa_exception) + thrown_size ) );
50         if( !ret ) {
51                 if( thrown_size <= sizeof(emergency_exception.buf) && TEST_AND_SET(emergency_exception_used) )
52                 {
53                         ret = &emergency_exception.info;
54                 }
55         }
56         if( !ret ) {
57                 _SysDebug("__cxa_allocate_exception - No free space");
58                 ::std::terminate();
59         }
60         ::_SysDebug("__cxa_allocate_exception: return %p", ret+1);
61         return ret + 1;
62 }
63
64 extern "C" void __cxa_free_exception(void *thrown_exception)
65 {
66         ::_SysDebug("__cxa_free_exception(%p)", thrown_exception);
67         if(thrown_exception == &emergency_exception.buf) {
68                 //assert(emergency_exception_used);
69                 emergency_exception_used = false;
70         }
71         else {
72                 __cxa_exception *except = static_cast<__cxa_exception*>( thrown_exception ) - 1;
73                 free(except);
74         }
75 }
76
77 extern "C" void __cxa_throw(void *thrown_exception, std::type_info *tinfo, void (*dest)(void*))
78 {
79         ::_SysDebug("__cxa_throw(%p,%p,%p) '%s'", thrown_exception, tinfo, dest, tinfo->name());
80         ::_SysDebug("- by %p", __builtin_return_address(0));
81         {
82                 const ::std::exception* e = reinterpret_cast<const ::std::exception*>(thrown_exception);
83                 ::_SysDebug("- e.what() = '%s'", e->what());
84         }
85         ::_SysDebug("- typeid(*tinfo) = %p", &typeid(*tinfo));
86
87         __cxa_exception *except = static_cast<__cxa_exception*>( thrown_exception ) - 1;
88         
89         except->unexpectedHandler = 0;
90         except->terminateHandler = 0;
91         except->exceptionType = tinfo;
92         except->exceptionDestructor = dest;
93         memcpy(&except->unwindHeader.exception_class, "Ac20C++\0", 8);
94         __cxa_get_globals()->uncaughtExceptions ++;
95         
96         int rv = _Unwind_RaiseException(thrown_exception);
97         
98         ::_SysDebug("__cxa_throw(%p,%s) :: UNCAUGHT %i", thrown_exception, tinfo->name(), rv);
99         ::std::terminate();
100 }
101
102 extern "C" void *__cxa_begin_catch(void *exceptionObject)
103 {
104         ::_SysDebug("__cxa_begin_catch(%p)", exceptionObject);
105         __cxa_exception *except = static_cast<__cxa_exception*>( exceptionObject ) - 1;
106         
107         except->handlerCount ++;
108         
109         except->nextException = __cxa_get_globals()->caughtExceptions;
110         __cxa_get_globals()->caughtExceptions = except;
111         
112         __cxa_get_globals_fast()->uncaughtExceptions --;
113         
114         return except;
115 }
116
117 extern "C" void __cxa_end_catch()
118 {
119         struct __cxa_exception  *except = __cxa_get_globals()->caughtExceptions;
120         ::_SysDebug("__cxa_end_catch - %p", except);
121         except->handlerCount --;
122         __cxa_get_globals()->caughtExceptions = except->nextException;
123         
124         if( except->handlerCount == 0 ) {
125                 __cxa_free_exception(except+1);
126         }
127 }
128

UCC git Repository :: git.ucc.asn.au