mirror of git://gcc.gnu.org/git/gcc.git
target.def (TARGET_HAS_IFUNC_P): New target hook.
* 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.
From-SVN: r197156
This commit is contained in:
parent
78b4e425a6
commit
2f251a0535
|
|
@ -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>
|
2013-03-27 Bin Cheng <bin.cheng@arm.com>
|
||||||
|
|
||||||
PR target/56102
|
PR target/56102
|
||||||
|
|
|
||||||
|
|
@ -664,8 +664,11 @@ case ${target} in
|
||||||
# Add Android userspace support to Linux targets.
|
# Add Android userspace support to Linux targets.
|
||||||
case $target in
|
case $target in
|
||||||
*linux*)
|
*linux*)
|
||||||
|
tm_p_file="${tm_p_file} linux-protos.h"
|
||||||
|
tmake_file="${tmake_file} t-linux-android"
|
||||||
tm_file="$tm_file linux-android.h"
|
tm_file="$tm_file linux-android.h"
|
||||||
extra_options="$extra_options linux-android.opt"
|
extra_options="$extra_options linux-android.opt"
|
||||||
|
extra_objs="$extra_objs linux-android.o"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
# Enable compilation for Android by default for *android* targets.
|
# 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"
|
tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
tmake_file="${tmake_file} arm/t-arm arm/t-arm-elf arm/t-bpabi arm/t-linux-eabi"
|
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 vxworks-dummy.h arm/arm.h"
|
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.
|
# Define multilib configuration for arm-linux-androideabi.
|
||||||
case ${target} in
|
case ${target} in
|
||||||
*-androideabi)
|
*-androideabi)
|
||||||
|
|
|
||||||
|
|
@ -29206,7 +29206,7 @@ make_name (tree decl, const char *suffix, bool make_unique)
|
||||||
return global_var_name;
|
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.
|
/* Make a dispatcher declaration for the multi-versioned function DECL.
|
||||||
Calls to DECL function will be replaced with calls to the dispatcher
|
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;
|
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;
|
struct cgraph_function_version_info *default_version_info = NULL;
|
||||||
|
|
||||||
gcc_assert (fn != NULL && DECL_FUNCTION_VERSIONED (fn));
|
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;
|
default_node = default_version_info->this_node;
|
||||||
|
|
||||||
#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GNU_INDIRECT_FUNCTION
|
#if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
|
||||||
/* Right now, the dispatching is done via ifunc. */
|
if (targetm.has_ifunc_p ())
|
||||||
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;
|
struct cgraph_function_version_info *it_v = NULL;
|
||||||
it_v = it_v->next;
|
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
|
else
|
||||||
error_at (DECL_SOURCE_LOCATION (default_node->symbol.decl),
|
|
||||||
"multiversioning needs ifunc which is not supported "
|
|
||||||
"in this configuration");
|
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
error_at (DECL_SOURCE_LOCATION (default_node->symbol.decl),
|
||||||
|
"multiversioning needs ifunc which is not supported "
|
||||||
|
"on this target");
|
||||||
|
}
|
||||||
|
|
||||||
return dispatch_decl;
|
return dispatch_decl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
@ -57,3 +57,6 @@
|
||||||
|
|
||||||
#define ANDROID_ENDFILE_SPEC \
|
#define ANDROID_ENDFILE_SPEC \
|
||||||
"%{shared: crtend_so%O%s;: crtend_android%O%s}"
|
"%{shared: crtend_so%O%s;: crtend_android%O%s}"
|
||||||
|
|
||||||
|
#undef TARGET_HAS_IFUNC_P
|
||||||
|
#define TARGET_HAS_IFUNC_P linux_android_has_ifunc_p
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
@ -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
|
||||||
|
|
@ -22055,11 +22055,14 @@ else
|
||||||
enable_gnu_indirect_function="$default_gnu_indirect_function"
|
enable_gnu_indirect_function="$default_gnu_indirect_function"
|
||||||
fi
|
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
|
if test $in_tree_ld != yes ; then
|
||||||
ld_ver=`$gcc_cv_ld --version 2>/dev/null | sed 1q`
|
ld_ver=`$gcc_cv_ld --version 2>/dev/null | sed 1q`
|
||||||
|
|
|
||||||
|
|
@ -2299,10 +2299,11 @@ AC_ARG_ENABLE(gnu-indirect-function,
|
||||||
Valid choices are 'yes' and 'no'.]) ;;
|
Valid choices are 'yes' and 'no'.]) ;;
|
||||||
esac],
|
esac],
|
||||||
[enable_gnu_indirect_function="$default_gnu_indirect_function"])
|
[enable_gnu_indirect_function="$default_gnu_indirect_function"])
|
||||||
if test x$enable_gnu_indirect_function = xyes; then
|
|
||||||
AC_DEFINE(HAVE_GNU_INDIRECT_FUNCTION, 1,
|
gif=`if test x$enable_gnu_indirect_function = xyes; then echo 1; else echo 0; fi`
|
||||||
[Define if your system supports gnu indirect functions.])
|
AC_DEFINE_UNQUOTED(HAVE_GNU_INDIRECT_FUNCTION, $gif,
|
||||||
fi
|
[Define if your system supports gnu indirect functions.])
|
||||||
|
|
||||||
|
|
||||||
changequote(,)dnl
|
changequote(,)dnl
|
||||||
if test $in_tree_ld != yes ; then
|
if test $in_tree_ld != yes ; then
|
||||||
|
|
|
||||||
|
|
@ -11341,3 +11341,9 @@ memory model bits are allowed.
|
||||||
@deftypevr {Target Hook} {unsigned char} TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
|
@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}.
|
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
|
@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
|
||||||
|
|
|
||||||
|
|
@ -11177,3 +11177,5 @@ memory model bits are allowed.
|
||||||
@end deftypefn
|
@end deftypefn
|
||||||
|
|
||||||
@hook TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
|
@hook TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
|
||||||
|
|
||||||
|
@hook TARGET_HAS_IFUNC_P
|
||||||
|
|
|
||||||
|
|
@ -1518,6 +1518,15 @@ DEFHOOK
|
||||||
bool, (const_rtx x),
|
bool, (const_rtx x),
|
||||||
default_use_anchors_for_symbol_p)
|
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
|
/* 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
|
call expression EXP. DECL will be the called function, or NULL if
|
||||||
this is an indirect call. */
|
this is an indirect call. */
|
||||||
|
|
|
||||||
|
|
@ -450,6 +450,14 @@ default_fixed_point_supported_p (void)
|
||||||
return ENABLE_FIXED_POINT;
|
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
|
/* NULL if INSN insn is valid within a low-overhead loop, otherwise returns
|
||||||
an error message.
|
an error message.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,8 @@ extern bool targhook_float_words_big_endian (void);
|
||||||
extern bool default_decimal_float_supported_p (void);
|
extern bool default_decimal_float_supported_p (void);
|
||||||
extern bool default_fixed_point_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 const char * default_invalid_within_doloop (const_rtx);
|
||||||
|
|
||||||
extern tree default_builtin_vectorized_function (tree, tree, tree);
|
extern tree default_builtin_vectorized_function (tree, tree, tree);
|
||||||
|
|
|
||||||
15
gcc/varasm.c
15
gcc/varasm.c
|
|
@ -5489,14 +5489,15 @@ do_assemble_alias (tree decl, tree target)
|
||||||
}
|
}
|
||||||
if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
|
if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
|
||||||
{
|
{
|
||||||
#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GNU_INDIRECT_FUNCTION
|
#if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
|
||||||
ASM_OUTPUT_TYPE_DIRECTIVE
|
if (targetm.has_ifunc_p ())
|
||||||
(asm_out_file, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
|
ASM_OUTPUT_TYPE_DIRECTIVE
|
||||||
IFUNC_ASM_TYPE);
|
(asm_out_file, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
|
||||||
#else
|
IFUNC_ASM_TYPE);
|
||||||
error_at (DECL_SOURCE_LOCATION (decl),
|
else
|
||||||
"ifunc is not supported in this configuration");
|
|
||||||
#endif
|
#endif
|
||||||
|
error_at (DECL_SOURCE_LOCATION (decl),
|
||||||
|
"ifunc is not supported on this target");
|
||||||
}
|
}
|
||||||
|
|
||||||
# ifdef ASM_OUTPUT_DEF_FROM_DECLS
|
# ifdef ASM_OUTPUT_DEF_FROM_DECLS
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue