diff mbox

[1/8] Use gcc attribute ifunc in libc_ifunc macro instead of inline assembly due to false debuginfo.

Message ID 1466682952-6301-1-git-send-email-stli@linux.vnet.ibm.com
State Superseded
Headers show

Commit Message

Stefan Liebler June 23, 2016, 11:55 a.m. UTC
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(-)

Comments

Stefan Liebler June 29, 2016, 12:55 p.m. UTC | #1
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)
>
Stefan Liebler July 4, 2016, 7:20 a.m. UTC | #2
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)
>>
>
>
Florian Weimer July 4, 2016, 8:31 a.m. UTC | #3
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
Paul E. Murphy July 27, 2016, 5:28 p.m. UTC | #4
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.
diff mbox

Patch

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)