public inbox for libc-alpha@sourceware.org
 help / color / mirror / Atom feed
* [PATCH 5/8] Use libc_ifunc macro for clock_* symbols in librt.
  2016-06-23 11:56 [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo Stefan Liebler
  2016-06-23 11:56 ` [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday Stefan Liebler
  2016-06-23 11:56 ` [PATCH 8/8] Use libc_ifunc macro for siglongjmp, longjmp in libpthread Stefan Liebler
@ 2016-06-23 11:56 ` Stefan Liebler
  2016-07-04  9:14   ` Florian Weimer
  2016-06-23 11:56 ` [PATCH 7/8] Use libc_ifunc macro for vfork in libpthread Stefan Liebler
                   ` (6 subsequent siblings)
  9 siblings, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-06-23 11:56 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, joseph, carlos, munroesj

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 | 33 ++++++++++++++-------------------
 1 file changed, 14 insertions(+), 19 deletions(-)

diff --git a/rt/clock-compat.c b/rt/clock-compat.c
index dc69e4a..b2a4d3b 100644
--- a/rt/clock-compat.c
+++ b/rt/clock-compat.c
@@ -28,13 +28,8 @@
 #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");
+# define INIT_ARCH()
+# define COMPAT_REDIRECT(name, proto, arglist) libc_ifunc (name, &__##name)
 #else
 # define COMPAT_REDIRECT(name, proto, arglist)				      \
   int									      \
@@ -45,21 +40,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] 47+ messages in thread

* [PATCH 2/8] s390: Refactor ifunc resolvers due to false debuginfo.
  2016-06-23 11:56 [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo Stefan Liebler
                   ` (3 preceding siblings ...)
  2016-06-23 11:56 ` [PATCH 7/8] Use libc_ifunc macro for vfork in libpthread Stefan Liebler
@ 2016-06-23 11:56 ` Stefan Liebler
  2016-07-04  8:37   ` Florian Weimer
  2016-06-23 11:56 ` [PATCH 4/8] ppc: Use libc_ifunc macro for time, gettimeofday Stefan Liebler
                   ` (4 subsequent siblings)
  9 siblings, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-06-23 11:56 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, joseph, carlos, munroesj

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_libc_ifunc_init): New define.
	* sysdeps/s390/multiarch/memchr.c: Redirect ifunced function in header
	and create a copy of the prototype for using as ifunc function.
	Add appropiate aliases to the real symbol names.
	* 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  | 63 +++++++++++++--------------------
 sysdeps/s390/multiarch/memchr.c         |  7 +++-
 sysdeps/s390/multiarch/mempcpy.c        | 14 ++++++--
 sysdeps/s390/multiarch/rawmemchr.c      |  8 +++--
 sysdeps/s390/multiarch/stpcpy.c         | 13 +++++--
 sysdeps/s390/multiarch/stpncpy.c        | 10 ++++--
 sysdeps/s390/multiarch/strcat.c         |  6 +++-
 sysdeps/s390/multiarch/strchr.c         | 10 ++++--
 sysdeps/s390/multiarch/strcmp.c         |  9 +++--
 sysdeps/s390/multiarch/strcpy.c         |  7 +++-
 sysdeps/s390/multiarch/strcspn.c        |  8 ++++-
 sysdeps/s390/multiarch/strlen.c         |  6 +++-
 sysdeps/s390/multiarch/strncmp.c        | 11 +++---
 sysdeps/s390/multiarch/strncpy.c        |  9 ++++-
 sysdeps/s390/multiarch/strnlen.c        | 11 ++++--
 sysdeps/s390/multiarch/strpbrk.c        |  8 ++++-
 sysdeps/s390/multiarch/strrchr.c        |  8 +++--
 sysdeps/s390/multiarch/strspn.c         |  8 ++++-
 sysdeps/s390/multiarch/wcschr.c         | 11 ++++--
 sysdeps/s390/multiarch/wcscmp.c         |  8 +++--
 sysdeps/s390/multiarch/wcspbrk.c        |  6 +++-
 sysdeps/s390/multiarch/wcsspn.c         |  6 +++-
 sysdeps/s390/multiarch/wmemchr.c        | 11 ++++--
 sysdeps/s390/multiarch/wmemset.c        | 11 ++++--
 sysdeps/s390/s390-32/multiarch/memcmp.c |  9 +++--
 sysdeps/s390/s390-32/multiarch/memcpy.c |  7 +++-
 sysdeps/s390/s390-32/multiarch/memset.c |  7 +++-
 sysdeps/s390/s390-64/multiarch/memcmp.c |  9 +++--
 sysdeps/s390/s390-64/multiarch/memcpy.c |  7 +++-
 sysdeps/s390/s390-64/multiarch/memset.c |  7 +++-
 30 files changed, 225 insertions(+), 90 deletions(-)

diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h
index 26e097a..95c98f1 100644
--- a/sysdeps/s390/multiarch/ifunc-resolve.h
+++ b/sysdeps/s390/multiarch/ifunc-resolve.h
@@ -40,53 +40,40 @@
 		       ".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(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 (FUNC) RESOLVERFUNC##_z196 attribute_hidden;		\
+  extern __typeof (FUNC) RESOLVERFUNC##_z10 attribute_hidden;           \
+  extern __typeof (FUNC) RESOLVERFUNC##_default attribute_hidden;       \
+  __ifunc (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)
 
+#define s390_vx_libc_ifunc_init()
 #define s390_vx_libc_ifunc2(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");
+  __ifunc (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..e7661df 100644
--- a/sysdeps/s390/multiarch/memchr.c
+++ b/sysdeps/s390/multiarch/memchr.c
@@ -17,8 +17,13 @@
    <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)
+extern __typeof (__redirect_memchr) __libc_memchr;
+s390_vx_libc_ifunc2 (__memchr, __libc_memchr)
+strong_alias (__libc_memchr, memchr)
+
 #endif
diff --git a/sysdeps/s390/multiarch/mempcpy.c b/sysdeps/s390/multiarch/mempcpy.c
index 34d8329..709d167 100644
--- a/sysdeps/s390/multiarch/mempcpy.c
+++ b/sysdeps/s390/multiarch/mempcpy.c
@@ -18,9 +18,17 @@
 
 
 #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");
+extern __typeof (__redirect_mempcpy) __libc___mempcpy;
+s390_libc_ifunc (____mempcpy, __libc___mempcpy)
+strong_alias (__libc___mempcpy, __mempcpy);
+weak_alias (__libc___mempcpy, mempcpy);
 #endif
diff --git a/sysdeps/s390/multiarch/rawmemchr.c b/sysdeps/s390/multiarch/rawmemchr.c
index 7186ccd..fac159f 100644
--- a/sysdeps/s390/multiarch/rawmemchr.c
+++ b/sysdeps/s390/multiarch/rawmemchr.c
@@ -17,11 +17,15 @@
    <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)
-weak_alias (__rawmemchr, rawmemchr)
+extern __typeof (__redirect___rawmemchr) __libc___rawmemchr;
+s390_vx_libc_ifunc2 (__rawmemchr, __libc___rawmemchr)
+strong_alias (__libc___rawmemchr, __rawmemchr)
+weak_alias (__libc___rawmemchr, rawmemchr)
 
 #else
 # include <string/rawmemchr.c>
diff --git a/sysdeps/s390/multiarch/stpcpy.c b/sysdeps/s390/multiarch/stpcpy.c
index dcde012..bae99ab 100644
--- a/sysdeps/s390/multiarch/stpcpy.c
+++ b/sysdeps/s390/multiarch/stpcpy.c
@@ -17,13 +17,20 @@
    <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)
-weak_alias (__stpcpy, stpcpy)
-libc_hidden_builtin_def (stpcpy)
+extern __typeof (__redirect___stpcpy) __libc___stpcpy;
+s390_vx_libc_ifunc2 (__stpcpy, __libc___stpcpy);
+strong_alias (__libc___stpcpy, __stpcpy)
+weak_alias (__libc___stpcpy, stpcpy)
 
 #else
 # include <string/stpcpy.c>
diff --git a/sysdeps/s390/multiarch/stpncpy.c b/sysdeps/s390/multiarch/stpncpy.c
index f5335b4..6c2b9bb 100644
--- a/sysdeps/s390/multiarch/stpncpy.c
+++ b/sysdeps/s390/multiarch/stpncpy.c
@@ -17,11 +17,17 @@
    <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)
-weak_alias (__stpncpy, stpncpy)
+extern __typeof (__redirect___stpncpy) __libc___stpncpy;
+s390_vx_libc_ifunc2 (__stpncpy, __libc___stpncpy)
+strong_alias (__libc___stpncpy, __stpncpy)
+weak_alias (__libc___stpncpy, stpncpy)
 
 #else
 # include <string/stpncpy.c>
diff --git a/sysdeps/s390/multiarch/strcat.c b/sysdeps/s390/multiarch/strcat.c
index c3b5e1c..f1db424 100644
--- a/sysdeps/s390/multiarch/strcat.c
+++ b/sysdeps/s390/multiarch/strcat.c
@@ -17,10 +17,14 @@
    <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)
+extern __typeof (__redirect_strcat) __libc_strcat;
+s390_vx_libc_ifunc2 (__strcat, __libc_strcat)
+strong_alias (__libc_strcat, strcat)
 
 #else
 # include <string/strcat.c>
diff --git a/sysdeps/s390/multiarch/strchr.c b/sysdeps/s390/multiarch/strchr.c
index 3c8c7e4..c8d40e7 100644
--- a/sysdeps/s390/multiarch/strchr.c
+++ b/sysdeps/s390/multiarch/strchr.c
@@ -17,11 +17,17 @@
    <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)
-weak_alias (strchr, index)
+extern __typeof (__redirect_strchr) __libc_strchr;
+s390_vx_libc_ifunc2 (__strchr, __libc_strchr)
+strong_alias (__libc_strchr, strchr)
+weak_alias (__libc_strchr, index)
 
 #else
 # include <string/strchr.c>
diff --git a/sysdeps/s390/multiarch/strcmp.c b/sysdeps/s390/multiarch/strcmp.c
index c4ccd34..8839e8b 100644
--- a/sysdeps/s390/multiarch/strcmp.c
+++ b/sysdeps/s390/multiarch/strcmp.c
@@ -17,10 +17,15 @@
    <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
 
+extern __typeof (__redirect_strcmp) __libc_strcmp;
+s390_vx_libc_ifunc2 (__strcmp, __libc_strcmp)
+strong_alias (__libc_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..a901bcd 100644
--- a/sysdeps/s390/multiarch/strcpy.c
+++ b/sysdeps/s390/multiarch/strcpy.c
@@ -17,8 +17,13 @@
    <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)
+extern __typeof (__redirect_strcpy) __libc_strcpy;
+s390_vx_libc_ifunc2 (__strcpy, __libc_strcpy)
+strong_alias (__libc_strcpy, strcpy)
+
 #endif
diff --git a/sysdeps/s390/multiarch/strcspn.c b/sysdeps/s390/multiarch/strcspn.c
index c23452a..a188f4b 100644
--- a/sysdeps/s390/multiarch/strcspn.c
+++ b/sysdeps/s390/multiarch/strcspn.c
@@ -17,10 +17,16 @@
    <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)
+extern __typeof (__redirect_strcspn) __libc_strcspn;
+s390_vx_libc_ifunc2 (__strcspn, __libc_strcspn)
+strong_alias (__libc_strcspn, strcspn)
 
 #else
 # include <string/strcspn.c>
diff --git a/sysdeps/s390/multiarch/strlen.c b/sysdeps/s390/multiarch/strlen.c
index 098d4e1..186b4e5 100644
--- a/sysdeps/s390/multiarch/strlen.c
+++ b/sysdeps/s390/multiarch/strlen.c
@@ -17,10 +17,14 @@
    <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)
+extern __typeof (__redirect_strlen) __libc_strlen;
+s390_vx_libc_ifunc2 (__strlen, __libc_strlen)
+strong_alias (__libc_strlen, strlen)
 
 #else
 # include <string/strlen.c>
diff --git a/sysdeps/s390/multiarch/strncmp.c b/sysdeps/s390/multiarch/strncmp.c
index 9a72c79..6c130cc 100644
--- a/sysdeps/s390/multiarch/strncmp.c
+++ b/sysdeps/s390/multiarch/strncmp.c
@@ -17,13 +17,16 @@
    <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)
+extern __typeof (__redirect_strncmp) __libc_strncmp;
+s390_vx_libc_ifunc2 (__strncmp, __libc_strncmp)
+strong_alias (__libc_strncmp, strncmp)
 
 #else
 # include <string/strncmp.c>
diff --git a/sysdeps/s390/multiarch/strncpy.c b/sysdeps/s390/multiarch/strncpy.c
index 1464551..2c294d2 100644
--- a/sysdeps/s390/multiarch/strncpy.c
+++ b/sysdeps/s390/multiarch/strncpy.c
@@ -17,8 +17,15 @@
    <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)
+extern __typeof (__redirect_strncpy) __libc_strncpy;
+s390_vx_libc_ifunc2 (__strncpy, __libc_strncpy);
+strong_alias (__libc_strncpy, strncpy)
+
 #endif
diff --git a/sysdeps/s390/multiarch/strnlen.c b/sysdeps/s390/multiarch/strnlen.c
index 48c3bb7..79edb236 100644
--- a/sysdeps/s390/multiarch/strnlen.c
+++ b/sysdeps/s390/multiarch/strnlen.c
@@ -17,12 +17,17 @@
    <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)
-weak_alias (__strnlen, strnlen)
-libc_hidden_def (strnlen)
+extern __typeof (__redirect___strnlen) __libc___strnlen;
+s390_vx_libc_ifunc2 (__strnlen, __libc___strnlen)
+strong_alias (__libc___strnlen, __strnlen)
+weak_alias (__libc___strnlen, strnlen)
 
 #else
 # include <string/strnlen.c>
diff --git a/sysdeps/s390/multiarch/strpbrk.c b/sysdeps/s390/multiarch/strpbrk.c
index cdc1399..dc267db 100644
--- a/sysdeps/s390/multiarch/strpbrk.c
+++ b/sysdeps/s390/multiarch/strpbrk.c
@@ -17,10 +17,16 @@
    <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)
+extern __typeof (__redirect_strpbrk) __libc_strpbrk;
+s390_vx_libc_ifunc2 (__strpbrk, __libc_strpbrk)
+strong_alias (__libc_strpbrk, strpbrk)
 
 #else
 # include <string/strpbrk.c>
diff --git a/sysdeps/s390/multiarch/strrchr.c b/sysdeps/s390/multiarch/strrchr.c
index e515d6b..b9c0fca 100644
--- a/sysdeps/s390/multiarch/strrchr.c
+++ b/sysdeps/s390/multiarch/strrchr.c
@@ -17,11 +17,15 @@
    <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)
+extern __typeof (__redirect_strrchr) __libc_strrchr;
+s390_vx_libc_ifunc2 (__strrchr, __libc_strrchr)
+strong_alias (__libc_strrchr, strrchr);
+weak_alias (__libc_strrchr, rindex);
 
 #else
 # include <string/strrchr.c>
diff --git a/sysdeps/s390/multiarch/strspn.c b/sysdeps/s390/multiarch/strspn.c
index 7c26af8..218ecdb 100644
--- a/sysdeps/s390/multiarch/strspn.c
+++ b/sysdeps/s390/multiarch/strspn.c
@@ -17,10 +17,16 @@
    <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)
+extern __typeof (__redirect_strspn) __libc_strspn;
+s390_vx_libc_ifunc2 (__strspn, __libc_strspn)
+strong_alias (__libc_strspn, strspn);
 
 #else
 # include <string/strspn.c>
diff --git a/sysdeps/s390/multiarch/wcschr.c b/sysdeps/s390/multiarch/wcschr.c
index fb51097..abc4e20 100644
--- a/sysdeps/s390/multiarch/wcschr.c
+++ b/sysdeps/s390/multiarch/wcschr.c
@@ -17,12 +17,17 @@
    <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)
-weak_alias (__wcschr, wcschr)
-libc_hidden_weak (wcschr)
+extern __typeof (__redirect___wcschr) __libc___wcschr;
+s390_vx_libc_ifunc2 (__wcschr, __libc___wcschr)
+strong_alias (__libc___wcschr, __wcschr)
+weak_alias (__libc___wcschr, wcschr)
 
 #else
 # include <wcsmbs/wcschr.c>
diff --git a/sysdeps/s390/multiarch/wcscmp.c b/sysdeps/s390/multiarch/wcscmp.c
index 705ef45..6675a73 100644
--- a/sysdeps/s390/multiarch/wcscmp.c
+++ b/sysdeps/s390/multiarch/wcscmp.c
@@ -17,11 +17,15 @@
    <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)
-weak_alias (__wcscmp, wcscmp)
+extern __typeof (__redirect___wcscmp) __libc__wcscmp;
+s390_vx_libc_ifunc2 (__wcscmp, __libc__wcscmp)
+strong_alias (__libc__wcscmp, __wcscmp)
+weak_alias (__libc__wcscmp, wcscmp)
 
 #else
 # include <wcsmbs/wcscmp.c>
diff --git a/sysdeps/s390/multiarch/wcspbrk.c b/sysdeps/s390/multiarch/wcspbrk.c
index 198144d..e3258a5 100644
--- a/sysdeps/s390/multiarch/wcspbrk.c
+++ b/sysdeps/s390/multiarch/wcspbrk.c
@@ -17,10 +17,14 @@
    <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)
+extern __typeof (__redirect_wcspbrk) __libc_wcspbrk;
+s390_vx_libc_ifunc2 (__wcspbrk, __libc_wcspbrk)
+strong_alias (__libc_wcspbrk, wcspbrk)
 
 #else
 # include <wcsmbs/wcspbrk.c>
diff --git a/sysdeps/s390/multiarch/wcsspn.c b/sysdeps/s390/multiarch/wcsspn.c
index 167a881..45cde8c 100644
--- a/sysdeps/s390/multiarch/wcsspn.c
+++ b/sysdeps/s390/multiarch/wcsspn.c
@@ -17,10 +17,14 @@
    <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)
+extern __typeof (__redirect_wcsspn) __libc_wcsspn;
+s390_vx_libc_ifunc2 (__wcsspn, __libc_wcsspn)
+strong_alias (__libc_wcsspn, wcsspn)
 
 #else
 # include <wcsmbs/wcsspn.c>
diff --git a/sysdeps/s390/multiarch/wmemchr.c b/sysdeps/s390/multiarch/wmemchr.c
index f2bfe3c..19b5fba 100644
--- a/sysdeps/s390/multiarch/wmemchr.c
+++ b/sysdeps/s390/multiarch/wmemchr.c
@@ -17,12 +17,17 @@
    <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)
-weak_alias (__wmemchr, wmemchr)
-libc_hidden_weak (wmemchr)
+extern __typeof (__redirect___wmemchr) __libc___wmemchr;
+s390_vx_libc_ifunc2 (__wmemchr, __libc___wmemchr)
+strong_alias (__libc___wmemchr, __wmemchr)
+weak_alias (__libc___wmemchr, wmemchr)
 
 #else
 # include <wcsmbs/wmemchr.c>
diff --git a/sysdeps/s390/multiarch/wmemset.c b/sysdeps/s390/multiarch/wmemset.c
index e9e695f..6434917 100644
--- a/sysdeps/s390/multiarch/wmemset.c
+++ b/sysdeps/s390/multiarch/wmemset.c
@@ -17,12 +17,17 @@
    <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)
-weak_alias (__wmemset, wmemset)
-libc_hidden_weak (wmemset)
+extern __typeof (__redirect___wmemset) __libc___wmemset;
+s390_vx_libc_ifunc2 (__wmemset, __libc___wmemset)
+strong_alias (__libc___wmemset, __wmemset)
+weak_alias (__libc___wmemset, 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..a3f5f07 100644
--- a/sysdeps/s390/s390-32/multiarch/memcmp.c
+++ b/sysdeps/s390/s390-32/multiarch/memcmp.c
@@ -17,8 +17,13 @@
    <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");
+extern __typeof (__redirect_memcmp) __libc_memcmp;
+s390_libc_ifunc (__memcmp, __libc_memcmp)
+strong_alias (__libc_memcmp, memcmp);
+weak_alias (__libc_memcmp, bcmp);
 #endif
diff --git a/sysdeps/s390/s390-32/multiarch/memcpy.c b/sysdeps/s390/s390-32/multiarch/memcpy.c
index 2a98aa0..3b91871 100644
--- a/sysdeps/s390/s390-32/multiarch/memcpy.c
+++ b/sysdeps/s390/s390-32/multiarch/memcpy.c
@@ -18,7 +18,12 @@
 
 /* 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)
+extern __typeof (__redirect_memcpy) __libc_memcpy;
+s390_libc_ifunc (__memcpy, __libc_memcpy)
+strong_alias (__libc_memcpy, memcpy);
 #endif
diff --git a/sysdeps/s390/s390-32/multiarch/memset.c b/sysdeps/s390/s390-32/multiarch/memset.c
index 89b8102..db62760 100644
--- a/sysdeps/s390/s390-32/multiarch/memset.c
+++ b/sysdeps/s390/s390-32/multiarch/memset.c
@@ -17,7 +17,12 @@
    <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)
+extern __typeof (__redirect_memset) __libc_memset;
+s390_libc_ifunc (__memset, __libc_memset)
+strong_alias (__libc_memset, memset);
 #endif
diff --git a/sysdeps/s390/s390-64/multiarch/memcmp.c b/sysdeps/s390/s390-64/multiarch/memcmp.c
index 44f72dc..a3f5f07 100644
--- a/sysdeps/s390/s390-64/multiarch/memcmp.c
+++ b/sysdeps/s390/s390-64/multiarch/memcmp.c
@@ -17,8 +17,13 @@
    <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");
+extern __typeof (__redirect_memcmp) __libc_memcmp;
+s390_libc_ifunc (__memcmp, __libc_memcmp)
+strong_alias (__libc_memcmp, memcmp);
+weak_alias (__libc_memcmp, bcmp);
 #endif
diff --git a/sysdeps/s390/s390-64/multiarch/memcpy.c b/sysdeps/s390/s390-64/multiarch/memcpy.c
index 2a98aa0..3b91871 100644
--- a/sysdeps/s390/s390-64/multiarch/memcpy.c
+++ b/sysdeps/s390/s390-64/multiarch/memcpy.c
@@ -18,7 +18,12 @@
 
 /* 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)
+extern __typeof (__redirect_memcpy) __libc_memcpy;
+s390_libc_ifunc (__memcpy, __libc_memcpy)
+strong_alias (__libc_memcpy, memcpy);
 #endif
diff --git a/sysdeps/s390/s390-64/multiarch/memset.c b/sysdeps/s390/s390-64/multiarch/memset.c
index 89b8102..db62760 100644
--- a/sysdeps/s390/s390-64/multiarch/memset.c
+++ b/sysdeps/s390/s390-64/multiarch/memset.c
@@ -17,7 +17,12 @@
    <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)
+extern __typeof (__redirect_memset) __libc_memset;
+s390_libc_ifunc (__memset, __libc_memset)
+strong_alias (__libc_memset, memset);
 #endif
-- 
2.3.0

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

* [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday.
  2016-06-23 11:56 [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo Stefan Liebler
@ 2016-06-23 11:56 ` Stefan Liebler
  2016-07-04  8:54   ` Florian Weimer
  2016-08-05  6:46   ` Stefan Liebler
  2016-06-23 11:56 ` [PATCH 8/8] Use libc_ifunc macro for siglongjmp, longjmp in libpthread Stefan Liebler
                   ` (8 subsequent siblings)
  9 siblings, 2 replies; 47+ messages in thread
From: Stefan Liebler @ 2016-06-23 11:56 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, joseph, carlos, munroesj

This patch uses the libc_ifunc 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 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 and create a copy of the prototype
	for using as ifunc function. Add appropiate aliases to the real symbol
	names.
	* 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 | 19 ++++++++++++++++---
 sysdeps/unix/sysv/linux/i386/time.c         | 15 ++++++++++++---
 sysdeps/unix/sysv/linux/x86/gettimeofday.c  | 20 ++++++--------------
 sysdeps/unix/sysv/linux/x86/time.c          | 18 +++++-------------
 5 files changed, 39 insertions(+), 48 deletions(-)

diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index a77308a..c651b24 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -730,21 +730,6 @@ for linking")
 #define libm_ifunc_init()
 #define libm_ifunc(name, expr) __ifunc (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..fc6cfdd 100644
--- a/sysdeps/unix/sysv/linux/i386/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
@@ -16,14 +16,27 @@
    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
 
-# undef libc_ifunc_hidden_def
-# define libc_ifunc_hidden_def(name)  \
-  libc_ifunc_hidden_def1 (__GI_##name, __gettimeofday_syscall)
+extern __typeof (__redirect___gettimeofday) __libc___gettimeofday;
+# define __gettimeofday __libc___gettimeofday
 
+# 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>
+
+#ifdef SHARED
+# undef __gettimeofday
+strong_alias (__libc___gettimeofday, __gettimeofday)
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/time.c b/sysdeps/unix/sysv/linux/i386/time.c
index 62b78b2..bacbf84 100644
--- a/sysdeps/unix/sysv/linux/i386/time.c
+++ b/sysdeps/unix/sysv/linux/i386/time.c
@@ -17,10 +17,19 @@
    <http://www.gnu.org/licenses/>.  */
 
 #ifdef SHARED
+# define time __redirect_time
+#endif
+
+#include <time.h>
+
+#ifdef SHARED
+# undef time
+
+extern __typeof (__redirect_time) 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..02f8d6e 100644
--- a/sysdeps/unix/sysv/linux/x86/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -29,20 +29,12 @@ __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)
+# 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 (__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..957d586 100644
--- a/sysdeps/unix/sysv/linux/x86/time.c
+++ b/sysdeps/unix/sysv/linux/x86/time.c
@@ -30,20 +30,12 @@ __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);
-
+#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 (time, (_dl_vdso_vsym ("__vdso_time", &linux26)
+		   ?:  &__time_syscall))
+libc_hidden_def (time)
 
 #else
 
-- 
2.3.0

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

