Usermode/libc++ - Debug in cxa code, list emplace and iterators, general STL fixes
[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         {
81                 const ::std::exception* e = reinterpret_cast<const ::std::exception*>(thrown_exception);
82                 ::_SysDebug("- e.what() = '%s'", e->what());
83         }
84         ::_SysDebug("- typeid(*tinfo) = %p", &typeid(*tinfo));
85
86         __cxa_exception *except = static_cast<__cxa_exception*>( thrown_exception ) - 1;
87         
88         except->unexpectedHandler = 0;
89         except->terminateHandler = 0;
90         except->exceptionType = tinfo;
91         except->exceptionDestructor = dest;
92         memcpy(&except->unwindHeader.exception_class, "Ac20C++\0", 8);
93         __cxa_get_globals()->uncaughtExceptions ++;
94         
95         _Unwind_RaiseException(thrown_exception);
96         
97         ::_SysDebug("__cxa_throw(%p,%s) :: UNCAUGHT", thrown_exception, tinfo->name());
98         ::std::terminate();
99 }
100
101 extern "C" void *__cxa_begin_catch(void *exceptionObject)
102 {
103         ::_SysDebug("__cxa_begin_catch(%p)", exceptionObject);
104         __cxa_exception *except = static_cast<__cxa_exception*>( exceptionObject ) - 1;
105         
106         except->handlerCount ++;
107         
108         except->nextException = __cxa_get_globals()->caughtExceptions;
109         __cxa_get_globals()->caughtExceptions = except;
110         
111         __cxa_get_globals_fast()->uncaughtExceptions --;
112         
113         return except;
114 }
115
116 extern "C" void __cxa_end_catch()
117 {
118         struct __cxa_exception  *except = __cxa_get_globals()->caughtExceptions;
119         ::_SysDebug("__cxa_end_catch - %p", except);
120         except->handlerCount --;
121         __cxa_get_globals()->caughtExceptions = except->nextException;
122         
123         if( except->handlerCount == 0 ) {
124                 __cxa_free_exception(except+1);
125         }
126 }
127

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