When linking a DLL without using dllexport attributes or a def file, all global symbols are exported, unless they are excluded for one reason or another. GNU ld has got a list of libraries and object files to exclude, so any symbols from e.g. libmingwex or libmingw32 or dllcrt2.o won't get exported.
However, libmsvcrt is missing from that list (and libucrtbase obviously isn't present either). In LLD, libmsvcrt and libucrtbase are part of the library exclude list. By linking with -Wl,--exclude-libs,libucrtbase.a, one can manually request to exclude any symbols from this library. There are a number of exceptions to the rules for autoexporting (which aren't clearly documented but can be found in ld/pe-dll.c in GNU binutils). One that seems to cover the cases that currently are found in libmsvcrt.a, explaining why such symbols haven't been exported before, is that a symbol foo won't be exported, if a corresponding symbol __imp_foo also is defined. We can use this to add __imp_ prefixed symbols for symbols that strictly don't need it (where no calling code currently refers to it with a dllimport attribute). Make the _CRTALLOC pointer static with an attribute indicating that it is used and should be kept even though unreferenced. All in all, this avoids exporting unintentional symbols from DLLs that link to ucrtbase, even though it might be desireable to add libmsvcrt and libucrtbase to the built-in exclude list as well. Signed-off-by: Martin Storsjö <mar...@martin.st> --- mingw-w64-crt/crt/ucrtbase_compat.c | 16 +++++++++++++++- mingw-w64-crt/stdio/ucrt__vsnprintf.c | 1 + mingw-w64-crt/stdio/ucrt_fprintf.c | 1 + mingw-w64-crt/stdio/ucrt_printf.c | 1 + mingw-w64-crt/stdio/ucrt_snprintf.c | 1 + mingw-w64-crt/stdio/ucrt_sprintf.c | 1 + mingw-w64-crt/stdio/ucrt_vfprintf.c | 1 + mingw-w64-crt/stdio/ucrt_vprintf.c | 1 + mingw-w64-crt/stdio/ucrt_vsnprintf.c | 1 + mingw-w64-crt/stdio/ucrt_vsprintf.c | 1 + 10 files changed, 24 insertions(+), 1 deletion(-) diff --git a/mingw-w64-crt/crt/ucrtbase_compat.c b/mingw-w64-crt/crt/ucrtbase_compat.c index 53e44f6..9d580df 100644 --- a/mingw-w64-crt/crt/ucrtbase_compat.c +++ b/mingw-w64-crt/crt/ucrtbase_compat.c @@ -153,7 +153,7 @@ static void __cdecl init_compat_dtor(void) atexit(free_locks); } -_CRTALLOC(".CRT$XID") _PVFV mingw_ucrtbase_compat_init = init_compat_dtor; +static _CRTALLOC(".CRT$XID") __attribute__((__used__)) _PVFV mingw_ucrtbase_compat_init = init_compat_dtor; // These are required to provide the unrepfixed data symbols "timezone" @@ -226,6 +226,20 @@ int __cdecl __ms_fwprintf(FILE *file, const wchar_t *fmt, ...) va_end(ap); return ret; } + +// Dummy/unused __imp_ wrappers, to make GNU ld not autoexport these symbols. +int __cdecl (*__MINGW_IMP_SYMBOL(__getmainargs))(int *, char ***, char ***, int, _startupinfo *) = __getmainargs; +int __cdecl (*__MINGW_IMP_SYMBOL(__wgetmainargs))(int *, wchar_t ***, wchar_t ***, int, _startupinfo *) = __wgetmainargs; +_onexit_t __cdecl (*__MINGW_IMP_SYMBOL(__dllonexit))(_onexit_t, _PVFV**, _PVFV**) = __dllonexit; +void __cdecl (*__MINGW_IMP_SYMBOL(_amsg_exit))(int) = _amsg_exit; +unsigned int __cdecl (*__MINGW_IMP_SYMBOL(_get_output_format))(void) = _get_output_format; +void __cdecl (*__MINGW_IMP_SYMBOL(_tzset))(void) = _tzset; +void __cdecl (*__MINGW_IMP_SYMBOL(tzset))(void) = tzset; +void __cdecl (*__MINGW_IMP_SYMBOL(_lock))(int) = _lock; +void __cdecl (*__MINGW_IMP_SYMBOL(_unlock))(int) = _unlock; +int __cdecl (*__MINGW_IMP_SYMBOL(fwprintf))(FILE *, const wchar_t *, ...) = fwprintf; +int __cdecl (*__MINGW_IMP_SYMBOL(_snwprintf))(wchar_t *restrict, size_t, const wchar_t *restrict, ...) = _snwprintf; +int __cdecl (*__MINGW_IMP_SYMBOL(__ms_fwprintf))(FILE *, const wchar_t *, ...) = __ms_fwprintf; #ifdef __GNUC__ #pragma GCC diagnostic pop #endif diff --git a/mingw-w64-crt/stdio/ucrt__vsnprintf.c b/mingw-w64-crt/stdio/ucrt__vsnprintf.c index 6828007..58f29f1 100644 --- a/mingw-w64-crt/stdio/ucrt__vsnprintf.c +++ b/mingw-w64-crt/stdio/ucrt__vsnprintf.c @@ -12,3 +12,4 @@ int __cdecl _vsnprintf(char * __restrict__ _Dest,size_t _Count,const char * __re { return __stdio_common_vsprintf(UCRTBASE_PRINTF_LEGACY_VSPRINTF_NULL_TERMINATION, _Dest, _Count, _Format, NULL, _Args); } +int __cdecl (*__MINGW_IMP_SYMBOL(_vsnprintf))(char *__restrict__, size_t, const char *__restrict__, va_list) = _vsnprintf; diff --git a/mingw-w64-crt/stdio/ucrt_fprintf.c b/mingw-w64-crt/stdio/ucrt_fprintf.c index 021a12a..f61e002 100644 --- a/mingw-w64-crt/stdio/ucrt_fprintf.c +++ b/mingw-w64-crt/stdio/ucrt_fprintf.c @@ -17,3 +17,4 @@ int __cdecl fprintf(FILE * __restrict__ _File,const char * __restrict__ _Format, __builtin_va_end(ap); return ret; } +int __cdecl (*__MINGW_IMP_SYMBOL(fprintf))(FILE *__restrict__, const char *__restrict__, ...) = fprintf; diff --git a/mingw-w64-crt/stdio/ucrt_printf.c b/mingw-w64-crt/stdio/ucrt_printf.c index d4a6e82..3cbacd7 100644 --- a/mingw-w64-crt/stdio/ucrt_printf.c +++ b/mingw-w64-crt/stdio/ucrt_printf.c @@ -17,3 +17,4 @@ int __cdecl printf(const char * __restrict__ _Format,...) __builtin_va_end(ap); return ret; } +int __cdecl (*__MINGW_IMP_SYMBOL(printf))(const char *__restrict__, ...) = printf; diff --git a/mingw-w64-crt/stdio/ucrt_snprintf.c b/mingw-w64-crt/stdio/ucrt_snprintf.c index 4ef7761..893e182 100644 --- a/mingw-w64-crt/stdio/ucrt_snprintf.c +++ b/mingw-w64-crt/stdio/ucrt_snprintf.c @@ -17,3 +17,4 @@ int snprintf (char * __restrict__ __stream, size_t __n, const char * __restrict_ __builtin_va_end(ap); return ret; } +int __cdecl (*__MINGW_IMP_SYMBOL(snprintf))(char *__restrict__, size_t, const char *__restrict__, ...) = snprintf; diff --git a/mingw-w64-crt/stdio/ucrt_sprintf.c b/mingw-w64-crt/stdio/ucrt_sprintf.c index 74d665d..b9029d5 100644 --- a/mingw-w64-crt/stdio/ucrt_sprintf.c +++ b/mingw-w64-crt/stdio/ucrt_sprintf.c @@ -17,3 +17,4 @@ int __cdecl sprintf(char * __restrict__ _Dest,const char * __restrict__ _Format, __builtin_va_end(ap); return ret; } +int __cdecl (*__MINGW_IMP_SYMBOL(snprintf))(char *__restrict__, const char *__restrict__, ...) = sprintf; diff --git a/mingw-w64-crt/stdio/ucrt_vfprintf.c b/mingw-w64-crt/stdio/ucrt_vfprintf.c index 71cbb0d..801229f 100644 --- a/mingw-w64-crt/stdio/ucrt_vfprintf.c +++ b/mingw-w64-crt/stdio/ucrt_vfprintf.c @@ -12,3 +12,4 @@ int __cdecl vfprintf(FILE * __restrict__ _File,const char * __restrict__ _Format { return __stdio_common_vfprintf(0, _File, _Format, NULL, _ArgList); } +int __cdecl (*__MINGW_IMP_SYMBOL(vfprintf))(FILE *__restrict__, const char *__restrict__, va_list) = vfprintf; diff --git a/mingw-w64-crt/stdio/ucrt_vprintf.c b/mingw-w64-crt/stdio/ucrt_vprintf.c index 20b8881..0f7ef28 100644 --- a/mingw-w64-crt/stdio/ucrt_vprintf.c +++ b/mingw-w64-crt/stdio/ucrt_vprintf.c @@ -12,3 +12,4 @@ int __cdecl vprintf(const char * __restrict__ _Format,va_list _ArgList) { return __stdio_common_vfprintf(0, stdout, _Format, NULL, _ArgList); } +int __cdecl (*__MINGW_IMP_SYMBOL(vprintf))(const char *__restrict__, va_list) = vprintf; diff --git a/mingw-w64-crt/stdio/ucrt_vsnprintf.c b/mingw-w64-crt/stdio/ucrt_vsnprintf.c index f1b5a94..0e0fcfb 100644 --- a/mingw-w64-crt/stdio/ucrt_vsnprintf.c +++ b/mingw-w64-crt/stdio/ucrt_vsnprintf.c @@ -12,3 +12,4 @@ int vsnprintf (char * __restrict__ __stream, size_t __n, const char * __restrict { return __stdio_common_vsprintf(UCRTBASE_PRINTF_STANDARD_SNPRINTF_BEHAVIOUR, __stream, __n, __format, NULL, __local_argv); } +int __cdecl (*__MINGW_IMP_SYMBOL(vsnprintf))(char *__restrict__, size_t, const char *__restrict__, va_list) = vsnprintf; diff --git a/mingw-w64-crt/stdio/ucrt_vsprintf.c b/mingw-w64-crt/stdio/ucrt_vsprintf.c index d335240..3214ef9 100644 --- a/mingw-w64-crt/stdio/ucrt_vsprintf.c +++ b/mingw-w64-crt/stdio/ucrt_vsprintf.c @@ -12,3 +12,4 @@ int __cdecl vsprintf(char * __restrict__ _Dest,const char * __restrict__ _Format { return __stdio_common_vsprintf(UCRTBASE_PRINTF_STANDARD_SNPRINTF_BEHAVIOUR, _Dest, (size_t)-1, _Format, NULL, _Args); } +int __cdecl (*__MINGW_IMP_SYMBOL(vsprintf))(char *__restrict__, const char *__restrict__, va_list) = vsprintf; -- 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