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

