Don't use IFUNC resolver for longjmp or system in libpthread (bug 21041)

Unlike the vfork forwarder and like the fork forwarder as in bug 19861,
there won't be a problem when the compiler does not turn this into a tail
call.

(cherry picked from commit fc5ad7024c)
This commit is contained in:
Andreas Schwab 2017-08-08 16:21:58 +02:00 committed by Aurelien Jarno
parent 6850e9c6ba
commit 88758c4ad3
3 changed files with 24 additions and 37 deletions

View File

@ -1,3 +1,9 @@
2017-08-08 Andreas Schwab <schwab@suse.de>
[BZ #21041]
* nptl/pt-longjmp.c (longjmp, siglongjmp): Don't use IFUNC resolver.
* nptl/pt-system.c (system): Likewise.
2017-11-21 Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com> 2017-11-21 Rajalakshmi Srinivasaraghavan <raji@linux.vnet.ibm.com>
* sysdeps/powerpc/powerpc64/power7/memcpy.S: Replace * sysdeps/powerpc/powerpc64/power7/memcpy.S: Replace

View File

@ -25,36 +25,25 @@
symbol in libpthread, but the historical ABI requires it. For static symbol in libpthread, but the historical ABI requires it. For static
linking, there is no need to provide anything here--the libc version linking, there is no need to provide anything here--the libc version
will be linked in. For shared library ABI compatibility, there must be will be linked in. For shared library ABI compatibility, there must be
longjmp and siglongjmp symbols in libpthread.so; so we define them using longjmp and siglongjmp symbols in libpthread.so.
IFUNC to redirect to the libc function. */
With an IFUNC resolver, it would be possible to avoid the indirection,
but the IFUNC resolver might run before the __libc_longjmp symbol has
been relocated, in which case the IFUNC resolver would not be able to
provide the correct address. */
#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22) #if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22)
# if HAVE_IFUNC
# undef INIT_ARCH
# define INIT_ARCH()
# define DEFINE_LONGJMP(name) libc_ifunc (name, &__libc_longjmp)
extern __typeof(longjmp) longjmp_ifunc;
extern __typeof(siglongjmp) siglongjmp_ifunc;
# else /* !HAVE_IFUNC */
static void __attribute__ ((noreturn, used)) static void __attribute__ ((noreturn, used))
longjmp_compat (jmp_buf env, int val) longjmp_compat (jmp_buf env, int val)
{ {
__libc_longjmp (env, val); __libc_longjmp (env, val);
} }
# define DEFINE_LONGJMP(name) strong_alias (longjmp_compat, name) strong_alias (longjmp_compat, longjmp_alias)
compat_symbol (libpthread, longjmp_alias, longjmp, GLIBC_2_0);
# endif /* HAVE_IFUNC */ strong_alias (longjmp_alias, siglongjmp_alias)
compat_symbol (libpthread, siglongjmp_alias, siglongjmp, GLIBC_2_0);
DEFINE_LONGJMP (longjmp_ifunc)
compat_symbol (libpthread, longjmp_ifunc, longjmp, GLIBC_2_0);
strong_alias (longjmp_ifunc, siglongjmp_ifunc)
compat_symbol (libpthread, siglongjmp_ifunc, siglongjmp, GLIBC_2_0);
#endif #endif

View File

@ -25,29 +25,21 @@
libpthread, but the historical ABI requires it. For static linking, libpthread, but the historical ABI requires it. For static linking,
there is no need to provide anything here--the libc version will be there is no need to provide anything here--the libc version will be
linked in. For shared library ABI compatibility, there must be a linked in. For shared library ABI compatibility, there must be a
'system' symbol in libpthread.so; so we define it using IFUNC to 'system' symbol in libpthread.so.
redirect to the libc function. */
With an IFUNC resolver, it would be possible to avoid the indirection,
but the IFUNC resolver might run before the __libc_system symbol has
been relocated, in which case the IFUNC resolver would not be able to
provide the correct address. */
#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22) #if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22)
# if HAVE_IFUNC
extern __typeof(system) system_ifunc;
# undef INIT_ARCH
# define INIT_ARCH()
libc_ifunc (system_ifunc, &__libc_system)
# else /* !HAVE_IFUNC */
static int __attribute__ ((used)) static int __attribute__ ((used))
system_compat (const char *line) system_compat (const char *line)
{ {
return __libc_system (line); return __libc_system (line);
} }
strong_alias (system_compat, system_ifunc) strong_alias (system_compat, system_alias)
compat_symbol (libpthread, system_alias, system, GLIBC_2_0);
# endif /* HAVE_IFUNC */
compat_symbol (libpthread, system_ifunc, system, GLIBC_2_0);
#endif #endif