This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
PATCH: PR other/49325: Incorrect target HAVE_INITFINI_ARRAY check
- From: "H.J. Lu" <hongjiu dot lu at intel dot com>
- To: gcc-patches at gcc dot gnu dot org
- Cc: bonzini at gnu dot org, Ralf dot Wildenhues at gmx dot de
- Date: Wed, 8 Jun 2011 09:49:08 -0700
- Subject: PATCH: PR other/49325: Incorrect target HAVE_INITFINI_ARRAY check
- Reply-to: "H.J. Lu" <hjl dot tools at gmail dot com>
Hi,
Target HAVE_INITFINI_ARRAY support was added by:
http://gcc.gnu.org/ml/gcc-patches/2002-11/msg00387.html
Unfortunately, it checks if host supports init_array/fini_array
sections, not target. It will generate wrong result for cross compiler.
This patch uses the target compiler instead of host compiler to check
this feature. For ia64, we set HAVE_INITFINI_ARRAY to 1 if
init_array/fini_array section can be used. For other targets, we
set it only if we can mix init_array/fini_array sections with
ctors/dtors sections. OK for trunk?
Thanks.
H.J.
---
2011-06-07 H.J. Lu <hongjiu.lu@intel.com>
PR other/49325
* acinclude.m4 (gcc_AC_INITFINI_ARRAY): Removed.
* configure.ac: Remove gcc_AC_INITFINI_ARRAY. Add
--enable-initfini-array and check if .init_array can be used with
.ctors.
* configure: Regenerated.
diff --git a/gcc/acinclude.m4 b/gcc/acinclude.m4
index 3eec559..0f5f686 100644
--- a/gcc/acinclude.m4
+++ b/gcc/acinclude.m4
@@ -369,26 +369,6 @@ else
fi
fi])
-AC_DEFUN([gcc_AC_INITFINI_ARRAY],
-[AC_ARG_ENABLE(initfini-array,
- [ --enable-initfini-array use .init_array/.fini_array sections],
- [], [
-AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support,
- gcc_cv_initfini_array, [dnl
- AC_RUN_IFELSE([AC_LANG_SOURCE([
-static int x = -1;
-int main (void) { return x; }
-int foo (void) { x = 0; }
-int (*fp) (void) __attribute__ ((section (".init_array"))) = foo;])],
- [gcc_cv_initfini_array=yes], [gcc_cv_initfini_array=no],
- [gcc_cv_initfini_array=no])])
- enable_initfini_array=$gcc_cv_initfini_array
-])
-if test $enable_initfini_array = yes; then
- AC_DEFINE(HAVE_INITFINI_ARRAY, 1,
- [Define .init_array/.fini_array sections are available and working.])
-fi])
-
dnl # _gcc_COMPUTE_GAS_VERSION
dnl # Used by gcc_GAS_VERSION_GTE_IFELSE
dnl #
diff --git a/gcc/configure b/gcc/configure
index a373518..a23e2fa 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -10447,6 +10447,7 @@ fi
# Restore CFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
CFLAGS="$saved_CFLAGS"
+# Check if .init_array can be used with .ctors.
# Check whether --enable-initfini-array was given.
if test "${enable_initfini_array+set}" = set; then :
enableval=$enable_initfini_array;
@@ -10457,16 +10458,114 @@ $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}" ; then
if test "$cross_compiling" = yes; then :
gcc_cv_initfini_array=no
else
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
/* end confdefs.h. */
+#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 ()
+{
+ return 0;
+}
+#endif
+
_ACEOF
if ac_fn_c_try_run "$LINENO"; then :
gcc_cv_initfini_array=yes
@@ -10477,6 +10576,9 @@ rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \
conftest.$ac_objext conftest.beam conftest.$ac_ext
fi
+ else
+ 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; }
@@ -17517,7 +17619,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 17520 "configure"
+#line 17622 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
@@ -17623,7 +17725,7 @@ else
lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
lt_status=$lt_dlunknown
cat > conftest.$ac_ext <<_LT_EOF
-#line 17626 "configure"
+#line 17728 "configure"
#include "confdefs.h"
#if HAVE_DLFCN_H
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 5e41479..0347b43 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -1134,7 +1134,126 @@ fi
# Restore CFLAGS from before the gcc_AC_NEED_DECLARATIONS tests.
CFLAGS="$saved_CFLAGS"
-gcc_AC_INITFINI_ARRAY
+# Check if .init_array can be used with .ctors.
+AC_ARG_ENABLE(initfini-array,
+ [ --enable-initfini-array use .init_array/.fini_array sections],
+ [], [
+AC_CACHE_CHECK(for .preinit_array/.init_array/.fini_array support,
+ gcc_cv_initfini_array, [dnl
+ if test "x${build}" = "x${target}" ; then
+ AC_RUN_IFELSE([AC_LANG_SOURCE([
+#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 ()
+{
+ return 0;
+}
+#endif
+])],
+ [gcc_cv_initfini_array=yes], [gcc_cv_initfini_array=no],
+ [gcc_cv_initfini_array=no])
+ else
+ gcc_cv_initfini_array=no
+ fi])
+ enable_initfini_array=$gcc_cv_initfini_array
+])
+if test $enable_initfini_array = yes; then
+ AC_DEFINE(HAVE_INITFINI_ARRAY, 1,
+ [Define .init_array/.fini_array sections are available and working.])
+fi
# mkdir takes a single argument on some systems.
gcc_AC_FUNC_MKDIR_TAKES_ONE_ARG