diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | nptl/pt-system.c | 48 |
2 files changed, 44 insertions, 8 deletions
diff --git a/ChangeLog b/ChangeLog index 31efde9d7d..94a3907a27 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,9 @@ 2015-02-06 Roland McGrath <roland@hack.frob.com> + * nptl/pt-system.c: Rewritten. Put everything under + [SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22)]. + Use IFUNC to redirect when possible. + * nptl/pt-longjmp.c: Rewritten. Put everything under [SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22)]. Use IFUNC to redirect when possible. diff --git a/nptl/pt-system.c b/nptl/pt-system.c index 795c5a04aa..389581f427 100644 --- a/nptl/pt-system.c +++ b/nptl/pt-system.c @@ -1,4 +1,5 @@ -/* Copyright (C) 2002-2015 Free Software Foundation, Inc. +/* ABI compatibility for 'system' symbol in libpthread ABI. + Copyright (C) 2002-2015 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. @@ -16,17 +17,48 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <errno.h> #include <stdlib.h> -#include <sysdep.h> -#include "pthreadP.h" +#include <shlib-compat.h> +/* libpthread once had its own 'system', though there was no apparent + reason for it. There is no use in having a separate symbol in + libpthread, but the historical ABI requires it. For static linking, + there is no need to provide anything here--the libc version will be + linked in. For shared library ABI compatibility, there must be a + 'system' symbol in libpthread.so; so we define it using IFUNC to + redirect to the libc function. */ -int -system (const char *line) +#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_22) + +# if HAVE_IFUNC + +static __typeof (system) * +__attribute__ ((used)) +system_resolve (void) +{ + return &__libc_system; +} + +asm (".globl system_ifunc\n" + ".type system_ifunc, %gnu_indirect_function"); + +# ifdef HAVE_ASM_SET_DIRECTIVE +asm (".set system_ifunc, system_resolve"); +# else +asm ("system_ifunc = system_resolve"); +# endif + +# else /* !HAVE_IFUNC */ + +static int __attribute__ ((used)) +system_compat (const char *line) { return __libc_system (line); } +strong_alias (system_compat, system_ifunc) + +# endif /* HAVE_IFUNC */ + +compat_symbol (libpthread, system_ifunc, system, GLIBC_2_0); -/* __libc_system in libc.so handles cancellation. */ -LIBC_CANCEL_HANDLED (); +#endif |