This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] Use libc_hidden_proto / _def for hidden wchar ifunc symbols.
On 11/13/2017 12:55 PM, Florian Weimer wrote:
On 11/13/2017 11:16 AM, Stefan Liebler wrote:
This patch adds the libc_hidden_proto / libc_hidden_def construct.
Then the __GI_* symbols are the default-ifunc-variants which can be
called without PLT.
attribute_hidden and *_hidden_{proto,def} conflict on some
architectures. You need to remove attribute_hidden as part of this change.
Thanks,
Florian
Thanks for this hint.
This is an updated version which removes the attribute_hidden, too.
Bye
Stefan
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.
diff --git a/include/wchar.h b/include/wchar.h
index 24b2eaa..1efc33b 100644
--- a/include/wchar.h
+++ b/include/wchar.h
@@ -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;
diff --git a/sysdeps/s390/multiarch/wcpncpy-c.c b/sysdeps/s390/multiarch/wcpncpy-c.c
index 7cb834b..b02e40a 100644
--- a/sysdeps/s390/multiarch/wcpncpy-c.c
+++ b/sysdeps/s390/multiarch/wcpncpy-c.c
@@ -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
diff --git a/sysdeps/s390/multiarch/wcpncpy.c b/sysdeps/s390/multiarch/wcpncpy.c
index 1a19a99..a902787 100644
--- a/sysdeps/s390/multiarch/wcpncpy.c
+++ b/sysdeps/s390/multiarch/wcpncpy.c
@@ -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
diff --git a/sysdeps/s390/multiarch/wcscat-c.c b/sysdeps/s390/multiarch/wcscat-c.c
index ef7c000..3ac6110 100644
--- a/sysdeps/s390/multiarch/wcscat-c.c
+++ b/sysdeps/s390/multiarch/wcscat-c.c
@@ -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
diff --git a/sysdeps/s390/multiarch/wcscat.c b/sysdeps/s390/multiarch/wcscat.c
index 2e7fded..3f1219e 100644
--- a/sysdeps/s390/multiarch/wcscat.c
+++ b/sysdeps/s390/multiarch/wcscat.c
@@ -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
diff --git a/sysdeps/s390/multiarch/wcschrnul-c.c b/sysdeps/s390/multiarch/wcschrnul-c.c
index 095ea12..209a305 100644
--- a/sysdeps/s390/multiarch/wcschrnul-c.c
+++ b/sysdeps/s390/multiarch/wcschrnul-c.c
@@ -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
diff --git a/sysdeps/s390/multiarch/wcschrnul.c b/sysdeps/s390/multiarch/wcschrnul.c
index f01ea9f..c112cfb 100644
--- a/sysdeps/s390/multiarch/wcschrnul.c
+++ b/sysdeps/s390/multiarch/wcschrnul.c
@@ -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
diff --git a/sysdeps/s390/multiarch/wcsncpy-c.c b/sysdeps/s390/multiarch/wcsncpy-c.c
index 32ec8ff..d896220 100644
--- a/sysdeps/s390/multiarch/wcsncpy-c.c
+++ b/sysdeps/s390/multiarch/wcsncpy-c.c
@@ -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
diff --git a/sysdeps/s390/multiarch/wcsncpy.c b/sysdeps/s390/multiarch/wcsncpy.c
index 6e1e8f0..e08a82f 100644
--- a/sysdeps/s390/multiarch/wcsncpy.c
+++ b/sysdeps/s390/multiarch/wcsncpy.c
@@ -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
diff --git a/sysdeps/s390/multiarch/wcsnlen-c.c b/sysdeps/s390/multiarch/wcsnlen-c.c
index e86ca65..c6bc0cc 100644
--- a/sysdeps/s390/multiarch/wcsnlen-c.c
+++ b/sysdeps/s390/multiarch/wcsnlen-c.c
@@ -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
diff --git a/sysdeps/s390/multiarch/wcsnlen.c b/sysdeps/s390/multiarch/wcsnlen.c
index 54486b9..df29343 100644
--- a/sysdeps/s390/multiarch/wcsnlen.c
+++ b/sysdeps/s390/multiarch/wcsnlen.c
@@ -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
diff --git a/sysdeps/x86_64/multiarch/wcsnlen-c.c b/sysdeps/x86_64/multiarch/wcsnlen-c.c
index e1ec7cf..a2d1187 100644
--- a/sysdeps/x86_64/multiarch/wcsnlen-c.c
+++ b/sysdeps/x86_64/multiarch/wcsnlen-c.c
@@ -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"
diff --git a/wcsmbs/wcpncpy.c b/wcsmbs/wcpncpy.c
index 42c17ea..8b49d8b 100644
--- a/wcsmbs/wcpncpy.c
+++ b/wcsmbs/wcpncpy.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
diff --git a/wcsmbs/wcscat.c b/wcsmbs/wcscat.c
index d567b73..1f9187b 100644
--- a/wcsmbs/wcscat.c
+++ b/wcsmbs/wcscat.c
@@ -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
diff --git a/wcsmbs/wcschrnul.c b/wcsmbs/wcschrnul.c
index 67ddb1a..fed10b3 100644
--- a/wcsmbs/wcschrnul.c
+++ b/wcsmbs/wcschrnul.c
@@ -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
diff --git a/wcsmbs/wcsncpy.c b/wcsmbs/wcsncpy.c
index 27bfb0d..45175ee 100644
--- a/wcsmbs/wcsncpy.c
+++ b/wcsmbs/wcsncpy.c
@@ -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
diff --git a/wcsmbs/wcsnlen.c b/wcsmbs/wcsnlen.c
index 21bb6db..cb9aff8 100644
--- a/wcsmbs/wcsnlen.c
+++ b/wcsmbs/wcsnlen.c
@@ -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