This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix up --enable-initfini-array autodetection in configure (PR bootstrap/50237)


Hi!

As discussed in the PR, compiling the initfini testcase with the
host compiler and running it is problematic for bootstrap, as
in stage1 we use the host compiler which might use one version of as/ld,
but stage2 is using stage1 compiler as host compiler and might use
a different as/ld.  If one of the linkers does support merging of
.init_array and .ctors properly and the other does not, we end up
with comparison failures e.g. because of go1 C++ sources.

The following patch attempts to perform a separate linker check
(grepping objdump of a linked binary) and checks so far glibc version
which is known to support .init_array properly.  Perhaps other
C libraries could be added there too (does e.g. Solaris support .init_array
properly, or FreeBSD, other OSes?).

Bootstrapped/regtested on x86_64-linux and i686-linux both with a linker
that does it right and a buggy one.

2012-01-18  Jakub Jelinek  <jakub@redhat.com>

	PR bootstrap/50237
	* config/initfini-array.h: Guard content of the header
	with #ifdef HAVE_INITFINI_ARRAY.
	* configure.ac: Move gcc_AC_INITFINI_ARRAY much later into the file.
	Add initfini-array.h to tm_file here.
	* acinclude.m4 (gcc_AC_INITFINI_ARRAY): For non-ia64 do a linker
	test.
	* config.gcc: Don't add initfini-array.h to tm_file here.
	* configure: Regenerated.

--- gcc/config/initfini-array.h.jj	2011-08-22 08:17:06.000000000 +0200
+++ gcc/config/initfini-array.h	2012-01-17 16:28:39.219571262 +0100
@@ -19,6 +19,8 @@
    along with GCC; see the file COPYING3.  If not see
    <http://www.gnu.org/licenses/>.  */
 
+#ifdef HAVE_INITFINI_ARRAY
+
 #define USE_INITFINI_ARRAY
 
 #undef INIT_SECTION_ASM_OP
@@ -35,3 +37,5 @@
 #define TARGET_ASM_CONSTRUCTOR default_elf_init_array_asm_out_constructor
 #undef TARGET_ASM_DESTRUCTOR
 #define TARGET_ASM_DESTRUCTOR default_elf_fini_array_asm_out_destructor
+
+#endif
--- gcc/configure.ac.jj	2012-01-13 21:47:35.000000000 +0100
+++ gcc/configure.ac	2012-01-17 16:28:00.461795315 +0100
@@ -1197,8 +1197,6 @@ fi
 CFLAGS="$saved_CFLAGS"
 CXXFLAGS="$saved_CXXFLAGS"
 
-gcc_AC_INITFINI_ARRAY
-
 # mkdir takes a single argument on some systems. 
 gcc_AC_FUNC_MKDIR_TAKES_ONE_ARG
 
@@ -1271,6 +1269,11 @@ if test x"$tmake_file" = x
 then tmake_file=$cpu_type/t-$cpu_type
 fi
 
+# Support --enable-initfini-array.
+if test x$enable_initfini_array != xno; then
+  tm_file="${tm_file} initfini-array.h"
+fi
+
 if test x"$dwarf2" = xyes
 then tm_file="$tm_file tm-dwarf2.h"
 fi
@@ -2422,6 +2425,8 @@ if test x$gcc_cv_ld_ro_rw_mix = xread-wr
 fi
 AC_MSG_RESULT($gcc_cv_ld_ro_rw_mix)
 
