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>
---
 mingw-w64-crt/configure.ac  | 38 ++++++++++++++++++++++++++++++++++++++
 mingw-w64-crt/crt/crtdll.c  |  6 +++++-
 mingw-w64-crt/crt/crtexe.c  |  6 +++++-
 mingw-w64-crt/crt/gccmain.c |  8 +++++++-
 4 files changed, 55 insertions(+), 3 deletions(-)

diff --git a/mingw-w64-crt/configure.ac b/mingw-w64-crt/configure.ac
index 6a42109..b235885 100644
--- a/mingw-w64-crt/configure.ac
+++ b/mingw-w64-crt/configure.ac
@@ -301,6 +301,44 @@ 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"
+LDFLAGS="$LDFLAGS -nostdlib"
+# 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"
+
 # 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

Reply via email to