Using the __clang__ ifdef isn't right; one could be using clang for compiling the mingw-w64 crt for use with binutils ld, which requires a slightly different setup of __CTOR_LIST__.
Also, to ease interoperability between binutils ld and lld, lld could potentially start providing the __CTOR_LIST__ symbol, and in that case we shouldn't be providing it ourselves either. Signed-off-by: Martin Storsjö <mar...@martin.st> --- This time by setting ac_no_link=no temporarily at the same time as we are adding -nostdlib to LDFLAGS, to allow running the linker test even though target libraries aren't necessarily available yet. --- mingw-w64-crt/configure.ac | 48 +++++++++++++++++++++++++++++++++++++++++++++ mingw-w64-crt/crt/crtdll.c | 6 +++++- mingw-w64-crt/crt/crtexe.c | 6 +++++- mingw-w64-crt/crt/gccmain.c | 8 +++++++- 4 files changed, 65 insertions(+), 3 deletions(-) diff --git a/mingw-w64-crt/configure.ac b/mingw-w64-crt/configure.ac index 6a42109..a492c1b 100644 --- a/mingw-w64-crt/configure.ac +++ b/mingw-w64-crt/configure.ac @@ -301,6 +301,54 @@ AC_ARG_ENABLE([tests-unicode], AM_CONDITIONAL([ENABLE_TESTS_UNICODE],[test x$enable_tests_unicode = xyes]) AC_MSG_RESULT([$enable_tests_unicode]) +AC_MSG_CHECKING([whether the linker provides __CTOR_LIST__]) +saved_LDFLAGS="$LDFLAGS" +saved_ac_no_link="$ac_no_link" +LDFLAGS="$LDFLAGS -nostdlib" +# Force ac_no_link to "no". When bootstrapping an environment, autoconf will +# earlier conclude that linking isn't possible (since -lmingw32 etc are +# missing), and set ac_no_link=yes. This forbids us from doing a test with +# AC_LINK_IFELSE here, even though we are knowingly setting -nostdlib, to +# make this specific testcase work even though the normally linked libraries +# aren't available yet. Override this variable to allow us to perform the link +# test. +ac_no_link=no +# Note that binutils 2.30 is broken with respect to __CTOR_LIST__ (the change +# was reverted for 2.31); it does provide __CTOR_LIST__ automatically only if +# necessary. But as long as there's no other definition of it, a fallback +# __CTOR_LIST__ gets pulled in from libgcc, and this fallback is only a dummy +# to prevent linker errors (in general) and isn't assigned to the right +# sections. Therefore, it'd be better to test whether we can/should provide +# our own __CTOR_LIST__. + +# But we can't test whether we can provide our own __CTOR_LIST__ with binutils +# ld either; even if our test provides its own symbol __CTOR_LIST__, ld will +# include it but silently use its own provided __CTOR_LIST__ instead, and +# won't error out. For actual real use, that'd mean a stray broken pointer in +# the .ctors section. + +# This test uses both mainCRTStartup and main functions, to let lld deduce +# entry point and subsystem automatically without having to manually specify, +# anything. And as long as main() is provided, we need to implicitly provide +# __main as well, since the compiler injects a call to it. +AC_LINK_IFELSE([AC_LANG_SOURCE([[ +#include <stdint.h> +extern const void * __CTOR_LIST__; +void __main(void) { +} +int main(void) { + return (int)(intptr_t)__CTOR_LIST__; +} +int mainCRTStartup(void) { + return main(); +} +]])], +[AC_DEFINE([HAVE_CTOR_LIST],[1],[Whether the linker provides __CTOR_LIST__]) +AC_MSG_RESULT(yes)], +[AC_MSG_RESULT(no)]) +LDFLAGS="$saved_LDFLAGS" +ac_no_link="$saved_ac_no_link" + # Checks for libraries. # Checks for header files. diff --git a/mingw-w64-crt/crt/crtdll.c b/mingw-w64-crt/crt/crtdll.c index 5f53602..6187f10 100644 --- a/mingw-w64-crt/crt/crtdll.c +++ b/mingw-w64-crt/crt/crtdll.c @@ -10,6 +10,10 @@ #define _DLL #endif +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #include <oscalls.h> #include <internal.h> #include <stdlib.h> @@ -40,7 +44,7 @@ extern _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[]; extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[]; extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[]; -#ifdef __clang__ +#ifndef HAVE_CTOR_LIST __attribute__ (( __section__ (".ctors"), __used__ , aligned(sizeof(void *)))) const void * __CTOR_LIST__ = (void *) -1; __attribute__ (( __section__ (".dtors"), __used__ , aligned(sizeof(void *)))) const void * __DTOR_LIST__ = (void *) -1; __attribute__ (( __section__ (".ctors.99999"), __used__ , aligned(sizeof(void *)))) const void * __CTOR_END__ = (void *) 0; diff --git a/mingw-w64-crt/crt/crtexe.c b/mingw-w64-crt/crt/crtexe.c index 80e0556..361afd2 100644 --- a/mingw-w64-crt/crt/crtexe.c +++ b/mingw-w64-crt/crt/crtexe.c @@ -9,6 +9,10 @@ #define _DLL #endif +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + #define SPECIAL_CRTEXE #include <oscalls.h> @@ -64,7 +68,7 @@ extern _CRTALLOC(".CRT$XIZ") _PIFV __xi_z[]; extern _CRTALLOC(".CRT$XCA") _PVFV __xc_a[]; extern _CRTALLOC(".CRT$XCZ") _PVFV __xc_z[]; -#ifdef __clang__ +#ifndef HAVE_CTOR_LIST __attribute__ (( __section__ (".ctors"), __used__ , aligned(sizeof(void *)))) const void * __CTOR_LIST__ = (void *) -1; __attribute__ (( __section__ (".dtors"), __used__ , aligned(sizeof(void *)))) const void * __DTOR_LIST__ = (void *) -1; __attribute__ (( __section__ (".ctors.99999"), __used__ , aligned(sizeof(void *)))) const void * __CTOR_END__ = (void *) 0; diff --git a/mingw-w64-crt/crt/gccmain.c b/mingw-w64-crt/crt/gccmain.c index 54cbf02..030cdce 100644 --- a/mingw-w64-crt/crt/gccmain.c +++ b/mingw-w64-crt/crt/gccmain.c @@ -8,6 +8,10 @@ #include <stdlib.h> #include <setjmp.h> +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + typedef void (*func_ptr) (void); extern func_ptr __CTOR_LIST__[]; extern func_ptr __DTOR_LIST__[]; @@ -28,7 +32,9 @@ __do_global_dtors (void) } } -#ifdef __clang__ +#ifndef HAVE_CTOR_LIST +// If the linker didn't provide __CTOR_LIST__, we provided it ourselves, +// and then we also know we have __CTOR_END__ available. extern func_ptr __CTOR_END__[]; extern func_ptr __DTOR_END__[]; -- 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