diff options
author | Adhemerval Zanella <azanella@linux.vnet.ibm.com> | 2013-03-28 16:28:56 -0500 |
---|---|---|
committer | Adhemerval Zanella <azanella@linux.vnet.ibm.com> | 2013-03-28 16:28:56 -0500 |
commit | 254d12ecfcaff6f3240447269c5c4da7a7798a0a (patch) | |
tree | a745956fef1ba44a1269da850bef27baf1d3baef | |
parent | 1ef83476d0aacae4ee0d2fd07aca2868cb1cdbcb (diff) | |
download | glibc-254d12ecfcaff6f3240447269c5c4da7a7798a0a.tar.gz glibc-254d12ecfcaff6f3240447269c5c4da7a7798a0a.tar.xz glibc-254d12ecfcaff6f3240447269c5c4da7a7798a0a.zip |
PowerPC: strnlen ifunc using C
-rw-r--r-- | sysdeps/powerpc/powerpc32/multiarch/init-arch.h | 17 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc32/multiarch/strnlen.S | 70 | ||||
-rw-r--r-- | sysdeps/powerpc/powerpc32/multiarch/strnlen.c | 36 |
3 files changed, 52 insertions, 71 deletions
diff --git a/sysdeps/powerpc/powerpc32/multiarch/init-arch.h b/sysdeps/powerpc/powerpc32/multiarch/init-arch.h index 17f870807a..a1b20eb870 100644 --- a/sysdeps/powerpc/powerpc32/multiarch/init-arch.h +++ b/sysdeps/powerpc/powerpc32/multiarch/init-arch.h @@ -17,5 +17,20 @@ #include <ldsodefs.h> +/* The code checks if _rtld_global_ro was realocated before trying to access + the dl_hwcap field. The assembly is to make the compiler not optimize the + test (&_rtld_global_ro != NULL), which is always true in ISO C (but not + in that case since _rtld_global_ro might not been realocated yet.). */ +#if defined(SHARED) && !defined(IS_IN_rtld) +# define __GLRO(value) \ + ({ volatile void **__p = (volatile void**)(&_rtld_global_ro); \ + unsigned long int __ret; \ + asm ("# x in %0" : "+r" (__p)); \ + __ret = (__p) ? GLRO(value) : 0; \ + __ret; }) +#else +# define __GLRO(value) GLRO(value) +#endif + # define INIT_ARCH() \ - unsigned long int hwcap = GLRO(dl_hwcap); + unsigned long int hwcap = __GLRO(dl_hwcap); diff --git a/sysdeps/powerpc/powerpc32/multiarch/strnlen.S b/sysdeps/powerpc/powerpc32/multiarch/strnlen.S deleted file mode 100644 index 1b3f46eaf1..0000000000 --- a/sysdeps/powerpc/powerpc32/multiarch/strnlen.S +++ /dev/null @@ -1,70 +0,0 @@ -/* Copyright (C) 2013 Free Software Foundation, Inc. - This file is part of the GNU C Library. - - The GNU C Library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - The GNU C Library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public - License along with the GNU C Library; if not, see - <http://www.gnu.org/licenses/>. */ - -#include <sysdep.h> -#include <rtld-global-offsets.h> - -/* Define multiple versions only for the definition in libc. */ -#ifndef NOT_IN_libc - .text -ENTRY(__strnlen) - .type __strnlen, @gnu_indirect_function -# ifdef PIC - mflr r6 - cfi_register (lr,r6) - SETUP_GOT_ACCESS (r5,got_label) - addis r5,r5,_GLOBAL_OFFSET_TABLE_-got_label@ha - addi r5,r5,_GLOBAL_OFFSET_TABLE_-got_label@l - mtlr r6 - cfi_same_value (lr) -# ifdef SHARED - lwz r6,_rtld_global_ro@got(r5) - /* If _rtld_global_ro is not initialized use the default ppc32 - implementation. */ - cmplwi r6,0 - beq L(ppc32) - lwz r6,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+4(r6) -# else - lwz r6,_dl_hwcap@got(r5) - lwz r6,4(r6) -# endif -# else /* PIC */ - lis r6,(_dl_hwcap+4)@ha - lwz r6,(_dl_hwcap+4)@l(r6) -# endif - andi. r7,r6,PPC_FEATURE_HAS_VSX - bne L(power7) -L(ppc32): -# ifdef PIC - lwz r3,__strnlen_ppc32@got(r5) -# else - lis r3,__strnlen_ppc32@ha - lwz r3,__strnlen_ppc32@l(r3) -# endif - blr -L(power7): -# ifdef PIC - lwz r3,__strnlen_power7@got(r5) -# else - lis r3,__strnlen_power7@ha - lwz r3,__strnlen_power7@l(r3) -# endif - blr -END(__strnlen) - -weak_alias (__strnlen, strnlen) -#endif diff --git a/sysdeps/powerpc/powerpc32/multiarch/strnlen.c b/sysdeps/powerpc/powerpc32/multiarch/strnlen.c new file mode 100644 index 0000000000..0fb946010d --- /dev/null +++ b/sysdeps/powerpc/powerpc32/multiarch/strnlen.c @@ -0,0 +1,36 @@ +/* Multiple versions of strnlen. + Copyright (C) 2013 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#ifndef NOT_IN_libc +# include <string.h> +# include <shlib-compat.h> +# include "init-arch.h" + +extern __typeof (__strnlen) __strnlen_ppc32 attribute_hidden; +extern __typeof (__strnlen) __strnlen_power7 attribute_hidden; + +/* Avoid DWARF definition DIE on ifunc symbol so that GDB can handle + ifunc symbol properly. */ +libc_ifunc (__strnlen, + (hwcap & PPC_FEATURE_HAS_VSX) + ? __strnlen_power7 + : __strnlen_ppc32); + +weak_alias (__strnlen, strnlen); +libc_hidden_def (strnlen) +#endif |