OSDN Git Service

Correct a typographic error; fix MinGW-Bug #39193
[mingw/mingw-org-wsl.git] / mingwrt / crt1.c
index c207702..439f9e8 100644 (file)
@@ -1,23 +1,46 @@
 /*
  * crt1.c
- * This file has no copyright assigned and is placed in the Public Domain.
- * This file is a part of the mingw-runtime package.
- * No warranty is given; refer to the file DISCLAIMER within the package.
  *
- * Source code for the startup proceedures used by all programs. This code
- * is compiled to make crt1.o, which should be located in the library path.
+ * Source code for the startup procedures used by all programs.  This
+ * code is compiled to crt1.o, which is located in the library path.
+ *
+ * $Id$
+ *
+ * Written by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
+ * Copyright (C) 1997, 1999, 2002-2007, 2009, 2010, 2014, 2016,
+ *   2017, MinGW.org Project.
+ *
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice, this permission notice, and the following
+ * disclaimer shall be included in all copies or substantial portions of
+ * the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OF OR OTHER
+ * DEALINGS IN THE SOFTWARE.
  *
- */
-
-/* Hide the declaration of _fmode with dllimport attribute in stdlib.h to
- * avoid problems with older GCC.
  */
 #define __IN_MINGW_RUNTIME
+/* Hide the declaration of _fmode(), with its dllimport attribute in
+ * <stdlib.h>, to avoid problems with older GCC.
+ */
 #include <stdlib.h>
 #include <stdio.h>
 #include <io.h>
 #include <process.h>
-#include <float.h>
+#include <fenv.h>
+
 #define WIN32_LEAN_AND_MEAN
 #include <windows.h>
 #include <signal.h>
@@ -83,8 +106,7 @@ extern void __GetMainArgs( int *, char ***, char ***, int );
 #endif
 
 void _mingw32_init_mainargs()
-{
-  /* This is the old start-up mechanism, in which we use a start-up
+{ /* This is the old start-up mechanism, in which we use a start-up
    * hook provided by Microsoft's runtime library to initialize the
    * argument and environment vectors.
    *
@@ -98,17 +120,17 @@ void _mingw32_init_mainargs()
 
 # define _CRT_GLOB_OPT  _CRT_glob & __CRT_GLOB_USE_MSVCRT__
 # ifdef __MSVCRT__
-    /* The MSVCRT.DLL start-up hook requires this invocation
-     * protocol...
-     */
-    _startupinfo start_info = { 0 };
-    __getmainargs( &_argc, &_argv, &dummy_envp, _CRT_GLOB_OPT, &start_info );
+  /* The MSVCRT.DLL start-up hook requires this invocation
+   * protocol...
+   */
+  _startupinfo start_info = { 0 };
+  __getmainargs( &_argc, &_argv, &dummy_envp, _CRT_GLOB_OPT, &start_info );
 
 # else
-    /* ...while a somewhat simpler protocol is applicable, in
-     * the case of the CRTDLL.DLL version.
-     */
-    __GetMainArgs( &_argc, &_argv, &dummy_envp, _CRT_GLOB_OPT );
+  /* ...while a somewhat simpler protocol is applicable, in
+   * the case of the CRTDLL.DLL version.
+   */
+  __GetMainArgs( &_argc, &_argv, &dummy_envp, _CRT_GLOB_OPT );
 # endif
 }
 
@@ -138,16 +160,15 @@ extern int _fmode;
 extern int* __p__fmode(void); /* To access the dll _fmode */
 #endif
 
-/*
- * Setup the default file handles to have the _CRT_fmode mode, as well as
- * any new files created by the user.
+/* Setup the default file handles to have the _CRT_fmode mode,
+ * as well as any new files created by the user.
  */
 extern int _CRT_fmode;
 
 static void
 _mingw32_init_fmode (void)
