public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH v3 8/9] Use libc_ifunc macro for vfork in libpthread.
  2016-08-24 14:05 [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Stefan Liebler
@ 2016-08-24 14:05 ` Stefan Liebler
  2016-08-30 12:40   ` Florian Weimer
  2016-08-24 14:05 ` [PATCH v3 9/9] Use libc_ifunc macro for siglongjmp, longjmp " Stefan Liebler
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 27+ messages in thread
From: Stefan Liebler @ 2016-08-24 14:05 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, fweimer, murphyp, schwab, joseph_myers

This patch uses the libc_ifunc macro to create already existing ifunc functions
vfork_ifunc and __vfork_ifunc if HAVE_IFUNC is defined.

ChangeLog:

	* nptl/pt-vfork.c (DEFINE_VFORK): Use libc_ifunc macro.
---
 nptl/pt-vfork.c | 22 +++++-----------------
 1 file changed, 5 insertions(+), 17 deletions(-)

diff --git a/nptl/pt-vfork.c b/nptl/pt-vfork.c
index 8f4be0c..563e3ec 100644
--- a/nptl/pt-vfork.c
+++ b/nptl/pt-vfork.c
@@ -46,32 +46,20 @@
 
 extern __typeof (vfork) __libc_vfork;   /* Defined in libc.  */
 
-static __typeof (vfork) *
-__attribute__ ((used))
-vfork_resolve (void)
-{
-  return &__libc_vfork;
-}
+# undef INIT_ARCH
+# define INIT_ARCH()
+# define DEFINE_VFORK(name) libc_ifunc (name, &__libc_vfork)
 
-# ifdef HAVE_ASM_SET_DIRECTIVE
-#  define DEFINE_VFORK(name) \
-  asm (".set " #name ", vfork_resolve\n" \
-       ".globl " #name "\n" \
-       ".type " #name ", %gnu_indirect_function");
-# else
-#  define DEFINE_VFORK(name) \
-  asm (#name " = vfork_resolve\n" \
-       ".globl " #name "\n" \
-       ".type " #name ", %gnu_indirect_function");
-# endif
 #endif
 
 #if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20)
+extern __typeof(vfork) vfork_ifunc;
 DEFINE_VFORK (vfork_ifunc)
 compat_symbol (libpthread, vfork_ifunc, vfork, GLIBC_2_0);
 #endif
 
 #if SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20)
+extern __typeof(vfork) __vfork_ifunc;
 DEFINE_VFORK (__vfork_ifunc)
 compat_symbol (libpthread, __vfork_ifunc, __vfork, GLIBC_2_1_2);
 #endif
-- 
2.3.0

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v3 5/9] ppc: Use libc_ifunc macro for time, gettimeofday.
  2016-08-24 14:05 [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Stefan Liebler
                   ` (3 preceding siblings ...)
  2016-08-24 14:05 ` [PATCH v3 4/9] i386, x86: Use libc_ifunc macro for time, gettimeofday Stefan Liebler
@ 2016-08-24 14:05 ` Stefan Liebler
  2016-08-30 13:46   ` Paul E. Murphy
  2016-08-24 14:05 ` [PATCH v3 3/9] s390: Refactor ifunc resolvers due to false debuginfo Stefan Liebler
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 27+ messages in thread
From: Stefan Liebler @ 2016-08-24 14:05 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, fweimer, murphyp, schwab, joseph_myers

This patch uses the libc_ifunc_hidden macro to create already existing ifunc functions
time and gettimeofday on power. This way, the libc_hidden_def macro can be used
instead of inline assemblies.
On ppc32, the __GI_* symbols do not target the ifunc symbol and thus the
redirection construct has to be applied here.

ChangeLog:

	* sysdeps/unix/sysv/linux/powerpc/gettimeofday.c (__gettimeofday):
	Use libc_ifunc_hidden and libc_hidden_def macro. Redirect ifunced function
	in header for using it as type for ifunc function because __GI_* symbols
	for ppc32 do not target the ifunc symbols.
	* sysdeps/unix/sysv/linux/powerpc/time.c (time): Likewise.
---
 sysdeps/unix/sysv/linux/powerpc/gettimeofday.c | 60 ++++++++++++-----------
 sysdeps/unix/sysv/linux/powerpc/time.c         | 67 +++++++++++++-------------
 2 files changed, 65 insertions(+), 62 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
index 25a4e7c..16c00d7 100644
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -15,6 +15,11 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#if defined SHARED && !defined __powerpc64__
+# define __gettimeofday __redirect___gettimeofday
+#else
+# define __redirect___gettimeofday __gettimeofday
+#endif
 
 #include <sys/time.h>
 
@@ -24,30 +29,14 @@
 # include <libc-vdso.h>
 # include <dl-machine.h>
 
-void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
-
-static int
-__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
+# ifndef __powerpc64__
+#  undef __gettimeofday
 
-void *
-gettimeofday_ifunc (void)
+int
+__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
 {
-  PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
-
-  /* If the vDSO is not available we fall back syscall.  */
-  void *vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
-  return (vdso_gettimeofday ? VDSO_IFUNC_RET (vdso_gettimeofday)
-	  : (void*)__gettimeofday_syscall);
+  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
 }
-asm (".type __gettimeofday, %gnu_indirect_function");
-
-/* This is doing "libc_hidden_def (__gettimeofday)" but the compiler won't
-   let us do it in C because it doesn't know we're defining __gettimeofday
-   here in this file.  */
-asm (".globl __GI___gettimeofday");
 
 /* __GI___gettimeofday is defined as hidden and for ppc32 it enables the
    compiler make a local call (symbol@local) for internal GLIBC usage. It
@@ -55,16 +44,29 @@ asm (".globl __GI___gettimeofday");
    For ppc64 a call to a function in another translation unit might use a
    different toc pointer thus disallowing direct branchess and making internal
    ifuncs calls safe.  */
-#ifdef __powerpc64__
-asm ("__GI___gettimeofday = __gettimeofday");
-#else
-int
-__gettimeofday_vsyscall (struct timeval *tv, struct timezone *tz)
+#  undef libc_hidden_def
+#  define libc_hidden_def(name)					\
+  __hidden_ver1 (__gettimeofday_vsyscall, __GI___gettimeofday,	\
+	       __gettimeofday_vsyscall);
+
+# endif /* !__powerpc64__  */
+
+static int
+__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
 {
-  return INLINE_VSYSCALL (gettimeofday, 2, tv, tz);
+  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
 }
-asm ("__GI___gettimeofday = __gettimeofday_vsyscall");
-#endif
+
+# define INIT_ARCH()							\
+  PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);		\
+  void *vdso_gettimeofday = _dl_vdso_vsym ("__kernel_gettimeofday", &linux2615);
+
+/* If the vDSO is not available we fall back syscall.  */
+libc_ifunc_hidden (__redirect___gettimeofday, __gettimeofday,
+		   vdso_gettimeofday
+		   ? VDSO_IFUNC_RET (vdso_gettimeofday)
+		   : (void *) __gettimeofday_syscall);
+libc_hidden_def (__gettimeofday)
 
 #else
 
diff --git a/sysdeps/unix/sysv/linux/powerpc/time.c b/sysdeps/unix/sysv/linux/powerpc/time.c
index 7973419..3da0b66 100644
--- a/sysdeps/unix/sysv/linux/powerpc/time.c
+++ b/sysdeps/unix/sysv/linux/powerpc/time.c
@@ -17,6 +17,11 @@
    <http://www.gnu.org/licenses/>.  */
 
 #ifdef SHARED
+# ifndef __powerpc64__
+#  define time __redirect_time
+# else
+#  define __redirect_time time
+# endif
 
 # include <time.h>
 # include <sysdep.h>
@@ -24,7 +29,26 @@
 # include <libc-vdso.h>
 # include <dl-machine.h>
 
-void *time_ifunc (void) asm ("time");
+# ifndef __powerpc64__
+#  undef time
+
+time_t
+__time_vsyscall (time_t *t)
+{
+  return INLINE_VSYSCALL (time, 1, t);
+}
+
+/* __GI_time is defined as hidden and for ppc32 it enables the
+   compiler make a local call (symbol@local) for internal GLIBC usage. It
+   means the PLT won't be used and the ifunc resolver will be called directly.
+   For ppc64 a call to a function in another translation unit might use a
+   different toc pointer thus disallowing direct branchess and making internal
+   ifuncs calls safe.  */
+#  undef libc_hidden_def
+#  define libc_hidden_def(name)					\
+  __hidden_ver1 (__time_vsyscall, __GI_time, __time_vsyscall);
+
+# endif /* !__powerpc64__  */
 
 static time_t
 time_syscall (time_t *t)
@@ -42,42 +66,19 @@ time_syscall (time_t *t)
   return result;
 }
 
-void *
-time_ifunc (void)
-{
-  PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);
-
-  /* If the vDSO is not available we fall back to the syscall.  */
+# define INIT_ARCH()							\
+  PREPARE_VERSION (linux2615, "LINUX_2.6.15", 123718565);		\
   void *vdso_time = _dl_vdso_vsym ("__kernel_time", &linux2615);
-  return (vdso_time ? VDSO_IFUNC_RET (vdso_time)
-	  : (void*)time_syscall);
-}
-asm (".type time, %gnu_indirect_function");
 
-/* This is doing "libc_hidden_def (time)" but the compiler won't
- * let us do it in C because it doesn't know we're defining time
- * here in this file.  */
-asm (".globl __GI_time");
-
-/* __GI_time is defined as hidden and for ppc32 it enables the
-   compiler make a local call (symbol@local) for internal GLIBC usage. It
-   means the PLT won't be used and the ifunc resolver will be called directly.
-   For ppc64 a call to a function in another translation unit might use a
-   different toc pointer thus disallowing direct branchess and making internal
-   ifuncs calls safe.  */
-#ifdef __powerpc64__
-asm ("__GI_time = time");
-#else
-time_t
-__time_vsyscall (time_t *t)
-{
-  return INLINE_VSYSCALL (time, 1, t);
-}
-asm ("__GI_time = __time_vsyscall");
-#endif
+/* If the vDSO is not available we fall back to the syscall.  */
+libc_ifunc_hidden (__redirect_time, time,
+		   vdso_time
+		   ? VDSO_IFUNC_RET (vdso_time)
+		   : (void *) time_syscall);
+libc_hidden_def (time)
 
 #else
 
 #include <sysdeps/posix/time.c>
 
-#endif
+#endif /* !SHARED */
-- 
2.3.0

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v3 6/9] Use libc_ifunc macro for clock_* symbols in librt.
  2016-08-24 14:05 [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Stefan Liebler
  2016-08-24 14:05 ` [PATCH v3 8/9] Use libc_ifunc macro for vfork in libpthread Stefan Liebler
  2016-08-24 14:05 ` [PATCH v3 9/9] Use libc_ifunc macro for siglongjmp, longjmp " Stefan Liebler
@ 2016-08-24 14:05 ` Stefan Liebler
  2016-08-30 12:39   ` Florian Weimer
  2016-08-24 14:05 ` [PATCH v3 4/9] i386, x86: Use libc_ifunc macro for time, gettimeofday Stefan Liebler
                   ` (7 subsequent siblings)
  10 siblings, 1 reply; 27+ messages in thread
From: Stefan Liebler @ 2016-08-24 14:05 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, fweimer, murphyp, schwab, joseph_myers

This patch uses the libc_ifunc macro to create already existing ifunc functions
clock_getres, clock_gettime, clock_settime, clock_getcpuclockid and
clock_nanosleep. If HAVE_IFUNC is defined, the macro COMPAT_REDIRECT uses
the libc_ifunc macro.
Furthermore some whitespace damage is cleaned.

ChangeLog:

	* rt/clock-compat.c (COMPAT_REDIRECT): Use libc_ifunc macro.
---
 rt/clock-compat.c | 34 +++++++++++++++-------------------
 1 file changed, 15 insertions(+), 19 deletions(-)

diff --git a/rt/clock-compat.c b/rt/clock-compat.c
index dc69e4a..b47781c 100644
--- a/rt/clock-compat.c
+++ b/rt/clock-compat.c
@@ -28,13 +28,9 @@
 #include <time.h>
 
 #if HAVE_IFUNC
-# define COMPAT_REDIRECT(name, proto, arglist)				      \
-  __typeof (name) *name##_ifunc (void) asm (#name);			      \
-  __typeof (name) *name##_ifunc (void)					      \
-  {									      \
-    return &__##name;							      \
-  }									      \
-  asm (".type " #name ", %gnu_indirect_function");
+# undef INIT_ARCH
+# define INIT_ARCH()
+# define COMPAT_REDIRECT(name, proto, arglist) libc_ifunc (name, &__##name)
 #else
 # define COMPAT_REDIRECT(name, proto, arglist)				      \
   int									      \
@@ -45,21 +41,21 @@
 #endif
 
 COMPAT_REDIRECT (clock_getres,
-                 (clockid_t clock_id, struct timespec *res),
-                 (clock_id, res))
+		 (clockid_t clock_id, struct timespec *res),
+		 (clock_id, res))
 COMPAT_REDIRECT (clock_gettime,
-                 (clockid_t clock_id, struct timespec *tp),
-                 (clock_id, tp))
+		 (clockid_t clock_id, struct timespec *tp),
+		 (clock_id, tp))
 COMPAT_REDIRECT (clock_settime,
-                 (clockid_t clock_id, const struct timespec *tp),
-                 (clock_id, tp))
+		 (clockid_t clock_id, const struct timespec *tp),
+		 (clock_id, tp))
 COMPAT_REDIRECT (clock_getcpuclockid,
-                 (pid_t pid, clockid_t *clock_id),
-                 (pid, clock_id))
+		 (pid_t pid, clockid_t *clock_id),
+		 (pid, clock_id))
 COMPAT_REDIRECT (clock_nanosleep,
-                 (clockid_t clock_id, int flags,
-                  const struct timespec *req,
-                  struct timespec *rem),
-                 (clock_id, flags, req, rem))
+		 (clockid_t clock_id, int flags,
+		  const struct timespec *req,
+		  struct timespec *rem),
+		 (clock_id, flags, req, rem))
 
 #endif
