2010-09-26  Nathan Sidwell  <nathan@codesourcery.com>

	* configure.ac: Add --enable-indirect-function option.
	* config.gcc: Add default_gnu_indirect_function.
	* config.in (HAVE_GAS_INDIRECT_FUNCTION): Rename to ...
	(HAVE_GNU_INDIRECT_FUNCTION): ... this.
	* varasm.c (do_assemble_alias): Adjust for macto name change.
	* configure: Rebuilt.
	* doc/install.texi: Document --enable-indirect-function.

	testsuite/
	* lib/target-supports-dg.exp (dg-require-ifunc): Remove extraneous
	alias checking.
	* lib/target-supports.exp (check_ifunc_available): Likewise.

Index: doc/install.texi
===================================================================
--- doc/install.texi	(revision 164584)
+++ doc/install.texi	(working copy)
@@ -1229,6 +1229,10 @@
 only available on systems with GNU libc.  When enabled, this will cause
 @option{-fuse-cxa-atexit} to be passed by default.
 
+@item --enable-indirect-function
+Define if you want to enable the ifunc attribute.  This option is
+currently only available on systems with GNU libc on certain targets.
+
 @item --enable-target-optspace
 Specify that target
 libraries should be optimized for code space instead of code speed.
Index: configure
===================================================================
--- configure	(revision 164584)
+++ configure	(working copy)
@@ -905,6 +905,7 @@
 enable_fast_install
 enable_libtool_lock
 with_plugin_ld
+enable_gnu_indirect_function
 enable_comdat
 enable_gnu_unique_object
 enable_linker_build_id
@@ -1611,6 +1612,9 @@
   --enable-fast-install[=PKGS]
                           optimize for fast installation [default=yes]
   --disable-libtool-lock  avoid locking (might break parallel builds)
+  --enable-gnu-indirect-function
+                          enable the use of the @gnu_indirect_function to
+                          glibc systems
   --enable-comdat         enable COMDAT group support
   --enable-gnu-unique-object	enable the use of the @gnu_unique_object ELF extension on
 				glibc systems
@@ -17139,7 +17143,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 17142 "configure"
+#line 17146 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -17245,7 +17249,7 @@
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<_LT_EOF
-#line 17248 "configure"
+#line 17252 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -21332,43 +21336,21 @@
 # gnu_indirect_function type is an extension proposed at
 # http://groups.google/com/group/generic-abi/files. It allows dynamic runtime
 # selection of function implementation
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for gnu_indirect_function" >&5
-$as_echo_n "checking assembler for gnu_indirect_function... " >&6; }
-if test "${gcc_cv_as_indirect_function+set}" = set; then :
-  $as_echo_n "(cached) " >&6
+# Check whether --enable-gnu-indirect-function was given.
+if test "${enable_gnu_indirect_function+set}" = set; then :
+  enableval=$enable_gnu_indirect_function; case $enable_gnu_indirect_function in
+    yes | no) ;;
+    *) as_fn_error "'$enable_gnu_indirect_function' is an invalid value for --enable-gnu-indirect-function.
+Valid choices are 'yes' and 'no'." "$LINENO" 5 ;;
+  esac
 else
