]> pd.if.org Git - pdclib.old/blob - platform/win32/crt0.c
Use the GCC ability to place each function/piece of data in its' own section, and...
[pdclib.old] / platform / win32 / crt0.c
1 #include <string.h>\r
2 #include <stdlib.h>\r
3 #include <stdio.h>\r
4 #include <signal.h>\r
5 #include <threads.h>\r
6 #include <wchar.h> // Watcom bug: winnt.h assumes string.h defines wchar_t\r
7 #include <windows.h>\r
8 #include <_PDCLIB_io.h>\r
9 #include <_PDCLIB_locale.h>\r
10 #include <_PDCLIB_clocale.h>\r
11 \r
12 static char ** argvToAnsi( wchar_t ** wargv, int argc )\r
13 {\r
14     char ** argv = malloc( sizeof( *argv ) * argc );\r
15     for ( int i = 0; i != argc; ++i ) {\r
16         int sz = WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_SEPCHARS,\r
17                                       wargv[i], -1, NULL, 0, NULL, NULL );\r
18         if(!(argv[i] = malloc(sz))) {\r
19             fputs("Error in C runtime initialization: "\r
20                   "unable to allocate buffer for argument", stderr);\r
21             abort();\r
22         }\r
23 \r
24         int rv = WideCharToMultiByte( CP_ACP, WC_COMPOSITECHECK | WC_SEPCHARS,\r
25                                       wargv[i], -1, argv[i], sz, NULL, NULL );\r
26 \r
27         if(rv != sz) {\r
28             fputs("Error in C runtime initialization: "\r
29                   "size mismatch during character set conversion", stderr);\r
30             abort();\r
31         }\r
32     }\r
33     return argv;\r
34 }\r
35 \r
36 static int        argc;\r
37 static wchar_t *  cl;\r
38 static wchar_t ** wargv;\r
39 static char    ** argv;\r
40 \r
41 static void freeArgs( void )\r
42 {\r
43     for(int i = 0; i != argc; i++) {\r
44         free( argv[i] );\r
45     }\r
46     free( argv );\r
47     LocalFree( wargv );\r
48 }\r
49 \r
50 extern void (*_PDCLIB_sigfpe)( int );\r
51 extern void (*_PDCLIB_sigill)( int );\r
52 extern void (*_PDCLIB_sigsegv)( int );\r
53 \r
54 static LPTOP_LEVEL_EXCEPTION_FILTER oldFilter;\r
55 static LONG CALLBACK sehExceptionFilter( EXCEPTION_POINTERS * exInfo )\r
56 {\r
57     int sig;\r
58     void (*handler)( int );\r
59 \r
60     switch( exInfo->ExceptionRecord->ExceptionCode ) {\r
61         case EXCEPTION_ACCESS_VIOLATION:\r
62         case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:\r
63         case EXCEPTION_DATATYPE_MISALIGNMENT:\r
64         case EXCEPTION_GUARD_PAGE:\r
65         case EXCEPTION_IN_PAGE_ERROR:\r
66         case EXCEPTION_STACK_OVERFLOW:\r
67             sig = SIGSEGV;\r
68             handler = _PDCLIB_sigsegv;\r
69             break;\r
70 \r
71         case EXCEPTION_ILLEGAL_INSTRUCTION:\r
72         case EXCEPTION_PRIV_INSTRUCTION:\r
73             sig = SIGILL;\r
74             handler = _PDCLIB_sigill;\r
75             break;\r
76 \r
77         case EXCEPTION_INT_DIVIDE_BY_ZERO:\r
78         case EXCEPTION_INT_OVERFLOW:\r
79         case EXCEPTION_FLT_DENORMAL_OPERAND:\r
80         case EXCEPTION_FLT_DIVIDE_BY_ZERO:\r
81         case EXCEPTION_FLT_INEXACT_RESULT:\r
82         case EXCEPTION_FLT_INVALID_OPERATION:\r
83         case EXCEPTION_FLT_OVERFLOW:\r
84         case EXCEPTION_FLT_STACK_CHECK:\r
85         case EXCEPTION_FLT_UNDERFLOW:\r
86             sig = SIGFPE;\r
87             handler = _PDCLIB_sigfpe;\r
88             break;\r
89 \r
90         default:\r
91             return oldFilter ? oldFilter( exInfo ) : EXCEPTION_EXECUTE_HANDLER;\r
92     }\r
93 \r
94     if(handler == SIG_DFL) {\r
95         return EXCEPTION_EXECUTE_HANDLER;\r
96     } else if(handler == SIG_IGN) {\r
97         return EXCEPTION_CONTINUE_EXECUTION;\r
98     } else {\r
99         handler( sig );\r
100         return EXCEPTION_CONTINUE_EXECUTION;\r
101     }\r
102 }\r
103 \r
104 extern int main( int argc, char ** argv, char ** envp );\r
105 \r
106 void __cdecl mainCRTStartup( void );\r
107 \r
108 void __cdecl mainCRTStartup( void ) \r
109 {\r
110     stdin->handle.pointer  = GetStdHandle(STD_INPUT_HANDLE);\r
111     stdout->handle.pointer = GetStdHandle(STD_OUTPUT_HANDLE);\r
112     stderr->handle.pointer = GetStdHandle(STD_ERROR_HANDLE);\r
113 \r
114     oldFilter = SetUnhandledExceptionFilter( sehExceptionFilter );\r
115 \r
116     cl    = GetCommandLineW();\r
117     wargv = CommandLineToArgvW(cl, &argc);\r
118     argv  = argvToAnsi(wargv, argc);\r
119 \r
120     _PDCLIB_initclocale( &_PDCLIB_global_locale );\r
121 \r
122     if(tss_create(&_PDCLIB_locale_tss, (tss_dtor_t) freelocale) \r
123             != thrd_success) {\r
124         fputs( "Error during C runtime initialization: "\r
125                "Unable to allocate locale TLS", stderr );\r
126         exit( EXIT_FAILURE );\r
127     }\r
128 \r
129     if(        mtx_init(&stdin->lock, mtx_recursive) != thrd_success \r
130             || mtx_init(&stdout->lock, mtx_recursive) != thrd_success\r
131             || mtx_init(&stderr->lock, mtx_recursive) != thrd_success ) {\r
132         fputs( "Error during C runtime initialization: "\r
133             "Unable to allocate stdio mutex", stderr );\r
134         exit( EXIT_FAILURE );\r
135     }\r
136 \r
137     atexit(freeArgs);\r
138 \r
139     int exitStatus = main(argc, argv, NULL);\r
140 \r
141     exit(exitStatus);\r
142 }