-- 
2.3.0

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v3 4/9] i386, x86: Use libc_ifunc macro for time, gettimeofday.
  2016-08-24 14:05 [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Stefan Liebler
                   ` (2 preceding siblings ...)
  2016-08-24 14:05 ` [PATCH v3 6/9] Use libc_ifunc macro for clock_* symbols in librt Stefan Liebler
@ 2016-08-24 14:05 ` Stefan Liebler
  2016-09-29 14:34   ` Andreas Schwab
  2016-08-24 14:05 ` [PATCH v3 5/9] ppc: " Stefan Liebler
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 27+ messages in thread
From: Stefan Liebler @ 2016-08-24 14:05 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, fweimer, murphyp, schwab, joseph_myers

This patch uses the libc_ifunc_hidden macro to create already existing ifunc functions
time and gettimeofday on intel. This way, the libc_hidden_def macro can be used
instead of the libc_ifunc_hidden_def one which was only used here. Thus the
macro is removed from libc-symbols.h.
On i386, the __GI_* symbols do not target the ifunc symbol and thus the
redirection construct has to be applied here.

ChangeLog:

	* sysdeps/unix/sysv/linux/x86/gettimeofday.c (__gettimeofday):
	Use libc_ifunc_hidden macro. Use libc_hidden_def instead of
	libc_ifunc_hidden_def.
	* sysdeps/unix/sysv/linux/x86/time.c (time): Likewise.
	* sysdeps/unix/sysv/linux/i386/gettimeofday.c (__gettimeofday):
	Redirect ifunced function in header for using it as type of ifunc'ed
	function. Redefine libc_hidden_def to use fallback non ifunc'ed
	function for __GI_* symbol.
	* sysdeps/unix/sysv/linux/i386/time.c (time): Likewise.
	* include/libc-symbols.h
	(libc_ifunc_hidden_def, libc_ifunc_hidden_def1): Delete macro.
---
 include/libc-symbols.h                      | 15 ---------------
 sysdeps/unix/sysv/linux/i386/gettimeofday.c | 14 ++++++++++----
 sysdeps/unix/sysv/linux/i386/time.c         | 14 +++++++++++---
 sysdeps/unix/sysv/linux/x86/gettimeofday.c  | 28 ++++++++++++++--------------
 sysdeps/unix/sysv/linux/x86/time.c          | 26 +++++++++++++-------------
 5 files changed, 48 insertions(+), 49 deletions(-)

diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index 44e5253..a53e1ca 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -781,21 +781,6 @@ for linking")
 #define libm_ifunc_init()
 #define libm_ifunc(name, expr) __ifunc (name, name, expr, void, libm_ifunc_init)
 
-#ifdef HAVE_ASM_SET_DIRECTIVE
-# define libc_ifunc_hidden_def1(local, name)				\
-    __asm__ (".globl " #local "\n\t"					\
-	     ".hidden " #local "\n\t"					\
-	     ".set " #local ", " #name);
-#else
-# define libc_ifunc_hidden_def1(local, name)				\
-    __asm__ (".globl " #local "\n\t"					\
-	     ".hidden " #local "\n\t"					\
-	     #local " = " #name);
-#endif
-
-#define libc_ifunc_hidden_def(name) \
-  libc_ifunc_hidden_def1 (__GI_##name, name)
-
 /* Add the compiler optimization to inhibit loop transformation to library
    calls.  This is used to avoid recursive calls in memset and memmove
    default implementations.  */
diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
index 965bb81..6ab1215 100644
--- a/sysdeps/unix/sysv/linux/i386/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
@@ -16,14 +16,20 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#ifdef SHARED
+# define __gettimeofday __redirect___gettimeofday
+#endif
+
 #include <sys/time.h>
 
 #ifdef SHARED
+# undef __gettimeofday
+# define __gettimeofday_type __redirect___gettimeofday
 
-# undef libc_ifunc_hidden_def
-# define libc_ifunc_hidden_def(name)  \
-  libc_ifunc_hidden_def1 (__GI_##name, __gettimeofday_syscall)
-
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+  __hidden_ver1 (__gettimeofday_syscall, __GI___gettimeofday, \
+	       __gettimeofday_syscall);
 #endif
 
 #include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>
diff --git a/sysdeps/unix/sysv/linux/i386/time.c b/sysdeps/unix/sysv/linux/i386/time.c
index 62b78b2..980a118 100644
--- a/sysdeps/unix/sysv/linux/i386/time.c
+++ b/sysdeps/unix/sysv/linux/i386/time.c
@@ -17,10 +17,18 @@
    <http://www.gnu.org/licenses/>.  */
 
 #ifdef SHARED
+# define time __redirect_time
+#endif
+
+#include <time.h>
+
+#ifdef SHARED
+# undef time
+# define time_type __redirect_time
 
-# undef libc_ifunc_hidden_def
-# define libc_ifunc_hidden_def(name)  \
-  libc_ifunc_hidden_def1 (__GI_##name, __time_syscall)
+# undef libc_hidden_def
+# define libc_hidden_def(name)  \
+  __hidden_ver1 (__time_syscall, __GI_time, __time_syscall);
 #endif
 
 #include <sysdeps/unix/sysv/linux/x86/time.c>
diff --git a/sysdeps/unix/sysv/linux/x86/gettimeofday.c b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
index 36f7c26..c82452f 100644
--- a/sysdeps/unix/sysv/linux/x86/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -29,20 +29,20 @@ __gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
   return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
 }
 
-void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
-
-void *
-gettimeofday_ifunc (void)
-{
-  PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
-
-  /* If the vDSO is not available we fall back to syscall.  */
-  return (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
-	  ?: (void*) (&__gettimeofday_syscall));
-}
-asm (".type __gettimeofday, %gnu_indirect_function");
-
-libc_ifunc_hidden_def(__gettimeofday)
+# ifndef __gettimeofday_type
+/* The i386 gettimeofday.c includes this file with a defined
+   __gettimeofday_type macro.  For x86_64 we have to define it to __gettimeofday
+   as the internal symbol is the ifunc'ed one.  */
+#  define __gettimeofday_type __gettimeofday
+# endif
+
+# undef INIT_ARCH
+# define INIT_ARCH() PREPARE_VERSION_KNOWN (linux26, LINUX_2_6)
+/* If the vDSO is not available we fall back to syscall.  */
+libc_ifunc_hidden (__gettimeofday_type, __gettimeofday,
+		   (_dl_vdso_vsym ("__vdso_gettimeofday", &linux26)
+		    ?: &__gettimeofday_syscall))
+libc_hidden_def (__gettimeofday)
 
 #else
 
diff --git a/sysdeps/unix/sysv/linux/x86/time.c b/sysdeps/unix/sysv/linux/x86/time.c
index f5f7f91..a40fe39 100644
--- a/sysdeps/unix/sysv/linux/x86/time.c
+++ b/sysdeps/unix/sysv/linux/x86/time.c
@@ -30,20 +30,20 @@ __time_syscall (time_t *t)
   return INTERNAL_SYSCALL (time, err, 1, t);
 }
 
-void *time_ifunc (void) __asm__ ("time");
-
-void *
-time_ifunc (void)
-{
-  PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
-
+# ifndef time_type
+/* The i386 time.c includes this file with a defined time_type macro.
+   For x86_64 we have to define it to time as the internal symbol is the
+   ifunc'ed one.  */
+#  define time_type time
+# endif
+
+#undef INIT_ARCH
+#define INIT_ARCH() PREPARE_VERSION_KNOWN (linux26, LINUX_2_6);
 /* If the vDSO is not available we fall back on the syscall.  */
-  return _dl_vdso_vsym ("__vdso_time", &linux26)
-			?: (void*) &__time_syscall;
-}
-asm (".type time, %gnu_indirect_function");
-
-libc_ifunc_hidden_def(time)
+libc_ifunc_hidden (time_type, time,
+		   (_dl_vdso_vsym ("__vdso_time", &linux26)
+		    ?:  &__time_syscall))
+libc_hidden_def (time)
 
 #else
 
-- 
2.3.0

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc.
@ 2016-08-24 14:05 Stefan Liebler
  2016-08-24 14:05 ` [PATCH v3 8/9] Use libc_ifunc macro for vfork in libpthread Stefan Liebler
                   ` (10 more replies)
  0 siblings, 11 replies; 27+ messages in thread
From: Stefan Liebler @ 2016-08-24 14:05 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, fweimer, murphyp, schwab, joseph_myers

This patch adds a configure check to test if gcc supports attribute ifunc.
The support can either be enabled in <gcc-src>/gcc/config.gcc for one
architecture in general by setting default_gnu_indirect_function variable to yes
or by configuring gcc with --enable-gnu-indirect-function.

The next patch rewrites libc_ifunc macro to use gcc attribute ifunc instead
of inline assembly to generate the IFUNC symbols due to false debuginfo.

If gcc does not support attribute ifunc, the old approach for generating
ifunc'ed symbols is used. Then the debug-information is false. Thus it is
recommended to use a gcc with indirect function support (See notes in INSTALL).
After this patch-series these inline assemblies for ifunc-handling are not
scattered in multiple files but are used only indirect via ifunc-macros
and can simply removed in libc-symbols.h in future.

If glibc is configured with --enable-multi-arch and gcc does not support
attribute ifunc, a configure warning is dumped!

This NEWS entry will be added:
* For multi-arch support it is recommended to use a GCC with gnu-indirect-function
  support as it is used to generate ifunc'ed symbols with correct
  debug-information. This support can either be enabled by configuring GCC with
  '--enable-gnu-indirect-function' or by enabling it by default by setting
  'default_gnu_indirect_function' variable for a particular architecture in
  gcc source file 'gcc/config.gcc'.

ChangeLog:

	* config.h.in (HAVE_GCC_IFUNC): New undef.
	* configure.ac: Add check if gcc supports attribute ifunc feature.
	* configure: Regenerated.
	* manual/install.texi: Add recommendation for gcc with
	indirect-function support.
	* INSTALL: Regenerated.
---
 INSTALL             |  8 ++++++++
 config.h.in         |  3 +++
 configure           | 42 ++++++++++++++++++++++++++++++++++++++++++
 configure.ac        | 33 +++++++++++++++++++++++++++++++++
 manual/install.texi |  7 +++++++
 5 files changed, 93 insertions(+)

diff --git a/INSTALL b/INSTALL
index ec3445f..1a67891 100644
--- a/INSTALL
+++ b/INSTALL
@@ -359,6 +359,14 @@ build the GNU C Library:
      better code.  As of release time, GCC 5.3 is the newest compiler
      verified to work to build the GNU C Library.
 
+     For multi-arch support it is recommended to use a GCC with
+     gnu-indirect-function support as it is used to generate ifunc'ed
+     symbols with correct debug-information.  This support can either be
+     enabled by configuring GCC with '--enable-gnu-indirect-function' or
+     by enabling it by default by setting
+     'default_gnu_indirect_function' variable for a particular
+     architecture in gcc source file 'gcc/config.gcc'.
+
      You can use whatever compiler you like to compile programs that use
      the GNU C Library.
 
diff --git a/config.h.in b/config.h.in
index 856ef6a..9f5c5ff 100644
--- a/config.h.in
+++ b/config.h.in
@@ -171,6 +171,9 @@
 /* Define to 1 if STT_GNU_IFUNC support actually works.  */
 #define HAVE_IFUNC 0
 
+/* Define if gcc supports attribute ifunc.  */
+#undef HAVE_GCC_IFUNC
+
 /* Define if the linker defines __ehdr_start.  */
 #undef HAVE_EHDR_START
 
diff --git a/configure b/configure
index 17625e1..8ffc2b5 100755
--- a/configure
+++ b/configure
@@ -3914,6 +3914,36 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ld_gnu_indirect_function" >&5
 $as_echo "$libc_cv_ld_gnu_indirect_function" >&6; }
 
+# Check if gcc supports attribute ifunc as it is used in libc_ifunc macro.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc attribute ifunc support" >&5
+$as_echo_n "checking for gcc attribute ifunc support... " >&6; }
+if ${libc_cv_gcc_indirect_function+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.c <<EOF
+extern int func (int);
+int used_func (int a)
+{
+  return a;
+}
+static void *resolver ()
+{
+  return &used_func;
+}
+extern __typeof (func) func __attribute__ ((ifunc ("resolver")));
+EOF
+libc_cv_gcc_indirect_function=no
+if ${CC-cc} -c conftest.c -o conftest.o 1>&5 \
+   2>&5 ; then
+  if $READELF -s conftest.o | grep IFUNC >/dev/null 2>&5; then
+    libc_cv_gcc_indirect_function=yes
+  fi
+fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_indirect_function" >&5
+$as_echo "$libc_cv_gcc_indirect_function" >&6; }
+
 if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then
   if test x"$multi_arch" = xyes; then
     as_fn_error $? "--enable-multi-arch support requires assembler and linker support" "$LINENO" 5
@@ -3921,6 +3951,13 @@ if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then
     multi_arch=no
   fi
 fi
+if test x"$libc_cv_gcc_indirect_function" != xyes &&
+   test x"$multi_arch" = xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-multi-arch support recommends a gcc with gnu-indirect-function support.
+Please use a gcc which supports it by default or configure gcc with --enable-gnu-indirect-function" >&5
+$as_echo "$as_me: WARNING: --enable-multi-arch support recommends a gcc with gnu-indirect-function support.
+Please use a gcc which supports it by default or configure gcc with --enable-gnu-indirect-function" >&2;}
+fi
 multi_arch_d=
 if test x"$multi_arch" != xno; then
   multi_arch_d=/multiarch
@@ -6504,6 +6541,11 @@ if test x"$libc_cv_ld_gnu_indirect_function" = xyes; then
 
 fi
 
+if test x"$libc_cv_gcc_indirect_function" = xyes; then
+  $as_echo "#define HAVE_GCC_IFUNC 1" >>confdefs.h
+
+fi
+
 # This is far from the AC_ARG_ENABLE that sets it so that a sysdeps
 # configure fragment can override the value to prevent this AC_DEFINE.
 
diff --git a/configure.ac b/configure.ac
index 33bcd62..643002f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -634,6 +634,30 @@ if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
 fi
 rm -f conftest*])
 
+# Check if gcc supports attribute ifunc as it is used in libc_ifunc macro.
+AC_CACHE_CHECK([for gcc attribute ifunc support],
+	       libc_cv_gcc_indirect_function, [dnl
+cat > conftest.c <<EOF
+extern int func (int);
+int used_func (int a)
+{
+  return a;
+}
+static void *resolver ()
+{
+  return &used_func;
+}
+extern __typeof (func) func __attribute__ ((ifunc ("resolver")));
+EOF
+libc_cv_gcc_indirect_function=no
+if ${CC-cc} -c conftest.c -o conftest.o 1>&AS_MESSAGE_LOG_FD \
+   2>&AS_MESSAGE_LOG_FD ; then
+  if $READELF -s conftest.o | grep IFUNC >/dev/null 2>&AS_MESSAGE_LOG_FD; then
+    libc_cv_gcc_indirect_function=yes
+  fi
+fi
+rm -f conftest*])
+
 if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then
   if test x"$multi_arch" = xyes; then
     AC_MSG_ERROR([--enable-multi-arch support requires assembler and linker support])
@@ -641,6 +665,11 @@ if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then
     multi_arch=no
   fi
 fi
+if test x"$libc_cv_gcc_indirect_function" != xyes &&
+   test x"$multi_arch" = xyes; then
+  AC_MSG_WARN([--enable-multi-arch support recommends a gcc with gnu-indirect-function support.
+Please use a gcc which supports it by default or configure gcc with --enable-gnu-indirect-function])
+fi
 multi_arch_d=
 if test x"$multi_arch" != xno; then
   multi_arch_d=/multiarch
@@ -1770,6 +1799,10 @@ if test x"$libc_cv_ld_gnu_indirect_function" = xyes; then
   AC_DEFINE(HAVE_IFUNC)
 fi
 
+if test x"$libc_cv_gcc_indirect_function" = xyes; then
+  AC_DEFINE(HAVE_GCC_IFUNC)
+fi
+
 # This is far from the AC_ARG_ENABLE that sets it so that a sysdeps
 # configure fragment can override the value to prevent this AC_DEFINE.
 AC_SUBST(use_nscd)
diff --git a/manual/install.texi b/manual/install.texi
index 79ee45f..d738ee0 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -402,6 +402,13 @@ the newest version of the compiler that is known to work for building
 release time, GCC 5.3 is the newest compiler verified to work to build
 @theglibc{}.
 
+For multi-arch support it is recommended to use a GCC with gnu-indirect-function
+support as it is used to generate ifunc'ed symbols with correct
+debug-information. This support can either be enabled by configuring GCC with
+@samp{--enable-gnu-indirect-function} or by enabling it by default by setting
+@samp{default_gnu_indirect_function} variable for a particular architecture in
+gcc source file @file{gcc/config.gcc}.
+
 You can use whatever compiler you like to compile programs that use
 @theglibc{}.
 
-- 
2.3.0

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v3 3/9] s390: Refactor ifunc resolvers due to false debuginfo.
  2016-08-24 14:05 [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Stefan Liebler
                   ` (4 preceding siblings ...)
  2016-08-24 14:05 ` [PATCH v3 5/9] ppc: " Stefan Liebler
@ 2016-08-24 14:05 ` Stefan Liebler
  2016-08-30 12:31   ` Florian Weimer
  2016-08-24 14:05 ` [PATCH v3 2/9] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly " Stefan Liebler
                   ` (4 subsequent siblings)
  10 siblings, 1 reply; 27+ messages in thread
From: Stefan Liebler @ 2016-08-24 14:05 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, fweimer, murphyp, schwab, joseph_myers

This patch adjusts the s390 specific ifunc helper macros in ifunc-resolve.h to
use the common __ifunc macro, which uses gcc attribute ifunc to get rid of the
false debuginfo. Therefore the redirection construct is applied where needed.

Perhaps in future we can switch some of the internal symbols __GI_* from the
fallback variant to the ifunc function. But this change is not
straightforward due to a segmentation fault while linking libc.so with older
binutils on s390.

ChangeLog:

	* sysdeps/s390/multiarch/ifunc-resolve.h
	(s390_vx_libc_ifunc2, s390_libc_ifunc): Use __ifunc from libc-symbols.h
	to create ifunc symbols.
	(s390_vx_libc_ifunc_init, s390_vx_libc_ifunc_redirected
	, s390_vx_libc_ifunc2_redirected, s390_libc_ifunc_init): New define.
	* sysdeps/s390/multiarch/memchr.c: Redirect ifunced function in header
	for using it as type for ifunc function.
	* sysdeps/s390/multiarch/mempcpy.c: Likewise.
	* sysdeps/s390/multiarch/rawmemchr.c: Likewise.
	* sysdeps/s390/multiarch/stpcpy.c: Likewise.
	* sysdeps/s390/multiarch/stpncpy.c: Likewise.
	* sysdeps/s390/multiarch/strcat.c: Likewise.
	* sysdeps/s390/multiarch/strchr.c: Likewise.
	* sysdeps/s390/multiarch/strcmp.c: Likewise.
	* sysdeps/s390/multiarch/strcpy.c: Likewise.
	* sysdeps/s390/multiarch/strcspn.c: Likewise.
	* sysdeps/s390/multiarch/strlen.c: Likewise.
	* sysdeps/s390/multiarch/strncmp.c: Likewise.
	* sysdeps/s390/multiarch/strncpy.c: Likewise.
	* sysdeps/s390/multiarch/strnlen.c: Likewise.
	* sysdeps/s390/multiarch/strpbrk.c: Likewise.
	* sysdeps/s390/multiarch/strrchr.c: Likewise.
	* sysdeps/s390/multiarch/strspn.c: Likewise.
	* sysdeps/s390/multiarch/wcschr.c: Likewise.
	* sysdeps/s390/multiarch/wcscmp.c: Likewise.
	* sysdeps/s390/multiarch/wcspbrk.c: Likewise.
	* sysdeps/s390/multiarch/wcsspn.c: Likewise.
	* sysdeps/s390/multiarch/wmemchr.c: Likewise.
	* sysdeps/s390/multiarch/wmemset.c: Likewise.
	* sysdeps/s390/s390-32/multiarch/memcmp.c: Likewise.
	* sysdeps/s390/s390-32/multiarch/memcpy.c: Likewise.
	* sysdeps/s390/s390-32/multiarch/memset.c: Likewise.
	* sysdeps/s390/s390-64/multiarch/memcmp.c: Likewise.
	* sysdeps/s390/s390-64/multiarch/memcpy.c: Likewise.
	* sysdeps/s390/s390-64/multiarch/memset.c: Likewise.
---
 sysdeps/s390/multiarch/ifunc-resolve.h  | 77 +++++++++++++++------------------
 sysdeps/s390/multiarch/memchr.c         |  5 ++-
 sysdeps/s390/multiarch/mempcpy.c        | 12 +++--
 sysdeps/s390/multiarch/rawmemchr.c      |  5 ++-
 sysdeps/s390/multiarch/stpcpy.c         |  9 +++-
 sysdeps/s390/multiarch/stpncpy.c        |  6 ++-
 sysdeps/s390/multiarch/strcat.c         |  4 +-
 sysdeps/s390/multiarch/strchr.c         |  6 ++-
 sysdeps/s390/multiarch/strcmp.c         |  7 ++-
 sysdeps/s390/multiarch/strcpy.c         |  5 ++-
 sysdeps/s390/multiarch/strcspn.c        |  6 ++-
 sysdeps/s390/multiarch/strlen.c         |  4 +-
 sysdeps/s390/multiarch/strncmp.c        |  9 ++--
 sysdeps/s390/multiarch/strncpy.c        |  7 ++-
 sysdeps/s390/multiarch/strnlen.c        |  7 ++-
 sysdeps/s390/multiarch/strpbrk.c        |  6 ++-
 sysdeps/s390/multiarch/strrchr.c        |  6 ++-
 sysdeps/s390/multiarch/strspn.c         |  6 ++-
 sysdeps/s390/multiarch/wcschr.c         |  7 ++-
 sysdeps/s390/multiarch/wcscmp.c         |  4 +-
 sysdeps/s390/multiarch/wcspbrk.c        |  4 +-
 sysdeps/s390/multiarch/wcsspn.c         |  4 +-
 sysdeps/s390/multiarch/wmemchr.c        |  7 ++-
 sysdeps/s390/multiarch/wmemset.c        |  7 ++-
 sysdeps/s390/s390-32/multiarch/memcmp.c |  7 ++-
 sysdeps/s390/s390-32/multiarch/memcpy.c |  5 ++-
 sysdeps/s390/s390-32/multiarch/memset.c |  5 ++-
 sysdeps/s390/s390-64/multiarch/memcmp.c |  7 ++-
 sysdeps/s390/s390-64/multiarch/memcpy.c |  5 ++-
 sysdeps/s390/s390-64/multiarch/memset.c |  5 ++-
 30 files changed, 169 insertions(+), 85 deletions(-)

diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h
index 26e097a..768829b 100644
--- a/sysdeps/s390/multiarch/ifunc-resolve.h
+++ b/sysdeps/s390/multiarch/ifunc-resolve.h
@@ -40,53 +40,46 @@
 		       ".machine pop"         "\n"			\
 		       : "=QS" (STFLE_BITS), "+d" (reg0)		\
 		       : : "cc");
+#define s390_libc_ifunc_init()						\
+  unsigned long long stfle_bits = 0ULL;					\
+  if (__glibc_likely((dl_hwcap & HWCAP_S390_STFLE)			\
+		     && (dl_hwcap & HWCAP_S390_ZARCH)			\
+		     && (dl_hwcap & HWCAP_S390_HIGH_GPRS)))		\
+    {									\
+      S390_STORE_STFLE (stfle_bits);					\
+    }
 
-#define s390_libc_ifunc(FUNC)						\
-  __asm__ (".globl " #FUNC "\n\t"					\
-	   ".type  " #FUNC ",@gnu_indirect_function\n\t"		\
-	   ".set   " #FUNC ",__resolve_" #FUNC "\n\t");			\
-									\
+#define s390_libc_ifunc(TYPE_FUNC, RESOLVERFUNC, FUNC)			\
   /* Make the declarations of the optimized functions hidden in order
      to prevent GOT slots being generated for them. */			\
-  extern void *__##FUNC##_z196 attribute_hidden;			\
-  extern void *__##FUNC##_z10 attribute_hidden;				\
-  extern void *__##FUNC##_default attribute_hidden;			\
-									\
-  void *__resolve_##FUNC (unsigned long int dl_hwcap)			\
-  {									\
-    if ((dl_hwcap & HWCAP_S390_STFLE)					\
-	&& (dl_hwcap & HWCAP_S390_ZARCH)				\
-	&& (dl_hwcap & HWCAP_S390_HIGH_GPRS))				\
-      {									\
-	unsigned long long stfle_bits;					\
-	S390_STORE_STFLE (stfle_bits);					\
-									\
-	if (S390_IS_Z196 (stfle_bits))					\
-	  return &__##FUNC##_z196;					\
-	else if (S390_IS_Z10 (stfle_bits))				\
-	  return &__##FUNC##_z10;					\
-	else								\
-	  return &__##FUNC##_default;					\
-      }									\
-    else								\
-      return &__##FUNC##_default;					\
-  }
+  extern __typeof (TYPE_FUNC) RESOLVERFUNC##_z196 attribute_hidden;	\
+  extern __typeof (TYPE_FUNC) RESOLVERFUNC##_z10 attribute_hidden;      \
+  extern __typeof (TYPE_FUNC) RESOLVERFUNC##_default attribute_hidden;  \
+  __ifunc (TYPE_FUNC, FUNC,						\
+	   __glibc_likely (S390_IS_Z196 (stfle_bits))			\
+	   ? RESOLVERFUNC##_z196					\
+	   : __glibc_likely (S390_IS_Z10 (stfle_bits))			\
+	     ? RESOLVERFUNC##_z10					\
+	     : RESOLVERFUNC##_default,					\
+	   unsigned long int dl_hwcap, s390_libc_ifunc_init);
 
 #define s390_vx_libc_ifunc(FUNC)		\
-  s390_vx_libc_ifunc2(FUNC, FUNC)
+  s390_vx_libc_ifunc2_redirected(FUNC, FUNC, FUNC)
 
-#define s390_vx_libc_ifunc2(RESOLVERFUNC, FUNC)				\
+#define s390_vx_libc_ifunc_redirected(TYPE_FUNC, FUNC)	\
+  s390_vx_libc_ifunc2_redirected(TYPE_FUNC, FUNC, FUNC)
+
+#define s390_vx_libc_ifunc2(RESOLVERFUNC, FUNC)	\
+  s390_vx_libc_ifunc2_redirected(FUNC, RESOLVERFUNC, FUNC)
+
+#define s390_vx_libc_ifunc_init()
+#define s390_vx_libc_ifunc2_redirected(TYPE_FUNC, RESOLVERFUNC, FUNC)	\
   /* Make the declarations of the optimized functions hidden in order
      to prevent GOT slots being generated for them.  */			\
-  extern __typeof (FUNC) RESOLVERFUNC##_vx attribute_hidden;		\
-  extern __typeof (FUNC) RESOLVERFUNC##_c attribute_hidden;		\
-  extern void *__resolve_##RESOLVERFUNC (unsigned long int) __asm__ (#FUNC); \
-									\
-  void *__resolve_##RESOLVERFUNC (unsigned long int dl_hwcap)		\
-  {									\
-    if (dl_hwcap & HWCAP_S390_VX)					\
-      return &RESOLVERFUNC##_vx;					\
-    else								\
-      return &RESOLVERFUNC##_c;						\
-  }									\
- __asm__ (".type " #FUNC ", %gnu_indirect_function");
+  extern __typeof (TYPE_FUNC) RESOLVERFUNC##_vx attribute_hidden;	\
+  extern __typeof (TYPE_FUNC) RESOLVERFUNC##_c attribute_hidden;	\
+  __ifunc (TYPE_FUNC, FUNC,						\
+	   (dl_hwcap & HWCAP_S390_VX)					\
+	   ? RESOLVERFUNC##_vx						\
+	   : RESOLVERFUNC##_c,						\
+	   unsigned long int dl_hwcap, s390_vx_libc_ifunc_init);
diff --git a/sysdeps/s390/multiarch/memchr.c b/sysdeps/s390/multiarch/memchr.c
index f80de1c..891ec7a 100644
--- a/sysdeps/s390/multiarch/memchr.c
+++ b/sysdeps/s390/multiarch/memchr.c
@@ -17,8 +17,11 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define memchr __redirect_memchr
 # include <string.h>
+# undef memchr
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc2 (__memchr, memchr)
+s390_vx_libc_ifunc2_redirected (__redirect_memchr, __memchr, memchr)
+
 #endif
diff --git a/sysdeps/s390/multiarch/mempcpy.c b/sysdeps/s390/multiarch/mempcpy.c
index 34d8329..bee3ee4 100644
--- a/sysdeps/s390/multiarch/mempcpy.c
+++ b/sysdeps/s390/multiarch/mempcpy.c
@@ -18,9 +18,15 @@
 
 
 #if defined SHARED && IS_IN (libc)
+# define mempcpy __redirect_mempcpy
+# define __mempcpy __redirect___mempcpy
+/* Omit the mempcpy inline definitions because it would redefine mempcpy.  */
+# define _HAVE_STRING_ARCH_mempcpy 1
+# include <string.h>
+# undef mempcpy
+# undef __mempcpy
 # include <ifunc-resolve.h>
-s390_libc_ifunc (__mempcpy)
 
-__asm__ (".weak mempcpy\n\t"
-	 ".set mempcpy,__mempcpy\n\t");
+s390_libc_ifunc (__redirect___mempcpy, ____mempcpy, __mempcpy)
+weak_alias (__mempcpy, mempcpy);
 #endif
diff --git a/sysdeps/s390/multiarch/rawmemchr.c b/sysdeps/s390/multiarch/rawmemchr.c
index 7186ccd..c4afa24 100644
--- a/sysdeps/s390/multiarch/rawmemchr.c
+++ b/sysdeps/s390/multiarch/rawmemchr.c
@@ -17,10 +17,13 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define __rawmemchr __redirect___rawmemchr
 # include <string.h>
+# undef __rawmemchr
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc (__rawmemchr)
+s390_vx_libc_ifunc2_redirected (__redirect___rawmemchr, __rawmemchr
+				, __rawmemchr)
 weak_alias (__rawmemchr, rawmemchr)
 
 #else
diff --git a/sysdeps/s390/multiarch/stpcpy.c b/sysdeps/s390/multiarch/stpcpy.c
index dcde012..cea6c07 100644
--- a/sysdeps/s390/multiarch/stpcpy.c
+++ b/sysdeps/s390/multiarch/stpcpy.c
@@ -17,13 +17,18 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define stpcpy __redirect_stpcpy
+# define __stpcpy __redirect___stpcpy
+/* Omit the stpcpy inline definitions because it would redefine stpcpy.  */
+# define __NO_STRING_INLINES
 # define NO_MEMPCPY_STPCPY_REDIRECT
 # include <string.h>
+# undef stpcpy
+# undef __stpcpy
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc (__stpcpy)
+s390_vx_libc_ifunc_redirected (__redirect___stpcpy, __stpcpy);
 weak_alias (__stpcpy, stpcpy)
-libc_hidden_builtin_def (stpcpy)
 
 #else
 # include <string/stpcpy.c>
diff --git a/sysdeps/s390/multiarch/stpncpy.c b/sysdeps/s390/multiarch/stpncpy.c
index f5335b4..cbbe8ba 100644
--- a/sysdeps/s390/multiarch/stpncpy.c
+++ b/sysdeps/s390/multiarch/stpncpy.c
@@ -17,10 +17,14 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define stpncpy __redirect_stpncpy
+# define __stpncpy __redirect___stpncpy
 # include <string.h>
+# undef stpncpy
+# undef __stpncpy
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc (__stpncpy)
+s390_vx_libc_ifunc_redirected (__redirect___stpncpy, __stpncpy)
 weak_alias (__stpncpy, stpncpy)
 
 #else
diff --git a/sysdeps/s390/multiarch/strcat.c b/sysdeps/s390/multiarch/strcat.c
index c3b5e1c..0c74c91 100644
--- a/sysdeps/s390/multiarch/strcat.c
+++ b/sysdeps/s390/multiarch/strcat.c
@@ -17,10 +17,12 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strcat __redirect_strcat
 # include <string.h>
+# undef strcat
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc2 (__strcat, strcat)
+s390_vx_libc_ifunc2_redirected (__redirect_strcat, __strcat, strcat)
 
 #else
 # include <string/strcat.c>
diff --git a/sysdeps/s390/multiarch/strchr.c b/sysdeps/s390/multiarch/strchr.c
index 3c8c7e4..3b378b9 100644
--- a/sysdeps/s390/multiarch/strchr.c
+++ b/sysdeps/s390/multiarch/strchr.c
@@ -17,10 +17,14 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strchr __redirect_strchr
+/* Omit the strchr inline definitions because it would redefine strchr.  */
+# define __NO_STRING_INLINES
 # include <string.h>
+# undef strchr
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc2 (__strchr, strchr)
+s390_vx_libc_ifunc2_redirected (__redirect_strchr, __strchr, strchr)
 weak_alias (strchr, index)
 
 #else
diff --git a/sysdeps/s390/multiarch/strcmp.c b/sysdeps/s390/multiarch/strcmp.c
index c4ccd34..faeaaa5 100644
--- a/sysdeps/s390/multiarch/strcmp.c
+++ b/sysdeps/s390/multiarch/strcmp.c
@@ -17,10 +17,13 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strcmp __redirect_strcmp
+/* Omit the strcmp inline definitions because it would redefine strcmp.  */
+# define __NO_STRING_INLINES
 # include <string.h>
 # include <ifunc-resolve.h>
+# undef strcmp
 
+s390_vx_libc_ifunc2_redirected (__redirect_strcmp, __strcmp, strcmp)
 
-# undef strcmp
-s390_vx_libc_ifunc2 (__strcmp, strcmp)
 #endif
diff --git a/sysdeps/s390/multiarch/strcpy.c b/sysdeps/s390/multiarch/strcpy.c
index f348199..9053b12 100644
--- a/sysdeps/s390/multiarch/strcpy.c
+++ b/sysdeps/s390/multiarch/strcpy.c
@@ -17,8 +17,11 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strcpy __redirect_strcpy
 # include <string.h>
+# undef strcpy
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc2 (__strcpy, strcpy)
+s390_vx_libc_ifunc2_redirected (__redirect_strcpy, __strcpy, strcpy)
+
 #endif
diff --git a/sysdeps/s390/multiarch/strcspn.c b/sysdeps/s390/multiarch/strcspn.c
index c23452a..d1fe33b 100644
--- a/sysdeps/s390/multiarch/strcspn.c
+++ b/sysdeps/s390/multiarch/strcspn.c
@@ -17,10 +17,14 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strcspn __redirect_strcspn
+/* Omit the strcspn inline definitions because it would redefine strcspn.  */
+# define __NO_STRING_INLINES
 # include <string.h>
+# undef strcspn
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc2 (__strcspn, strcspn)
+s390_vx_libc_ifunc2_redirected (__redirect_strcspn, __strcspn, strcspn)
 
 #else
 # include <string/strcspn.c>
diff --git a/sysdeps/s390/multiarch/strlen.c b/sysdeps/s390/multiarch/strlen.c
index 098d4e1..8329f2b 100644
--- a/sysdeps/s390/multiarch/strlen.c
+++ b/sysdeps/s390/multiarch/strlen.c
@@ -17,10 +17,12 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strlen __redirect_strlen
 # include <string.h>
 # include <ifunc-resolve.h>
+# undef strlen
 
-s390_vx_libc_ifunc2 (__strlen, strlen)
+s390_vx_libc_ifunc2_redirected (__redirect_strlen, __strlen, strlen)
 
 #else
 # include <string/strlen.c>
diff --git a/sysdeps/s390/multiarch/strncmp.c b/sysdeps/s390/multiarch/strncmp.c
index 9a72c79..2bdf4bf 100644
--- a/sysdeps/s390/multiarch/strncmp.c
+++ b/sysdeps/s390/multiarch/strncmp.c
@@ -17,13 +17,14 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strncmp __redirect_strncmp
+/* Omit the strncmp inline definitions because it would redefine strncmp.  */
+# define __NO_STRING_INLINES
 # include <string.h>
+# undef strncmp
 # include <ifunc-resolve.h>
 
-
-# undef strcmp
-extern __typeof (strncmp) __strncmp;
-s390_vx_libc_ifunc2 (__strncmp, strncmp)
+s390_vx_libc_ifunc2_redirected (__redirect_strncmp, __strncmp, strncmp)
 
 #else
 # include <string/strncmp.c>
diff --git a/sysdeps/s390/multiarch/strncpy.c b/sysdeps/s390/multiarch/strncpy.c
index 1464551..c4d13a9 100644
--- a/sysdeps/s390/multiarch/strncpy.c
+++ b/sysdeps/s390/multiarch/strncpy.c
@@ -17,8 +17,13 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strncpy __redirect_strncpy
+/* Omit the strncpy inline definitions because it would redefine strncpy.  */
+# define __NO_STRING_INLINES
 # include <string.h>
+# undef strncpy
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc2 (__strncpy, strncpy)
+s390_vx_libc_ifunc2_redirected (__redirect_strncpy, __strncpy, strncpy);
+
 #endif
diff --git a/sysdeps/s390/multiarch/strnlen.c b/sysdeps/s390/multiarch/strnlen.c
index 48c3bb7..ecb69eb 100644
--- a/sysdeps/s390/multiarch/strnlen.c
+++ b/sysdeps/s390/multiarch/strnlen.c
@@ -17,12 +17,15 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strnlen __redirect_strnlen
+# define __strnlen __redirect___strnlen
 # include <string.h>
+# undef strnlen
+# undef __strnlen
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc (__strnlen)
+s390_vx_libc_ifunc_redirected (__redirect___strnlen, __strnlen)
 weak_alias (__strnlen, strnlen)
-libc_hidden_def (strnlen)
 
 #else
 # include <string/strnlen.c>
diff --git a/sysdeps/s390/multiarch/strpbrk.c b/sysdeps/s390/multiarch/strpbrk.c
index cdc1399..09c3fff 100644
--- a/sysdeps/s390/multiarch/strpbrk.c
+++ b/sysdeps/s390/multiarch/strpbrk.c
@@ -17,10 +17,14 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strpbrk __redirect_strpbrk
+/* Omit the strpbrk inline definitions because it would redefine strpbrk.  */
+# define __NO_STRING_INLINES
 # include <string.h>
+# undef strpbrk
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc2 (__strpbrk, strpbrk)
+s390_vx_libc_ifunc2_redirected (__redirect_strpbrk, __strpbrk, strpbrk)
 
 #else
 # include <string/strpbrk.c>
diff --git a/sysdeps/s390/multiarch/strrchr.c b/sysdeps/s390/multiarch/strrchr.c
index e515d6b..2da8581 100644
--- a/sysdeps/s390/multiarch/strrchr.c
+++ b/sysdeps/s390/multiarch/strrchr.c
@@ -17,11 +17,13 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strrchr __redirect_strrchr
 # include <string.h>
+# undef strrchr
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc2 (__strrchr, strrchr)
-weak_alias (strrchr, rindex)
+s390_vx_libc_ifunc2_redirected (__redirect_strrchr, __strrchr, strrchr)
+weak_alias (strrchr, rindex);
 
 #else
 # include <string/strrchr.c>
diff --git a/sysdeps/s390/multiarch/strspn.c b/sysdeps/s390/multiarch/strspn.c
index 7c26af8..1d9514d 100644
--- a/sysdeps/s390/multiarch/strspn.c
+++ b/sysdeps/s390/multiarch/strspn.c
@@ -17,10 +17,14 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define strspn __redirect_strspn
+/* Omit the strspn inline definitions because it would redefine strspn.  */
+# define __NO_STRING_INLINES
 # include <string.h>
+# undef strspn
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc2 (__strspn, strspn)
+s390_vx_libc_ifunc2_redirected (__redirect_strspn, __strspn, strspn)
 
 #else
 # include <string/strspn.c>
diff --git a/sysdeps/s390/multiarch/wcschr.c b/sysdeps/s390/multiarch/wcschr.c
index fb51097..3e0ff8b 100644
--- a/sysdeps/s390/multiarch/wcschr.c
+++ b/sysdeps/s390/multiarch/wcschr.c
@@ -17,12 +17,15 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define wcschr __redirect_wcschr
+# define __wcschr __redirect___wcschr
 # include <wchar.h>
+# undef wcschr
+# undef __wcschr
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc (__wcschr)
+s390_vx_libc_ifunc_redirected (__redirect___wcschr, __wcschr)
 weak_alias (__wcschr, wcschr)
-libc_hidden_weak (wcschr)
 
 #else
 # include <wcsmbs/wcschr.c>
diff --git a/sysdeps/s390/multiarch/wcscmp.c b/sysdeps/s390/multiarch/wcscmp.c
index 705ef45..dc29b32 100644
--- a/sysdeps/s390/multiarch/wcscmp.c
+++ b/sysdeps/s390/multiarch/wcscmp.c
@@ -17,10 +17,12 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define __wcscmp __redirect___wcscmp
 # include <wchar.h>
+# undef __wcscmp
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc (__wcscmp)
+s390_vx_libc_ifunc_redirected (__redirect___wcscmp, __wcscmp)
 weak_alias (__wcscmp, wcscmp)
 
 #else
diff --git a/sysdeps/s390/multiarch/wcspbrk.c b/sysdeps/s390/multiarch/wcspbrk.c
index 198144d..9824bd5 100644
--- a/sysdeps/s390/multiarch/wcspbrk.c
+++ b/sysdeps/s390/multiarch/wcspbrk.c
@@ -17,10 +17,12 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define wcspbrk __redirect_wcspbrk
 # include <wchar.h>
+# undef wcspbrk
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc2 (__wcspbrk, wcspbrk)
+s390_vx_libc_ifunc2_redirected (__redirect_wcspbrk, __wcspbrk, wcspbrk)
 
 #else
 # include <wcsmbs/wcspbrk.c>
diff --git a/sysdeps/s390/multiarch/wcsspn.c b/sysdeps/s390/multiarch/wcsspn.c
index 167a881..d153d44 100644
--- a/sysdeps/s390/multiarch/wcsspn.c
+++ b/sysdeps/s390/multiarch/wcsspn.c
@@ -17,10 +17,12 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define wcsspn __redirect_wcsspn
 # include <wchar.h>
+# undef wcsspn
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc2 (__wcsspn, wcsspn)
+s390_vx_libc_ifunc2_redirected (__redirect_wcsspn, __wcsspn, wcsspn)
 
 #else
 # include <wcsmbs/wcsspn.c>
diff --git a/sysdeps/s390/multiarch/wmemchr.c b/sysdeps/s390/multiarch/wmemchr.c
index f2bfe3c..45b3441 100644
--- a/sysdeps/s390/multiarch/wmemchr.c
+++ b/sysdeps/s390/multiarch/wmemchr.c
@@ -17,12 +17,15 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define wmemchr __redirect_wmemchr
+# define __wmemchr __redirect___wmemchr
 # include <wchar.h>
+# undef wmemchr
+# undef __wmemchr
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc (__wmemchr)
+s390_vx_libc_ifunc_redirected (__redirect___wmemchr, __wmemchr)
 weak_alias (__wmemchr, wmemchr)
-libc_hidden_weak (wmemchr)
 
 #else
 # include <wcsmbs/wmemchr.c>
diff --git a/sysdeps/s390/multiarch/wmemset.c b/sysdeps/s390/multiarch/wmemset.c
index e9e695f..2fc57ee 100644
--- a/sysdeps/s390/multiarch/wmemset.c
+++ b/sysdeps/s390/multiarch/wmemset.c
@@ -17,12 +17,15 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define wmemset __redirect_wmemset
+# define __wmemset __redirect___wmemset
 # include <wchar.h>
+# undef wmemset
+# undef __wmemset
 # include <ifunc-resolve.h>
 
-s390_vx_libc_ifunc (__wmemset)
+s390_vx_libc_ifunc_redirected (__redirect___wmemset, __wmemset)
 weak_alias (__wmemset, wmemset)
-libc_hidden_weak (wmemset)
 
 #else
 # include <wcsmbs/wmemset.c>
diff --git a/sysdeps/s390/s390-32/multiarch/memcmp.c b/sysdeps/s390/s390-32/multiarch/memcmp.c
index 44f72dc..453b170 100644
--- a/sysdeps/s390/s390-32/multiarch/memcmp.c
+++ b/sysdeps/s390/s390-32/multiarch/memcmp.c
@@ -17,8 +17,11 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define memcmp __redirect_memcmp
+# include <string.h>
+# undef memcmp
 # include <ifunc-resolve.h>
 
-s390_libc_ifunc (memcmp)
-__asm__(".weak bcmp ; bcmp = memcmp");
+s390_libc_ifunc (__redirect_memcmp, __memcmp, memcmp)
+weak_alias (memcmp, bcmp);
 #endif
diff --git a/sysdeps/s390/s390-32/multiarch/memcpy.c b/sysdeps/s390/s390-32/multiarch/memcpy.c
index 2a98aa0..33e4bcd 100644
--- a/sysdeps/s390/s390-32/multiarch/memcpy.c
+++ b/sysdeps/s390/s390-32/multiarch/memcpy.c
@@ -18,7 +18,10 @@
 
 /* In the static lib memcpy is needed before the reloc is resolved.  */
 #if defined SHARED && IS_IN (libc)
+# define memcpy __redirect_memcpy
+# include <string.h>
+# undef memcpy
 # include <ifunc-resolve.h>
 
-s390_libc_ifunc (memcpy)
+s390_libc_ifunc (__redirect_memcpy, __memcpy, memcpy)
 #endif
diff --git a/sysdeps/s390/s390-32/multiarch/memset.c b/sysdeps/s390/s390-32/multiarch/memset.c
index 89b8102..84ddeda 100644
--- a/sysdeps/s390/s390-32/multiarch/memset.c
+++ b/sysdeps/s390/s390-32/multiarch/memset.c
@@ -17,7 +17,10 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define memset __redirect_memset
+# include <string.h>
+# undef memset
 # include <ifunc-resolve.h>
 
-s390_libc_ifunc (memset)
+s390_libc_ifunc (__redirect_memset, __memset, memset)
 #endif
diff --git a/sysdeps/s390/s390-64/multiarch/memcmp.c b/sysdeps/s390/s390-64/multiarch/memcmp.c
index 44f72dc..453b170 100644
--- a/sysdeps/s390/s390-64/multiarch/memcmp.c
+++ b/sysdeps/s390/s390-64/multiarch/memcmp.c
@@ -17,8 +17,11 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define memcmp __redirect_memcmp
+# include <string.h>
+# undef memcmp
 # include <ifunc-resolve.h>
 
-s390_libc_ifunc (memcmp)
-__asm__(".weak bcmp ; bcmp = memcmp");
+s390_libc_ifunc (__redirect_memcmp, __memcmp, memcmp)
+weak_alias (memcmp, bcmp);
 #endif
diff --git a/sysdeps/s390/s390-64/multiarch/memcpy.c b/sysdeps/s390/s390-64/multiarch/memcpy.c
index 2a98aa0..33e4bcd 100644
--- a/sysdeps/s390/s390-64/multiarch/memcpy.c
+++ b/sysdeps/s390/s390-64/multiarch/memcpy.c
@@ -18,7 +18,10 @@
 
 /* In the static lib memcpy is needed before the reloc is resolved.  */
 #if defined SHARED && IS_IN (libc)
+# define memcpy __redirect_memcpy
+# include <string.h>
+# undef memcpy
 # include <ifunc-resolve.h>
 
-s390_libc_ifunc (memcpy)
+s390_libc_ifunc (__redirect_memcpy, __memcpy, memcpy)
 #endif
diff --git a/sysdeps/s390/s390-64/multiarch/memset.c b/sysdeps/s390/s390-64/multiarch/memset.c
index 89b8102..84ddeda 100644
--- a/sysdeps/s390/s390-64/multiarch/memset.c
+++ b/sysdeps/s390/s390-64/multiarch/memset.c
@@ -17,7 +17,10 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define memset __redirect_memset
+# include <string.h>
+# undef memset
 # include <ifunc-resolve.h>
 
-s390_libc_ifunc (memset)
+s390_libc_ifunc (__redirect_memset, __memset, memset)
 #endif
-- 
2.3.0

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v3 9/9] Use libc_ifunc macro for siglongjmp, longjmp in libpthread.
  2016-08-24 14:05 [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Stefan Liebler
  2016-08-24 14:05 ` [PATCH v3 8/9] Use libc_ifunc macro for vfork in libpthread Stefan Liebler
@ 2016-08-24 14:05 ` Stefan Liebler
  2016-10-06 11:59   ` Florian Weimer
  2016-08-24 14:05 ` [PATCH v3 6/9] Use libc_ifunc macro for clock_* symbols in librt Stefan Liebler
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 27+ messages in thread
From: Stefan Liebler @ 2016-08-24 14:05 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, fweimer, murphyp, schwab, joseph_myers

This patch uses the libc_ifunc macro to create already existing ifunc functions
longjmp_ifunc, siglongjmp_ifunc if HAVE_IFUNC is defined.
The s390 pt-longjmp.c includes the common pt-longjmp.c and uses strong_alias
to create the longjmp, siglongjmp symbols for glibc version 2.19.

ChangeLog:

	* nptl/pt-longjmp.c (DEFINE_LONGJMP): Use libc_ifunc macro.
	* sysdeps/unix/sysv/linux/s390/pt-longjmp.c (longjmp, siglongjmp):
	Use strong_alias to create symbols for glibc verison 2.19.
---
 nptl/pt-longjmp.c                         | 24 ++++++------------------
 sysdeps/unix/sysv/linux/s390/pt-longjmp.c |  4 ++--
 2 files changed, 8 insertions(+), 20 deletions(-)

diff --git a/nptl/pt-longjmp.c b/nptl/pt-longjmp.c
index a1cc286..a19cd59 100644
--- a/nptl/pt-longjmp.c
+++ b/nptl/pt-longjmp.c
@@ -32,24 +32,12 @@
 
 # if HAVE_IFUNC
 
-static __typeof (longjmp) *
-__attribute__ ((used))
-longjmp_resolve (void)
-{
-  return &__libc_longjmp;
-}
+#  undef INIT_ARCH
+#  define INIT_ARCH()
+#  define DEFINE_LONGJMP(name) libc_ifunc (name, &__libc_longjmp)
 
-#  ifdef HAVE_ASM_SET_DIRECTIVE
-#   define DEFINE_LONGJMP(name) \
-  asm (".set " #name ", longjmp_resolve\n" \
-       ".globl " #name "\n" \
-       ".type " #name ", %gnu_indirect_function");
-#  else
-#   define DEFINE_LONGJMP(name) \
-  asm (#name " = longjmp_resolve\n" \
-       ".globl " #name "\n" \
-       ".type " #name ", %gnu_indirect_function");
-#  endif
+extern __typeof(longjmp) longjmp_ifunc;
+extern __typeof(siglongjmp) siglongjmp_ifunc;
 
 # else  /* !HAVE_IFUNC */
 
@@ -66,7 +54,7 @@ longjmp_compat (jmp_buf env, int val)
 DEFINE_LONGJMP (longjmp_ifunc)
 compat_symbol (libpthread, longjmp_ifunc, longjmp, GLIBC_2_0);
 
-DEFINE_LONGJMP (siglongjmp_ifunc)
+strong_alias (longjmp_ifunc, siglongjmp_ifunc)
 compat_symbol (libpthread, siglongjmp_ifunc, siglongjmp, GLIBC_2_0);
 
 #endif
diff --git a/sysdeps/unix/sysv/linux/s390/pt-longjmp.c b/sysdeps/unix/sysv/linux/s390/pt-longjmp.c
index 10e825c..2abf112 100644
--- a/sysdeps/unix/sysv/linux/s390/pt-longjmp.c
+++ b/sysdeps/unix/sysv/linux/s390/pt-longjmp.c
@@ -26,8 +26,8 @@
 /* In glibc release 2.19 new versions of longjmp-functions were introduced,
    but were reverted before 2.20. Thus both versions are the same function.  */
 
-DEFINE_LONGJMP (__v2longjmp)
+strong_alias (longjmp_ifunc, __v2longjmp)
 compat_symbol (libpthread, __v2longjmp, longjmp, GLIBC_2_19);
-DEFINE_LONGJMP (__v2siglongjmp)
+strong_alias (siglongjmp_ifunc, __v2siglongjmp)
 compat_symbol (libpthread, __v2siglongjmp, siglongjmp, GLIBC_2_19);
 #endif /* SHLIB_COMPAT (libpthread, GLIBC_2_19, GLIBC_2_20))  */
-- 
2.3.0

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v3 2/9] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-08-24 14:05 [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Stefan Liebler
                   ` (5 preceding siblings ...)
  2016-08-24 14:05 ` [PATCH v3 3/9] s390: Refactor ifunc resolvers due to false debuginfo Stefan Liebler
@ 2016-08-24 14:05 ` Stefan Liebler
  2016-08-29 20:16   ` Paul E. Murphy
  2016-09-29 18:38   ` Adhemerval Zanella
  2016-08-24 17:02 ` [PATCH v3 7/9] Use libc_ifunc macro for system in libpthread Stefan Liebler
                   ` (3 subsequent siblings)
  10 siblings, 2 replies; 27+ messages in thread
From: Stefan Liebler @ 2016-08-24 14:05 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, fweimer, murphyp, schwab, joseph_myers

The current s390 ifunc resolver for vector optimized functions and the common
libc_ifunc macro in include/libc-symbols.h uses something like that to generate ifunc'ed functions:
extern void *__resolve___strlen(unsigned long int dl_hwcap) asm (strlen);
asm (".type strlen, %gnu_indirect_function");

This leads to false debug information:
objdump --dwarf=info libc.so:
...
<1><1e6424>: Abbrev Number: 43 (DW_TAG_subprogram)
    <1e6425>   DW_AT_external    : 1
    <1e6425>   DW_AT_name        : (indirect string, offset: 0x1146e): __resolve___strlen
    <1e6429>   DW_AT_decl_file   : 1
    <1e642a>   DW_AT_decl_line   : 23
    <1e642b>   DW_AT_linkage_name: (indirect string, offset: 0x1147a): strlen
    <1e642f>   DW_AT_prototyped  : 1
    <1e642f>   DW_AT_type        : <0x1e4ccd>
    <1e6433>   DW_AT_low_pc      : 0x998e0
    <1e643b>   DW_AT_high_pc     : 0x16
    <1e6443>   DW_AT_frame_base  : 1 byte block: 9c     (DW_OP_call_frame_cfa)
    <1e6445>   DW_AT_GNU_all_call_sites: 1
    <1e6445>   DW_AT_sibling     : <0x1e6459>
 <2><1e6449>: Abbrev Number: 44 (DW_TAG_formal_parameter)
    <1e644a>   DW_AT_name        : (indirect string, offset: 0x1845): dl_hwcap
    <1e644e>   DW_AT_decl_file   : 1
    <1e644f>   DW_AT_decl_line   : 23
    <1e6450>   DW_AT_type        : <0x1e4c8d>
    <1e6454>   DW_AT_location    : 0x122115 (location list)
...

The debuginfo for the ifunc-resolver function contains the DW_AT_linkage_name
field, which names the real function name "strlen". If you perform an inferior
function call to strlen in lldb, then it fails due to something like that:
"error: no matching function for call to 'strlen'
candidate function not viable: no known conversion from 'const char [6]'
to 'unsigned long' for 1st argument"

The unsigned long is the dl_hwcap argument of the resolver function.
The strlen function itself has no debufinfo.

The s390 ifunc resolver for memset & co uses something like that:
asm (".globl FUNC"
     ".type FUNC, @gnu_indirect_function"
     ".set FUNC, __resolve_FUNC");

This way the debuginfo for the ifunc-resolver function does not conain the
DW_AT_linkage_name field and the real function has no debuginfo, too.

Using this strategy for the vector optimized functions leads to some troubles
for functions like strnlen. Here we have __strnlen and a weak alias strnlen.
The __strnlen function is the ifunc function, which is realized with the asm-
statement above. The weak_alias-macro can't be used here due to undefined symbol:
gcc ../sysdeps/s390/multiarch/strnlen.c -c ...
In file included from <command-line>:0:0:
../sysdeps/s390/multiarch/strnlen.c:28:24: error: ‘strnlen’ aliased to undefined symbol ‘__strnlen’
 weak_alias (__strnlen, strnlen)
                        ^
./../include/libc-symbols.h:111:26: note: in definition of macro ‘_weak_alias’
   extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)));
                          ^