+gcc_AC_INITFINI_ARRAY
+
 # Check if we have .[us]leb128, and support symbol arithmetic with it.
 gcc_GAS_CHECK_FEATURE([.sleb128 and .uleb128], gcc_cv_as_leb128,
   [elf,2,11,0],,
--- gcc/acinclude.m4.jj	2011-08-26 18:41:44.000000000 +0200
+++ gcc/acinclude.m4	2012-01-18 20:41:51.448002554 +0100
@@ -376,119 +376,85 @@ AC_DEFUN([gcc_AC_INITFINI_ARRAY],
 AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support,
 		 gcc_cv_initfini_array, [dnl
   if test "x${build}" = "x${target}" && test "x${build}" = "x${host}"; then
-    AC_RUN_IFELSE([AC_LANG_SOURCE([
+    case "${target}" in
+      ia64-*)
+	AC_RUN_IFELSE([AC_LANG_SOURCE([
 #ifndef __ELF__
 #error Not an ELF OS
 #endif
-#ifdef __ia64__
 /* We turn on .preinit_array/.init_array/.fini_array support for ia64
    if it can be used.  */
 static int x = -1;
 int main (void) { return x; }
 int foo (void) { x = 0; }
 int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;
-#else
-extern void abort ();
-static int count;
-
-static void
-init1005 ()
-{
-  if (count != 0)
-    abort ();
-  count = 1005;
-}
-void (*const init_array1005[]) ()
-  __attribute__ ((section (".init_array.01005"), aligned (sizeof (void *))))
-  = { init1005 };
-static void
-fini1005 ()
-{
-  if (count != 1005)
-    abort ();
-}
-void (*const fini_array1005[]) ()
-  __attribute__ ((section (".fini_array.01005"), aligned (sizeof (void *))))
-  = { fini1005 };
-
-static void
-ctor1007 ()
-{
-  if (count != 1005)
-    abort ();
-  count = 1007;
-}
-void (*const ctors1007[]) ()
-  __attribute__ ((section (".ctors.64528"), aligned (sizeof (void *))))
-  = { ctor1007 };
-static void
-dtor1007 ()
-{
-  if (count != 1007)
-    abort ();
-  count = 1005;
-}
-void (*const dtors1007[]) ()
-  __attribute__ ((section (".dtors.64528"), aligned (sizeof (void *))))
-  = { dtor1007 };
-
-static void
-init65530 ()
-{
-  if (count != 1007)
-    abort ();
-  count = 65530;
-}
-void (*const init_array65530[]) ()
-  __attribute__ ((section (".init_array.65530"), aligned (sizeof (void *))))
-  = { init65530 };
-static void
-fini65530 ()
-{
-  if (count != 65530)
-    abort ();
-  count = 1007;
-}
-void (*const fini_array65530[]) ()
-  __attribute__ ((section (".fini_array.65530"), aligned (sizeof (void *))))
-  = { fini65530 };
-
-static void
-ctor65535 ()
-{
-  if (count != 65530)
-    abort ();
-  count = 65535;
-}
-void (*const ctors65535[]) ()
-  __attribute__ ((section (".ctors"), aligned (sizeof (void *))))
-  = { ctor65535 };
-static void
-dtor65535 ()
-{
-  if (count != 65535)
-    abort ();
-  count = 65530;
-}
-void (*const dtors65535[]) ()
-  __attribute__ ((section (".dtors"), aligned (sizeof (void *))))
-  = { dtor65535 };
-
-int
-main ()
-{
-  if (count != 65535)
-    abort ();
-  return 0;
-}
-#endif
 ])],
 	     [gcc_cv_initfini_array=yes], [gcc_cv_initfini_array=no],
-	     [gcc_cv_initfini_array=no])
-   else
-     AC_MSG_CHECKING(cross compile... guessing)
-     gcc_cv_initfini_array=no
-   fi])
+	     [gcc_cv_initfini_array=no]);;
+      *)
+	gcc_cv_initfini_array=no
+	if test $in_tree_ld = yes ; then
+	  if test "$gcc_cv_gld_major_version" -eq 2 \
+	     -a "$gcc_cv_gld_minor_version" -ge 22 \
+	     -o "$gcc_cv_gld_major_version" -gt 2 \
+	     && test $in_tree_ld_is_elf = yes; then
+	    gcc_cv_initfini_array=yes
+	  fi
+	elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then
+	  cat > conftest.s <<\EOF
+.section .dtors,"a",%progbits
+.balign 4
+.byte 'A', 'A', 'A', 'A'
+.section .ctors,"a",%progbits
+.balign 4
+.byte 'B', 'B', 'B', 'B'
+.section .fini_array.65530,"a",%progbits
+.balign 4
+.byte 'C', 'C', 'C', 'C'
+.section .init_array.65530,"a",%progbits
+.balign 4
+.byte 'D', 'D', 'D', 'D'
+.section .dtors.64528,"a",%progbits
+.balign 4
+.byte 'E', 'E', 'E', 'E'
+.section .ctors.64528,"a",%progbits
+.balign 4
+.byte 'F', 'F', 'F', 'F'
+.section .fini_array.01005,"a",%progbits
+.balign 4
+.byte 'G', 'G', 'G', 'G'
+.section .init_array.01005,"a",%progbits
+.balign 4
+.byte 'H', 'H', 'H', 'H'
+.text
+EOF
+	  if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \
+	     && $gcc_cv_ld -e 0 -o conftest conftest.o > /dev/null 2>&1 \
+	     && $gcc_cv_objdump -s -j .init_array conftest \
+		| grep HHHHFFFFDDDDBBBB > /dev/null 2>&1 \
+	     && $gcc_cv_objdump -s -j .fini_array conftest \
+		| grep GGGGEEEECCCCAAAA > /dev/null 2>&1; then
+	    gcc_cv_initfini_array=yes
+	  fi
+changequote(,)dnl
+	  rm -f conftest conftest.*
+changequote([,])dnl
+	fi
+	AC_PREPROC_IFELSE([AC_LANG_SOURCE([
+#ifndef __ELF__
+#error Not an ELF OS
+#endif
+#include <stdlib.h>
+#if defined __GLIBC_PREREQ && __GLIBC_PREREQ (2, 4)
+#else
+#error The C library not known to support .init_array/.fini_array
+#endif
+])],, [gcc_cv_initfini_array=no]);;
+    esac
+  else
+    AC_MSG_CHECKING(cross compile... guessing)
+    gcc_cv_initfini_array=no
+  fi])
   enable_initfini_array=$gcc_cv_initfini_array
 ])
 if test $enable_initfini_array = yes; then