-  gcc_cv_as_indirect_function=no
-    if test $in_tree_gas = yes; then
-    if test $in_tree_gas_is_elf = yes \
-  && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 20 \) \* 1000 + 1`
-  then gcc_cv_as_indirect_function=yes
+  enable_gnu_indirect_function="$default_gnu_indirect_function"
 fi
-  elif test x$gcc_cv_as != x; then
-    echo '	.type  Foo, @gnu_indirect_function
-Foo:' > conftest.s
-    if { ac_try='$gcc_cv_as $gcc_cv_as_flags  -o conftest.o conftest.s >&5'
-  { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
-  (eval $ac_try) 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }
-    then
-	gcc_cv_as_indirect_function=yes
-    else
-      echo "configure: failed program was" >&5
-      cat conftest.s >&5
-    fi
-    rm -f conftest.o conftest.s
-  fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_indirect_function" >&5
-$as_echo "$gcc_cv_as_indirect_function" >&6; }
 
+if test x$enable_gnu_indirect_function = xyes; then
 
-if test $gcc_cv_as_indirect_function = yes ; then
+$as_echo "#define HAVE_GNU_INDIRECT_FUNCTION 1" >>confdefs.h
 
-$as_echo "#define HAVE_GAS_INDIRECT_FUNCTION 1" >>confdefs.h
-
 fi
 
 if test $in_tree_ld != yes ; then
Index: testsuite/lib/target-supports-dg.exp
===================================================================
--- testsuite/lib/target-supports-dg.exp	(revision 164584)
+++ testsuite/lib/target-supports-dg.exp	(working copy)
@@ -94,12 +94,7 @@
 # test.
 
 proc dg-require-ifunc { args } {
-    set ifunc_available [ check_ifunc_available ]
-    if { $ifunc_available == -1 } {
-	upvar name name
-	unresolved "$name"
-    }
-    if { $ifunc_available < 2 } {
+    if { ![ check_ifunc_available ] } {
 	upvar dg-do-what dg-do-what
 	set dg-do-what [list [lindex ${dg-do-what} 0] "N" "P"]
     }
Index: testsuite/lib/target-supports.exp
===================================================================
--- testsuite/lib/target-supports.exp	(revision 164584)
+++ testsuite/lib/target-supports.exp	(working copy)
@@ -372,12 +372,10 @@
 # proc check_ifunc_available { }
 ###############################
 
-# Determine if the target toolchain supports the alias attribute.
+# Determine if the target toolchain supports the ifunc attribute.
 
-# Returns 2 if the target supports aliases.  Returns 1 if the target
-# only supports weak aliased.  Returns 0 if the target does not
-# support aliases at all.  Returns -1 if support for aliases could not
-# be determined.
+# Returns 1 if the target supports ifunc.  Returns 0 if the target
+# does not support ifunc.
 
 proc check_ifunc_available { } {
     global ifunc_available_saved
@@ -390,26 +388,19 @@
 	set obj ifunc[pid].o
         verbose "check_ifunc_available  compiling testfile $src" 2
 	set f [open $src "w"]
-	# Compile a small test program.  The definition of "g" is
-	# necessary to keep the Solaris assembler from complaining
-	# about the program.
-	puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif\n"
-	puts $f "void g() {} void f() __attribute__((ifunc(\"g\")));"
+	puts $f "#endif"
+	puts $f "#ifdef __cplusplus\nextern \"C\"\n#endif"
+	puts $f "void g() {}"
+	puts $f "void f() __attribute__((ifunc(\"g\")));"
 	close $f
 	set lines [${tool}_target_compile $src $obj object ""]
 	file delete $src
 	remote_file build delete $obj
 
 	if [string match "" $lines] then {
-	    # No error messages, everything is OK.
-	    set ifunc_available_saved 2
+	    set ifunc_available_saved 1
 	} else {
-	    if [regexp "ifunc is not supported" $lines] {
-		verbose "check_ifunc_available  target does not support ifunc" 2
-		set ifunc_available_saved 0
-	    } else {
-		set ifunc_available_saved -1
-	    }
+	    set ifunc_available_saved 0
 	}
 
 	verbose "check_ifunc_available  returning $ifunc_available_saved" 2
Index: config.in
===================================================================
--- config.in	(revision 164584)
+++ config.in	(working copy)
@@ -968,8 +968,8 @@
 /* Define if your assembler and linker support .hidden. */
 #undef HAVE_GAS_HIDDEN
 
-/* Define if your assembler supports indirect function type. */
-#undef HAVE_GAS_INDIRECT_FUNCTION
+/* Define if your system supports gnu indirect functions. */
+#undef HAVE_GNU_INDIRECT_FUNCTION
 
 /* Define if your assembler supports .lcomm with an alignment field. */
 #ifndef USED_FOR_TARGET
Index: configure.ac
===================================================================
--- configure.ac	(revision 164584)
+++ configure.ac	(working copy)
@@ -2161,14 +2161,18 @@
 # gnu_indirect_function type is an extension proposed at
 # http://groups.google/com/group/generic-abi/files. It allows dynamic runtime
 # selection of function implementation
-gcc_GAS_CHECK_FEATURE(gnu_indirect_function, gcc_cv_as_indirect_function,
- [elf,2,20,1],,
-[	.type  Foo, @gnu_indirect_function
-Foo:])
-GCC_TARGET_TEMPLATE([HAVE_GAS_INDIRECT_FUNCTION])
-if test $gcc_cv_as_indirect_function = yes ; then
-  AC_DEFINE(HAVE_GAS_INDIRECT_FUNCTION, 1,
-  [Define if your assembler supports indirect function type.])
+AC_ARG_ENABLE(gnu-indirect-function,
+ [AS_HELP_STRING([--enable-gnu-indirect-function],
+                 [enable the use of the @gnu_indirect_function to glibc systems])],
+ [case $enable_gnu_indirect_function in
+    yes | no) ;;
+    *) AC_MSG_ERROR(['$enable_gnu_indirect_function' is an invalid value for --enable-gnu-indirect-function.
+Valid choices are 'yes' and 'no'.]) ;;
+  esac],
+ [enable_gnu_indirect_function="$default_gnu_indirect_function"])
+if test x$enable_gnu_indirect_function = xyes; then
+  AC_DEFINE(HAVE_GNU_INDIRECT_FUNCTION, 1,
+   [Define if your system supports gnu indirect functions.])
 fi
 
 changequote(,)dnl
Index: varasm.c
===================================================================
--- varasm.c	(revision 164584)
+++ varasm.c	(working copy)
@@ -5357,7 +5357,7 @@
     }
   if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
     {
-#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GAS_INDIRECT_FUNCTION
+#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GNU_INDIRECT_FUNCTION
       ASM_OUTPUT_TYPE_DIRECTIVE
 	(asm_out_file, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
 	 IFUNC_ASM_TYPE);
Index: config.gcc
===================================================================
--- config.gcc	(revision 164584)
+++ config.gcc	(working copy)
@@ -45,6 +45,16 @@
 #			default value of $default_use_cxa_atexit is set to
 #			"no" except for targets which are known to be OK.
 #
+#  default_gnu_indirect_function
+#                       The default value for the $enable_gnu_indirect_function
+#                       variable.  enable_gnu_indirect_function relies
+#			upon the presence of a non-standard gnu ifunc support
+#			in the assembler, linker and dynamic linker.
+#			Since not all libraries provide the dynamic linking
+#			support, the default value of
+#			$default_gnu_indirect_function is set to
+#			"no" except for targets which are known to be OK.
+#
 #  gas_flag		Either yes or no depending on whether GNU as was
 #			requested.
 #
@@ -205,6 +215,7 @@
 gas="$gas_flag"
 gnu_ld="$gnu_ld_flag"
 default_use_cxa_atexit=no
+default_gnu_indirect_function=no
 target_gtfiles=
 need_64bit_hwint=
 need_64bit_isa=
@@ -1192,6 +1203,8 @@
 	tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h linux.h glibc-stdint.h"
 	case ${target} in
 	i[34567]86-*-linux*)
+		# Assume modern glibc
+		default_gnu_indirect_function=yes
 		if test x$enable_targets = xall; then
 			tm_file="${tm_file} i386/x86-64.h i386/linux64.h"
 			tm_defines="${tm_defines} TARGET_BI_ARCH=1"
@@ -1227,6 +1240,8 @@
 	tm_file="${tm_file} i386/unix.h i386/att.h dbxelf.h elfos.h svr4.h linux.h glibc-stdint.h \
 		 i386/x86-64.h i386/linux64.h"
 	case ${target} in
+	x86_64-*-linux*)
+	  default_gnu_indirect_function=glibc-2011 ;;
 	x86_64-*-kfreebsd*-gnu) tm_file="${tm_file} kfreebsd-gnu.h" ;;
 	x86_64-*-knetbsd*-gnu) tm_file="${tm_file} knetbsd-gnu.h" ;;
 	esac
