[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
This commit is contained in:
Jérôme Gardou 2020-12-28 12:06:34 +01:00 committed by Jérôme Gardou
parent 6c6d9bee68
commit 8a6d653044
4 changed files with 51 additions and 43 deletions

View file

@ -883,7 +883,7 @@
@ stub -version=0x600+ -arch=i386 _msize_debug @ stub -version=0x600+ -arch=i386 _msize_debug
@ cdecl _nextafter(double double) @ cdecl _nextafter(double double)
@ stub -arch=x86_64 _nextafterf @ 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) @ varargs _open(str long)
@ cdecl _open_osfhandle(long long) @ cdecl _open_osfhandle(long long)
@ extern _osplatform @ extern _osplatform
@ -1293,7 +1293,7 @@
@ cdecl atan2(double double) @ cdecl atan2(double double)
@ cdecl -arch=x86_64,arm atan2f(long) @ cdecl -arch=x86_64,arm atan2f(long)
@ cdecl -arch=x86_64,arm atanf(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 atof(str)
@ cdecl atoi(str) @ cdecl atoi(str)
@ cdecl atol(str) @ cdecl atol(str)

View file

@ -4,7 +4,6 @@
* No warranty is given; refer to the file DISCLAIMER.PD within this package. * No warranty is given; refer to the file DISCLAIMER.PD within this package.
*/ */
#undef CRTDLL
#ifndef _DLL #ifndef _DLL
#define _DLL #define _DLL
#endif #endif
@ -20,7 +19,7 @@
void __cdecl _lock (int _File); void __cdecl _lock (int _File);
void __cdecl _unlock (int _File); void __cdecl _unlock (int _File);
_PVFV *__onexitbegin; _PVFV *__onexitbegin;
_PVFV *__onexitend; _PVFV *__onexitend;
@ -33,16 +32,19 @@ void __call_atexit(void)
/* Note: should only be called with the exit lock held */ /* Note: should only be called with the exit lock held */
_PVFV *first, *last; _PVFV *first, *last;
first = (_PVFV *)_decode_pointer(__onexitbegin); if (!__onexitbegin)
last = (_PVFV *)_decode_pointer(__onexitend);; return;
if (!first) return; first = (_PVFV *)_decode_pointer(__onexitbegin);
last = (_PVFV *)_decode_pointer(__onexitend);
while (--last >= first) while (--last >= first)
if (*last) if (*last)
(**last)(); (**last)();
free(first); free(first);
__onexitbegin = __onexitend = NULL;
} }
/* Choose a different name to prevent name conflicts. The CRT one works fine. */ /* 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) _onexit_t __cdecl _onexit(_onexit_t func)
{ {
_PVFV *onexitbegin; _PVFV *onexitbegin;
_PVFV *onexitend; _PVFV *onexitend;
_onexit_t retval; _onexit_t retval;
onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin); #ifndef CRTDLL
if (__onexitbegin == (_PVFV *) -1)
if (onexitbegin == (_PVFV *) -1) return (* __MINGW_IMP_SYMBOL(_onexit)) (func);
#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);
#endif #endif
_lock (_EXIT_LOCK1);
onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin);
onexitend = (_PVFV *) _decode_pointer (__onexitend);
retval = __dllonexit (func, &onexitbegin, &onexitend);
__onexitbegin = (_PVFV *) _encode_pointer (onexitbegin); _lock (_EXIT_LOCK1);
__onexitend = (_PVFV *) _encode_pointer (onexitend);
_unlock (_EXIT_LOCK1); if (!__onexitbegin)
return retval; {
/* 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 int __cdecl

View file

@ -62,14 +62,8 @@ static int
__cdecl __cdecl
pre_c_init (void) 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; return 0;
} }
@ -136,14 +130,15 @@ WINBOOL WINAPI _CRT_INIT (HANDLE hDllHandle, DWORD dwReason, LPVOID lpreserved)
} }
else else
{ {
_PVFV * onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin); if (__onexitbegin)
if (onexitbegin)
{ {
_PVFV *onexitbegin = (_PVFV *) _decode_pointer (__onexitbegin);
_PVFV *onexitend = (_PVFV *) _decode_pointer (__onexitend); _PVFV *onexitend = (_PVFV *) _decode_pointer (__onexitend);
while (--onexitend >= onexitbegin) while (--onexitend >= onexitbegin)
if (*onexitend != NULL) if (*onexitend != NULL)
(**onexitend) (); (**onexitend) ();
free (onexitbegin); if (!lpreserved)
free(onexitbegin);
__onexitbegin = __onexitend = (_PVFV *) NULL; __onexitbegin = __onexitend = (_PVFV *) NULL;
} }
__native_startup_state = __uninitialized; __native_startup_state = __uninitialized;

View file

@ -127,7 +127,7 @@ pre_c_init (void)
__set_app_type(_GUI_APP); __set_app_type(_GUI_APP);
else else
__set_app_type (_CONSOLE_APP); __set_app_type (_CONSOLE_APP);
__onexitbegin = __onexitend = (_PVFV *) _encode_pointer ((_PVFV *)(-1)); __onexitbegin = __onexitend = (_PVFV *)(-1);
* __MINGW_IMP_SYMBOL(_fmode) = _fmode; * __MINGW_IMP_SYMBOL(_fmode) = _fmode;
* __MINGW_IMP_SYMBOL(_commode) = _commode; * __MINGW_IMP_SYMBOL(_commode) = _commode;