--- gcc/config.gcc.jj	2012-01-02 20:39:59.000000000 +0100
+++ gcc/config.gcc	2012-01-17 16:26:54.442178715 +0100
@@ -2941,11 +2941,6 @@ if test x$with_schedule = x; then
 	esac
 fi
 
-# Support --enable-initfini-array.
-if test x$enable_initfini_array = xyes; then
-  tm_file="${tm_file} initfini-array.h"
-fi
-
 # Validate and mark as valid any --with options supported
 # by this target.  In order to use a particular --with option
 # you must list it in supported_defaults; validating the value
--- gcc/configure.jj	2012-01-13 21:47:35.000000000 +0100
+++ gcc/configure	2012-01-18 20:42:14.193761057 +0100
@@ -893,7 +893,6 @@ enable_languages
 with_multilib_list
 enable_rpath
 with_libiconv_prefix
-enable_initfini_array
 enable_sjlj_exceptions
 enable_secureplt
 enable_leading_mingw64_underscores
@@ -906,6 +905,7 @@ enable_fast_install
 enable_libtool_lock
 with_plugin_ld
 enable_gnu_indirect_function
+enable_initfini_array
 enable_comdat
 enable_gnu_unique_object
 enable_linker_build_id
@@ -1591,7 +1591,6 @@ Optional Features:
   --disable-shared        don't provide a shared libgcc
   --enable-languages=LIST specify which front-ends to build
   --disable-rpath         do not hardcode runtime library paths
-  --enable-initfini-array	use .init_array/.fini_array sections
   --enable-sjlj-exceptions
                           arrange to use setjmp/longjmp exception handling
   --enable-secureplt      enable -msecure-plt by default for PowerPC
@@ -1615,6 +1614,7 @@ Optional Features:
   --enable-gnu-indirect-function
                           enable the use of the @gnu_indirect_function to
                           glibc systems
+  --enable-initfini-array	use .init_array/.fini_array sections
   --enable-comdat         enable COMDAT group support
   --enable-gnu-unique-object
                           enable the use of the @gnu_unique_object ELF
@@ -10986,157 +10986,6 @@ fi
 CFLAGS="$saved_CFLAGS"
 CXXFLAGS="$saved_CXXFLAGS"
 
