commit 528b86d124130cc97a283b668b17a868915f069e
Author: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Thu Apr 14 16:56:51 2016 +0200
S390: Refactor ifunc resolvers due to false debuginfo.
The current s390 ifunc resolver for vector optimized functions 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 tosomething 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, this redirection is not needed.
This patch adjusts the s390 specific ifunc helper macros in ifunc-resolve.h to
use gcc attribute ifunc to get rid of the false debuginfo. Therefore the
redirection construct is applied where needed.
Is this okay to commit?
Does anybody know a better solution for the trouble with internal symbols?
Perhaps in future we can switch some of the internal symbols __GI_* from the
fallback variant to the ifunc function. But this change is also not
straightforward due to a segmentation fault while linking libc.so with older
binutils.
Bye
Stefan
ChangeLog:
* sysdeps/s390/multiarch/ifunc-resolve.h
(s390_vx_libc_ifunc2): Use gcc attribute ifunc for ifunc symbols
and make resolver function static.
(s390_libc_ifunc): Align as most as possible to s390_vx_libc_ifunc2.
* sysdeps/s390/multiarch/memchr.c: Redirect ifunced function in header
and create a copy of the prototype for using as 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.
@@ -41,18 +41,17 @@
: "=QS" (STFLE_BITS), "+d" (reg0) \
: : "cc");
-#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) \
+ extern __typeof (FUNC) FUNC \
+ __attribute__ ((ifunc ("__resolve_" #RESOLVERFUNC))); \
\
/* 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; \
+ extern __typeof (FUNC) RESOLVERFUNC##_z196 attribute_hidden; \
+ extern __typeof (FUNC) RESOLVERFUNC##_z10 attribute_hidden; \
+ extern __typeof (FUNC) RESOLVERFUNC##_default attribute_hidden; \
\
- void *__resolve_##FUNC (unsigned long int dl_hwcap) \
+ static void *__resolve_##RESOLVERFUNC (unsigned long int dl_hwcap) \
{ \
if ((dl_hwcap & HWCAP_S390_STFLE) \
&& (dl_hwcap & HWCAP_S390_ZARCH) \
@@ -62,31 +61,32 @@
S390_STORE_STFLE (stfle_bits); \
\
if (S390_IS_Z196 (stfle_bits)) \
- return &__##FUNC##_z196; \
+ return &RESOLVERFUNC##_z196; \
else if (S390_IS_Z10 (stfle_bits)) \
- return &__##FUNC##_z10; \
+ return &RESOLVERFUNC##_z10; \
else \
- return &__##FUNC##_default; \
+ return &RESOLVERFUNC##_default; \
} \
else \
- return &__##FUNC##_default; \
+ return &RESOLVERFUNC##_default; \
}
#define s390_vx_libc_ifunc(FUNC) \
s390_vx_libc_ifunc2(FUNC, FUNC)
#define s390_vx_libc_ifunc2(RESOLVERFUNC, FUNC) \
+ extern __typeof (FUNC) FUNC \
+ __attribute__ ((ifunc ("__resolve_" #RESOLVERFUNC))); \
+ \
/* 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) \
+ static 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");
+ }
@@ -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
@@ -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
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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
@@ -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
@@ -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>
@@ -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>
@@ -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>
@@ -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
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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>
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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