By avoiding turning fprintf(stderr,) into fwrite(stderr,) we can localize the compat wrapping for that to fprintf. Then we shouldn't ever need to worry about functions needing init_compat to be called before they're invoked by the constructor.
This allows simplifying the ucrtbase_compat.c code quite significantly. Signed-off-by: Martin Storsjö <mar...@martin.st> --- Moved the -fno-builtin-fprintf to lib*_libmingw32_a_CFLAGS. --- mingw-w64-crt/Makefile.am | 4 ++++ mingw-w64-crt/crt/ucrtbase_compat.c | 42 +------------------------------------ 2 files changed, 5 insertions(+), 41 deletions(-) diff --git a/mingw-w64-crt/Makefile.am b/mingw-w64-crt/Makefile.am index 8e8494e..eaa0080 100644 --- a/mingw-w64-crt/Makefile.am +++ b/mingw-w64-crt/Makefile.am @@ -596,6 +596,7 @@ lib32_liblargeint_a_CPPFLAGS=$(CPPFLAGS32) $(sysincludes) lib32_LIBRARIES += lib32/libmingw32.a lib32_libmingw32_a_CPPFLAGS=$(CPPFLAGS32) -D_SYSCRT=1 -DCRTDLL=1 $(extra_include) $(AM_CPPFLAGS) +lib32_libmingw32_a_CFLAGS=-fno-builtin-fprintf $(AM_CFLAGS) lib32_libmingw32_a_SOURCES = $(src_libmingw32) lib32_LIBRARIES += lib32/libmingwex.a @@ -903,6 +904,7 @@ lib64_liblargeint_a_CPPFLAGS=$(CPPFLAGS64) $(sysincludes) lib64_LIBRARIES += lib64/libmingw32.a lib64_libmingw32_a_CPPFLAGS=$(CPPFLAGS64) -D_SYSCRT=1 -DCRTDLL=1 $(extra_include) $(AM_CPPFLAGS) +lib64_libmingw32_a_CFLAGS=-fno-builtin-fprintf $(AM_CFLAGS) lib64_libmingw32_a_SOURCES = $(src_libmingw32) lib64_LIBRARIES += lib64/libmingwex.a @@ -1208,6 +1210,7 @@ libarm32_liblargeint_a_CPPFLAGS=$(CPPFLAGSARM32) $(sysincludes) libarm32_LIBRARIES += libarm32/libmingw32.a libarm32_libmingw32_a_CPPFLAGS=$(CPPFLAGSARM32) -D_SYSCRT=1 -DCRTDLL=1 $(extra_include) $(AM_CPPFLAGS) +libarm32_libmingw32_a_CFLAGS=-fno-builtin-fprintf $(AM_CFLAGS) libarm32_libmingw32_a_SOURCES = $(src_libmingw32) libarm32_LIBRARIES += libarm32/libmingwex.a @@ -1465,6 +1468,7 @@ libarm64_liblargeint_a_CPPFLAGS=$(CPPFLAGSARM64) $(sysincludes) libarm64_LIBRARIES += libarm64/libmingw32.a libarm64_libmingw32_a_CPPFLAGS=$(CPPFLAGSARM64) -D_SYSCRT=1 -DCRTDLL=1 $(extra_include) $(AM_CPPFLAGS) +libarm64_libmingw32_a_CFLAGS=-fno-builtin-fprintf $(AM_CFLAGS) libarm64_libmingw32_a_SOURCES = $(src_libmingw32) libarm64_LIBRARIES += libarm64/libmingwex.a diff --git a/mingw-w64-crt/crt/ucrtbase_compat.c b/mingw-w64-crt/crt/ucrtbase_compat.c index 3d0fdbb..ca5381a 100644 --- a/mingw-w64-crt/crt/ucrtbase_compat.c +++ b/mingw-w64-crt/crt/ucrtbase_compat.c @@ -151,9 +151,7 @@ char ** __MINGW_IMP_SYMBOL(_wcmdln); // to work properly with ucrtbase.dll. #define _EXIT_LOCK1 8 -static int compat_inited; static CRITICAL_SECTION exit_lock; -static size_t (*real_fwrite)(const void *restrict, size_t, size_t, FILE *restrict); static char * (*real_setlocale)(int, const char*); static wchar_t * (*real__wsetlocale)(int, const wchar_t*); static int local__mb_cur_max; @@ -164,14 +162,11 @@ static void __cdecl free_locks(void) DeleteCriticalSection(&exit_lock); } -static void __cdecl init_compat(void) +static void __cdecl init_compat_dtor(void) { HANDLE ucrt; - if (compat_inited) - return; ucrt = GetModuleHandle("ucrtbase.dll"); - real_fwrite = (size_t (*)(const void *restrict, size_t, size_t, FILE *restrict)) GetProcAddress(ucrt, "fwrite"); real_setlocale = (char * (*)(int, const char*)) GetProcAddress(ucrt, "setlocale"); real__wsetlocale = (wchar_t * (*)(int, const wchar_t*)) GetProcAddress(ucrt, "_wsetlocale"); @@ -179,16 +174,6 @@ static void __cdecl init_compat(void) local__mb_cur_max = ___mb_cur_max_func(); - compat_inited = 1; -} - -static void __cdecl init_compat_dtor(void) -{ - init_compat(); - // atexit requires parts for this is inited at .CRT$XIAA, but we might need - // the compat init for fwrite (fprintf with a constant string) already in - // _pei386_runtime_relocator which for DLLs is run before the constructors - // in .CRT$XIAA. atexit(free_locks); } @@ -203,8 +188,6 @@ _CRTALLOC(".CRT$XID") _PVFV mingw_ucrtbase_compat_init = init_compat_dtor; char * __cdecl setlocale(int _Category, const char *_Locale) { char *ret; - if (!compat_inited) - init_compat(); ret = real_setlocale(_Category, _Locale); local__mb_cur_max = ___mb_cur_max_func(); return ret; @@ -213,8 +196,6 @@ char * __cdecl setlocale(int _Category, const char *_Locale) wchar_t * __cdecl _wsetlocale(int _Category, const wchar_t *_Locale) { wchar_t *ret; - if (!compat_inited) - init_compat(); ret = real__wsetlocale(_Category, _Locale); local__mb_cur_max = ___mb_cur_max_func(); return ret; @@ -256,8 +237,6 @@ FILE *__cdecl __iob_func(void) // files. int __cdecl vfprintf(FILE *ptr, const char *fmt, va_list ap) { - if (!compat_inited) - init_compat(); if (ptr != &local_iob[2]) abort(); return real_vfprintf(stderr, fmt, ap); @@ -267,8 +246,6 @@ int __cdecl fprintf(FILE *ptr, const char *fmt, ...) { va_list ap; int ret; - if (!compat_inited) - init_compat(); if (ptr != &local_iob[2]) abort(); va_start(ap, fmt); @@ -282,8 +259,6 @@ int __cdecl fwprintf(FILE *ptr, const wchar_t *fmt, ...) { va_list ap; int ret; - if (!compat_inited) - init_compat(); if (ptr != &local_iob[2]) abort(); va_start(ap, fmt); @@ -302,21 +277,6 @@ int __cdecl _snwprintf(wchar_t * restrict _Dest, size_t _Count, const wchar_t * return ret; } -// fprintf calls with a constant value can be rewritten to fwrite, -// but we need to catch any case of passing the compat dummy stderr -// before we call the real fwrite. -// Normally, init_compat is called via the CRTALLOC array, but if -// _pei386_runtime_relocator fails and tries to print to stderr, -// we can end up here before those constructors have been run. -size_t __cdecl fwrite(const void *restrict ptr, size_t size, size_t nitems, FILE *restrict stream) -{ - if (!compat_inited) - init_compat(); - if (stream == &local_iob[2]) - stream = stderr; - return real_fwrite(ptr, size, nitems, stream); -} - // This is called for wchar cases with __USE_MINGW_ANSI_STDIO enabled (where the // char case just uses fputc). The FILE* is a valid file here, shouldn't be our // dummy stderr. -- 2.7.4 ------------------------------------------------------------------------------ Check out the vibrant tech community on one of the world's most engaging tech sites, Slashdot.org! http://sdm.link/slashdot _______________________________________________ Mingw-w64-public mailing list Mingw-w64-public@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mingw-w64-public