-# Check whether --enable-initfini-array was given.
-if test "${enable_initfini_array+set}" = set; then :
-  enableval=$enable_initfini_array;
-else
-
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for .preinit_array/.init_array/.fini_array support" >&5
-$as_echo_n "checking for .preinit_array/.init_array/.fini_array support... " >&6; }
-if test "${gcc_cv_initfini_array+set}" = set; then :
-  $as_echo_n "(cached) " >&6
-else
-    if test "x${build}" = "x${target}" && test "x${build}" = "x${host}"; then
-    if test "$cross_compiling" = yes; then :
-  gcc_cv_initfini_array=no
-else
-  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
-/* end confdefs.h.  */
-
-#ifndef __ELF__
-#error Not an ELF OS
-#endif
-#ifdef __ia64__
-/* We turn on .preinit_array/.init_array/.fini_array support for ia64
-   if it can be used.  */
-static int x = -1;
-int main (void) { return x; }
-int foo (void) { x = 0; }
-int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;
-#else
-extern void abort ();
-static int count;
-
-static void
-init1005 ()
-{
-  if (count != 0)
-    abort ();
-  count = 1005;
-}
-void (*const init_array1005) ()
-  __attribute__ ((section (".init_array.01005"), aligned (sizeof (void *))))
-  = { init1005 };
-static void
-fini1005 ()
-{
-  if (count != 1005)
-    abort ();
-}
-void (*const fini_array1005) ()
-  __attribute__ ((section (".fini_array.01005"), aligned (sizeof (void *))))
-  = { fini1005 };
-
-static void
-ctor1007 ()
-{
-  if (count != 1005)
-    abort ();
-  count = 1007;
-}
-void (*const ctors1007) ()
-  __attribute__ ((section (".ctors.64528"), aligned (sizeof (void *))))
-  = { ctor1007 };
-static void
-dtor1007 ()
-{
-  if (count != 1007)
-    abort ();
-  count = 1005;
-}
-void (*const dtors1007) ()
-  __attribute__ ((section (".dtors.64528"), aligned (sizeof (void *))))
-  = { dtor1007 };
-
-static void
-init65530 ()
-{
-  if (count != 1007)
-    abort ();
-  count = 65530;
-}
-void (*const init_array65530) ()
-  __attribute__ ((section (".init_array.65530"), aligned (sizeof (void *))))
-  = { init65530 };
-static void
-fini65530 ()
-{
-  if (count != 65530)
-    abort ();
-  count = 1007;
-}
-void (*const fini_array65530) ()
-  __attribute__ ((section (".fini_array.65530"), aligned (sizeof (void *))))
-  = { fini65530 };
-
-static void
-ctor65535 ()
-{
-  if (count != 65530)
-    abort ();
-  count = 65535;
-}
-void (*const ctors65535) ()
-  __attribute__ ((section (".ctors"), aligned (sizeof (void *))))
-  = { ctor65535 };
-static void
-dtor65535 ()
-{
-  if (count != 65535)
-    abort ();
-  count = 65530;
-}
-void (*const dtors65535) ()
-  __attribute__ ((section (".dtors"), aligned (sizeof (void *))))
-  = { dtor65535 };
-
-int
-main ()
-{
-  if (count != 65535)
-    abort ();
-  return 0;
-}
-#endif
-
-_ACEOF
-if ac_fn_c_try_run "$LINENO"; then :
-  gcc_cv_initfini_array=yes
-else
-  gcc_cv_initfini_array=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
-  conftest.$ac_objext conftest.beam conftest.$ac_ext
-fi
-
-   else
-     { $as_echo "$as_me:${as_lineno-$LINENO}: checking cross compile... guessing" >&5
-$as_echo_n "checking cross compile... guessing... " >&6; }
-     gcc_cv_initfini_array=no
-   fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_initfini_array" >&5
-$as_echo "$gcc_cv_initfini_array" >&6; }
-  enable_initfini_array=$gcc_cv_initfini_array
-
-fi
-
-if test $enable_initfini_array = yes; then
-
-$as_echo "#define HAVE_INITFINI_ARRAY 1" >>confdefs.h
-
-fi
-
 # mkdir takes a single argument on some systems.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking if mkdir takes one argument" >&5
 $as_echo_n "checking if mkdir takes one argument... " >&6; }
@@ -11255,6 +11104,11 @@ if test x"$tmake_file" = x
 then tmake_file=$cpu_type/t-$cpu_type
 fi
 
+# Support --enable-initfini-array.
+if test x$enable_initfini_array != xno; then
+  tm_file="${tm_file} initfini-array.h"
+fi
+
 if test x"$dwarf2" = xyes
 then tm_file="$tm_file tm-dwarf2.h"
 fi
@@ -18116,7 +17970,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 18119 "configure"
+#line 17973 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -18222,7 +18076,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 18225 "configure"
+#line 18079 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -22496,6 +22350,130 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_ld_ro_rw_mix" >&5
 $as_echo "$gcc_cv_ld_ro_rw_mix" >&6; }
 
