On Mon, 2017-10-02 at 15:38 +0100, Szabolcs Nagy wrote: > > looks good to me, but i cannot approve. > > (this will make libatomic depend on ifuncs on aarch64*-linux-gnu.)
If you build GCC with default options, ifunc is enabled on aarch64 and used by libatomic but if you configure with '--disable-gnu-indirect- function' then GCC will not recognize the 'resolver' attribute and libatomic will build the 'old' way and not use IFUNC's. It seems like using '--disable-version-specific-runtime-libs' should allow GCC to recognize the 'resolver' attribute for IFUNCs but to not use them when building libatomic but when I tried that I got ifuncs in libatomic anyway. I think that is a bug and I will look into it some more. The recent alias checking improvements made to GCC and which caused some glibc build problems also caused the ifunc check in libatomic to fail. That problem has been fixed but it involved a change to libatomic/ibatomic_i.h that conflicted with this patch so I am including an updated version that will apply cleanly to the top of tree. Only libatomic_i.h changed. Steve Ellcey sell...@cavium.com 2017-10-03 Steve Ellcey <sell...@cavium.com> * Makefile.am (ARCH_AARCH64_LINUX): Add IFUNC_OPTIONS and libatomic_la_LIBADD. * config/linux/aarch64/host-config.h: New file. * configure.ac (IFUNC_RESOLVER_ARGS): Define. (ARCH_AARCH64_LINUX): New conditional for IFUNC builds. * configure.tgt (aarch64): Set ARCH and try_ifunc. (aarch64*-*-linux*) Update config_path. (aarch64*-*-linux*) Set IFUNC_RESOLVER_ARGS. * libatomic_i.h (GEN_SELECTOR): Add IFUNC_RESOLVER_ARGS argument. * Makefile.in: Regenerate. * auto-config.h.in: Regenerate. * configure: Regenerate.
diff --git a/libatomic/Makefile.am b/libatomic/Makefile.am index d731406..92d19c6 100644 --- a/libatomic/Makefile.am +++ b/libatomic/Makefile.am @@ -122,6 +122,10 @@ libatomic_la_LIBADD = $(foreach s,$(SIZES),$(addsuffix _$(s)_.lo,$(SIZEOBJS))) ## On a target-specific basis, include alternates to be selected by IFUNC. if HAVE_IFUNC +if ARCH_AARCH64_LINUX +IFUNC_OPTIONS = -march=armv8.1-a +libatomic_la_LIBADD += $(foreach s,$(SIZES),$(addsuffix _$(s)_1_.lo,$(SIZEOBJS))) +endif if ARCH_ARM_LINUX IFUNC_OPTIONS = -march=armv7-a -DHAVE_KERNEL64 libatomic_la_LIBADD += $(foreach s,$(SIZES),$(addsuffix _$(s)_1_.lo,$(SIZEOBJS))) diff --git a/libatomic/config/linux/aarch64/host-config.h b/libatomic/config/linux/aarch64/host-config.h index e69de29..08810a9 100644 --- a/libatomic/config/linux/aarch64/host-config.h +++ b/libatomic/config/linux/aarch64/host-config.h @@ -0,0 +1,36 @@ +/* Copyright (C) 2017 Free Software Foundation, Inc. + + This file is part of the GNU Atomic Library (libatomic). + + Libatomic 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 of the License, or + (at your option) any later version. + + Libatomic 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. + + Under Section 7 of GPL version 3, you are granted additional + permissions described in the GCC Runtime Library Exception, version + 3.1, as published by the Free Software Foundation. + + You should have received a copy of the GNU General Public License and + a copy of the GCC Runtime Library Exception along with this program; + see the files COPYING3 and COPYING.RUNTIME respectively. If not, see + <http://www.gnu.org/licenses/>. */ + +#if HAVE_IFUNC +#include <stdlib.h> + +# ifdef HWCAP_ATOMICS +# define IFUNC_COND_1 (hwcap & HWCAP_ATOMICS) +# else +# define IFUNC_COND_1 (false) +# endif +# define IFUNC_NCOND(N) (1) + +#endif /* HAVE_IFUNC */ + +#include_next <host-config.h> diff --git a/libatomic/configure.ac b/libatomic/configure.ac index 023f172..b717d3d 100644 --- a/libatomic/configure.ac +++ b/libatomic/configure.ac @@ -163,6 +163,10 @@ if test -n "$UNSUPPORTED"; then AC_MSG_ERROR([Configuration ${target} is unsupported.]) fi +# Write out the ifunc resolver arg type. +AC_DEFINE_UNQUOTED(IFUNC_RESOLVER_ARGS, $IFUNC_RESOLVER_ARGS, + [Define ifunc resolver function argument.]) + # Disable fallbacks to __sync routines from libgcc. Otherwise we'll # make silly decisions about what the cpu can do. CFLAGS="$save_CFLAGS -fno-sync-libcalls $XCFLAGS" @@ -247,6 +251,8 @@ AC_SUBST(LIBS) AC_SUBST(SIZES) AM_CONDITIONAL(HAVE_IFUNC, test x$libat_cv_have_ifunc = xyes) +AM_CONDITIONAL(ARCH_AARCH64_LINUX, + [expr "$config_path" : ".* linux/aarch64 .*" > /dev/null]) AM_CONDITIONAL(ARCH_ARM_LINUX, [expr "$config_path" : ".* linux/arm .*" > /dev/null]) AM_CONDITIONAL(ARCH_I386, diff --git a/libatomic/configure.tgt b/libatomic/configure.tgt index b8af3ab..388ae95 100644 --- a/libatomic/configure.tgt +++ b/libatomic/configure.tgt @@ -40,6 +40,14 @@ case "${target_cpu}" in riscv*) ARCH=riscv ;; sh*) ARCH=sh ;; + aarch64*) + ARCH=aarch64 + case "${target}" in + aarch64*-*-linux*) + try_ifunc=yes + ;; + esac + ;; arm*) ARCH=arm case "${target}" in @@ -109,6 +117,11 @@ fi # Other system configury case "${target}" in + aarch64*-*-linux*) + # OS support for atomic primitives. + config_path="${config_path} linux/aarch64 posix" + ;; + arm*-*-linux*) # OS support for atomic primitives. config_path="${config_path} linux/arm posix" @@ -153,3 +166,14 @@ case "${target}" in UNSUPPORTED=1 ;; esac + +# glibc will pass hwcap to ifunc resolver functions as an argument. +# The type may be different on different architectures. +case "${target}" in + aarch64*-*-*) + IFUNC_RESOLVER_ARGS="uint64_t hwcap" + ;; + *) + IFUNC_RESOLVER_ARGS="void" + ;; +esac diff --git a/libatomic/libatomic_i.h b/libatomic/libatomic_i.h index 2dad4a8..2ecc27a 100644 --- a/libatomic/libatomic_i.h +++ b/libatomic/libatomic_i.h @@ -240,7 +240,7 @@ bool libat_is_lock_free (size_t, void *) MAN(is_lock_free); # if IFUNC_NCOND(N) == 1 # define GEN_SELECTOR(X) \ extern typeof(C2(libat_,X)) C3(libat_,X,_i1) HIDDEN; \ - static typeof(C2(libat_,X)) * C2(select_,X) (void) \ + static typeof(C2(libat_,X)) * C2(select_,X) (IFUNC_RESOLVER_ARGS) \ { \ if (IFUNC_COND_1) \ return C3(libat_,X,_i1); \ @@ -250,7 +250,7 @@ bool libat_is_lock_free (size_t, void *) MAN(is_lock_free); # define GEN_SELECTOR(X) \ extern typeof(C2(libat_,X)) C3(libat_,X,_i1) HIDDEN; \ extern typeof(C2(libat_,X)) C3(libat_,X,_i2) HIDDEN; \ - static typeof(C2(libat_,X)) * C2(select_,X) (void) \ + static typeof(C2(libat_,X)) * C2(select_,X) (IFUNC_RESOLVER_ARGS) \ { \ if (IFUNC_COND_1) \ return C3(libat_,X,_i1); \ @@ -263,7 +263,7 @@ bool libat_is_lock_free (size_t, void *) MAN(is_lock_free); extern typeof(C2(libat_,X)) C3(libat_,X,_i1) HIDDEN; \ extern typeof(C2(libat_,X)) C3(libat_,X,_i2) HIDDEN; \ extern typeof(C2(libat_,X)) C3(libat_,X,_i3) HIDDEN; \ - static typeof(C2(libat_,X)) * C2(select_,X) (void) \ + static typeof(C2(libat_,X)) * C2(select_,X) (IFUNC_RESOLVER_ARGS) \ { \ if (IFUNC_COND_1) \ return C3(libat_,X,_i1); \