* [PATCH 4/8] ppc: Use libc_ifunc macro for time, gettimeofday.
  2016-06-23 11:56 [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo Stefan Liebler
                   ` (4 preceding siblings ...)
  2016-06-23 11:56 ` [PATCH 2/8] s390: Refactor ifunc resolvers due to false debuginfo Stefan Liebler
@ 2016-06-23 11:56 ` Stefan Liebler
  2016-07-29 15:38   ` Stefan Liebler
  2016-06-23 14:16 ` [PATCH 6/8] Use libc_ifunc macro for system in libpthread Stefan Liebler
                   ` (3 subsequent siblings)
  9 siblings, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-06-23 11:56 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, joseph, carlos, munroesj

This patch uses the libc_ifunc 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 and libc_hidden_def macro. Redirect ifunced function in
	header and create a copy of the prototype for using as ifunc function
	for ppc32 and add appropiate aliases to the real symbol names.
	* sysdeps/unix/sysv/linux/powerpc/time.c (time): Likewise.
---
 sysdeps/unix/sysv/linux/powerpc/gettimeofday.c | 64 ++++++++++++++-----------
 sysdeps/unix/sysv/linux/powerpc/time.c         | 66 +++++++++++++-------------
 2 files changed, 69 insertions(+), 61 deletions(-)

diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
index 25a4e7c..366364c 100644
--- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
@@ -15,6 +15,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
+#if defined SHARED && !defined __powerpc64__
+# define __gettimeofday __redirect___gettimeofday
+#endif
 
 #include <sys/time.h>
 
@@ -24,30 +27,17 @@
 # include <libc-vdso.h>
 # include <dl-machine.h>
 
-void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
+# ifndef __powerpc64__
+#  undef __gettimeofday
 
-static int
-__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
-{
-  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
-}
+extern __typeof (__redirect___gettimeofday) __libc___gettimeofday;
+#  define __gettimeofday __libc___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 +45,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
+
+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 (__gettimeofday,
+	    vdso_gettimeofday
+	    ? VDSO_IFUNC_RET (vdso_gettimeofday)
+	    : (void *) __gettimeofday_syscall);
+libc_hidden_def (__gettimeofday)
 
 #else
 
@@ -81,3 +84,8 @@ libc_hidden_def (__gettimeofday)
 #endif
 weak_alias (__gettimeofday, gettimeofday)
 libc_hidden_weak (gettimeofday)
+
+#if defined SHARED && !defined __powerpc64__
+# undef __gettimeofday
+strong_alias (__libc___gettimeofday, __gettimeofday)
+#endif
diff --git a/sysdeps/unix/sysv/linux/powerpc/time.c b/sysdeps/unix/sysv/linux/powerpc/time.c
index 7973419..200f4a7 100644
--- a/sysdeps/unix/sysv/linux/powerpc/time.c
+++ b/sysdeps/unix/sysv/linux/powerpc/time.c
@@ -17,6 +17,9 @@
    <http://www.gnu.org/licenses/>.  */
 
 #ifdef SHARED
+# ifndef __powerpc64__
+#  define time __redirect_time
+# endif
 
 # include <time.h>
 # include <sysdep.h>
@@ -24,7 +27,27 @@
 # include <libc-vdso.h>
 # include <dl-machine.h>
 
-void *time_ifunc (void) asm ("time");
+# ifndef __powerpc64__
+#  undef time
+extern __typeof (__redirect_time) 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 +65,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 (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] 47+ messages in thread

* [PATCH 7/8] Use libc_ifunc macro for vfork in libpthread.
  2016-06-23 11:56 [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo Stefan Liebler
                   ` (2 preceding siblings ...)
  2016-06-23 11:56 ` [PATCH 5/8] Use libc_ifunc macro for clock_* symbols in librt Stefan Liebler
@ 2016-06-23 11:56 ` Stefan Liebler
  2016-07-04 14:15   ` Stefan Liebler
  2016-06-23 11:56 ` [PATCH 2/8] s390: Refactor ifunc resolvers due to false debuginfo Stefan Liebler
                   ` (5 subsequent siblings)
  9 siblings, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-06-23 11:56 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, joseph, carlos, munroesj

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 | 21 ++++-----------------
 1 file changed, 4 insertions(+), 17 deletions(-)

diff --git a/nptl/pt-vfork.c b/nptl/pt-vfork.c
index 8f4be0c..6258835 100644
--- a/nptl/pt-vfork.c
+++ b/nptl/pt-vfork.c
@@ -46,32 +46,19 @@
 
 extern __typeof (vfork) __libc_vfork;   /* Defined in libc.  */
 
-static __typeof (vfork) *
-__attribute__ ((used))
-vfork_resolve (void)
-{
-  return &__libc_vfork;
-}
+# 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] 47+ messages in thread

* [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
@ 2016-06-23 11:56 Stefan Liebler
  2016-06-23 11:56 ` [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday Stefan Liebler
                   ` (9 more replies)
  0 siblings, 10 replies; 47+ messages in thread
From: Stefan Liebler @ 2016-06-23 11:56 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, joseph, carlos, munroesj

The current s390 ifunc resolver for vector optimized functions and the common
libc_ifunc macro in include/libc-symbols.h uses something like that:
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.
Usage 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:
extern __typeof (__redirect___strnlen) __libc___strnlen;
__typeof (__libc___strnlen) __libc___strnlen __attribute__ ((ifunc ("__resolve_strnlen")));
strong_alias (__libc___strnlen, __strnlen)
weak_alias (__libc___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 or if the __GI_* symbol
targets to the ifunc symbol, 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.

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.

Tested the whole patchset by building glibc and running the testsuite on s390,
intel, power for 32/64bit. The __GI_* symbols targets the same functions as
before.

Okay to commit?

Bye
Stefan

ChangeLog:

	* include/libc-symbols.h (__ifunc): New macro uses gcc attribute ifunc.
	(libc_ifunc, libm_ifunc): Use __ifunc as base macro.
	(libm_ifunc_init): New define.
	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c:
	Redirect ifunced function in header and create a copy of the prototype
	for using as ifunc function. Add appropiate aliases to the real symbol
	names.
	* 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/fpu/multiarch/s_isnanf.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/fpu/multiarch/s_isnanf.cLikewise.
	* 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/stpcpy.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.
---
 include/libc-symbols.h                             | 23 +++++++++-------------
 .../powerpc32/power4/fpu/multiarch/s_finite.c      | 12 +++++++++--
 .../powerpc32/power4/fpu/multiarch/s_finitef.c     | 12 +++++++++--
 .../powerpc32/power4/fpu/multiarch/s_isinf.c       | 12 +++++++++--
 .../powerpc32/power4/fpu/multiarch/s_isinff.c      | 13 ++++++++++--
 .../powerpc32/power4/fpu/multiarch/s_isnan.c       | 12 +++++++++--
 .../powerpc32/power4/fpu/multiarch/s_isnanf.c      |  1 +
 .../powerpc/powerpc32/power4/multiarch/memcmp.c    |  6 +++++-
 .../powerpc/powerpc32/power4/multiarch/memcpy.c    |  8 +++++++-
 .../powerpc/powerpc32/power4/multiarch/memmove.c   |  7 ++++++-
 .../powerpc/powerpc32/power4/multiarch/mempcpy.c   | 13 +++++++++---
 .../powerpc/powerpc32/power4/multiarch/memset.c    |  7 ++++++-
 .../powerpc/powerpc32/power4/multiarch/rawmemchr.c |  8 ++++++--
 .../powerpc/powerpc32/power4/multiarch/strchr.c    | 10 ++++++++--
 .../powerpc/powerpc32/power4/multiarch/strlen.c    |  7 ++++++-
 .../powerpc/powerpc32/power4/multiarch/strncmp.c   |  8 +++++++-
 .../powerpc/powerpc32/power4/multiarch/strnlen.c   | 11 ++++++++---
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c | 12 +++++++++--
 .../powerpc/powerpc64/fpu/multiarch/s_finitef.c    | 12 +++++++++--
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c  | 12 +++++++++--
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c | 12 +++++++++--
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c  | 12 +++++++++--
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c |  1 +
 sysdeps/powerpc/powerpc64/multiarch/memcmp.c       |  6 +++++-
 sysdeps/powerpc/powerpc64/multiarch/mempcpy.c      | 13 +++++++++---
 sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c    |  8 ++++++--
 sysdeps/powerpc/powerpc64/multiarch/stpcpy.c       |  1 +
 sysdeps/powerpc/powerpc64/multiarch/stpncpy.c      | 10 ++++++++--
 sysdeps/powerpc/powerpc64/multiarch/strcat.c       |  6 +++++-
 sysdeps/powerpc/powerpc64/multiarch/strchr.c       | 10 ++++++++--
 sysdeps/powerpc/powerpc64/multiarch/strcmp.c       |  8 +++++++-
 sysdeps/powerpc/powerpc64/multiarch/strcpy.c       |  6 +++++-
 sysdeps/powerpc/powerpc64/multiarch/strncmp.c      |  8 +++++++-
 sysdeps/powerpc/powerpc64/multiarch/strncpy.c      |  9 +++++++--
 sysdeps/powerpc/powerpc64/multiarch/strnlen.c      | 11 ++++++++---
 sysdeps/powerpc/powerpc64/multiarch/strrchr.c      |  8 ++++++--
 sysdeps/powerpc/powerpc64/multiarch/strstr.c       |  6 +++++-
 sysdeps/powerpc/powerpc64/multiarch/wcschr.c       | 11 ++++++++---
 38 files changed, 277 insertions(+), 75 deletions(-)

diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index 4548e09..a77308a 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -714,26 +714,21 @@ for linking")
 #endif
 
 /* Marker used for indirection function symbols.  */
-#define libc_ifunc(name, expr)						\
-  extern void *name##_ifunc (void) __asm__ (#name);			\
-  void *name##_ifunc (void)						\
+#define __ifunc(name, expr, arg, init)					\
+  extern __typeof (name) name __attribute__ ((ifunc(#name "_ifunc")));	\
+  static void *name##_ifunc (arg)					\
   {									\
-    INIT_ARCH ();							\
+    init ();								\
     __typeof (name) *res = expr;					\
     return res;								\
-  }									\
-  __asm__ (".type " #name ", %gnu_indirect_function");
+  }
+
+#define libc_ifunc(name, expr) __ifunc (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, 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..ee643a1 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,13 +26,18 @@
 
 extern __typeof (__finite) __finite_ppc32 attribute_hidden;
 extern __typeof (__finite) __finite_power7 attribute_hidden;
+extern __typeof (__finite) __libc___finite;
+#undef __finite
+#undef __finitef
+#undef __finitel
 
-libc_ifunc (__finite,
+libc_ifunc (__libc___finite,
 	    (hwcap & PPC_FEATURE_ARCH_2_06)
 	    ? __finite_power7
             : __finite_ppc32);
 
-weak_alias (__finite, finite)
+strong_alias (__libc___finite, __finite)
+weak_alias (__libc___finite, finite)
 
 #ifdef NO_LONG_DOUBLE
 strong_alias (__finite, __finitel)
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c
index 831c94f..f2a5389 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.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 <shlib-compat.h>
 #include "init-arch.h"
@@ -23,10 +26,15 @@
 extern __typeof (__finitef) __finitef_ppc32 attribute_hidden;
 /* The power7 finite(double) works for float.  */
 extern __typeof (__finitef) __finite_power7 attribute_hidden;
+extern __typeof (__finitef) __libc___finitef;
+#undef __finite
+#undef __finitef
+#undef __finitel
 
-libc_ifunc (__finitef,
+libc_ifunc (__libc___finitef,
 	    (hwcap & PPC_FEATURE_ARCH_2_06)
 	    ? __finite_power7
             : __finitef_ppc32);
 
-weak_alias (__finitef, finitef)
+strong_alias (__libc___finitef, __finitef)
+weak_alias (__libc___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..7321631 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,13 +26,18 @@
 
 extern __typeof (__isinf) __isinf_ppc32 attribute_hidden;
 extern __typeof (__isinf) __isinf_power7 attribute_hidden;
+extern __typeof (__isinf) __libc___isinf;
+#undef __isinf
+#undef __isinff
+#undef __isinfl
 
-libc_ifunc (__isinf,
+libc_ifunc (__libc___isinf,
 	    (hwcap & PPC_FEATURE_ARCH_2_06)
 	    ? __isinf_power7
             : __isinf_ppc32);
 
-weak_alias (__isinf, isinf)
+strong_alias (__libc___isinf, __isinf)
+weak_alias (__libc___isinf, isinf)
 
 #ifdef NO_LONG_DOUBLE
 strong_alias (__isinf, __isinfl)
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c
index 2ab83ee..75bb7dc 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.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,10 +27,16 @@
 extern __typeof (__isinff) __isinff_ppc32 attribute_hidden;
 /* The power7 isinf(double) works for float.  */
 extern __typeof (__isinff) __isinf_power7 attribute_hidden;
+extern __typeof (__isinff) __libc___isinff;
+#undef __isinf
+#undef __isinff
+#undef __isinfl
 
-libc_ifunc (__isinff,
+
+libc_ifunc (__libc___isinff,
 	    (hwcap & PPC_FEATURE_ARCH_2_06)
 	    ? __isinf_power7
             : __isinff_ppc32);
 
-weak_alias (__isinff, isinff)
+strong_alias (__libc___isinff, __isinff)
+weak_alias (__libc___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..99aa84b 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,8 +28,12 @@ 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;
+extern __typeof (__isnan) __libc___isnan;
+#undef __isnan
+#undef __isnanf
+#undef __isnanl
 
-libc_ifunc (__isnan,
+libc_ifunc (__libc___isnan,
 	    (hwcap & PPC_FEATURE_ARCH_2_06)
 	    ? __isnan_power7 :
 	      (hwcap & PPC_FEATURE_ARCH_2_05)
@@ -35,7 +42,8 @@ libc_ifunc (__isnan,
 		? __isnan_power5
             : __isnan_ppc32);
 
-weak_alias (__isnan, isnan)
+strong_alias (__libc___isnan, __isnan)
+weak_alias (__libc___isnan, isnan)
 
 #ifdef NO_LONG_DOUBLE
 strong_alias (__isnan, __isnanl)
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
index c43c0f3..304b2a7 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
@@ -35,4 +35,5 @@ libc_ifunc (__isnanf,
 		? __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..c18814f 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c
@@ -18,17 +18,21 @@
 
 /* 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;
+extern __typeof (memcmp) __libc_memcmp;
+# undef memcmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memcmp,
+libc_ifunc (__libc_memcmp,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __memcmp_power7
             : __memcmp_ppc);
+strong_alias (__libc_memcmp, memcmp);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c
index f379e47..5e68152 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,10 +31,12 @@ 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;
+extern __typeof (memcpy) __libc_memcpy;
+# undef memcpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memcpy,
+libc_ifunc (__libc_memcpy,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __memcpy_power7 :
 	      (hwcap & PPC_FEATURE_ARCH_2_06)
@@ -42,4 +46,6 @@ libc_ifunc (memcpy,
 		  (hwcap & PPC_FEATURE_CELL_BE)
 		  ? __memcpy_cell
             : __memcpy_ppc);
+
+strong_alias (__libc_memcpy, memcpy);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
index 4173184..ee8ab0c 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
@@ -19,16 +19,21 @@
 #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;
+extern __typeof (__redirect_memmove) __libc_memmove;
+# undef memmove
 
-libc_ifunc (memmove,
+libc_ifunc (__libc_memmove,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __memmove_power7
             : __memmove_ppc);
+
+strong_alias (__libc_memmove, memmove);
 #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..9b5dec9 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c
@@ -17,23 +17,30 @@
    <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;
+extern __typeof (__mempcpy) __libc___mempcpy;
+# undef mempcpy
+# undef __mempcpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__mempcpy,
+libc_ifunc (__libc___mempcpy,
 	    (hwcap & PPC_FEATURE_HAS_VSX)
             ? __mempcpy_power7
             : __mempcpy_ppc);
 
-weak_alias (__mempcpy, mempcpy)
-libc_hidden_def (mempcpy)
+strong_alias (__libc___mempcpy, __mempcpy)
+weak_alias (__libc___mempcpy, 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..a759e57 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,17 @@
 extern __typeof (memset) __memset_ppc attribute_hidden;
 extern __typeof (memset) __memset_power6 attribute_hidden;
 extern __typeof (memset) __memset_power7 attribute_hidden;
+extern __typeof (memset) __libc_memset;
+# undef memset
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memset,
+libc_ifunc (__libc_memset,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __memset_power7 :
 	      (hwcap & PPC_FEATURE_ARCH_2_05)
 		? __memset_power6
             : __memset_ppc);
+
+strong_alias (__libc_memset, memset);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c b/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
index f06030e..f31bd55 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
@@ -17,21 +17,25 @@
    <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;
+extern __typeof (__rawmemchr) __libc___rawmemchr;
+# undef __rawmemchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__rawmemchr,
+libc_ifunc (__libc___rawmemchr,
 	    (hwcap & PPC_FEATURE_HAS_VSX)
             ? __rawmemchr_power7
             : __rawmemchr_ppc);
 
-weak_alias (__rawmemchr, rawmemchr)
+strong_alias (__libc___rawmemchr, __rawmemchr)
+weak_alias (__libc___rawmemchr, rawmemchr)
 #else
 #include <string/rawmemchr.c>
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
index 2cfde63..87284f9 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
@@ -18,18 +18,24 @@
 
 /* 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;
+extern __typeof (strchr) __libc_strchr;
+# undef strchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strchr,
+libc_ifunc (__libc_strchr,
 	    (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strchr_power7
             : __strchr_ppc);
-weak_alias (strchr, index)
+strong_alias (__libc_strchr, strchr)
+weak_alias (__libc_strchr, index)
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
index af5921a..f21c680 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
@@ -17,15 +17,20 @@
    <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;
+extern __typeof (strlen) __libc_strlen;
+# undef strlen
 
-libc_ifunc (strlen,
+libc_ifunc (__libc_strlen,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strlen_power7
             : __strlen_ppc);
+
+strong_alias (__libc_strlen, strlen)
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c
index 7cc7628..ad3a17b 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,14 @@
 extern __typeof (strncmp) __strncmp_ppc attribute_hidden;
 extern __typeof (strncmp) __strncmp_power4 attribute_hidden;
 extern __typeof (strncmp) __strncmp_power7 attribute_hidden;
+extern __typeof (strncmp) __libc_strncmp;
+# undef strncmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strncmp,
+libc_ifunc (__libc_strncmp,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strncmp_power7
             : __strncmp_ppc);
+strong_alias (__libc_strncmp, strncmp)
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
index 8f1e7c9..d04d8b9 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
@@ -17,17 +17,22 @@
    <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;
+extern __typeof (__strnlen) __libc___strnlen;
+# undef strnlen
+# undef __strnlen
 
-libc_ifunc (__strnlen,
+libc_ifunc (__libc___strnlen,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strnlen_power7
             : __strnlen_ppc);
-weak_alias (__strnlen, strnlen)
-libc_hidden_def (strnlen)
+strong_alias (__libc___strnlen, __strnlen)
+weak_alias (__libc___strnlen, strnlen)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
index 067edc2..ed1934f 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,15 +27,20 @@
 extern __typeof (__finite) __finite_ppc64 attribute_hidden;
 extern __typeof (__finite) __finite_power7 attribute_hidden;
 extern __typeof (__finite) __finite_power8 attribute_hidden;
+extern __typeof (__finite) __libc___finite;
+#undef __finite
+#undef __finitef
+#undef __finitel
 
-libc_ifunc (__finite,
+libc_ifunc (__libc___finite,
 	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
 	    ? __finite_power8 :
 	      (hwcap & PPC_FEATURE_ARCH_2_06)
 	      ? __finite_power7
             : __finite_ppc64);
 
-weak_alias (__finite, finite)
+strong_alias (__libc___finite, __finite)
+weak_alias (__libc___finite, finite)
 
 #ifdef NO_LONG_DOUBLE
 strong_alias (__finite, __finitel)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
index e0b4686..6da1313 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.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 <shlib-compat.h>
 #include "init-arch.h"
@@ -24,12 +27,17 @@ 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;
+extern __typeof (__finitef) __libc___finitef;
+#undef __finite
+#undef __finitef
+#undef __finitel
 
-libc_ifunc (__finitef,
+libc_ifunc (__libc___finitef,
 	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
 	    ? __finite_power8 :
 	      (hwcap & PPC_FEATURE_ARCH_2_06)
 	      ? __finite_power7
             : __finitef_ppc64);
 
-weak_alias (__finitef, finitef)
+strong_alias (__libc___finitef, __finitef)
+weak_alias (__libc___finitef, finitef)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
index 07e159d..380dab8 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,15 +27,20 @@
 extern __typeof (__isinf) __isinf_ppc64 attribute_hidden;
 extern __typeof (__isinf) __isinf_power7 attribute_hidden;
 extern __typeof (__isinf) __isinf_power8 attribute_hidden;
+extern __typeof (__isinf) __libc___isinf;
+#undef __isinf
+#undef __isinff
+#undef __isinfl
 
-libc_ifunc (__isinf,
+libc_ifunc (__libc___isinf,
 	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
 	    ? __isinf_power8 :
 	      (hwcap & PPC_FEATURE_ARCH_2_06)
 	      ? __isinf_power7
             : __isinf_ppc64);
 
-weak_alias (__isinf, isinf)
+strong_alias (__libc___isinf, __isinf)
+weak_alias (__libc___isinf, isinf)
 
 #ifdef NO_LONG_DOUBLE
 strong_alias (__isinf, __isinfl)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
index 2cb161b..065d218 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.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>
@@ -25,12 +28,17 @@ 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;
+extern __typeof (__isinff) __libc___isinff;
+#undef __isinf
+#undef __isinff
+#undef __isinfl
 
-libc_ifunc (__isinff,
+libc_ifunc (__libc___isinff,
 	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
 	    ? __isinf_power8 :
 	      (hwcap & PPC_FEATURE_ARCH_2_06)
 	      ? __isinf_power7
             : __isinff_ppc64);
 
-weak_alias (__isinff, isinff)
+strong_alias (__libc___isinff, __isinff)
+weak_alias (__libc___isinff, isinff)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
index a614f25..a2c9308 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,8 +30,12 @@ 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;
+extern __typeof (__isnan) __libc___isnan;
+#undef __isnan
+#undef __isnanf
+#undef __isnanl
 
-libc_ifunc (__isnan,
+libc_ifunc (__libc___isnan,
 	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
 	    ? __isnan_power8 :
 	      (hwcap & PPC_FEATURE_ARCH_2_06)
@@ -41,7 +48,8 @@ libc_ifunc (__isnan,
 		      ? __isnan_power5
             : __isnan_ppc64);
 
-weak_alias (__isnan, isnan)
+strong_alias (__libc___isnan, __isnan)
+weak_alias (__libc___isnan, isnan)
 
 #ifdef NO_LONG_DOUBLE
 strong_alias (__isnan, __isnanl)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
index acbc131..72e9a07 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
@@ -40,4 +40,5 @@ libc_ifunc (__isnanf,
 		      ? __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..b31aadf 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,18 @@
 extern __typeof (memcmp) __memcmp_ppc attribute_hidden;
 extern __typeof (memcmp) __memcmp_power4 attribute_hidden;
 extern __typeof (memcmp) __memcmp_power7 attribute_hidden;
+extern __typeof (memcmp) __libc_memcmp;
+# undef memcmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memcmp,
+libc_ifunc (__libc_memcmp,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __memcmp_power7 :
 	      (hwcap & PPC_FEATURE_POWER4)
 		? __memcmp_power4
             : __memcmp_ppc);
+strong_alias (__libc_memcmp, memcmp);
 #else
 #include <string/memcmp.c>
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
index 3c77b5f..9b5dec9 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
@@ -17,23 +17,30 @@
    <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;
+extern __typeof (__mempcpy) __libc___mempcpy;
+# undef mempcpy
+# undef __mempcpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__mempcpy,
+libc_ifunc (__libc___mempcpy,
 	    (hwcap & PPC_FEATURE_HAS_VSX)
             ? __mempcpy_power7
             : __mempcpy_ppc);
 
-weak_alias (__mempcpy, mempcpy)
-libc_hidden_def (mempcpy)
+strong_alias (__libc___mempcpy, __mempcpy)
+weak_alias (__libc___mempcpy, 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..f31bd55 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
@@ -17,21 +17,25 @@
    <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;
+extern __typeof (__rawmemchr) __libc___rawmemchr;
+# undef __rawmemchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__rawmemchr,
+libc_ifunc (__libc___rawmemchr,
 	    (hwcap & PPC_FEATURE_HAS_VSX)
             ? __rawmemchr_power7
             : __rawmemchr_ppc);
 
-weak_alias (__rawmemchr, rawmemchr)
+strong_alias (__libc___rawmemchr, __rawmemchr)
+weak_alias (__libc___rawmemchr, rawmemchr)
 #else
 #include <string/rawmemchr.c>
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
index bbc1691..3867b9e 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
@@ -34,6 +34,7 @@ libc_ifunc (__stpcpy,
             : __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..b5c7457 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,17 @@
 extern __typeof (__stpncpy) __stpncpy_ppc attribute_hidden;
 extern __typeof (__stpncpy) __stpncpy_power7 attribute_hidden;
 extern __typeof (__stpncpy) __stpncpy_power8 attribute_hidden;
+extern __typeof (__stpncpy) __libc___stpncpy;
+# undef stpncpy
+# undef __stpncpy
 
-libc_ifunc (__stpncpy,
+libc_ifunc (__libc___stpncpy,
             (hwcap2 & PPC_FEATURE2_ARCH_2_07)
             ? __stpncpy_power8 :
               (hwcap & PPC_FEATURE_HAS_VSX)
               ? __stpncpy_power7
             : __stpncpy_ppc);
 
-weak_alias (__stpncpy, stpncpy)
+strong_alias (__libc___stpncpy, __stpncpy)
+weak_alias (__libc___stpncpy, stpncpy)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcat.c b/sysdeps/powerpc/powerpc64/multiarch/strcat.c
index a2894ae..b4fd540 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,14 @@
 extern __typeof (strcat) __strcat_ppc attribute_hidden;
 extern __typeof (strcat) __strcat_power7 attribute_hidden;
 extern __typeof (strcat) __strcat_power8 attribute_hidden;
+extern __typeof (strcat) __libc_strcat;
+# undef strcat
 
-libc_ifunc (strcat,
+libc_ifunc (__libc_strcat,
             (hwcap2 & PPC_FEATURE2_ARCH_2_07)
             ? __strcat_power8 :
               (hwcap & PPC_FEATURE_HAS_VSX)
               ? __strcat_power7
             : __strcat_ppc);
+strong_alias (__libc_strcat, strcat)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchr.c b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
index 2cfde63..87284f9 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strchr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
@@ -18,18 +18,24 @@
 
 /* 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;
+extern __typeof (strchr) __libc_strchr;
+# undef strchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strchr,
+libc_ifunc (__libc_strchr,
 	    (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strchr_power7
             : __strchr_ppc);
-weak_alias (strchr, index)
+strong_alias (__libc_strchr, strchr)
+weak_alias (__libc_strchr, index)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
index aee888a..32ab75d 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,14 @@
 extern __typeof (strcmp) __strcmp_ppc attribute_hidden;
 extern __typeof (strcmp) __strcmp_power7 attribute_hidden;
 extern __typeof (strcmp) __strcmp_power8 attribute_hidden;
+extern __typeof (strcmp) __libc_strcmp;
+# undef strcmp
 
-libc_ifunc (strcmp,
+libc_ifunc (__libc_strcmp,
             (hwcap2 & PPC_FEATURE2_ARCH_2_07)
               ? __strcmp_power8 :
               (hwcap & PPC_FEATURE_HAS_VSX)
               ? __strcmp_power7
             : __strcmp_ppc);
+strong_alias (__libc_strcmp, strcmp)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcpy.c b/sysdeps/powerpc/powerpc64/multiarch/strcpy.c
index d2c3858..31d6c92 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,14 @@
 extern __typeof (strcpy) __strcpy_ppc attribute_hidden;
 extern __typeof (strcpy) __strcpy_power7 attribute_hidden;
 extern __typeof (strcpy) __strcpy_power8 attribute_hidden;
+extern __typeof (strcpy) __libc_strcpy;
+#undef strcpy
 
-libc_ifunc (strcpy,
+libc_ifunc (__libc_strcpy,
             (hwcap2 & PPC_FEATURE2_ARCH_2_07)
             ? __strcpy_power8 :
               (hwcap & PPC_FEATURE_HAS_VSX)
               ? __strcpy_power7
             : __strcpy_ppc);
+strong_alias (__libc_strcpy, strcpy)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
index 1eb6e51..5a70c8e 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,10 +29,12 @@ 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;
+extern __typeof (strncmp) __libc_strncmp;
+# undef strncmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strncmp,
+libc_ifunc (__libc_strncmp,
             (hwcap2 & PPC_FEATURE2_ARCH_2_07)
             ? __strncmp_power8 :
               (hwcap & PPC_FEATURE_HAS_VSX)
@@ -37,4 +42,5 @@ libc_ifunc (strncmp,
 		(hwcap & PPC_FEATURE_POWER4)
 		? __strncmp_power4
             : __strncmp_ppc);
+strong_alias (__libc_strncmp, strncmp)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy.c b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
index 0176514..2914e96 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,16 @@
 extern __typeof (strncpy) __strncpy_ppc attribute_hidden;
 extern __typeof (strncpy) __strncpy_power7 attribute_hidden;
 extern __typeof (strncpy) __strncpy_power8 attribute_hidden;
+extern __typeof (strncpy) __libc___strncpy;
+# undef strncpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
  ifunc symbol properly. */
-libc_ifunc (strncpy,
+libc_ifunc (__libc___strncpy,
             (hwcap2 & PPC_FEATURE2_ARCH_2_07)
             ? __strncpy_power8 :
               (hwcap & PPC_FEATURE_HAS_VSX)
               ? __strncpy_power7
             : __strncpy_ppc);
-
+strong_alias (__libc___strncpy, strncpy)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
index c4907e9..8a27746 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
@@ -17,19 +17,24 @@
    <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;
+extern __typeof (__strnlen) __libc___strnlen;
+# undef strnlen
+# undef __strnlen
 
-libc_ifunc (__strnlen,
+libc_ifunc (__libc___strnlen,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strnlen_power7
             : __strnlen_ppc);
-weak_alias (__strnlen, strnlen)
-libc_hidden_def (strnlen)
+strong_alias (__libc___strnlen, __strnlen)
+weak_alias (__libc___strnlen, strnlen)
 
 #else
 #include <string/strnlen.c>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
index 45742bc..bbbc477 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
@@ -18,18 +18,22 @@
 
 /* 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;
+extern __typeof (strrchr) __libc_strrchr;
+#undef strrchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strrchr,
+libc_ifunc (__libc_strrchr,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strrchr_power7
             : __strrchr_ppc);
-weak_alias (strrchr, rindex)
+strong_alias (__libc_strrchr, strrchr)
+weak_alias (__libc_strrchr, rindex)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strstr.c b/sysdeps/powerpc/powerpc64/multiarch/strstr.c
index 7efc4b0..afde4de 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strstr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strstr.c
@@ -18,17 +18,21 @@
 
 /* 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;
+extern __typeof (strstr) __libc_strstr;
+# undef strstr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strstr,
+libc_ifunc (__libc_strstr,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strstr_power7
             : __strstr_ppc);
+strong_alias (__libc_strstr, strstr)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcschr.c b/sysdeps/powerpc/powerpc64/multiarch/wcschr.c
index 44c9b97..3d12a6e 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,18 @@
 extern __typeof (wcschr) __wcschr_ppc attribute_hidden;
 extern __typeof (wcschr) __wcschr_power6 attribute_hidden;
 extern __typeof (wcschr) __wcschr_power7 attribute_hidden;
+extern __typeof (wcschr) __libc___wcschr;
+# undef wcschr
+# undef __wcschr
 
-libc_ifunc (__wcschr,
+libc_ifunc (__libc___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)
+strong_alias (__libc___wcschr, __wcschr)
+weak_alias (__libc___wcschr, wcschr)
 #else
 #undef libc_hidden_def
 #define libc_hidden_def(a)
-- 
2.3.0

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

* [PATCH 8/8] Use libc_ifunc macro for siglongjmp, longjmp in libpthread.
  2016-06-23 11:56 [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo Stefan Liebler
  2016-06-23 11:56 ` [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday Stefan Liebler
@ 2016-06-23 11:56 ` Stefan Liebler
  2016-07-04 14:05   ` Stefan Liebler
  2016-06-23 11:56 ` [PATCH 5/8] Use libc_ifunc macro for clock_* symbols in librt Stefan Liebler
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-06-23 11:56 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, joseph, carlos, munroesj

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                         | 23 +++++------------------
 sysdeps/unix/sysv/linux/s390/pt-longjmp.c |  4 ++--
 2 files changed, 7 insertions(+), 20 deletions(-)

diff --git a/nptl/pt-longjmp.c b/nptl/pt-longjmp.c
index a1cc286..7c452cb 100644
--- a/nptl/pt-longjmp.c
+++ b/nptl/pt-longjmp.c
@@ -32,24 +32,11 @@
 
 # if HAVE_IFUNC
 
-static __typeof (longjmp) *
-__attribute__ ((used))
-longjmp_resolve (void)
-{
-  return &__libc_longjmp;
-}
+#  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 +53,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] 47+ messages in thread

* [PATCH 6/8] Use libc_ifunc macro for system in libpthread.
  2016-06-23 11:56 [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo Stefan Liebler
                   ` (5 preceding siblings ...)
  2016-06-23 11:56 ` [PATCH 4/8] ppc: Use libc_ifunc macro for time, gettimeofday Stefan Liebler
@ 2016-06-23 14:16 ` Stefan Liebler
  2016-07-04 14:10   ` Stefan Liebler
  2016-06-29 12:56 ` [PING][PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo Stefan Liebler
                   ` (2 subsequent siblings)
  9 siblings, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-06-23 14:16 UTC (permalink / raw)
  To: libc-alpha; +Cc: stli, joseph, carlos, munroesj

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 | 18 +++---------------
 1 file changed, 3 insertions(+), 15 deletions(-)

diff --git a/nptl/pt-system.c b/nptl/pt-system.c
index 56f2a89..6515056 100644
--- a/nptl/pt-system.c
+++ b/nptl/pt-system.c
@@ -32,21 +32,9 @@
 
 # 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;
+#  define INIT_ARCH()
+libc_ifunc (system_ifunc, &__libc_system)
 
 # else  /* !HAVE_IFUNC */
 
-- 
2.3.0

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

* Re: [PING][PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-06-23 11:56 [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo Stefan Liebler
                   ` (6 preceding siblings ...)
  2016-06-23 14:16 ` [PATCH 6/8] Use libc_ifunc macro for system in libpthread Stefan Liebler
@ 2016-06-29 12:56 ` Stefan Liebler
  2016-07-04  7:25   ` Stefan Liebler
  2016-07-04  8:31 ` [PATCH " Florian Weimer
  2016-07-27 17:54 ` [PATCH " Paul E. Murphy
  9 siblings, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-06-29 12:56 UTC (permalink / raw)
  To: libc-alpha

PING

On 06/23/2016 01:55 PM, Stefan Liebler wrote:
> The current s390 ifunc resolver for vector optimized functions and the common
> libc_ifunc macro in include/libc-symbols.h uses something like that:
> 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.
> Usage 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:
> extern __typeof (__redirect___strnlen) __libc___strnlen;
> __typeof (__libc___strnlen) __libc___strnlen __attribute__ ((ifunc ("__resolve_strnlen")));
> strong_alias (__libc___strnlen, __strnlen)
> weak_alias (__libc___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 or if the __GI_* symbol
> targets to the ifunc symbol, 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.
>
> 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.
>
> Tested the whole patchset by building glibc and running the testsuite on s390,
> intel, power for 32/64bit. The __GI_* symbols targets the same functions as
> before.
>
> Okay to commit?
>
> Bye
> Stefan
>
> ChangeLog:
>
> 	* include/libc-symbols.h (__ifunc): New macro uses gcc attribute ifunc.
> 	(libc_ifunc, libm_ifunc): Use __ifunc as base macro.
> 	(libm_ifunc_init): New define.
> 	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c:
> 	Redirect ifunced function in header and create a copy of the prototype
> 	for using as ifunc function. Add appropiate aliases to the real symbol
> 	names.
> 	* 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/fpu/multiarch/s_isnanf.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/fpu/multiarch/s_isnanf.cLikewise.
> 	* 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/stpcpy.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.
> ---
>   include/libc-symbols.h                             | 23 +++++++++-------------
>   .../powerpc32/power4/fpu/multiarch/s_finite.c      | 12 +++++++++--
>   .../powerpc32/power4/fpu/multiarch/s_finitef.c     | 12 +++++++++--
>   .../powerpc32/power4/fpu/multiarch/s_isinf.c       | 12 +++++++++--
>   .../powerpc32/power4/fpu/multiarch/s_isinff.c      | 13 ++++++++++--
>   .../powerpc32/power4/fpu/multiarch/s_isnan.c       | 12 +++++++++--
>   .../powerpc32/power4/fpu/multiarch/s_isnanf.c      |  1 +
>   .../powerpc/powerpc32/power4/multiarch/memcmp.c    |  6 +++++-
>   .../powerpc/powerpc32/power4/multiarch/memcpy.c    |  8 +++++++-
>   .../powerpc/powerpc32/power4/multiarch/memmove.c   |  7 ++++++-
>   .../powerpc/powerpc32/power4/multiarch/mempcpy.c   | 13 +++++++++---
>   .../powerpc/powerpc32/power4/multiarch/memset.c    |  7 ++++++-
>   .../powerpc/powerpc32/power4/multiarch/rawmemchr.c |  8 ++++++--
>   .../powerpc/powerpc32/power4/multiarch/strchr.c    | 10 ++++++++--
>   .../powerpc/powerpc32/power4/multiarch/strlen.c    |  7 ++++++-
>   .../powerpc/powerpc32/power4/multiarch/strncmp.c   |  8 +++++++-
>   .../powerpc/powerpc32/power4/multiarch/strnlen.c   | 11 ++++++++---
>   sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c | 12 +++++++++--
>   .../powerpc/powerpc64/fpu/multiarch/s_finitef.c    | 12 +++++++++--
>   sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c  | 12 +++++++++--
>   sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c | 12 +++++++++--
>   sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c  | 12 +++++++++--
>   sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c |  1 +
>   sysdeps/powerpc/powerpc64/multiarch/memcmp.c       |  6 +++++-
>   sysdeps/powerpc/powerpc64/multiarch/mempcpy.c      | 13 +++++++++---
>   sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c    |  8 ++++++--
>   sysdeps/powerpc/powerpc64/multiarch/stpcpy.c       |  1 +
>   sysdeps/powerpc/powerpc64/multiarch/stpncpy.c      | 10 ++++++++--
>   sysdeps/powerpc/powerpc64/multiarch/strcat.c       |  6 +++++-
>   sysdeps/powerpc/powerpc64/multiarch/strchr.c       | 10 ++++++++--
>   sysdeps/powerpc/powerpc64/multiarch/strcmp.c       |  8 +++++++-
>   sysdeps/powerpc/powerpc64/multiarch/strcpy.c       |  6 +++++-
>   sysdeps/powerpc/powerpc64/multiarch/strncmp.c      |  8 +++++++-
>   sysdeps/powerpc/powerpc64/multiarch/strncpy.c      |  9 +++++++--
>   sysdeps/powerpc/powerpc64/multiarch/strnlen.c      | 11 ++++++++---
>   sysdeps/powerpc/powerpc64/multiarch/strrchr.c      |  8 ++++++--
>   sysdeps/powerpc/powerpc64/multiarch/strstr.c       |  6 +++++-
>   sysdeps/powerpc/powerpc64/multiarch/wcschr.c       | 11 ++++++++---
>   38 files changed, 277 insertions(+), 75 deletions(-)
>
> diff --git a/include/libc-symbols.h b/include/libc-symbols.h
> index 4548e09..a77308a 100644
> --- a/include/libc-symbols.h
> +++ b/include/libc-symbols.h
> @@ -714,26 +714,21 @@ for linking")
>   #endif
>
>   /* Marker used for indirection function symbols.  */
> -#define libc_ifunc(name, expr)						\
> -  extern void *name##_ifunc (void) __asm__ (#name);			\
> -  void *name##_ifunc (void)						\
> +#define __ifunc(name, expr, arg, init)					\
> +  extern __typeof (name) name __attribute__ ((ifunc(#name "_ifunc")));	\
> +  static void *name##_ifunc (arg)					\
>     {									\
> -    INIT_ARCH ();							\
> +    init ();								\
>       __typeof (name) *res = expr;					\
>       return res;								\
> -  }									\
> -  __asm__ (".type " #name ", %gnu_indirect_function");
> +  }
> +
> +#define libc_ifunc(name, expr) __ifunc (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, 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..ee643a1 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,13 +26,18 @@
>
>   extern __typeof (__finite) __finite_ppc32 attribute_hidden;
>   extern __typeof (__finite) __finite_power7 attribute_hidden;
> +extern __typeof (__finite) __libc___finite;
> +#undef __finite
> +#undef __finitef
> +#undef __finitel
>
> -libc_ifunc (__finite,
> +libc_ifunc (__libc___finite,
>   	    (hwcap & PPC_FEATURE_ARCH_2_06)
>   	    ? __finite_power7
>               : __finite_ppc32);
>
> -weak_alias (__finite, finite)
> +strong_alias (__libc___finite, __finite)
> +weak_alias (__libc___finite, finite)
>
>   #ifdef NO_LONG_DOUBLE
>   strong_alias (__finite, __finitel)
> diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c
> index 831c94f..f2a5389 100644
> --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c
> +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.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 <shlib-compat.h>
>   #include "init-arch.h"
> @@ -23,10 +26,15 @@
>   extern __typeof (__finitef) __finitef_ppc32 attribute_hidden;
>   /* The power7 finite(double) works for float.  */
>   extern __typeof (__finitef) __finite_power7 attribute_hidden;
> +extern __typeof (__finitef) __libc___finitef;
> +#undef __finite
> +#undef __finitef
> +#undef __finitel
>
> -libc_ifunc (__finitef,
> +libc_ifunc (__libc___finitef,
>   	    (hwcap & PPC_FEATURE_ARCH_2_06)
>   	    ? __finite_power7
>               : __finitef_ppc32);
>
> -weak_alias (__finitef, finitef)
> +strong_alias (__libc___finitef, __finitef)
> +weak_alias (__libc___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..7321631 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,13 +26,18 @@
>
>   extern __typeof (__isinf) __isinf_ppc32 attribute_hidden;
>   extern __typeof (__isinf) __isinf_power7 attribute_hidden;
> +extern __typeof (__isinf) __libc___isinf;
> +#undef __isinf
> +#undef __isinff
> +#undef __isinfl
>
> -libc_ifunc (__isinf,
> +libc_ifunc (__libc___isinf,
>   	    (hwcap & PPC_FEATURE_ARCH_2_06)
>   	    ? __isinf_power7
>               : __isinf_ppc32);
>
> -weak_alias (__isinf, isinf)
> +strong_alias (__libc___isinf, __isinf)
> +weak_alias (__libc___isinf, isinf)
>
>   #ifdef NO_LONG_DOUBLE
>   strong_alias (__isinf, __isinfl)
> diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c
> index 2ab83ee..75bb7dc 100644
> --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c
> +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.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,10 +27,16 @@
>   extern __typeof (__isinff) __isinff_ppc32 attribute_hidden;
>   /* The power7 isinf(double) works for float.  */
>   extern __typeof (__isinff) __isinf_power7 attribute_hidden;
> +extern __typeof (__isinff) __libc___isinff;
> +#undef __isinf
> +#undef __isinff
> +#undef __isinfl
>
> -libc_ifunc (__isinff,
> +
> +libc_ifunc (__libc___isinff,
>   	    (hwcap & PPC_FEATURE_ARCH_2_06)
>   	    ? __isinf_power7
>               : __isinff_ppc32);
>
> -weak_alias (__isinff, isinff)
> +strong_alias (__libc___isinff, __isinff)
> +weak_alias (__libc___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..99aa84b 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,8 +28,12 @@ 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;
> +extern __typeof (__isnan) __libc___isnan;
> +#undef __isnan
> +#undef __isnanf
> +#undef __isnanl
>
> -libc_ifunc (__isnan,
> +libc_ifunc (__libc___isnan,
>   	    (hwcap & PPC_FEATURE_ARCH_2_06)
>   	    ? __isnan_power7 :
>   	      (hwcap & PPC_FEATURE_ARCH_2_05)
> @@ -35,7 +42,8 @@ libc_ifunc (__isnan,
>   		? __isnan_power5
>               : __isnan_ppc32);
>
> -weak_alias (__isnan, isnan)
> +strong_alias (__libc___isnan, __isnan)
> +weak_alias (__libc___isnan, isnan)
>
>   #ifdef NO_LONG_DOUBLE
>   strong_alias (__isnan, __isnanl)
> diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
> index c43c0f3..304b2a7 100644
> --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
> +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
> @@ -35,4 +35,5 @@ libc_ifunc (__isnanf,
>   		? __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..c18814f 100644
> --- a/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c
> +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c
> @@ -18,17 +18,21 @@
>
>   /* 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;
> +extern __typeof (memcmp) __libc_memcmp;
> +# undef memcmp
>
>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>      ifunc symbol properly.  */
> -libc_ifunc (memcmp,
> +libc_ifunc (__libc_memcmp,
>               (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __memcmp_power7
>               : __memcmp_ppc);
> +strong_alias (__libc_memcmp, memcmp);
>   #endif
> diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c
> index f379e47..5e68152 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,10 +31,12 @@ 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;
> +extern __typeof (memcpy) __libc_memcpy;
> +# undef memcpy
>
>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>      ifunc symbol properly.  */
> -libc_ifunc (memcpy,
> +libc_ifunc (__libc_memcpy,
>               (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __memcpy_power7 :
>   	      (hwcap & PPC_FEATURE_ARCH_2_06)
> @@ -42,4 +46,6 @@ libc_ifunc (memcpy,
>   		  (hwcap & PPC_FEATURE_CELL_BE)
>   		  ? __memcpy_cell
>               : __memcpy_ppc);
> +
> +strong_alias (__libc_memcpy, memcpy);
>   #endif
> diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
> index 4173184..ee8ab0c 100644
> --- a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
> +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
> @@ -19,16 +19,21 @@
>   #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;
> +extern __typeof (__redirect_memmove) __libc_memmove;
> +# undef memmove
>
> -libc_ifunc (memmove,
> +libc_ifunc (__libc_memmove,
>               (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __memmove_power7
>               : __memmove_ppc);
> +
> +strong_alias (__libc_memmove, memmove);
>   #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..9b5dec9 100644
> --- a/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c
> +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c
> @@ -17,23 +17,30 @@
>      <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;
> +extern __typeof (__mempcpy) __libc___mempcpy;
> +# undef mempcpy
> +# undef __mempcpy
>
>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>      ifunc symbol properly.  */
> -libc_ifunc (__mempcpy,
> +libc_ifunc (__libc___mempcpy,
>   	    (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __mempcpy_power7
>               : __mempcpy_ppc);
>
> -weak_alias (__mempcpy, mempcpy)
> -libc_hidden_def (mempcpy)
> +strong_alias (__libc___mempcpy, __mempcpy)
> +weak_alias (__libc___mempcpy, 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..a759e57 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,17 @@
>   extern __typeof (memset) __memset_ppc attribute_hidden;
>   extern __typeof (memset) __memset_power6 attribute_hidden;
>   extern __typeof (memset) __memset_power7 attribute_hidden;
> +extern __typeof (memset) __libc_memset;
> +# undef memset
>
>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>      ifunc symbol properly.  */
> -libc_ifunc (memset,
> +libc_ifunc (__libc_memset,
>               (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __memset_power7 :
>   	      (hwcap & PPC_FEATURE_ARCH_2_05)
>   		? __memset_power6
>               : __memset_ppc);
> +
> +strong_alias (__libc_memset, memset);
>   #endif
> diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c b/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
> index f06030e..f31bd55 100644
> --- a/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
> +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
> @@ -17,21 +17,25 @@
>      <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;
> +extern __typeof (__rawmemchr) __libc___rawmemchr;
> +# undef __rawmemchr
>
>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>      ifunc symbol properly.  */
> -libc_ifunc (__rawmemchr,
> +libc_ifunc (__libc___rawmemchr,
>   	    (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __rawmemchr_power7
>               : __rawmemchr_ppc);
>
> -weak_alias (__rawmemchr, rawmemchr)
> +strong_alias (__libc___rawmemchr, __rawmemchr)
> +weak_alias (__libc___rawmemchr, rawmemchr)
>   #else
>   #include <string/rawmemchr.c>
>   #endif
> diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
> index 2cfde63..87284f9 100644
> --- a/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
> +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
> @@ -18,18 +18,24 @@
>
>   /* 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;
> +extern __typeof (strchr) __libc_strchr;
> +# undef strchr
>
>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>      ifunc symbol properly.  */
> -libc_ifunc (strchr,
> +libc_ifunc (__libc_strchr,
>   	    (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __strchr_power7
>               : __strchr_ppc);
> -weak_alias (strchr, index)
> +strong_alias (__libc_strchr, strchr)
> +weak_alias (__libc_strchr, index)
>   #endif
> diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
> index af5921a..f21c680 100644
> --- a/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
> +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
> @@ -17,15 +17,20 @@
>      <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;
> +extern __typeof (strlen) __libc_strlen;
> +# undef strlen
>
> -libc_ifunc (strlen,
> +libc_ifunc (__libc_strlen,
>               (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __strlen_power7
>               : __strlen_ppc);
> +
> +strong_alias (__libc_strlen, strlen)
>   #endif
> diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c
> index 7cc7628..ad3a17b 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,14 @@
>   extern __typeof (strncmp) __strncmp_ppc attribute_hidden;
>   extern __typeof (strncmp) __strncmp_power4 attribute_hidden;
>   extern __typeof (strncmp) __strncmp_power7 attribute_hidden;
> +extern __typeof (strncmp) __libc_strncmp;
> +# undef strncmp
>
>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>      ifunc symbol properly.  */
> -libc_ifunc (strncmp,
> +libc_ifunc (__libc_strncmp,
>               (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __strncmp_power7
>               : __strncmp_ppc);
> +strong_alias (__libc_strncmp, strncmp)
>   #endif
> diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
> index 8f1e7c9..d04d8b9 100644
> --- a/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
> +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
> @@ -17,17 +17,22 @@
>      <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;
> +extern __typeof (__strnlen) __libc___strnlen;
> +# undef strnlen
> +# undef __strnlen
>
> -libc_ifunc (__strnlen,
> +libc_ifunc (__libc___strnlen,
>               (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __strnlen_power7
>               : __strnlen_ppc);
> -weak_alias (__strnlen, strnlen)
> -libc_hidden_def (strnlen)
> +strong_alias (__libc___strnlen, __strnlen)
> +weak_alias (__libc___strnlen, strnlen)
>   #endif
> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
> index 067edc2..ed1934f 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,15 +27,20 @@
>   extern __typeof (__finite) __finite_ppc64 attribute_hidden;
>   extern __typeof (__finite) __finite_power7 attribute_hidden;
>   extern __typeof (__finite) __finite_power8 attribute_hidden;
> +extern __typeof (__finite) __libc___finite;
> +#undef __finite
> +#undef __finitef
> +#undef __finitel
>
> -libc_ifunc (__finite,
> +libc_ifunc (__libc___finite,
>   	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>   	    ? __finite_power8 :
>   	      (hwcap & PPC_FEATURE_ARCH_2_06)
>   	      ? __finite_power7
>               : __finite_ppc64);
>
> -weak_alias (__finite, finite)
> +strong_alias (__libc___finite, __finite)
> +weak_alias (__libc___finite, finite)
>
>   #ifdef NO_LONG_DOUBLE
>   strong_alias (__finite, __finitel)
> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
> index e0b4686..6da1313 100644
> --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
> +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.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 <shlib-compat.h>
>   #include "init-arch.h"
> @@ -24,12 +27,17 @@ 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;
> +extern __typeof (__finitef) __libc___finitef;
> +#undef __finite
> +#undef __finitef
> +#undef __finitel
>
> -libc_ifunc (__finitef,
> +libc_ifunc (__libc___finitef,
>   	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>   	    ? __finite_power8 :
>   	      (hwcap & PPC_FEATURE_ARCH_2_06)
>   	      ? __finite_power7
>               : __finitef_ppc64);
>
> -weak_alias (__finitef, finitef)
> +strong_alias (__libc___finitef, __finitef)
> +weak_alias (__libc___finitef, finitef)
> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
> index 07e159d..380dab8 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,15 +27,20 @@
>   extern __typeof (__isinf) __isinf_ppc64 attribute_hidden;
>   extern __typeof (__isinf) __isinf_power7 attribute_hidden;
>   extern __typeof (__isinf) __isinf_power8 attribute_hidden;
> +extern __typeof (__isinf) __libc___isinf;
> +#undef __isinf
> +#undef __isinff
> +#undef __isinfl
>
> -libc_ifunc (__isinf,
> +libc_ifunc (__libc___isinf,
>   	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>   	    ? __isinf_power8 :
>   	      (hwcap & PPC_FEATURE_ARCH_2_06)
>   	      ? __isinf_power7
>               : __isinf_ppc64);
>
> -weak_alias (__isinf, isinf)
> +strong_alias (__libc___isinf, __isinf)
> +weak_alias (__libc___isinf, isinf)
>
>   #ifdef NO_LONG_DOUBLE
>   strong_alias (__isinf, __isinfl)
> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
> index 2cb161b..065d218 100644
> --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
> +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.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>
> @@ -25,12 +28,17 @@ 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;
> +extern __typeof (__isinff) __libc___isinff;
> +#undef __isinf
> +#undef __isinff
> +#undef __isinfl
>
> -libc_ifunc (__isinff,
> +libc_ifunc (__libc___isinff,
>   	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>   	    ? __isinf_power8 :
>   	      (hwcap & PPC_FEATURE_ARCH_2_06)
>   	      ? __isinf_power7
>               : __isinff_ppc64);
>
> -weak_alias (__isinff, isinff)
> +strong_alias (__libc___isinff, __isinff)
> +weak_alias (__libc___isinff, isinff)
> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
> index a614f25..a2c9308 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,8 +30,12 @@ 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;
> +extern __typeof (__isnan) __libc___isnan;
> +#undef __isnan
> +#undef __isnanf
> +#undef __isnanl
>
> -libc_ifunc (__isnan,
> +libc_ifunc (__libc___isnan,
>   	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>   	    ? __isnan_power8 :
>   	      (hwcap & PPC_FEATURE_ARCH_2_06)
> @@ -41,7 +48,8 @@ libc_ifunc (__isnan,
>   		      ? __isnan_power5
>               : __isnan_ppc64);
>
> -weak_alias (__isnan, isnan)
> +strong_alias (__libc___isnan, __isnan)
> +weak_alias (__libc___isnan, isnan)
>
>   #ifdef NO_LONG_DOUBLE
>   strong_alias (__isnan, __isnanl)
> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
> index acbc131..72e9a07 100644
> --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
> +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
> @@ -40,4 +40,5 @@ libc_ifunc (__isnanf,
>   		      ? __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..b31aadf 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,18 @@
>   extern __typeof (memcmp) __memcmp_ppc attribute_hidden;
>   extern __typeof (memcmp) __memcmp_power4 attribute_hidden;
>   extern __typeof (memcmp) __memcmp_power7 attribute_hidden;
> +extern __typeof (memcmp) __libc_memcmp;
> +# undef memcmp
>
>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>      ifunc symbol properly.  */
> -libc_ifunc (memcmp,
> +libc_ifunc (__libc_memcmp,
>               (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __memcmp_power7 :
>   	      (hwcap & PPC_FEATURE_POWER4)
>   		? __memcmp_power4
>               : __memcmp_ppc);
> +strong_alias (__libc_memcmp, memcmp);
>   #else
>   #include <string/memcmp.c>
>   #endif
> diff --git a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
> index 3c77b5f..9b5dec9 100644
> --- a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
> +++ b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
> @@ -17,23 +17,30 @@
>      <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;
> +extern __typeof (__mempcpy) __libc___mempcpy;
> +# undef mempcpy
> +# undef __mempcpy
>
>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>      ifunc symbol properly.  */
> -libc_ifunc (__mempcpy,
> +libc_ifunc (__libc___mempcpy,
>   	    (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __mempcpy_power7
>               : __mempcpy_ppc);
>
> -weak_alias (__mempcpy, mempcpy)
> -libc_hidden_def (mempcpy)
> +strong_alias (__libc___mempcpy, __mempcpy)
> +weak_alias (__libc___mempcpy, 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..f31bd55 100644
> --- a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
> +++ b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
> @@ -17,21 +17,25 @@
>      <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;
> +extern __typeof (__rawmemchr) __libc___rawmemchr;
> +# undef __rawmemchr
>
>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>      ifunc symbol properly.  */
> -libc_ifunc (__rawmemchr,
> +libc_ifunc (__libc___rawmemchr,
>   	    (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __rawmemchr_power7
>               : __rawmemchr_ppc);
>
> -weak_alias (__rawmemchr, rawmemchr)
> +strong_alias (__libc___rawmemchr, __rawmemchr)
> +weak_alias (__libc___rawmemchr, rawmemchr)
>   #else
>   #include <string/rawmemchr.c>
>   #endif
> diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
> index bbc1691..3867b9e 100644
> --- a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
> +++ b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
> @@ -34,6 +34,7 @@ libc_ifunc (__stpcpy,
>               : __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..b5c7457 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,17 @@
>   extern __typeof (__stpncpy) __stpncpy_ppc attribute_hidden;
>   extern __typeof (__stpncpy) __stpncpy_power7 attribute_hidden;
>   extern __typeof (__stpncpy) __stpncpy_power8 attribute_hidden;
> +extern __typeof (__stpncpy) __libc___stpncpy;
> +# undef stpncpy
> +# undef __stpncpy
>
> -libc_ifunc (__stpncpy,
> +libc_ifunc (__libc___stpncpy,
>               (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>               ? __stpncpy_power8 :
>                 (hwcap & PPC_FEATURE_HAS_VSX)
>                 ? __stpncpy_power7
>               : __stpncpy_ppc);
>
> -weak_alias (__stpncpy, stpncpy)
> +strong_alias (__libc___stpncpy, __stpncpy)
> +weak_alias (__libc___stpncpy, stpncpy)
>   #endif
> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcat.c b/sysdeps/powerpc/powerpc64/multiarch/strcat.c
> index a2894ae..b4fd540 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,14 @@
>   extern __typeof (strcat) __strcat_ppc attribute_hidden;
>   extern __typeof (strcat) __strcat_power7 attribute_hidden;
>   extern __typeof (strcat) __strcat_power8 attribute_hidden;
> +extern __typeof (strcat) __libc_strcat;
> +# undef strcat
>
> -libc_ifunc (strcat,
> +libc_ifunc (__libc_strcat,
>               (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>               ? __strcat_power8 :
>                 (hwcap & PPC_FEATURE_HAS_VSX)
>                 ? __strcat_power7
>               : __strcat_ppc);
> +strong_alias (__libc_strcat, strcat)
>   #endif
> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchr.c b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
> index 2cfde63..87284f9 100644
> --- a/sysdeps/powerpc/powerpc64/multiarch/strchr.c
> +++ b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
> @@ -18,18 +18,24 @@
>
>   /* 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;
> +extern __typeof (strchr) __libc_strchr;
> +# undef strchr
>
>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>      ifunc symbol properly.  */
> -libc_ifunc (strchr,
> +libc_ifunc (__libc_strchr,
>   	    (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __strchr_power7
>               : __strchr_ppc);
> -weak_alias (strchr, index)
> +strong_alias (__libc_strchr, strchr)
> +weak_alias (__libc_strchr, index)
>   #endif
> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
> index aee888a..32ab75d 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,14 @@
>   extern __typeof (strcmp) __strcmp_ppc attribute_hidden;
>   extern __typeof (strcmp) __strcmp_power7 attribute_hidden;
>   extern __typeof (strcmp) __strcmp_power8 attribute_hidden;
> +extern __typeof (strcmp) __libc_strcmp;
> +# undef strcmp
>
> -libc_ifunc (strcmp,
> +libc_ifunc (__libc_strcmp,
>               (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>                 ? __strcmp_power8 :
>                 (hwcap & PPC_FEATURE_HAS_VSX)
>                 ? __strcmp_power7
>               : __strcmp_ppc);
> +strong_alias (__libc_strcmp, strcmp)
>   #endif
> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcpy.c b/sysdeps/powerpc/powerpc64/multiarch/strcpy.c
> index d2c3858..31d6c92 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,14 @@
>   extern __typeof (strcpy) __strcpy_ppc attribute_hidden;
>   extern __typeof (strcpy) __strcpy_power7 attribute_hidden;
>   extern __typeof (strcpy) __strcpy_power8 attribute_hidden;
> +extern __typeof (strcpy) __libc_strcpy;
> +#undef strcpy
>
> -libc_ifunc (strcpy,
> +libc_ifunc (__libc_strcpy,
>               (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>               ? __strcpy_power8 :
>                 (hwcap & PPC_FEATURE_HAS_VSX)
>                 ? __strcpy_power7
>               : __strcpy_ppc);
> +strong_alias (__libc_strcpy, strcpy)
>   #endif
> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
> index 1eb6e51..5a70c8e 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,10 +29,12 @@ 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;
> +extern __typeof (strncmp) __libc_strncmp;
> +# undef strncmp
>
>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>      ifunc symbol properly.  */
> -libc_ifunc (strncmp,
> +libc_ifunc (__libc_strncmp,
>               (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>               ? __strncmp_power8 :
>                 (hwcap & PPC_FEATURE_HAS_VSX)
> @@ -37,4 +42,5 @@ libc_ifunc (strncmp,
>   		(hwcap & PPC_FEATURE_POWER4)
>   		? __strncmp_power4
>               : __strncmp_ppc);
> +strong_alias (__libc_strncmp, strncmp)
>   #endif
> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy.c b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
> index 0176514..2914e96 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,16 @@
>   extern __typeof (strncpy) __strncpy_ppc attribute_hidden;
>   extern __typeof (strncpy) __strncpy_power7 attribute_hidden;
>   extern __typeof (strncpy) __strncpy_power8 attribute_hidden;
> +extern __typeof (strncpy) __libc___strncpy;
> +# undef strncpy
>
>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>    ifunc symbol properly. */
> -libc_ifunc (strncpy,
> +libc_ifunc (__libc___strncpy,
>               (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>               ? __strncpy_power8 :
>                 (hwcap & PPC_FEATURE_HAS_VSX)
>                 ? __strncpy_power7
>               : __strncpy_ppc);
> -
> +strong_alias (__libc___strncpy, strncpy)
>   #endif
> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
> index c4907e9..8a27746 100644
> --- a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
> +++ b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
> @@ -17,19 +17,24 @@
>      <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;
> +extern __typeof (__strnlen) __libc___strnlen;
> +# undef strnlen
> +# undef __strnlen
>
> -libc_ifunc (__strnlen,
> +libc_ifunc (__libc___strnlen,
>               (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __strnlen_power7
>               : __strnlen_ppc);
> -weak_alias (__strnlen, strnlen)
> -libc_hidden_def (strnlen)
> +strong_alias (__libc___strnlen, __strnlen)
> +weak_alias (__libc___strnlen, strnlen)
>
>   #else
>   #include <string/strnlen.c>
> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
> index 45742bc..bbbc477 100644
> --- a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
> +++ b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
> @@ -18,18 +18,22 @@
>
>   /* 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;
> +extern __typeof (strrchr) __libc_strrchr;
> +#undef strrchr
>
>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>      ifunc symbol properly.  */
> -libc_ifunc (strrchr,
> +libc_ifunc (__libc_strrchr,
>               (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __strrchr_power7
>               : __strrchr_ppc);
> -weak_alias (strrchr, rindex)
> +strong_alias (__libc_strrchr, strrchr)
> +weak_alias (__libc_strrchr, rindex)
>   #endif
> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strstr.c b/sysdeps/powerpc/powerpc64/multiarch/strstr.c
> index 7efc4b0..afde4de 100644
> --- a/sysdeps/powerpc/powerpc64/multiarch/strstr.c
> +++ b/sysdeps/powerpc/powerpc64/multiarch/strstr.c
> @@ -18,17 +18,21 @@
>
>   /* 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;
> +extern __typeof (strstr) __libc_strstr;
> +# undef strstr
>
>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>      ifunc symbol properly.  */
> -libc_ifunc (strstr,
> +libc_ifunc (__libc_strstr,
>               (hwcap & PPC_FEATURE_HAS_VSX)
>               ? __strstr_power7
>               : __strstr_ppc);
> +strong_alias (__libc_strstr, strstr)
>   #endif
> diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcschr.c b/sysdeps/powerpc/powerpc64/multiarch/wcschr.c
> index 44c9b97..3d12a6e 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,18 @@
>   extern __typeof (wcschr) __wcschr_ppc attribute_hidden;
>   extern __typeof (wcschr) __wcschr_power6 attribute_hidden;
>   extern __typeof (wcschr) __wcschr_power7 attribute_hidden;
> +extern __typeof (wcschr) __libc___wcschr;
> +# undef wcschr
> +# undef __wcschr
>
> -libc_ifunc (__wcschr,
> +libc_ifunc (__libc___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)
> +strong_alias (__libc___wcschr, __wcschr)
> +weak_alias (__libc___wcschr, wcschr)
>   #else
>   #undef libc_hidden_def
>   #define libc_hidden_def(a)
>

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

* Re: [PING][PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-06-29 12:56 ` [PING][PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo Stefan Liebler
@ 2016-07-04  7:25   ` Stefan Liebler
  0 siblings, 0 replies; 47+ messages in thread
From: Stefan Liebler @ 2016-07-04  7:25 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joseph S. Myers, Carlos O'Donell, munroesj

PING

On 06/29/2016 02:55 PM, Stefan Liebler wrote:
> PING
>
> On 06/23/2016 01:55 PM, Stefan Liebler wrote:
>> The current s390 ifunc resolver for vector optimized functions and the
>> common
>> libc_ifunc macro in include/libc-symbols.h uses something like that:
>> 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.
>> Usage 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:
>> extern __typeof (__redirect___strnlen) __libc___strnlen;
>> __typeof (__libc___strnlen) __libc___strnlen __attribute__ ((ifunc
>> ("__resolve_strnlen")));
>> strong_alias (__libc___strnlen, __strnlen)
>> weak_alias (__libc___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 or if the __GI_*
>> symbol
>> targets to the ifunc symbol, 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.
>>
>> 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.
>>
>> Tested the whole patchset by building glibc and running the testsuite
>> on s390,
>> intel, power for 32/64bit. The __GI_* symbols targets the same
>> functions as
>> before.
>>
>> Okay to commit?
>>
>> Bye
>> Stefan
>>
>> ChangeLog:
>>
>>     * include/libc-symbols.h (__ifunc): New macro uses gcc attribute
>> ifunc.
>>     (libc_ifunc, libm_ifunc): Use __ifunc as base macro.
>>     (libm_ifunc_init): New define.
>>     * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c:
>>     Redirect ifunced function in header and create a copy of the
>> prototype
>>     for using as ifunc function. Add appropiate aliases to the real
>> symbol
>>     names.
>>     * 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/fpu/multiarch/s_isnanf.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/fpu/multiarch/s_isnanf.cLikewise.
>>     * 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/stpcpy.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.
>> ---
>>   include/libc-symbols.h                             | 23
>> +++++++++-------------
>>   .../powerpc32/power4/fpu/multiarch/s_finite.c      | 12 +++++++++--
>>   .../powerpc32/power4/fpu/multiarch/s_finitef.c     | 12 +++++++++--
>>   .../powerpc32/power4/fpu/multiarch/s_isinf.c       | 12 +++++++++--
>>   .../powerpc32/power4/fpu/multiarch/s_isinff.c      | 13 ++++++++++--
>>   .../powerpc32/power4/fpu/multiarch/s_isnan.c       | 12 +++++++++--
>>   .../powerpc32/power4/fpu/multiarch/s_isnanf.c      |  1 +
>>   .../powerpc/powerpc32/power4/multiarch/memcmp.c    |  6 +++++-
>>   .../powerpc/powerpc32/power4/multiarch/memcpy.c    |  8 +++++++-
>>   .../powerpc/powerpc32/power4/multiarch/memmove.c   |  7 ++++++-
>>   .../powerpc/powerpc32/power4/multiarch/mempcpy.c   | 13 +++++++++---
>>   .../powerpc/powerpc32/power4/multiarch/memset.c    |  7 ++++++-
>>   .../powerpc/powerpc32/power4/multiarch/rawmemchr.c |  8 ++++++--
>>   .../powerpc/powerpc32/power4/multiarch/strchr.c    | 10 ++++++++--
>>   .../powerpc/powerpc32/power4/multiarch/strlen.c    |  7 ++++++-
>>   .../powerpc/powerpc32/power4/multiarch/strncmp.c   |  8 +++++++-
>>   .../powerpc/powerpc32/power4/multiarch/strnlen.c   | 11 ++++++++---
>>   sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c | 12 +++++++++--
>>   .../powerpc/powerpc64/fpu/multiarch/s_finitef.c    | 12 +++++++++--
>>   sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c  | 12 +++++++++--
>>   sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c | 12 +++++++++--
>>   sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c  | 12 +++++++++--
>>   sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c |  1 +
>>   sysdeps/powerpc/powerpc64/multiarch/memcmp.c       |  6 +++++-
>>   sysdeps/powerpc/powerpc64/multiarch/mempcpy.c      | 13 +++++++++---
>>   sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c    |  8 ++++++--
>>   sysdeps/powerpc/powerpc64/multiarch/stpcpy.c       |  1 +
>>   sysdeps/powerpc/powerpc64/multiarch/stpncpy.c      | 10 ++++++++--
>>   sysdeps/powerpc/powerpc64/multiarch/strcat.c       |  6 +++++-
>>   sysdeps/powerpc/powerpc64/multiarch/strchr.c       | 10 ++++++++--
>>   sysdeps/powerpc/powerpc64/multiarch/strcmp.c       |  8 +++++++-
>>   sysdeps/powerpc/powerpc64/multiarch/strcpy.c       |  6 +++++-
>>   sysdeps/powerpc/powerpc64/multiarch/strncmp.c      |  8 +++++++-
>>   sysdeps/powerpc/powerpc64/multiarch/strncpy.c      |  9 +++++++--
>>   sysdeps/powerpc/powerpc64/multiarch/strnlen.c      | 11 ++++++++---
>>   sysdeps/powerpc/powerpc64/multiarch/strrchr.c      |  8 ++++++--
>>   sysdeps/powerpc/powerpc64/multiarch/strstr.c       |  6 +++++-
>>   sysdeps/powerpc/powerpc64/multiarch/wcschr.c       | 11 ++++++++---
>>   38 files changed, 277 insertions(+), 75 deletions(-)
>>
>> diff --git a/include/libc-symbols.h b/include/libc-symbols.h
>> index 4548e09..a77308a 100644
>> --- a/include/libc-symbols.h
>> +++ b/include/libc-symbols.h
>> @@ -714,26 +714,21 @@ for linking")
>>   #endif
>>
>>   /* Marker used for indirection function symbols.  */
>> -#define libc_ifunc(name, expr)                        \
>> -  extern void *name##_ifunc (void) __asm__ (#name);            \
>> -  void *name##_ifunc (void)                        \
>> +#define __ifunc(name, expr, arg, init)                    \
>> +  extern __typeof (name) name __attribute__ ((ifunc(#name
>> "_ifunc")));    \
>> +  static void *name##_ifunc (arg)                    \
>>     {                                    \
>> -    INIT_ARCH ();                            \
>> +    init ();                                \
>>       __typeof (name) *res = expr;                    \
>>       return res;                                \
>> -  }                                    \
>> -  __asm__ (".type " #name ", %gnu_indirect_function");
>> +  }
>> +
>> +#define libc_ifunc(name, expr) __ifunc (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, 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..ee643a1 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,13 +26,18 @@
>>
>>   extern __typeof (__finite) __finite_ppc32 attribute_hidden;
>>   extern __typeof (__finite) __finite_power7 attribute_hidden;
>> +extern __typeof (__finite) __libc___finite;
>> +#undef __finite
>> +#undef __finitef
>> +#undef __finitel
>>
>> -libc_ifunc (__finite,
>> +libc_ifunc (__libc___finite,
>>           (hwcap & PPC_FEATURE_ARCH_2_06)
>>           ? __finite_power7
>>               : __finite_ppc32);
>>
>> -weak_alias (__finite, finite)
>> +strong_alias (__libc___finite, __finite)
>> +weak_alias (__libc___finite, finite)
>>
>>   #ifdef NO_LONG_DOUBLE
>>   strong_alias (__finite, __finitel)
>> diff --git
>> a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c
>> b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c
>> index 831c94f..f2a5389 100644
>> --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c
>> +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.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 <shlib-compat.h>
>>   #include "init-arch.h"
>> @@ -23,10 +26,15 @@
>>   extern __typeof (__finitef) __finitef_ppc32 attribute_hidden;
>>   /* The power7 finite(double) works for float.  */
>>   extern __typeof (__finitef) __finite_power7 attribute_hidden;
>> +extern __typeof (__finitef) __libc___finitef;
>> +#undef __finite
>> +#undef __finitef
>> +#undef __finitel
>>
>> -libc_ifunc (__finitef,
>> +libc_ifunc (__libc___finitef,
>>           (hwcap & PPC_FEATURE_ARCH_2_06)
>>           ? __finite_power7
>>               : __finitef_ppc32);
>>
>> -weak_alias (__finitef, finitef)
>> +strong_alias (__libc___finitef, __finitef)
>> +weak_alias (__libc___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..7321631 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,13 +26,18 @@
>>
>>   extern __typeof (__isinf) __isinf_ppc32 attribute_hidden;
>>   extern __typeof (__isinf) __isinf_power7 attribute_hidden;
>> +extern __typeof (__isinf) __libc___isinf;
>> +#undef __isinf
>> +#undef __isinff
>> +#undef __isinfl
>>
>> -libc_ifunc (__isinf,
>> +libc_ifunc (__libc___isinf,
>>           (hwcap & PPC_FEATURE_ARCH_2_06)
>>           ? __isinf_power7
>>               : __isinf_ppc32);
>>
>> -weak_alias (__isinf, isinf)
>> +strong_alias (__libc___isinf, __isinf)
>> +weak_alias (__libc___isinf, isinf)
>>
>>   #ifdef NO_LONG_DOUBLE
>>   strong_alias (__isinf, __isinfl)
>> diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c
>> b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c
>> index 2ab83ee..75bb7dc 100644
>> --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c
>> +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.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,10 +27,16 @@
>>   extern __typeof (__isinff) __isinff_ppc32 attribute_hidden;
>>   /* The power7 isinf(double) works for float.  */
>>   extern __typeof (__isinff) __isinf_power7 attribute_hidden;
>> +extern __typeof (__isinff) __libc___isinff;
>> +#undef __isinf
>> +#undef __isinff
>> +#undef __isinfl
>>
>> -libc_ifunc (__isinff,
>> +
>> +libc_ifunc (__libc___isinff,
>>           (hwcap & PPC_FEATURE_ARCH_2_06)
>>           ? __isinf_power7
>>               : __isinff_ppc32);
>>
>> -weak_alias (__isinff, isinff)
>> +strong_alias (__libc___isinff, __isinff)
>> +weak_alias (__libc___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..99aa84b 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,8 +28,12 @@ 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;
>> +extern __typeof (__isnan) __libc___isnan;
>> +#undef __isnan
>> +#undef __isnanf
>> +#undef __isnanl
>>
>> -libc_ifunc (__isnan,
>> +libc_ifunc (__libc___isnan,
>>           (hwcap & PPC_FEATURE_ARCH_2_06)
>>           ? __isnan_power7 :
>>             (hwcap & PPC_FEATURE_ARCH_2_05)
>> @@ -35,7 +42,8 @@ libc_ifunc (__isnan,
>>           ? __isnan_power5
>>               : __isnan_ppc32);
>>
>> -weak_alias (__isnan, isnan)
>> +strong_alias (__libc___isnan, __isnan)
>> +weak_alias (__libc___isnan, isnan)
>>
>>   #ifdef NO_LONG_DOUBLE
>>   strong_alias (__isnan, __isnanl)
>> diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
>> b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
>> index c43c0f3..304b2a7 100644
>> --- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
>> +++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
>> @@ -35,4 +35,5 @@ libc_ifunc (__isnanf,
>>           ? __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..c18814f 100644
>> --- a/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c
>> +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c
>> @@ -18,17 +18,21 @@
>>
>>   /* 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;
>> +extern __typeof (memcmp) __libc_memcmp;
>> +# undef memcmp
>>
>>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>>      ifunc symbol properly.  */
>> -libc_ifunc (memcmp,
>> +libc_ifunc (__libc_memcmp,
>>               (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __memcmp_power7
>>               : __memcmp_ppc);
>> +strong_alias (__libc_memcmp, memcmp);
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c
>> b/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c
>> index f379e47..5e68152 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,10 +31,12 @@ 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;
>> +extern __typeof (memcpy) __libc_memcpy;
>> +# undef memcpy
>>
>>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>>      ifunc symbol properly.  */
>> -libc_ifunc (memcpy,
>> +libc_ifunc (__libc_memcpy,
>>               (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __memcpy_power7 :
>>             (hwcap & PPC_FEATURE_ARCH_2_06)
>> @@ -42,4 +46,6 @@ libc_ifunc (memcpy,
>>             (hwcap & PPC_FEATURE_CELL_BE)
>>             ? __memcpy_cell
>>               : __memcpy_ppc);
>> +
>> +strong_alias (__libc_memcpy, memcpy);
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
>> b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
>> index 4173184..ee8ab0c 100644
>> --- a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
>> +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
>> @@ -19,16 +19,21 @@
>>   #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;
>> +extern __typeof (__redirect_memmove) __libc_memmove;
>> +# undef memmove
>>
>> -libc_ifunc (memmove,
>> +libc_ifunc (__libc_memmove,
>>               (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __memmove_power7
>>               : __memmove_ppc);
>> +
>> +strong_alias (__libc_memmove, memmove);
>>   #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..9b5dec9 100644
>> --- a/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c
>> +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c
>> @@ -17,23 +17,30 @@
>>      <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;
>> +extern __typeof (__mempcpy) __libc___mempcpy;
>> +# undef mempcpy
>> +# undef __mempcpy
>>
>>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>>      ifunc symbol properly.  */
>> -libc_ifunc (__mempcpy,
>> +libc_ifunc (__libc___mempcpy,
>>           (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __mempcpy_power7
>>               : __mempcpy_ppc);
>>
>> -weak_alias (__mempcpy, mempcpy)
>> -libc_hidden_def (mempcpy)
>> +strong_alias (__libc___mempcpy, __mempcpy)
>> +weak_alias (__libc___mempcpy, 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..a759e57 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,17 @@
>>   extern __typeof (memset) __memset_ppc attribute_hidden;
>>   extern __typeof (memset) __memset_power6 attribute_hidden;
>>   extern __typeof (memset) __memset_power7 attribute_hidden;
>> +extern __typeof (memset) __libc_memset;
>> +# undef memset
>>
>>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>>      ifunc symbol properly.  */
>> -libc_ifunc (memset,
>> +libc_ifunc (__libc_memset,
>>               (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __memset_power7 :
>>             (hwcap & PPC_FEATURE_ARCH_2_05)
>>           ? __memset_power6
>>               : __memset_ppc);
>> +
>> +strong_alias (__libc_memset, memset);
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
>> b/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
>> index f06030e..f31bd55 100644
>> --- a/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
>> +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
>> @@ -17,21 +17,25 @@
>>      <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;
>> +extern __typeof (__rawmemchr) __libc___rawmemchr;
>> +# undef __rawmemchr
>>
>>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>>      ifunc symbol properly.  */
>> -libc_ifunc (__rawmemchr,
>> +libc_ifunc (__libc___rawmemchr,
>>           (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __rawmemchr_power7
>>               : __rawmemchr_ppc);
>>
>> -weak_alias (__rawmemchr, rawmemchr)
>> +strong_alias (__libc___rawmemchr, __rawmemchr)
>> +weak_alias (__libc___rawmemchr, rawmemchr)
>>   #else
>>   #include <string/rawmemchr.c>
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
>> b/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
>> index 2cfde63..87284f9 100644
>> --- a/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
>> +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
>> @@ -18,18 +18,24 @@
>>
>>   /* 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;
>> +extern __typeof (strchr) __libc_strchr;
>> +# undef strchr
>>
>>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>>      ifunc symbol properly.  */
>> -libc_ifunc (strchr,
>> +libc_ifunc (__libc_strchr,
>>           (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __strchr_power7
>>               : __strchr_ppc);
>> -weak_alias (strchr, index)
>> +strong_alias (__libc_strchr, strchr)
>> +weak_alias (__libc_strchr, index)
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
>> b/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
>> index af5921a..f21c680 100644
>> --- a/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
>> +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
>> @@ -17,15 +17,20 @@
>>      <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;
>> +extern __typeof (strlen) __libc_strlen;
>> +# undef strlen
>>
>> -libc_ifunc (strlen,
>> +libc_ifunc (__libc_strlen,
>>               (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __strlen_power7
>>               : __strlen_ppc);
>> +
>> +strong_alias (__libc_strlen, strlen)
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c
>> b/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c
>> index 7cc7628..ad3a17b 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,14 @@
>>   extern __typeof (strncmp) __strncmp_ppc attribute_hidden;
>>   extern __typeof (strncmp) __strncmp_power4 attribute_hidden;
>>   extern __typeof (strncmp) __strncmp_power7 attribute_hidden;
>> +extern __typeof (strncmp) __libc_strncmp;
>> +# undef strncmp
>>
>>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>>      ifunc symbol properly.  */
>> -libc_ifunc (strncmp,
>> +libc_ifunc (__libc_strncmp,
>>               (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __strncmp_power7
>>               : __strncmp_ppc);
>> +strong_alias (__libc_strncmp, strncmp)
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
>> b/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
>> index 8f1e7c9..d04d8b9 100644
>> --- a/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
>> +++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
>> @@ -17,17 +17,22 @@
>>      <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;
>> +extern __typeof (__strnlen) __libc___strnlen;
>> +# undef strnlen
>> +# undef __strnlen
>>
>> -libc_ifunc (__strnlen,
>> +libc_ifunc (__libc___strnlen,
>>               (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __strnlen_power7
>>               : __strnlen_ppc);
>> -weak_alias (__strnlen, strnlen)
>> -libc_hidden_def (strnlen)
>> +strong_alias (__libc___strnlen, __strnlen)
>> +weak_alias (__libc___strnlen, strnlen)
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
>> b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
>> index 067edc2..ed1934f 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,15 +27,20 @@
>>   extern __typeof (__finite) __finite_ppc64 attribute_hidden;
>>   extern __typeof (__finite) __finite_power7 attribute_hidden;
>>   extern __typeof (__finite) __finite_power8 attribute_hidden;
>> +extern __typeof (__finite) __libc___finite;
>> +#undef __finite
>> +#undef __finitef
>> +#undef __finitel
>>
>> -libc_ifunc (__finite,
>> +libc_ifunc (__libc___finite,
>>           (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>>           ? __finite_power8 :
>>             (hwcap & PPC_FEATURE_ARCH_2_06)
>>             ? __finite_power7
>>               : __finite_ppc64);
>>
>> -weak_alias (__finite, finite)
>> +strong_alias (__libc___finite, __finite)
>> +weak_alias (__libc___finite, finite)
>>
>>   #ifdef NO_LONG_DOUBLE
>>   strong_alias (__finite, __finitel)
>> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
>> b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
>> index e0b4686..6da1313 100644
>> --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
>> +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.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 <shlib-compat.h>
>>   #include "init-arch.h"
>> @@ -24,12 +27,17 @@ 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;
>> +extern __typeof (__finitef) __libc___finitef;
>> +#undef __finite
>> +#undef __finitef
>> +#undef __finitel
>>
>> -libc_ifunc (__finitef,
>> +libc_ifunc (__libc___finitef,
>>           (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>>           ? __finite_power8 :
>>             (hwcap & PPC_FEATURE_ARCH_2_06)
>>             ? __finite_power7
>>               : __finitef_ppc64);
>>
>> -weak_alias (__finitef, finitef)
>> +strong_alias (__libc___finitef, __finitef)
>> +weak_alias (__libc___finitef, finitef)
>> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
>> b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
>> index 07e159d..380dab8 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,15 +27,20 @@
>>   extern __typeof (__isinf) __isinf_ppc64 attribute_hidden;
>>   extern __typeof (__isinf) __isinf_power7 attribute_hidden;
>>   extern __typeof (__isinf) __isinf_power8 attribute_hidden;
>> +extern __typeof (__isinf) __libc___isinf;
>> +#undef __isinf
>> +#undef __isinff
>> +#undef __isinfl
>>
>> -libc_ifunc (__isinf,
>> +libc_ifunc (__libc___isinf,
>>           (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>>           ? __isinf_power8 :
>>             (hwcap & PPC_FEATURE_ARCH_2_06)
>>             ? __isinf_power7
>>               : __isinf_ppc64);
>>
>> -weak_alias (__isinf, isinf)
>> +strong_alias (__libc___isinf, __isinf)
>> +weak_alias (__libc___isinf, isinf)
>>
>>   #ifdef NO_LONG_DOUBLE
>>   strong_alias (__isinf, __isinfl)
>> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
>> b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
>> index 2cb161b..065d218 100644
>> --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
>> +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.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>
>> @@ -25,12 +28,17 @@ 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;
>> +extern __typeof (__isinff) __libc___isinff;
>> +#undef __isinf
>> +#undef __isinff
>> +#undef __isinfl
>>
>> -libc_ifunc (__isinff,
>> +libc_ifunc (__libc___isinff,
>>           (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>>           ? __isinf_power8 :
>>             (hwcap & PPC_FEATURE_ARCH_2_06)
>>             ? __isinf_power7
>>               : __isinff_ppc64);
>>
>> -weak_alias (__isinff, isinff)
>> +strong_alias (__libc___isinff, __isinff)
>> +weak_alias (__libc___isinff, isinff)
>> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
>> b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
>> index a614f25..a2c9308 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,8 +30,12 @@ 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;
>> +extern __typeof (__isnan) __libc___isnan;
>> +#undef __isnan
>> +#undef __isnanf
>> +#undef __isnanl
>>
>> -libc_ifunc (__isnan,
>> +libc_ifunc (__libc___isnan,
>>           (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>>           ? __isnan_power8 :
>>             (hwcap & PPC_FEATURE_ARCH_2_06)
>> @@ -41,7 +48,8 @@ libc_ifunc (__isnan,
>>                 ? __isnan_power5
>>               : __isnan_ppc64);
>>
>> -weak_alias (__isnan, isnan)
>> +strong_alias (__libc___isnan, __isnan)
>> +weak_alias (__libc___isnan, isnan)
>>
>>   #ifdef NO_LONG_DOUBLE
>>   strong_alias (__isnan, __isnanl)
>> diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
>> b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
>> index acbc131..72e9a07 100644
>> --- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
>> +++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
>> @@ -40,4 +40,5 @@ libc_ifunc (__isnanf,
>>                 ? __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..b31aadf 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,18 @@
>>   extern __typeof (memcmp) __memcmp_ppc attribute_hidden;
>>   extern __typeof (memcmp) __memcmp_power4 attribute_hidden;
>>   extern __typeof (memcmp) __memcmp_power7 attribute_hidden;
>> +extern __typeof (memcmp) __libc_memcmp;
>> +# undef memcmp
>>
>>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>>      ifunc symbol properly.  */
>> -libc_ifunc (memcmp,
>> +libc_ifunc (__libc_memcmp,
>>               (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __memcmp_power7 :
>>             (hwcap & PPC_FEATURE_POWER4)
>>           ? __memcmp_power4
>>               : __memcmp_ppc);
>> +strong_alias (__libc_memcmp, memcmp);
>>   #else
>>   #include <string/memcmp.c>
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
>> b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
>> index 3c77b5f..9b5dec9 100644
>> --- a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
>> +++ b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
>> @@ -17,23 +17,30 @@
>>      <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;
>> +extern __typeof (__mempcpy) __libc___mempcpy;
>> +# undef mempcpy
>> +# undef __mempcpy
>>
>>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>>      ifunc symbol properly.  */
>> -libc_ifunc (__mempcpy,
>> +libc_ifunc (__libc___mempcpy,
>>           (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __mempcpy_power7
>>               : __mempcpy_ppc);
>>
>> -weak_alias (__mempcpy, mempcpy)
>> -libc_hidden_def (mempcpy)
>> +strong_alias (__libc___mempcpy, __mempcpy)
>> +weak_alias (__libc___mempcpy, 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..f31bd55 100644
>> --- a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
>> +++ b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
>> @@ -17,21 +17,25 @@
>>      <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;
>> +extern __typeof (__rawmemchr) __libc___rawmemchr;
>> +# undef __rawmemchr
>>
>>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>>      ifunc symbol properly.  */
>> -libc_ifunc (__rawmemchr,
>> +libc_ifunc (__libc___rawmemchr,
>>           (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __rawmemchr_power7
>>               : __rawmemchr_ppc);
>>
>> -weak_alias (__rawmemchr, rawmemchr)
>> +strong_alias (__libc___rawmemchr, __rawmemchr)
>> +weak_alias (__libc___rawmemchr, rawmemchr)
>>   #else
>>   #include <string/rawmemchr.c>
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
>> b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
>> index bbc1691..3867b9e 100644
>> --- a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
>> +++ b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
>> @@ -34,6 +34,7 @@ libc_ifunc (__stpcpy,
>>               : __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..b5c7457 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,17 @@
>>   extern __typeof (__stpncpy) __stpncpy_ppc attribute_hidden;
>>   extern __typeof (__stpncpy) __stpncpy_power7 attribute_hidden;
>>   extern __typeof (__stpncpy) __stpncpy_power8 attribute_hidden;
>> +extern __typeof (__stpncpy) __libc___stpncpy;
>> +# undef stpncpy
>> +# undef __stpncpy
>>
>> -libc_ifunc (__stpncpy,
>> +libc_ifunc (__libc___stpncpy,
>>               (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>>               ? __stpncpy_power8 :
>>                 (hwcap & PPC_FEATURE_HAS_VSX)
>>                 ? __stpncpy_power7
>>               : __stpncpy_ppc);
>>
>> -weak_alias (__stpncpy, stpncpy)
>> +strong_alias (__libc___stpncpy, __stpncpy)
>> +weak_alias (__libc___stpncpy, stpncpy)
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcat.c
>> b/sysdeps/powerpc/powerpc64/multiarch/strcat.c
>> index a2894ae..b4fd540 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,14 @@
>>   extern __typeof (strcat) __strcat_ppc attribute_hidden;
>>   extern __typeof (strcat) __strcat_power7 attribute_hidden;
>>   extern __typeof (strcat) __strcat_power8 attribute_hidden;
>> +extern __typeof (strcat) __libc_strcat;
>> +# undef strcat
>>
>> -libc_ifunc (strcat,
>> +libc_ifunc (__libc_strcat,
>>               (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>>               ? __strcat_power8 :
>>                 (hwcap & PPC_FEATURE_HAS_VSX)
>>                 ? __strcat_power7
>>               : __strcat_ppc);
>> +strong_alias (__libc_strcat, strcat)
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchr.c
>> b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
>> index 2cfde63..87284f9 100644
>> --- a/sysdeps/powerpc/powerpc64/multiarch/strchr.c
>> +++ b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
>> @@ -18,18 +18,24 @@
>>
>>   /* 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;
>> +extern __typeof (strchr) __libc_strchr;
>> +# undef strchr
>>
>>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>>      ifunc symbol properly.  */
>> -libc_ifunc (strchr,
>> +libc_ifunc (__libc_strchr,
>>           (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __strchr_power7
>>               : __strchr_ppc);
>> -weak_alias (strchr, index)
>> +strong_alias (__libc_strchr, strchr)
>> +weak_alias (__libc_strchr, index)
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
>> b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
>> index aee888a..32ab75d 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,14 @@
>>   extern __typeof (strcmp) __strcmp_ppc attribute_hidden;
>>   extern __typeof (strcmp) __strcmp_power7 attribute_hidden;
>>   extern __typeof (strcmp) __strcmp_power8 attribute_hidden;
>> +extern __typeof (strcmp) __libc_strcmp;
>> +# undef strcmp
>>
>> -libc_ifunc (strcmp,
>> +libc_ifunc (__libc_strcmp,
>>               (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>>                 ? __strcmp_power8 :
>>                 (hwcap & PPC_FEATURE_HAS_VSX)
>>                 ? __strcmp_power7
>>               : __strcmp_ppc);
>> +strong_alias (__libc_strcmp, strcmp)
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcpy.c
>> b/sysdeps/powerpc/powerpc64/multiarch/strcpy.c
>> index d2c3858..31d6c92 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,14 @@
>>   extern __typeof (strcpy) __strcpy_ppc attribute_hidden;
>>   extern __typeof (strcpy) __strcpy_power7 attribute_hidden;
>>   extern __typeof (strcpy) __strcpy_power8 attribute_hidden;
>> +extern __typeof (strcpy) __libc_strcpy;
>> +#undef strcpy
>>
>> -libc_ifunc (strcpy,
>> +libc_ifunc (__libc_strcpy,
>>               (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>>               ? __strcpy_power8 :
>>                 (hwcap & PPC_FEATURE_HAS_VSX)
>>                 ? __strcpy_power7
>>               : __strcpy_ppc);
>> +strong_alias (__libc_strcpy, strcpy)
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
>> b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
>> index 1eb6e51..5a70c8e 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,10 +29,12 @@ 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;
>> +extern __typeof (strncmp) __libc_strncmp;
>> +# undef strncmp
>>
>>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>>      ifunc symbol properly.  */
>> -libc_ifunc (strncmp,
>> +libc_ifunc (__libc_strncmp,
>>               (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>>               ? __strncmp_power8 :
>>                 (hwcap & PPC_FEATURE_HAS_VSX)
>> @@ -37,4 +42,5 @@ libc_ifunc (strncmp,
>>           (hwcap & PPC_FEATURE_POWER4)
>>           ? __strncmp_power4
>>               : __strncmp_ppc);
>> +strong_alias (__libc_strncmp, strncmp)
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
>> b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
>> index 0176514..2914e96 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,16 @@
>>   extern __typeof (strncpy) __strncpy_ppc attribute_hidden;
>>   extern __typeof (strncpy) __strncpy_power7 attribute_hidden;
>>   extern __typeof (strncpy) __strncpy_power8 attribute_hidden;
>> +extern __typeof (strncpy) __libc___strncpy;
>> +# undef strncpy
>>
>>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>>    ifunc symbol properly. */
>> -libc_ifunc (strncpy,
>> +libc_ifunc (__libc___strncpy,
>>               (hwcap2 & PPC_FEATURE2_ARCH_2_07)
>>               ? __strncpy_power8 :
>>                 (hwcap & PPC_FEATURE_HAS_VSX)
>>                 ? __strncpy_power7
>>               : __strncpy_ppc);
>> -
>> +strong_alias (__libc___strncpy, strncpy)
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
>> b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
>> index c4907e9..8a27746 100644
>> --- a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
>> +++ b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
>> @@ -17,19 +17,24 @@
>>      <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;
>> +extern __typeof (__strnlen) __libc___strnlen;
>> +# undef strnlen
>> +# undef __strnlen
>>
>> -libc_ifunc (__strnlen,
>> +libc_ifunc (__libc___strnlen,
>>               (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __strnlen_power7
>>               : __strnlen_ppc);
>> -weak_alias (__strnlen, strnlen)
>> -libc_hidden_def (strnlen)
>> +strong_alias (__libc___strnlen, __strnlen)
>> +weak_alias (__libc___strnlen, strnlen)
>>
>>   #else
>>   #include <string/strnlen.c>
>> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
>> b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
>> index 45742bc..bbbc477 100644
>> --- a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
>> +++ b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
>> @@ -18,18 +18,22 @@
>>
>>   /* 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;
>> +extern __typeof (strrchr) __libc_strrchr;
>> +#undef strrchr
>>
>>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>>      ifunc symbol properly.  */
>> -libc_ifunc (strrchr,
>> +libc_ifunc (__libc_strrchr,
>>               (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __strrchr_power7
>>               : __strrchr_ppc);
>> -weak_alias (strrchr, rindex)
>> +strong_alias (__libc_strrchr, strrchr)
>> +weak_alias (__libc_strrchr, rindex)
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc64/multiarch/strstr.c
>> b/sysdeps/powerpc/powerpc64/multiarch/strstr.c
>> index 7efc4b0..afde4de 100644
>> --- a/sysdeps/powerpc/powerpc64/multiarch/strstr.c
>> +++ b/sysdeps/powerpc/powerpc64/multiarch/strstr.c
>> @@ -18,17 +18,21 @@
>>
>>   /* 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;
>> +extern __typeof (strstr) __libc_strstr;
>> +# undef strstr
>>
>>   /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
>>      ifunc symbol properly.  */
>> -libc_ifunc (strstr,
>> +libc_ifunc (__libc_strstr,
>>               (hwcap & PPC_FEATURE_HAS_VSX)
>>               ? __strstr_power7
>>               : __strstr_ppc);
>> +strong_alias (__libc_strstr, strstr)
>>   #endif
>> diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcschr.c
>> b/sysdeps/powerpc/powerpc64/multiarch/wcschr.c
>> index 44c9b97..3d12a6e 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,18 @@
>>   extern __typeof (wcschr) __wcschr_ppc attribute_hidden;
>>   extern __typeof (wcschr) __wcschr_power6 attribute_hidden;
>>   extern __typeof (wcschr) __wcschr_power7 attribute_hidden;
>> +extern __typeof (wcschr) __libc___wcschr;
>> +# undef wcschr
>> +# undef __wcschr
>>
>> -libc_ifunc (__wcschr,
>> +libc_ifunc (__libc___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)
>> +strong_alias (__libc___wcschr, __wcschr)
>> +weak_alias (__libc___wcschr, wcschr)
>>   #else
>>   #undef libc_hidden_def
>>   #define libc_hidden_def(a)
>>
>
>

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

* Re: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-06-23 11:56 [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo Stefan Liebler
                   ` (7 preceding siblings ...)
  2016-06-29 12:56 ` [PING][PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo Stefan Liebler
@ 2016-07-04  8:31 ` Florian Weimer
  2016-07-04 14:00   ` Stefan Liebler
  2016-07-27 17:54 ` [PATCH " Paul E. Murphy
  9 siblings, 1 reply; 47+ messages in thread
From: Florian Weimer @ 2016-07-04  8:31 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha; +Cc: joseph, carlos, munroesj

On 06/23/2016 01:55 PM, Stefan Liebler wrote:

> 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.
>
> 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.
>
> Tested the whole patchset by building glibc and running the testsuite on s390,
> intel, power for 32/64bit. The __GI_* symbols targets the same functions as
> before.
>
> Okay to commit?

These changes (i.e. patch 1/8) look reasonable to me.  Perhaps wait 
another day if someone else objects.

> ChangeLog:
>
> 	* include/libc-symbols.h (__ifunc): New macro uses gcc attribute ifunc.
> 	(libc_ifunc, libm_ifunc): Use __ifunc as base macro.
> 	(libm_ifunc_init): New define.
> 	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c:
> 	Redirect ifunced function in header and create a copy of the prototype
> 	for using as ifunc function. Add appropiate aliases to the real symbol

“appropriate“

>  /* Marker used for indirection function symbols.  */
> -#define libc_ifunc(name, expr)						\
> -  extern void *name##_ifunc (void) __asm__ (#name);			\
> -  void *name##_ifunc (void)						\
> +#define __ifunc(name, expr, arg, init)					\
> +  extern __typeof (name) name __attribute__ ((ifunc(#name "_ifunc")));	\

Space after ifunc.

Thanks,
Florian

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

* Re: [PATCH 2/8] s390: Refactor ifunc resolvers due to false debuginfo.
  2016-06-23 11:56 ` [PATCH 2/8] s390: Refactor ifunc resolvers due to false debuginfo Stefan Liebler
@ 2016-07-04  8:37   ` Florian Weimer
  2016-07-04 13:55     ` Stefan Liebler
  0 siblings, 1 reply; 47+ messages in thread
From: Florian Weimer @ 2016-07-04  8:37 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha; +Cc: joseph, carlos, munroesj

On 06/23/2016 01:55 PM, Stefan Liebler wrote:
> 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_libc_ifunc_init): New define.
> 	* sysdeps/s390/multiarch/memchr.c: Redirect ifunced function in header
> 	and create a copy of the prototype for using as ifunc function.
> 	Add appropiate aliases to the real symbol names.

“appropriate”

> +  __ifunc (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);

I don't think GNU style allows starting a line with a comma, and “:” 
should be at the start of the line, not the end.

Otherwise, the changes look reasonable.

Thanks,
Florian

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

* Re: [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday.
  2016-06-23 11:56 ` [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday Stefan Liebler
@ 2016-07-04  8:54   ` Florian Weimer
  2016-07-04 13:41     ` Adhemerval Zanella
  2016-07-04 13:53     ` Stefan Liebler
  2016-08-05  6:46   ` Stefan Liebler
  1 sibling, 2 replies; 47+ messages in thread
From: Florian Weimer @ 2016-07-04  8:54 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha; +Cc: joseph, carlos, munroesj

On 06/23/2016 01:55 PM, Stefan Liebler wrote:
> This patch uses the libc_ifunc 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.

I'm not sure if I understand what is going on here. 
sysdeps/unix/sysv/linux/x86/gettimeofday.c is compiled straight for 
x86_64, but wrapped on i386, right?

I wonder if it possible to avoid some of the preprocessor magic by 
introducing a separate x86_64 file.

Thanks,
Florian

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

* Re: [PATCH 5/8] Use libc_ifunc macro for clock_* symbols in librt.
  2016-06-23 11:56 ` [PATCH 5/8] Use libc_ifunc macro for clock_* symbols in librt Stefan Liebler
@ 2016-07-04  9:14   ` Florian Weimer
  2016-07-04 13:49     ` Stefan Liebler
  0 siblings, 1 reply; 47+ messages in thread
From: Florian Weimer @ 2016-07-04  9:14 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha; +Cc: joseph, carlos, munroesj

On 06/23/2016 01:55 PM, Stefan Liebler wrote:
> +# define INIT_ARCH()
> +# define COMPAT_REDIRECT(name, proto, arglist) libc_ifunc (name, &__##name)

Doesn't this cause INIT_ARCH redefinition warnings in some cases?

Thanks,
Florian

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

* Re: [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday.
  2016-07-04  8:54   ` Florian Weimer
@ 2016-07-04 13:41     ` Adhemerval Zanella
  2016-07-06 12:19       ` Florian Weimer
  2016-07-04 13:53     ` Stefan Liebler
  1 sibling, 1 reply; 47+ messages in thread
From: Adhemerval Zanella @ 2016-07-04 13:41 UTC (permalink / raw)
  To: libc-alpha



On 04/07/2016 05:54, Florian Weimer wrote:
> On 06/23/2016 01:55 PM, Stefan Liebler wrote:
>> This patch uses the libc_ifunc 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.
> 
> I'm not sure if I understand what is going on here. sysdeps/unix/sysv/linux/x86/gettimeofday.c is compiled straight for x86_64, but wrapped on i386, right?
> 

If I recall correctly i686 has the same issue as powerpc32, where ifunc for local
hidden symbols fails to resolve where called by another function library function.
This examples shows the issue:

$ cat test.c
#define libc_ifunc_hidden_def1(local, name)   \
    __asm__ (".globl " #local "\n\t"         \
             ".hidden " #local "\n\t"        \
             #local " = " #name);

#define libc_ifunc_hidden_def(name) \
  libc_ifunc_hidden_def1 (__GI_##name, name)

int foo (void) __attribute__ ((ifunc ("foo_ifunc")));

static int global = 1;

static int
f1 (void)
{
  return 0;
}

static int
f2 (void)
{
  return 1;
}

void *
foo_ifunc (void)
{
  return global == 1 ? f1 : f2;
}

libc_ifunc_hidden_def (foo)
$ cat test2.c 
#define __hidden_proto_hiddenattr(attrs...) \
  __attribute__ ((visibility ("hidden"), ##attrs))
#define hidden_proto(name, attrs...) \
  __hidden_proto (name, , __GI_##name, ##attrs)
#define __hidden_proto(name, thread, internal, attrs...)           \
  extern thread __typeof (name) name __asm__ (#internal) \
  __hidden_proto_hiddenattr (attrs);

int foo (void);
hidden_proto (foo)

int bar (void)
{
  return foo ();
}
$ cat main.c 
int bar (void);

int main ()
{
  return bar ();
}
$ gcc -Wall -fpic test.c -c -m32
$ gcc -Wall -fpic test2.c -c -m32
$ gcc -shared test.o test2.o -o libtest.so -m32
$ gcc -Wall main.c -c -m32
$ gcc main.o -o main -L. -ltest -m32
$ LD_LIBRARY_PATH=. ./main 
Segmentation fault (core dumped)

I am using binutils 2.26 from Ubuntu 16.04 and I am not sure if it has been fixed
in more recent versions.

> I wonder if it possible to avoid some of the preprocessor magic by introducing a separate x86_64 file.

I am not sure if it would be gain, the i386/gettimeofday.c is doing exactly what
it does not support (libc_ifunc_hidden_def symbol being called from other library
calls).  I think it worth a comment though.

Another possible cleanup could be consolidate powerpc and x86 gettimeofday
gettimeofay.

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

* Re: [PATCH 5/8] Use libc_ifunc macro for clock_* symbols in librt.
  2016-07-04  9:14   ` Florian Weimer
@ 2016-07-04 13:49     ` Stefan Liebler
  0 siblings, 0 replies; 47+ messages in thread
From: Stefan Liebler @ 2016-07-04 13:49 UTC (permalink / raw)
  To: libc-alpha

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

On 07/04/2016 11:14 AM, Florian Weimer wrote:
> On 06/23/2016 01:55 PM, Stefan Liebler wrote:
>> +# define INIT_ARCH()
>> +# define COMPAT_REDIRECT(name, proto, arglist) libc_ifunc (name,
>> &__##name)
>
> Doesn't this cause INIT_ARCH redefinition warnings in some cases?
>
> Thanks,
> Florian
>
At the moment INIT_ARCH is only defined in
-sysdeps/powerpc/powerpc32/power4/multiarch/init-arch.h
-sysdeps/x86/cpu-features.h

The latter one is included in ldsodefs.h which is included in dl-vdso.h.
Thus the undef is needed in x86/i386 time.c/gettimeofday.c.

I built and run testsuite for intel, power and s390. There did not occur 
a redefinition warning.

Nevertheless, this is a good point and I add an undef INIT_ARCH before 
the definition in this patch and the other "Use libc_ifunc macro for ABC 
in libDEF." patches.

[-- Attachment #2: 0005-Use-libc_ifunc-macro-for-clock_-symbols-in-librt.patch --]
[-- Type: text/x-patch, Size: 2593 bytes --]

From d80e99d0fcd917cdd66a8d9697e75de59e67b863 Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Mon, 4 Jul 2016 15:33:56 +0200
Subject: [PATCH 5/8] Use libc_ifunc macro for clock_* symbols in librt.

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] 47+ messages in thread

* Re: [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday.
  2016-07-04  8:54   ` Florian Weimer
  2016-07-04 13:41     ` Adhemerval Zanella
@ 2016-07-04 13:53     ` Stefan Liebler
  2016-07-06 11:42       ` Florian Weimer
  1 sibling, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-07-04 13:53 UTC (permalink / raw)
  To: libc-alpha

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

On 07/04/2016 10:54 AM, Florian Weimer wrote:
> On 06/23/2016 01:55 PM, Stefan Liebler wrote:
>> This patch uses the libc_ifunc 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.
>
> I'm not sure if I understand what is going on here.
> sysdeps/unix/sysv/linux/x86/gettimeofday.c is compiled straight for
> x86_64, but wrapped on i386, right?
Yes you are right, e.g. ...:
-x86_64 compiles sysdeps/unix/sysv/linux/x86/gettimeofday.c
-i686 compiles sysdeps/unix/sysv/linux/i386/gettimeofday.c

>
> I wonder if it possible to avoid some of the preprocessor magic by
> introducing a separate x86_64 file.
Do you mean moving x86/gettimeofday.c to x86_64/gettimeofday.c
and get rid of #include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>?

I think it won't save much of the preprocessor stuff.
The redirection of __gettimeofday in sys/time.h and the redifinition of 
libc_hidden_def are needed.
We can only save the define/undef __gettimeofday around inclusion of 
x86/gettimeofday.c. But then we have to duplicate the code.
In file sysdeps/unix/sysv/linux/i386/time.c we can't save anything.

>
> Thanks,
> Florian
>

The attached patch only updates the typo in ChangeLog.

[-- Attachment #2: 0003-i386-x86-Use-libc_ifunc-macro-for-time-gettimeofday.patch --]
[-- Type: text/x-patch, Size: 6281 bytes --]

From a8ea51a141f137447a6a483cb820bcc12b265675 Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Mon, 4 Jul 2016 15:33:56 +0200
Subject: [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday.

This patch uses the libc_ifunc 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 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 and create a copy of the prototype
	for using as ifunc function. Add appropriate aliases to the real symbol
	names.
	* 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 | 19 ++++++++++++++++---
 sysdeps/unix/sysv/linux/i386/time.c         | 15 ++++++++++++---
 sysdeps/unix/sysv/linux/x86/gettimeofday.c  | 20 ++++++--------------
 sysdeps/unix/sysv/linux/x86/time.c          | 18 +++++-------------
 5 files changed, 39 insertions(+), 48 deletions(-)

diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index 5938eae..b0ea8f4 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -730,21 +730,6 @@ for linking")
 #define libm_ifunc_init()
 #define libm_ifunc(name, expr) __ifunc (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..fc6cfdd 100644
--- a/sysdeps/unix/sysv/linux/i386/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
@@ -16,14 +16,27 @@
    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
 
-# undef libc_ifunc_hidden_def
-# define libc_ifunc_hidden_def(name)  \
-  libc_ifunc_hidden_def1 (__GI_##name, __gettimeofday_syscall)
+extern __typeof (__redirect___gettimeofday) __libc___gettimeofday;
+# define __gettimeofday __libc___gettimeofday
 
+# 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>
+
+#ifdef SHARED
+# undef __gettimeofday
+strong_alias (__libc___gettimeofday, __gettimeofday)
+#endif
diff --git a/sysdeps/unix/sysv/linux/i386/time.c b/sysdeps/unix/sysv/linux/i386/time.c
index 62b78b2..bacbf84 100644
--- a/sysdeps/unix/sysv/linux/i386/time.c
+++ b/sysdeps/unix/sysv/linux/i386/time.c
@@ -17,10 +17,19 @@
    <http://www.gnu.org/licenses/>.  */
 
 #ifdef SHARED
+# define time __redirect_time
+#endif
+
+#include <time.h>
+
+#ifdef SHARED
+# undef time
+
+extern __typeof (__redirect_time) 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..02f8d6e 100644
--- a/sysdeps/unix/sysv/linux/x86/gettimeofday.c
+++ b/sysdeps/unix/sysv/linux/x86/gettimeofday.c
@@ -29,20 +29,12 @@ __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)
+# 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 (__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..957d586 100644
--- a/sysdeps/unix/sysv/linux/x86/time.c
+++ b/sysdeps/unix/sysv/linux/x86/time.c
@@ -30,20 +30,12 @@ __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);
-
+#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 (time, (_dl_vdso_vsym ("__vdso_time", &linux26)
+		   ?:  &__time_syscall))
+libc_hidden_def (time)
 
 #else
 
-- 
2.3.0


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

* Re: [PATCH 2/8] s390: Refactor ifunc resolvers due to false debuginfo.
  2016-07-04  8:37   ` Florian Weimer
@ 2016-07-04 13:55     ` Stefan Liebler
  2016-07-29 14:55       ` Stefan Liebler
  0 siblings, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-07-04 13:55 UTC (permalink / raw)
  To: libc-alpha

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

On 07/04/2016 10:37 AM, Florian Weimer wrote:
> On 06/23/2016 01:55 PM, Stefan Liebler wrote:
>> 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_libc_ifunc_init): New define.
>>     * sysdeps/s390/multiarch/memchr.c: Redirect ifunced function in
>> header
>>     and create a copy of the prototype for using as ifunc function.
>>     Add appropiate aliases to the real symbol names.
>
> “appropriate”
Ok
>
>> +  __ifunc (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);
>
> I don't think GNU style allows starting a line with a comma, and “:”
> should be at the start of the line, not the end.
>
Ok, I corrected it. Thanks.
> Otherwise, the changes look reasonable.
>
> Thanks,
> Florian
>

[-- Attachment #2: 0002-s390-Refactor-ifunc-resolvers-due-to-false-debuginfo.patch --]
[-- Type: text/x-patch, Size: 27838 bytes --]

From f6e1567350d526b8f7746f49b9c99b4450eac4fe Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Mon, 4 Jul 2016 15:33:56 +0200
Subject: [PATCH 2/8] s390: Refactor ifunc resolvers due to false debuginfo.

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_libc_ifunc_init): New define.
	* sysdeps/s390/multiarch/memchr.c: Redirect ifunced function in header
	and create a copy of the prototype for using as ifunc function.
	Add appropriate aliases to the real symbol names.
	* 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  | 63 +++++++++++++--------------------
 sysdeps/s390/multiarch/memchr.c         |  7 +++-
 sysdeps/s390/multiarch/mempcpy.c        | 14 ++++++--
 sysdeps/s390/multiarch/rawmemchr.c      |  8 +++--
 sysdeps/s390/multiarch/stpcpy.c         | 13 +++++--
 sysdeps/s390/multiarch/stpncpy.c        | 10 ++++--
 sysdeps/s390/multiarch/strcat.c         |  6 +++-
 sysdeps/s390/multiarch/strchr.c         | 10 ++++--
 sysdeps/s390/multiarch/strcmp.c         |  9 +++--
 sysdeps/s390/multiarch/strcpy.c         |  7 +++-
 sysdeps/s390/multiarch/strcspn.c        |  8 ++++-
 sysdeps/s390/multiarch/strlen.c         |  6 +++-
 sysdeps/s390/multiarch/strncmp.c        | 11 +++---
 sysdeps/s390/multiarch/strncpy.c        |  9 ++++-
 sysdeps/s390/multiarch/strnlen.c        | 11 ++++--
 sysdeps/s390/multiarch/strpbrk.c        |  8 ++++-
 sysdeps/s390/multiarch/strrchr.c        |  8 +++--
 sysdeps/s390/multiarch/strspn.c         |  8 ++++-
 sysdeps/s390/multiarch/wcschr.c         | 11 ++++--
 sysdeps/s390/multiarch/wcscmp.c         |  8 +++--
 sysdeps/s390/multiarch/wcspbrk.c        |  6 +++-
 sysdeps/s390/multiarch/wcsspn.c         |  6 +++-
 sysdeps/s390/multiarch/wmemchr.c        | 11 ++++--
 sysdeps/s390/multiarch/wmemset.c        | 11 ++++--
 sysdeps/s390/s390-32/multiarch/memcmp.c |  9 +++--
 sysdeps/s390/s390-32/multiarch/memcpy.c |  7 +++-
 sysdeps/s390/s390-32/multiarch/memset.c |  7 +++-
 sysdeps/s390/s390-64/multiarch/memcmp.c |  9 +++--
 sysdeps/s390/s390-64/multiarch/memcpy.c |  7 +++-
 sysdeps/s390/s390-64/multiarch/memset.c |  7 +++-
 30 files changed, 225 insertions(+), 90 deletions(-)

diff --git a/sysdeps/s390/multiarch/ifunc-resolve.h b/sysdeps/s390/multiarch/ifunc-resolve.h
index 26e097a..f11b28b 100644
--- a/sysdeps/s390/multiarch/ifunc-resolve.h
+++ b/sysdeps/s390/multiarch/ifunc-resolve.h
@@ -40,53 +40,40 @@
 		       ".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(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 (FUNC) RESOLVERFUNC##_z196 attribute_hidden;		\
+  extern __typeof (FUNC) RESOLVERFUNC##_z10 attribute_hidden;           \
+  extern __typeof (FUNC) RESOLVERFUNC##_default attribute_hidden;       \
+  __ifunc (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)
 
+#define s390_vx_libc_ifunc_init()
 #define s390_vx_libc_ifunc2(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");
+  __ifunc (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..e7661df 100644
--- a/sysdeps/s390/multiarch/memchr.c
+++ b/sysdeps/s390/multiarch/memchr.c
@@ -17,8 +17,13 @@
    <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)
+extern __typeof (__redirect_memchr) __libc_memchr;
+s390_vx_libc_ifunc2 (__memchr, __libc_memchr)
+strong_alias (__libc_memchr, memchr)
+
 #endif
diff --git a/sysdeps/s390/multiarch/mempcpy.c b/sysdeps/s390/multiarch/mempcpy.c
index 34d8329..709d167 100644
--- a/sysdeps/s390/multiarch/mempcpy.c
+++ b/sysdeps/s390/multiarch/mempcpy.c
@@ -18,9 +18,17 @@
 
 
 #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");
+extern __typeof (__redirect_mempcpy) __libc___mempcpy;
+s390_libc_ifunc (____mempcpy, __libc___mempcpy)
+strong_alias (__libc___mempcpy, __mempcpy);
+weak_alias (__libc___mempcpy, mempcpy);
 #endif
diff --git a/sysdeps/s390/multiarch/rawmemchr.c b/sysdeps/s390/multiarch/rawmemchr.c
index 7186ccd..fac159f 100644
--- a/sysdeps/s390/multiarch/rawmemchr.c
+++ b/sysdeps/s390/multiarch/rawmemchr.c
@@ -17,11 +17,15 @@
    <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)
-weak_alias (__rawmemchr, rawmemchr)
+extern __typeof (__redirect___rawmemchr) __libc___rawmemchr;
+s390_vx_libc_ifunc2 (__rawmemchr, __libc___rawmemchr)
+strong_alias (__libc___rawmemchr, __rawmemchr)
+weak_alias (__libc___rawmemchr, rawmemchr)
 
 #else
 # include <string/rawmemchr.c>
diff --git a/sysdeps/s390/multiarch/stpcpy.c b/sysdeps/s390/multiarch/stpcpy.c
index dcde012..bae99ab 100644
--- a/sysdeps/s390/multiarch/stpcpy.c
+++ b/sysdeps/s390/multiarch/stpcpy.c
@@ -17,13 +17,20 @@
    <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)
-weak_alias (__stpcpy, stpcpy)
-libc_hidden_builtin_def (stpcpy)
+extern __typeof (__redirect___stpcpy) __libc___stpcpy;
+s390_vx_libc_ifunc2 (__stpcpy, __libc___stpcpy);
+strong_alias (__libc___stpcpy, __stpcpy)
+weak_alias (__libc___stpcpy, stpcpy)
 
 #else
 # include <string/stpcpy.c>
diff --git a/sysdeps/s390/multiarch/stpncpy.c b/sysdeps/s390/multiarch/stpncpy.c
index f5335b4..6c2b9bb 100644
--- a/sysdeps/s390/multiarch/stpncpy.c
+++ b/sysdeps/s390/multiarch/stpncpy.c
@@ -17,11 +17,17 @@
    <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)
-weak_alias (__stpncpy, stpncpy)
+extern __typeof (__redirect___stpncpy) __libc___stpncpy;
+s390_vx_libc_ifunc2 (__stpncpy, __libc___stpncpy)
+strong_alias (__libc___stpncpy, __stpncpy)
+weak_alias (__libc___stpncpy, stpncpy)
 
 #else
 # include <string/stpncpy.c>
diff --git a/sysdeps/s390/multiarch/strcat.c b/sysdeps/s390/multiarch/strcat.c
index c3b5e1c..f1db424 100644
--- a/sysdeps/s390/multiarch/strcat.c
+++ b/sysdeps/s390/multiarch/strcat.c
@@ -17,10 +17,14 @@
    <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)
+extern __typeof (__redirect_strcat) __libc_strcat;
+s390_vx_libc_ifunc2 (__strcat, __libc_strcat)
+strong_alias (__libc_strcat, strcat)
 
 #else
 # include <string/strcat.c>
diff --git a/sysdeps/s390/multiarch/strchr.c b/sysdeps/s390/multiarch/strchr.c
index 3c8c7e4..c8d40e7 100644
--- a/sysdeps/s390/multiarch/strchr.c
+++ b/sysdeps/s390/multiarch/strchr.c
@@ -17,11 +17,17 @@
    <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)
-weak_alias (strchr, index)
+extern __typeof (__redirect_strchr) __libc_strchr;
+s390_vx_libc_ifunc2 (__strchr, __libc_strchr)
+strong_alias (__libc_strchr, strchr)
+weak_alias (__libc_strchr, index)
 
 #else
 # include <string/strchr.c>
diff --git a/sysdeps/s390/multiarch/strcmp.c b/sysdeps/s390/multiarch/strcmp.c
index c4ccd34..8839e8b 100644
--- a/sysdeps/s390/multiarch/strcmp.c
+++ b/sysdeps/s390/multiarch/strcmp.c
@@ -17,10 +17,15 @@
    <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
 
+extern __typeof (__redirect_strcmp) __libc_strcmp;
+s390_vx_libc_ifunc2 (__strcmp, __libc_strcmp)
+strong_alias (__libc_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..a901bcd 100644
--- a/sysdeps/s390/multiarch/strcpy.c
+++ b/sysdeps/s390/multiarch/strcpy.c
@@ -17,8 +17,13 @@
    <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)
+extern __typeof (__redirect_strcpy) __libc_strcpy;
+s390_vx_libc_ifunc2 (__strcpy, __libc_strcpy)
+strong_alias (__libc_strcpy, strcpy)
+
 #endif
diff --git a/sysdeps/s390/multiarch/strcspn.c b/sysdeps/s390/multiarch/strcspn.c
index c23452a..a188f4b 100644
--- a/sysdeps/s390/multiarch/strcspn.c
+++ b/sysdeps/s390/multiarch/strcspn.c
@@ -17,10 +17,16 @@
    <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)
+extern __typeof (__redirect_strcspn) __libc_strcspn;
+s390_vx_libc_ifunc2 (__strcspn, __libc_strcspn)
+strong_alias (__libc_strcspn, strcspn)
 
 #else
 # include <string/strcspn.c>
diff --git a/sysdeps/s390/multiarch/strlen.c b/sysdeps/s390/multiarch/strlen.c
index 098d4e1..186b4e5 100644
--- a/sysdeps/s390/multiarch/strlen.c
+++ b/sysdeps/s390/multiarch/strlen.c
@@ -17,10 +17,14 @@
    <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)
+extern __typeof (__redirect_strlen) __libc_strlen;
+s390_vx_libc_ifunc2 (__strlen, __libc_strlen)
+strong_alias (__libc_strlen, strlen)
 
 #else
 # include <string/strlen.c>
diff --git a/sysdeps/s390/multiarch/strncmp.c b/sysdeps/s390/multiarch/strncmp.c
index 9a72c79..6c130cc 100644
--- a/sysdeps/s390/multiarch/strncmp.c
+++ b/sysdeps/s390/multiarch/strncmp.c
@@ -17,13 +17,16 @@
    <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)
+extern __typeof (__redirect_strncmp) __libc_strncmp;
+s390_vx_libc_ifunc2 (__strncmp, __libc_strncmp)
+strong_alias (__libc_strncmp, strncmp)
 
 #else
 # include <string/strncmp.c>
diff --git a/sysdeps/s390/multiarch/strncpy.c b/sysdeps/s390/multiarch/strncpy.c
index 1464551..2c294d2 100644
--- a/sysdeps/s390/multiarch/strncpy.c
+++ b/sysdeps/s390/multiarch/strncpy.c
@@ -17,8 +17,15 @@
    <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)
+extern __typeof (__redirect_strncpy) __libc_strncpy;
+s390_vx_libc_ifunc2 (__strncpy, __libc_strncpy);
+strong_alias (__libc_strncpy, strncpy)
+
 #endif
diff --git a/sysdeps/s390/multiarch/strnlen.c b/sysdeps/s390/multiarch/strnlen.c
index 48c3bb7..79edb236 100644
--- a/sysdeps/s390/multiarch/strnlen.c
+++ b/sysdeps/s390/multiarch/strnlen.c
@@ -17,12 +17,17 @@
    <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)
-weak_alias (__strnlen, strnlen)
-libc_hidden_def (strnlen)
+extern __typeof (__redirect___strnlen) __libc___strnlen;
+s390_vx_libc_ifunc2 (__strnlen, __libc___strnlen)
+strong_alias (__libc___strnlen, __strnlen)
+weak_alias (__libc___strnlen, strnlen)
 
 #else
 # include <string/strnlen.c>
diff --git a/sysdeps/s390/multiarch/strpbrk.c b/sysdeps/s390/multiarch/strpbrk.c
index cdc1399..dc267db 100644
--- a/sysdeps/s390/multiarch/strpbrk.c
+++ b/sysdeps/s390/multiarch/strpbrk.c
@@ -17,10 +17,16 @@
    <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)
+extern __typeof (__redirect_strpbrk) __libc_strpbrk;
+s390_vx_libc_ifunc2 (__strpbrk, __libc_strpbrk)
+strong_alias (__libc_strpbrk, strpbrk)
 
 #else
 # include <string/strpbrk.c>
diff --git a/sysdeps/s390/multiarch/strrchr.c b/sysdeps/s390/multiarch/strrchr.c
index e515d6b..b9c0fca 100644
--- a/sysdeps/s390/multiarch/strrchr.c
+++ b/sysdeps/s390/multiarch/strrchr.c
@@ -17,11 +17,15 @@
    <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)
+extern __typeof (__redirect_strrchr) __libc_strrchr;
+s390_vx_libc_ifunc2 (__strrchr, __libc_strrchr)
+strong_alias (__libc_strrchr, strrchr);
+weak_alias (__libc_strrchr, rindex);
 
 #else
 # include <string/strrchr.c>
diff --git a/sysdeps/s390/multiarch/strspn.c b/sysdeps/s390/multiarch/strspn.c
index 7c26af8..218ecdb 100644
--- a/sysdeps/s390/multiarch/strspn.c
+++ b/sysdeps/s390/multiarch/strspn.c
@@ -17,10 +17,16 @@
    <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)
+extern __typeof (__redirect_strspn) __libc_strspn;
+s390_vx_libc_ifunc2 (__strspn, __libc_strspn)
+strong_alias (__libc_strspn, strspn);
 
 #else
 # include <string/strspn.c>
diff --git a/sysdeps/s390/multiarch/wcschr.c b/sysdeps/s390/multiarch/wcschr.c
index fb51097..abc4e20 100644
--- a/sysdeps/s390/multiarch/wcschr.c
+++ b/sysdeps/s390/multiarch/wcschr.c
@@ -17,12 +17,17 @@
    <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)
-weak_alias (__wcschr, wcschr)
-libc_hidden_weak (wcschr)
+extern __typeof (__redirect___wcschr) __libc___wcschr;
+s390_vx_libc_ifunc2 (__wcschr, __libc___wcschr)
+strong_alias (__libc___wcschr, __wcschr)
+weak_alias (__libc___wcschr, wcschr)
 
 #else
 # include <wcsmbs/wcschr.c>
diff --git a/sysdeps/s390/multiarch/wcscmp.c b/sysdeps/s390/multiarch/wcscmp.c
index 705ef45..6675a73 100644
--- a/sysdeps/s390/multiarch/wcscmp.c
+++ b/sysdeps/s390/multiarch/wcscmp.c
@@ -17,11 +17,15 @@
    <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)
-weak_alias (__wcscmp, wcscmp)
+extern __typeof (__redirect___wcscmp) __libc__wcscmp;
+s390_vx_libc_ifunc2 (__wcscmp, __libc__wcscmp)
+strong_alias (__libc__wcscmp, __wcscmp)
+weak_alias (__libc__wcscmp, wcscmp)
 
 #else
 # include <wcsmbs/wcscmp.c>
diff --git a/sysdeps/s390/multiarch/wcspbrk.c b/sysdeps/s390/multiarch/wcspbrk.c
index 198144d..e3258a5 100644
--- a/sysdeps/s390/multiarch/wcspbrk.c
+++ b/sysdeps/s390/multiarch/wcspbrk.c
@@ -17,10 +17,14 @@
    <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)
+extern __typeof (__redirect_wcspbrk) __libc_wcspbrk;
+s390_vx_libc_ifunc2 (__wcspbrk, __libc_wcspbrk)
+strong_alias (__libc_wcspbrk, wcspbrk)
 
 #else
 # include <wcsmbs/wcspbrk.c>
diff --git a/sysdeps/s390/multiarch/wcsspn.c b/sysdeps/s390/multiarch/wcsspn.c
index 167a881..45cde8c 100644
--- a/sysdeps/s390/multiarch/wcsspn.c
+++ b/sysdeps/s390/multiarch/wcsspn.c
@@ -17,10 +17,14 @@
    <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)
+extern __typeof (__redirect_wcsspn) __libc_wcsspn;
+s390_vx_libc_ifunc2 (__wcsspn, __libc_wcsspn)
+strong_alias (__libc_wcsspn, wcsspn)
 
 #else
 # include <wcsmbs/wcsspn.c>
diff --git a/sysdeps/s390/multiarch/wmemchr.c b/sysdeps/s390/multiarch/wmemchr.c
index f2bfe3c..19b5fba 100644
--- a/sysdeps/s390/multiarch/wmemchr.c
+++ b/sysdeps/s390/multiarch/wmemchr.c
@@ -17,12 +17,17 @@
    <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)
-weak_alias (__wmemchr, wmemchr)
-libc_hidden_weak (wmemchr)
+extern __typeof (__redirect___wmemchr) __libc___wmemchr;
+s390_vx_libc_ifunc2 (__wmemchr, __libc___wmemchr)
+strong_alias (__libc___wmemchr, __wmemchr)
+weak_alias (__libc___wmemchr, wmemchr)
 
 #else
 # include <wcsmbs/wmemchr.c>
diff --git a/sysdeps/s390/multiarch/wmemset.c b/sysdeps/s390/multiarch/wmemset.c
index e9e695f..6434917 100644
--- a/sysdeps/s390/multiarch/wmemset.c
+++ b/sysdeps/s390/multiarch/wmemset.c
@@ -17,12 +17,17 @@
    <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)
-weak_alias (__wmemset, wmemset)
-libc_hidden_weak (wmemset)
+extern __typeof (__redirect___wmemset) __libc___wmemset;
+s390_vx_libc_ifunc2 (__wmemset, __libc___wmemset)
+strong_alias (__libc___wmemset, __wmemset)
+weak_alias (__libc___wmemset, 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..a3f5f07 100644
--- a/sysdeps/s390/s390-32/multiarch/memcmp.c
+++ b/sysdeps/s390/s390-32/multiarch/memcmp.c
@@ -17,8 +17,13 @@
    <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");
+extern __typeof (__redirect_memcmp) __libc_memcmp;
+s390_libc_ifunc (__memcmp, __libc_memcmp)
+strong_alias (__libc_memcmp, memcmp);
+weak_alias (__libc_memcmp, bcmp);
 #endif
diff --git a/sysdeps/s390/s390-32/multiarch/memcpy.c b/sysdeps/s390/s390-32/multiarch/memcpy.c
index 2a98aa0..3b91871 100644
--- a/sysdeps/s390/s390-32/multiarch/memcpy.c
+++ b/sysdeps/s390/s390-32/multiarch/memcpy.c
@@ -18,7 +18,12 @@
 
 /* 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)
+extern __typeof (__redirect_memcpy) __libc_memcpy;
+s390_libc_ifunc (__memcpy, __libc_memcpy)
+strong_alias (__libc_memcpy, memcpy);
 #endif
diff --git a/sysdeps/s390/s390-32/multiarch/memset.c b/sysdeps/s390/s390-32/multiarch/memset.c
index 89b8102..db62760 100644
--- a/sysdeps/s390/s390-32/multiarch/memset.c
+++ b/sysdeps/s390/s390-32/multiarch/memset.c
@@ -17,7 +17,12 @@
    <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)
+extern __typeof (__redirect_memset) __libc_memset;
+s390_libc_ifunc (__memset, __libc_memset)
+strong_alias (__libc_memset, memset);
 #endif
diff --git a/sysdeps/s390/s390-64/multiarch/memcmp.c b/sysdeps/s390/s390-64/multiarch/memcmp.c
index 44f72dc..a3f5f07 100644
--- a/sysdeps/s390/s390-64/multiarch/memcmp.c
+++ b/sysdeps/s390/s390-64/multiarch/memcmp.c
@@ -17,8 +17,13 @@
    <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");
+extern __typeof (__redirect_memcmp) __libc_memcmp;
+s390_libc_ifunc (__memcmp, __libc_memcmp)
+strong_alias (__libc_memcmp, memcmp);
+weak_alias (__libc_memcmp, bcmp);
 #endif
diff --git a/sysdeps/s390/s390-64/multiarch/memcpy.c b/sysdeps/s390/s390-64/multiarch/memcpy.c
index 2a98aa0..3b91871 100644
--- a/sysdeps/s390/s390-64/multiarch/memcpy.c
+++ b/sysdeps/s390/s390-64/multiarch/memcpy.c
@@ -18,7 +18,12 @@
 
 /* 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)
+extern __typeof (__redirect_memcpy) __libc_memcpy;
+s390_libc_ifunc (__memcpy, __libc_memcpy)
+strong_alias (__libc_memcpy, memcpy);
 #endif
diff --git a/sysdeps/s390/s390-64/multiarch/memset.c b/sysdeps/s390/s390-64/multiarch/memset.c
index 89b8102..db62760 100644
--- a/sysdeps/s390/s390-64/multiarch/memset.c
+++ b/sysdeps/s390/s390-64/multiarch/memset.c
@@ -17,7 +17,12 @@
    <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)
+extern __typeof (__redirect_memset) __libc_memset;
+s390_libc_ifunc (__memset, __libc_memset)
+strong_alias (__libc_memset, memset);
 #endif
-- 
2.3.0


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

* Re: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-07-04  8:31 ` [PATCH " Florian Weimer
@ 2016-07-04 14:00   ` Stefan Liebler
  2016-07-06 11:45     ` Florian Weimer
  0 siblings, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-07-04 14:00 UTC (permalink / raw)
  To: libc-alpha; +Cc: munroesj

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

On 07/04/2016 10:31 AM, Florian Weimer wrote:
> On 06/23/2016 01:55 PM, Stefan Liebler wrote:
>
>> 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.
>>
>> 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.
>>
>> Tested the whole patchset by building glibc and running the testsuite
>> on s390,
>> intel, power for 32/64bit. The __GI_* symbols targets the same
>> functions as
>> before.
>>
>> Okay to commit?
>
> These changes (i.e. patch 1/8) look reasonable to me.  Perhaps wait
> another day if someone else objects.
Do I have to wait for an explicit okay from intel/power maintainer?
>
>> ChangeLog:
>>
>>     * include/libc-symbols.h (__ifunc): New macro uses gcc attribute
>> ifunc.
>>     (libc_ifunc, libm_ifunc): Use __ifunc as base macro.
>>     (libm_ifunc_init): New define.
>>     * sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c:
>>     Redirect ifunced function in header and create a copy of the
>> prototype
>>     for using as ifunc function. Add appropiate aliases to the real
>> symbol
>
> “appropriate“
Adjusted all ChangeLogs with this typo.

>
>>  /* Marker used for indirection function symbols.  */
>> -#define libc_ifunc(name, expr)                        \
>> -  extern void *name##_ifunc (void) __asm__ (#name);            \
>> -  void *name##_ifunc (void)                        \
>> +#define __ifunc(name, expr, arg, init)                    \
>> +  extern __typeof (name) name __attribute__ ((ifunc(#name
>> "_ifunc")));    \
>
> Space after ifunc.
okay
>
> Thanks,
> Florian
>
Thanks for the review.

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Use-gcc-attribute-ifunc-in-libc_ifunc-macro-instead-.patch --]
[-- Type: text/x-patch; name="0001-Use-gcc-attribute-ifunc-in-libc_ifunc-macro-instead-.patch", Size: 53423 bytes --]

From 295005dbd0ea3fd1150002502d7b9e60cafea3ac Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Mon, 4 Jul 2016 15:33:56 +0200
Subject: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of
 inline assembly due to false debuginfo.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The current s390 ifunc resolver for vector optimized functions and the common
libc_ifunc macro in include/libc-symbols.h uses something like that:
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.
Usage 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:
extern __typeof (__redirect___strnlen) __libc___strnlen;
__typeof (__libc___strnlen) __libc___strnlen __attribute__ ((ifunc ("__resolve_strnlen")));
strong_alias (__libc___strnlen, __strnlen)
weak_alias (__libc___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 or if the __GI_* symbol
targets to the ifunc symbol, 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.

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.

Tested the whole patchset by building glibc and running the testsuite on s390,
intel, power for 32/64bit. The __GI_* symbols targets the same functions as
before.

Okay to commit?

Bye
Stefan

ChangeLog:

	* include/libc-symbols.h (__ifunc): New macro uses gcc attribute ifunc.
	(libc_ifunc, libm_ifunc): Use __ifunc as base macro.
	(libm_ifunc_init): New define.
	* sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finite.c:
	Redirect ifunced function in header and create a copy of the prototype
	for using as ifunc function. Add appropriate aliases to the real symbol
	names.
	* 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/fpu/multiarch/s_isnanf.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/fpu/multiarch/s_isnanf.cLikewise.
	* 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/stpcpy.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.
---
 include/libc-symbols.h                             | 23 +++++++++-------------
 .../powerpc32/power4/fpu/multiarch/s_finite.c      | 12 +++++++++--
 .../powerpc32/power4/fpu/multiarch/s_finitef.c     | 12 +++++++++--
 .../powerpc32/power4/fpu/multiarch/s_isinf.c       | 12 +++++++++--
 .../powerpc32/power4/fpu/multiarch/s_isinff.c      | 13 ++++++++++--
 .../powerpc32/power4/fpu/multiarch/s_isnan.c       | 12 +++++++++--
 .../powerpc32/power4/fpu/multiarch/s_isnanf.c      |  1 +
 .../powerpc/powerpc32/power4/multiarch/memcmp.c    |  6 +++++-
 .../powerpc/powerpc32/power4/multiarch/memcpy.c    |  8 +++++++-
 .../powerpc/powerpc32/power4/multiarch/memmove.c   |  7 ++++++-
 .../powerpc/powerpc32/power4/multiarch/mempcpy.c   | 13 +++++++++---
 .../powerpc/powerpc32/power4/multiarch/memset.c    |  7 ++++++-
 .../powerpc/powerpc32/power4/multiarch/rawmemchr.c |  8 ++++++--
 .../powerpc/powerpc32/power4/multiarch/strchr.c    | 10 ++++++++--
 .../powerpc/powerpc32/power4/multiarch/strlen.c    |  7 ++++++-
 .../powerpc/powerpc32/power4/multiarch/strncmp.c   |  8 +++++++-
 .../powerpc/powerpc32/power4/multiarch/strnlen.c   | 11 ++++++++---
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c | 12 +++++++++--
 .../powerpc/powerpc64/fpu/multiarch/s_finitef.c    | 12 +++++++++--
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c  | 12 +++++++++--
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c | 12 +++++++++--
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c  | 12 +++++++++--
 sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c |  1 +
 sysdeps/powerpc/powerpc64/multiarch/memcmp.c       |  6 +++++-
 sysdeps/powerpc/powerpc64/multiarch/mempcpy.c      | 13 +++++++++---
 sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c    |  8 ++++++--
 sysdeps/powerpc/powerpc64/multiarch/stpcpy.c       |  1 +
 sysdeps/powerpc/powerpc64/multiarch/stpncpy.c      | 10 ++++++++--
 sysdeps/powerpc/powerpc64/multiarch/strcat.c       |  6 +++++-
 sysdeps/powerpc/powerpc64/multiarch/strchr.c       | 10 ++++++++--
 sysdeps/powerpc/powerpc64/multiarch/strcmp.c       |  8 +++++++-
 sysdeps/powerpc/powerpc64/multiarch/strcpy.c       |  6 +++++-
 sysdeps/powerpc/powerpc64/multiarch/strncmp.c      |  8 +++++++-
 sysdeps/powerpc/powerpc64/multiarch/strncpy.c      |  9 +++++++--
 sysdeps/powerpc/powerpc64/multiarch/strnlen.c      | 11 ++++++++---
 sysdeps/powerpc/powerpc64/multiarch/strrchr.c      |  8 ++++++--
 sysdeps/powerpc/powerpc64/multiarch/strstr.c       |  6 +++++-
 sysdeps/powerpc/powerpc64/multiarch/wcschr.c       | 11 ++++++++---
 38 files changed, 277 insertions(+), 75 deletions(-)

diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index 4548e09..5938eae 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -714,26 +714,21 @@ for linking")
 #endif
 
 /* Marker used for indirection function symbols.  */
-#define libc_ifunc(name, expr)						\
-  extern void *name##_ifunc (void) __asm__ (#name);			\
-  void *name##_ifunc (void)						\
+#define __ifunc(name, expr, arg, init)					\
+  extern __typeof (name) name __attribute__ ((ifunc (#name "_ifunc")));	\
+  static void *name##_ifunc (arg)					\
   {									\
-    INIT_ARCH ();							\
+    init ();								\
     __typeof (name) *res = expr;					\
     return res;								\
-  }									\
-  __asm__ (".type " #name ", %gnu_indirect_function");
+  }
+
+#define libc_ifunc(name, expr) __ifunc (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, 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..ee643a1 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,13 +26,18 @@
 
 extern __typeof (__finite) __finite_ppc32 attribute_hidden;
 extern __typeof (__finite) __finite_power7 attribute_hidden;
+extern __typeof (__finite) __libc___finite;
+#undef __finite
+#undef __finitef
+#undef __finitel
 
-libc_ifunc (__finite,
+libc_ifunc (__libc___finite,
 	    (hwcap & PPC_FEATURE_ARCH_2_06)
 	    ? __finite_power7
             : __finite_ppc32);
 
-weak_alias (__finite, finite)
+strong_alias (__libc___finite, __finite)
+weak_alias (__libc___finite, finite)
 
 #ifdef NO_LONG_DOUBLE
 strong_alias (__finite, __finitel)
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c
index 831c94f..f2a5389 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_finitef.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 <shlib-compat.h>
 #include "init-arch.h"
@@ -23,10 +26,15 @@
 extern __typeof (__finitef) __finitef_ppc32 attribute_hidden;
 /* The power7 finite(double) works for float.  */
 extern __typeof (__finitef) __finite_power7 attribute_hidden;
+extern __typeof (__finitef) __libc___finitef;
+#undef __finite
+#undef __finitef
+#undef __finitel
 
-libc_ifunc (__finitef,
+libc_ifunc (__libc___finitef,
 	    (hwcap & PPC_FEATURE_ARCH_2_06)
 	    ? __finite_power7
             : __finitef_ppc32);
 
-weak_alias (__finitef, finitef)
+strong_alias (__libc___finitef, __finitef)
+weak_alias (__libc___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..7321631 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,13 +26,18 @@
 
 extern __typeof (__isinf) __isinf_ppc32 attribute_hidden;
 extern __typeof (__isinf) __isinf_power7 attribute_hidden;
+extern __typeof (__isinf) __libc___isinf;
+#undef __isinf
+#undef __isinff
+#undef __isinfl
 
-libc_ifunc (__isinf,
+libc_ifunc (__libc___isinf,
 	    (hwcap & PPC_FEATURE_ARCH_2_06)
 	    ? __isinf_power7
             : __isinf_ppc32);
 
-weak_alias (__isinf, isinf)
+strong_alias (__libc___isinf, __isinf)
+weak_alias (__libc___isinf, isinf)
 
 #ifdef NO_LONG_DOUBLE
 strong_alias (__isinf, __isinfl)
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c
index 2ab83ee..75bb7dc 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isinff.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,10 +27,16 @@
 extern __typeof (__isinff) __isinff_ppc32 attribute_hidden;
 /* The power7 isinf(double) works for float.  */
 extern __typeof (__isinff) __isinf_power7 attribute_hidden;
+extern __typeof (__isinff) __libc___isinff;
+#undef __isinf
+#undef __isinff
+#undef __isinfl
 
-libc_ifunc (__isinff,
+
+libc_ifunc (__libc___isinff,
 	    (hwcap & PPC_FEATURE_ARCH_2_06)
 	    ? __isinf_power7
             : __isinff_ppc32);
 
-weak_alias (__isinff, isinff)
+strong_alias (__libc___isinff, __isinff)
+weak_alias (__libc___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..99aa84b 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,8 +28,12 @@ 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;
+extern __typeof (__isnan) __libc___isnan;
+#undef __isnan
+#undef __isnanf
+#undef __isnanl
 
-libc_ifunc (__isnan,
+libc_ifunc (__libc___isnan,
 	    (hwcap & PPC_FEATURE_ARCH_2_06)
 	    ? __isnan_power7 :
 	      (hwcap & PPC_FEATURE_ARCH_2_05)
@@ -35,7 +42,8 @@ libc_ifunc (__isnan,
 		? __isnan_power5
             : __isnan_ppc32);
 
-weak_alias (__isnan, isnan)
+strong_alias (__libc___isnan, __isnan)
+weak_alias (__libc___isnan, isnan)
 
 #ifdef NO_LONG_DOUBLE
 strong_alias (__isnan, __isnanl)
diff --git a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
index c43c0f3..304b2a7 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
@@ -35,4 +35,5 @@ libc_ifunc (__isnanf,
 		? __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..c18814f 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memcmp.c
@@ -18,17 +18,21 @@
 
 /* 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;
+extern __typeof (memcmp) __libc_memcmp;
+# undef memcmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memcmp,
+libc_ifunc (__libc_memcmp,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __memcmp_power7
             : __memcmp_ppc);
+strong_alias (__libc_memcmp, memcmp);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memcpy.c
index f379e47..5e68152 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,10 +31,12 @@ 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;
+extern __typeof (memcpy) __libc_memcpy;
+# undef memcpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memcpy,
+libc_ifunc (__libc_memcpy,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __memcpy_power7 :
 	      (hwcap & PPC_FEATURE_ARCH_2_06)
@@ -42,4 +46,6 @@ libc_ifunc (memcpy,
 		  (hwcap & PPC_FEATURE_CELL_BE)
 		  ? __memcpy_cell
             : __memcpy_ppc);
+
+strong_alias (__libc_memcpy, memcpy);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
index 4173184..ee8ab0c 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/memmove.c
@@ -19,16 +19,21 @@
 #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;
+extern __typeof (__redirect_memmove) __libc_memmove;
+# undef memmove
 
-libc_ifunc (memmove,
+libc_ifunc (__libc_memmove,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __memmove_power7
             : __memmove_ppc);
+
+strong_alias (__libc_memmove, memmove);
 #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..9b5dec9 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/mempcpy.c
@@ -17,23 +17,30 @@
    <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;
+extern __typeof (__mempcpy) __libc___mempcpy;
+# undef mempcpy
+# undef __mempcpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__mempcpy,
+libc_ifunc (__libc___mempcpy,
 	    (hwcap & PPC_FEATURE_HAS_VSX)
             ? __mempcpy_power7
             : __mempcpy_ppc);
 
-weak_alias (__mempcpy, mempcpy)
-libc_hidden_def (mempcpy)
+strong_alias (__libc___mempcpy, __mempcpy)
+weak_alias (__libc___mempcpy, 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..a759e57 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,17 @@
 extern __typeof (memset) __memset_ppc attribute_hidden;
 extern __typeof (memset) __memset_power6 attribute_hidden;
 extern __typeof (memset) __memset_power7 attribute_hidden;
+extern __typeof (memset) __libc_memset;
+# undef memset
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memset,
+libc_ifunc (__libc_memset,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __memset_power7 :
 	      (hwcap & PPC_FEATURE_ARCH_2_05)
 		? __memset_power6
             : __memset_ppc);
+
+strong_alias (__libc_memset, memset);
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c b/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
index f06030e..f31bd55 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/rawmemchr.c
@@ -17,21 +17,25 @@
    <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;
+extern __typeof (__rawmemchr) __libc___rawmemchr;
+# undef __rawmemchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__rawmemchr,
+libc_ifunc (__libc___rawmemchr,
 	    (hwcap & PPC_FEATURE_HAS_VSX)
             ? __rawmemchr_power7
             : __rawmemchr_ppc);
 
-weak_alias (__rawmemchr, rawmemchr)
+strong_alias (__libc___rawmemchr, __rawmemchr)
+weak_alias (__libc___rawmemchr, rawmemchr)
 #else
 #include <string/rawmemchr.c>
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
index 2cfde63..87284f9 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strchr.c
@@ -18,18 +18,24 @@
 
 /* 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;
+extern __typeof (strchr) __libc_strchr;
+# undef strchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strchr,
+libc_ifunc (__libc_strchr,
 	    (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strchr_power7
             : __strchr_ppc);
-weak_alias (strchr, index)
+strong_alias (__libc_strchr, strchr)
+weak_alias (__libc_strchr, index)
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
index af5921a..f21c680 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strlen.c
@@ -17,15 +17,20 @@
    <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;
+extern __typeof (strlen) __libc_strlen;
+# undef strlen
 
-libc_ifunc (strlen,
+libc_ifunc (__libc_strlen,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strlen_power7
             : __strlen_ppc);
+
+strong_alias (__libc_strlen, strlen)
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strncmp.c
index 7cc7628..ad3a17b 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,14 @@
 extern __typeof (strncmp) __strncmp_ppc attribute_hidden;
 extern __typeof (strncmp) __strncmp_power4 attribute_hidden;
 extern __typeof (strncmp) __strncmp_power7 attribute_hidden;
+extern __typeof (strncmp) __libc_strncmp;
+# undef strncmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strncmp,
+libc_ifunc (__libc_strncmp,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strncmp_power7
             : __strncmp_ppc);
+strong_alias (__libc_strncmp, strncmp)
 #endif
diff --git a/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c b/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
index 8f1e7c9..d04d8b9 100644
--- a/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
+++ b/sysdeps/powerpc/powerpc32/power4/multiarch/strnlen.c
@@ -17,17 +17,22 @@
    <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;
+extern __typeof (__strnlen) __libc___strnlen;
+# undef strnlen
+# undef __strnlen
 
-libc_ifunc (__strnlen,
+libc_ifunc (__libc___strnlen,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strnlen_power7
             : __strnlen_ppc);
-weak_alias (__strnlen, strnlen)
-libc_hidden_def (strnlen)
+strong_alias (__libc___strnlen, __strnlen)
+weak_alias (__libc___strnlen, strnlen)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c
index 067edc2..ed1934f 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,15 +27,20 @@
 extern __typeof (__finite) __finite_ppc64 attribute_hidden;
 extern __typeof (__finite) __finite_power7 attribute_hidden;
 extern __typeof (__finite) __finite_power8 attribute_hidden;
+extern __typeof (__finite) __libc___finite;
+#undef __finite
+#undef __finitef
+#undef __finitel
 
-libc_ifunc (__finite,
+libc_ifunc (__libc___finite,
 	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
 	    ? __finite_power8 :
 	      (hwcap & PPC_FEATURE_ARCH_2_06)
 	      ? __finite_power7
             : __finite_ppc64);
 
-weak_alias (__finite, finite)
+strong_alias (__libc___finite, __finite)
+weak_alias (__libc___finite, finite)
 
 #ifdef NO_LONG_DOUBLE
 strong_alias (__finite, __finitel)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
index e0b4686..6da1313 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_finitef.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 <shlib-compat.h>
 #include "init-arch.h"
@@ -24,12 +27,17 @@ 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;
+extern __typeof (__finitef) __libc___finitef;
+#undef __finite
+#undef __finitef
+#undef __finitel
 
-libc_ifunc (__finitef,
+libc_ifunc (__libc___finitef,
 	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
 	    ? __finite_power8 :
 	      (hwcap & PPC_FEATURE_ARCH_2_06)
 	      ? __finite_power7
             : __finitef_ppc64);
 
-weak_alias (__finitef, finitef)
+strong_alias (__libc___finitef, __finitef)
+weak_alias (__libc___finitef, finitef)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c
index 07e159d..380dab8 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,15 +27,20 @@
 extern __typeof (__isinf) __isinf_ppc64 attribute_hidden;
 extern __typeof (__isinf) __isinf_power7 attribute_hidden;
 extern __typeof (__isinf) __isinf_power8 attribute_hidden;
+extern __typeof (__isinf) __libc___isinf;
+#undef __isinf
+#undef __isinff
+#undef __isinfl
 
-libc_ifunc (__isinf,
+libc_ifunc (__libc___isinf,
 	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
 	    ? __isinf_power8 :
 	      (hwcap & PPC_FEATURE_ARCH_2_06)
 	      ? __isinf_power7
             : __isinf_ppc64);
 
-weak_alias (__isinf, isinf)
+strong_alias (__libc___isinf, __isinf)
+weak_alias (__libc___isinf, isinf)
 
 #ifdef NO_LONG_DOUBLE
 strong_alias (__isinf, __isinfl)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
index 2cb161b..065d218 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinff.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>
@@ -25,12 +28,17 @@ 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;
+extern __typeof (__isinff) __libc___isinff;
+#undef __isinf
+#undef __isinff
+#undef __isinfl
 
-libc_ifunc (__isinff,
+libc_ifunc (__libc___isinff,
 	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
 	    ? __isinf_power8 :
 	      (hwcap & PPC_FEATURE_ARCH_2_06)
 	      ? __isinf_power7
             : __isinff_ppc64);
 
-weak_alias (__isinff, isinff)
+strong_alias (__libc___isinff, __isinff)
+weak_alias (__libc___isinff, isinff)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnan.c
index a614f25..a2c9308 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,8 +30,12 @@ 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;
+extern __typeof (__isnan) __libc___isnan;
+#undef __isnan
+#undef __isnanf
+#undef __isnanl
 
-libc_ifunc (__isnan,
+libc_ifunc (__libc___isnan,
 	    (hwcap2 & PPC_FEATURE2_ARCH_2_07)
 	    ? __isnan_power8 :
 	      (hwcap & PPC_FEATURE_ARCH_2_06)
@@ -41,7 +48,8 @@ libc_ifunc (__isnan,
 		      ? __isnan_power5
             : __isnan_ppc64);
 
-weak_alias (__isnan, isnan)
+strong_alias (__libc___isnan, __isnan)
+weak_alias (__libc___isnan, isnan)
 
 #ifdef NO_LONG_DOUBLE
 strong_alias (__isnan, __isnanl)
diff --git a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
index acbc131..72e9a07 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
@@ -40,4 +40,5 @@ libc_ifunc (__isnanf,
 		      ? __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..b31aadf 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,18 @@
 extern __typeof (memcmp) __memcmp_ppc attribute_hidden;
 extern __typeof (memcmp) __memcmp_power4 attribute_hidden;
 extern __typeof (memcmp) __memcmp_power7 attribute_hidden;
+extern __typeof (memcmp) __libc_memcmp;
+# undef memcmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (memcmp,
+libc_ifunc (__libc_memcmp,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __memcmp_power7 :
 	      (hwcap & PPC_FEATURE_POWER4)
 		? __memcmp_power4
             : __memcmp_ppc);
+strong_alias (__libc_memcmp, memcmp);
 #else
 #include <string/memcmp.c>
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
index 3c77b5f..9b5dec9 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/mempcpy.c
@@ -17,23 +17,30 @@
    <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;
+extern __typeof (__mempcpy) __libc___mempcpy;
+# undef mempcpy
+# undef __mempcpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__mempcpy,
+libc_ifunc (__libc___mempcpy,
 	    (hwcap & PPC_FEATURE_HAS_VSX)
             ? __mempcpy_power7
             : __mempcpy_ppc);
 
-weak_alias (__mempcpy, mempcpy)
-libc_hidden_def (mempcpy)
+strong_alias (__libc___mempcpy, __mempcpy)
+weak_alias (__libc___mempcpy, 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..f31bd55 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/rawmemchr.c
@@ -17,21 +17,25 @@
    <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;
+extern __typeof (__rawmemchr) __libc___rawmemchr;
+# undef __rawmemchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (__rawmemchr,
+libc_ifunc (__libc___rawmemchr,
 	    (hwcap & PPC_FEATURE_HAS_VSX)
             ? __rawmemchr_power7
             : __rawmemchr_ppc);
 
-weak_alias (__rawmemchr, rawmemchr)
+strong_alias (__libc___rawmemchr, __rawmemchr)
+weak_alias (__libc___rawmemchr, rawmemchr)
 #else
 #include <string/rawmemchr.c>
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
index bbc1691..3867b9e 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
@@ -34,6 +34,7 @@ libc_ifunc (__stpcpy,
             : __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..b5c7457 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,17 @@
 extern __typeof (__stpncpy) __stpncpy_ppc attribute_hidden;
 extern __typeof (__stpncpy) __stpncpy_power7 attribute_hidden;
 extern __typeof (__stpncpy) __stpncpy_power8 attribute_hidden;
+extern __typeof (__stpncpy) __libc___stpncpy;
+# undef stpncpy
+# undef __stpncpy
 
-libc_ifunc (__stpncpy,
+libc_ifunc (__libc___stpncpy,
             (hwcap2 & PPC_FEATURE2_ARCH_2_07)
             ? __stpncpy_power8 :
               (hwcap & PPC_FEATURE_HAS_VSX)
               ? __stpncpy_power7
             : __stpncpy_ppc);
 
-weak_alias (__stpncpy, stpncpy)
+strong_alias (__libc___stpncpy, __stpncpy)
+weak_alias (__libc___stpncpy, stpncpy)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcat.c b/sysdeps/powerpc/powerpc64/multiarch/strcat.c
index a2894ae..b4fd540 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,14 @@
 extern __typeof (strcat) __strcat_ppc attribute_hidden;
 extern __typeof (strcat) __strcat_power7 attribute_hidden;
 extern __typeof (strcat) __strcat_power8 attribute_hidden;
+extern __typeof (strcat) __libc_strcat;
+# undef strcat
 
-libc_ifunc (strcat,
+libc_ifunc (__libc_strcat,
             (hwcap2 & PPC_FEATURE2_ARCH_2_07)
             ? __strcat_power8 :
               (hwcap & PPC_FEATURE_HAS_VSX)
               ? __strcat_power7
             : __strcat_ppc);
+strong_alias (__libc_strcat, strcat)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strchr.c b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
index 2cfde63..87284f9 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strchr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strchr.c
@@ -18,18 +18,24 @@
 
 /* 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;
+extern __typeof (strchr) __libc_strchr;
+# undef strchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strchr,
+libc_ifunc (__libc_strchr,
 	    (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strchr_power7
             : __strchr_ppc);
-weak_alias (strchr, index)
+strong_alias (__libc_strchr, strchr)
+weak_alias (__libc_strchr, index)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcmp.c b/sysdeps/powerpc/powerpc64/multiarch/strcmp.c
index aee888a..32ab75d 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,14 @@
 extern __typeof (strcmp) __strcmp_ppc attribute_hidden;
 extern __typeof (strcmp) __strcmp_power7 attribute_hidden;
 extern __typeof (strcmp) __strcmp_power8 attribute_hidden;
+extern __typeof (strcmp) __libc_strcmp;
+# undef strcmp
 
-libc_ifunc (strcmp,
+libc_ifunc (__libc_strcmp,
             (hwcap2 & PPC_FEATURE2_ARCH_2_07)
               ? __strcmp_power8 :
               (hwcap & PPC_FEATURE_HAS_VSX)
               ? __strcmp_power7
             : __strcmp_ppc);
+strong_alias (__libc_strcmp, strcmp)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strcpy.c b/sysdeps/powerpc/powerpc64/multiarch/strcpy.c
index d2c3858..31d6c92 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,14 @@
 extern __typeof (strcpy) __strcpy_ppc attribute_hidden;
 extern __typeof (strcpy) __strcpy_power7 attribute_hidden;
 extern __typeof (strcpy) __strcpy_power8 attribute_hidden;
+extern __typeof (strcpy) __libc_strcpy;
+#undef strcpy
 
-libc_ifunc (strcpy,
+libc_ifunc (__libc_strcpy,
             (hwcap2 & PPC_FEATURE2_ARCH_2_07)
             ? __strcpy_power8 :
               (hwcap & PPC_FEATURE_HAS_VSX)
               ? __strcpy_power7
             : __strcpy_ppc);
+strong_alias (__libc_strcpy, strcpy)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncmp.c b/sysdeps/powerpc/powerpc64/multiarch/strncmp.c
index 1eb6e51..5a70c8e 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,10 +29,12 @@ 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;
+extern __typeof (strncmp) __libc_strncmp;
+# undef strncmp
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strncmp,
+libc_ifunc (__libc_strncmp,
             (hwcap2 & PPC_FEATURE2_ARCH_2_07)
             ? __strncmp_power8 :
               (hwcap & PPC_FEATURE_HAS_VSX)
@@ -37,4 +42,5 @@ libc_ifunc (strncmp,
 		(hwcap & PPC_FEATURE_POWER4)
 		? __strncmp_power4
             : __strncmp_ppc);
+strong_alias (__libc_strncmp, strncmp)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strncpy.c b/sysdeps/powerpc/powerpc64/multiarch/strncpy.c
index 0176514..2914e96 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,16 @@
 extern __typeof (strncpy) __strncpy_ppc attribute_hidden;
 extern __typeof (strncpy) __strncpy_power7 attribute_hidden;
 extern __typeof (strncpy) __strncpy_power8 attribute_hidden;
+extern __typeof (strncpy) __libc___strncpy;
+# undef strncpy
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
  ifunc symbol properly. */
-libc_ifunc (strncpy,
+libc_ifunc (__libc___strncpy,
             (hwcap2 & PPC_FEATURE2_ARCH_2_07)
             ? __strncpy_power8 :
               (hwcap & PPC_FEATURE_HAS_VSX)
               ? __strncpy_power7
             : __strncpy_ppc);
-
+strong_alias (__libc___strncpy, strncpy)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
index c4907e9..8a27746 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strnlen.c
@@ -17,19 +17,24 @@
    <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;
+extern __typeof (__strnlen) __libc___strnlen;
+# undef strnlen
+# undef __strnlen
 
-libc_ifunc (__strnlen,
+libc_ifunc (__libc___strnlen,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strnlen_power7
             : __strnlen_ppc);
-weak_alias (__strnlen, strnlen)
-libc_hidden_def (strnlen)
+strong_alias (__libc___strnlen, __strnlen)
+weak_alias (__libc___strnlen, strnlen)
 
 #else
 #include <string/strnlen.c>
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
index 45742bc..bbbc477 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strrchr.c
@@ -18,18 +18,22 @@
 
 /* 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;
+extern __typeof (strrchr) __libc_strrchr;
+#undef strrchr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strrchr,
+libc_ifunc (__libc_strrchr,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strrchr_power7
             : __strrchr_ppc);
-weak_alias (strrchr, rindex)
+strong_alias (__libc_strrchr, strrchr)
+weak_alias (__libc_strrchr, rindex)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/strstr.c b/sysdeps/powerpc/powerpc64/multiarch/strstr.c
index 7efc4b0..afde4de 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/strstr.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/strstr.c
@@ -18,17 +18,21 @@
 
 /* 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;
+extern __typeof (strstr) __libc_strstr;
+# undef strstr
 
 /* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle
    ifunc symbol properly.  */
-libc_ifunc (strstr,
+libc_ifunc (__libc_strstr,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strstr_power7
             : __strstr_ppc);
+strong_alias (__libc_strstr, strstr)
 #endif
diff --git a/sysdeps/powerpc/powerpc64/multiarch/wcschr.c b/sysdeps/powerpc/powerpc64/multiarch/wcschr.c
index 44c9b97..3d12a6e 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,18 @@
 extern __typeof (wcschr) __wcschr_ppc attribute_hidden;
 extern __typeof (wcschr) __wcschr_power6 attribute_hidden;
 extern __typeof (wcschr) __wcschr_power7 attribute_hidden;
+extern __typeof (wcschr) __libc___wcschr;
+# undef wcschr
+# undef __wcschr
 
-libc_ifunc (__wcschr,
+libc_ifunc (__libc___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)
+strong_alias (__libc___wcschr, __wcschr)
+weak_alias (__libc___wcschr, wcschr)
 #else
 #undef libc_hidden_def
 #define libc_hidden_def(a)
-- 
2.3.0


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

* Re: [PATCH 8/8] Use libc_ifunc macro for siglongjmp, longjmp in libpthread.
  2016-06-23 11:56 ` [PATCH 8/8] Use libc_ifunc macro for siglongjmp, longjmp in libpthread Stefan Liebler
@ 2016-07-04 14:05   ` Stefan Liebler
  0 siblings, 0 replies; 47+ messages in thread
From: Stefan Liebler @ 2016-07-04 14:05 UTC (permalink / raw)
  To: libc-alpha

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

This updated patch first undefines INIT_ARCH before it is defined.

On 06/23/2016 01:55 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.
> ---
>   nptl/pt-longjmp.c                         | 23 +++++------------------
>   sysdeps/unix/sysv/linux/s390/pt-longjmp.c |  4 ++--
>   2 files changed, 7 insertions(+), 20 deletions(-)
>
> diff --git a/nptl/pt-longjmp.c b/nptl/pt-longjmp.c
> index a1cc286..7c452cb 100644
> --- a/nptl/pt-longjmp.c
> +++ b/nptl/pt-longjmp.c
> @@ -32,24 +32,11 @@
>
>   # if HAVE_IFUNC
>
> -static __typeof (longjmp) *
> -__attribute__ ((used))
> -longjmp_resolve (void)
> -{
> -  return &__libc_longjmp;
> -}
> +#  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 +53,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))  */
>

[-- Attachment #2: 0008-Use-libc_ifunc-macro-for-siglongjmp-longjmp-in-libpt.patch --]
[-- Type: text/x-patch, Size: 2871 bytes --]

From 7f756e0e39a90324d84dd7eba0e0ba5c2c90ee2a Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Mon, 4 Jul 2016 15:33:57 +0200
Subject: [PATCH 8/8] Use libc_ifunc macro for siglongjmp, longjmp in
 libpthread.

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] 47+ messages in thread

* Re: [PATCH 6/8] Use libc_ifunc macro for system in libpthread.
  2016-06-23 14:16 ` [PATCH 6/8] Use libc_ifunc macro for system in libpthread Stefan Liebler
@ 2016-07-04 14:10   ` Stefan Liebler
  0 siblings, 0 replies; 47+ messages in thread
From: Stefan Liebler @ 2016-07-04 14:10 UTC (permalink / raw)
  To: libc-alpha

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

This updated patch first undefines INIT_ARCH before it is defined.

On 06/23/2016 01:55 PM, Stefan Liebler wrote:
> 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 | 18 +++---------------
>   1 file changed, 3 insertions(+), 15 deletions(-)
>
> diff --git a/nptl/pt-system.c b/nptl/pt-system.c
> index 56f2a89..6515056 100644
> --- a/nptl/pt-system.c
> +++ b/nptl/pt-system.c
> @@ -32,21 +32,9 @@
>
>   # 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;
> +#  define INIT_ARCH()
> +libc_ifunc (system_ifunc, &__libc_system)
>
>   # else  /* !HAVE_IFUNC */
>
>

[-- Attachment #2: 0006-Use-libc_ifunc-macro-for-system-in-libpthread.patch --]
[-- Type: text/x-patch, Size: 1174 bytes --]

From e8236a40057b8efd9d16096b023d0ce8a085d3e2 Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Mon, 4 Jul 2016 15:33:56 +0200
Subject: [PATCH 6/8] Use libc_ifunc macro for system in libpthread.

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] 47+ messages in thread

* Re: [PATCH 7/8] Use libc_ifunc macro for vfork in libpthread.
  2016-06-23 11:56 ` [PATCH 7/8] Use libc_ifunc macro for vfork in libpthread Stefan Liebler
@ 2016-07-04 14:15   ` Stefan Liebler
  0 siblings, 0 replies; 47+ messages in thread
From: Stefan Liebler @ 2016-07-04 14:15 UTC (permalink / raw)
  To: libc-alpha

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

This updated patch first undefines INIT_ARCH before it is defined.

On 06/23/2016 01:55 PM, Stefan Liebler wrote:
> 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 | 21 ++++-----------------
>   1 file changed, 4 insertions(+), 17 deletions(-)
>
> diff --git a/nptl/pt-vfork.c b/nptl/pt-vfork.c
> index 8f4be0c..6258835 100644
> --- a/nptl/pt-vfork.c
> +++ b/nptl/pt-vfork.c
> @@ -46,32 +46,19 @@
>
>   extern __typeof (vfork) __libc_vfork;   /* Defined in libc.  */
>
> -static __typeof (vfork) *
> -__attribute__ ((used))
> -vfork_resolve (void)
> -{
> -  return &__libc_vfork;
> -}
> +# 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
>

[-- Attachment #2: 0007-Use-libc_ifunc-macro-for-vfork-in-libpthread.patch --]
[-- Type: text/x-patch, Size: 1717 bytes --]

From 899785dab6aae3ba488382b38a8f67916e39cf2b Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Mon, 4 Jul 2016 15:33:57 +0200
Subject: [PATCH 7/8] Use libc_ifunc macro for vfork in libpthread.

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] 47+ messages in thread

* Re: [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday.
  2016-07-04 13:53     ` Stefan Liebler
@ 2016-07-06 11:42       ` Florian Weimer
  0 siblings, 0 replies; 47+ messages in thread
From: Florian Weimer @ 2016-07-06 11:42 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha

On 07/04/2016 03:45 PM, Stefan Liebler wrote:
>> I wonder if it possible to avoid some of the preprocessor magic by
>> introducing a separate x86_64 file.
> Do you mean moving x86/gettimeofday.c to x86_64/gettimeofday.c
> and get rid of #include <sysdeps/unix/sysv/linux/x86/gettimeofday.c>?

More like keeping the generic part in x86/gettimeofday.c, and overrides 
in i386/gettimeofday.c and x86_64/gettimeofday.c.  I was just wondering 
if that would be simpler.

I just don't like all these convoluted preprocessor hacks.

Florian

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

* Re: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-07-04 14:00   ` Stefan Liebler
@ 2016-07-06 11:45     ` Florian Weimer
  2016-07-12 14:57       ` [PING][PATCH " Stefan Liebler
  0 siblings, 1 reply; 47+ messages in thread
From: Florian Weimer @ 2016-07-06 11:45 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha; +Cc: munroesj

On 07/04/2016 03:44 PM, Stefan Liebler wrote:
>> These changes (i.e. patch 1/8) look reasonable to me.  Perhaps wait
>> another day if someone else objects.
> Do I have to wait for an explicit okay from intel/power maintainer?

1/8 is power-only, and I assumed that you could deal with this question 
internally. :)

The x86 changes need more substantial review from someone more familiar 
with this part of glibc, I think.

Florian

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

* Re: [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday.
  2016-07-04 13:41     ` Adhemerval Zanella
@ 2016-07-06 12:19       ` Florian Weimer
  0 siblings, 0 replies; 47+ messages in thread
From: Florian Weimer @ 2016-07-06 12:19 UTC (permalink / raw)
  To: Adhemerval Zanella, libc-alpha

On 07/04/2016 03:40 PM, Adhemerval Zanella wrote:
> If I recall correctly i686 has the same issue as powerpc32, where ifunc for local
> hidden symbols fails to resolve where called by another function library function.
> This examples shows the issue:

Thanks.  I believe this is a missing diagnostic in binutils.  The static 
link should fail due to incompatible relocations.  It is not possible to 
call an IFUNC (which needs an indirect call) while also avoiding the PLT 
on x86 (which results in a direct call).

Have you reported the lack of a diagnostic as a binutils RFE/bug?

Thanks,
Florian

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

* Re: [PING][PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-07-06 11:45     ` Florian Weimer
@ 2016-07-12 14:57       ` Stefan Liebler
  2016-07-20 15:47         ` Stefan Liebler
  0 siblings, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-07-12 14:57 UTC (permalink / raw)
  To: libc-alpha; +Cc: munroesj, Carlos O'Donell, Joseph S. Myers

PING

see latest patches:

[PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of 
inline assembly due to false debuginfo.
(This alters ppc and common code!)
https://www.sourceware.org/ml/libc-alpha/2016-07/msg00093.html

[PATCH 2/8] s390: Refactor ifunc resolvers due to false debuginfo.
https://www.sourceware.org/ml/libc-alpha/2016-07/msg00092.html

[PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday.
https://www.sourceware.org/ml/libc-alpha/2016-07/msg00091.html

[PATCH 4/8] ppc: Use libc_ifunc macro for time, gettimeofday.
https://www.sourceware.org/ml/libc-alpha/2016-06/msg00900.html

[PATCH 5/8] Use libc_ifunc macro for clock_* symbols in librt.
https://www.sourceware.org/ml/libc-alpha/2016-07/msg00090.html

[PATCH 6/8] Use libc_ifunc macro for system in libpthread.
https://www.sourceware.org/ml/libc-alpha/2016-07/msg00097.html

[PATCH 7/8] Use libc_ifunc macro for vfork in libpthread.
https://www.sourceware.org/ml/libc-alpha/2016-07/msg00098.html

[PATCH 8/8] Use libc_ifunc macro for siglongjmp, longjmp in libpthread.
https://www.sourceware.org/ml/libc-alpha/2016-07/msg00095.html


Hint:
These patches won't be commited before glibc 2.24 release.
The patch "[PATCH 03/14 v7] Do not stack-protect ifunc resolvers." 
(https://www.sourceware.org/ml/libc-alpha/2016-07/msg00174.html) depends 
on this series.

On 07/06/2016 01:45 PM, Florian Weimer wrote:
> On 07/04/2016 03:44 PM, Stefan Liebler wrote:
>>> These changes (i.e. patch 1/8) look reasonable to me.  Perhaps wait
>>> another day if someone else objects.
>> Do I have to wait for an explicit okay from intel/power maintainer?
>
> 1/8 is power-only, and I assumed that you could deal with this question
> internally. :)
>
> The x86 changes need more substantial review from someone more familiar
> with this part of glibc, I think.
>
> Florian
>

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

* Re: [PING][PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-07-12 14:57       ` [PING][PATCH " Stefan Liebler
@ 2016-07-20 15:47         ` Stefan Liebler
  2016-07-27 16:57           ` Stefan Liebler
  0 siblings, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-07-20 15:47 UTC (permalink / raw)
  To: libc-alpha; +Cc: munroesj, Carlos O'Donell, Joseph S. Myers

PING

On 07/12/2016 04:57 PM, Stefan Liebler wrote:
> PING
>
> see latest patches:
>
> [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of
> inline assembly due to false debuginfo.
> (This alters ppc and common code!)
> https://www.sourceware.org/ml/libc-alpha/2016-07/msg00093.html
>
> [PATCH 2/8] s390: Refactor ifunc resolvers due to false debuginfo.
> https://www.sourceware.org/ml/libc-alpha/2016-07/msg00092.html
>
> [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday.
> https://www.sourceware.org/ml/libc-alpha/2016-07/msg00091.html
>
> [PATCH 4/8] ppc: Use libc_ifunc macro for time, gettimeofday.
> https://www.sourceware.org/ml/libc-alpha/2016-06/msg00900.html
>
> [PATCH 5/8] Use libc_ifunc macro for clock_* symbols in librt.
> https://www.sourceware.org/ml/libc-alpha/2016-07/msg00090.html
>
> [PATCH 6/8] Use libc_ifunc macro for system in libpthread.
> https://www.sourceware.org/ml/libc-alpha/2016-07/msg00097.html
>
> [PATCH 7/8] Use libc_ifunc macro for vfork in libpthread.
> https://www.sourceware.org/ml/libc-alpha/2016-07/msg00098.html
>
> [PATCH 8/8] Use libc_ifunc macro for siglongjmp, longjmp in libpthread.
> https://www.sourceware.org/ml/libc-alpha/2016-07/msg00095.html
>
>
> Hint:
> These patches won't be commited before glibc 2.24 release.
> The patch "[PATCH 03/14 v7] Do not stack-protect ifunc resolvers."
> (https://www.sourceware.org/ml/libc-alpha/2016-07/msg00174.html) depends
> on this series.
>
> On 07/06/2016 01:45 PM, Florian Weimer wrote:
>> On 07/04/2016 03:44 PM, Stefan Liebler wrote:
>>>> These changes (i.e. patch 1/8) look reasonable to me.  Perhaps wait
>>>> another day if someone else objects.
>>> Do I have to wait for an explicit okay from intel/power maintainer?
>>
>> 1/8 is power-only, and I assumed that you could deal with this question
>> internally. :)
>>
>> The x86 changes need more substantial review from someone more familiar
>> with this part of glibc, I think.
>>
>> Florian
>>
>
>

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

* Re: [PING][PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-07-20 15:47         ` Stefan Liebler
@ 2016-07-27 16:57           ` Stefan Liebler
  0 siblings, 0 replies; 47+ messages in thread
From: Stefan Liebler @ 2016-07-27 16:57 UTC (permalink / raw)
  To: libc-alpha; +Cc: munroesj, Carlos O'Donell, Joseph S. Myers

PING

On 07/20/2016 04:05 PM, Stefan Liebler wrote:
> PING
>
> On 07/12/2016 04:57 PM, Stefan Liebler wrote:
>> PING
>>
>> see latest patches:
>>
>> [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of
>> inline assembly due to false debuginfo.
>> (This alters ppc and common code!)
>> https://www.sourceware.org/ml/libc-alpha/2016-07/msg00093.html
>>
>> [PATCH 2/8] s390: Refactor ifunc resolvers due to false debuginfo.
>> https://www.sourceware.org/ml/libc-alpha/2016-07/msg00092.html
>>
>> [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday.
>> https://www.sourceware.org/ml/libc-alpha/2016-07/msg00091.html
>>
>> [PATCH 4/8] ppc: Use libc_ifunc macro for time, gettimeofday.
>> https://www.sourceware.org/ml/libc-alpha/2016-06/msg00900.html
>>
>> [PATCH 5/8] Use libc_ifunc macro for clock_* symbols in librt.
>> https://www.sourceware.org/ml/libc-alpha/2016-07/msg00090.html
>>
>> [PATCH 6/8] Use libc_ifunc macro for system in libpthread.
>> https://www.sourceware.org/ml/libc-alpha/2016-07/msg00097.html
>>
>> [PATCH 7/8] Use libc_ifunc macro for vfork in libpthread.
>> https://www.sourceware.org/ml/libc-alpha/2016-07/msg00098.html
>>
>> [PATCH 8/8] Use libc_ifunc macro for siglongjmp, longjmp in libpthread.
>> https://www.sourceware.org/ml/libc-alpha/2016-07/msg00095.html
>>
>>
>> Hint:
>> These patches won't be commited before glibc 2.24 release.
>> The patch "[PATCH 03/14 v7] Do not stack-protect ifunc resolvers."
>> (https://www.sourceware.org/ml/libc-alpha/2016-07/msg00174.html) depends
>> on this series.
>>
>> On 07/06/2016 01:45 PM, Florian Weimer wrote:
>>> On 07/04/2016 03:44 PM, Stefan Liebler wrote:
>>>>> These changes (i.e. patch 1/8) look reasonable to me.  Perhaps wait
>>>>> another day if someone else objects.
>>>> Do I have to wait for an explicit okay from intel/power maintainer?
>>>
>>> 1/8 is power-only, and I assumed that you could deal with this question
>>> internally. :)
>>>
>>> The x86 changes need more substantial review from someone more familiar
>>> with this part of glibc, I think.
>>>
>>> Florian
>>>
>>
>>
>
>

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

* Re: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-06-23 11:56 [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo Stefan Liebler
                   ` (8 preceding siblings ...)
  2016-07-04  8:31 ` [PATCH " Florian Weimer
@ 2016-07-27 17:54 ` Paul E. Murphy
  2016-07-29 14:50   ` Stefan Liebler
  9 siblings, 1 reply; 47+ messages in thread
From: Paul E. Murphy @ 2016-07-27 17:54 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha
  Cc: joseph, carlos, munroesj, Tulio Magno Quites Machado Filho



On 06/23/2016 06:55 AM, Stefan Liebler wrote:
> diff --git a/include/libc-symbols.h b/include/libc-symbols.h
> index 4548e09..a77308a 100644
> --- a/include/libc-symbols.h
> +++ b/include/libc-symbols.h
> @@ -714,26 +714,21 @@ for linking")
>  #endif
> 
>  /* Marker used for indirection function symbols.  */
> -#define libc_ifunc(name, expr)						\
> -  extern void *name##_ifunc (void) __asm__ (#name);			\
> -  void *name##_ifunc (void)						\
> +#define __ifunc(name, expr, arg, init)					\
> +  extern __typeof (name) name __attribute__ ((ifunc(#name "_ifunc")));	\
> +  static void *name##_ifunc (arg)					\
>    {									\
> -    INIT_ARCH ();							\
> +    init ();								\
>      __typeof (name) *res = expr;					\
>      return res;								\
> -  }									\
> -  __asm__ (".type " #name ", %gnu_indirect_function");
> +  }
> +
> +#define libc_ifunc(name, expr) __ifunc (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, expr, void, libm_ifunc_init)
> 
>  #ifdef HAVE_ASM_SET_DIRECTIVE
>  # define libc_ifunc_hidden_def1(local, name)				\

I'm suspecting this attribute is not always enabled on all toolchains.

Testing this out with the system toolchain on a ppc64le P8 Ubuntu 14.04 system,
I was greeted with:

../sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c:35:13: error: ifunc is not supported in this configuration

gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04) 


What is the preferred method for exposing ifunc'ed API?  I see both
strong and weak aliases used in ppc multiarch code.  GCC claims only
strong are supported, but both macros are used throughout ppc
multiarch and seem to work.

Likewise, many of the changes add an extra declaration for the 
ifunc'ed symbol.  Isn't this now handled by the __ifunc() macro?
Can these redundant declarations be removed?

Simiarly, are all the macro redirections necessary? The redirects
in s_finitef.c for double and long double seem unnecessary, and
removing all them worked as expected.

Maybe another macro like libc_ifunc_public would be useful to
properly declare, and alias an indirect function?  That would
simplify much ppc code.

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

* Re: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-07-27 17:54 ` [PATCH " Paul E. Murphy
@ 2016-07-29 14:50   ` Stefan Liebler
  2016-08-01 20:18     ` Paul E. Murphy
  0 siblings, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-07-29 14:50 UTC (permalink / raw)
  To: libc-alpha; +Cc: Paul E. Murphy

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

On 07/27/2016 07:28 PM, Paul E. Murphy wrote:
> I'm suspecting this attribute is not always enabled on all toolchains.
>
> Testing this out with the system toolchain on a ppc64le P8 Ubuntu 14.04 system,
> I was greeted with:
>
> ../sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c:35:13: error: ifunc is not supported in this configuration
>
> gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
>
I've tested it on a ppc64 P7 RHEL 7 system with gcc 4.8.5 and there 
gcc/binutils have ifunc support. Why is ifunc not enabled in your gcc 
but binutils supports IFUNC? Is this related to ppc64le and/or Ubuntu 
14.04 / 16.04?
Does someone know if gcc does not support ifunc on other architectures / 
distros?
>
> What is the preferred method for exposing ifunc'ed API?  I see both
> strong and weak aliases used in ppc multiarch code.  GCC claims only
> strong are supported, but both macros are used throughout ppc
> multiarch and seem to work.
This patch does not change if a symbol is weak or strong.
The current ifunc symbols reflect the behaviour of the common code.

>
> Likewise, many of the changes add an extra declaration for the
> ifunc'ed symbol.  Isn't this now handled by the __ifunc() macro?
> Can these redundant declarations be removed?
The extra declaration and the redirection is needed if you have an
internal __GI_* symbol which is directed to a dedicated fallback
variant instead of being the ifunc'ed symbol (see e.g. strncpy).

The libc_hidden_builtin_def(strncpy) creates the __GI_strncpy
symbol in sysdeps/powerpc/powerpc64/multiarch/strncpy-ppc64.c.
If gcc creates the ifunc symbol without the extra declaration and 
redirection and uses gcc-attribute-ifunc without 
libc_hidden_builtin_def(strncpy), then gcc produces an ifunced 
__GI_strncpy symbol but no strncpy symbol.
If you add the libc_hidden_builtin_def(strncpy), gcc produces
an ifunced strncpy symbol and an ifunced __GI_strncpy symbol.
In both cases you have two __GI_strncpy symbols and linking libc.so fails.

If the __GI_* symbol is ifunc'ed, too like stpcpy, you don't need the 
extra declaration and redirection.
Have a look at sysdeps/powerpc/powerpc64/multiarch/stpcpy.c.

But you are right, the extra declaration is not needed and if it is done
in the __ifunc() macro. See below.

>
> Simiarly, are all the macro redirections necessary? The redirects
> in s_finitef.c for double and long double seem unnecessary, and
> removing all them worked as expected.
Yes you are right. In s_finitef.c/s_isinff.c the redirects are not 
necessary. I can remove them.

>
> Maybe another macro like libc_ifunc_public would be useful to
> properly declare, and alias an indirect function?  That would
> simplify much ppc code.
The redirection in the header files can't be done within such a macro
because you have to do it before including the header file.
To make the declaration, the macro would need to get the redirected 
function name and the real function name. As it is only needed if 
redirection is needed, the macro name should reflect this and could be 
named libc_ifunc_redirected instead of libc_ifunc_public.
Then it could do something like that:
#define libc_ifunc_redirected (redirected_name, name, expr) \
extern typeof (redirected_name) __libc_##name __attribute__ (ifunc)\
static void *resolver(arg) {...}\
strong_alias (__libc_##name, name)

The usage in e.g. strnlen.c could be:
# define strnlen __redirect_strnlen
# define __strnlen __redirect___strnlen
# include <string.h>

extern __typeof (__strnlen) __strnlen_ppc attribute_hidden;
extern __typeof (__strnlen) __strnlen_power7 attribute_hidden;
# undef strnlen
# undef __strnlen


libc_ifunc_redirected (__redirect___strnlen, __strnlen,
             (hwcap & PPC_FEATURE_HAS_VSX)
             ? __strnlen_power7
             : __strnlen_ppc);
weak_alias (__strnlen, strnlen)

I've updated the patches with these changes.
Please have a further look.

Thanks
Stefan

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Use-gcc-attribute-ifunc-in-libc_ifunc-macro-instead-.patch --]
[-- Type: text/x-patch; name="0001-Use-gcc-attribute-ifunc-in-libc_ifunc-macro-instead-.patch", Size: 55094 bytes --]

From 4d0b5a32e673549d1870edb2036f01398e950287 Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Fri, 29 Jul 2016 16:38:57 +0200
Subject: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of
 inline assembly due to false debuginfo.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The current s390 ifunc resolver for vector optimized functions and the common
libc_ifunc macro in include/libc-symbols.h uses something like that:
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.
Usage 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:
extern __typeof (__redirect___strnlen) __libc___strnlen;
__typeof (__libc___strnlen) __libc___strnlen __attribute__ ((ifunc ("__resolve_strnlen")));
strong_alias (__libc___strnlen, __strnlen)
weak_alias (__libc___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 or if the __GI_* symbol
targets to the ifunc symbol, 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.

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.

Tested the whole patchset by building glibc and running the testsuite on s390,
intel, power for 32/64bit. The __GI_* symbols targets the same functions as
before.

Okay to commit?

Bye
Stefan

ChangeLog:

	* include/libc-symbols.h (__ifunc): New macro uses gcc attribute ifunc.
	(libc_ifunc, libm_ifunc): Use __ifunc as base macro.
	(libc_ifunc_redirected, libm_ifunc_init): New define.
	* 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/fpu/multiarch/s_isnanf.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/fpu/multiarch/s_isnanf.cLikewise.
	* 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/stpcpy.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.
---
 include/libc-symbols.h                             | 33 ++++++++++++----------
 .../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      |  1 +
 .../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 |  1 +
 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       |  1 +
 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, 330 insertions(+), 211 deletions(-)

diff --git a/include/libc-symbols.h b/include/libc-symbols.h
index 4548e09..b95a0f9 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -714,26 +714,29 @@ for linking")
 #endif
 
 /* Marker used for indirection function symbols.  */
-#define libc_ifunc(name, expr)						\
-  extern void *name##_ifunc (void) __asm__ (#name);			\
-  void *name##_ifunc (void)						\
+#define __ifunc(type_name, name, expr, arg, init)			\
+  extern __typeof (type_name) name __attribute__			\
+			      ((ifunc (#name "_ifunc")));		\
+  static void *name##_ifunc (arg)					\
   {									\
-    INIT_ARCH ();							\
-    __typeof (name) *res = expr;					\
+    init ();								\
+    __typeof (type_name) *res = expr;					\
     return res;								\
-  }									\
-  __asm__ (".type " #name ", %gnu_indirect_function");
+  }
+
+#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)
+
 
 /* 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..304b2a7 100644
--- a/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
+++ b/sysdeps/powerpc/powerpc32/power4/fpu/multiarch/s_isnanf.c
@@ -35,4 +35,5 @@ libc_ifunc (__isnanf,
 		? __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..72e9a07 100644
--- a/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
+++ b/sysdeps/powerpc/powerpc64/fpu/multiarch/s_isnanf.c
@@ -40,4 +40,5 @@ libc_ifunc (__isnanf,
 		      ? __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..3867b9e 100644
--- a/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
+++ b/sysdeps/powerpc/powerpc64/multiarch/stpcpy.c
@@ -34,6 +34,7 @@ libc_ifunc (__stpcpy,
             : __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] 47+ messages in thread

* Re: [PATCH 2/8] s390: Refactor ifunc resolvers due to false debuginfo.
  2016-07-04 13:55     ` Stefan Liebler
@ 2016-07-29 14:55       ` Stefan Liebler
  0 siblings, 0 replies; 47+ messages in thread
From: Stefan Liebler @ 2016-07-29 14:55 UTC (permalink / raw)
  To: libc-alpha; +Cc: Paul E. Murphy

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

This is an update due to the comments from Paul.

On 07/04/2016 03:45 PM, Stefan Liebler wrote:
> On 07/04/2016 10:37 AM, Florian Weimer wrote:
>> On 06/23/2016 01:55 PM, Stefan Liebler wrote:
>>> 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_libc_ifunc_init): New define.
>>>     * sysdeps/s390/multiarch/memchr.c: Redirect ifunced function in
>>> header
>>>     and create a copy of the prototype for using as ifunc function.
>>>     Add appropiate aliases to the real symbol names.
>>
>> “appropriate”
> Ok
>>
>>> +  __ifunc (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);
>>
>> I don't think GNU style allows starting a line with a comma, and “:”
>> should be at the start of the line, not the end.
>>
> Ok, I corrected it. Thanks.
>> Otherwise, the changes look reasonable.
>>
>> Thanks,
>> Florian
>>

[-- Attachment #2: 0002-s390-Refactor-ifunc-resolvers-due-to-false-debuginfo.patch --]
[-- Type: text/x-patch, Size: 25599 bytes --]

From d18cf88de897f59018b71ed7e905d7785a59769e Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Fri, 29 Jul 2016 16:38:57 +0200
Subject: [PATCH 2/8] s390: Refactor ifunc resolvers due to false debuginfo.

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] 47+ messages in thread

* Re: [PATCH 4/8] ppc: Use libc_ifunc macro for time, gettimeofday.
  2016-06-23 11:56 ` [PATCH 4/8] ppc: Use libc_ifunc macro for time, gettimeofday Stefan Liebler
@ 2016-07-29 15:38   ` Stefan Liebler
  2016-08-02 15:45     ` Paul E. Murphy
  0 siblings, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-07-29 15:38 UTC (permalink / raw)
  To: libc-alpha; +Cc: Paul E. Murphy

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

This is an update due to the comments from Paul.

On 06/23/2016 01:55 PM, Stefan Liebler wrote:
> This patch uses the libc_ifunc 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 and libc_hidden_def macro. Redirect ifunced function in
> 	header and create a copy of the prototype for using as ifunc function
> 	for ppc32 and add appropiate aliases to the real symbol names.
> 	* sysdeps/unix/sysv/linux/powerpc/time.c (time): Likewise.
> ---
>   sysdeps/unix/sysv/linux/powerpc/gettimeofday.c | 64 ++++++++++++++-----------
>   sysdeps/unix/sysv/linux/powerpc/time.c         | 66 +++++++++++++-------------
>   2 files changed, 69 insertions(+), 61 deletions(-)
>
> diff --git a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
> index 25a4e7c..366364c 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
> +++ b/sysdeps/unix/sysv/linux/powerpc/gettimeofday.c
> @@ -15,6 +15,9 @@
>      License along with the GNU C Library; if not, see
>      <http://www.gnu.org/licenses/>.  */
>
> +#if defined SHARED && !defined __powerpc64__
> +# define __gettimeofday __redirect___gettimeofday
> +#endif
>
>   #include <sys/time.h>
>
> @@ -24,30 +27,17 @@
>   # include <libc-vdso.h>
>   # include <dl-machine.h>
>
> -void *gettimeofday_ifunc (void) __asm__ ("__gettimeofday");
> +# ifndef __powerpc64__
> +#  undef __gettimeofday
>
> -static int
> -__gettimeofday_syscall (struct timeval *tv, struct timezone *tz)
> -{
> -  return INLINE_SYSCALL (gettimeofday, 2, tv, tz);
> -}
> +extern __typeof (__redirect___gettimeofday) __libc___gettimeofday;
> +#  define __gettimeofday __libc___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 +45,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
> +
> +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 (__gettimeofday,
> +	    vdso_gettimeofday
> +	    ? VDSO_IFUNC_RET (vdso_gettimeofday)
> +	    : (void *) __gettimeofday_syscall);
> +libc_hidden_def (__gettimeofday)
>
>   #else
>
> @@ -81,3 +84,8 @@ libc_hidden_def (__gettimeofday)
>   #endif
>   weak_alias (__gettimeofday, gettimeofday)
>   libc_hidden_weak (gettimeofday)
> +
> +#if defined SHARED && !defined __powerpc64__
> +# undef __gettimeofday
> +strong_alias (__libc___gettimeofday, __gettimeofday)
> +#endif
> diff --git a/sysdeps/unix/sysv/linux/powerpc/time.c b/sysdeps/unix/sysv/linux/powerpc/time.c
> index 7973419..200f4a7 100644
> --- a/sysdeps/unix/sysv/linux/powerpc/time.c
> +++ b/sysdeps/unix/sysv/linux/powerpc/time.c
> @@ -17,6 +17,9 @@
>      <http://www.gnu.org/licenses/>.  */
>
>   #ifdef SHARED
> +# ifndef __powerpc64__
> +#  define time __redirect_time
> +# endif
>
>   # include <time.h>
>   # include <sysdep.h>
> @@ -24,7 +27,27 @@
>   # include <libc-vdso.h>
>   # include <dl-machine.h>
>
> -void *time_ifunc (void) asm ("time");
> +# ifndef __powerpc64__
> +#  undef time
> +extern __typeof (__redirect_time) 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 +65,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 (time,
> +	    vdso_time
> +	    ? VDSO_IFUNC_RET (vdso_time)
> +	    : (void *) time_syscall);
> +libc_hidden_def (time)
>
>   #else
>
>   #include <sysdeps/posix/time.c>
>
> -#endif
> +#endif /* !SHARED */
>

[-- Attachment #2: 0004-ppc-Use-libc_ifunc-macro-for-time-gettimeofday.patch --]
[-- Type: text/x-patch, Size: 7047 bytes --]

From 1d0febc930b57ad58cce43ea520ab4dba98d155c Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Fri, 29 Jul 2016 16:38:57 +0200
Subject: [PATCH 4/8] ppc: Use libc_ifunc macro for time, gettimeofday.

This patch uses the libc_ifunc 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 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..9cbcaf6 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_redirected (__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..b42827a 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_redirected (__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] 47+ messages in thread

* Re: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-07-29 14:50   ` Stefan Liebler
@ 2016-08-01 20:18     ` Paul E. Murphy
  2016-08-02 14:08       ` Stefan Liebler
  0 siblings, 1 reply; 47+ messages in thread
From: Paul E. Murphy @ 2016-08-01 20:18 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha



On 07/29/2016 09:48 AM, Stefan Liebler wrote:
> On 07/27/2016 07:28 PM, Paul E. Murphy wrote:
>> I'm suspecting this attribute is not always enabled on all toolchains.
>>
>> Testing this out with the system toolchain on a ppc64le P8 Ubuntu 14.04 system,
>> I was greeted with:
>>
>> ../sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c:35:13: error: ifunc is not supported in this configuration
>>
>> gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
>>
> I've tested it on a ppc64 P7 RHEL 7 system with gcc 4.8.5 and there gcc/binutils have ifunc support. Why is ifunc not enabled in your gcc but binutils supports IFUNC? Is this related to ppc64le and/or Ubuntu 14.04 / 16.04?
> Does someone know if gcc does not support ifunc on other architectures / distros?

I can't shine any light onto why, but it does demonstrate the need to
update the configury to check for this case, and handle it sensibly.

Currently it only checks whether binutils supports ifunc, and enables
multiarch in the absence of more specific options passed to configure.

> Yes you are right. In s_finitef.c/s_isinff.c the redirects are not necessary. I can remove them.

I assume the same holds for the extra redirects in s_finite, s_isinf,
and s_isnan.  Otherwise, the ppc specific changes are ok.

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

* Re: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-08-01 20:18     ` Paul E. Murphy
@ 2016-08-02 14:08       ` Stefan Liebler
  2016-08-03 11:33         ` Florian Weimer
  2016-08-05  6:46         ` Stefan Liebler
  0 siblings, 2 replies; 47+ messages in thread
From: Stefan Liebler @ 2016-08-02 14:08 UTC (permalink / raw)
  To: libc-alpha

On 08/01/2016 10:18 PM, Paul E. Murphy wrote:
>
>
> On 07/29/2016 09:48 AM, Stefan Liebler wrote:
>> On 07/27/2016 07:28 PM, Paul E. Murphy wrote:
>>> I'm suspecting this attribute is not always enabled on all toolchains.
>>>
>>> Testing this out with the system toolchain on a ppc64le P8 Ubuntu 14.04 system,
>>> I was greeted with:
>>>
>>> ../sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c:35:13: error: ifunc is not supported in this configuration
>>>
>>> gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
>>>
>> I've tested it on a ppc64 P7 RHEL 7 system with gcc 4.8.5 and there gcc/binutils have ifunc support. Why is ifunc not enabled in your gcc but binutils supports IFUNC? Is this related to ppc64le and/or Ubuntu 14.04 / 16.04?
>> Does someone know if gcc does not support ifunc on other architectures / distros?
>
> I can't shine any light onto why, but it does demonstrate the need to
> update the configury to check for this case, and handle it sensibly.
>
> Currently it only checks whether binutils supports ifunc, and enables
> multiarch in the absence of more specific options passed to configure.
>
Okay. Then I can add an extra configure check to test the gcc attribute 
ifunc support. If there is no support, a fallback ifunc-macro which uses 
the old behaviour could be used. Then it won't break the build but the 
debuginfo is not correct, too. Perhaps this fallback can be removed in 
future. Do you know if gcc in Ubuntu 16.04 has ifunc support for ppc64le?

>> Yes you are right. In s_finitef.c/s_isinff.c the redirects are not necessary. I can remove them.
>
> I assume the same holds for the extra redirects in s_finite, s_isinf,
> and s_isnan.  Otherwise, the ppc specific changes are ok.

Compiling s_finite.c without redirecting __finitef fails due:
In file included from 
../sysdeps/powerpc/powerpc64/fpu/multiarch/s_finite.c:22:0:
../include/math.h:15:18: error: ‘__finitef’ undeclared here (not in a 
function)
  hidden_proto (__finitef)


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

In math/math.h:
76: #define __MATHDECL_1(type, function,suffix, args) \
   extern type __MATH_PRECNAME(function,suffix) args __THROW
100: # define __MATH_PRECNAME(name,r) name##f##r
/* Include the file of declarations again, this time using `float'
    instead of `double' and appending f to each function name.  */
104: # include <bits/mathcalls.h>

In math/bits/mathcalls.h:
195: __MATHDECL_1 (int,__finite,, (_Mdouble_ __value)) __attribute__ 
((__const__));

Here is the declaration of "__finitef". Due to the redirection of 
__finite to __redirect___finite we get the declaration of 
__redirect___finitef instead of __finitef and thus __finitef is not 
declared as recognized by gcc and we have to redirect 
__finitef/__finitel, too.
The same applies to s_isnan.c and s_isinf.c.


Bye
Stefan

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

* Re: [PATCH 4/8] ppc: Use libc_ifunc macro for time, gettimeofday.
  2016-07-29 15:38   ` Stefan Liebler
@ 2016-08-02 15:45     ` Paul E. Murphy
  2016-08-05  6:46       ` Stefan Liebler
  0 siblings, 1 reply; 47+ messages in thread
From: Paul E. Murphy @ 2016-08-02 15:45 UTC (permalink / raw)
  To: Stefan Liebler, libc-alpha

Ok, pending approval of the first patch.

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

* Re: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-08-02 14:08       ` Stefan Liebler
@ 2016-08-03 11:33         ` Florian Weimer
  2016-08-03 15:49           ` Joseph Myers
  2016-08-05  6:46         ` Stefan Liebler
  1 sibling, 1 reply; 47+ messages in thread
From: Florian Weimer @ 2016-08-03 11:33 UTC (permalink / raw)
  To: Stefan Liebler; +Cc: libc-alpha

On 08/02/2016 04:07 PM, Stefan Liebler wrote:
> Okay. Then I can add an extra configure check to test the gcc attribute
> ifunc support. If there is no support, a fallback ifunc-macro which uses
> the old behaviour could be used. Then it won't break the build but the
> debuginfo is not correct, too. Perhaps this fallback can be removed in
> future. Do you know if gcc in Ubuntu 16.04 has ifunc support for ppc64le?

I would prefer if we could bump the minimum GCC and binutils version 
instead.

(I assume IFUNC support is not an optional feature in either tool which 
can be disabled at build time.)

Thanks,
Florian

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

* Re: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-08-03 11:33         ` Florian Weimer
@ 2016-08-03 15:49           ` Joseph Myers
  2016-08-05  6:46             ` Stefan Liebler
  0 siblings, 1 reply; 47+ messages in thread
From: Joseph Myers @ 2016-08-03 15:49 UTC (permalink / raw)
  To: Florian Weimer; +Cc: Stefan Liebler, libc-alpha

On Wed, 3 Aug 2016, Florian Weimer wrote:

> On 08/02/2016 04:07 PM, Stefan Liebler wrote:
> > Okay. Then I can add an extra configure check to test the gcc attribute
> > ifunc support. If there is no support, a fallback ifunc-macro which uses
> > the old behaviour could be used. Then it won't break the build but the
> > debuginfo is not correct, too. Perhaps this fallback can be removed in
> > future. Do you know if gcc in Ubuntu 16.04 has ifunc support for ppc64le?
> 
> I would prefer if we could bump the minimum GCC and binutils version instead.

Is GCC 4.8 recent enough?  (We required 4.7 for glibc 2.23, so moving to a 
requirement of 4.8 for glibc 2.25 would be reasonable on the basis of 
time-based updates to version requirements.  Binutils 2.24 would be 
required on the same basis and is already required for x86_64.)

-- 
Joseph S. Myers
joseph@codesourcery.com

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

* Re: [PATCH 4/8] ppc: Use libc_ifunc macro for time, gettimeofday.
  2016-08-02 15:45     ` Paul E. Murphy
@ 2016-08-05  6:46       ` Stefan Liebler
  0 siblings, 0 replies; 47+ messages in thread
From: Stefan Liebler @ 2016-08-05  6:46 UTC (permalink / raw)
  To: libc-alpha

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

On 08/02/2016 05:45 PM, Paul E. Murphy wrote:
> Ok, pending approval of the first patch.
>
>
This is an updated version due to changes in the first patch with 
libc_ifunc fallback if gcc does not support gcc attribute ifunc.

[-- Attachment #2: 0004-ppc-Use-libc_ifunc-macro-for-time-gettimeofday.patch --]
[-- Type: text/x-patch, Size: 7028 bytes --]

From 223b642762d639bca416cc3e99af98d21074fcd7 Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Thu, 4 Aug 2016 18:46:23 +0200
Subject: [PATCH 4/8] ppc: Use libc_ifunc macro for time, gettimeofday.

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] 47+ messages in thread

* Re: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-08-02 14:08       ` Stefan Liebler
  2016-08-03 11:33         ` Florian Weimer
@ 2016-08-05  6:46         ` Stefan Liebler
  1 sibling, 0 replies; 47+ messages in thread
From: Stefan Liebler @ 2016-08-05  6:46 UTC (permalink / raw)
  To: libc-alpha; +Cc: Paul E. Murphy, Joseph S. Myers, Florian Weimer

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

On 08/02/2016 04:07 PM, Stefan Liebler wrote:
> On 08/01/2016 10:18 PM, Paul E. Murphy wrote:
>>
>>
>> On 07/29/2016 09:48 AM, Stefan Liebler wrote:
>>> On 07/27/2016 07:28 PM, Paul E. Murphy wrote:
>>>> I'm suspecting this attribute is not always enabled on all toolchains.
>>>>
>>>> Testing this out with the system toolchain on a ppc64le P8 Ubuntu
>>>> 14.04 system,
>>>> I was greeted with:
>>>>
>>>> ../sysdeps/powerpc/powerpc64/fpu/multiarch/s_isinf.c:35:13: error:
>>>> ifunc is not supported in this configuration
>>>>
>>>> gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04)
>>>>
>>> I've tested it on a ppc64 P7 RHEL 7 system with gcc 4.8.5 and there
>>> gcc/binutils have ifunc support. Why is ifunc not enabled in your gcc
>>> but binutils supports IFUNC? Is this related to ppc64le and/or Ubuntu
>>> 14.04 / 16.04?
>>> Does someone know if gcc does not support ifunc on other
>>> architectures / distros?
>>
>> I can't shine any light onto why, but it does demonstrate the need to
>> update the configury to check for this case, and handle it sensibly.
>>
>> Currently it only checks whether binutils supports ifunc, and enables
>> multiarch in the absence of more specific options passed to configure.
>>
> Okay. Then I can add an extra configure check to test the gcc attribute
> ifunc support. If there is no support, a fallback ifunc-macro which uses
> the old behaviour could be used. Then it won't break the build but the
> debuginfo is not correct, too. Perhaps this fallback can be removed in
> future. Do you know if gcc in Ubuntu 16.04 has ifunc support for ppc64le?
>
Hi,

this is an updated version of the patch.
It adds a configure check to test if gcc supports attribute ifunc 
feature as not all configurations have support.
As fallback the old behaviour is used for the libc_ifunc macros.

The libc_ifunc macro with the old behaviour fails if the ifunc'ed 
function has an internal symbol. gcc fails with:
error: ‘__EI___stpcpy’ aliased to undefined symbol ‘__GI___stpcpy’
    extern __typeof (name) __EI_##name \
                           ^
./../include/libc-symbols.h:412:29: note: in expansion of macro 
‘__hidden_ver1’
  #  define hidden_def(name)  __hidden_ver1(__GI_##name, name, name);
                              ^
./../include/libc-symbols.h:463:32: note: in expansion of macro ‘hidden_def’
  # define libc_hidden_def(name) hidden_def (name)
                                 ^
../sysdeps/powerpc/powerpc64/multiarch/stpcpy.c:37:1: note: in expansion 
of macro ‘libc_hidden_def’
  libc_hidden_def (__stpcpy)
  ^

Therefore there is now a new libc_ifunc_hidden macro which uses e.g.:
extern __typof(__stpcpy) __libc___stpcpy;
and generates an ifunc'ed __libc___stpcpy function.
Afterwards a strong alias is used to create the internal symbol (via 
libc_hidden_def) and the real one:
strong_alias (__libc___stpcpy, __stpcpy);

Gcc with attribute ifunc can handle this case without an extra __libc_* 
function.

I've updated the i386, x86 / ppc time, gettimeofday patch to reflect 
these changes, too.

Tested on 32/64bit intel, powerpc, s390.
Paul: Can you retest it on powerpc little endian?

Bye
Stefan

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: 0001-Use-gcc-attribute-ifunc-in-libc_ifunc-macro-instead-.patch --]
[-- Type: text/x-patch; name="0001-Use-gcc-attribute-ifunc-in-libc_ifunc-macro-instead-.patch", Size: 62907 bytes --]

From c769887cc50f9d2305c44a93959854ca2ae76a0e Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Thu, 4 Aug 2016 18:46:23 +0200
Subject: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of
 inline assembly due to false debuginfo.
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

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.

Tested the whole patchset by building glibc and running the testsuite on s390,
intel, power for 32/64bit. The __GI_* symbols targets the same functions as
before.

Okay to commit?

Bye
Stefan

ChangeLog:

	* include/libc-symbols.h (__ifunc): New macro uses gcc attribute ifunc.
	(libc_ifunc, libm_ifunc): Use __ifunc as base macro.
	(libc_ifunc_redirected, libm_ifunc_init): New define.
	* config.h.in (HAVE_GCC_IFUNC): New undefine.
	* configure.ac: Add check if gcc supports attribute ifunc feature.
	* configure: Regenerated.
	* 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.
---
 config.h.in                                        |  3 +
 configure                                          | 36 +++++++++++
 configure.ac                                       | 29 +++++++++
 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 +++---
 41 files changed, 459 insertions(+), 238 deletions(-)

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..1b487b9 100755
--- a/configure
+++ b/configure
@@ -3914,6 +3914,37 @@ 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
@@ -6504,6 +6535,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..92f4838 100644
--- a/configure.ac
+++ b/configure.ac
@@ -634,6 +634,31 @@ 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])
@@ -1770,6 +1795,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/include/libc-symbols.h b/include/libc-symbols.h
index 4548e09..db6aba2 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -713,27 +713,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] 47+ messages in thread

* Re: [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday.
  2016-06-23 11:56 ` [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday Stefan Liebler
  2016-07-04  8:54   ` Florian Weimer
@ 2016-08-05  6:46   ` Stefan Liebler
  2016-08-05  8:38     ` Andreas Schwab
  1 sibling, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-08-05  6:46 UTC (permalink / raw)
  To: libc-alpha

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

This is an updated version due to changes in the first patch with 
libc_ifunc fallback if gcc does not support gcc attribute ifunc.

[-- Attachment #2: 0003-i386-x86-Use-libc_ifunc-macro-for-time-gettimeofday.patch --]
[-- Type: text/x-patch, Size: 6576 bytes --]

From 72ee959cd28ed906cb8f35283ba2bd091995728b Mon Sep 17 00:00:00 2001
From: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Thu, 4 Aug 2016 18:46:23 +0200
Subject: [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday.

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.
	(redirection): New define.
	* 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 db6aba2..4c59404 100644
--- a/include/libc-symbols.h
+++ b/include/libc-symbols.h
@@ -772,21 +772,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..cbf7833 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 redirection __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..c1c0cbd 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 redirection __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..4e53801 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 redirection
+/* The i386 gettimeofday.c includes this file with a defined redirection.
+   For x86_64 we have to define it to __gettimeofday as the internal symbol is
+   the ifunc'ed one.  */
+#  define redirection __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 (redirection, __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..88ee750 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 redirection
+/* The i386 time.c includes this file with a defined redirection.
+   For x86_64 we have to define it to time as the internal symbol is the
+   ifunc'ed one.  */
+#  define redirection 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 (redirection, time,
+		   (_dl_vdso_vsym ("__vdso_time", &linux26)
+		    ?:  &__time_syscall))
+libc_hidden_def (time)
 
 #else
 
-- 
2.3.0


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

* Re: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-08-03 15:49           ` Joseph Myers
@ 2016-08-05  6:46             ` Stefan Liebler
  2016-08-05  8:32               ` Andreas Schwab
  0 siblings, 1 reply; 47+ messages in thread
From: Stefan Liebler @ 2016-08-05  6:46 UTC (permalink / raw)
  To: libc-alpha; +Cc: Joseph S. Myers, Florian Weimer, Paul E. Murphy

On 08/03/2016 05:49 PM, Joseph Myers wrote:
> On Wed, 3 Aug 2016, Florian Weimer wrote:
>
>> On 08/02/2016 04:07 PM, Stefan Liebler wrote:
>>> Okay. Then I can add an extra configure check to test the gcc attribute
>>> ifunc support. If there is no support, a fallback ifunc-macro which uses
>>> the old behaviour could be used. Then it won't break the build but the
>>> debuginfo is not correct, too. Perhaps this fallback can be removed in
>>> future. Do you know if gcc in Ubuntu 16.04 has ifunc support for ppc64le?
>>
>> I would prefer if we could bump the minimum GCC and binutils version instead.
>
> Is GCC 4.8 recent enough?  (We required 4.7 for glibc 2.23, so moving to a
> requirement of 4.8 for glibc 2.25 would be reasonable on the basis of
> time-based updates to version requirements.  Binutils 2.24 would be
> required on the same basis and is already required for x86_64.)
>
Requiring a specific gcc / binutils version does not work. E.g. on s390x 
a gcc 4.7.4 has attribute ifunc support.
According to <gcc-src>/gcc/configure.ac there is an option 
--enable-gnu-indirect-function. If it is not specified it defaults to 
default_gnu_indirect_function variable. This is set to yes in 
<gcc-src>/gcc/config.gcc for intel / s390. Otherwise it is no.

According to the fedora / CentOS gcc.spec file ifunc is also enabled on 
e.g. power:
%ifarch %{ix86} x86_64 ppc ppc64 ppc64le ppc64p7 s390 s390x %{arm} aarch64
%global attr_ifunc 1
%else
%global attr_ifunc 0
%endif

%if 0%{?fedora} >= 21 || 0%{?rhel} >= 7
%if %{attr_ifunc}
    --enable-gnu-indirect-function \
%endif
%endif

I don't know how other distros handle this ifunc feature.

There is already a configure-check for binutils support which sets 
HAVE_IFUNC and the libc_ifunc-macro is only used if HAVE_IFUNC is set.

As already proposed I add a configure check to test gcc if attribute 
ifunc is supported and use it in libc_ifunc macro if available. As 
fallback, the old behaviour is used.

See my latest patch update.

Bye
Stefan

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

* Re: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-08-05  6:46             ` Stefan Liebler
@ 2016-08-05  8:32               ` Andreas Schwab
  2016-08-05  8:34                 ` Florian Weimer
  0 siblings, 1 reply; 47+ messages in thread
From: Andreas Schwab @ 2016-08-05  8:32 UTC (permalink / raw)
  To: Stefan Liebler
  Cc: libc-alpha, Joseph S. Myers, Florian Weimer, Paul E. Murphy

On Fr, Aug 05 2016, Stefan Liebler <stli@linux.vnet.ibm.com> wrote:

> Requiring a specific gcc / binutils version does not work. E.g. on s390x a
> gcc 4.7.4 has attribute ifunc support.
> According to <gcc-src>/gcc/configure.ac there is an option
> --enable-gnu-indirect-function. If it is not specified it defaults to
> default_gnu_indirect_function variable. This is set to yes in
> <gcc-src>/gcc/config.gcc for intel / s390. Otherwise it is no.

That should probably be updated, then.

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] 47+ messages in thread

* Re: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-08-05  8:32               ` Andreas Schwab
@ 2016-08-05  8:34                 ` Florian Weimer
  2016-08-05 15:11                   ` Paul E. Murphy
  0 siblings, 1 reply; 47+ messages in thread
From: Florian Weimer @ 2016-08-05  8:34 UTC (permalink / raw)
  To: Andreas Schwab, Stefan Liebler
  Cc: libc-alpha, Joseph S. Myers, Paul E. Murphy

On 08/05/2016 10:31 AM, Andreas Schwab wrote:
> On Fr, Aug 05 2016, Stefan Liebler <stli@linux.vnet.ibm.com> wrote:
>
>> Requiring a specific gcc / binutils version does not work. E.g. on s390x a
>> gcc 4.7.4 has attribute ifunc support.
>> According to <gcc-src>/gcc/configure.ac there is an option
>> --enable-gnu-indirect-function. If it is not specified it defaults to
>> default_gnu_indirect_function variable. This is set to yes in
>> <gcc-src>/gcc/config.gcc for intel / s390. Otherwise it is no.
>
> That should probably be updated, then.

I agree.  Can we require that GCC is configured with 
--enable-gnu-indirect-function for future glibc releases, please?

Thanks,
Florian

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

* Re: [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday.
  2016-08-05  6:46   ` Stefan Liebler
@ 2016-08-05  8:38     ` Andreas Schwab
  2016-08-08 14:46       ` Stefan Liebler
  0 siblings, 1 reply; 47+ messages in thread
From: Andreas Schwab @ 2016-08-05  8:38 UTC (permalink / raw)
  To: Stefan Liebler; +Cc: libc-alpha

On Fr, Aug 05 2016, Stefan Liebler <stli@linux.vnet.ibm.com> wrote:

> diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
> index 965bb81..cbf7833 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 redirection __redirect___gettimeofday

Please use a more specific name for this macro.

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] 47+ messages in thread

* Re: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-08-05  8:34                 ` Florian Weimer
@ 2016-08-05 15:11                   ` Paul E. Murphy
  2016-08-08 14:46                     ` Stefan Liebler
  0 siblings, 1 reply; 47+ messages in thread
From: Paul E. Murphy @ 2016-08-05 15:11 UTC (permalink / raw)
  To: Florian Weimer, Stefan Liebler
  Cc: Andreas Schwab, libc-alpha, Joseph S. Myers



On 08/05/2016 03:34 AM, Florian Weimer wrote:
> On 08/05/2016 10:31 AM, Andreas Schwab wrote:
>> On Fr, Aug 05 2016, Stefan Liebler <stli@linux.vnet.ibm.com> wrote:
>>
>>> Requiring a specific gcc / binutils version does not work. E.g. on s390x a
>>> gcc 4.7.4 has attribute ifunc support.
>>> According to <gcc-src>/gcc/configure.ac there is an option
>>> --enable-gnu-indirect-function. If it is not specified it defaults to
>>> default_gnu_indirect_function variable. This is set to yes in
>>> <gcc-src>/gcc/config.gcc for intel / s390. Otherwise it is no.
>>
>> That should probably be updated, then.
> 
> I agree.  Can we require that GCC is configured with --enable-gnu-indirect-function for future glibc releases, please?
> 
> Thanks,
> Florian
> 

Predicated on the desire to enable multiarch support.  Otherwise,
I agree.


Stefan, would you mind splitting out the configury changes into a
separate patch to enforce this stricter toolchain requirement when
testing for multiarch support?

Likewise, I would prefer disabling by default, and throwing
an error at configure time if --enable-multi-arch is requested
on such a toolchain.  Then, libc-symbols.h would not need to
maintain an old version of those macros which require less
rigid symbol mucking.

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

* Re: [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday.
  2016-08-05  8:38     ` Andreas Schwab
@ 2016-08-08 14:46       ` Stefan Liebler
  0 siblings, 0 replies; 47+ messages in thread
From: Stefan Liebler @ 2016-08-08 14:46 UTC (permalink / raw)
  To: libc-alpha

On 08/05/2016 10:38 AM, Andreas Schwab wrote:
> On Fr, Aug 05 2016, Stefan Liebler <stli@linux.vnet.ibm.com> wrote:
>
>> diff --git a/sysdeps/unix/sysv/linux/i386/gettimeofday.c b/sysdeps/unix/sysv/linux/i386/gettimeofday.c
>> index 965bb81..cbf7833 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 redirection __redirect___gettimeofday
>
> Please use a more specific name for this macro.
>
> Andreas.
>
Okay. Renamed to time_type and __gettimeofday_type.
I've posted the whole series again. See follow-up thread:

"[PATCH v2 4/9] i386, x86: Use libc_ifunc macro for time, gettimeofday."
https://www.sourceware.org/ml/libc-alpha/2016-08/msg00257.html

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

* Re: [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.
  2016-08-05 15:11                   ` Paul E. Murphy
@ 2016-08-08 14:46                     ` Stefan Liebler
  0 siblings, 0 replies; 47+ messages in thread
From: Stefan Liebler @ 2016-08-08 14:46 UTC (permalink / raw)
  To: libc-alpha

On 08/05/2016 05:11 PM, Paul E. Murphy wrote:
>
>
> On 08/05/2016 03:34 AM, Florian Weimer wrote:
>> On 08/05/2016 10:31 AM, Andreas Schwab wrote:
>>> On Fr, Aug 05 2016, Stefan Liebler <stli@linux.vnet.ibm.com> wrote:
>>>
>>>> Requiring a specific gcc / binutils version does not work. E.g. on s390x a
>>>> gcc 4.7.4 has attribute ifunc support.
>>>> According to <gcc-src>/gcc/configure.ac there is an option
>>>> --enable-gnu-indirect-function. If it is not specified it defaults to
>>>> default_gnu_indirect_function variable. This is set to yes in
>>>> <gcc-src>/gcc/config.gcc for intel / s390. Otherwise it is no.
>>>
>>> That should probably be updated, then.
>>
>> I agree.  Can we require that GCC is configured with --enable-gnu-indirect-function for future glibc releases, please?
>>
>> Thanks,
>> Florian
>>
>
> Predicated on the desire to enable multiarch support.  Otherwise,
> I agree.
>
>
> Stefan, would you mind splitting out the configury changes into a
> separate patch to enforce this stricter toolchain requirement when
> testing for multiarch support?
>
> Likewise, I would prefer disabling by default, and throwing
> an error at configure time if --enable-multi-arch is requested
> on such a toolchain.  Then, libc-symbols.h would not need to
> maintain an old version of those macros which require less
> rigid symbol mucking.
>
Okay. I've added an extra patch for the configure check
and posted the whole series again. See follow-up thread:

"[PATCH v2 1/9] Add configure check to test if gcc supports attribute 
ifunc."
https://www.sourceware.org/ml/libc-alpha/2016-08/msg00258.html

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

end of thread, other threads:[~2016-08-08 14:46 UTC | newest]

Thread overview: 47+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-23 11:56 [PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo Stefan Liebler
2016-06-23 11:56 ` [PATCH 3/8] i386, x86: Use libc_ifunc macro for time, gettimeofday Stefan Liebler
2016-07-04  8:54   ` Florian Weimer
2016-07-04 13:41     ` Adhemerval Zanella
2016-07-06 12:19       ` Florian Weimer
2016-07-04 13:53     ` Stefan Liebler
2016-07-06 11:42       ` Florian Weimer
2016-08-05  6:46   ` Stefan Liebler
2016-08-05  8:38     ` Andreas Schwab
2016-08-08 14:46       ` Stefan Liebler
2016-06-23 11:56 ` [PATCH 8/8] Use libc_ifunc macro for siglongjmp, longjmp in libpthread Stefan Liebler
2016-07-04 14:05   ` Stefan Liebler
2016-06-23 11:56 ` [PATCH 5/8] Use libc_ifunc macro for clock_* symbols in librt Stefan Liebler
2016-07-04  9:14   ` Florian Weimer
2016-07-04 13:49     ` Stefan Liebler
2016-06-23 11:56 ` [PATCH 7/8] Use libc_ifunc macro for vfork in libpthread Stefan Liebler
2016-07-04 14:15   ` Stefan Liebler
2016-06-23 11:56 ` [PATCH 2/8] s390: Refactor ifunc resolvers due to false debuginfo Stefan Liebler
2016-07-04  8:37   ` Florian Weimer
2016-07-04 13:55     ` Stefan Liebler
2016-07-29 14:55       ` Stefan Liebler
2016-06-23 11:56 ` [PATCH 4/8] ppc: Use libc_ifunc macro for time, gettimeofday Stefan Liebler
2016-07-29 15:38   ` Stefan Liebler
2016-08-02 15:45     ` Paul E. Murphy
2016-08-05  6:46       ` Stefan Liebler
2016-06-23 14:16 ` [PATCH 6/8] Use libc_ifunc macro for system in libpthread Stefan Liebler
2016-07-04 14:10   ` Stefan Liebler
2016-06-29 12:56 ` [PING][PATCH 1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo Stefan Liebler
2016-07-04  7:25   ` Stefan Liebler
2016-07-04  8:31 ` [PATCH " Florian Weimer
2016-07-04 14:00   ` Stefan Liebler
2016-07-06 11:45     ` Florian Weimer
2016-07-12 14:57       ` [PING][PATCH " Stefan Liebler
2016-07-20 15:47         ` Stefan Liebler
2016-07-27 16:57           ` Stefan Liebler
2016-07-27 17:54 ` [PATCH " Paul E. Murphy
2016-07-29 14:50   ` Stefan Liebler
2016-08-01 20:18     ` Paul E. Murphy
2016-08-02 14:08       ` Stefan Liebler
2016-08-03 11:33         ` Florian Weimer
2016-08-03 15:49           ` Joseph Myers
2016-08-05  6:46             ` Stefan Liebler
2016-08-05  8:32               ` Andreas Schwab
2016-08-05  8:34                 ` Florian Weimer
2016-08-05 15:11                   ` Paul E. Murphy
2016-08-08 14:46                     ` Stefan Liebler
2016-08-05  6:46         ` 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).