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

Reply via email to