https://git.reactos.org/?p=reactos.git;a=commitdiff;h=8a6d65304483b2cea0fef…
commit 8a6d65304483b2cea0fef4d7d35fa0b5b2a7db59
Author: Jérôme Gardou <jerome.gardou(a)reactos.org>
AuthorDate: Mon Dec 28 12:06:34 2020 +0100
Commit: Jérôme Gardou <zefklop(a)users.noreply.github.com>
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;