+# Check whether --enable-initfini-array was given.
+if test "${enable_initfini_array+set}" = set; then :
+  enableval=$enable_initfini_array;
+else
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for .preinit_array/.init_array/.fini_array support" >&5
+$as_echo_n "checking for .preinit_array/.init_array/.fini_array support... " >&6; }
+if test "${gcc_cv_initfini_array+set}" = set; then :
+  $as_echo_n "(cached) " >&6
+else
+    if test "x${build}" = "x${target}" && test "x${build}" = "x${host}"; then
+    case "${target}" in
+      ia64-*)
+	if test "$cross_compiling" = yes; then :
+  gcc_cv_initfini_array=no
+else
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifndef __ELF__
+#error Not an ELF OS
+#endif
+/* We turn on .preinit_array/.init_array/.fini_array support for ia64
+   if it can be used.  */
+static int x = -1;
+int main (void) { return x; }
+int foo (void) { x = 0; }
+int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;
+
+_ACEOF
+if ac_fn_c_try_run "$LINENO"; then :
+  gcc_cv_initfini_array=yes
+else
+  gcc_cv_initfini_array=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
+  conftest.$ac_objext conftest.beam conftest.$ac_ext
+fi
+;;
+      *)
+	gcc_cv_initfini_array=no
+	if test $in_tree_ld = yes ; then
+	  if test "$gcc_cv_gld_major_version" -eq 2 \
+	     -a "$gcc_cv_gld_minor_version" -ge 22 \
+	     -o "$gcc_cv_gld_major_version" -gt 2 \
+	     && test $in_tree_ld_is_elf = yes; then
+	    gcc_cv_initfini_array=yes
+	  fi
+	elif test x$gcc_cv_as != x -a x$gcc_cv_ld != x -a x$gcc_cv_objdump != x ; then
+	  cat > conftest.s <<\EOF
+.section .dtors,"a",%progbits
+.balign 4
+.byte 'A', 'A', 'A', 'A'
+.section .ctors,"a",%progbits
+.balign 4
+.byte 'B', 'B', 'B', 'B'
+.section .fini_array.65530,"a",%progbits
+.balign 4
+.byte 'C', 'C', 'C', 'C'
+.section .init_array.65530,"a",%progbits
+.balign 4
+.byte 'D', 'D', 'D', 'D'
+.section .dtors.64528,"a",%progbits
+.balign 4
+.byte 'E', 'E', 'E', 'E'
+.section .ctors.64528,"a",%progbits
+.balign 4
+.byte 'F', 'F', 'F', 'F'
+.section .fini_array.01005,"a",%progbits
+.balign 4
+.byte 'G', 'G', 'G', 'G'
+.section .init_array.01005,"a",%progbits
+.balign 4
+.byte 'H', 'H', 'H', 'H'
+.text
+EOF
+	  if $gcc_cv_as -o conftest.o conftest.s > /dev/null 2>&1 \
+	     && $gcc_cv_ld -e 0 -o conftest conftest.o > /dev/null 2>&1 \
+	     && $gcc_cv_objdump -s -j .init_array conftest \
+		| grep HHHHFFFFDDDDBBBB > /dev/null 2>&1 \
+	     && $gcc_cv_objdump -s -j .fini_array conftest \
+		| grep GGGGEEEECCCCAAAA > /dev/null 2>&1; then
+	    gcc_cv_initfini_array=yes
+	  fi
+	  rm -f conftest conftest.*
+	fi
+	cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+
+#ifndef __ELF__
+#error Not an ELF OS
+#endif
+#include <stdlib.h>
+#if defined __GLIBC_PREREQ && __GLIBC_PREREQ (2, 4)
+#else
+#error The C library not known to support .init_array/.fini_array
+#endif
+
+_ACEOF
+if ac_fn_c_try_cpp "$LINENO"; then :
+
+else
+  gcc_cv_initfini_array=no
+fi
+rm -f conftest.err conftest.$ac_ext;;
+    esac
+  else
+    { $as_echo "$as_me:${as_lineno-$LINENO}: checking cross compile... guessing" >&5
+$as_echo_n "checking cross compile... guessing... " >&6; }
+    gcc_cv_initfini_array=no
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_initfini_array" >&5
+$as_echo "$gcc_cv_initfini_array" >&6; }
+  enable_initfini_array=$gcc_cv_initfini_array
+
+fi
+
+if test $enable_initfini_array = yes; then
+
+$as_echo "#define HAVE_INITFINI_ARRAY 1" >>confdefs.h
+
+fi
+
 # Check if we have .[us]leb128, and support symbol arithmetic with it.
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for .sleb128 and .uleb128" >&5
 $as_echo_n "checking assembler for .sleb128 and .uleb128... " >&6; }

	Jakub


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]