-{
-  /* Don't set the std file mode if the user hasn't set any value for it.
+{ /* Don't set the std file mode if the user hasn't set any
+   * value for it.
    */
   if (_CRT_fmode)
   {
@@ -167,9 +188,9 @@ _mingw32_init_fmode (void)
   /* Now sync the dll _fmode to the one for this .exe.
    */
 # ifdef __MSVCRT__
-    *__p__fmode() = _fmode;
+  *__p__fmode() = _fmode;
 # else
-    *_imp___fmode_dll = _fmode;
+  *_imp___fmode_dll = _fmode;
 # endif
 }
 
@@ -184,42 +205,46 @@ _gnu_exception_handler (EXCEPTION_POINTERS * exception_data)
   int reset_fpu = 0;
 
   switch (exception_data->ExceptionRecord->ExceptionCode)
-    {
+  {
     case EXCEPTION_ACCESS_VIOLATION:
-      /* test if the user has set SIGSEGV */
+      /* Test if the user has set SIGSEGV
+       */
       old_handler = signal (SIGSEGV, SIG_DFL);
       if (old_handler == SIG_IGN)
-       {
-         /* this is undefined if the signal was raised by anything other
-            than raise ().  */
-         signal (SIGSEGV, SIG_IGN);
-         action = EXCEPTION_CONTINUE_EXECUTION;
-       }
+      { /* This is undefined if the signal was raised by
+        * anything other than raise()
+        */
+       signal (SIGSEGV, SIG_IGN);
+       action = EXCEPTION_CONTINUE_EXECUTION;
+      }
       else if (old_handler != SIG_DFL)
-       {
-         /* This means 'old' is a user defined function. Call it */
-         (*old_handler) (SIGSEGV);
-         action = EXCEPTION_CONTINUE_EXECUTION;
-       }
+      { /* This means 'old_handler' is a user defined
+        * function.  Call it
+        */
+       (*old_handler) (SIGSEGV);
+       action = EXCEPTION_CONTINUE_EXECUTION;
+      }
       break;
 
     case EXCEPTION_ILLEGAL_INSTRUCTION:
     case EXCEPTION_PRIV_INSTRUCTION:
-      /* test if the user has set SIGILL */
+      /* Test if the user has set SIGILL
+       */
       old_handler = signal (SIGILL, SIG_DFL);
       if (old_handler == SIG_IGN)
-       {
-         /* this is undefined if the signal was raised by anything other
-            than raise ().  */
-         signal (SIGILL, SIG_IGN);
-         action = EXCEPTION_CONTINUE_EXECUTION;
-       }
+      { /* This is undefined if the signal was raised by
+        * anything other than raise()
+        */
+       signal (SIGILL, SIG_IGN);
+       action = EXCEPTION_CONTINUE_EXECUTION;
+      }
       else if (old_handler != SIG_DFL)
-       {
-         /* This means 'old' is a user defined function. Call it */
-         (*old_handler) (SIGILL);
-         action = EXCEPTION_CONTINUE_EXECUTION;
-       }
+      { /* This means 'old_handler' is a user defined
+        * function.  Call it
+        */
+       (*old_handler) (SIGILL);
+       action = EXCEPTION_CONTINUE_EXECUTION;
+      }
       break;
 
     case EXCEPTION_FLT_INVALID_OPERATION:
@@ -232,33 +257,57 @@ _gnu_exception_handler (EXCEPTION_POINTERS * exception_data)
       /* fall through. */
 
     case EXCEPTION_INT_DIVIDE_BY_ZERO:
-      /* test if the user has set SIGFPE */
+      /* Test if the user has set SIGFPE
+       */
       old_handler = signal (SIGFPE, SIG_DFL);
       if (old_handler == SIG_IGN)
-       {
-         signal (SIGFPE, SIG_IGN);
-         if (reset_fpu)
-           _fpreset ();
-         action = EXCEPTION_CONTINUE_EXECUTION;
-       }
+      {
+       signal (SIGFPE, SIG_IGN);
+       if (reset_fpu)
+         fesetenv (FE_DFL_ENV);
+       action = EXCEPTION_CONTINUE_EXECUTION;
+      }
       else if (old_handler != SIG_DFL)
-       {
-         /* This means 'old' is a user defined function. Call it */
-         (*old_handler) (SIGFPE);
-         action = EXCEPTION_CONTINUE_EXECUTION;
-       }
-      break;
-
-    default:
-      break;
-    }
+      { /* This means 'old_handler' is a user defined
+        * function.  Call it
+        */
+       (*old_handler) (SIGFPE);
+       action = EXCEPTION_CONTINUE_EXECUTION;
+      }
+  }
   return action;
 }
 
-/* The function mainCRTStartup is the entry point for all console programs.
+/* During application start-up, we establish the default configuration
+ * for the FPU.  MSVCRT.DLL provides the _fpreset() function to perform
+ * the appropriate initialization, but it sets the default operation to
+ * be in IEEE-754 8-byte mode, whereas we prefer IEEE-754 10-byte mode,
+ * to better support GCC's 10-byte long doubles; nevertheless, we offer
+ * the option, via the _CRT_fenv global variable, to establish either
+ * one of these modes as initial default, it should be set to either
+ * FE_PD64_ENV, (defined in <fenv.h>, reflecting the 64-bit precision
+ * of the 10-byte mode, and established as default for _CRT_fenv within
+ * the runtime library), or overridden by a setting of FE_PD53_ENV, in
+ * user code, like this:
+ *
+ *   #include <fenv.h>
+ *   const fenv_t *_CRT_fenv = FE_PD53_ENV;
+ *
+ * (or by linking with CRT_fp8.o), to select the 53-bit precision of
+ * the 8-byte mode.
+ *
+ * Whichever of these assignments, i.e. FE_PD64_ENV or FE_PD53_ENV, is
+ * in effect when the following __mingw_CRTStartup() function is invoked,
+ * will cause FE_DFL_ENV to be mapped to one or other of the predefined
+ * environments, FE_PC64_ENV or FE_PC53_ENV, respectively.
+ */
+extern const fenv_t *_CRT_fenv;
+
+/* The function mainCRTStartup(), (defined below), is the entry point
+ * for all console programs, it is, primarily, a wrapper around the
+ * following __mingw_CRTStartup() helper function.
  */
