commit 9c8af17c56134cb1cde6a3adc3aa7737c49cbeff
Author: Stefan Liebler <stli@linux.vnet.ibm.com>
Date: Mon Nov 13 13:46:50 2017 +0100
Use libc_hidden_proto / _def for hidden wchar ifunc symbols.
On s390 (31bit) various debug/tst-*chk* testcases are failing as the tests
are ending with a segmentation fault.
One test is e.g. calling wcsnrtombs in debug/tst-chk1.c:1549.
The function wcsnrtombs itself calls __wcsnlen. This function is called via
PLT! The PLT-stub itself loads the address from GOT (r12 is assumed to be
the GOT-pointer). In this case the loaded address is zero and the following
branch leads to the segmentation fault.
Due to the attribute-hidden in commit 44af8a32c341672b5160fdc2839767e9a837ad26
"Mark internal wchar functions with attribute_hidden [BZ #18822]"
for e.g. the __wcsnlen function, r12 is not loaded with the GOT-pointer
in wcsnrtombs.
On s390x (64bit), this __wcsnlen call is also using the PLT-stub. But it is
not failing as the GOT-pointer is setup with larl-instruction by the PLT-stub
itself.
Note: On s390x/s390, __wcsnlen is an IFUNC symbol.
On x86_64, __wcsnlen is also an IFUNC symbol and is called via PLT, too.
Further IFUNC symbols on s390 which were marked as hidden by the mentioned
commit are: __wcscat, __wcsncpy, __wcpncpy, __wcschrnul.
This patch adds the libc_hidden_proto / libc_hidden_def construct and
removes the attribute_hidden as it conflicts with libc_hidden* construct on
some architectures. Then the __GI_* symbols are the default-ifunc-variants
which can be called without PLT.
ChangeLog:
* include/wchar.h (__wcsnlen, __wcscat, __wcsncpy, __wcpncpy,
__wcschrnul): Add libc_hidden_proto, Remove attribute_hidden.
* wcsmbs/wcsnlen.c (__wcsnlen): Add libc_hidden_def.
* wcsmbs/wcscat.c (__wcscat): Likewise.
* wcsmbs/wcschrnul.c (__wcschrnul): Likewise.
* wcsmbs/wcsncpy.c (__wcsncpy): Likewise.
* wcsmbs/wcpncpy.c (__wcpncpy): Likewise.
* sysdeps/x86_64/multiarch/wcsnlen-c.c (__wcsnlen): Add libc_hidden_def
which aliases to default ifunc-variant.
* sysdeps/s390/multiarch/wcsnlen-c.c (__wcsnlen): Likewise.
* sysdeps/s390/multiarch/wcscat-c.c (__wcscat): Likewise.
* sysdeps/s390/multiarch/wcschrnul-c.c (__wcschrnul): Likewise.
* sysdeps/s390/multiarch/wcsncpy-c.c (__wcsncpy): Likewise.
* sysdeps/s390/multiarch/wcpncpy-c.c (__wcpncpy): Likewise.
* sysdeps/s390/multiarch/wcsnlen.c (__wcsnlen): Redirect symbol in
header and use s390_vx_libc_ifunc_redirected instead of
s390_vx_libc_ifunc.
* sysdeps/s390/multiarch/wcscat.c (__wcscat): Likewise.
* sysdeps/s390/multiarch/wcschrnul.c (__wcschrnul): Likewise.
* sysdeps/s390/multiarch/wcsncpy.c (__wcsncpy): Likewise.
* sysdeps/s390/multiarch/wcpncpy.c (__wcpncpy): Likewise.
@@ -152,9 +152,10 @@ extern int __wcsncasecmp (const wchar_t *__s1, const wchar_t *__s2,
__attribute_pure__;
extern size_t __wcslen (const wchar_t *__s) __attribute_pure__;
extern size_t __wcsnlen (const wchar_t *__s, size_t __maxlen)
- attribute_hidden __attribute_pure__;
-extern wchar_t *__wcscat (wchar_t *dest, const wchar_t *src)
- attribute_hidden;
+ __attribute_pure__;
+libc_hidden_proto (__wcsnlen)
+extern wchar_t *__wcscat (wchar_t *dest, const wchar_t *src);
+libc_hidden_proto (__wcscat)
extern wint_t __btowc (int __c) attribute_hidden;
extern int __mbsinit (const __mbstate_t *__ps);
extern size_t __mbrtowc (wchar_t *__restrict __pwc,
@@ -182,11 +183,12 @@ extern size_t __wcsnrtombs (char *__restrict __dst,
__mbstate_t *__restrict __ps)
attribute_hidden;
extern wchar_t *__wcsncpy (wchar_t *__restrict __dest,
- const wchar_t *__restrict __src, size_t __n)
- attribute_hidden;
+ const wchar_t *__restrict __src, size_t __n);
+libc_hidden_proto (__wcsncpy)
extern wchar_t *__wcpcpy (wchar_t *__dest, const wchar_t *__src);
extern wchar_t *__wcpncpy (wchar_t *__dest, const wchar_t *__src,
- size_t __n) attribute_hidden;
+ size_t __n);
+libc_hidden_proto (__wcpncpy)
extern wchar_t *__wmemcpy (wchar_t *__s1, const wchar_t *s2,
size_t __n) attribute_hidden;
extern wchar_t *__wmempcpy (wchar_t *__restrict __s1,
@@ -195,7 +197,8 @@ extern wchar_t *__wmempcpy (wchar_t *__restrict __s1,
extern wchar_t *__wmemmove (wchar_t *__s1, const wchar_t *__s2,
size_t __n) attribute_hidden;
extern wchar_t *__wcschrnul (const wchar_t *__s, wchar_t __wc)
- attribute_hidden __attribute_pure__;
+ __attribute_pure__;
+libc_hidden_proto (__wcschrnul)
extern wchar_t *__wmemset_chk (wchar_t *__s, wchar_t __c, size_t __n,
size_t __ns) __THROW;
@@ -21,5 +21,11 @@
# include <wchar.h>
extern __typeof (__wcpncpy) __wcpncpy_c;
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__wcpncpy_c, __GI___wcpncpy, __wcpncpy_c);
+# endif /* SHARED */
# include <wcsmbs/wcpncpy.c>
+libc_hidden_def (__wcpncpy)
#endif
@@ -17,10 +17,12 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define __wcpncpy __redirect___wcpncpy
# include <wchar.h>
+# undef __wcpncpy
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc (__wcpncpy)
+s390_vx_libc_ifunc_redirected (__redirect___wcpncpy, __wcpncpy)
weak_alias (__wcpncpy, wcpncpy)
#else
@@ -21,5 +21,11 @@
# include <wchar.h>
extern __typeof (__wcscat) __wcscat_c;
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__wcscat_c, __GI___wcscat, __wcscat_c);
+# endif /* SHARED */
# include <wcsmbs/wcscat.c>
+libc_hidden_def (__wcscat)
#endif
@@ -17,10 +17,12 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define __wcscat __redirect___wcscat
# include <wchar.h>
+# undef __wcscat
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc (__wcscat)
+s390_vx_libc_ifunc_redirected (__redirect___wcscat, __wcscat)
weak_alias (__wcscat, wcscat)
#else
@@ -21,5 +21,11 @@
# include <wchar.h>
extern __typeof (__wcschrnul) __wcschrnul_c;
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__wcschrnul_c, __GI___wcschrnul, __wcschrnul_c);
+# endif /* SHARED */
# include <wcsmbs/wcschrnul.c>
+libc_hidden_def (__wcschrnul)
#endif
@@ -17,10 +17,12 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define __wcschrnul __redirect___wcschrnul
# include <wchar.h>
+# undef __wcschrnul
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc (__wcschrnul)
+s390_vx_libc_ifunc_redirected (__redirect___wcschrnul, __wcschrnul)
weak_alias (__wcschrnul, wcschrnul)
#else
@@ -21,5 +21,11 @@
# include <wchar.h>
extern __typeof (__wcsncpy) __wcsncpy_c;
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__wcsncpy_c, __GI___wcsncpy, __wcsncpy_c);
+# endif /* SHARED */
# include <wcsmbs/wcsncpy.c>
+libc_hidden_def (__wcsncpy)
#endif
@@ -17,10 +17,12 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define __wcsncpy __redirect___wcsncpy
# include <wchar.h>
+# undef __wcsncpy
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc (__wcsncpy)
+s390_vx_libc_ifunc_redirected (__redirect___wcsncpy, __wcsncpy)
weak_alias (__wcsncpy, wcsncpy)
#else
@@ -21,5 +21,11 @@
# include <wchar.h>
extern __typeof (__wcsnlen) __wcsnlen_c;
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__wcsnlen_c, __GI___wcsnlen, __wcsnlen_c);
+# endif /* SHARED */
# include <wcsmbs/wcsnlen.c>
+libc_hidden_def (__wcsnlen)
#endif
@@ -17,10 +17,12 @@
<http://www.gnu.org/licenses/>. */
#if defined HAVE_S390_VX_ASM_SUPPORT && IS_IN (libc)
+# define __wcsnlen __redirect___wcsnlen
# include <wchar.h>
+# undef __wcsnlen
# include <ifunc-resolve.h>
-s390_vx_libc_ifunc (__wcsnlen)
+s390_vx_libc_ifunc_redirected (__redirect___wcsnlen, __wcsnlen)
weak_alias (__wcsnlen, wcsnlen)
#else
@@ -4,6 +4,13 @@
# define WCSNLEN __wcsnlen_sse2
extern __typeof (wcsnlen) __wcsnlen_sse2;
+
+# ifdef SHARED
+# undef libc_hidden_def
+# define libc_hidden_def(name) \
+ __hidden_ver1 (__wcsnlen_sse2, __GI___wcsnlen, __wcsnlen_sse2);
+libc_hidden_def (__wcsnlen)
+# endif /* SHARED */
#endif
#include "wcsmbs/wcsnlen.c"
@@ -83,5 +83,6 @@ __wcpncpy (wchar_t *dest, const wchar_t *src, size_t n)
}
#ifndef WCPNCPY
+libc_hidden_def (__wcpncpy)
weak_alias (__wcpncpy, wcpncpy)
#endif
@@ -49,5 +49,6 @@ __wcscat (wchar_t *dest, const wchar_t *src)
return dest;
}
#ifndef WCSCAT
+libc_hidden_def (__wcscat)
weak_alias (__wcscat, wcscat)
#endif
@@ -34,5 +34,6 @@ __wcschrnul (const wchar_t *wcs, const wchar_t wc)
return (wchar_t *) wcs;
}
#ifndef WCSCHRNUL
+libc_hidden_def (__wcschrnul)
weak_alias (__wcschrnul, wcschrnul)
#endif
@@ -84,5 +84,6 @@ __wcsncpy (wchar_t *dest, const wchar_t *src, size_t n)
return s;
}
#ifndef WCSNCPY
+libc_hidden_def (__wcsncpy)
weak_alias (__wcsncpy, wcsncpy)
#endif
@@ -46,5 +46,6 @@ __wcsnlen (const wchar_t *s, size_t maxlen)
return len;
}
#ifndef WCSNLEN
+libc_hidden_def (__wcsnlen)
weak_alias (__wcsnlen, wcsnlen)
#endif