https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8a6d65304483b2cea0fef4d7d35fa0b5b2a7db59

commit 8a6d65304483b2cea0fef4d7d35fa0b5b2a7db59
Author:     Jérôme Gardou <[email protected]>
AuthorDate: Mon Dec 28 12:06:34 2020 +0100
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Wed Dec 30 19:03:52 2020 +0100

    [CRT] Fix _onexit
    
    Avoid calling malloc in CR initialisation code.
    Have executables call msvcrt implementation, while the DLLs keep their own 
function tables
    
    CORE-17362
---
 dll/win32/msvcrt/msvcrt.spec   |  4 +--
 sdk/lib/crt/startup/atonexit.c | 77 ++++++++++++++++++++++++------------------
 sdk/lib/crt/startup/crtdll.c   | 15 +++-----
 sdk/lib/crt/startup/crtexe.c   |  2 +-
 4 files changed, 53 insertions(+), 45 deletions(-)

diff --git a/dll/win32/msvcrt/msvcrt.spec b/dll/win32/msvcrt/msvcrt.spec
index 00bf4e65f3d..848e2602e45 100644
--- a/dll/win32/msvcrt/msvcrt.spec
+++ b/dll/win32/msvcrt/msvcrt.spec
@@ -883,7 +883,7 @@
 @ stub -version=0x600+ -arch=i386 _msize_debug
 @ cdecl _nextafter(double double)
 @ stub -arch=x86_64 _nextafterf
-@ cdecl _onexit(ptr)
+@ extern _onexit # Declaring it as extern let us use the symbol from msvcrtex 
while having the __imp_ symbol defined in the import lib
 @ varargs _open(str long)
 @ cdecl _open_osfhandle(long long)
 @ extern _osplatform
@@ -1293,7 +1293,7 @@
 @ cdecl atan2(double double)
 @ cdecl -arch=x86_64,arm atan2f(long)
 @ cdecl -arch=x86_64,arm atanf(long)
-@ extern atexit # <-- keep this as an extern, thank you
+@ extern atexit # Declaring it as extern let us use the symbol from msvcrtex 
while having the __imp_ symbol defined in the import lib for those who really 
need it
 @ cdecl atof(str)
 @ cdecl atoi(str)
 @ cdecl atol(str)
diff --git a/sdk/lib/crt/startup/atonexit.c b/sdk/lib/crt/startup/atonexit.c
index 1774e90f1b3..ff6021aacfe 100644
--- a/sdk/lib/crt/startup/atonexit.c
+++ b/sdk/lib/crt/startup/atonexit.c
@@ -4,7 +4,6 @@
  * No warranty is given; refer to the file DISCLAIMER.PD within this package.
  */
 
-#undef CRTDLL
 #ifndef _DLL
 #define _DLL
 #endif
@@ -20,7 +19,7 @@
 
   void __cdecl _lock (int _File);
   void __cdecl _unlock (int _File);
-  
+
 _PVFV *__onexitbegin;
 _PVFV *__onexitend;
 
@@ -33,16 +32,19 @@ void __call_atexit(void)
     /* Note: should only be called with the exit lock held */
     _PVFV *first, *last;
 
-    first =  (_PVFV *)_decode_pointer(__onexitbegin);
-    last = (_PVFV *)_decode_pointer(__onexitend);;
+    if (!__onexitbegin)
+        return;
 
-    if (!first) return;
+    first =  (_PVFV *)_decode_pointer(__onexitbegin);
+    last = (_PVFV *)_decode_pointer(__onexitend);
 
     while (--last >= first)
         if (*last)
             (**last)();
 
     free(first);
+
+    __onexitbegin = __onexitend = NULL;
 }
 
 /* Choose a different name to prevent name conflicts. The CRT one works fine.  
*/
@@ -50,34 +52,45 @@ _onexit_t __cdecl _onexit(_onexit_t func);
 
 _onexit_t __cdecl _onexit(_onexit_t func)
 {
-  _PVFV *onexitbegin;
-  _PVFV *onexitend;
-  _onexit_t retval;
-
-  onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin);
-
-  if (onexitbegin == (_PVFV *) -1)
-#ifdef __REACTOS__
-  {
-      onexitbegin = (_PVFV *)calloc(32, sizeof(_onexit_t));
-      if (onexitbegin == NULL)
-        return NULL;
-      __onexitbegin = _encode_pointer(onexitbegin);
-      __onexitend = _encode_pointer(onexitbegin + 32);
-  }
-#else
-    return (* __MINGW_IMP_SYMBOL(_onexit)) (func);
+    _PVFV *onexitbegin;
+    _PVFV *onexitend;
+    _onexit_t retval;
+
+#ifndef CRTDLL
+    if (__onexitbegin == (_PVFV *) -1)
+        return (* __MINGW_IMP_SYMBOL(_onexit)) (func);
 #endif
