diff options
author | Florian Weimer <fweimer@redhat.com> | 2019-07-02 15:12:20 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2019-07-02 16:51:13 +0200 |
commit | 41d6f74e6cb6a92ab428c11ee1e408b2a16aa1b0 (patch) | |
tree | ece03ae53e8fd589f2c493cb753c132545a49196 /nptl | |
parent | 27cec9aed97447dff887a88f4241604fffd8c525 (diff) | |
download | glibc-41d6f74e6cb6a92ab428c11ee1e408b2a16aa1b0.tar.gz |
nptl: Remove vfork IFUNC-based forwarder from libpthread [BZ #20188]
With commit f0b2132b35248c1f4a80f62a2c38cddcc802aa8c ("ld.so:
Support moving versioned symbols between sonames [BZ #24741]"), the
dynamic linker will find the definition of vfork in libc and binds
a vfork reference to that symbol, even if the soname in the version
reference says that the symbol should be located in libpthread.
As a result, the forwarder (whether it's IFUNC-based or a duplicate
of the libc implementation) is no longer necessary.
On older architectures, a placeholder symbol is required, to make sure
that the GLIBC_2.1.2 symbol version does not go away, or is turned in
to a weak symbol definition by the link editor. (The symbol version
needs to preserved so that the symbol coverage check in
elf/dl-version.c does not fail for old binaries.)
mips32 is an outlier: It defined __vfork@@GLIBC_2.2, but the
baseline is GLIBC_2.0. Since there are other @@GLIBC_2.2 symbols,
the placeholder symbol is not needed there.
Diffstat (limited to 'nptl')
-rw-r--r-- | nptl/Makefile | 5 | ||||
-rw-r--r-- | nptl/Versions | 5 | ||||
-rw-r--r-- | nptl/libpthread-compat.c | 37 | ||||
-rw-r--r-- | nptl/pt-vfork.c | 65 |
4 files changed, 42 insertions, 70 deletions
diff --git a/nptl/Makefile b/nptl/Makefile index de312b3477..d23a235581 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -120,7 +120,7 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \ cancellation \ lowlevellock \ lll_timedlock_wait \ - pt-fork pt-vfork pt-fcntl \ + pt-fork pt-fcntl \ $(pthread-compat-wrappers) \ pt-raise pt-system \ flockfile ftrylockfile funlockfile \ @@ -144,7 +144,8 @@ libpthread-routines = nptl-init nptlfreeres vars events version pt-interp \ mtx_destroy mtx_init mtx_lock mtx_timedlock \ mtx_trylock mtx_unlock call_once cnd_broadcast \ cnd_destroy cnd_init cnd_signal cnd_timedwait cnd_wait \ - tss_create tss_delete tss_get tss_set pthread_mutex_conf + tss_create tss_delete tss_get tss_set pthread_mutex_conf \ + libpthread-compat # pthread_setuid pthread_seteuid pthread_setreuid \ # pthread_setresuid \ # pthread_setgid pthread_setegid pthread_setregid \ diff --git a/nptl/Versions b/nptl/Versions index e7f691da7a..6007fd03e7 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -36,7 +36,6 @@ libc { __libc_alloca_cutoff; # Internal libc interface to libpthread __libc_dl_error_tsd; - __libc_vfork; __libc_pthread_init; __libc_current_sigrtmin_private; __libc_current_sigrtmax_private; __libc_allocate_rtsig_private; @@ -98,7 +97,7 @@ libpthread { sem_destroy; sem_getvalue; sem_init; sem_post; sem_trywait; sem_wait; # Special fork handling. - fork; __fork; vfork; + fork; __fork; # Cancellation points. close; __close; fcntl; __fcntl; read; __read; write; __write; accept; @@ -152,7 +151,7 @@ libpthread { } GLIBC_2.1.2 { - __vfork; + __libpthread_version_placeholder; } GLIBC_2.2 { diff --git a/nptl/libpthread-compat.c b/nptl/libpthread-compat.c new file mode 100644 index 0000000000..ea29e9f47b --- /dev/null +++ b/nptl/libpthread-compat.c @@ -0,0 +1,37 @@ +/* Placeholder definitions to pull in removed symbol versions. + Copyright (C) 2019 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 <shlib-compat.h> + +/* This is an unused compatibility symbol definition, to prevent ld + from creating a weak version definition for GLIBC_2.1.2. (__vfork + used to be defined at that version, but it is now provided by libc, + and there are no versions left in libpthread for that symbol + version.) If the ABI baseline for glibc is the GLIBC_2.2 symbol + version or later, the placeholder symbol is not needed because + there are plenty of other symbols which populate those later + versions. */ +#if (SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_2)) +void +attribute_compat_text_section +__libpthread_version_placeholder (void) +{ +} +compat_symbol (libpthread, __libpthread_version_placeholder, + __libpthread_version_placeholder, GLIBC_2_1_2); +#endif diff --git a/nptl/pt-vfork.c b/nptl/pt-vfork.c deleted file mode 100644 index 3676977669..0000000000 --- a/nptl/pt-vfork.c +++ /dev/null @@ -1,65 +0,0 @@ -/* vfork ABI-compatibility entry points for libpthread. - Copyright (C) 2014-2019 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 <unistd.h> -#include <shlib-compat.h> - -/* libpthread used to have its own vfork implementation that differed - from libc's only in having a pointless micro-optimization. There - is no longer any use to having a separate copy 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 __vfork and - vfork symbols in libpthread.so; so we define them using IFUNC to - redirect to the libc function. */ - -/* Note! If the architecture doesn't support IFUNC, then we need an - alternate target-specific mechanism to implement this. So we just - assume IFUNC here and require that the target override this file - if necessary. - - If the architecture can assume all supported versions of gcc will - produce a tail-call to __libc_vfork, consider including the version - in sysdeps/unix/sysv/linux/aarch64/pt-vfork.c. */ - -#if !HAVE_IFUNC -# error "must write pt-vfork for this machine or get IFUNC support" -#endif - -#if (SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) \ - || SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20)) - -extern __typeof (vfork) __libc_vfork; /* Defined in libc. */ - -# undef INIT_ARCH -# define INIT_ARCH() -# define DEFINE_VFORK(name) libc_ifunc (name, &__libc_vfork) - -#endif - -#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_20) -extern __typeof(vfork) vfork_ifunc; -DEFINE_VFORK (vfork_ifunc) -compat_symbol (libpthread, vfork_ifunc, vfork, GLIBC_2_0); -#endif - -#if SHLIB_COMPAT (libpthread, GLIBC_2_1_2, GLIBC_2_20) -extern __typeof(vfork) __vfork_ifunc; -DEFINE_VFORK (__vfork_ifunc) -compat_symbol (libpthread, __vfork_ifunc, __vfork, GLIBC_2_1_2); -#endif |