../sysdeps/s390/multiarch/strnlen.c:28:1: note: in expansion of macro ‘weak_alias’
 weak_alias (__strnlen, strnlen)
 ^
make[2]: *** [build/string/strnlen.o] Error 1

As the __strnlen function is defined with asm-statements the function name
__strnlen isn't known by gcc. But the weak alias can also be done with an
asm statement to resolve this issue:
__asm__ (".weak  strnlen\n\t"
         ".set   strnlen,__strnlen\n");

In order to use the weak_alias macro, gcc needs to know the ifunc function. The
minimum gcc to build glibc is currently 4.7, which supports attribute((ifunc)).
See https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html.
It is only supported if gcc is configured with --enable-gnu-indirect-function
or gcc supports it by default for at least intel and s390x architecture.
This patch uses the old behaviour if gcc support is not available.
Usage of attribute ifunc is something like that:
__typeof (FUNC) FUNC __attribute__ ((ifunc ("__resolve_FUNC")));

Then gcc produces the same .globl, .type, .set assembler instructions like above.
And the debuginfo does not contain the DW_AT_linkage_name field and there is no
debuginfo for the real function, too.

But in order to get it work, there is also some extra work to do.
Currently, the glibc internal symbol on s390x e.g. __GI___strnlen is not the
ifunc symbol, but the fallback __strnlen_c symbol. Thus I have to omit the
libc_hidden_def macro in strnlen.c (here is the ifunc function __strnlen)
because it is already handled in strnlen-c.c (here is __strnlen_c).

Due to libc_hidden_proto (__strnlen) in string.h, compiling fails:
gcc ../sysdeps/s390/multiarch/strnlen.c -c ...
In file included from <command-line>:0:0:
../sysdeps/s390/multiarch/strnlen.c:53:24: error: ‘strnlen’ aliased to undefined symbol ‘__strnlen’
 weak_alias (__strnlen, strnlen)
                        ^
./../include/libc-symbols.h:111:26: note: in definition of macro ‘_weak_alias’
   extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)));
                          ^
../sysdeps/s390/multiarch/strnlen.c:53:1: note: in expansion of macro ‘weak_alias’
 weak_alias (__strnlen, strnlen)
 ^
make[2]: *** [build/string/strnlen.os] Error 1

I have to redirect the prototypes for __strnlen in string.h and create a copy
of the prototype for using as ifunc function:
__typeof (__redirect___strnlen) __strnlen __attribute__ ((ifunc ("__resolve_strnlen")));
weak_alias (__strnlen, strnlen)

This way there is no trouble with the internal __GI_* symbols.
Glibc builds fine with this construct and the debuginfo is "correct".
For functions without a __GI_* symbol like memccpy this redirection is not needed.

This patch adjusts the common libc_ifunc and libm_ifunc macro to use gcc
attribute ifunc. Due to this change, the macro users where the __GI_* symbol
does not target the ifunc symbol have to be prepared with the redirection
construct.
Furthermore a configure check to test gcc support is added. If it is not supported,
the old behaviour is used.

This patch also prepares the libc_ifunc macro to be useable in s390-ifunc-macro.
The s390 ifunc-resolver-functions do have an hwcaps parameter and not all
resolvers need the same initialization code. The next patch in this series
changes the s390 ifunc macros to use this common one.

ChangeLog:

	* include/libc-symbols.h (__ifunc_resolver):
	New macro is used by __ifunc* macros.
	(__ifunc): New macro uses gcc attribute ifunc or inline assembly
	depending on HAVE_GCC_IFUNC.
	(libc_ifunc, libm_ifunc): Use __ifunc as base macro.
	(libc_ifunc_redirected, libc_ifunc_hidden, libm_ifunc_init): New macro.
	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c:
	Redirect ifunced function in header for using as type for ifunc function.
	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/multiarch/memset.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c: Likewise.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c: Likewise.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c: Likewise.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c: Likewise.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c: Likewise.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c: Likewise.
	* sysdeps/powerpc/powerpc64/multiarch/memcmp.c: Likewise.
	* sysdeps/powerpc/powerpc64/multiarch/mempcpy.c: Likewise.
	* sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c: Likewise.
	* sysdeps/powerpc/powerpc64/multiarch/stpncpy.c: Likewise.
	* sysdeps/powerpc/powerpc64/multiarch/strcat.c: Likewise.
	* sysdeps/powerpc/powerpc64/multiarch/strchr.c: Likewise.
	* sysdeps/powerpc/powerpc64/multiarch/strcmp.c: Likewise.
	* sysdeps/powerpc/powerpc64/multiarch/strcpy.c: Likewise.
	* sysdeps/powerpc/powerpc64/multiarch/strncmp.c: Likewise.
	* sysdeps/powerpc/powerpc64/multiarch/strncpy.c: Likewise.
	* sysdeps/powerpc/powerpc64/multiarch/strnlen.c: Likewise.
	* sysdeps/powerpc/powerpc64/multiarch/strrchr.c: Likewise.
	* sysdeps/powerpc/powerpc64/multiarch/strstr.c: Likewise.
	* sysdeps/powerpc/powerpc64/multiarch/wcschr.c: Likewise.
	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c:
	Add libc_hidden_def() and use libc_ifunc_hidden() macro
	instead of libc_ifunc() macro.
	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c: Likewise.
	* sysdeps/powerpc/powerpc64/multiarch/stpcpy.c: Likewise.
---
 include/libc-symbols.h                             | 69 +++++++++++++++++-----
 .../powerpc32/power4/fpu/multiarch/s_finite.c      | 16 +++--
 .../powerpc32/power4/fpu/multiarch/s_finitef.c     | 10 ++--
 .../powerpc32/power4/fpu/multiarch/s_isinf.c       | 16 +++--
 .../powerpc32/power4/fpu/multiarch/s_isinff.c      | 10 ++--
 .../powerpc32/power4/fpu/multiarch/s_isnan.c       | 24 +++++---
 .../powerpc32/power4/fpu/multiarch/s_isnanf.c      | 17 +++---
 .../powerpc/powerpc32/power4/multiarch/memcmp.c    | 10 ++--
 .../powerpc/powerpc32/power4/multiarch/memcpy.c    | 23 ++++----
 .../powerpc/powerpc32/power4/multiarch/memmove.c   | 10 ++--
 .../powerpc/powerpc32/power4/multiarch/mempcpy.c   | 15 +++--
 .../powerpc/powerpc32/power4/multiarch/memset.c    | 14 +++--
 .../powerpc/powerpc32/power4/multiarch/rawmemchr.c | 11 ++--
 .../powerpc/powerpc32/power4/multiarch/strchr.c    | 12 ++--
 .../powerpc/powerpc32/power4/multiarch/strlen.c    | 10 ++--
 .../powerpc/powerpc32/power4/multiarch/strncmp.c   | 12 ++--
 .../powerpc/powerpc32/power4/multiarch/strnlen.c   | 13 ++--
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c | 20 ++++---
 .../powerpc/powerpc64/fpu/multiarch/s_finitef.c    | 14 +++--
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c  | 20 ++++---
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c | 14 +++--
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c  | 32 ++++++----
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c | 25 ++++----
 sysdeps/powerpc/powerpc64/multiarch/memcmp.c       | 14 +++--
 sysdeps/powerpc/powerpc64/multiarch/mempcpy.c      | 15 +++--
 sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c    | 10 ++--
 sysdeps/powerpc/powerpc64/multiarch/stpcpy.c       | 13 ++--
 sysdeps/powerpc/powerpc64/multiarch/stpncpy.c      | 17 +++---
 sysdeps/powerpc/powerpc64/multiarch/strcat.c       | 14 +++--
 sysdeps/powerpc/powerpc64/multiarch/strchr.c       | 12 ++--
 sysdeps/powerpc/powerpc64/multiarch/strcmp.c       | 16 +++--
 sysdeps/powerpc/powerpc64/multiarch/strcpy.c       | 14 +++--
 sysdeps/powerpc/powerpc64/multiarch/strncmp.c      | 20 ++++---
 sysdeps/powerpc/powerpc64/multiarch/strncpy.c      | 16 +++--
 sysdeps/powerpc/powerpc64/multiarch/strnlen.c      | 14 +++--
 sysdeps/powerpc/powerpc64/multiarch/strrchr.c      | 10 ++--
 sysdeps/powerpc/powerpc64/multiarch/strstr.c       | 10 ++--
 sysdeps/powerpc/powerpc64/multiarch/wcschr.c       | 17 +++---
 38 files changed, 391 insertions(+), 238 deletions(-)

diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index c2b499a..44e5253 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -722,27 +722,64 @@ for linking")
 # define compat_data_section .section ".data.compat", "aw";
 #endif
 
