3 * This file has no copyright assigned and is placed in the Public Domain.
4 * This file is a part of the mingw-runtime package.
5 * No warranty is given; refer to the file DISCLAIMER within the package.
7 * Source code for the startup proceedures used by all programs. This code
8 * is compiled to make crt1.o, which should be located in the library path.
12 /* Hide the declaration of _fmode with dllimport attribute in stdlib.h to
13 avoid problems with older GCC. */
14 #define __IN_MINGW_RUNTIME
20 #define WIN32_LEAN_AND_MEAN
24 /* NOTE: The code for initializing the _argv, _argc, and environ variables
25 * has been moved to a separate .c file which is included in both
26 * crt1.c and dllcrt1.c. This means changes in the code don't have to
27 * be manually synchronized, but it does lead to this not-generally-
28 * a-good-idea use of include. */
30 #include "cpu_features.h"
32 extern void _pei386_runtime_relocator (void);
34 extern int main (int, char **, char **);
37 * Must have the correct app type for MSVCRT.
41 #define __UNKNOWN_APP 0
42 #define __CONSOLE_APP 1
47 void __set_app_type(int);
48 #endif /* __MSVCRT__ */
50 /* Global _fmode for this .exe, not the one in msvcrt.dll,
51 The default is set in txtmode.o in libmingw32.a */
52 /* Override the dllimport'd declarations in stdlib.h */
56 extern int* __p__fmode(void); /* To access the dll _fmode */
60 * Setup the default file handles to have the _CRT_fmode mode, as well as
61 * any new files created by the user.
63 extern int _CRT_fmode
;
66 _mingw32_init_fmode (void)
68 /* Don't set the std file mode if the user hasn't set any value for it. */
74 * This overrides the default file mode settings for stdin,
75 * stdout and stderr. At first I thought you would have to
76 * test with isatty, but it seems that the DOS console at
77 * least is smart enough to handle _O_BINARY stdout and
78 * still display correctly.
82 _setmode (_fileno (stdin
), _CRT_fmode
);
86 _setmode (_fileno (stdout
), _CRT_fmode
);
90 _setmode (_fileno (stderr
), _CRT_fmode
);
94 /* Now sync the dll _fmode to the one for this .exe. */
96 *__p__fmode() = _fmode
;
98 *_imp___fmode_dll
= _fmode
;
102 /* This function will be called when a trap occurs. Thanks to Jacob
103 Navia for his contribution. */
105 _gnu_exception_handler (EXCEPTION_POINTERS
* exception_data
)
107 void (*old_handler
) (int);
108 LONG action
= EXCEPTION_CONTINUE_SEARCH
;
111 switch (exception_data
->ExceptionRecord
->ExceptionCode
)
113 case EXCEPTION_ACCESS_VIOLATION
:
114 /* test if the user has set SIGSEGV */
115 old_handler
= signal (SIGSEGV
, SIG_DFL
);
116 if (old_handler
== SIG_IGN
)
118 /* this is undefined if the signal was raised by anything other
120 signal (SIGSEGV
, SIG_IGN
);
121 action
= EXCEPTION_CONTINUE_EXECUTION
;
123 else if (old_handler
!= SIG_DFL
)
125 /* This means 'old' is a user defined function. Call it */
126 (*old_handler
) (SIGSEGV
);
127 action
= EXCEPTION_CONTINUE_EXECUTION
;
131 case EXCEPTION_ILLEGAL_INSTRUCTION
:
132 case EXCEPTION_PRIV_INSTRUCTION
:
133 /* test if the user has set SIGILL */
134 old_handler
= signal (SIGILL
, SIG_DFL
);
135 if (old_handler
== SIG_IGN
)
137 /* this is undefined if the signal was raised by anything other
139 signal (SIGILL
, SIG_IGN
);
140 action
= EXCEPTION_CONTINUE_EXECUTION
;
142 else if (old_handler
!= SIG_DFL
)
144 /* This means 'old' is a user defined function. Call it */
145 (*old_handler
) (SIGILL
);
146 action
= EXCEPTION_CONTINUE_EXECUTION
;
150 case EXCEPTION_FLT_INVALID_OPERATION
:
151 case EXCEPTION_FLT_DIVIDE_BY_ZERO
:
152 case EXCEPTION_FLT_DENORMAL_OPERAND
:
153 case EXCEPTION_FLT_OVERFLOW
:
154 case EXCEPTION_FLT_UNDERFLOW
:
155 case EXCEPTION_FLT_INEXACT_RESULT
:
159 case EXCEPTION_INT_DIVIDE_BY_ZERO
:
160 /* test if the user has set SIGFPE */
161 old_handler
= signal (SIGFPE
, SIG_DFL
);
162 if (old_handler
== SIG_IGN
)
164 signal (SIGFPE
, SIG_IGN
);
167 action
= EXCEPTION_CONTINUE_EXECUTION
;
169 else if (old_handler
!= SIG_DFL
)
171 /* This means 'old' is a user defined function. Call it */
172 (*old_handler
) (SIGFPE
);
173 action
= EXCEPTION_CONTINUE_EXECUTION
;
184 * The function mainCRTStartup is the entry point for all console programs.
186 static void __attribute__((noreturn
))
187 __mingw_CRTStartup (void)
192 * Set up the top-level exception handler so that signal handling
193 * works as expected. The mapping between ANSI/POSIX signals and
194 * Win32 SE is not 1-to-1, so caveat emptore.
197 SetUnhandledExceptionFilter (_gnu_exception_handler
);
200 * Initialize floating point unit.
202 __cpu_features_init (); /* Do we have SSE, etc.*/
203 _fpreset (); /* Supplied by the runtime library. */
206 * Set up __argc, __argv and _environ.
208 _mingw32_init_mainargs ();
211 * Sets the default file mode.
212 * If _CRT_fmode is set, also set mode for stdin, stdout
213 * and stderr, as well
214 * NOTE: DLLs don't do this because that would be rude!
216 _mingw32_init_fmode ();
218 /* Adust references to dllimported data that have non-zero offsets. */
219 #if defined(__i386__)
220 _pei386_runtime_relocator ();
223 #if defined(__GNUC__)
224 #if defined(__i386__)
225 /* Align the stack to 16 bytes for the sake of SSE ops in main
226 or in functions inlined into main. */
227 asm __volatile__ ("andl $-16, %%esp" : : : "%esp");
228 #elif defined(__mips__)
229 /* Align the stack to 16 bytes */
230 asm __volatile__ ("andi %sp,%sp,-16" : : : "%sp");
231 #elif defined(__PowerPC__)
232 /* Align the stack to 16 bytes */
233 asm __volatile__ ("li 0,15\n\tandc 1,1,0" : : : "r1");
235 #error Unsupported architecture
237 #elif defined(_MSC_VER)
239 /* Align the stack to 16 bytes for the sake of SSE ops in main
240 or in functions inlined into main. */
241 __asm
and esp
, 0FFFFFFF0h
250 * Call the main function. If the user does not supply one
251 * the one in the 'libmingw32.a' library will be linked in, and
252 * that one calls WinMain. See main.c in the 'lib' dir
255 nRet
= main (_argc
, _argv
, _environ
);
258 * Perform exit processing for the C library. This means
259 * flushing output and calling 'atexit' registered functions.
267 * The function mainCRTStartup is the entry point for all console programs.
270 mainCRTStartup (void)
273 __set_app_type (__CONSOLE_APP
);
275 __mingw_CRTStartup ();
279 * For now the GUI startup function is the same as the console one.
280 * This simply gets rid of the annoying warning about not being able
281 * to find WinMainCRTStartup when linking GUI applications.
284 WinMainCRTStartup (void)
287 __set_app_type (__GUI_APP
);
289 __mingw_CRTStartup ();
294 * We force use of library version of atexit, which is only
295 * visible in import lib as _imp__atexit
297 extern int (*_imp__atexit
)(void (*)(void));
298 int atexit (void (* pfn
)(void) )
300 return ( (*_imp__atexit
)(pfn
));
303 /* Likewise for non-ANSI _onexit */
304 extern _onexit_t (*_imp___onexit
)(_onexit_t
);
306 _onexit (_onexit_t pfn
)
308 return (*_imp___onexit
)(pfn
);