1 /*
2 * modified by Nintendo, NOTE this code is built into coreinit.rpl
3 * this copy is just for reference.
4 */
5 /*
6 Language Independent Library
7
8 Copyright 1983-2008 Green Hills Software,Inc.
9
10 * This program is the property of Green Hills Software, Inc,
11 * its contents are proprietary information and no part of it
12 * is to be disclosed to anyone except employees of Green Hills
13 * Software, Inc., or as agreed in writing signed by the President
14 * of Green Hills Software, Inc.
15 */
16 /* ind_exit.c: low-level startup & shutdown. Machine Independent. */
17
18 /* please examine ind_io.c for an overview of this file's contents */
19
20 #if defined(EMBEDDED)
21
22 #include "indos.h"
23 #include "ind_exit.h"
24 #include "ind_thrd.h"
25 #if 1 // CAFE MOD
26 #include <ppc_ghs.h>
27 #include <cafe/os.h>
28 #endif // CAFE MOD
29
30 #pragma weak __cpp_exception_cleanup
31 extern void __cpp_exception_cleanup(void **);
32 #pragma weak __ghs_cpp_exception_cleanup
33 extern void __ghs_cpp_exception_cleanup(void);
34
35 /*============================================================================*/
36 /* FUNCTIONS ALWAYS NEEDED TO RUN PROGRAMS COMPILED WITH THE DEFAULT CRT0 */
37 /*============================================================================*/
38 /* _exit() terminate the program */
39 /* __ghs_at_exit() arrange for a function to be invoked at exit() time */
40 /*============================================================================*/
41
42 static struct __GHS_AT_EXIT *exitlisthead;
43
44 /******************************************************************************/
45 /* void _exit (code); */
46 /* Exit from the program with a status code specified by code. */
47 /* DO NOT RETURN! */
48 /* */
49 /* This function is called by exit() after the libraries have shut down, */
50 /* and also by ind_crt0.c in the event that the program's main() returns. */
51 /******************************************************************************/
52 #if defined(__scllc_asm)
53 /* StarCore LLC assembler doesn't support "set __exit,__Exit" */
54 #pragma asm
55 section .text
56 global __exit
57 __exit type func
58 endsec
59 #pragma endasm
60 #else
61 #pragma weak _exit = _Exit
62 #endif
63
64 #if 1 // CAFE MOD
65 typedef void (*vfpt)();
66 extern vfpt _ctors[];
67
68 #pragma weak __cpp_exception_cleanup
69 void __cpp_exception_cleanup(void **);
70
71 void (*__atexit_cleanup)(int);
72 void (*__stdio_cleanup)(void);
73
74 #pragma weak __ghs_at_exit_cleanup
75 void __ghs_at_exit_cleanup(void);
76
exit(int status)77 void exit(int status)
78 {
79 // run the explicit atexit list here NOTE: RPX DTORS are
80 // called in this list before any other DTORS are called
81 #ifdef _DEBUG
82 OSReportVerbose("ATEXIT: RPX (calls RPX DTORs)\n");
83 #endif
84 if (__atexit_cleanup) {
85 __atexit_cleanup(status);
86 }
87
88 // don't call DTORs here coreinit.rpl is not allowed to have DTORs
89 // note does not work as __call_dtors() is a C++ function...
90 // __call_dtors();
91
92 if (__stdio_cleanup) {
93 __stdio_cleanup();
94 }
95
96 _Exit(status);
97 }
98
99 extern void __PPCExit(int result);
100
__ghs_at_exit_cleanup(void)101 void __ghs_at_exit_cleanup(void)
102 {
103 struct __GHS_AT_EXIT *el;
104
105 for (el = exitlisthead; el; el = el->next)
106 el->func();
107 }
108
_Exit(int code)109 void _Exit (int code)
110 {
111 __ghs_at_exit_cleanup();
112
113 /* do we really need to do this?
114 * or can we just exit?
115 */
116 if (__cpp_exception_cleanup) {
117 OSThread *pThread = OSGetCurrentThread();
118 if (pThread)
119 __cpp_exception_cleanup(&pThread->crt.__eh_globals);
120 }
121
122 __PPCExit(code);
123
124 /* If we get here, __PPCExit didn't do anything. Loop forever. */
125 for (;;)
126 continue;
127 }
128 #endif // CAFE MOD
129
130 #if 0 // CAFE GHS ORIG
131 void _Exit (int code)
132 {
133 struct __GHS_AT_EXIT *el;
134
135 __ghsLock();
136 for (el = exitlisthead; el; el = el->next)
137 el->func();
138
139 /* [nikola] Mon Sep 20 15:07:55 PDT 1999 - cleanup the exception handling */
140 #ifndef __disable_thread_safe_extensions
141 /*--------------------*/
142 /* C++ Thread-safe */
143 /* Exception handling */
144 /*--------------------*/
145 {
146 if(__ghs_weak_sym_check(__cpp_exception_cleanup))
147 __ghs_cpp_exception_cleanup();
148 }
149 #endif /* !defined(__disable_thread_safe_extensions) */
150 __ghsUnlock();
151
152 #pragma ghs nowarning 1547 /* Syscall prototype problems */
153 (void)__ghs_syscall(SYSCALL_EXIT, code);
154 #pragma ghs endnowarning 1547
155 /* If we get here, SYSCALL_EXIT didn't do anything. Loop forever. */
156 for (;;)
157 continue;
158 }
159 #endif // CAFE GHS ORIG
160
161 /******************************************************************************/
162 /* void __ghs_at_exit (struct __GHS_AT_EXIT *gae); */
163 /* Add gae to the list of functions to be executed when _Exit() is called. */
164 /******************************************************************************/
__ghs_at_exit(struct __GHS_AT_EXIT * gae)165 void __ghs_at_exit (struct __GHS_AT_EXIT *gae)
166 {
167 __ghsLock();
168 gae->next = exitlisthead;
169 exitlisthead = gae;
170 __ghsUnlock();
171 }
172 #endif /* EMBEDDED */
173