summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog21
-rw-r--r--gcc/config.gcc8
-rw-r--r--gcc/config/i386/i386.c60
-rw-r--r--gcc/config/linux-android.c33
-rw-r--r--gcc/config/linux-android.h3
-rw-r--r--gcc/config/linux-protos.h21
-rw-r--r--gcc/config/t-linux-android23
-rwxr-xr-xgcc/configure9
-rw-r--r--gcc/configure.ac9
-rw-r--r--gcc/doc/tm.texi6
-rw-r--r--gcc/doc/tm.texi.in2
-rw-r--r--gcc/target.def9
-rw-r--r--gcc/targhooks.c8
-rw-r--r--gcc/targhooks.h2
-rw-r--r--gcc/varasm.c15
15 files changed, 185 insertions, 44 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index f8ae2ac497e..f00cb045ab2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,24 @@
+2013-03-27 Alexander Ivchenko <alexander.ivchenko@intel.com>
+
+ * gcc/target.def (TARGET_HAS_IFUNC_P): New target hook.
+ * gcc/doc/tm.texi.in (TARGET_HAS_IFUNC_P): New.
+ * gcc/doc/tm.texi: Regenerate.
+ * gcc/targhooks.h (default_has_ifunc_p): New.
+ * gcc/targhooks.c (default_has_ifunc_p): Ditto.
+ * gcc/config/linux-protos.h: New file.
+ * gcc/config/linux-android.h (TARGET_HAS_IFUNC_P): Using version of
+ this hook for linux which disables support of indirect functions in
+ android.
+ * gcc/config/linux-android.c: New file.
+ * gcc/config/t-linux-android.c: Ditto.
+ * gcc/config.gcc: Added new object file linux-android.o.
+ * gcc/config/i386/i386.c (ix86_get_function_versions_dispatcher):
+ Using TARGET_HAS_IFUNC hook instead of HAVE_GNU_INDIRECT_FUNCTION.
+ * gcc/varasm.c (do_assemble_alias): Likewise.
+ * configure.ac: Define HAVE_GNU_INDIRECT_FUNCTION as zero if the target
+ doesn't support indirect functions.
+ * configure: Regenerate.
+
2013-03-27 Bin Cheng <bin.cheng@arm.com>
PR target/56102
diff --git a/gcc/config.gcc b/gcc/config.gcc
index 1a0be50f033..11af65f9fab 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -664,8 +664,11 @@ case ${target} in
# Add Android userspace support to Linux targets.
case $target in
*linux*)
+ tm_p_file="${tm_p_file} linux-protos.h"
+ tmake_file="${tmake_file} t-linux-android"
tm_file="$tm_file linux-android.h"
extra_options="$extra_options linux-android.opt"
+ extra_objs="$extra_objs linux-android.o"
;;
esac
# Enable compilation for Android by default for *android* targets.
@@ -875,8 +878,9 @@ arm*-*-linux-*) # ARM GNU/Linux with ELF
tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
;;
esac
- tmake_file="${tmake_file} arm/t-arm arm/t-arm-elf arm/t-bpabi arm/t-linux-eabi"
- tm_file="$tm_file arm/bpabi.h arm/linux-eabi.h arm/aout.h vxworks-dummy.h arm/arm.h"
+ tmake_file="${tmake_file} arm/t-arm arm/t-arm-elf arm/t-bpabi arm/t-linux-eabi t-linux-android"
+ tm_file="$tm_file arm/bpabi.h arm/linux-eabi.h arm/aout.h arm/arm.h"
+ extra_objs="$extra_objs linux-android.o"
# Define multilib configuration for arm-linux-androideabi.
case ${target} in
*-androideabi)
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index b835c5da2ab..030183c9e0f 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -29206,7 +29206,7 @@ make_name (tree decl, const char *suffix, bool make_unique)
return global_var_name;
}
-#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GNU_INDIRECT_FUNCTION
+#if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
/* Make a dispatcher declaration for the multi-versioned function DECL.
Calls to DECL function will be replaced with calls to the dispatcher
@@ -29277,12 +29277,6 @@ ix86_get_function_versions_dispatcher (void *decl)
tree dispatch_decl = NULL;
-#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GNU_INDIRECT_FUNCTION
- struct cgraph_function_version_info *it_v = NULL;
- struct cgraph_node *dispatcher_node = NULL;
- struct cgraph_function_version_info *dispatcher_version_info = NULL;
-#endif
-
struct cgraph_function_version_info *default_version_info = NULL;
gcc_assert (fn != NULL && DECL_FUNCTION_VERSIONED (fn));
@@ -29327,30 +29321,40 @@ ix86_get_function_versions_dispatcher (void *decl)
default_node = default_version_info->this_node;
-#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GNU_INDIRECT_FUNCTION
- /* Right now, the dispatching is done via ifunc. */
- dispatch_decl = make_dispatcher_decl (default_node->symbol.decl);
-
- dispatcher_node = cgraph_get_create_node (dispatch_decl);
- gcc_assert (dispatcher_node != NULL);
- dispatcher_node->dispatcher_function = 1;
- dispatcher_version_info
- = insert_new_cgraph_node_version (dispatcher_node);
- dispatcher_version_info->next = default_version_info;
- dispatcher_node->local.finalized = 1;
-
- /* Set the dispatcher for all the versions. */
- it_v = default_version_info;
- while (it_v != NULL)
+#if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
+ if (targetm.has_ifunc_p ())
{
- it_v->dispatcher_resolver = dispatch_decl;
- it_v = it_v->next;
+ struct cgraph_function_version_info *it_v = NULL;
+ struct cgraph_node *dispatcher_node = NULL;
+ struct cgraph_function_version_info *dispatcher_version_info = NULL;
+
+ /* Right now, the dispatching is done via ifunc. */
+ dispatch_decl = make_dispatcher_decl (default_node->symbol.decl);
+
+ dispatcher_node = cgraph_get_create_node (dispatch_decl);
+ gcc_assert (dispatcher_node != NULL);
+ dispatcher_node->dispatcher_function = 1;
+ dispatcher_version_info
+ = insert_new_cgraph_node_version (dispatcher_node);
+ dispatcher_version_info->next = default_version_info;
+ dispatcher_node->local.finalized = 1;
+
+ /* Set the dispatcher for all the versions. */
+ it_v = default_version_info;
+ while (it_v != NULL)
+ {
+ it_v->dispatcher_resolver = dispatch_decl;
+ it_v = it_v->next;
+ }
}
-#else
- error_at (DECL_SOURCE_LOCATION (default_node->symbol.decl),
- "multiversioning needs ifunc which is not supported "
- "in this configuration");
+ else
#endif
+ {
+ error_at (DECL_SOURCE_LOCATION (default_node->symbol.decl),
+ "multiversioning needs ifunc which is not supported "
+ "on this target");
+ }
+
return dispatch_decl;
}
diff --git a/gcc/config/linux-android.c b/gcc/config/linux-android.c
new file mode 100644
index 00000000000..d6e47a70e7a
--- /dev/null
+++ b/gcc/config/linux-android.c
@@ -0,0 +1,33 @@
+/* Functions for Linux Android as target machine for GNU C compiler.
+ Copyright (C) 2013.
+ Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+#include "config.h"
+#include "system.h"
+#include "coretypes.h"
+#include "tm.h"
+#include "linux-protos.h"
+
+/* Android does not support GNU indirect functions. */
+
+bool
+linux_android_has_ifunc_p (void)
+{
+ return TARGET_ANDROID ? false : HAVE_GNU_INDIRECT_FUNCTION;
+}
diff --git a/gcc/config/linux-android.h b/gcc/config/linux-android.h
index 2c87c846cd7..831a19c416e 100644
--- a/gcc/config/linux-android.h
+++ b/gcc/config/linux-android.h
@@ -57,3 +57,6 @@
#define ANDROID_ENDFILE_SPEC \
"%{shared: crtend_so%O%s;: crtend_android%O%s}"
+
+#undef TARGET_HAS_IFUNC_P
+#define TARGET_HAS_IFUNC_P linux_android_has_ifunc_p
diff --git a/gcc/config/linux-protos.h b/gcc/config/linux-protos.h
new file mode 100644
index 00000000000..3f926e5dffd
--- /dev/null
+++ b/gcc/config/linux-protos.h
@@ -0,0 +1,21 @@
+/* Prototypes.
+ Copyright (C) 2013.
+ Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with GCC; see the file COPYING3. If not see
+<http://www.gnu.org/licenses/>. */
+
+extern bool linux_android_has_ifunc_p (void);
diff --git a/gcc/config/t-linux-android b/gcc/config/t-linux-android
new file mode 100644
index 00000000000..6f9b03330a7
--- /dev/null
+++ b/gcc/config/t-linux-android
@@ -0,0 +1,23 @@
+# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013
+# Free Software Foundation, Inc.
+#
+# This file is part of GCC.
+#
+# GCC is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3, or (at your option)
+# any later version.
+#
+# GCC is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with GCC; see the file COPYING3. If not see
+# <http://www.gnu.org/licenses/>.
+
+linux-android.o: $(srcdir)/config/linux-android.c $(CONFIG_H) $(SYSTEM_H) \
+ coretypes.h $(TM_H) $(TM_P_H)
+ $(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+ $(srcdir)/config/linux-android.c
diff --git a/gcc/configure b/gcc/configure
index eac96cdac70..3db6a77c315 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -22055,11 +22055,14 @@ else
enable_gnu_indirect_function="$default_gnu_indirect_function"
fi
-if test x$enable_gnu_indirect_function = xyes; then
-$as_echo "#define HAVE_GNU_INDIRECT_FUNCTION 1" >>confdefs.h
+gif=`if test x$enable_gnu_indirect_function = xyes; then echo 1; else echo 0; fi`
+
+cat >>confdefs.h <<_ACEOF
+#define HAVE_GNU_INDIRECT_FUNCTION $gif
+_ACEOF
+
-fi
if test $in_tree_ld != yes ; then
ld_ver=`$gcc_cv_ld --version 2>/dev/null | sed 1q`
diff --git a/gcc/configure.ac b/gcc/configure.ac
index 40a1af7a4a4..e9ad74c642d 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -2299,10 +2299,11 @@ AC_ARG_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
+
+gif=`if test x$enable_gnu_indirect_function = xyes; then echo 1; else echo 0; fi`
+AC_DEFINE_UNQUOTED(HAVE_GNU_INDIRECT_FUNCTION, $gif,
+[Define if your system supports gnu indirect functions.])
+
changequote(,)dnl
if test $in_tree_ld != yes ; then
diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi
index cbbc82dfe39..9f78ae4a46a 100644
--- a/gcc/doc/tm.texi
+++ b/gcc/doc/tm.texi
@@ -11341,3 +11341,9 @@ memory model bits are allowed.
@deftypevr {Target Hook} {unsigned char} TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
This value should be set if the result written by @code{atomic_test_and_set} is not exactly 1, i.e. the @code{bool} @code{true}.
@end deftypevr
+
+@deftypefn {Target Hook} bool TARGET_HAS_IFUNC_P (void)
+It returns true if the target supports GNU indirect functions.
+The support includes the assembler, linker and dynamic linker.
+The default value of this hook is based on target's libc.
+@end deftypefn
diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in
index dfba947f51b..b67df84041e 100644
--- a/gcc/doc/tm.texi.in
+++ b/gcc/doc/tm.texi.in
@@ -11177,3 +11177,5 @@ memory model bits are allowed.
@end deftypefn
@hook TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
+
+@hook TARGET_HAS_IFUNC_P
diff --git a/gcc/target.def b/gcc/target.def
index 831cad8119b..3ad587093f1 100644
--- a/gcc/target.def
+++ b/gcc/target.def
@@ -1518,6 +1518,15 @@ DEFHOOK
bool, (const_rtx x),
default_use_anchors_for_symbol_p)
+/* True if target supports indirect functions. */
+DEFHOOK
+(has_ifunc_p,
+ "It returns true if the target supports GNU indirect functions.\n\
+The support includes the assembler, linker and dynamic linker.\n\
+The default value of this hook is based on target's libc.",
+ bool, (void),
+ default_has_ifunc_p)
+
/* True if it is OK to do sibling call optimization for the specified
call expression EXP. DECL will be the called function, or NULL if
this is an indirect call. */
diff --git a/gcc/targhooks.c b/gcc/targhooks.c
index 6c12a4ad91a..61ca0057ba5 100644
--- a/gcc/targhooks.c
+++ b/gcc/targhooks.c
@@ -450,6 +450,14 @@ default_fixed_point_supported_p (void)
return ENABLE_FIXED_POINT;
}
+/* True if the target supports GNU indirect functions. */
+
+bool
+default_has_ifunc_p (void)
+{
+ return HAVE_GNU_INDIRECT_FUNCTION;
+}
+
/* NULL if INSN insn is valid within a low-overhead loop, otherwise returns
an error message.
diff --git a/gcc/targhooks.h b/gcc/targhooks.h
index d23b3529fe5..0837c09c324 100644
--- a/gcc/targhooks.h
+++ b/gcc/targhooks.h
@@ -72,6 +72,8 @@ extern bool targhook_float_words_big_endian (void);
extern bool default_decimal_float_supported_p (void);
extern bool default_fixed_point_supported_p (void);
+extern bool default_has_ifunc_p (void);
+
extern const char * default_invalid_within_doloop (const_rtx);
extern tree default_builtin_vectorized_function (tree, tree, tree);
diff --git a/gcc/varasm.c b/gcc/varasm.c
index 66481031022..2532d804214 100644
--- a/gcc/varasm.c
+++ b/gcc/varasm.c
@@ -5489,14 +5489,15 @@ do_assemble_alias (tree decl, tree target)
}
if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
{
-#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);
-#else
- error_at (DECL_SOURCE_LOCATION (decl),
- "ifunc is not supported in this configuration");
+#if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
+ if (targetm.has_ifunc_p ())
+ ASM_OUTPUT_TYPE_DIRECTIVE
+ (asm_out_file, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
+ IFUNC_ASM_TYPE);
+ else
#endif
+ error_at (DECL_SOURCE_LOCATION (decl),
+ "ifunc is not supported on this target");
}
# ifdef ASM_OUTPUT_DEF_FROM_DECLS