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...@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