4 * Startup file for GCC/Mingw32 builds
5 * (replaces gcc's default c:\egcs\...\{crt1.o,dllcrt1.o})
7 * This file is taken from the Mingw32 package.
8 * Created by Colin Peters for Mingw32
9 * Modified by Mumit Khan
12 * Added (in modified form) to Perl standard distribution to fix
13 * problems linking against PerlCRT or MSVCRT
14 * -- Benjamin Stuhl <sho_pi@hotmail.com> 10-17-1999
27 * Access to a standard 'main'-like argument count and list. Also included
28 * is a table of environment variables.
39 extern void __getmainargs (int *, char ***, char ***, int, _startupinfo *);
41 extern void __GetMainArgs (int *, char ***, char ***, int);
45 * Initialize the _argc, _argv and environ variables.
48 _mingw32_init_mainargs ()
50 /* The environ variable is provided directly in stdlib.h through
51 * a dll function call. */
54 _startupinfo start_info;
55 start_info.newmode = 0;
59 * Microsoft's runtime provides a function for doing just that.
62 (void) __getmainargs (&_argc, &_argv, &dummy_environ, _CRT_glob,
66 (void) __GetMainArgs (&_argc, &_argv, &dummy_environ, _CRT_glob);
70 #if defined(EXESTARTUP) /* gcrt0.o - startup for an executable */
72 extern int main (int, char **, char **);
75 * Must have the correct app type for MSVCRT.
79 #define __UNKNOWN_APP 0
80 #define __CONSOLE_APP 1
82 __MINGW_IMPORT void __set_app_type(int);
83 #endif /* __MSVCRT__ */
86 * Setup the default file handles to have the _CRT_fmode mode, as well as
87 * any new files created by the user.
89 extern unsigned int _CRT_fmode;
92 _mingw32_init_fmode ()
94 /* Don't set the file mode if the user hasn't set any value for it. */
100 * This overrides the default file mode settings for stdin,
101 * stdout and stderr. At first I thought you would have to
102 * test with isatty, but it seems that the DOS console at
103 * least is smart enough to handle _O_BINARY stdout and
104 * still display correctly.
108 _setmode (_fileno (stdin), _CRT_fmode);
112 _setmode (_fileno (stdout), _CRT_fmode);
116 _setmode (_fileno (stderr), _CRT_fmode);
121 /* This function will be called when a trap occurs. Thanks to Jacob
122 Navia for his contribution. */
124 _gnu_exception_handler (EXCEPTION_POINTERS * exception_data)
126 void (*old_handler) (int);
127 long action = EXCEPTION_CONTINUE_SEARCH;
130 switch (exception_data->ExceptionRecord->ExceptionCode)
132 case EXCEPTION_ACCESS_VIOLATION:
133 /* test if the user has set SIGSEGV */
134 old_handler = signal (SIGSEGV, SIG_DFL);
135 if (old_handler == SIG_IGN)
137 /* this is undefined if the signal was raised by anything other
139 signal (SIGSEGV, 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) (SIGSEGV);
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.
187 __mingw_CRTStartup ()
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 _fpreset (); /* Supplied by the runtime library. */
205 * Set up __argc, __argv and _environ.
207 _mingw32_init_mainargs ();
210 * Sets the default file mode for stdin, stdout and stderr, as well
211 * as files later opened by the user, to _CRT_fmode.
212 * NOTE: DLLs don't do this because that would be rude!
214 _mingw32_init_fmode ();
217 * Call the main function. If the user does not supply one
218 * the one in the 'libmingw32.a' library will be linked in, and
219 * that one calls WinMain. See main.c in the 'lib' dir
222 nRet = main (_argc, _argv, environ);
225 * Perform exit processing for the C library. This means
226 * flushing output and calling 'atexit' registered functions.
236 * The function mainCRTStartup is the entry point for all console programs.
242 __set_app_type (__CONSOLE_APP);
244 __mingw_CRTStartup ();
249 * For now the GUI startup function is the same as the console one.
250 * This simply gets rid of the annoying warning about not being able
251 * to find WinMainCRTStartup when linking GUI applications.
257 __set_app_type (__GUI_APP);
259 __mingw_CRTStartup ();
262 #elif defined(DLLSTARTUP) /* dllcrt0.o - startup for a DLL */
264 /* Unlike normal crt1, I don't initialize the FPU, because the process
265 * should have done that already. I also don't set the file handle modes,
266 * because that would be rude. */
269 extern void __main ();
270 extern void __do_global_dtors ();
273 extern BOOL WINAPI DllMain (HANDLE, DWORD, LPVOID);
276 DllMainCRTStartup (HANDLE hDll, DWORD dwReason, LPVOID lpReserved)
280 if (dwReason == DLL_PROCESS_ATTACH)
282 _mingw32_init_mainargs ();
285 /* From libgcc.a, calls global class constructors. */
291 * Call the user-supplied DllMain subroutine
292 * NOTE: DllMain is optional, so libmingw32.a includes a stub
293 * which will be used if the user does not supply one.
295 bRet = DllMain (hDll, dwReason, lpReserved);
298 if (dwReason == DLL_PROCESS_DETACH)
300 /* From libgcc.a, calls global class destructors. */
301 __do_global_dtors ();
309 * For the moment a dummy atexit. Atexit causes problems in DLLs, especially
310 * if they are dynamically loaded. For now atexit inside a DLL does nothing.
311 * NOTE: We need this even if the DLL author never calls atexit because
312 * the global constructor function __do_global_ctors called from __main
313 * will attempt to register __do_global_dtors using atexit.
314 * Thanks to Andrey A. Smirnov for pointing this one out.
317 atexit (void (*pfn) ())
323 #error No startup target!
324 #endif /* EXESTARTUP */