-/* Marker used for indirection function symbols.  */
-#define libc_ifunc(name, expr)						\
-  extern void *name##_ifunc (void) __asm__ (#name);			\
-  void *name##_ifunc (void)						\
+/* Helper / base  macros for indirect function symbols.  */
+#define __ifunc_resolver(type_name, name, expr, arg, init, classifier)	\
+  classifier void *name##_ifunc (arg)					\
   {									\
-    INIT_ARCH ();							\
-    __typeof (name) *res = expr;					\
+    init ();								\
+    __typeof (type_name) *res = expr;					\
     return res;								\
-  }									\
-  __asm__ (".type " #name ", %gnu_indirect_function");
+  }
+
+#ifdef HAVE_GCC_IFUNC
+# define __ifunc(type_name, name, expr, arg, init)			\
+  extern __typeof (type_name) name __attribute__			\
+			      ((ifunc (#name "_ifunc")));		\
+  __ifunc_resolver (type_name, name, expr, arg, init, static)
+
+# define __ifunc_hidden(type_name, name, expr, arg, init)	\
+  __ifunc (type_name, name, expr, arg, init)
+#else
+/* Gcc does not support __attribute__ ((ifunc (...))).  Use the old behaviour
+   as fallback.  But keep in mind that the debug information for the ifunc
+   resolver functions is not correct.  It contains the ifunc'ed function as
+   DW_AT_linkage_name.  E.g. lldb uses this field and an inferior function
+   call of the ifunc'ed function will fail due to "no matching function for call
+   to ..." because the ifunc'ed function and the resolver function have
+   different signatures.  (Gcc support is disabled at least on a ppc64le
+   Ubuntu 14.04 system.)  */
+
+# define __ifunc(type_name, name, expr, arg, init)			\
+  extern __typeof (type_name) name;					\
+  void *name##_ifunc (arg) __asm__ (#name);				\
+  __ifunc_resolver (type_name, name, expr, arg, init,)			\
+ __asm__ (".type " #name ", %gnu_indirect_function");
+
+# define __ifunc_hidden(type_name, name, expr, arg, init)		\
+  extern __typeof (type_name) __libc_##name;				\
+  __ifunc (type_name, __libc_##name, expr, arg, init)			\
+  strong_alias (__libc_##name, name);
+#endif /* !HAVE_GCC_IFUNC  */
+
+/* Use libc_ifunc if your ifunc'ed function has no internal symbol.  */
+#define libc_ifunc(name, expr) __ifunc (name, name, expr, void, INIT_ARCH)
+
+/* Use libc_ifunc_redirected if your ifunc'ed function has an internal symbol
+   which should be a dedicated fallback function instead of ifunc'ed.
+   You have to redirect the function in the header file and use it as
+   redirected_name.  */
+#define libc_ifunc_redirected(redirected_name, name, expr)	\
+  __ifunc (redirected_name, name, expr, void, INIT_ARCH)
+
+/* Use libc_ifunc_hidden if your ifunc'ed function has an internal symbol
+   which should be the ifunc'ed function'.  */
+#define libc_ifunc_hidden(redirected_name, name, expr)			\
+  __ifunc_hidden (redirected_name, name, expr, void, INIT_ARCH)
 
 /* The body of the function is supposed to use __get_cpu_features
    which will, if necessary, initialize the data first.  */
-#define libm_ifunc(name, expr)						\
-  extern void *name##_ifunc (void) __asm__ (#name);			\
-  void *name##_ifunc (void)						\
-  {									\
-    __typeof (name) *res = expr;					\
-    return res;								\
-  }									\
-  __asm__ (".type " #name ", %gnu_indirect_function");
+#define libm_ifunc_init()
+#define libm_ifunc(name, expr) __ifunc (name, name, expr, void, libm_ifunc_init)
 
 #ifdef HAVE_ASM_SET_DIRECTIVE
 # define libc_ifunc_hidden_def1(local, name)				\
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c
index c860a1b..0c0d128 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c
@@ -16,6 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __finite __redirect___finite
+#define __finitef __redirect___finitef
+#define __finitel __redirect___finitel
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -23,11 +26,14 @@
 
 extern __typeof (__finite) __finite_ppc32 attribute_hidden;
 extern __typeof (__finite) __finite_power7 attribute_hidden;
-
-libc_ifunc (__finite,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __finite_power7
-            : __finite_ppc32);
+#undef __finite
+#undef __finitef
+#undef __finitel
+
+libc_ifunc_redirected (__redirect___finite,  __finite,
+		       (hwcap & PPC_FEATURE_ARCH_2_06)
+		       ? __finite_power7
+		       : __finite_ppc32);
 
 weak_alias (__finite, finite)
 
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c
index 831c94f..683477a 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c
@@ -16,6 +16,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __finitef __redirect___finitef
 #include <math.h>
 #include <shlib-compat.h>
 #include "init-arch.h"
@@ -23,10 +24,11 @@
 extern __typeof (__finitef) __finitef_ppc32 attribute_hidden;
 /* The power7 finite(double) works for float.  */
 extern __typeof (__finitef) __finite_power7 attribute_hidden;
+#undef __finitef
 
-libc_ifunc (__finitef,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __finite_power7
-            : __finitef_ppc32);
+libc_ifunc_redirected  (__redirect___finitef, __finitef,
+			(hwcap & PPC_FEATURE_ARCH_2_06)
+			? __finite_power7
+			: __finitef_ppc32);
 
 weak_alias (__finitef, finitef)
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c
index 506c111..fe6c912 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c
@@ -16,6 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __isinf __redirect___isinf
+#define __isinff __redirect___isinff
+#define __isinfl __redirect___isinfl
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -23,11 +26,14 @@
 
 extern __typeof (__isinf) __isinf_ppc32 attribute_hidden;
 extern __typeof (__isinf) __isinf_power7 attribute_hidden;
-
-libc_ifunc (__isinf,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __isinf_power7
-            : __isinf_ppc32);
+#undef __isinf
+#undef __isinff
+#undef __isinfl
+
+libc_ifunc_redirected (__redirect___isinf,  __isinf,
+		       (hwcap & PPC_FEATURE_ARCH_2_06)
+		       ? __isinf_power7
+		       : __isinf_ppc32);
 
 weak_alias (__isinf, isinf)
 
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c
index 2ab83ee..1706092 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c
@@ -16,6 +16,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __isinff __redirect___isinff
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -24,10 +25,11 @@
 extern __typeof (__isinff) __isinff_ppc32 attribute_hidden;
 /* The power7 isinf(double) works for float.  */
 extern __typeof (__isinff) __isinf_power7 attribute_hidden;
+#undef __isinff
 
-libc_ifunc (__isinff,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __isinf_power7
-            : __isinff_ppc32);
+libc_ifunc_redirected (__redirect___isinff,  __isinff,
+		       (hwcap & PPC_FEATURE_ARCH_2_06)
+		       ? __isinf_power7
+		       : __isinff_ppc32);
 
 weak_alias (__isinff, isinff)
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c
index 8f848d7..3655b81 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c
@@ -16,6 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __isnan __redirect___isnan
+#define __isnanf __redirect___isnanf
+#define __isnanl __redirect___isnanl
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -25,15 +28,18 @@ extern __typeof (__isnan) __isnan_ppc32 attribute_hidden;
 extern __typeof (__isnan) __isnan_power5 attribute_hidden;
 extern __typeof (__isnan) __isnan_power6 attribute_hidden;
 extern __typeof (__isnan) __isnan_power7 attribute_hidden;
-
-libc_ifunc (__isnan,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __isnan_power7 :
-	      (hwcap & PPC_FEATURE_ARCH_2_05)
-	      ? __isnan_power6 :
-		(hwcap & PPC_FEATURE_POWER5)
-		? __isnan_power5
-            : __isnan_ppc32);
+#undef __isnan
+#undef __isnanf
+#undef __isnanl
+
+libc_ifunc_redirected (__redirect___isnan, __isnan,
+		       (hwcap & PPC_FEATURE_ARCH_2_06)
+		       ? __isnan_power7
+		       : (hwcap & PPC_FEATURE_ARCH_2_05)
+			 ? __isnan_power6
+			 : (hwcap & PPC_FEATURE_POWER5)
+			   ? __isnan_power5
+			   : __isnan_ppc32);
 
 weak_alias (__isnan, isnan)
 
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
index c43c0f3..e1d6707 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
@@ -26,13 +26,14 @@ extern __typeof (__isnanf) __isnanf_power5 attribute_hidden;
 extern __typeof (__isnanf) __isnanf_power6 attribute_hidden;
 extern __typeof (__isnanf) __isnan_power7 attribute_hidden;
 
-libc_ifunc (__isnanf,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __isnan_power7 :
-	      (hwcap & PPC_FEATURE_ARCH_2_05)
-	      ? __isnanf_power6 :
-		(hwcap & PPC_FEATURE_POWER5)
-		? __isnanf_power5
-            : __isnan_ppc32);
+libc_ifunc_hidden (__isnanf, __isnanf,
+		   (hwcap & PPC_FEATURE_ARCH_2_06)
+		   ? __isnan_power7
+		   : (hwcap & PPC_FEATURE_ARCH_2_05)
+		     ? __isnanf_power6
+		     : (hwcap & PPC_FEATURE_POWER5)
+		       ? __isnanf_power5
+		       : __isnan_ppc32);
 
+hidden_def (__isnanf)
 weak_alias (__isnanf, isnanf)
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c
index c08519c..49d424f 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c
@@ -18,17 +18,19 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if IS_IN (libc)
+# define memcmp __redirect_memcmp
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (memcmp) __memcmp_ppc attribute_hidden;
 extern __typeof (memcmp) __memcmp_power7 attribute_hidden;
+# undef memcmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memcmp,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __memcmp_power7
-            : __memcmp_ppc);
+libc_ifunc_redirected (__redirect_memcmp, memcmp,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __memcmp_power7
+		       : __memcmp_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c
index f379e47..1a5da21 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c
@@ -20,6 +20,8 @@
    DSO.  In static binaries we need memcpy before the initialization
    happened.  */
 #if defined SHARED && IS_IN (libc)
+# undef memcpy
+# define memcpy __redirect_memcpy
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -29,17 +31,18 @@ extern __typeof (memcpy) __memcpy_cell attribute_hidden;
 extern __typeof (memcpy) __memcpy_power6 attribute_hidden;
 extern __typeof (memcpy) __memcpy_a2 attribute_hidden;
 extern __typeof (memcpy) __memcpy_power7 attribute_hidden;
+# undef memcpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memcpy,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __memcpy_power7 :
-	      (hwcap & PPC_FEATURE_ARCH_2_06)
-	      ? __memcpy_a2 :
-		(hwcap & PPC_FEATURE_ARCH_2_05)
-		? __memcpy_power6 :
-		  (hwcap & PPC_FEATURE_CELL_BE)
-		  ? __memcpy_cell
-            : __memcpy_ppc);
+libc_ifunc_redirected (__redirect_memcpy, memcpy,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __memcpy_power7
+		       : (hwcap & PPC_FEATURE_ARCH_2_06)
+			 ? __memcpy_a2
+			 : (hwcap & PPC_FEATURE_ARCH_2_05)
+			   ? __memcpy_power6
+			   : (hwcap & PPC_FEATURE_CELL_BE)
+			     ? __memcpy_cell
+			     : __memcpy_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
index 4173184..1dfb5be 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
@@ -19,16 +19,18 @@
 #if defined SHARED && IS_IN (libc)
 /* Redefine memmove so that the compiler won't complain about the type
    mismatch with the IFUNC selector in strong_alias, below.  */
+# define memmove __redirect_memmove
 # include <string.h>
 # include "init-arch.h"
 
 extern __typeof (memmove) __memmove_ppc attribute_hidden;
 extern __typeof (memmove) __memmove_power7 attribute_hidden;
+# undef memmove
 
-libc_ifunc (memmove,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __memmove_power7
-            : __memmove_ppc);
+libc_ifunc_redirected (__redirect_memmove, memmove,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __memmove_power7
+		       : __memmove_ppc);
 #else
 # include <string/memmove.c>
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c b/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c
index 3c77b5f..3c7c644 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c
@@ -17,23 +17,28 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define mempcpy __redirect_mempcpy
+# define __mempcpy __redirect___mempcpy
 # define NO_MEMPCPY_STPCPY_REDIRECT
+/* Omit the mempcpy inline definitions because it would redefine mempcpy.  */
+# define _HAVE_STRING_ARCH_mempcpy 1
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (__mempcpy) __mempcpy_ppc attribute_hidden;
 extern __typeof (__mempcpy) __mempcpy_power7 attribute_hidden;
+# undef mempcpy
+# undef __mempcpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__mempcpy,
-	    (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __mempcpy_power7
-            : __mempcpy_ppc);
+libc_ifunc_redirected (__redirect___mempcpy,  __mempcpy,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __mempcpy_power7
+		       : __mempcpy_ppc);
 
 weak_alias (__mempcpy, mempcpy)
-libc_hidden_def (mempcpy)
 #else
 # include <string/mempcpy.c>
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memset.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memset.c
index 1d7fc7f..a5c0142 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memset.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memset.c
@@ -18,6 +18,7 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if defined SHARED && IS_IN (libc)
+# define memset __redirect_memset
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -25,13 +26,14 @@
 extern __typeof (memset) __memset_ppc attribute_hidden;
 extern __typeof (memset) __memset_power6 attribute_hidden;
 extern __typeof (memset) __memset_power7 attribute_hidden;
+# undef memset
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memset,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __memset_power7 :
-	      (hwcap & PPC_FEATURE_ARCH_2_05)
-		? __memset_power6
-            : __memset_ppc);
+libc_ifunc_redirected (__redirect_memset, memset,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __memset_power7
+		       : (hwcap & PPC_FEATURE_ARCH_2_05)
+			 ? __memset_power6
+			 : __memset_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c b/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
index f06030e..d72b5df 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
@@ -17,20 +17,21 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define __rawmemchr __redirect___rawmemchr
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (__rawmemchr) __rawmemchr_ppc attribute_hidden;
 extern __typeof (__rawmemchr) __rawmemchr_power7 attribute_hidden;
+# undef __rawmemchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__rawmemchr,
-	    (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __rawmemchr_power7
-            : __rawmemchr_ppc);
-
+libc_ifunc_redirected (__redirect___rawmemchr, __rawmemchr,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __rawmemchr_power7
+		       : __rawmemchr_ppc);
 weak_alias (__rawmemchr, rawmemchr)
 #else
 #include <string/rawmemchr.c>
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
index 2cfde63..c23384f 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
@@ -18,18 +18,22 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if defined SHARED && IS_IN (libc)
+# define strchr __redirect_strchr
+/* Omit the strchr inline definitions because it would redefine strchr.  */
+# define __NO_STRING_INLINES
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (strchr) __strchr_ppc attribute_hidden;
 extern __typeof (strchr) __strchr_power7 attribute_hidden;
+# undef strchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strchr,
-	    (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strchr_power7
-            : __strchr_ppc);
+libc_ifunc_redirected (__redirect_strchr,  strchr,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strchr_power7
+		       : __strchr_ppc);
 weak_alias (strchr, index)
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
index af5921a..b676b26 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
@@ -17,15 +17,17 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined SHARED && IS_IN (libc)
+# define strlen __redirect_strlen
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (strlen) __strlen_ppc attribute_hidden;
 extern __typeof (strlen) __strlen_power7 attribute_hidden;
+# undef strlen
 
-libc_ifunc (strlen,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strlen_power7
-            : __strlen_ppc);
+libc_ifunc_redirected (__redirect_strlen, strlen,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strlen_power7
+		       : __strlen_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c
index 7cc7628..c384b4c 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c
@@ -18,6 +18,9 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if defined SHARED && IS_IN (libc)
+# define strncmp __redirect_strncmp
+/* Omit the strncmp inline definitions because it would redefine strncmp.  */
+# define __NO_STRING_INLINES
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -25,11 +28,12 @@
 extern __typeof (strncmp) __strncmp_ppc attribute_hidden;
 extern __typeof (strncmp) __strncmp_power4 attribute_hidden;
 extern __typeof (strncmp) __strncmp_power7 attribute_hidden;
+# undef strncmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strncmp,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strncmp_power7
-            : __strncmp_ppc);
+libc_ifunc_redirected (__redirect_strncmp, strncmp,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strncmp_power7
+		       : __strncmp_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
index 8f1e7c9..c3681be 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
@@ -17,17 +17,20 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define strnlen __redirect_strnlen
+# define __strnlen __redirect___strnlen
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (__strnlen) __strnlen_ppc attribute_hidden;
 extern __typeof (__strnlen) __strnlen_power7 attribute_hidden;
+# undef strnlen
+# undef __strnlen
 
-libc_ifunc (__strnlen,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strnlen_power7
-            : __strnlen_ppc);
+libc_ifunc_redirected (__redirect___strnlen, __strnlen,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strnlen_power7
+		       : __strnlen_ppc);
 weak_alias (__strnlen, strnlen)
-libc_hidden_def (strnlen)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
index 067edc2..c7d67f1 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
@@ -16,6 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __finite __redirect___finite
+#define __finitef __redirect___finitef
+#define __finitel __redirect___finitel
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -24,13 +27,16 @@
 extern __typeof (__finite) __finite_ppc64 attribute_hidden;
 extern __typeof (__finite) __finite_power7 attribute_hidden;
 extern __typeof (__finite) __finite_power8 attribute_hidden;
-
-libc_ifunc (__finite,
-	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-	    ? __finite_power8 :
-	      (hwcap & PPC_FEATURE_ARCH_2_06)
-	      ? __finite_power7
-            : __finite_ppc64);
+#undef __finite
+#undef __finitef
+#undef __finitel
+
+libc_ifunc_redirected (__redirect___finite, __finite,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __finite_power8
+		       : (hwcap & PPC_FEATURE_ARCH_2_06)
+			 ? __finite_power7
+			 : __finite_ppc64);
 
 weak_alias (__finite, finite)
 
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
index e0b4686..c9ecd0d 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
@@ -16,6 +16,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __finitef __redirect___finitef
 #include <math.h>
 #include <shlib-compat.h>
 #include "init-arch.h"
@@ -24,12 +25,13 @@ extern __typeof (__finitef) __finitef_ppc64 attribute_hidden;
 /* The double-precision version also works for single-precision.  */
 extern __typeof (__finitef) __finite_power7 attribute_hidden;
 extern __typeof (__finitef) __finite_power8 attribute_hidden;
+#undef __finitef
 
-libc_ifunc (__finitef,
-	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-	    ? __finite_power8 :
-	      (hwcap & PPC_FEATURE_ARCH_2_06)
-	      ? __finite_power7
-            : __finitef_ppc64);
+libc_ifunc_redirected (__redirect___finitef, __finitef,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __finite_power8
+		       : (hwcap & PPC_FEATURE_ARCH_2_06)
+			 ? __finite_power7
+			 : __finitef_ppc64);
 
 weak_alias (__finitef, finitef)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
index 07e159d..a13ec27 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
@@ -16,6 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __isinf __redirect___isinf
+#define __isinff __redirect___isinff
+#define __isinfl __redirect___isinfl
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -24,13 +27,16 @@
 extern __typeof (__isinf) __isinf_ppc64 attribute_hidden;
 extern __typeof (__isinf) __isinf_power7 attribute_hidden;
 extern __typeof (__isinf) __isinf_power8 attribute_hidden;
-
-libc_ifunc (__isinf,
-	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-	    ? __isinf_power8 :
-	      (hwcap & PPC_FEATURE_ARCH_2_06)
-	      ? __isinf_power7
-            : __isinf_ppc64);
+#undef __isinf
+#undef __isinff
+#undef __isinfl
+
+libc_ifunc_redirected (__redirect___isinf, __isinf,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __isinf_power8
+		       : (hwcap & PPC_FEATURE_ARCH_2_06)
+			 ? __isinf_power7
+			 : __isinf_ppc64);
 
 weak_alias (__isinf, isinf)
 
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
index 2cb161b..cafc118 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
@@ -16,6 +16,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __isinff __redirect___isinff
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -25,12 +26,13 @@ extern __typeof (__isinff) __isinff_ppc64 attribute_hidden;
 /* The double-precision version also works for single-precision.  */
 extern __typeof (__isinff) __isinf_power7 attribute_hidden;
 extern __typeof (__isinff) __isinf_power8 attribute_hidden;
+#undef __isinff
 
-libc_ifunc (__isinff,
-	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-	    ? __isinf_power8 :
-	      (hwcap & PPC_FEATURE_ARCH_2_06)
-	      ? __isinf_power7
-            : __isinff_ppc64);
+libc_ifunc_redirected (__redirect___isinff, __isinff,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __isinf_power8
+		       : (hwcap & PPC_FEATURE_ARCH_2_06)
+			 ? __isinf_power7
+			 : __isinff_ppc64);
 
 weak_alias (__isinff, isinff)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
index a614f25..fce3c9d 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
@@ -16,6 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __isnan __redirect___isnan
+#define __isnanf __redirect___isnanf
+#define __isnanl __redirect___isnanl
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -27,19 +30,22 @@ extern __typeof (__isnan) __isnan_power6 attribute_hidden;
 extern __typeof (__isnan) __isnan_power6x attribute_hidden;
 extern __typeof (__isnan) __isnan_power7 attribute_hidden;
 extern __typeof (__isnan) __isnan_power8 attribute_hidden;
-
-libc_ifunc (__isnan,
-	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-	    ? __isnan_power8 :
-	      (hwcap & PPC_FEATURE_ARCH_2_06)
-	      ? __isnan_power7 :
-		(hwcap & PPC_FEATURE_POWER6_EXT)
-		? __isnan_power6x :
-		  (hwcap & PPC_FEATURE_ARCH_2_05)
-		    ? __isnan_power6 :
-		    (hwcap & PPC_FEATURE_POWER5)
-		      ? __isnan_power5
-            : __isnan_ppc64);
+#undef __isnan
+#undef __isnanf
+#undef __isnanl
+
+libc_ifunc_redirected (__redirect___isnan, __isnan,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __isnan_power8
+		       : (hwcap & PPC_FEATURE_ARCH_2_06)
+			 ? __isnan_power7
+			 : (hwcap & PPC_FEATURE_POWER6_EXT)
+			   ? __isnan_power6x
+			   : (hwcap & PPC_FEATURE_ARCH_2_05)
+			     ? __isnan_power6
+			     : (hwcap & PPC_FEATURE_POWER5)
+			       ? __isnan_power5
+			       : __isnan_ppc64);
 
 weak_alias (__isnan, isnan)
 
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
index acbc131..903ea86 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
@@ -27,17 +27,18 @@ extern __typeof (__isnanf) __isnan_power6x attribute_hidden;
 extern __typeof (__isnanf) __isnan_power7 attribute_hidden;
 extern __typeof (__isnanf) __isnan_power8 attribute_hidden;
 
-libc_ifunc (__isnanf,
-	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-	    ? __isnan_power8 :
-	      (hwcap & PPC_FEATURE_ARCH_2_06)
-	      ? __isnan_power7 :
-		(hwcap & PPC_FEATURE_POWER6_EXT)
-		  ? __isnan_power6x :
-		  (hwcap & PPC_FEATURE_ARCH_2_05)
-		    ? __isnan_power6 :
-		    (hwcap & PPC_FEATURE_POWER5)
-		      ? __isnan_power5
-            : __isnan_ppc64);
+libc_ifunc_hidden (__isnanf, __isnanf,
+		   (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		   ? __isnan_power8
+		   : (hwcap & PPC_FEATURE_ARCH_2_06)
+		     ? __isnan_power7
+		     : (hwcap & PPC_FEATURE_POWER6_EXT)
+		       ? __isnan_power6x
+		       : (hwcap & PPC_FEATURE_ARCH_2_05)
+			 ? __isnan_power6
+			 : (hwcap & PPC_FEATURE_POWER5)
+			   ? __isnan_power5
+			   : __isnan_ppc64);
 
+hidden_def (__isnanf)
 weak_alias (__isnanf, isnanf)
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp.c b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
index e8cf6ae..a45ebd7 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
@@ -18,6 +18,7 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if IS_IN (libc)
+# define memcmp __redirect_memcmp
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -25,15 +26,16 @@
 extern __typeof (memcmp) __memcmp_ppc attribute_hidden;
 extern __typeof (memcmp) __memcmp_power4 attribute_hidden;
 extern __typeof (memcmp) __memcmp_power7 attribute_hidden;
+# undef memcmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memcmp,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __memcmp_power7 :
-	      (hwcap & PPC_FEATURE_POWER4)
-		? __memcmp_power4
-            : __memcmp_ppc);
+libc_ifunc_redirected (__redirect_memcmp, memcmp,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __memcmp_power7
+		       : (hwcap & PPC_FEATURE_POWER4)
+			 ? __memcmp_power4
+			 : __memcmp_ppc);
 #else
 #include <string/memcmp.c>
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
index 3c77b5f..36ec954 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
@@ -17,23 +17,28 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define mempcpy __redirect_mempcpy
+# define __mempcpy __redirect___mempcpy
 # define NO_MEMPCPY_STPCPY_REDIRECT
+/* Omit the mempcpy inline definitions because it would redefine mempcpy.  */
+# define _HAVE_STRING_ARCH_mempcpy 1
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (__mempcpy) __mempcpy_ppc attribute_hidden;
 extern __typeof (__mempcpy) __mempcpy_power7 attribute_hidden;
+# undef mempcpy
+# undef __mempcpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__mempcpy,
-	    (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __mempcpy_power7
-            : __mempcpy_ppc);
+libc_ifunc_redirected (__redirect___mempcpy, __mempcpy,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __mempcpy_power7
+		       : __mempcpy_ppc);
 
 weak_alias (__mempcpy, mempcpy)
-libc_hidden_def (mempcpy)
 #else
 # include <string/mempcpy.c>
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
index f06030e..b53b148 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
@@ -17,19 +17,21 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define __rawmemchr __redirect___rawmemchr
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (__rawmemchr) __rawmemchr_ppc attribute_hidden;
 extern __typeof (__rawmemchr) __rawmemchr_power7 attribute_hidden;
+# undef __rawmemchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__rawmemchr,
-	    (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __rawmemchr_power7
-            : __rawmemchr_ppc);
+libc_ifunc_redirected (__redirect___rawmemchr, __rawmemchr,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __rawmemchr_power7
+		       : __rawmemchr_ppc);
 
 weak_alias (__rawmemchr, rawmemchr)
 #else
diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
index bbc1691..e378138 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
@@ -26,14 +26,15 @@ extern __typeof (__stpcpy) __stpcpy_ppc attribute_hidden;
 extern __typeof (__stpcpy) __stpcpy_power7 attribute_hidden;
 extern __typeof (__stpcpy) __stpcpy_power8 attribute_hidden;
 
-libc_ifunc (__stpcpy,
-            (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-            ? __stpcpy_power8 :
-              (hwcap & PPC_FEATURE_HAS_VSX)
-              ? __stpcpy_power7
-            : __stpcpy_ppc);
+libc_ifunc_hidden (__stpcpy, __stpcpy,
+		   (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		   ? __stpcpy_power8
+		   : (hwcap & PPC_FEATURE_HAS_VSX)
+		     ? __stpcpy_power7
+		     : __stpcpy_ppc);
 
 weak_alias (__stpcpy, stpcpy)
+libc_hidden_def (__stpcpy)
 libc_hidden_def (stpcpy)
 #else
 # include <string/stpcpy.c>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c b/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c
index b1484b1..fb3b529 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c
@@ -17,6 +17,8 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define stpncpy __redirect_stpncpy
+# define __stpncpy __redirect___stpncpy
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -24,13 +26,14 @@
 extern __typeof (__stpncpy) __stpncpy_ppc attribute_hidden;
 extern __typeof (__stpncpy) __stpncpy_power7 attribute_hidden;
 extern __typeof (__stpncpy) __stpncpy_power8 attribute_hidden;
+# undef stpncpy
+# undef __stpncpy
 
-libc_ifunc (__stpncpy,
-            (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-            ? __stpncpy_power8 :
-              (hwcap & PPC_FEATURE_HAS_VSX)
-              ? __stpncpy_power7
-            : __stpncpy_ppc);
-
+libc_ifunc_redirected (__redirect___stpncpy, __stpncpy,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __stpncpy_power8
+		       : (hwcap & PPC_FEATURE_HAS_VSX)
+			 ? __stpncpy_power7
+			 : __stpncpy_ppc);
 weak_alias (__stpncpy, stpncpy)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcat.c b/sysdeps/powerpc/powerpc64/multiarch/strcat.c
index a2894ae..5080ed1 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strcat.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcat.c
@@ -17,6 +17,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define strcat __redirect_strcat
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -24,11 +25,12 @@
 extern __typeof (strcat) __strcat_ppc attribute_hidden;
 extern __typeof (strcat) __strcat_power7 attribute_hidden;
 extern __typeof (strcat) __strcat_power8 attribute_hidden;
+# undef strcat
 
-libc_ifunc (strcat,
-            (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-            ? __strcat_power8 :
-              (hwcap & PPC_FEATURE_HAS_VSX)
-              ? __strcat_power7
-            : __strcat_ppc);
+libc_ifunc_redirected (__redirect_strcat, strcat,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __strcat_power8
+		       : (hwcap & PPC_FEATURE_HAS_VSX)
+			 ? __strcat_power7
+			 : __strcat_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchr.c b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
index 2cfde63..e24d6b3 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strchr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
@@ -18,18 +18,22 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if defined SHARED && IS_IN (libc)
+# define strchr __redirect_strchr
+/* Omit the strchr inline definitions because it would redefine strchr.  */
+# define __NO_STRING_INLINES
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (strchr) __strchr_ppc attribute_hidden;
 extern __typeof (strchr) __strchr_power7 attribute_hidden;
+# undef strchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strchr,
-	    (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strchr_power7
-            : __strchr_ppc);
+libc_ifunc_redirected (__redirect_strchr, strchr,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strchr_power7
+		       : __strchr_ppc);
 weak_alias (strchr, index)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
index aee888a..06f89cb 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
@@ -17,6 +17,9 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined SHARED && IS_IN (libc)
+# define strcmp __redirect_strcmp
+/* Omit the strcmp inline definitions because it would redefine strcmp.  */
+# define __NO_STRING_INLINES
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -24,11 +27,12 @@
 extern __typeof (strcmp) __strcmp_ppc attribute_hidden;
 extern __typeof (strcmp) __strcmp_power7 attribute_hidden;
 extern __typeof (strcmp) __strcmp_power8 attribute_hidden;
+# undef strcmp
 
-libc_ifunc (strcmp,
-            (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-              ? __strcmp_power8 :
-              (hwcap & PPC_FEATURE_HAS_VSX)
-              ? __strcmp_power7
-            : __strcmp_ppc);
+libc_ifunc_redirected (__redirect_strcmp, strcmp,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __strcmp_power8
+		       : (hwcap & PPC_FEATURE_HAS_VSX)
+			 ? __strcmp_power7
+			 : __strcmp_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcpy.c b/sysdeps/powerpc/powerpc64/multiarch/strcpy.c
index d2c3858..8708fc7 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strcpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcpy.c
@@ -17,6 +17,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined SHARED && IS_IN (libc)
+# define strcpy __redirect_strcpy
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -24,11 +25,12 @@
 extern __typeof (strcpy) __strcpy_ppc attribute_hidden;
 extern __typeof (strcpy) __strcpy_power7 attribute_hidden;
 extern __typeof (strcpy) __strcpy_power8 attribute_hidden;
+#undef strcpy
 
-libc_ifunc (strcpy,
-            (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-            ? __strcpy_power8 :
-              (hwcap & PPC_FEATURE_HAS_VSX)
-              ? __strcpy_power7
-            : __strcpy_ppc);
+libc_ifunc_redirected (__redirect_strcpy, strcpy,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __strcpy_power8
+		       : (hwcap & PPC_FEATURE_HAS_VSX)
+			 ? __strcpy_power7
+			 : __strcpy_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
index 1eb6e51..63a1aa0 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
@@ -18,6 +18,9 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if defined SHARED && IS_IN (libc)
+# define strncmp __redirect_strncmp
+/* Omit the strncmp inline definitions because it would redefine strncmp.  */
+# define __NO_STRING_INLINES
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -26,15 +29,16 @@ extern __typeof (strncmp) __strncmp_ppc attribute_hidden;
 extern __typeof (strncmp) __strncmp_power4 attribute_hidden;
 extern __typeof (strncmp) __strncmp_power7 attribute_hidden;
 extern __typeof (strncmp) __strncmp_power8 attribute_hidden;
+# undef strncmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strncmp,
-            (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-            ? __strncmp_power8 :
-              (hwcap & PPC_FEATURE_HAS_VSX)
-              ? __strncmp_power7 :
-		(hwcap & PPC_FEATURE_POWER4)
-		? __strncmp_power4
-            : __strncmp_ppc);
+libc_ifunc_redirected (__redirect_strncmp, strncmp,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __strncmp_power8
+		       : (hwcap & PPC_FEATURE_HAS_VSX)
+			 ? __strncmp_power7
+			 : (hwcap & PPC_FEATURE_POWER4)
+			   ? __strncmp_power4
+			   : __strncmp_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy.c b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
index 0176514..64495df 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
@@ -18,6 +18,9 @@
 
 /* Define multiple versions only for definition in libc. */
 #if IS_IN (libc)
+# define strncpy __redirect_strncpy
+/* Omit the strncpy inline definitions because it would redefine strncpy.  */
+# define __NO_STRING_INLINES
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -25,14 +28,15 @@
 extern __typeof (strncpy) __strncpy_ppc attribute_hidden;
 extern __typeof (strncpy) __strncpy_power7 attribute_hidden;
 extern __typeof (strncpy) __strncpy_power8 attribute_hidden;
+# undef strncpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
  ifunc symbol properly. */
-libc_ifunc (strncpy,
-            (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-            ? __strncpy_power8 :
-              (hwcap & PPC_FEATURE_HAS_VSX)
-              ? __strncpy_power7
-            : __strncpy_ppc);
+libc_ifunc_redirected (__redirect_strncpy, strncpy,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __strncpy_power8
+		       : (hwcap & PPC_FEATURE_HAS_VSX)
+			 ? __strncpy_power7
+			 : __strncpy_ppc);
 
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
index c4907e9..71dc12d 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
@@ -17,19 +17,21 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define strnlen __redirect_strnlen
+# define __strnlen __redirect___strnlen
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (__strnlen) __strnlen_ppc attribute_hidden;
 extern __typeof (__strnlen) __strnlen_power7 attribute_hidden;
-
-libc_ifunc (__strnlen,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strnlen_power7
-            : __strnlen_ppc);
+# undef strnlen
+# undef __strnlen
+libc_ifunc_redirected (__redirect___strnlen, __strnlen,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strnlen_power7
+		       : __strnlen_ppc);
 weak_alias (__strnlen, strnlen)
-libc_hidden_def (strnlen)
 
 #else
 #include <string/strnlen.c>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
index 45742bc..e485b02 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
@@ -18,18 +18,20 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if IS_IN (libc)
+# define strrchr __redirect_strrchr
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (strrchr) __strrchr_ppc attribute_hidden;
 extern __typeof (strrchr) __strrchr_power7 attribute_hidden;
+#undef strrchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strrchr,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strrchr_power7
-            : __strrchr_ppc);
+libc_ifunc_redirected (__redirect_strrchr, strrchr,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strrchr_power7
+		       : __strrchr_ppc);
 weak_alias (strrchr, rindex)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strstr.c b/sysdeps/powerpc/powerpc64/multiarch/strstr.c
index 7efc4b0..9a390c2 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strstr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strstr.c
@@ -18,17 +18,19 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if IS_IN (libc)
+# define strstr __redirect_strstr
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (strstr) __strstr_ppc attribute_hidden;
 extern __typeof (strstr) __strstr_power7 attribute_hidden;
+# undef strstr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strstr,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strstr_power7
-            : __strstr_ppc);
+libc_ifunc_redirected (__redirect_strstr, strstr,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strstr_power7
+		       : __strstr_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcschr.c b/sysdeps/powerpc/powerpc64/multiarch/wcschr.c
index 44c9b97..a470542 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/wcschr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/wcschr.c
@@ -17,6 +17,8 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define wcschr __redirect_wcschr
+# define __wcschr __redirect___wcschr
 # include <wchar.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -24,15 +26,16 @@
 extern __typeof (wcschr) __wcschr_ppc attribute_hidden;
 extern __typeof (wcschr) __wcschr_power6 attribute_hidden;
 extern __typeof (wcschr) __wcschr_power7 attribute_hidden;
+# undef wcschr
+# undef __wcschr
 
-libc_ifunc (__wcschr,
-	     (hwcap & PPC_FEATURE_HAS_VSX)
-             ? __wcschr_power7 :
-	       (hwcap & PPC_FEATURE_ARCH_2_05)
-	       ? __wcschr_power6
-             : __wcschr_ppc);
+libc_ifunc_redirected (__redirect___wcschr, __wcschr,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __wcschr_power7
+		       : (hwcap & PPC_FEATURE_ARCH_2_05)
+			 ? __wcschr_power6
+			 : __wcschr_ppc);
 weak_alias (__wcschr, wcschr)
-libc_hidden_builtin_def (wcschr)
 #else
 #undef libc_hidden_def
 #define libc_hidden_def(a)
-- 
2.3.0

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PATCH v3 7/9] Use libc_ifunc macro for system in libpthread.
  2016-08-24 14:05 [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Stefan Liebler
                   ` (6 preceding siblings ...)
  2016-08-24 14:05 ` [PATCH v3 2/9] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly " Stefan Liebler
@ 2016-08-24 17:02 ` Stefan Liebler
  2016-08-30 12:39   ` Florian Weimer
  2016-08-29  9:34 ` [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Florian Weimer
                   ` (2 subsequent siblings)
  10 siblings, 1 reply; 27+ messages in thread
From: Stefan Liebler @ 2016-08-24 17:02 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, fweimer, murphyp, schwab, joseph_myers

This patch uses the libc_ifunc macro to create already existing ifunc function
system_ifunc if HAVE_IFUNC is defined.

ChangeLog:

	* nptl/pt-system.c (system_ifunc): Use libc_ifunc macro.
---
 nptl/pt-system.c | 19 ++++---------------
 1 file changed, 4 insertions(+), 15 deletions(-)

diff --git a/nptl/pt-system.c b/nptl/pt-system.c
index 56f2a89..cc415da 100644
--- a/nptl/pt-system.c
+++ b/nptl/pt-system.c
@@ -32,21 +32,10 @@
 
 # if HAVE_IFUNC
 
-static __typeof (system) *
-__attribute__ ((used))
-system_resolve (void)
-{
-  return &__libc_system;
-}
-
-asm (".globl system_ifunc\n"
-     ".type system_ifunc, %gnu_indirect_function");
-
-#  ifdef HAVE_ASM_SET_DIRECTIVE
-asm (".set system_ifunc, system_resolve");
-#  else
-asm ("system_ifunc = system_resolve");
-#  endif
+extern __typeof(system) system_ifunc;
+#  undef INIT_ARCH
+#  define INIT_ARCH()
+libc_ifunc (system_ifunc, &__libc_system)
 
 # else  /* !HAVE_IFUNC */
 
-- 
2.3.0

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc.
  2016-08-24 14:05 [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Stefan Liebler
                   ` (7 preceding siblings ...)
  2016-08-24 17:02 ` [PATCH v3 7/9] Use libc_ifunc macro for system in libpthread Stefan Liebler
@ 2016-08-29  9:34 ` Florian Weimer
  2016-08-30 14:12   ` Stefan Liebler
  2016-09-05  7:13 ` [PING][PATCH " Stefan Liebler
  2016-10-07  9:19 ` [PATCH " Stefan Liebler
  10 siblings, 1 reply; 27+ messages in thread
From: Florian Weimer @ 2016-08-29  9:34 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha; +Cc: murphyp, schwab, joseph_myers

On 08/24/2016 04:04 PM, Stefan Liebler wrote:
> +For multi-arch support it is recommended to use a GCC with gnu-indirect-function
> +support as it is used to generate ifunc'ed symbols with correct
> +debug-information. This support can either be enabled by configuring GCC with
> +@samp{--enable-gnu-indirect-function} or by enabling it by default by setting
> +@samp{default_gnu_indirect_function} variable for a particular architecture in
> +gcc source file @file{gcc/config.gcc}.

Maybe use this text instead?

For multi-arch support it is recommended to use a GCC which has been 
built with support for GNU indirect functions.  This ensures that 
correct debugging information is generated for functions selected by 
IFUNC resolvers.  This support can either be enabled by configuring GCC 
with @samp{--enable-gnu-indirect-function}, or by enabling it by default 
by setting @samp{default_gnu_indirect_function} variable for a 
particular architecture in the GCC source file @file{gcc/config.gcc}.


The configure check looks okay to me.  Some existing checks use 
AC_TRY_COMPILE, others use the manual expansion you provided.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 2/9] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-08-24 14:05 ` [PATCH v3 2/9] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly " Stefan Liebler
@ 2016-08-29 20:16   ` Paul E. Murphy
  2016-08-30 14:12     ` Stefan Liebler
  2016-09-29 18:38   ` Adhemerval Zanella
  1 sibling, 1 reply; 27+ messages in thread
From: Paul E. Murphy @ 2016-08-29 20:16 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha; +Cc: fweimer, schwab, joseph_myers



On 08/24/2016 09:04 AM, Stefan Liebler wrote:

> 
> This way there is no trouble with the internal __GI_* symbols.
> Glibc builds fine with this construct and the debuginfo is "correct".
> For functions without a __GI_* symbol like memccpy this redirection is not needed.

Should memccpy read mempcpy?  Also, is the reason why you are able to remove the
libc_hidden_def usage later on in this patch?

> --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c
> +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c
> @@ -16,6 +16,9 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
> 
> +#define __finite __redirect___finite
> +#define __finitef __redirect___finitef
> +#define __finitel __redirect___finitel
finitef and finitel don't seem to be needed here.

>  #include <math.h>
>  #include <math_ldbl_opt.h>
>  #include <shlib-compat.h>
> @@ -23,11 +26,14 @@
> 
>  extern __typeof (__finite) __finite_ppc32 attribute_hidden;
>  extern __typeof (__finite) __finite_power7 attribute_hidden;
> -
> -libc_ifunc (__finite,
> -	    (hwcap & PPC_FEATURE_ARCH_2_06)
> -	    ? __finite_power7
> -            : __finite_ppc32);
> +#undef __finite
> +#undef __finitef
> +#undef __finitel
Likewise.


> diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c
> index 506c111..fe6c912 100644
> --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c
> +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c
> @@ -16,6 +16,9 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
> 
> +#define __isinf __redirect___isinf
> +#define __isinff __redirect___isinff
> +#define __isinfl __redirect___isinfl
Similarly, __isinff and __isinfl don't seem to need indirect.

>  #include <math.h>
>  #include <math_ldbl_opt.h>
>  #include <shlib-compat.h>
> @@ -23,11 +26,14 @@
> 
>  extern __typeof (__isinf) __isinf_ppc32 attribute_hidden;
>  extern __typeof (__isinf) __isinf_power7 attribute_hidden;
> -
> -libc_ifunc (__isinf,
> -	    (hwcap & PPC_FEATURE_ARCH_2_06)
> -	    ? __isinf_power7
> -            : __isinf_ppc32);
> +#undef __isinf
> +#undef __isinff
> +#undef __isinfl
Likewise.


> diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c
> index 8f848d7..3655b81 100644
> --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c
> +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c
> @@ -16,6 +16,9 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
> 
> +#define __isnan __redirect___isnan
> +#define __isnanf __redirect___isnanf
> +#define __isnanl __redirect___isnanl
__isnanf and __isnanl don't appear to need overrides too. 

>  #include <math.h>
>  #include <math_ldbl_opt.h>
>  #include <shlib-compat.h>
> @@ -25,15 +28,18 @@ extern __typeof (__isnan) __isnan_ppc32 attribute_hidden;
>  extern __typeof (__isnan) __isnan_power5 attribute_hidden;
>  extern __typeof (__isnan) __isnan_power6 attribute_hidden;
>  extern __typeof (__isnan) __isnan_power7 attribute_hidden;
> -
> -libc_ifunc (__isnan,
> -	    (hwcap & PPC_FEATURE_ARCH_2_06)
> -	    ? __isnan_power7 :
> -	      (hwcap & PPC_FEATURE_ARCH_2_05)
> -	      ? __isnan_power6 :
> -		(hwcap & PPC_FEATURE_POWER5)
> -		? __isnan_power5
> -            : __isnan_ppc32);
> +#undef __isnan
> +#undef __isnanf
> +#undef __isnanl
Likewise.

> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
> index 067edc2..c7d67f1 100644
> --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
> +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
> @@ -16,6 +16,9 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
> 
> +#define __finite __redirect___finite
> +#define __finitef __redirect___finitef
> +#define __finitel __redirect___finitel
__finitef and __finitel redirection doesn't seem necessary here.

>  #include <math.h>
>  #include <math_ldbl_opt.h>
>  #include <shlib-compat.h>
> @@ -24,13 +27,16 @@
>  extern __typeof (__finite) __finite_ppc64 attribute_hidden;
>  extern __typeof (__finite) __finite_power7 attribute_hidden;
>  extern __typeof (__finite) __finite_power8 attribute_hidden;
> -
> -libc_ifunc (__finite,
> -	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
> -	    ? __finite_power8 :
> -	      (hwcap & PPC_FEATURE_ARCH_2_06)
> -	      ? __finite_power7
> -            : __finite_ppc64);
> +#undef __finite
> +#undef __finitef
> +#undef __finitel
Likewise.


> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
> index 07e159d..a13ec27 100644
> --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
> +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
> @@ -16,6 +16,9 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
> 
> +#define __isinf __redirect___isinf
> +#define __isinff __redirect___isinff
> +#define __isinfl __redirect___isinfl
__isinff __isinfl don't seem to need redirection here.

>  #include <math.h>
>  #include <math_ldbl_opt.h>
>  #include <shlib-compat.h>
> @@ -24,13 +27,16 @@
>  extern __typeof (__isinf) __isinf_ppc64 attribute_hidden;
>  extern __typeof (__isinf) __isinf_power7 attribute_hidden;
>  extern __typeof (__isinf) __isinf_power8 attribute_hidden;
> -
> -libc_ifunc (__isinf,
> -	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
> -	    ? __isinf_power8 :
> -	      (hwcap & PPC_FEATURE_ARCH_2_06)
> -	      ? __isinf_power7
> -            : __isinf_ppc64);
> +#undef __isinf
> +#undef __isinff
> +#undef __isinfl
Likewise.

> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
> index a614f25..fce3c9d 100644
> --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
> +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
> @@ -16,6 +16,9 @@
>     License along with the GNU C Library; if not, see
>     <http://www.gnu.org/licenses/>.  */
> 
> +#define __isnan __redirect___isnan
> +#define __isnanf __redirect___isnanf
> +#define __isnanl __redirect___isnanl
Is __isnanf or __isnanl redirection necessary here?

>  #include <math.h>
>  #include <math_ldbl_opt.h>
>  #include <shlib-compat.h>
> @@ -27,19 +30,22 @@ extern __typeof (__isnan) __isnan_power6 attribute_hidden;
>  extern __typeof (__isnan) __isnan_power6x attribute_hidden;
>  extern __typeof (__isnan) __isnan_power7 attribute_hidden;
>  extern __typeof (__isnan) __isnan_power8 attribute_hidden;
> -
> -libc_ifunc (__isnan,
> -	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
> -	    ? __isnan_power8 :
> -	      (hwcap & PPC_FEATURE_ARCH_2_06)
> -	      ? __isnan_power7 :
> -		(hwcap & PPC_FEATURE_POWER6_EXT)
> -		? __isnan_power6x :
> -		  (hwcap & PPC_FEATURE_ARCH_2_05)
> -		    ? __isnan_power6 :
> -		    (hwcap & PPC_FEATURE_POWER5)
> -		      ? __isnan_power5
> -            : __isnan_ppc64);
> +#undef __isnan
> +#undef __isnanf
> +#undef __isnanl
Likewise.

> diff --git a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
> index 3c77b5f..36ec954 100644
> --- a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
> +++ b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c

> -libc_hidden_def (mempcpy)
These removals are allowed because of the behavior you've mentioned in changelog?


Otherwise, the ppc bits of this patch are OK with the removal of the extra redirections.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 3/9] s390: Refactor ifunc resolvers due to false debuginfo.
  2016-08-24 14:05 ` [PATCH v3 3/9] s390: Refactor ifunc resolvers due to false debuginfo Stefan Liebler
@ 2016-08-30 12:31   ` Florian Weimer
  2016-08-30 14:12     ` Stefan Liebler
  0 siblings, 1 reply; 27+ messages in thread
From: Florian Weimer @ 2016-08-30 12:31 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha; +Cc: murphyp, schwab, joseph_myers

On 08/24/2016 04:04 PM, Stefan Liebler wrote:
>  #if defined SHARED && IS_IN (libc)
> +# define mempcpy __redirect_mempcpy
> +# define __mempcpy __redirect___mempcpy
> +/* Omit the mempcpy inline definitions because it would redefine mempcpy.  */
> +# define _HAVE_STRING_ARCH_mempcpy 1
> +# include <string.h>
> +# undef mempcpy
> +# undef __mempcpy
>  # include <ifunc-resolve.h>

The long-term maintainability of such #define trickery still concerns 
me.  What would be needed to avoid that?

(This obviously shouldn't be part of this patch sequence, I'm just curious.)

Thanks,
Florian

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 7/9] Use libc_ifunc macro for system in libpthread.
  2016-08-24 17:02 ` [PATCH v3 7/9] Use libc_ifunc macro for system in libpthread Stefan Liebler
@ 2016-08-30 12:39   ` Florian Weimer
  0 siblings, 0 replies; 27+ messages in thread
From: Florian Weimer @ 2016-08-30 12:39 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha; +Cc: murphyp, schwab, joseph_myers

On 08/24/2016 04:04 PM, Stefan Liebler wrote:
> 	* nptl/pt-system.c (system_ifunc): Use libc_ifunc macro.

Likewise, looks okay.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 6/9] Use libc_ifunc macro for clock_* symbols in librt.
  2016-08-24 14:05 ` [PATCH v3 6/9] Use libc_ifunc macro for clock_* symbols in librt Stefan Liebler
@ 2016-08-30 12:39   ` Florian Weimer
  0 siblings, 0 replies; 27+ messages in thread
From: Florian Weimer @ 2016-08-30 12:39 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha; +Cc: murphyp, schwab, joseph_myers

On 08/24/2016 04:04 PM, Stefan Liebler wrote:
> 	* rt/clock-compat.c (COMPAT_REDIRECT): Use libc_ifunc macro.

Looks okay to me.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 8/9] Use libc_ifunc macro for vfork in libpthread.
  2016-08-24 14:05 ` [PATCH v3 8/9] Use libc_ifunc macro for vfork in libpthread Stefan Liebler
@ 2016-08-30 12:40   ` Florian Weimer
  0 siblings, 0 replies; 27+ messages in thread
From: Florian Weimer @ 2016-08-30 12:40 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha; +Cc: murphyp, schwab, joseph_myers

On 08/24/2016 04:04 PM, Stefan Liebler wrote:
> 	* nptl/pt-vfork.c (DEFINE_VFORK): Use libc_ifunc macro.

Okay as well.

Florian

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 5/9] ppc: Use libc_ifunc macro for time, gettimeofday.
  2016-08-24 14:05 ` [PATCH v3 5/9] ppc: " Stefan Liebler
@ 2016-08-30 13:46   ` Paul E. Murphy
  0 siblings, 0 replies; 27+ messages in thread
From: Paul E. Murphy @ 2016-08-30 13:46 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha; +Cc: fweimer, schwab, joseph_myers



On 08/24/2016 09:04 AM, Stefan Liebler wrote:
> This patch uses the libc_ifunc_hidden macro to create already existing ifunc functions
> time and gettimeofday on power. This way, the libc_hidden_def macro can be used
> instead of inline assemblies.
> On ppc32, the __GI_* symbols do not target the ifunc symbol and thus the
> redirection construct has to be applied here.
> 
> ChangeLog:
> 
> 	* sysdeps/unix/sysv/linux/powerpc/gettimeofday.c (__gettimeofday):
> 	Use libc_ifunc_hidden and libc_hidden_def macro. Redirect ifunced function
> 	in header for using it as type for ifunc function because __GI_* symbols
> 	for ppc32 do not target the ifunc symbols.
> 	* sysdeps/unix/sysv/linux/powerpc/time.c (time): Likewise.

This patch looks ok to me.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 3/9] s390: Refactor ifunc resolvers due to false debuginfo.
  2016-08-30 12:31   ` Florian Weimer
@ 2016-08-30 14:12     ` Stefan Liebler
  0 siblings, 0 replies; 27+ messages in thread
From: Stefan Liebler @ 2016-08-30 14:12 UTC (permalink / raw)
  To: libc-alpha

On 08/30/2016 02:31 PM, Florian Weimer wrote:
> On 08/24/2016 04:04 PM, Stefan Liebler wrote:
>>  #if defined SHARED && IS_IN (libc)
>> +# define mempcpy __redirect_mempcpy
>> +# define __mempcpy __redirect___mempcpy
>> +/* Omit the mempcpy inline definitions because it would redefine
>> mempcpy.  */
>> +# define _HAVE_STRING_ARCH_mempcpy 1
>> +# include <string.h>
>> +# undef mempcpy
>> +# undef __mempcpy
>>  # include <ifunc-resolve.h>
>
> The long-term maintainability of such #define trickery still concerns
> me.  What would be needed to avoid that?
>
I think we need a possibility to omit the hidden_proto definitions for 
the ifunc'ed symbols when using libc_ifunc macro. Then we wouldn't need 
the redirection and could use the libc_ifunc macro instead of 
libc_ifunc_redirected.
Only thoughts. Not tested if there are other pitfalls.
> (This obviously shouldn't be part of this patch sequence, I'm just
> curious.)
>
> Thanks,
> Florian
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 2/9] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-08-29 20:16   ` Paul E. Murphy
@ 2016-08-30 14:12     ` Stefan Liebler
  0 siblings, 0 replies; 27+ messages in thread
From: Stefan Liebler @ 2016-08-30 14:12 UTC (permalink / raw)
  To: libc-alpha

On 08/29/2016 10:16 PM, Paul E. Murphy wrote:
>
>
> On 08/24/2016 09:04 AM, Stefan Liebler wrote:
>
>>
>> This way there is no trouble with the internal __GI_* symbols.
>> Glibc builds fine with this construct and the debuginfo is "correct".
>> For functions without a __GI_* symbol like memccpy this redirection is not needed.
>
> Should memccpy read mempcpy?  Also, is the reason why you are able to remove the
> libc_hidden_def usage later on in this patch?
>
Sorry. This comment means sysdeps/s390/multiarch/memccpy.c. There is 
also a weak alias but no __GI_* symbol.

Regarding mempcpy in powerpc:
Before this patch there were two __GI_mempcpy symbols in powerpc-build:
readelf -s string/mempcpy.os | grep __GI_mempcpy
     16: 0000000000000000   156 IFUNC   WEAK   HIDDEN     7 __GI_mempcpy

readelf -s string/mempcpy-ppc64.os | grep __GI_mempcpy
     13: 0000000000000000    64 FUNC    GLOBAL DEFAULT    6 __GI_mempcpy

This only works as the IFUNC-one is weak. The resulting libc.so uses the 
non-IFUNC-one:
readelf -s libc.so | grep _mempcpy
   4716: 00000000001d8580    64 FUNC    LOCAL  DEFAULT   27 __GI_mempcpy
   5360: 00000000001d8580    64 FUNC    LOCAL  DEFAULT   27 __mempcpy_ppc
...

With the redirection I can remove the libc_hidden_def (mempcpy) in 
sysdeps/powerpc/powerpc64/multiarch/mempcpy.c and 
sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c. Now it is obvious 
that the libc_hidden_def in 
sysdeps/powerpc/powerpc64/multiarch/mempcpy-ppc64.c and 
sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy-ppc32.c is used.

>> --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c
>> +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c
>> @@ -16,6 +16,9 @@
>>     License along with the GNU C Library; if not, see
>>     <http://www.gnu.org/licenses/>.  */
>>
>> +#define __finite __redirect___finite
>> +#define __finitef __redirect___finitef
>> +#define __finitel __redirect___finitel
> finitef and finitel don't seem to be needed here.
>
If I omit the the redirection of finitef and finitel the following error 
occurs (See my further comments below):
gcc ../sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c -c ...
In file included from <command-line>:0:0:
../include/math.h:15:15: error: ‘__finitef’ undeclared here (not in a 
function)
  hidden_proto (__finitef)
                ^
./../include/libc-symbols.h:409:27: note: in definition of macro 
‘__hidden_proto’
    extern thread __typeof (name) name __asm__ (__hidden_asmname 
(#internal)) \
                            ^
../include/math.h:15:1: note: in expansion of macro ‘hidden_proto’
  hidden_proto (__finitef)
  ^
../include/math.h:20:15: error: ‘__finitel’ undeclared here (not in a 
function)
  hidden_proto (__finitel)
                ^
./../include/libc-symbols.h:409:27: note: in definition of macro 
‘__hidden_proto’
    extern thread __typeof (name) name __asm__ (__hidden_asmname 
(#internal)) \
                            ^
../include/math.h:20:1: note: in expansion of macro ‘hidden_proto’
  hidden_proto (__finitel)
  ^
In file included from ../sysdeps/powerpc/fpu/math_private.h:26:0,
                  from ../sysdeps/ieee754/ldbl-opt/math_ldbl_opt.h:40,
                  from 
../sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c:23:
../sysdeps/generic/math_private.h:325:12: error: ‘__finitel’ redeclared 
as different kind of symbol
  extern int __finitel (long double);
             ^
In file included from <command-line>:0:0:
../include/math.h:20:15: note: previous declaration of ‘__finitel’ was here
  hidden_proto (__finitel)
                ^
./../include/libc-symbols.h:409:33: note: in definition of macro 
‘__hidden_proto’
    extern thread __typeof (name) name __asm__ (__hidden_asmname 
(#internal)) \
                                  ^
../include/math.h:20:1: note: in expansion of macro ‘hidden_proto’
  hidden_proto (__finitel)



Due to the mechanism in math.h (see below) the redirection of __finite 
leads to also redirecting the definition of __finitef, __finitel as it 
is also used in those __MATHDECL_1 usages in math/bits/mathcalls.h but 
not in include/math.h when using hidden_proto (__finite[fl]).
Thus I also have to redirect the float and long double versions.
This also applies to __isinf, __isnan.

include/math.h:
  3: #include <math/math.h>
15: hidden_proto (__finitef)
20: hidden_proto (__finitel)

math/math.h:
96: #define __MATHDECL_1(type, function,suffix, args) \
   extern type __MATH_PRECNAME(function,suffix) args __THROW
104, 125, 172: #include <bits/mathcalls.h>
(for float, double, long double math functions)

math/bits/mathcalls.h:
194:__MATHDECL_1 (int,__isinf,, (_Mdouble_ __value)) __attribute__ 
((__const__));
197: __MATHDECL_1 (int,__finite,, (_Mdouble_ __value)) __attribute__ 
((__const__));
236: __MATHDECL_1 (int,__isnan,, (_Mdouble_ __value)) __attribute__ 
((__const__));



>>  #include <math.h>
>>  #include <math_ldbl_opt.h>
>>  #include <shlib-compat.h>
>> @@ -23,11 +26,14 @@
>>
>>  extern __typeof (__finite) __finite_ppc32 attribute_hidden;
>>  extern __typeof (__finite) __finite_power7 attribute_hidden;
>> -
>> -libc_ifunc (__finite,
>> -	    (hwcap & PPC_FEATURE_ARCH_2_06)
>> -	    ? __finite_power7
>> -            : __finite_ppc32);
>> +#undef __finite
>> +#undef __finitef
>> +#undef __finitel
> Likewise.
>
>
>> diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c
>> index 506c111..fe6c912 100644
>> --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c
>> +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c
>> @@ -16,6 +16,9 @@
>>     License along with the GNU C Library; if not, see
>>     <http://www.gnu.org/licenses/>.  */
>>
>> +#define __isinf __redirect___isinf
>> +#define __isinff __redirect___isinff
>> +#define __isinfl __redirect___isinfl
> Similarly, __isinff and __isinfl don't seem to need indirect.
>
Same reason as in comment for 
sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c.
>>  #include <math.h>
>>  #include <math_ldbl_opt.h>
>>  #include <shlib-compat.h>
>> @@ -23,11 +26,14 @@
>>
>>  extern __typeof (__isinf) __isinf_ppc32 attribute_hidden;
>>  extern __typeof (__isinf) __isinf_power7 attribute_hidden;
>> -
>> -libc_ifunc (__isinf,
>> -	    (hwcap & PPC_FEATURE_ARCH_2_06)
>> -	    ? __isinf_power7
>> -            : __isinf_ppc32);
>> +#undef __isinf
>> +#undef __isinff
>> +#undef __isinfl
> Likewise.
>
>
>> diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c
>> index 8f848d7..3655b81 100644
>> --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c
>> +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c
>> @@ -16,6 +16,9 @@
>>     License along with the GNU C Library; if not, see
>>     <http://www.gnu.org/licenses/>.  */
>>
>> +#define __isnan __redirect___isnan
>> +#define __isnanf __redirect___isnanf
>> +#define __isnanl __redirect___isnanl
> __isnanf and __isnanl don't appear to need overrides too.
>
Same reason as in comment for 
sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c.
>>  #include <math.h>
>>  #include <math_ldbl_opt.h>
>>  #include <shlib-compat.h>
>> @@ -25,15 +28,18 @@ extern __typeof (__isnan) __isnan_ppc32 attribute_hidden;
>>  extern __typeof (__isnan) __isnan_power5 attribute_hidden;
>>  extern __typeof (__isnan) __isnan_power6 attribute_hidden;
>>  extern __typeof (__isnan) __isnan_power7 attribute_hidden;
>> -
>> -libc_ifunc (__isnan,
>> -	    (hwcap & PPC_FEATURE_ARCH_2_06)
>> -	    ? __isnan_power7 :
>> -	      (hwcap & PPC_FEATURE_ARCH_2_05)
>> -	      ? __isnan_power6 :
>> -		(hwcap & PPC_FEATURE_POWER5)
>> -		? __isnan_power5
>> -            : __isnan_ppc32);
>> +#undef __isnan
>> +#undef __isnanf
>> +#undef __isnanl
> Likewise.
>
>> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
>> index 067edc2..c7d67f1 100644
>> --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
>> +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
>> @@ -16,6 +16,9 @@
>>     License along with the GNU C Library; if not, see
>>     <http://www.gnu.org/licenses/>.  */
>>
>> +#define __finite __redirect___finite
>> +#define __finitef __redirect___finitef
>> +#define __finitel __redirect___finitel
> __finitef and __finitel redirection doesn't seem necessary here.
>
Same reason as in comment for 
sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c.
>>  #include <math.h>
>>  #include <math_ldbl_opt.h>
>>  #include <shlib-compat.h>
>> @@ -24,13 +27,16 @@
>>  extern __typeof (__finite) __finite_ppc64 attribute_hidden;
>>  extern __typeof (__finite) __finite_power7 attribute_hidden;
>>  extern __typeof (__finite) __finite_power8 attribute_hidden;
>> -
>> -libc_ifunc (__finite,
>> -	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>> -	    ? __finite_power8 :
>> -	      (hwcap & PPC_FEATURE_ARCH_2_06)
>> -	      ? __finite_power7
>> -            : __finite_ppc64);
>> +#undef __finite
>> +#undef __finitef
>> +#undef __finitel
> Likewise.
>
>
>> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
>> index 07e159d..a13ec27 100644
>> --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
>> +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
>> @@ -16,6 +16,9 @@
>>     License along with the GNU C Library; if not, see
>>     <http://www.gnu.org/licenses/>.  */
>>
>> +#define __isinf __redirect___isinf
>> +#define __isinff __redirect___isinff
>> +#define __isinfl __redirect___isinfl
> __isinff __isinfl don't seem to need redirection here.
>
Same reason as in comment for 
sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c.
>>  #include <math.h>
>>  #include <math_ldbl_opt.h>
>>  #include <shlib-compat.h>
>> @@ -24,13 +27,16 @@
>>  extern __typeof (__isinf) __isinf_ppc64 attribute_hidden;
>>  extern __typeof (__isinf) __isinf_power7 attribute_hidden;
>>  extern __typeof (__isinf) __isinf_power8 attribute_hidden;
>> -
>> -libc_ifunc (__isinf,
>> -	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>> -	    ? __isinf_power8 :
>> -	      (hwcap & PPC_FEATURE_ARCH_2_06)
>> -	      ? __isinf_power7
>> -            : __isinf_ppc64);
>> +#undef __isinf
>> +#undef __isinff
>> +#undef __isinfl
> Likewise.
>
>> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
>> index a614f25..fce3c9d 100644
>> --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
>> +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
>> @@ -16,6 +16,9 @@
>>     License along with the GNU C Library; if not, see
>>     <http://www.gnu.org/licenses/>.  */
>>
>> +#define __isnan __redirect___isnan
>> +#define __isnanf __redirect___isnanf
>> +#define __isnanl __redirect___isnanl
> Is __isnanf or __isnanl redirection necessary here?
>
Same reason as in comment for 
sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c.
>>  #include <math.h>
>>  #include <math_ldbl_opt.h>
>>  #include <shlib-compat.h>
>> @@ -27,19 +30,22 @@ extern __typeof (__isnan) __isnan_power6 attribute_hidden;
>>  extern __typeof (__isnan) __isnan_power6x attribute_hidden;
>>  extern __typeof (__isnan) __isnan_power7 attribute_hidden;
>>  extern __typeof (__isnan) __isnan_power8 attribute_hidden;
>> -
>> -libc_ifunc (__isnan,
>> -	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>> -	    ? __isnan_power8 :
>> -	      (hwcap & PPC_FEATURE_ARCH_2_06)
>> -	      ? __isnan_power7 :
>> -		(hwcap & PPC_FEATURE_POWER6_EXT)
>> -		? __isnan_power6x :
>> -		  (hwcap & PPC_FEATURE_ARCH_2_05)
>> -		    ? __isnan_power6 :
>> -		    (hwcap & PPC_FEATURE_POWER5)
>> -		      ? __isnan_power5
>> -            : __isnan_ppc64);
>> +#undef __isnan
>> +#undef __isnanf
>> +#undef __isnanl
> Likewise.
>
>> diff --git a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
>> index 3c77b5f..36ec954 100644
>> --- a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
>> +++ b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
>
>> -libc_hidden_def (mempcpy)
> These removals are allowed because of the behavior you've mentioned in changelog?
See "Regarding mempcpy in powerpc:" above.
>
>
> Otherwise, the ppc bits of this patch are OK with the removal of the extra redirections.
>
Thanks for reviewing.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc.
  2016-08-29  9:34 ` [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Florian Weimer
@ 2016-08-30 14:12   ` Stefan Liebler
  0 siblings, 0 replies; 27+ messages in thread
From: Stefan Liebler @ 2016-08-30 14:12 UTC (permalink / raw)
  To: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 1370 bytes --]

On 08/29/2016 11:34 AM, Florian Weimer wrote:
> On 08/24/2016 04:04 PM, Stefan Liebler wrote:
>> +For multi-arch support it is recommended to use a GCC with
>> gnu-indirect-function
>> +support as it is used to generate ifunc'ed symbols with correct
>> +debug-information. This support can either be enabled by configuring
>> GCC with
>> +@samp{--enable-gnu-indirect-function} or by enabling it by default by
>> setting
>> +@samp{default_gnu_indirect_function} variable for a particular
>> architecture in
>> +gcc source file @file{gcc/config.gcc}.
>
> Maybe use this text instead?
> 6808c16e2d067c8137fa9eae6078dc55c5d355c6
> For multi-arch support it is recommended to use a GCC which has been
> built with support for GNU indirect functions.  This ensures that
> correct debugging information is generated for functions selected by
> IFUNC resolvers.  This support can either be enabled by configuring GCC
> with @samp{--enable-gnu-indirect-function}, or by enabling it by default
> by setting @samp{default_gnu_indirect_function} variable for a
> particular architecture in the GCC source file @file{gcc/config.gcc}.
>
Okay. I've updated install-files and I'll use this updated text also for 
the NEWS entry.
>
> The configure check looks okay to me.  Some existing checks use
> AC_TRY_COMPILE, others use the manual expansion you provided.
>
> Thanks,
> Florian
>


[-- Attachment #2: 20160830_ifunc_configure_check.patch --]
[-- Type: text/x-patch, Size: 8598 bytes --]

commit 3cfc378ca6f95feaa35b99b4b5897fa35dbff68f
Author: Stefan Liebler <stli@linux.vnet.ibm.com>
Date:   Wed Aug 24 10:18:14 2016 +0200

    Add configure check to test if gcc supports attribute ifunc.
    
    This patch adds a configure check to test if gcc supports attribute ifunc.
    The support can either be enabled in <gcc-src>/gcc/config.gcc for one
    architecture in general by setting default_gnu_indirect_function variable to yes
    or by configuring gcc with --enable-gnu-indirect-function.
    
    The next patch rewrites libc_ifunc macro to use gcc attribute ifunc instead
    of inline assembly to generate the IFUNC symbols due to false debuginfo.
    
    If gcc does not support attribute ifunc, the old approach for generating
    ifunc'ed symbols is used. Then the debug-information is false. Thus it is
    recommended to use a gcc with indirect function support (See notes in INSTALL).
    After this patch-series these inline assemblies for ifunc-handling are not
    scattered in multiple files but are used only indirect via ifunc-macros
    and can simply removed in libc-symbols.h in future.
    
    If glibc is configured with --enable-multi-arch and gcc does not support
    attribute ifunc, a configure warning is dumped!
    
    This NEWS entry will be added:
    * For multi-arch support it is recommended to use a GCC which has
      been built with support for GNU indirect functions.  This ensures
      that correct debugging information is generated for functions
      selected by IFUNC resolvers.  This support can either be enabled by
      configuring GCC with '--enable-gnu-indirect-function', or by
      enabling it by default by setting 'default_gnu_indirect_function'
      variable for a particular architecture in the GCC source file
      'gcc/config.gcc'.
    
    ChangeLog:
    
    	* config.h.in (HAVE_GCC_IFUNC): New undef.
    	* configure.ac: Add check if gcc supports attribute ifunc feature.
    	* configure: Regenerated.
    	* manual/install.texi: Add recommendation for gcc with
    	indirect-function support.
    	* INSTALL: Regenerated.

diff --git a/INSTALL b/INSTALL
index ec3445f..66be341 100644
--- a/INSTALL
+++ b/INSTALL
@@ -359,6 +359,15 @@ build the GNU C Library:
      better code.  As of release time, GCC 5.3 is the newest compiler
      verified to work to build the GNU C Library.
 
+     For multi-arch support it is recommended to use a GCC which has
+     been built with support for GNU indirect functions.  This ensures
+     that correct debugging information is generated for functions
+     selected by IFUNC resolvers.  This support can either be enabled by
+     configuring GCC with '--enable-gnu-indirect-function', or by
+     enabling it by default by setting 'default_gnu_indirect_function'
+     variable for a particular architecture in the GCC source file
+     'gcc/config.gcc'.
+
      You can use whatever compiler you like to compile programs that use
      the GNU C Library.
 
diff --git a/config.h.in b/config.h.in
index 856ef6a..9f5c5ff 100644
--- a/config.h.in
+++ b/config.h.in
@@ -171,6 +171,9 @@
 /* Define to 1 if STT_GNU_IFUNC support actually works.  */
 #define HAVE_IFUNC 0
 
+/* Define if gcc supports attribute ifunc.  */
+#undef HAVE_GCC_IFUNC
+
 /* Define if the linker defines __ehdr_start.  */
 #undef HAVE_EHDR_START
 
diff --git a/configure b/configure
index 17625e1..8ffc2b5 100755
--- a/configure
+++ b/configure
@@ -3914,6 +3914,36 @@ fi
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_ld_gnu_indirect_function" >&5
 $as_echo "$libc_cv_ld_gnu_indirect_function" >&6; }
 
+# Check if gcc supports attribute ifunc as it is used in libc_ifunc macro.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for gcc attribute ifunc support" >&5
+$as_echo_n "checking for gcc attribute ifunc support... " >&6; }
+if ${libc_cv_gcc_indirect_function+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  cat > conftest.c <<EOF
+extern int func (int);
+int used_func (int a)
+{
+  return a;
+}
+static void *resolver ()
+{
+  return &used_func;
+}
+extern __typeof (func) func __attribute__ ((ifunc ("resolver")));
+EOF
+libc_cv_gcc_indirect_function=no
+if ${CC-cc} -c conftest.c -o conftest.o 1>&5 \
+   2>&5 ; then
+  if $READELF -s conftest.o | grep IFUNC >/dev/null 2>&5; then
+    libc_cv_gcc_indirect_function=yes
+  fi
+fi
+rm -f conftest*
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $libc_cv_gcc_indirect_function" >&5
+$as_echo "$libc_cv_gcc_indirect_function" >&6; }
+
 if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then
   if test x"$multi_arch" = xyes; then
     as_fn_error $? "--enable-multi-arch support requires assembler and linker support" "$LINENO" 5
@@ -3921,6 +3951,13 @@ if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then
     multi_arch=no
   fi
 fi
+if test x"$libc_cv_gcc_indirect_function" != xyes &&
+   test x"$multi_arch" = xyes; then
+  { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: --enable-multi-arch support recommends a gcc with gnu-indirect-function support.
+Please use a gcc which supports it by default or configure gcc with --enable-gnu-indirect-function" >&5
+$as_echo "$as_me: WARNING: --enable-multi-arch support recommends a gcc with gnu-indirect-function support.
+Please use a gcc which supports it by default or configure gcc with --enable-gnu-indirect-function" >&2;}
+fi
 multi_arch_d=
 if test x"$multi_arch" != xno; then
   multi_arch_d=/multiarch
@@ -6504,6 +6541,11 @@ if test x"$libc_cv_ld_gnu_indirect_function" = xyes; then
 
 fi
 
+if test x"$libc_cv_gcc_indirect_function" = xyes; then
+  $as_echo "#define HAVE_GCC_IFUNC 1" >>confdefs.h
+
+fi
+
 # This is far from the AC_ARG_ENABLE that sets it so that a sysdeps
 # configure fragment can override the value to prevent this AC_DEFINE.
 
diff --git a/configure.ac b/configure.ac
index 33bcd62..643002f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -634,6 +634,30 @@ if ${CC-cc} $CFLAGS $CPPFLAGS $LDFLAGS \
 fi
 rm -f conftest*])
 
+# Check if gcc supports attribute ifunc as it is used in libc_ifunc macro.
+AC_CACHE_CHECK([for gcc attribute ifunc support],
+	       libc_cv_gcc_indirect_function, [dnl
+cat > conftest.c <<EOF
+extern int func (int);
+int used_func (int a)
+{
+  return a;
+}
+static void *resolver ()
+{
+  return &used_func;
+}
+extern __typeof (func) func __attribute__ ((ifunc ("resolver")));
+EOF
+libc_cv_gcc_indirect_function=no
+if ${CC-cc} -c conftest.c -o conftest.o 1>&AS_MESSAGE_LOG_FD \
+   2>&AS_MESSAGE_LOG_FD ; then
+  if $READELF -s conftest.o | grep IFUNC >/dev/null 2>&AS_MESSAGE_LOG_FD; then
+    libc_cv_gcc_indirect_function=yes
+  fi
+fi
+rm -f conftest*])
+
 if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then
   if test x"$multi_arch" = xyes; then
     AC_MSG_ERROR([--enable-multi-arch support requires assembler and linker support])
@@ -641,6 +665,11 @@ if test x"$libc_cv_ld_gnu_indirect_function" != xyes; then
     multi_arch=no
   fi
 fi
+if test x"$libc_cv_gcc_indirect_function" != xyes &&
+   test x"$multi_arch" = xyes; then
+  AC_MSG_WARN([--enable-multi-arch support recommends a gcc with gnu-indirect-function support.
+Please use a gcc which supports it by default or configure gcc with --enable-gnu-indirect-function])
+fi
 multi_arch_d=
 if test x"$multi_arch" != xno; then
   multi_arch_d=/multiarch
@@ -1770,6 +1799,10 @@ if test x"$libc_cv_ld_gnu_indirect_function" = xyes; then
   AC_DEFINE(HAVE_IFUNC)
 fi
 
+if test x"$libc_cv_gcc_indirect_function" = xyes; then
+  AC_DEFINE(HAVE_GCC_IFUNC)
+fi
+
 # This is far from the AC_ARG_ENABLE that sets it so that a sysdeps
 # configure fragment can override the value to prevent this AC_DEFINE.
 AC_SUBST(use_nscd)
diff --git a/manual/install.texi b/manual/install.texi
index 79ee45f..5f5705e 100644
--- a/manual/install.texi
+++ b/manual/install.texi
@@ -402,6 +402,14 @@ the newest version of the compiler that is known to work for building
 release time, GCC 5.3 is the newest compiler verified to work to build
 @theglibc{}.
 
+For multi-arch support it is recommended to use a GCC which has been built with
+support for GNU indirect functions.  This ensures that correct debugging
+information is generated for functions selected by IFUNC resolvers.  This
+support can either be enabled by configuring GCC with
+@samp{--enable-gnu-indirect-function}, or by enabling it by default by setting
+@samp{default_gnu_indirect_function} variable for a particular architecture in
+the GCC source file @file{gcc/config.gcc}.
+
 You can use whatever compiler you like to compile programs that use
 @theglibc{}.
 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* [PING][PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc.
  2016-08-24 14:05 [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Stefan Liebler
                   ` (8 preceding siblings ...)
  2016-08-29  9:34 ` [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Florian Weimer
@ 2016-09-05  7:13 ` Stefan Liebler
  2016-09-29 13:50   ` Stefan Liebler
  2016-10-07  9:19 ` [PATCH " Stefan Liebler
  10 siblings, 1 reply; 27+ messages in thread
From: Stefan Liebler @ 2016-09-05  7:13 UTC (permalink / raw)
  To: libc-alpha; +Cc: Florian Weimer, Paul E. Murphy, schwab, Joseph S. Myers

On 08/24/2016 04:04 PM, Stefan Liebler wrote:
> This patch adds a configure check to test if gcc supports attribute ifunc.
> The support can either be enabled in <gcc-src>/gcc/config.gcc for one
> architecture in general by setting default_gnu_indirect_function variable to yes
> or by configuring gcc with --enable-gnu-indirect-function.
>
> The next patch rewrites libc_ifunc macro to use gcc attribute ifunc instead
> of inline assembly to generate the IFUNC symbols due to false debuginfo.
>
> If gcc does not support attribute ifunc, the old approach for generating
> ifunc'ed symbols is used. Then the debug-information is false. Thus it is
> recommended to use a gcc with indirect function support (See notes in INSTALL).
> After this patch-series these inline assemblies for ifunc-handling are not
> scattered in multiple files but are used only indirect via ifunc-macros
> and can simply removed in libc-symbols.h in future.
>
> If glibc is configured with --enable-multi-arch and gcc does not support
> attribute ifunc, a configure warning is dumped!
>
> This NEWS entry will be added:
> * For multi-arch support it is recommended to use a GCC with gnu-indirect-function
>   support as it is used to generate ifunc'ed symbols with correct
>   debug-information. This support can either be enabled by configuring GCC with
>   '--enable-gnu-indirect-function' or by enabling it by default by setting
>   'default_gnu_indirect_function' variable for a particular architecture in
>   gcc source file 'gcc/config.gcc'.
>
> ChangeLog:
>
> 	* config.h.in (HAVE_GCC_IFUNC): New undef.
> 	* configure.ac: Add check if gcc supports attribute ifunc feature.
> 	* configure: Regenerated.
> 	* manual/install.texi: Add recommendation for gcc with
> 	indirect-function support.
> 	* INSTALL: Regenerated.

Hi,

PING.

Here is the current status of the patchset:
-"[PATCH v3 1/9] Add configure check to test if gcc supports attribute 
ifunc.":
ok from Florian.

-"[PATCH v3 2/9] Use gcc attribute ifunc in libc_ifunc macro instead of 
inline assembly due to false debuginfo.":
partial ok from Paul. Paul, are the redirection of the f/l variants of 
__finite and others ok as they are needed (see my previous answer)?
PING: ifunc-macros in libc-symbols.h

-"[PATCH v3 3/9] s390: Refactor ifunc resolvers due to false debuginfo.":
PING.

-"[PATCH v3 4/9] i386, x86: Use libc_ifunc macro for time, gettimeofday.":
PING. Andreas, are the names for the redirection defines okay?

-"[PATCH v3 5/9] ppc: Use libc_ifunc macro for time, gettimeofday.":
ok from Paul.

-"[PATCH v3 6/9] Use libc_ifunc macro for clock_* symbols in librt.":
ok from Florian.

-"[PATCH v3 7/9] Use libc_ifunc macro for system in libpthread.":
ok from Florian.

-"[PATCH v3 8/9] Use libc_ifunc macro for vfork in libpthread.":
ok from Florian.

-"[PATCH v3 9/9] Use libc_ifunc macro for siglongjmp, longjmp in 
libpthread.":
PING.

Bye.
Stefan

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PING][PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc.
  2016-09-05  7:13 ` [PING][PATCH " Stefan Liebler
@ 2016-09-29 13:50   ` Stefan Liebler
  0 siblings, 0 replies; 27+ messages in thread
From: Stefan Liebler @ 2016-09-29 13:50 UTC (permalink / raw)
  To: libc-alpha

PING.


On 09/05/2016 09:12 AM, Stefan Liebler wrote:
> On 08/24/2016 04:04 PM, Stefan Liebler wrote:
>> This patch adds a configure check to test if gcc supports attribute
>> ifunc.
>> The support can either be enabled in <gcc-src>/gcc/config.gcc for one
>> architecture in general by setting default_gnu_indirect_function
>> variable to yes
>> or by configuring gcc with --enable-gnu-indirect-function.
>>
>> The next patch rewrites libc_ifunc macro to use gcc attribute ifunc
>> instead
>> of inline assembly to generate the IFUNC symbols due to false debuginfo.
>>
>> If gcc does not support attribute ifunc, the old approach for generating
>> ifunc'ed symbols is used. Then the debug-information is false. Thus it is
>> recommended to use a gcc with indirect function support (See notes in
>> INSTALL).
>> After this patch-series these inline assemblies for ifunc-handling are
>> not
>> scattered in multiple files but are used only indirect via ifunc-macros
>> and can simply removed in libc-symbols.h in future.
>>
>> If glibc is configured with --enable-multi-arch and gcc does not support
>> attribute ifunc, a configure warning is dumped!
>>
>> This NEWS entry will be added:
>> * For multi-arch support it is recommended to use a GCC with
>> gnu-indirect-function
>>   support as it is used to generate ifunc'ed symbols with correct
>>   debug-information. This support can either be enabled by configuring
>> GCC with
>>   '--enable-gnu-indirect-function' or by enabling it by default by
>> setting
>>   'default_gnu_indirect_function' variable for a particular
>> architecture in
>>   gcc source file 'gcc/config.gcc'.
>>
>> ChangeLog:
>>
>>     * config.h.in (HAVE_GCC_IFUNC): New undef.
>>     * configure.ac: Add check if gcc supports attribute ifunc feature.
>>     * configure: Regenerated.
>>     * manual/install.texi: Add recommendation for gcc with
>>     indirect-function support.
>>     * INSTALL: Regenerated.
>
> Hi,
>
> PING.
>
> Here is the current status of the patchset:
> -"[PATCH v3 1/9] Add configure check to test if gcc supports attribute
> ifunc.":
> ok from Florian.
>
> -"[PATCH v3 2/9] Use gcc attribute ifunc in libc_ifunc macro instead of
> inline assembly due to false debuginfo.":
> partial ok from Paul. Paul, are the redirection of the f/l variants of
> __finite and others ok as they are needed (see my previous answer)?
> PING: ifunc-macros in libc-symbols.h
>
> -"[PATCH v3 3/9] s390: Refactor ifunc resolvers due to false debuginfo.":
> PING.
>
> -"[PATCH v3 4/9] i386, x86: Use libc_ifunc macro for time, gettimeofday.":
> PING. Andreas, are the names for the redirection defines okay?
>
> -"[PATCH v3 5/9] ppc: Use libc_ifunc macro for time, gettimeofday.":
> ok from Paul.
>
> -"[PATCH v3 6/9] Use libc_ifunc macro for clock_* symbols in librt.":
> ok from Florian.
>
> -"[PATCH v3 7/9] Use libc_ifunc macro for system in libpthread.":
> ok from Florian.
>
> -"[PATCH v3 8/9] Use libc_ifunc macro for vfork in libpthread.":
> ok from Florian.
>
> -"[PATCH v3 9/9] Use libc_ifunc macro for siglongjmp, longjmp in
> libpthread.":
> PING.
>
> Bye.
> Stefan
>

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 4/9] i386, x86: Use libc_ifunc macro for time, gettimeofday.
  2016-08-24 14:05 ` [PATCH v3 4/9] i386, x86: Use libc_ifunc macro for time, gettimeofday Stefan Liebler
@ 2016-09-29 14:34   ` Andreas Schwab
  0 siblings, 0 replies; 27+ messages in thread
From: Andreas Schwab @ 2016-09-29 14:34 UTC (permalink / raw)
  To: Stefan Liebler; +Cc: libc-alpha, fweimer, murphyp, joseph_myers

Ok.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 2/9] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-08-24 14:05 ` [PATCH v3 2/9] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly " Stefan Liebler
  2016-08-29 20:16   ` Paul E. Murphy
@ 2016-09-29 18:38   ` Adhemerval Zanella
  2016-09-30 13:45     ` Stefan Liebler
  1 sibling, 1 reply; 27+ messages in thread
From: Adhemerval Zanella @ 2016-09-29 18:38 UTC (permalink / raw)
  To: libc-alpha

Patch LGTM and a powerpc32/power7 (to actually uses ifunc) and a build/run
for powerpc64le seems ok.  

I see with recent Andreas ack of 4/9 that only 3/9 (s390 bits) and
9/9 (siglongjmp, longjmp in libpthread) seems to be the impending
bits.  I plan to check on 9/9, but I won't be able to proper review
3/9 since I do not have access to a s390 machine anymore.

Some comments below:

On 24/08/2016 07:04, Stefan Liebler wrote:
> diff --git a/include/libc-symbols.h b/include/libc-symbols.h
> index c2b499a..44e5253 100644
> --- a/include/libc-symbols.h
> +++ b/include/libc-symbols.h
> @@ -722,27 +722,64 @@ for linking")
>  # define compat_data_section .section ".data.compat", "aw";
>  #endif
>  
> -/* Marker used for indirection function symbols.  */
> -#define libc_ifunc(name, expr)						\
> -  extern void *name##_ifunc (void) __asm__ (#name);			\
> -  void *name##_ifunc (void)						\
> +/* Helper / base  macros for indirect function symbols.  */
> +#define __ifunc_resolver(type_name, name, expr, arg, init, classifier)	\
> +  classifier void *name##_ifunc (arg)					\
>    {									\
> -    INIT_ARCH ();							\
> -    __typeof (name) *res = expr;					\
> +    init ();								\
> +    __typeof (type_name) *res = expr;					\
>      return res;								\
> -  }									\
> -  __asm__ (".type " #name ", %gnu_indirect_function");
> +  }
> +
> +#ifdef HAVE_GCC_IFUNC
> +# define __ifunc(type_name, name, expr, arg, init)			\
> +  extern __typeof (type_name) name __attribute__			\
> +			      ((ifunc (#name "_ifunc")));		\
> +  __ifunc_resolver (type_name, name, expr, arg, init, static)
> +
> +# define __ifunc_hidden(type_name, name, expr, arg, init)	\
> +  __ifunc (type_name, name, expr, arg, init)
> +#else
> +/* Gcc does not support __attribute__ ((ifunc (...))).  Use the old behaviour
> +   as fallback.  But keep in mind that the debug information for the ifunc
> +   resolver functions is not correct.  It contains the ifunc'ed function as
> +   DW_AT_linkage_name.  E.g. lldb uses this field and an inferior function
> +   call of the ifunc'ed function will fail due to "no matching function for call

Line too long.

> +   to ..." because the ifunc'ed function and the resolver function have
> +   different signatures.  (Gcc support is disabled at least on a ppc64le
> +   Ubuntu 14.04 system.)  */
> +
> +# define __ifunc(type_name, name, expr, arg, init)			\
> +  extern __typeof (type_name) name;					\
> +  void *name##_ifunc (arg) __asm__ (#name);				\
> +  __ifunc_resolver (type_name, name, expr, arg, init,)			\
> + __asm__ (".type " #name ", %gnu_indirect_function");
> +
> +# define __ifunc_hidden(type_name, name, expr, arg, init)		\
> +  extern __typeof (type_name) __libc_##name;				\
> +  __ifunc (type_name, __libc_##name, expr, arg, init)			\
> +  strong_alias (__libc_##name, name);
> +#endif /* !HAVE_GCC_IFUNC  */
> +
> +/* Use libc_ifunc if your ifunc'ed function has no internal symbol.  */
> +#define libc_ifunc(name, expr) __ifunc (name, name, expr, void, INIT_ARCH)

I think it will be valuable to add a comment like the one on same
file at line 341 with a usage example on how to use
libc_ifunc{_redirected,_hidden} and difference between each usage and
the possible requirements (such as name redirection).

> +
> +/* Use libc_ifunc_redirected if your ifunc'ed function has an internal symbol
> +   which should be a dedicated fallback function instead of ifunc'ed.
> +   You have to redirect the function in the header file and use it as
> +   redirected_name.  */
> +#define libc_ifunc_redirected(redirected_name, name, expr)	\
> +  __ifunc (redirected_name, name, expr, void, INIT_ARCH)
> +
> +/* Use libc_ifunc_hidden if your ifunc'ed function has an internal symbol
> +   which should be the ifunc'ed function'.  */
> +#define libc_ifunc_hidden(redirected_name, name, expr)			\
> +  __ifunc_hidden (redirected_name, name, expr, void, INIT_ARCH)
>  
>  /* The body of the function is supposed to use __get_cpu_features
>     which will, if necessary, initialize the data first.  */
> -#define libm_ifunc(name, expr)						\
> -  extern void *name##_ifunc (void) __asm__ (#name);			\
> -  void *name##_ifunc (void)						\
> -  {									\
> -    __typeof (name) *res = expr;					\
> -    return res;								\
> -  }									\
> -  __asm__ (".type " #name ", %gnu_indirect_function");
> +#define libm_ifunc_init()
> +#define libm_ifunc(name, expr) __ifunc (name, name, expr, void, libm_ifunc_init)

Line too long.

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 2/9] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-09-29 18:38   ` Adhemerval Zanella
@ 2016-09-30 13:45     ` Stefan Liebler
  2016-10-04 13:14       ` Adhemerval Zanella
  0 siblings, 1 reply; 27+ messages in thread
From: Stefan Liebler @ 2016-09-30 13:45 UTC (permalink / raw)
  To: libc-alpha

[-- Attachment #1: Type: text/plain, Size: 4964 bytes --]

Hi Adhemerval,

thanks for reviewing. I've split the too long lines and added a comment 
block for libc_ifunc{_redirected,_hidden} macros in include/libc-symbols.h.

Yes you are right, review for patch 9 is still missing. I've tested the 
s390 part on s390x/s390. If patch 9 is okay, I'll commit the patch series.

Thanks.
Stefan

On 09/29/2016 08:38 PM, Adhemerval Zanella wrote:
> Patch LGTM and a powerpc32/power7 (to actually uses ifunc) and a build/run
> for powerpc64le seems ok.
>
> I see with recent Andreas ack of 4/9 that only 3/9 (s390 bits) and
> 9/9 (siglongjmp, longjmp in libpthread) seems to be the impending
> bits.  I plan to check on 9/9, but I won't be able to proper review
> 3/9 since I do not have access to a s390 machine anymore.
>
> Some comments below:
>
> On 24/08/2016 07:04, Stefan Liebler wrote:
>> diff --git a/include/libc-symbols.h b/include/libc-symbols.h
>> index c2b499a..44e5253 100644
>> --- a/include/libc-symbols.h
>> +++ b/include/libc-symbols.h
>> @@ -722,27 +722,64 @@ for linking")
>>  # define compat_data_section .section ".data.compat", "aw";
>>  #endif
>>
>> -/* Marker used for indirection function symbols.  */
>> -#define libc_ifunc(name, expr)						\
>> -  extern void *name##_ifunc (void) __asm__ (#name);			\
>> -  void *name##_ifunc (void)						\
>> +/* Helper / base  macros for indirect function symbols.  */
>> +#define __ifunc_resolver(type_name, name, expr, arg, init, classifier)	\
>> +  classifier void *name##_ifunc (arg)					\
>>    {									\
>> -    INIT_ARCH ();							\
>> -    __typeof (name) *res = expr;					\
>> +    init ();								\
>> +    __typeof (type_name) *res = expr;					\
>>      return res;								\
>> -  }									\
>> -  __asm__ (".type " #name ", %gnu_indirect_function");
>> +  }
>> +
>> +#ifdef HAVE_GCC_IFUNC
>> +# define __ifunc(type_name, name, expr, arg, init)			\
>> +  extern __typeof (type_name) name __attribute__			\
>> +			      ((ifunc (#name "_ifunc")));		\
>> +  __ifunc_resolver (type_name, name, expr, arg, init, static)
>> +
>> +# define __ifunc_hidden(type_name, name, expr, arg, init)	\
>> +  __ifunc (type_name, name, expr, arg, init)
>> +#else
>> +/* Gcc does not support __attribute__ ((ifunc (...))).  Use the old behaviour
>> +   as fallback.  But keep in mind that the debug information for the ifunc
>> +   resolver functions is not correct.  It contains the ifunc'ed function as
>> +   DW_AT_linkage_name.  E.g. lldb uses this field and an inferior function
>> +   call of the ifunc'ed function will fail due to "no matching function for call
>
> Line too long.
>
>> +   to ..." because the ifunc'ed function and the resolver function have
>> +   different signatures.  (Gcc support is disabled at least on a ppc64le
>> +   Ubuntu 14.04 system.)  */
>> +
>> +# define __ifunc(type_name, name, expr, arg, init)			\
>> +  extern __typeof (type_name) name;					\
>> +  void *name##_ifunc (arg) __asm__ (#name);				\
>> +  __ifunc_resolver (type_name, name, expr, arg, init,)			\
>> + __asm__ (".type " #name ", %gnu_indirect_function");
>> +
>> +# define __ifunc_hidden(type_name, name, expr, arg, init)		\
>> +  extern __typeof (type_name) __libc_##name;				\
>> +  __ifunc (type_name, __libc_##name, expr, arg, init)			\
>> +  strong_alias (__libc_##name, name);
>> +#endif /* !HAVE_GCC_IFUNC  */
>> +
>> +/* Use libc_ifunc if your ifunc'ed function has no internal symbol.  */
>> +#define libc_ifunc(name, expr) __ifunc (name, name, expr, void, INIT_ARCH)
>
> I think it will be valuable to add a comment like the one on same
> file at line 341 with a usage example on how to use
> libc_ifunc{_redirected,_hidden} and difference between each usage and
> the possible requirements (such as name redirection).
>
>> +
>> +/* Use libc_ifunc_redirected if your ifunc'ed function has an internal symbol
>> +   which should be a dedicated fallback function instead of ifunc'ed.
>> +   You have to redirect the function in the header file and use it as
>> +   redirected_name.  */
>> +#define libc_ifunc_redirected(redirected_name, name, expr)	\
>> +  __ifunc (redirected_name, name, expr, void, INIT_ARCH)
>> +
>> +/* Use libc_ifunc_hidden if your ifunc'ed function has an internal symbol
>> +   which should be the ifunc'ed function'.  */
>> +#define libc_ifunc_hidden(redirected_name, name, expr)			\
>> +  __ifunc_hidden (redirected_name, name, expr, void, INIT_ARCH)
>>
>>  /* The body of the function is supposed to use __get_cpu_features
>>     which will, if necessary, initialize the data first.  */
>> -#define libm_ifunc(name, expr)						\
>> -  extern void *name##_ifunc (void) __asm__ (#name);			\
>> -  void *name##_ifunc (void)						\
>> -  {									\
>> -    __typeof (name) *res = expr;					\
>> -    return res;								\
>> -  }									\
>> -  __asm__ (".type " #name ", %gnu_indirect_function");
>> +#define libm_ifunc_init()
>> +#define libm_ifunc(name, expr) __ifunc (name, name, expr, void, libm_ifunc_init)
>
> Line too long.
>


[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 20160930_2.patch --]
[-- Type: text/x-patch; name="20160930_2.patch", Size: 59834 bytes --]

commit 9e95c428798b86f8bf0c7c1eaf8434266220f1ab
Author: Stefan Liebler <stli@linux.vnet.ibm.com>
Date:   Wed Aug 24 10:18:14 2016 +0200

    Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
    
    The current s390 ifunc resolver for vector optimized functions and the common
    libc_ifunc macro in include/libc-symbols.h uses something like that to generate ifunc'ed functions:
    extern void *__resolve___strlen(unsigned long int dl_hwcap) asm (strlen);
    asm (".type strlen, %gnu_indirect_function");
    
    This leads to false debug information:
    objdump --dwarf=info libc.so:
    ...
    <1><1e6424>: Abbrev Number: 43 (DW_TAG_subprogram)
        <1e6425>   DW_AT_external    : 1
        <1e6425>   DW_AT_name        : (indirect string, offset: 0x1146e): __resolve___strlen
        <1e6429>   DW_AT_decl_file   : 1
        <1e642a>   DW_AT_decl_line   : 23
        <1e642b>   DW_AT_linkage_name: (indirect string, offset: 0x1147a): strlen
        <1e642f>   DW_AT_prototyped  : 1
        <1e642f>   DW_AT_type        : <0x1e4ccd>
        <1e6433>   DW_AT_low_pc      : 0x998e0
        <1e643b>   DW_AT_high_pc     : 0x16
        <1e6443>   DW_AT_frame_base  : 1 byte block: 9c     (DW_OP_call_frame_cfa)
        <1e6445>   DW_AT_GNU_all_call_sites: 1
        <1e6445>   DW_AT_sibling     : <0x1e6459>
     <2><1e6449>: Abbrev Number: 44 (DW_TAG_formal_parameter)
        <1e644a>   DW_AT_name        : (indirect string, offset: 0x1845): dl_hwcap
        <1e644e>   DW_AT_decl_file   : 1
        <1e644f>   DW_AT_decl_line   : 23
        <1e6450>   DW_AT_type        : <0x1e4c8d>
        <1e6454>   DW_AT_location    : 0x122115 (location list)
    ...
    
    The debuginfo for the ifunc-resolver function contains the DW_AT_linkage_name
    field, which names the real function name "strlen". If you perform an inferior
    function call to strlen in lldb, then it fails due to something like that:
    "error: no matching function for call to 'strlen'
    candidate function not viable: no known conversion from 'const char [6]'
    to 'unsigned long' for 1st argument"
    
    The unsigned long is the dl_hwcap argument of the resolver function.
    The strlen function itself has no debufinfo.
    
    The s390 ifunc resolver for memset & co uses something like that:
    asm (".globl FUNC"
         ".type FUNC, @gnu_indirect_function"
         ".set FUNC, __resolve_FUNC");
    
    This way the debuginfo for the ifunc-resolver function does not conain the
    DW_AT_linkage_name field and the real function has no debuginfo, too.
    
    Using this strategy for the vector optimized functions leads to some troubles
    for functions like strnlen. Here we have __strnlen and a weak alias strnlen.
    The __strnlen function is the ifunc function, which is realized with the asm-
    statement above. The weak_alias-macro can't be used here due to undefined symbol:
    gcc ../sysdeps/s390/multiarch/strnlen.c -c ...
    In file included from <command-line>:0:0:
    ../sysdeps/s390/multiarch/strnlen.c:28:24: error: ‘strnlen’ aliased to undefined symbol ‘__strnlen’
     weak_alias (__strnlen, strnlen)
                            ^
    ./../include/libc-symbols.h:111:26: note: in definition of macro ‘_weak_alias’
       extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)));
                              ^
    ../sysdeps/s390/multiarch/strnlen.c:28:1: note: in expansion of macro ‘weak_alias’
     weak_alias (__strnlen, strnlen)
     ^
    make[2]: *** [build/string/strnlen.o] Error 1
    
    As the __strnlen function is defined with asm-statements the function name
    __strnlen isn't known by gcc. But the weak alias can also be done with an
    asm statement to resolve this issue:
    __asm__ (".weak  strnlen\n\t"
             ".set   strnlen,__strnlen\n");
    
    In order to use the weak_alias macro, gcc needs to know the ifunc function. The
    minimum gcc to build glibc is currently 4.7, which supports attribute((ifunc)).
    See https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html.
    It is only supported if gcc is configured with --enable-gnu-indirect-function
    or gcc supports it by default for at least intel and s390x architecture.
    This patch uses the old behaviour if gcc support is not available.
    Usage of attribute ifunc is something like that:
    __typeof (FUNC) FUNC __attribute__ ((ifunc ("__resolve_FUNC")));
    
    Then gcc produces the same .globl, .type, .set assembler instructions like above.
    And the debuginfo does not contain the DW_AT_linkage_name field and there is no
    debuginfo for the real function, too.
    
    But in order to get it work, there is also some extra work to do.
    Currently, the glibc internal symbol on s390x e.g. __GI___strnlen is not the
    ifunc symbol, but the fallback __strnlen_c symbol. Thus I have to omit the
    libc_hidden_def macro in strnlen.c (here is the ifunc function __strnlen)
    because it is already handled in strnlen-c.c (here is __strnlen_c).
    
    Due to libc_hidden_proto (__strnlen) in string.h, compiling fails:
    gcc ../sysdeps/s390/multiarch/strnlen.c -c ...
    In file included from <command-line>:0:0:
    ../sysdeps/s390/multiarch/strnlen.c:53:24: error: ‘strnlen’ aliased to undefined symbol ‘__strnlen’
     weak_alias (__strnlen, strnlen)
                            ^
    ./../include/libc-symbols.h:111:26: note: in definition of macro ‘_weak_alias’
       extern __typeof (name) aliasname __attribute__ ((weak, alias (#name)));
                              ^
    ../sysdeps/s390/multiarch/strnlen.c:53:1: note: in expansion of macro ‘weak_alias’
     weak_alias (__strnlen, strnlen)
     ^
    make[2]: *** [build/string/strnlen.os] Error 1
    
    I have to redirect the prototypes for __strnlen in string.h and create a copy
    of the prototype for using as ifunc function:
    __typeof (__redirect___strnlen) __strnlen __attribute__ ((ifunc ("__resolve_strnlen")));
    weak_alias (__strnlen, strnlen)
    
    This way there is no trouble with the internal __GI_* symbols.
    Glibc builds fine with this construct and the debuginfo is "correct".
    For functions without a __GI_* symbol like memccpy this redirection is not needed.
    
    This patch adjusts the common libc_ifunc and libm_ifunc macro to use gcc
    attribute ifunc. Due to this change, the macro users where the __GI_* symbol
    does not target the ifunc symbol have to be prepared with the redirection
    construct.
    Furthermore a configure check to test gcc support is added. If it is not supported,
    the old behaviour is used.
    
    This patch also prepares the libc_ifunc macro to be useable in s390-ifunc-macro.
    The s390 ifunc-resolver-functions do have an hwcaps parameter and not all
    resolvers need the same initialization code. The next patch in this series
    changes the s390 ifunc macros to use this common one.
    
    ChangeLog:
    
    	* include/libc-symbols.h (__ifunc_resolver):
    	New macro is used by __ifunc* macros.
    	(__ifunc): New macro uses gcc attribute ifunc or inline assembly
    	depending on HAVE_GCC_IFUNC.
    	(libc_ifunc, libm_ifunc): Use __ifunc as base macro.
    	(libc_ifunc_redirected, libc_ifunc_hidden, libm_ifunc_init): New macro.
    	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c:
    	Redirect ifunced function in header for using as type for ifunc function.
    	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c: Likewise.
    	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c: Likewise.
    	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c: Likewise.
    	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c: Likewise.
    	* sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c: Likewise.
    	* sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c: Likewise.
    	* sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c: Likewise.
    	* sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c: Likewise.
    	* sysdeps/powerpc/powerpc32/power4/multiarch/memset.c: Likewise.
    	* sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c: Likewise.
    	* sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c: Likewise.
    	* sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c: Likewise.
    	* sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c: Likewise.
    	* sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c: Likewise.
    	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c: Likewise.
    	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c: Likewise.
    	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c: Likewise.
    	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c: Likewise.
    	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c: Likewise.
    	* sysdeps/powerpc/powerpc64/multiarch/memcmp.c: Likewise.
    	* sysdeps/powerpc/powerpc64/multiarch/mempcpy.c: Likewise.
    	* sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c: Likewise.
    	* sysdeps/powerpc/powerpc64/multiarch/stpncpy.c: Likewise.
    	* sysdeps/powerpc/powerpc64/multiarch/strcat.c: Likewise.
    	* sysdeps/powerpc/powerpc64/multiarch/strchr.c: Likewise.
    	* sysdeps/powerpc/powerpc64/multiarch/strcmp.c: Likewise.
    	* sysdeps/powerpc/powerpc64/multiarch/strcpy.c: Likewise.
    	* sysdeps/powerpc/powerpc64/multiarch/strncmp.c: Likewise.
    	* sysdeps/powerpc/powerpc64/multiarch/strncpy.c: Likewise.
    	* sysdeps/powerpc/powerpc64/multiarch/strnlen.c: Likewise.
    	* sysdeps/powerpc/powerpc64/multiarch/strrchr.c: Likewise.
    	* sysdeps/powerpc/powerpc64/multiarch/strstr.c: Likewise.
    	* sysdeps/powerpc/powerpc64/multiarch/wcschr.c: Likewise.
    	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c:
    	Add libc_hidden_def() and use libc_ifunc_hidden() macro
    	instead of libc_ifunc() macro.
    	* sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c: Likewise.
    	* sysdeps/powerpc/powerpc64/multiarch/stpcpy.c: Likewise.

diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index e362d42..6ae309a 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -737,27 +737,137 @@ for linking")
 # define compat_data_section .section ".data.compat", "aw";
 #endif
 
-/* Marker used for indirection function symbols.  */
-#define libc_ifunc(name, expr)						\
-  extern void *name##_ifunc (void) __asm__ (#name);			\
-  void *name##_ifunc (void)						\
+/* Helper / base  macros for indirect function symbols.  */
+#define __ifunc_resolver(type_name, name, expr, arg, init, classifier)	\
+  classifier void *name##_ifunc (arg)					\
   {									\
-    INIT_ARCH ();							\
-    __typeof (name) *res = expr;					\
+    init ();								\
+    __typeof (type_name) *res = expr;					\
     return res;								\
-  }									\
-  __asm__ (".type " #name ", %gnu_indirect_function");
+  }
+
+#ifdef HAVE_GCC_IFUNC
+# define __ifunc(type_name, name, expr, arg, init)			\
+  extern __typeof (type_name) name __attribute__			\
+			      ((ifunc (#name "_ifunc")));		\
+  __ifunc_resolver (type_name, name, expr, arg, init, static)
+
+# define __ifunc_hidden(type_name, name, expr, arg, init)	\
+  __ifunc (type_name, name, expr, arg, init)
+#else
+/* Gcc does not support __attribute__ ((ifunc (...))).  Use the old behaviour
+   as fallback.  But keep in mind that the debug information for the ifunc
+   resolver functions is not correct.  It contains the ifunc'ed function as
+   DW_AT_linkage_name.  E.g. lldb uses this field and an inferior function
+   call of the ifunc'ed function will fail due to "no matching function for
+   call to ..." because the ifunc'ed function and the resolver function have
+   different signatures.  (Gcc support is disabled at least on a ppc64le
+   Ubuntu 14.04 system.)  */
+
+# define __ifunc(type_name, name, expr, arg, init)			\
+  extern __typeof (type_name) name;					\
+  void *name##_ifunc (arg) __asm__ (#name);				\
+  __ifunc_resolver (type_name, name, expr, arg, init,)			\
+ __asm__ (".type " #name ", %gnu_indirect_function");
+
+# define __ifunc_hidden(type_name, name, expr, arg, init)		\
+  extern __typeof (type_name) __libc_##name;				\
+  __ifunc (type_name, __libc_##name, expr, arg, init)			\
+  strong_alias (__libc_##name, name);
+#endif /* !HAVE_GCC_IFUNC  */
+
+/* The following macros are used for indirect function symbols in libc.so.
+   First of all, you need to have the function prototyped somewhere,
+   say in foo.h:
+
+   int foo (int __bar);
+
+   If you have an implementation for foo which e.g. uses a special hardware
+   feature which isn't available on all machines where this libc.so will be
+   used but decideable if available at runtime e.g. via hwcaps, you can provide
+   two or multiple implementations of foo:
+
+   int __foo_default (int __bar)
+   {
+     return __bar;
+   }
+
+   int __foo_special (int __bar)
+   {
+     return __bar;
+   }
+
+   If your function foo has no libc_hidden_proto (foo) defined for PLT
+   bypassing, you can use:
+
+   #define INIT_ARCH() unsigned long int hwcap = __GLRO(dl_hwcap);
+
+   libc_ifunc (foo, (hwcap & HWCAP_SPECIAL) ? __foo_special : __foo_default);
+
+   This will define a resolver function for foo which returns __foo_special or
+   __foo_default depending on your specified expression.  Please note that you
+   have to define a macro function INIT_ARCH before using libc_ifunc macro as
+   it is called by the resolver function before evaluating the specified
+   expression.  In this example it is used to prepare the hwcap variable.
+   The resolver function is assigned to an ifunc'ed symbol foo.  Calls to foo
+   from inside or outside of libc.so will be indirected by a PLT call.
+
+   If your function foo has a libc_hidden_proto (foo) defined for PLT bypassing
+   and calls to foo within libc.so should always go to one specific
+   implementation of foo e.g. __foo_default then you have to add:
+
+   __hidden_ver1 (__foo_default, __GI_foo, __foo_default);
+
+   or a tweaked definition of libc_hidden_def macro after the __foo_default
+   function definition.  Calls to foo within libc.so will always go directly to
+   __foo_default.  Calls to foo from outside libc.so will be indirected by a
+   PLT call to ifunc'ed symbol foo which you have to define in a separate
+   compile unit:
+
+   #define foo __redirect_foo
+   #include <foo.h>
+   #undef foo
+
+   extern __typeof (__redirect_foo) __foo_default attribute_hidden;
+   extern __typeof (__redirect_foo) __foo_special attribute_hidden;
+
+   libc_ifunc_redirected (__redirect_foo, foo,
+			  (hwcap & HWCAP_SPECIAL)
+			  ? __foo_special
+			  : __foo_default);
+
+   This will define the ifunc'ed symbol foo like above.  The redirection of foo
+   in header file is needed to omit an additional defintion of __GI_foo which
+   would end in a linker error while linking libc.so.  You have to specify
+   __redirect_foo as first parameter which is used within libc_ifunc_redirected
+   macro in conjunction with typeof to define the ifunc'ed symbol foo.
+
+   If your function foo has a libc_hidden_proto (foo) defined and calls to foo
+   within or from outside libc.so should go via ifunc'ed symbol, then you have
+   to use:
+
+   libc_ifunc_hidden (foo, foo,
+		      (hwcap & HWCAP_SPECIAL)
+		      ? __foo_special
+		      : __foo_default);
+   libc_hidden_def (foo)
+
+   The first parameter foo of libc_ifunc_hidden macro is used in the same way
+   as for libc_ifunc_redirected macro.  */
+
+#define libc_ifunc(name, expr) __ifunc (name, name, expr, void, INIT_ARCH)
+
+#define libc_ifunc_redirected(redirected_name, name, expr)	\
+  __ifunc (redirected_name, name, expr, void, INIT_ARCH)
+
+#define libc_ifunc_hidden(redirected_name, name, expr)			\
+  __ifunc_hidden (redirected_name, name, expr, void, INIT_ARCH)
 
 /* The body of the function is supposed to use __get_cpu_features
    which will, if necessary, initialize the data first.  */
-#define libm_ifunc(name, expr)						\
-  extern void *name##_ifunc (void) __asm__ (#name);			\
-  void *name##_ifunc (void)						\
-  {									\
-    __typeof (name) *res = expr;					\
-    return res;								\
-  }									\
-  __asm__ (".type " #name ", %gnu_indirect_function");
+#define libm_ifunc_init()
+#define libm_ifunc(name, expr)				\
+  __ifunc (name, name, expr, void, libm_ifunc_init)
 
 #ifdef HAVE_ASM_SET_DIRECTIVE
 # define libc_ifunc_hidden_def1(local, name)				\
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c
index c860a1b..0c0d128 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c
@@ -16,6 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __finite __redirect___finite
+#define __finitef __redirect___finitef
+#define __finitel __redirect___finitel
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -23,11 +26,14 @@
 
 extern __typeof (__finite) __finite_ppc32 attribute_hidden;
 extern __typeof (__finite) __finite_power7 attribute_hidden;
-
-libc_ifunc (__finite,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __finite_power7
-            : __finite_ppc32);
+#undef __finite
+#undef __finitef
+#undef __finitel
+
+libc_ifunc_redirected (__redirect___finite,  __finite,
+		       (hwcap & PPC_FEATURE_ARCH_2_06)
+		       ? __finite_power7
+		       : __finite_ppc32);
 
 weak_alias (__finite, finite)
 
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c
index 831c94f..683477a 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c
@@ -16,6 +16,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __finitef __redirect___finitef
 #include <math.h>
 #include <shlib-compat.h>
 #include "init-arch.h"
@@ -23,10 +24,11 @@
 extern __typeof (__finitef) __finitef_ppc32 attribute_hidden;
 /* The power7 finite(double) works for float.  */
 extern __typeof (__finitef) __finite_power7 attribute_hidden;
+#undef __finitef
 
-libc_ifunc (__finitef,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __finite_power7
-            : __finitef_ppc32);
+libc_ifunc_redirected  (__redirect___finitef, __finitef,
+			(hwcap & PPC_FEATURE_ARCH_2_06)
+			? __finite_power7
+			: __finitef_ppc32);
 
 weak_alias (__finitef, finitef)
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c
index 506c111..fe6c912 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinf.c
@@ -16,6 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __isinf __redirect___isinf
+#define __isinff __redirect___isinff
+#define __isinfl __redirect___isinfl
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -23,11 +26,14 @@
 
 extern __typeof (__isinf) __isinf_ppc32 attribute_hidden;
 extern __typeof (__isinf) __isinf_power7 attribute_hidden;
-
-libc_ifunc (__isinf,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __isinf_power7
-            : __isinf_ppc32);
+#undef __isinf
+#undef __isinff
+#undef __isinfl
+
+libc_ifunc_redirected (__redirect___isinf,  __isinf,
+		       (hwcap & PPC_FEATURE_ARCH_2_06)
+		       ? __isinf_power7
+		       : __isinf_ppc32);
 
 weak_alias (__isinf, isinf)
 
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c
index 2ab83ee..1706092 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c
@@ -16,6 +16,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __isinff __redirect___isinff
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -24,10 +25,11 @@
 extern __typeof (__isinff) __isinff_ppc32 attribute_hidden;
 /* The power7 isinf(double) works for float.  */
 extern __typeof (__isinff) __isinf_power7 attribute_hidden;
+#undef __isinff
 
-libc_ifunc (__isinff,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __isinf_power7
-            : __isinff_ppc32);
+libc_ifunc_redirected (__redirect___isinff,  __isinff,
+		       (hwcap & PPC_FEATURE_ARCH_2_06)
+		       ? __isinf_power7
+		       : __isinff_ppc32);
 
 weak_alias (__isinff, isinff)
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c
index 8f848d7..3655b81 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnan.c
@@ -16,6 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __isnan __redirect___isnan
+#define __isnanf __redirect___isnanf
+#define __isnanl __redirect___isnanl
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -25,15 +28,18 @@ extern __typeof (__isnan) __isnan_ppc32 attribute_hidden;
 extern __typeof (__isnan) __isnan_power5 attribute_hidden;
 extern __typeof (__isnan) __isnan_power6 attribute_hidden;
 extern __typeof (__isnan) __isnan_power7 attribute_hidden;
-
-libc_ifunc (__isnan,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __isnan_power7 :
-	      (hwcap & PPC_FEATURE_ARCH_2_05)
-	      ? __isnan_power6 :
-		(hwcap & PPC_FEATURE_POWER5)
-		? __isnan_power5
-            : __isnan_ppc32);
+#undef __isnan
+#undef __isnanf
+#undef __isnanl
+
+libc_ifunc_redirected (__redirect___isnan, __isnan,
+		       (hwcap & PPC_FEATURE_ARCH_2_06)
+		       ? __isnan_power7
+		       : (hwcap & PPC_FEATURE_ARCH_2_05)
+			 ? __isnan_power6
+			 : (hwcap & PPC_FEATURE_POWER5)
+			   ? __isnan_power5
+			   : __isnan_ppc32);
 
 weak_alias (__isnan, isnan)
 
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
index c43c0f3..e1d6707 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
@@ -26,13 +26,14 @@ extern __typeof (__isnanf) __isnanf_power5 attribute_hidden;
 extern __typeof (__isnanf) __isnanf_power6 attribute_hidden;
 extern __typeof (__isnanf) __isnan_power7 attribute_hidden;
 
-libc_ifunc (__isnanf,
-	    (hwcap & PPC_FEATURE_ARCH_2_06)
-	    ? __isnan_power7 :
-	      (hwcap & PPC_FEATURE_ARCH_2_05)
-	      ? __isnanf_power6 :
-		(hwcap & PPC_FEATURE_POWER5)
-		? __isnanf_power5
-            : __isnan_ppc32);
+libc_ifunc_hidden (__isnanf, __isnanf,
+		   (hwcap & PPC_FEATURE_ARCH_2_06)
+		   ? __isnan_power7
+		   : (hwcap & PPC_FEATURE_ARCH_2_05)
+		     ? __isnanf_power6
+		     : (hwcap & PPC_FEATURE_POWER5)
+		       ? __isnanf_power5
+		       : __isnan_ppc32);
 
+hidden_def (__isnanf)
 weak_alias (__isnanf, isnanf)
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c
index c08519c..49d424f 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c
@@ -18,17 +18,19 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if IS_IN (libc)
+# define memcmp __redirect_memcmp
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (memcmp) __memcmp_ppc attribute_hidden;
 extern __typeof (memcmp) __memcmp_power7 attribute_hidden;
+# undef memcmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memcmp,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __memcmp_power7
-            : __memcmp_ppc);
+libc_ifunc_redirected (__redirect_memcmp, memcmp,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __memcmp_power7
+		       : __memcmp_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c
index f379e47..1a5da21 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c
@@ -20,6 +20,8 @@
    DSO.  In static binaries we need memcpy before the initialization
    happened.  */
 #if defined SHARED && IS_IN (libc)
+# undef memcpy
+# define memcpy __redirect_memcpy
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -29,17 +31,18 @@ extern __typeof (memcpy) __memcpy_cell attribute_hidden;
 extern __typeof (memcpy) __memcpy_power6 attribute_hidden;
 extern __typeof (memcpy) __memcpy_a2 attribute_hidden;
 extern __typeof (memcpy) __memcpy_power7 attribute_hidden;
+# undef memcpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memcpy,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __memcpy_power7 :
-	      (hwcap & PPC_FEATURE_ARCH_2_06)
-	      ? __memcpy_a2 :
-		(hwcap & PPC_FEATURE_ARCH_2_05)
-		? __memcpy_power6 :
-		  (hwcap & PPC_FEATURE_CELL_BE)
-		  ? __memcpy_cell
-            : __memcpy_ppc);
+libc_ifunc_redirected (__redirect_memcpy, memcpy,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __memcpy_power7
+		       : (hwcap & PPC_FEATURE_ARCH_2_06)
+			 ? __memcpy_a2
+			 : (hwcap & PPC_FEATURE_ARCH_2_05)
+			   ? __memcpy_power6
+			   : (hwcap & PPC_FEATURE_CELL_BE)
+			     ? __memcpy_cell
+			     : __memcpy_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
index 4173184..1dfb5be 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
@@ -19,16 +19,18 @@
 #if defined SHARED && IS_IN (libc)
 /* Redefine memmove so that the compiler won't complain about the type
    mismatch with the IFUNC selector in strong_alias, below.  */
+# define memmove __redirect_memmove
 # include <string.h>
 # include "init-arch.h"
 
 extern __typeof (memmove) __memmove_ppc attribute_hidden;
 extern __typeof (memmove) __memmove_power7 attribute_hidden;
+# undef memmove
 
-libc_ifunc (memmove,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __memmove_power7
-            : __memmove_ppc);
+libc_ifunc_redirected (__redirect_memmove, memmove,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __memmove_power7
+		       : __memmove_ppc);
 #else
 # include <string/memmove.c>
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c b/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c
index 3c77b5f..3c7c644 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c
@@ -17,23 +17,28 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define mempcpy __redirect_mempcpy
+# define __mempcpy __redirect___mempcpy
 # define NO_MEMPCPY_STPCPY_REDIRECT
+/* Omit the mempcpy inline definitions because it would redefine mempcpy.  */
+# define _HAVE_STRING_ARCH_mempcpy 1
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (__mempcpy) __mempcpy_ppc attribute_hidden;
 extern __typeof (__mempcpy) __mempcpy_power7 attribute_hidden;
+# undef mempcpy
+# undef __mempcpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__mempcpy,
-	    (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __mempcpy_power7
-            : __mempcpy_ppc);
+libc_ifunc_redirected (__redirect___mempcpy,  __mempcpy,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __mempcpy_power7
+		       : __mempcpy_ppc);
 
 weak_alias (__mempcpy, mempcpy)
-libc_hidden_def (mempcpy)
 #else
 # include <string/mempcpy.c>
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memset.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memset.c
index 1d7fc7f..a5c0142 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memset.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memset.c
@@ -18,6 +18,7 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if defined SHARED && IS_IN (libc)
+# define memset __redirect_memset
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -25,13 +26,14 @@
 extern __typeof (memset) __memset_ppc attribute_hidden;
 extern __typeof (memset) __memset_power6 attribute_hidden;
 extern __typeof (memset) __memset_power7 attribute_hidden;
+# undef memset
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memset,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __memset_power7 :
-	      (hwcap & PPC_FEATURE_ARCH_2_05)
-		? __memset_power6
-            : __memset_ppc);
+libc_ifunc_redirected (__redirect_memset, memset,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __memset_power7
+		       : (hwcap & PPC_FEATURE_ARCH_2_05)
+			 ? __memset_power6
+			 : __memset_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c b/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
index f06030e..d72b5df 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
@@ -17,20 +17,21 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define __rawmemchr __redirect___rawmemchr
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (__rawmemchr) __rawmemchr_ppc attribute_hidden;
 extern __typeof (__rawmemchr) __rawmemchr_power7 attribute_hidden;
+# undef __rawmemchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__rawmemchr,
-	    (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __rawmemchr_power7
-            : __rawmemchr_ppc);
-
+libc_ifunc_redirected (__redirect___rawmemchr, __rawmemchr,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __rawmemchr_power7
+		       : __rawmemchr_ppc);
 weak_alias (__rawmemchr, rawmemchr)
 #else
 #include <string/rawmemchr.c>
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
index 2cfde63..c23384f 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
@@ -18,18 +18,22 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if defined SHARED && IS_IN (libc)
+# define strchr __redirect_strchr
+/* Omit the strchr inline definitions because it would redefine strchr.  */
+# define __NO_STRING_INLINES
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (strchr) __strchr_ppc attribute_hidden;
 extern __typeof (strchr) __strchr_power7 attribute_hidden;
+# undef strchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strchr,
-	    (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strchr_power7
-            : __strchr_ppc);
+libc_ifunc_redirected (__redirect_strchr,  strchr,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strchr_power7
+		       : __strchr_ppc);
 weak_alias (strchr, index)
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
index af5921a..b676b26 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
@@ -17,15 +17,17 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined SHARED && IS_IN (libc)
+# define strlen __redirect_strlen
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (strlen) __strlen_ppc attribute_hidden;
 extern __typeof (strlen) __strlen_power7 attribute_hidden;
+# undef strlen
 
-libc_ifunc (strlen,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strlen_power7
-            : __strlen_ppc);
+libc_ifunc_redirected (__redirect_strlen, strlen,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strlen_power7
+		       : __strlen_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c
index 7cc7628..c384b4c 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c
@@ -18,6 +18,9 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if defined SHARED && IS_IN (libc)
+# define strncmp __redirect_strncmp
+/* Omit the strncmp inline definitions because it would redefine strncmp.  */
+# define __NO_STRING_INLINES
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -25,11 +28,12 @@
 extern __typeof (strncmp) __strncmp_ppc attribute_hidden;
 extern __typeof (strncmp) __strncmp_power4 attribute_hidden;
 extern __typeof (strncmp) __strncmp_power7 attribute_hidden;
+# undef strncmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strncmp,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strncmp_power7
-            : __strncmp_ppc);
+libc_ifunc_redirected (__redirect_strncmp, strncmp,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strncmp_power7
+		       : __strncmp_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
index 8f1e7c9..c3681be 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
@@ -17,17 +17,20 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define strnlen __redirect_strnlen
+# define __strnlen __redirect___strnlen
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (__strnlen) __strnlen_ppc attribute_hidden;
 extern __typeof (__strnlen) __strnlen_power7 attribute_hidden;
+# undef strnlen
+# undef __strnlen
 
-libc_ifunc (__strnlen,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strnlen_power7
-            : __strnlen_ppc);
+libc_ifunc_redirected (__redirect___strnlen, __strnlen,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strnlen_power7
+		       : __strnlen_ppc);
 weak_alias (__strnlen, strnlen)
-libc_hidden_def (strnlen)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
index 067edc2..c7d67f1 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
@@ -16,6 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __finite __redirect___finite
+#define __finitef __redirect___finitef
+#define __finitel __redirect___finitel
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -24,13 +27,16 @@
 extern __typeof (__finite) __finite_ppc64 attribute_hidden;
 extern __typeof (__finite) __finite_power7 attribute_hidden;
 extern __typeof (__finite) __finite_power8 attribute_hidden;
-
-libc_ifunc (__finite,
-	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-	    ? __finite_power8 :
-	      (hwcap & PPC_FEATURE_ARCH_2_06)
-	      ? __finite_power7
-            : __finite_ppc64);
+#undef __finite
+#undef __finitef
+#undef __finitel
+
+libc_ifunc_redirected (__redirect___finite, __finite,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __finite_power8
+		       : (hwcap & PPC_FEATURE_ARCH_2_06)
+			 ? __finite_power7
+			 : __finite_ppc64);
 
 weak_alias (__finite, finite)
 
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
index e0b4686..c9ecd0d 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
@@ -16,6 +16,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __finitef __redirect___finitef
 #include <math.h>
 #include <shlib-compat.h>
 #include "init-arch.h"
@@ -24,12 +25,13 @@ extern __typeof (__finitef) __finitef_ppc64 attribute_hidden;
 /* The double-precision version also works for single-precision.  */
 extern __typeof (__finitef) __finite_power7 attribute_hidden;
 extern __typeof (__finitef) __finite_power8 attribute_hidden;
+#undef __finitef
 
-libc_ifunc (__finitef,
-	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-	    ? __finite_power8 :
-	      (hwcap & PPC_FEATURE_ARCH_2_06)
-	      ? __finite_power7
-            : __finitef_ppc64);
+libc_ifunc_redirected (__redirect___finitef, __finitef,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __finite_power8
+		       : (hwcap & PPC_FEATURE_ARCH_2_06)
+			 ? __finite_power7
+			 : __finitef_ppc64);
 
 weak_alias (__finitef, finitef)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
index 07e159d..a13ec27 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
@@ -16,6 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __isinf __redirect___isinf
+#define __isinff __redirect___isinff
+#define __isinfl __redirect___isinfl
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -24,13 +27,16 @@
 extern __typeof (__isinf) __isinf_ppc64 attribute_hidden;
 extern __typeof (__isinf) __isinf_power7 attribute_hidden;
 extern __typeof (__isinf) __isinf_power8 attribute_hidden;
-
-libc_ifunc (__isinf,
-	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-	    ? __isinf_power8 :
-	      (hwcap & PPC_FEATURE_ARCH_2_06)
-	      ? __isinf_power7
-            : __isinf_ppc64);
+#undef __isinf
+#undef __isinff
+#undef __isinfl
+
+libc_ifunc_redirected (__redirect___isinf, __isinf,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __isinf_power8
+		       : (hwcap & PPC_FEATURE_ARCH_2_06)
+			 ? __isinf_power7
+			 : __isinf_ppc64);
 
 weak_alias (__isinf, isinf)
 
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
index 2cb161b..cafc118 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
@@ -16,6 +16,7 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __isinff __redirect___isinff
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -25,12 +26,13 @@ extern __typeof (__isinff) __isinff_ppc64 attribute_hidden;
 /* The double-precision version also works for single-precision.  */
 extern __typeof (__isinff) __isinf_power7 attribute_hidden;
 extern __typeof (__isinff) __isinf_power8 attribute_hidden;
+#undef __isinff
 
-libc_ifunc (__isinff,
-	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-	    ? __isinf_power8 :
-	      (hwcap & PPC_FEATURE_ARCH_2_06)
-	      ? __isinf_power7
-            : __isinff_ppc64);
+libc_ifunc_redirected (__redirect___isinff, __isinff,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __isinf_power8
+		       : (hwcap & PPC_FEATURE_ARCH_2_06)
+			 ? __isinf_power7
+			 : __isinff_ppc64);
 
 weak_alias (__isinff, isinff)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
index a614f25..fce3c9d 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
@@ -16,6 +16,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#define __isnan __redirect___isnan
+#define __isnanf __redirect___isnanf
+#define __isnanl __redirect___isnanl
 #include <math.h>
 #include <math_ldbl_opt.h>
 #include <shlib-compat.h>
@@ -27,19 +30,22 @@ extern __typeof (__isnan) __isnan_power6 attribute_hidden;
 extern __typeof (__isnan) __isnan_power6x attribute_hidden;
 extern __typeof (__isnan) __isnan_power7 attribute_hidden;
 extern __typeof (__isnan) __isnan_power8 attribute_hidden;
-
-libc_ifunc (__isnan,
-	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-	    ? __isnan_power8 :
-	      (hwcap & PPC_FEATURE_ARCH_2_06)
-	      ? __isnan_power7 :
-		(hwcap & PPC_FEATURE_POWER6_EXT)
-		? __isnan_power6x :
-		  (hwcap & PPC_FEATURE_ARCH_2_05)
-		    ? __isnan_power6 :
-		    (hwcap & PPC_FEATURE_POWER5)
-		      ? __isnan_power5
-            : __isnan_ppc64);
+#undef __isnan
+#undef __isnanf
+#undef __isnanl
+
+libc_ifunc_redirected (__redirect___isnan, __isnan,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __isnan_power8
+		       : (hwcap & PPC_FEATURE_ARCH_2_06)
+			 ? __isnan_power7
+			 : (hwcap & PPC_FEATURE_POWER6_EXT)
+			   ? __isnan_power6x
+			   : (hwcap & PPC_FEATURE_ARCH_2_05)
+			     ? __isnan_power6
+			     : (hwcap & PPC_FEATURE_POWER5)
+			       ? __isnan_power5
+			       : __isnan_ppc64);
 
 weak_alias (__isnan, isnan)
 
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
index acbc131..903ea86 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
@@ -27,17 +27,18 @@ extern __typeof (__isnanf) __isnan_power6x attribute_hidden;
 extern __typeof (__isnanf) __isnan_power7 attribute_hidden;
 extern __typeof (__isnanf) __isnan_power8 attribute_hidden;
 
-libc_ifunc (__isnanf,
-	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-	    ? __isnan_power8 :
-	      (hwcap & PPC_FEATURE_ARCH_2_06)
-	      ? __isnan_power7 :
-		(hwcap & PPC_FEATURE_POWER6_EXT)
-		  ? __isnan_power6x :
-		  (hwcap & PPC_FEATURE_ARCH_2_05)
-		    ? __isnan_power6 :
-		    (hwcap & PPC_FEATURE_POWER5)
-		      ? __isnan_power5
-            : __isnan_ppc64);
+libc_ifunc_hidden (__isnanf, __isnanf,
+		   (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		   ? __isnan_power8
+		   : (hwcap & PPC_FEATURE_ARCH_2_06)
+		     ? __isnan_power7
+		     : (hwcap & PPC_FEATURE_POWER6_EXT)
+		       ? __isnan_power6x
+		       : (hwcap & PPC_FEATURE_ARCH_2_05)
+			 ? __isnan_power6
+			 : (hwcap & PPC_FEATURE_POWER5)
+			   ? __isnan_power5
+			   : __isnan_ppc64);
 
+hidden_def (__isnanf)
 weak_alias (__isnanf, isnanf)
diff --git a/sysdeps/powerpc/powerpc64/multiarch/memcmp.c b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
index e8cf6ae..a45ebd7 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/memcmp.c
@@ -18,6 +18,7 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if IS_IN (libc)
+# define memcmp __redirect_memcmp
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -25,15 +26,16 @@
 extern __typeof (memcmp) __memcmp_ppc attribute_hidden;
 extern __typeof (memcmp) __memcmp_power4 attribute_hidden;
 extern __typeof (memcmp) __memcmp_power7 attribute_hidden;
+# undef memcmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memcmp,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __memcmp_power7 :
-	      (hwcap & PPC_FEATURE_POWER4)
-		? __memcmp_power4
-            : __memcmp_ppc);
+libc_ifunc_redirected (__redirect_memcmp, memcmp,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __memcmp_power7
+		       : (hwcap & PPC_FEATURE_POWER4)
+			 ? __memcmp_power4
+			 : __memcmp_ppc);
 #else
 #include <string/memcmp.c>
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
index 3c77b5f..36ec954 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
@@ -17,23 +17,28 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define mempcpy __redirect_mempcpy
+# define __mempcpy __redirect___mempcpy
 # define NO_MEMPCPY_STPCPY_REDIRECT
+/* Omit the mempcpy inline definitions because it would redefine mempcpy.  */
+# define _HAVE_STRING_ARCH_mempcpy 1
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (__mempcpy) __mempcpy_ppc attribute_hidden;
 extern __typeof (__mempcpy) __mempcpy_power7 attribute_hidden;
+# undef mempcpy
+# undef __mempcpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__mempcpy,
-	    (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __mempcpy_power7
-            : __mempcpy_ppc);
+libc_ifunc_redirected (__redirect___mempcpy, __mempcpy,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __mempcpy_power7
+		       : __mempcpy_ppc);
 
 weak_alias (__mempcpy, mempcpy)
-libc_hidden_def (mempcpy)
 #else
 # include <string/mempcpy.c>
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
index f06030e..b53b148 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
@@ -17,19 +17,21 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define __rawmemchr __redirect___rawmemchr
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (__rawmemchr) __rawmemchr_ppc attribute_hidden;
 extern __typeof (__rawmemchr) __rawmemchr_power7 attribute_hidden;
+# undef __rawmemchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__rawmemchr,
-	    (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __rawmemchr_power7
-            : __rawmemchr_ppc);
+libc_ifunc_redirected (__redirect___rawmemchr, __rawmemchr,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __rawmemchr_power7
+		       : __rawmemchr_ppc);
 
 weak_alias (__rawmemchr, rawmemchr)
 #else
diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
index bbc1691..e378138 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
@@ -26,14 +26,15 @@ extern __typeof (__stpcpy) __stpcpy_ppc attribute_hidden;
 extern __typeof (__stpcpy) __stpcpy_power7 attribute_hidden;
 extern __typeof (__stpcpy) __stpcpy_power8 attribute_hidden;
 
-libc_ifunc (__stpcpy,
-            (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-            ? __stpcpy_power8 :
-              (hwcap & PPC_FEATURE_HAS_VSX)
-              ? __stpcpy_power7
-            : __stpcpy_ppc);
+libc_ifunc_hidden (__stpcpy, __stpcpy,
+		   (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		   ? __stpcpy_power8
+		   : (hwcap & PPC_FEATURE_HAS_VSX)
+		     ? __stpcpy_power7
+		     : __stpcpy_ppc);
 
 weak_alias (__stpcpy, stpcpy)
+libc_hidden_def (__stpcpy)
 libc_hidden_def (stpcpy)
 #else
 # include <string/stpcpy.c>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c b/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c
index b1484b1..fb3b529 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/stpncpy.c
@@ -17,6 +17,8 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define stpncpy __redirect_stpncpy
+# define __stpncpy __redirect___stpncpy
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -24,13 +26,14 @@
 extern __typeof (__stpncpy) __stpncpy_ppc attribute_hidden;
 extern __typeof (__stpncpy) __stpncpy_power7 attribute_hidden;
 extern __typeof (__stpncpy) __stpncpy_power8 attribute_hidden;
+# undef stpncpy
+# undef __stpncpy
 
-libc_ifunc (__stpncpy,
-            (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-            ? __stpncpy_power8 :
-              (hwcap & PPC_FEATURE_HAS_VSX)
-              ? __stpncpy_power7
-            : __stpncpy_ppc);
-
+libc_ifunc_redirected (__redirect___stpncpy, __stpncpy,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __stpncpy_power8
+		       : (hwcap & PPC_FEATURE_HAS_VSX)
+			 ? __stpncpy_power7
+			 : __stpncpy_ppc);
 weak_alias (__stpncpy, stpncpy)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcat.c b/sysdeps/powerpc/powerpc64/multiarch/strcat.c
index a2894ae..5080ed1 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strcat.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcat.c
@@ -17,6 +17,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define strcat __redirect_strcat
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -24,11 +25,12 @@
 extern __typeof (strcat) __strcat_ppc attribute_hidden;
 extern __typeof (strcat) __strcat_power7 attribute_hidden;
 extern __typeof (strcat) __strcat_power8 attribute_hidden;
+# undef strcat
 
-libc_ifunc (strcat,
-            (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-            ? __strcat_power8 :
-              (hwcap & PPC_FEATURE_HAS_VSX)
-              ? __strcat_power7
-            : __strcat_ppc);
+libc_ifunc_redirected (__redirect_strcat, strcat,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __strcat_power8
+		       : (hwcap & PPC_FEATURE_HAS_VSX)
+			 ? __strcat_power7
+			 : __strcat_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchr.c b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
index 2cfde63..e24d6b3 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strchr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
@@ -18,18 +18,22 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if defined SHARED && IS_IN (libc)
+# define strchr __redirect_strchr
+/* Omit the strchr inline definitions because it would redefine strchr.  */
+# define __NO_STRING_INLINES
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (strchr) __strchr_ppc attribute_hidden;
 extern __typeof (strchr) __strchr_power7 attribute_hidden;
+# undef strchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strchr,
-	    (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strchr_power7
-            : __strchr_ppc);
+libc_ifunc_redirected (__redirect_strchr, strchr,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strchr_power7
+		       : __strchr_ppc);
 weak_alias (strchr, index)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
index aee888a..06f89cb 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
@@ -17,6 +17,9 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined SHARED && IS_IN (libc)
+# define strcmp __redirect_strcmp
+/* Omit the strcmp inline definitions because it would redefine strcmp.  */
+# define __NO_STRING_INLINES
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -24,11 +27,12 @@
 extern __typeof (strcmp) __strcmp_ppc attribute_hidden;
 extern __typeof (strcmp) __strcmp_power7 attribute_hidden;
 extern __typeof (strcmp) __strcmp_power8 attribute_hidden;
+# undef strcmp
 
-libc_ifunc (strcmp,
-            (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-              ? __strcmp_power8 :
-              (hwcap & PPC_FEATURE_HAS_VSX)
-              ? __strcmp_power7
-            : __strcmp_ppc);
+libc_ifunc_redirected (__redirect_strcmp, strcmp,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __strcmp_power8
+		       : (hwcap & PPC_FEATURE_HAS_VSX)
+			 ? __strcmp_power7
+			 : __strcmp_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcpy.c b/sysdeps/powerpc/powerpc64/multiarch/strcpy.c
index d2c3858..8708fc7 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strcpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strcpy.c
@@ -17,6 +17,7 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if defined SHARED && IS_IN (libc)
+# define strcpy __redirect_strcpy
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -24,11 +25,12 @@
 extern __typeof (strcpy) __strcpy_ppc attribute_hidden;
 extern __typeof (strcpy) __strcpy_power7 attribute_hidden;
 extern __typeof (strcpy) __strcpy_power8 attribute_hidden;
+#undef strcpy
 
-libc_ifunc (strcpy,
-            (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-            ? __strcpy_power8 :
-              (hwcap & PPC_FEATURE_HAS_VSX)
-              ? __strcpy_power7
-            : __strcpy_ppc);
+libc_ifunc_redirected (__redirect_strcpy, strcpy,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __strcpy_power8
+		       : (hwcap & PPC_FEATURE_HAS_VSX)
+			 ? __strcpy_power7
+			 : __strcpy_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
index 1eb6e51..63a1aa0 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
@@ -18,6 +18,9 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if defined SHARED && IS_IN (libc)
+# define strncmp __redirect_strncmp
+/* Omit the strncmp inline definitions because it would redefine strncmp.  */
+# define __NO_STRING_INLINES
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -26,15 +29,16 @@ extern __typeof (strncmp) __strncmp_ppc attribute_hidden;
 extern __typeof (strncmp) __strncmp_power4 attribute_hidden;
 extern __typeof (strncmp) __strncmp_power7 attribute_hidden;
 extern __typeof (strncmp) __strncmp_power8 attribute_hidden;
+# undef strncmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strncmp,
-            (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-            ? __strncmp_power8 :
-              (hwcap & PPC_FEATURE_HAS_VSX)
-              ? __strncmp_power7 :
-		(hwcap & PPC_FEATURE_POWER4)
-		? __strncmp_power4
-            : __strncmp_ppc);
+libc_ifunc_redirected (__redirect_strncmp, strncmp,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __strncmp_power8
+		       : (hwcap & PPC_FEATURE_HAS_VSX)
+			 ? __strncmp_power7
+			 : (hwcap & PPC_FEATURE_POWER4)
+			   ? __strncmp_power4
+			   : __strncmp_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy.c b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
index 0176514..64495df 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
@@ -18,6 +18,9 @@
 
 /* Define multiple versions only for definition in libc. */
 #if IS_IN (libc)
+# define strncpy __redirect_strncpy
+/* Omit the strncpy inline definitions because it would redefine strncpy.  */
+# define __NO_STRING_INLINES
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -25,14 +28,15 @@
 extern __typeof (strncpy) __strncpy_ppc attribute_hidden;
 extern __typeof (strncpy) __strncpy_power7 attribute_hidden;
 extern __typeof (strncpy) __strncpy_power8 attribute_hidden;
+# undef strncpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
  ifunc symbol properly. */
-libc_ifunc (strncpy,
-            (hwcap2 & PPC_FEATURE2_ARCH_2_07)
-            ? __strncpy_power8 :
-              (hwcap & PPC_FEATURE_HAS_VSX)
-              ? __strncpy_power7
-            : __strncpy_ppc);
+libc_ifunc_redirected (__redirect_strncpy, strncpy,
+		       (hwcap2 & PPC_FEATURE2_ARCH_2_07)
+		       ? __strncpy_power8
+		       : (hwcap & PPC_FEATURE_HAS_VSX)
+			 ? __strncpy_power7
+			 : __strncpy_ppc);
 
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
index c4907e9..71dc12d 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
@@ -17,19 +17,21 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define strnlen __redirect_strnlen
+# define __strnlen __redirect___strnlen
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (__strnlen) __strnlen_ppc attribute_hidden;
 extern __typeof (__strnlen) __strnlen_power7 attribute_hidden;
-
-libc_ifunc (__strnlen,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strnlen_power7
-            : __strnlen_ppc);
+# undef strnlen
+# undef __strnlen
+libc_ifunc_redirected (__redirect___strnlen, __strnlen,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strnlen_power7
+		       : __strnlen_ppc);
 weak_alias (__strnlen, strnlen)
-libc_hidden_def (strnlen)
 
 #else
 #include <string/strnlen.c>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
index 45742bc..e485b02 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
@@ -18,18 +18,20 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if IS_IN (libc)
+# define strrchr __redirect_strrchr
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (strrchr) __strrchr_ppc attribute_hidden;
 extern __typeof (strrchr) __strrchr_power7 attribute_hidden;
+#undef strrchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strrchr,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strrchr_power7
-            : __strrchr_ppc);
+libc_ifunc_redirected (__redirect_strrchr, strrchr,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strrchr_power7
+		       : __strrchr_ppc);
 weak_alias (strrchr, rindex)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strstr.c b/sysdeps/powerpc/powerpc64/multiarch/strstr.c
index 7efc4b0..9a390c2 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strstr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strstr.c
@@ -18,17 +18,19 @@
 
 /* Define multiple versions only for definition in libc.  */
 #if IS_IN (libc)
+# define strstr __redirect_strstr
 # include <string.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
 
 extern __typeof (strstr) __strstr_ppc attribute_hidden;
 extern __typeof (strstr) __strstr_power7 attribute_hidden;
+# undef strstr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strstr,
-            (hwcap & PPC_FEATURE_HAS_VSX)
-            ? __strstr_power7
-            : __strstr_ppc);
+libc_ifunc_redirected (__redirect_strstr, strstr,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __strstr_power7
+		       : __strstr_ppc);
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcschr.c b/sysdeps/powerpc/powerpc64/multiarch/wcschr.c
index 44c9b97..a470542 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/wcschr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/wcschr.c
@@ -17,6 +17,8 @@
    <http://www.gnu.org/licenses/>.  */
 
 #if IS_IN (libc)
+# define wcschr __redirect_wcschr
+# define __wcschr __redirect___wcschr
 # include <wchar.h>
 # include <shlib-compat.h>
 # include "init-arch.h"
@@ -24,15 +26,16 @@
 extern __typeof (wcschr) __wcschr_ppc attribute_hidden;
 extern __typeof (wcschr) __wcschr_power6 attribute_hidden;
 extern __typeof (wcschr) __wcschr_power7 attribute_hidden;
+# undef wcschr
+# undef __wcschr
 
-libc_ifunc (__wcschr,
-	     (hwcap & PPC_FEATURE_HAS_VSX)
-             ? __wcschr_power7 :
-	       (hwcap & PPC_FEATURE_ARCH_2_05)
-	       ? __wcschr_power6
-             : __wcschr_ppc);
+libc_ifunc_redirected (__redirect___wcschr, __wcschr,
+		       (hwcap & PPC_FEATURE_HAS_VSX)
+		       ? __wcschr_power7
+		       : (hwcap & PPC_FEATURE_ARCH_2_05)
+			 ? __wcschr_power6
+			 : __wcschr_ppc);
 weak_alias (__wcschr, wcschr)
-libc_hidden_builtin_def (wcschr)
 #else
 #undef libc_hidden_def
 #define libc_hidden_def(a)

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 2/9] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-09-30 13:45     ` Stefan Liebler
@ 2016-10-04 13:14       ` Adhemerval Zanella
  0 siblings, 0 replies; 27+ messages in thread
From: Adhemerval Zanella @ 2016-10-04 13:14 UTC (permalink / raw)
  To: libc-alpha

Thanks, LGTM.

On 30/09/2016 10:45, Stefan Liebler wrote:
> Hi Adhemerval,
> 
> thanks for reviewing. I've split the too long lines and added a comment block for libc_ifunc{_redirected,_hidden} macros in include/libc-symbols.h.
> 
> Yes you are right, review for patch 9 is still missing. I've tested the s390 part on s390x/s390. If patch 9 is okay, I'll commit the patch series.
> 
> Thanks.
> Stefan
> 
> On 09/29/2016 08:38 PM, Adhemerval Zanella wrote:
>> Patch LGTM and a powerpc32/power7 (to actually uses ifunc) and a build/run
>> for powerpc64le seems ok.
>>
>> I see with recent Andreas ack of 4/9 that only 3/9 (s390 bits) and
>> 9/9 (siglongjmp, longjmp in libpthread) seems to be the impending
>> bits.  I plan to check on 9/9, but I won't be able to proper review
>> 3/9 since I do not have access to a s390 machine anymore.
>>
>> Some comments below:
>>
>> On 24/08/2016 07:04, Stefan Liebler wrote:
>>> diff --git a/include/libc-symbols.h b/include/libc-symbols.h
>>> index c2b499a..44e5253 100644
>>> --- a/include/libc-symbols.h
>>> +++ b/include/libc-symbols.h
>>> @@ -722,27 +722,64 @@ for linking")
>>>  # define compat_data_section .section ".data.compat", "aw";
>>>  #endif
>>>
>>> -/* Marker used for indirection function symbols.  */
>>> -#define libc_ifunc(name, expr)                        \
>>> -  extern void *name##_ifunc (void) __asm__ (#name);            \
>>> -  void *name##_ifunc (void)                        \
>>> +/* Helper / base  macros for indirect function symbols.  */
>>> +#define __ifunc_resolver(type_name, name, expr, arg, init, classifier)    \
>>> +  classifier void *name##_ifunc (arg)                    \
>>>    {                                    \
>>> -    INIT_ARCH ();                            \
>>> -    __typeof (name) *res = expr;                    \
>>> +    init ();                                \
>>> +    __typeof (type_name) *res = expr;                    \
>>>      return res;                                \
>>> -  }                                    \
>>> -  __asm__ (".type " #name ", %gnu_indirect_function");
>>> +  }
>>> +
>>> +#ifdef HAVE_GCC_IFUNC
>>> +# define __ifunc(type_name, name, expr, arg, init)            \
>>> +  extern __typeof (type_name) name __attribute__            \
>>> +                  ((ifunc (#name "_ifunc")));        \
>>> +  __ifunc_resolver (type_name, name, expr, arg, init, static)
>>> +
>>> +# define __ifunc_hidden(type_name, name, expr, arg, init)    \
>>> +  __ifunc (type_name, name, expr, arg, init)
>>> +#else
>>> +/* Gcc does not support __attribute__ ((ifunc (...))).  Use the old behaviour
>>> +   as fallback.  But keep in mind that the debug information for the ifunc
>>> +   resolver functions is not correct.  It contains the ifunc'ed function as
>>> +   DW_AT_linkage_name.  E.g. lldb uses this field and an inferior function
>>> +   call of the ifunc'ed function will fail due to "no matching function for call
>>
>> Line too long.
>>
>>> +   to ..." because the ifunc'ed function and the resolver function have
>>> +   different signatures.  (Gcc support is disabled at least on a ppc64le
>>> +   Ubuntu 14.04 system.)  */
>>> +
>>> +# define __ifunc(type_name, name, expr, arg, init)            \
>>> +  extern __typeof (type_name) name;                    \
>>> +  void *name##_ifunc (arg) __asm__ (#name);                \
>>> +  __ifunc_resolver (type_name, name, expr, arg, init,)            \
>>> + __asm__ (".type " #name ", %gnu_indirect_function");
>>> +
>>> +# define __ifunc_hidden(type_name, name, expr, arg, init)        \
>>> +  extern __typeof (type_name) __libc_##name;                \
>>> +  __ifunc (type_name, __libc_##name, expr, arg, init)            \
>>> +  strong_alias (__libc_##name, name);
>>> +#endif /* !HAVE_GCC_IFUNC  */
>>> +
>>> +/* Use libc_ifunc if your ifunc'ed function has no internal symbol.  */
>>> +#define libc_ifunc(name, expr) __ifunc (name, name, expr, void, INIT_ARCH)
>>
>> I think it will be valuable to add a comment like the one on same
>> file at line 341 with a usage example on how to use
>> libc_ifunc{_redirected,_hidden} and difference between each usage and
>> the possible requirements (such as name redirection).
>>
>>> +
>>> +/* Use libc_ifunc_redirected if your ifunc'ed function has an internal symbol
>>> +   which should be a dedicated fallback function instead of ifunc'ed.
>>> +   You have to redirect the function in the header file and use it as
>>> +   redirected_name.  */
>>> +#define libc_ifunc_redirected(redirected_name, name, expr)    \
>>> +  __ifunc (redirected_name, name, expr, void, INIT_ARCH)
>>> +
>>> +/* Use libc_ifunc_hidden if your ifunc'ed function has an internal symbol
>>> +   which should be the ifunc'ed function'.  */
>>> +#define libc_ifunc_hidden(redirected_name, name, expr)            \
>>> +  __ifunc_hidden (redirected_name, name, expr, void, INIT_ARCH)
>>>
>>>  /* The body of the function is supposed to use __get_cpu_features
>>>     which will, if necessary, initialize the data first.  */
>>> -#define libm_ifunc(name, expr)                        \
>>> -  extern void *name##_ifunc (void) __asm__ (#name);            \
>>> -  void *name##_ifunc (void)                        \
>>> -  {                                    \
>>> -    __typeof (name) *res = expr;                    \
>>> -    return res;                                \
>>> -  }                                    \
>>> -  __asm__ (".type " #name ", %gnu_indirect_function");
>>> +#define libm_ifunc_init()
>>> +#define libm_ifunc(name, expr) __ifunc (name, name, expr, void, libm_ifunc_init)
>>
>> Line too long.
>>
> 

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 9/9] Use libc_ifunc macro for siglongjmp, longjmp in libpthread.
  2016-08-24 14:05 ` [PATCH v3 9/9] Use libc_ifunc macro for siglongjmp, longjmp " Stefan Liebler
@ 2016-10-06 11:59   ` Florian Weimer
  0 siblings, 0 replies; 27+ messages in thread
From: Florian Weimer @ 2016-10-06 11:59 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha; +Cc: murphyp, schwab, joseph_myers

On 08/24/2016 04:04 PM, Stefan Liebler wrote:
> This patch uses the libc_ifunc macro to create already existing ifunc functions
> longjmp_ifunc, siglongjmp_ifunc if HAVE_IFUNC is defined.
> The s390 pt-longjmp.c includes the common pt-longjmp.c and uses strong_alias
> to create the longjmp, siglongjmp symbols for glibc version 2.19.
>
> ChangeLog:
>
> 	* nptl/pt-longjmp.c (DEFINE_LONGJMP): Use libc_ifunc macro.
> 	* sysdeps/unix/sysv/linux/s390/pt-longjmp.c (longjmp, siglongjmp):
> 	Use strong_alias to create symbols for glibc verison 2.19.

This is okay for now.

Once this is in, I'm going to submit a patch which replaces the IFUNC 
resolver with a direct call (similar to what we did for fork) because of 
the relocation ordering issue that can cause those IFUNC resolvers to go 
wrong.

Thanks,
Florian

^ permalink raw reply	[flat|nested] 27+ messages in thread

* Re: [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc.
  2016-08-24 14:05 [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Stefan Liebler
                   ` (9 preceding siblings ...)
  2016-09-05  7:13 ` [PING][PATCH " Stefan Liebler
@ 2016-10-07  9:19 ` Stefan Liebler
  10 siblings, 0 replies; 27+ messages in thread
From: Stefan Liebler @ 2016-10-07  9:19 UTC (permalink / raw)
  To: libc-alpha

Hi,

as all patches are acked I've pushed the series.
I also opened the bug "Bug 77894 - Enable GNU indirect function support 
by default as it will be used in glibc."
(https://gcc.gnu.org/bugzilla/show_bug.cgi?id=77894) against gcc and 
sent a note to the distribution maintainers listed in 
https://sourceware.org/glibc/wiki/MAINTAINERS#Distribution_Maintainers.

Thanks.
Stefan

On 08/24/2016 04:04 PM, Stefan Liebler wrote:
> This patch adds a configure check to test if gcc supports attribute ifunc.
> The support can either be enabled in <gcc-src>/gcc/config.gcc for one
> architecture in general by setting default_gnu_indirect_function variable to yes
> or by configuring gcc with --enable-gnu-indirect-function.
>
> The next patch rewrites libc_ifunc macro to use gcc attribute ifunc instead
> of inline assembly to generate the IFUNC symbols due to false debuginfo.
>
> If gcc does not support attribute ifunc, the old approach for generating
> ifunc'ed symbols is used. Then the debug-information is false. Thus it is
> recommended to use a gcc with indirect function support (See notes in INSTALL).
> After this patch-series these inline assemblies for ifunc-handling are not
> scattered in multiple files but are used only indirect via ifunc-macros
> and can simply removed in libc-symbols.h in future.
> > ---
>  INSTALL             |  8 ++++++++

> If glibc is configured with --enable-multi-arch and gcc does not support
> attribute ifunc, a configure warning is dumped!
>
> This NEWS entry will be added:
> * For multi-arch support it is recommended to use a GCC with gnu-indirect-function
>   support as it is used to generate ifunc'ed symbols with correct
>   debug-information. This support can either be enabled by configuring GCC with
>   '--enable-gnu-indirect-function' or by enabling it by default by setting
>   'default_gnu_indirect_function' variable for a particular architecture in
>   gcc source file 'gcc/config.gcc'.
>
> ChangeLog:
>
> 	* config.h.in (HAVE_GCC_IFUNC): New undef.
> 	* configure.ac: Add check if gcc supports attribute ifunc feature.
> 	* configure: Regenerated.
> 	* manual/install.texi: Add recommendation for gcc with
> 	indirect-function support.
> 	* INSTALL: Regenerated.

^ permalink raw reply	[flat|nested] 27+ messages in thread

end of thread, other threads:[~2016-10-07  9:19 UTC | newest]

Thread overview: 27+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-08-24 14:05 [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Stefan Liebler
2016-08-24 14:05 ` [PATCH v3 8/9] Use libc_ifunc macro for vfork in libpthread Stefan Liebler
2016-08-30 12:40   ` Florian Weimer
2016-08-24 14:05 ` [PATCH v3 9/9] Use libc_ifunc macro for siglongjmp, longjmp " Stefan Liebler
2016-10-06 11:59   ` Florian Weimer
2016-08-24 14:05 ` [PATCH v3 6/9] Use libc_ifunc macro for clock_* symbols in librt Stefan Liebler
2016-08-30 12:39   ` Florian Weimer
2016-08-24 14:05 ` [PATCH v3 4/9] i386, x86: Use libc_ifunc macro for time, gettimeofday Stefan Liebler
2016-09-29 14:34   ` Andreas Schwab
2016-08-24 14:05 ` [PATCH v3 5/9] ppc: " Stefan Liebler
2016-08-30 13:46   ` Paul E. Murphy
2016-08-24 14:05 ` [PATCH v3 3/9] s390: Refactor ifunc resolvers due to false debuginfo Stefan Liebler
2016-08-30 12:31   ` Florian Weimer
2016-08-30 14:12     ` Stefan Liebler
2016-08-24 14:05 ` [PATCH v3 2/9] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly " Stefan Liebler
2016-08-29 20:16   ` Paul E. Murphy
2016-08-30 14:12     ` Stefan Liebler
2016-09-29 18:38   ` Adhemerval Zanella
2016-09-30 13:45     ` Stefan Liebler
2016-10-04 13:14       ` Adhemerval Zanella
2016-08-24 17:02 ` [PATCH v3 7/9] Use libc_ifunc macro for system in libpthread Stefan Liebler
2016-08-30 12:39   ` Florian Weimer
2016-08-29  9:34 ` [PATCH v3 1/9] Add configure check to test if gcc supports attribute ifunc Florian Weimer
2016-08-30 14:12   ` Stefan Liebler
2016-09-05  7:13 ` [PING][PATCH " Stefan Liebler
2016-09-29 13:50   ` Stefan Liebler
2016-10-07  9:19 ` [PATCH " Stefan Liebler

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).