ucrtbase: Make sure that compat symbols aren't autoexported
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ö <martin@martin.st>
diff --git a/mingw-w64-crt/crt/ucrtbase_compat.c b/mingw-w64-crt/crt/ucrtbase_compat.c
index 53e44f6..cb4e827 100644
--- a/mingw-w64-crt/crt/ucrtbase_compat.c
+++ b/mingw-w64-crt/crt/ucrtbase_compat.c
@@ -153,7 +153,7 @@
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,19 @@
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(_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 @@
{
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 @@
__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 @@
__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 @@
__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 @@
__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 @@
{
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 @@
{
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 @@
{
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 @@
{
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;