-  _lock (_EXIT_LOCK1);
-  onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin);
-  onexitend = (_PVFV *) _decode_pointer (__onexitend);
-  
-  retval = __dllonexit (func, &onexitbegin, &onexitend);
-
-  __onexitbegin = (_PVFV *) _encode_pointer (onexitbegin);
-  __onexitend = (_PVFV *) _encode_pointer (onexitend);
-  _unlock (_EXIT_LOCK1);
-  return retval;
+
+    _lock (_EXIT_LOCK1);
+
+    if (!__onexitbegin)
+    {
+        /* First time we are called. Initialize our array */
+        onexitbegin = calloc(1, sizeof(*onexitbegin));
+        if (!onexitbegin)
+        {
+            _unlock(_EXIT_LOCK1);
+            return NULL;
+        }
+        onexitend = onexitbegin;
+    }
+    else
+    {
+        onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin);
+        onexitend = (_PVFV *) _decode_pointer (__onexitend);
+    }
+
+    retval = __dllonexit (func, &onexitbegin, &onexitend);
+
+    if (retval != NULL)
+    {
+        /* Update our globals in case of success */
+        __onexitbegin = (_PVFV *) _encode_pointer (onexitbegin);
+        __onexitend = (_PVFV *) _encode_pointer (onexitend);
+    }
+
+    _unlock (_EXIT_LOCK1);
+    return retval;
 }
 
 int __cdecl
diff --git a/sdk/lib/crt/startup/crtdll.c b/sdk/lib/crt/startup/crtdll.c
index afe23284f50..b9f5838b9fb 100644
--- a/sdk/lib/crt/startup/crtdll.c
+++ b/sdk/lib/crt/startup/crtdll.c
@@ -62,14 +62,8 @@ static int
 __cdecl
 pre_c_init (void)
 {
-    _PVFV *onexitbegin;
+    __onexitend = __onexitbegin = NULL;
 
-    onexitbegin = (_PVFV *) malloc (32 * sizeof (_PVFV));
-    __onexitend = __onexitbegin = (_PVFV *) _encode_pointer (onexitbegin);
-
-    if (onexitbegin == NULL)
-        return 1;
-    *onexitbegin = (_PVFV) NULL;
     return 0;
 }
 
@@ -136,14 +130,15 @@ WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD 
dwReason, LPVOID lpreserved)
         }
         else
         {
-            _PVFV * onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin);
-            if (onexitbegin)
+            if (__onexitbegin)
             {
+                _PVFV *onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin);
                 _PVFV *onexitend = (_PVFV *) _decode_pointer (__onexitend);
                 while (--onexitend >= onexitbegin)
                     if (*onexitend != NULL)
                         (**onexitend) ();
-                free (onexitbegin);
+                if (!lpreserved)
+                    free(onexitbegin);
                 __onexitbegin = __onexitend = (_PVFV *) NULL;
             }
             __native_startup_state = __uninitialized;
diff --git a/sdk/lib/crt/startup/crtexe.c b/sdk/lib/crt/startup/crtexe.c
index a09d4b5b441..4e6f1e4d1f6 100644
--- a/sdk/lib/crt/startup/crtexe.c
+++ b/sdk/lib/crt/startup/crtexe.c
@@ -127,7 +127,7 @@ pre_c_init (void)
     __set_app_type(_GUI_APP);
   else
     __set_app_type (_CONSOLE_APP);
-  __onexitbegin = __onexitend = (_PVFV *) _encode_pointer ((_PVFV *)(-1));
+  __onexitbegin = __onexitend = (_PVFV *)(-1);
 
   * __MINGW_IMP_SYMBOL(_fmode) = _fmode;
   * __MINGW_IMP_SYMBOL(_commode) = _commode;

Reply via email to