-static void  __MINGW_ATTRIB_NORETURN
-__mingw_CRTStartup (void)
+static __MINGW_ATTRIB_NORETURN  void __mingw_CRTStartup (void)
 {
   int nRet;
 
@@ -274,19 +323,18 @@ __mingw_CRTStartup (void)
    */
   SetUnhandledExceptionFilter (_gnu_exception_handler);
 
-  /* Initialize floating point unit.
+  /* Initialize the floating point unit.
    */
-  __cpu_features_init ();      /* Do we have SSE, etc.*/
-  _fpreset ();                 /* Supplied by the runtime library. */
+  __cpu_features_init ();      /* Do we have SSE, etc. */
+  fesetenv (_CRT_fenv);        /* Supplied by the runtime library. */
 
   /* Set up __argc, __argv and _environ.
    */
   _setargv ();
 
-  /* Sets the default file mode.
-   * If _CRT_fmode is set, also set mode for stdin, stdout
-   * and stderr, as well
-   * NOTE: DLLs don't do this because that would be rude!
+  /* Set the default file mode.  If _CRT_fmode is set, also set mode
+   * for stdin, stdout and stderr, as well.  NOTE: DLLs don't do this
+   * because that would be rude!
    */
   _mingw32_init_fmode ();
 
@@ -299,31 +347,32 @@ __mingw_CRTStartup (void)
    */
   asm  __volatile__  ("andl $-16, %%esp" : : : "%esp");
 
-   /* From libgcc.a, __main calls global class constructors via
-      __do_global_ctors, This in turn  registers  __do_global_dtors
-      as the first entry of the app's atexit table.  We do this
-      explicitly at app startup rather than rely on gcc to generate
-      the call in main's  prologue, since main may be imported from a dll
-      which has its own __do_global_ctors.  */
-    __main ();
+  /* From libgcc.a, __main() calls global class constructors via
+   * __do_global_ctors(); this in turn registers __do_global_dtors()
+   * as the first entry of the application's atexit() table.  We do
+   * this explicitly at application startup rather than rely on GCC
+   * to generate the call in main()'s prologue, since main() may be
+   * imported from a DLL which has its own __do_global_ctors()
+   */
+  __main ();
 
-  /* Call the main function. If the user does not supply one
+  /* Call the main() function. If the user does not supply one
    * the one in the 'libmingw32.a' library will be linked in, and
-   * that one calls WinMain. See main.c in the 'lib' dir
+   * that one calls WinMain().  See main.c in the 'lib' directory
    * for more details.
    */
   nRet = main (_argc, _argv, environ);
 
-  /* Perform exit processing for the C library. This means
-   * flushing output and calling 'atexit' registered functions.
+  /* Perform exit processing for the C library. This means flushing
+   * output and calling atexit() registered functions.
    */
   _cexit ();
 
   ExitProcess (nRet);
 }
 
-/*
- * The function mainCRTStartup is the entry point for all console programs.
+/* The function mainCRTStartup() is the entry point for all console
+ * programs.
  */
 void
 mainCRTStartup (void)
@@ -334,8 +383,7 @@ mainCRTStartup (void)
   __mingw_CRTStartup ();
 }
 
-/*
- * For now the GUI startup function is the same as the console one.
+/* For now the GUI startup function is the same as the console one.
  * This simply gets rid of the annoying warning about not being able
  * to find WinMainCRTStartup when linking GUI applications.
  */
@@ -348,20 +396,15 @@ WinMainCRTStartup (void)
   __mingw_CRTStartup ();
 }
 
-/*
- *  We force use of library version of atexit, which is only
- *  visible in import lib as _imp__atexit
+/* We force use of library version of atexit(), which is only
+ * visible in import lib as _imp__atexit
  */
 extern int (*_imp__atexit)(void (*)(void));
-int atexit (void (* pfn )(void) )
-{
-  return ( (*_imp__atexit)(pfn));
-}
+int atexit (void (* pfn )(void)){ return (*_imp__atexit)(pfn); }
 
-/* Likewise for non-ANSI _onexit */
+/* Likewise for non-ANSI _onexit()
+ */
 extern _onexit_t (*_imp___onexit)(_onexit_t);
-_onexit_t
-_onexit (_onexit_t pfn )
-{
-  return (*_imp___onexit)(pfn);
-}
+_onexit_t _onexit (_onexit_t pfn){ return (*_imp___onexit)(pfn); }
+
+/* $RCSfile$: end of file */