diff options
-rw-r--r-- | gcc/ChangeLog | 21 | ||||
-rw-r--r-- | gcc/config.gcc | 8 | ||||
-rw-r--r-- | gcc/config/i386/i386.c | 60 | ||||
-rw-r--r-- | gcc/config/linux-android.c | 33 | ||||
-rw-r--r-- | gcc/config/linux-android.h | 3 | ||||
-rw-r--r-- | gcc/config/linux-protos.h | 21 | ||||
-rw-r--r-- | gcc/config/t-linux-android | 23 | ||||
-rwxr-xr-x | gcc/configure | 9 | ||||
-rw-r--r-- | gcc/configure.ac | 9 | ||||
-rw-r--r-- | gcc/doc/tm.texi | 6 | ||||
-rw-r--r-- | gcc/doc/tm.texi.in | 2 | ||||
-rw-r--r-- | gcc/target.def | 9 | ||||
-rw-r--r-- | gcc/targhooks.c | 8 | ||||
-rw-r--r-- | gcc/targhooks.h | 2 | ||||
-rw-r--r-- | gcc/varasm.c | 15 |
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 |