diff options
author | H.J. Lu <hjl.tools@gmail.com> | 2012-09-13 06:01:04 -0700 |
---|---|---|
committer | H.J. Lu <hjl.tools@gmail.com> | 2015-09-16 13:00:11 -0700 |
commit | a574db341f6583a625f529493ec423ab436f69c9 (patch) | |
tree | 17469779f5091ba2d4f5ac50156a8c21e60bc492 | |
parent | 5c0fcf5e6abb72f16fc5a260218a3dc4d16a977f (diff) | |
download | glibc-a574db341f6583a625f529493ec423ab436f69c9.zip glibc-a574db341f6583a625f529493ec423ab436f69c9.tar.gz glibc-a574db341f6583a625f529493ec423ab436f69c9.tar.bz2 |
Use STB_SECONDARY on pthread functions in libchjl/pthread/2.21
Use STB_SECONDARY binding on pthread functions in libc so that they will
be preempted by definitions in libpthread at link-time as well as at
run-time.
* csu/libc-tls.c (__pthread_initialize_minimal): Mark it
secondary if HAVE_ASM_SECONDARY_DIRECTIVE is defined.
* misc/error.c (error): Replace pthread_setcancelstate with
__pthread_setcancelstate.
(error_at_line): Likewise.
* posix/wordexp.c (parse_comm): Likewise.
* stdlib/fmtmsg.c (fmtmsg): Likewise.
* nptl/Makefile: Include ../Makeconfig.
(libc-libpthread-routines): New macro.
(libc-libpthread-static-only-routines): Likewise.
(static-only-routines): Add $(libc-libpthread-static-only-routines)
if $(have-secondary) is yes.
(routines): Add $(libc-libpthread-routines) if $(have-secondary)
is yes.
(CFLAGS-libc-pthread_unwind.c): New.
* nptl/Versions [HAVE_ASM_SECONDARY_DIRECTIVE] (libc:GLIBC_2.0):
Add _pthread_cleanup_pop_restore, _pthread_cleanup_push_defer,
__pthread_getspecific, __pthread_setspecific,
__pthread_key_create, pthread_once, __pthread_once,
__pthread_mutex_lock and __pthread_mutex_unlock.
[HAVE_ASM_SECONDARY_DIRECTIVE] (libc:GLIBC_2.2): Add
__pthread_rwlock_init, __pthread_rwlock_destroy,
__pthread_rwlock_rdlock, __pthread_rwlock_wrlock and
__pthread_rwlock_unlock.
[HAVE_ASM_SECONDARY_DIRECTIVE] (libc:GLIBC_PRIVATE): Add
__pthread_unwind and __pthread_setcancelstate.
[HAVE_ASM_SECONDARY_DIRECTIVE] (libpthread:GLIBC_PRIVATE): Add
__pthread_setcancelstate.
* nptl/forward.c [HAVE_ASM_SECONDARY_DIRECTIVE] (FORWARD2): New.
(FORWARD_NORETURN): Likewise.
(pthread_setcancelstate): Renamed to ...
(__pthread_setcancelstate): This. Don't define if
(__pthread_unwind): Don't define if HAVE_ASM_SECONDARY_DIRECTIVE
is defined.
* nptl/libc-cleanup_defer_compat.c: New file.
* nptl/libc-pthread_getspecific.c: Likewise.
* nptl/libc-pthread_key_create.c: Likewise.
* nptl/libc-pthread_mutex_lock.c: Likewise.
* nptl/libc-pthread_mutex_unlock.c: Likewise.
* nptl/libc-pthread_once.c: Likewise.
* nptl/libc-pthread_rwlock_destroy.c: Likewise.
* nptl/libc-pthread_rwlock_init.c: Likewise.
* nptl/libc-pthread_rwlock_rdlock.c: Likewise.
* nptl/libc-pthread_rwlock_unlock.c: Likewise.
* nptl/libc-pthread_rwlock_wrlock.c: Likewise.
* nptl/libc-pthread_setcancelstate.c: Likewise.
* nptl/libc-pthread_setspecific.c: Likewise.
* nptl/libc-pthread_unwind.c: Likewise.
* nptl/nptl-init.c (pthread_functions): Don't include secondary
pthread functions in libc if HAVE_ASM_SECONDARY_DIRECTIVE is
defined. Replace ptr_pthread_setcancelstate with
ptr___pthread_setcancelstate.
* sysdeps/nptl/pthread-functions.h (pthread_functions): Likewise.
* nptl/pthreadP.h (__pthread_unwind): Don't mark it weak if
HAVE_ASM_SECONDARY_DIRECTIVE is defined.
(__pthread_cond_broadcast_2_0): Declare only if not in libc.
(__pthread_cond_destroy_2_0): Likewise.
(__pthread_cond_init_2_0): Likewise.
(__pthread_cond_signal_2_0): Likewise.
(__pthread_cond_timedwait_2_0): Likewise.
(__pthread_cond_wait_2_0): Likewise.
* scripts/abilist.awk: Support secondary symbols.
* sysdeps/generic/localplt.data: Allow pthread functions.
* sysdeps/unix/sysv/linux/i386/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/i386/localplt.data: Likewise.
* sysdeps/unix/sysv/linux/x86_64/64/libc.abilist: Likewise.
* sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist: Likewise.
* sysdeps/nptl/bits/libc-lockP.h (PTFAVAIL): Defined as 1 if
HAVE_ASM_SECONDARY_DIRECTIVE is defined.
(__libc_maybe_call): Always call FUNC if
HAVE_ASM_SECONDARY_DIRECTIVE is defined.
(__libc_ptf_call): Likewise.
(__libc_ptf_call_always): Likewise.
(__pthread_mutex_init): Don't mark it weak if
HAVE_ASM_SECONDARY_DIRECTIVE is defined.
(__pthread_mutex_destroy): Likewise.
(__pthread_mutex_lock): Likewise.
(__pthread_mutex_trylock): Likewise.
(__pthread_mutex_unlock): Likewise.
(__pthread_mutexattr_init): Likewise.
(__pthread_mutexattr_destroy): Likewise.
(__pthread_mutexattr_settype): Likewise.
(__pthread_rwlock_destroy): Likewise.
(__pthread_rwlock_rdlock): Likewise.
(__pthread_rwlock_tryrdlock): Likewise.
(__pthread_rwlock_wrlock): Likewise.
(__pthread_rwlock_trywrlock): Likewise.
(__pthread_rwlock_unlock): Likewise.
(__pthread_key_create): Likewise.
(__pthread_setspecific): Likewise.
(__pthread_getspecific): Likewise.
(__pthread_once): Likewise.
(__pthread_initialize): Likewise.
(__pthread_atfork): Likewise.
(_pthread_cleanup_push_defer): Likewise.
(_pthread_cleanup_pop_restore): Likewise.
(__pthread_setcancelstate): New prototype.
(pthread_setcancelstate): Renamed to ...
(__pthread_setcancelstate): This. Don't mark it weak if
HAVE_ASM_SECONDARY_DIRECTIVE is defined.
* sysdeps/unix/sysv/linux/x86_64/cancellation.S (__pthread_unwind):
Likewise.
* sysdeps/unix/sysv/linux/fatal-prepare.h (FATAL_PREPARE): Always
call __pthread_setcancelstate if HAVE_ASM_SECONDARY_DIRECTIVE is
defined. Replace pthread_setcancelstate with
__pthread_setcancelstate.
* sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S: Make
__lll_lock_wait_private and __lll_unlock_wake_private weak in
libc.a.
* sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S: Likewise.
35 files changed, 691 insertions, 66 deletions
diff --git a/csu/libc-tls.c b/csu/libc-tls.c index 64d1779..3715ded 100644 --- a/csu/libc-tls.c +++ b/csu/libc-tls.c @@ -232,6 +232,11 @@ _dl_tls_setup (void) } +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +/* Make sure that it is used only when libpthread.a is not used */ +asm (".secondary __pthread_initialize_minimal"); +#endif + /* This is the minimal initialization function used when libpthread is not used. */ void diff --git a/misc/error.c b/misc/error.c index aaa120d..9d479d1 100644 --- a/misc/error.c +++ b/misc/error.c @@ -298,8 +298,8 @@ error (int status, int errnum, const char *message, ...) /* We do not want this call to be cut short by a thread cancellation. Therefore disable cancellation for now. */ int state = PTHREAD_CANCEL_ENABLE; - __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), - 0); + __libc_ptf_call (__pthread_setcancelstate, + (PTHREAD_CANCEL_DISABLE, &state), 0); #endif flush_stdout (); @@ -323,7 +323,7 @@ error (int status, int errnum, const char *message, ...) #ifdef _LIBC _IO_funlockfile (stderr); # ifdef __libc_ptf_call - __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); + __libc_ptf_call (__pthread_setcancelstate, (state, NULL), 0); # endif #endif } @@ -360,8 +360,8 @@ error_at_line (int status, int errnum, const char *file_name, /* We do not want this call to be cut short by a thread cancellation. Therefore disable cancellation for now. */ int state = PTHREAD_CANCEL_ENABLE; - __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), - 0); + __libc_ptf_call (__pthread_setcancelstate, + (PTHREAD_CANCEL_DISABLE, &state), 0); #endif flush_stdout (); @@ -393,7 +393,7 @@ error_at_line (int status, int errnum, const char *file_name, #ifdef _LIBC _IO_funlockfile (stderr); # ifdef __libc_ptf_call - __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); + __libc_ptf_call (__pthread_setcancelstate, (state, NULL), 0); # endif #endif } diff --git a/nptl/Makefile b/nptl/Makefile index b5345ce..ad5845d 100644 --- a/nptl/Makefile +++ b/nptl/Makefile @@ -28,9 +28,31 @@ extra-libs := libpthread extra-libs-others := $(extra-libs) install-lib-ldscripts := libpthread.so +include ../Makeconfig + routines = alloca_cutoff forward libc-lowlevellock libc-cancellation \ libc-cleanup libc_pthread_init libc_multiple_threads \ register-atfork unregister-atfork +ifeq (yes,$(have-secondary)) +libc-libpthread-routines = libc-cleanup_defer_compat \ + libc-pthread_getspecific \ + libc-pthread_key_create \ + libc-pthread_mutex_lock \ + libc-pthread_mutex_unlock \ + libc-pthread_once \ + libc-pthread_rwlock_rdlock \ + libc-pthread_rwlock_unlock \ + libc-pthread_rwlock_wrlock \ + libc-pthread_setcancelstate \ + libc-pthread_setspecific \ + libc-pthread_unwind + +libc-libpthread-static-only-routines = libc-pthread_rwlock_destroy \ + libc-pthread_rwlock_init +static-only-routines += $(libc-libpthread-static-only-routines) +libc-libpthread-routines += $(libc-libpthread-static-only-routines) +routines += $(libc-libpthread-routines) +endif shared-only-routines = forward libpthread-routines = nptl-init vars events version \ @@ -167,7 +189,13 @@ CFLAGS-pthread_exit.c = -fexceptions # Among others, __pthread_unwind is forwarded. This function must handle # exceptions. +ifeq (yes,$(have-secondary)) +# __pthread_unwind can't call abort and GCC doesn't know kill won't +# return. +CFLAGS-libc-pthread_unwind.c += -fexceptions -Wno-error +else CFLAGS-forward.c = -fexceptions +endif # The following are cancellation points. Some of the functions can # block and therefore temporarily enable asynchronous cancellation. diff --git a/nptl/Versions b/nptl/Versions index 4e134fa..d80c6bd 100644 --- a/nptl/Versions +++ b/nptl/Versions @@ -16,10 +16,26 @@ libc { pthread_mutex_lock; pthread_mutex_unlock; pthread_self; pthread_setcancelstate; pthread_setcanceltype; +#if HAVE_ASM_SECONDARY_DIRECTIVE + # Provide additional secondary pthread functions. + _pthread_cleanup_pop_restore; _pthread_cleanup_push_defer; + __pthread_getspecific; __pthread_setspecific; + __pthread_key_create; + pthread_once; + __pthread_once; + __pthread_mutex_lock; __pthread_mutex_unlock; +#endif } GLIBC_2.1 { pthread_attr_init; } +#if HAVE_ASM_SECONDARY_DIRECTIVE + GLIBC_2.2 { + # Provide additional secondary pthread functions. + __pthread_rwlock_rdlock; __pthread_rwlock_wrlock; + __pthread_rwlock_unlock; + } +#endif GLIBC_2.3.2 { __register_atfork; @@ -36,6 +52,11 @@ libc { __libc_pthread_init; __libc_current_sigrtmin_private; __libc_current_sigrtmax_private; __libc_allocate_rtsig_private; +#if HAVE_ASM_SECONDARY_DIRECTIVE + # Provide additional secondary pthread function. + __pthread_unwind; + __pthread_setcancelstate; +#endif } } @@ -270,6 +291,9 @@ libpthread { __pthread_initialize_minimal; __pthread_clock_gettime; __pthread_clock_settime; __pthread_unwind; __pthread_get_minstack; +#if HAVE_ASM_SECONDARY_DIRECTIVE + __pthread_setcancelstate; +#endif __shm_directory; } } diff --git a/nptl/forward.c b/nptl/forward.c index db74f8d..8bb8c18 100644 --- a/nptl/forward.c +++ b/nptl/forward.c @@ -31,7 +31,26 @@ struct pthread_functions __libc_pthread_functions attribute_hidden; int __libc_pthread_functions_init attribute_hidden; -#define FORWARD2(name, rettype, decl, params, defaction) \ +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +/* Make sure that it is used only when libpthread is not used. */ +# define FORWARD2(name, rettype, decl, params, defaction) \ +asm (".secondary "#name); \ +rettype \ +name decl \ +{ \ + defaction; \ +} + +/* Same as FORWARD2, only without return. */ +# define FORWARD_NORETURN(name, rettype, decl, params, defaction) \ +asm (".secondary "#name); \ +rettype \ +name decl \ +{ \ + defaction; \ +} +#else +# define FORWARD2(name, rettype, decl, params, defaction) \ rettype \ name decl \ { \ @@ -42,7 +61,7 @@ name decl \ } /* Same as FORWARD2, only without return. */ -#define FORWARD_NORETURN(name, rettype, decl, params, defaction) \ +# define FORWARD_NORETURN(name, rettype, decl, params, defaction) \ rettype \ name decl \ { \ @@ -51,6 +70,7 @@ name decl \ \ PTHFCT_CALL (ptr_##name, params); \ } +#endif #define FORWARD(name, decl, params, defretval) \ FORWARD2 (name, int, decl, params, return defretval) @@ -197,13 +217,15 @@ FORWARD (pthread_mutex_unlock, (pthread_mutex_t *mutex), (mutex), 0) FORWARD2 (pthread_self, pthread_t, (void), (), return 0) -FORWARD (pthread_setcancelstate, (int state, int *oldstate), (state, oldstate), - 0) +FORWARD (__pthread_setcancelstate, (int state, int *oldstate), + (state, oldstate), 0) FORWARD (pthread_setcanceltype, (int type, int *oldtype), (type, oldtype), 0) +#ifndef HAVE_ASM_SECONDARY_DIRECTIVE FORWARD_NORETURN (__pthread_unwind, void attribute_hidden __attribute ((noreturn)) __cleanup_fct_attribute attribute_compat_text_section, (__pthread_unwind_buf_t *buf), (buf), __safe_fatal ()) +#endif diff --git a/nptl/libc-cleanup_defer_compat.c b/nptl/libc-cleanup_defer_compat.c new file mode 100644 index 0000000..ea1cc6e --- /dev/null +++ b/nptl/libc-cleanup_defer_compat.c @@ -0,0 +1,40 @@ +/* Copyright (C) 2015 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/>. */ + +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +# include "pthreadP.h" + +/* Make sure that it is used only when libpthread is not used */ +asm (".secondary _pthread_cleanup_push_defer"); + +void +_pthread_cleanup_push_defer (struct _pthread_cleanup_buffer *buffer, + void (*routine) (void *), void *arg) +{ +} + +/* Make sure that it is used only when libpthread is not used */ +asm (".secondary _pthread_cleanup_pop_restore"); + +void +_pthread_cleanup_pop_restore (struct _pthread_cleanup_buffer *buffer, + int execute) +{ + if (execute) + buffer->__routine (buffer->__arg); +} +#endif diff --git a/nptl/libc-pthread_getspecific.c b/nptl/libc-pthread_getspecific.c new file mode 100644 index 0000000..31a0258 --- /dev/null +++ b/nptl/libc-pthread_getspecific.c @@ -0,0 +1,31 @@ +/* Copyright (C) 2015 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/>. */ + +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +#include <stdlib.h> +#include "pthreadP.h" + +/* Make sure that it is used only when libpthread is not used. */ +asm (".secondary __pthread_getspecific"); + +void * +__pthread_getspecific (pthread_key_t key) +{ + /* Not valid. */ + return NULL; +} +#endif diff --git a/nptl/libc-pthread_key_create.c b/nptl/libc-pthread_key_create.c new file mode 100644 index 0000000..e6f631b --- /dev/null +++ b/nptl/libc-pthread_key_create.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2015 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/>. */ + +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +# include <errno.h> +# include "pthreadP.h" + +/* Make sure that it is used only when libpthread is not used. */ +asm (".secondary __pthread_key_create"); + +int +__pthread_key_create (pthread_key_t *key, void (*destr) (void *)) +{ + return EINVAL; +} +#endif diff --git a/nptl/libc-pthread_mutex_lock.c b/nptl/libc-pthread_mutex_lock.c new file mode 100644 index 0000000..15b97b1 --- /dev/null +++ b/nptl/libc-pthread_mutex_lock.c @@ -0,0 +1,32 @@ +/* Copyright (C) 2015 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/>. */ + +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +# include "pthreadP.h" + +/* Make sure that it is used only when libpthread is not used. */ +asm (".secondary __pthread_mutex_lock"); +asm (".secondary pthread_mutex_lock"); + +int +__pthread_mutex_lock (pthread_mutex_t *mutex) +{ + return 0; +} + +strong_alias (__pthread_mutex_lock, pthread_mutex_lock) +#endif diff --git a/nptl/libc-pthread_mutex_unlock.c b/nptl/libc-pthread_mutex_unlock.c new file mode 100644 index 0000000..f4a9949 --- /dev/null +++ b/nptl/libc-pthread_mutex_unlock.c @@ -0,0 +1,32 @@ +/* Copyright (C) 2015 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/>. */ + +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +# include "pthreadP.h" + +/* Make sure that it is used only when libpthread is not used. */ +asm (".secondary __pthread_mutex_unlock"); +asm (".secondary pthread_mutex_unlock"); + +int +__pthread_mutex_unlock (pthread_mutex_t *mutex) +{ + return 0; +} + +strong_alias (__pthread_mutex_unlock, pthread_mutex_unlock) +#endif diff --git a/nptl/libc-pthread_once.c b/nptl/libc-pthread_once.c new file mode 100644 index 0000000..ed26e06 --- /dev/null +++ b/nptl/libc-pthread_once.c @@ -0,0 +1,37 @@ +/* Copyright (C) 2015 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/>. */ + +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +#include "pthreadP.h" + +/* Make sure that it is used only when libpthread is not used. */ +asm (".secondary __pthread_once"); +asm (".secondary pthread_once"); + +int +__pthread_once (pthread_once_t *once_control, + void (*init_routine) (void)) +{ + if (*once_control == PTHREAD_ONCE_INIT) + { + init_routine (); + *once_control |= 2; + } + return 0; +} +strong_alias (__pthread_once, pthread_once) +#endif diff --git a/nptl/libc-pthread_rwlock_destroy.c b/nptl/libc-pthread_rwlock_destroy.c new file mode 100644 index 0000000..9df8b84 --- /dev/null +++ b/nptl/libc-pthread_rwlock_destroy.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2015 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/>. */ + +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +# include "pthreadP.h" + +/* Make sure that it is used only when libpthread is not used. */ +asm (".secondary __pthread_rwlock_destroy"); + +int +__pthread_rwlock_destroy (pthread_rwlock_t *rwlock) +{ + return 0; +} +#endif diff --git a/nptl/libc-pthread_rwlock_init.c b/nptl/libc-pthread_rwlock_init.c new file mode 100644 index 0000000..c245724 --- /dev/null +++ b/nptl/libc-pthread_rwlock_init.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2015 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/>. */ + +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +# include "pthreadP.h" + +/* Make sure that it is used only when libpthread is not used. */ +asm (".secondary __pthread_rwlock_init"); + +int +__pthread_rwlock_init (pthread_rwlock_t *rwlock, + const pthread_rwlockattr_t *attr) +{ + return 0; +} +#endif diff --git a/nptl/libc-pthread_rwlock_rdlock.c b/nptl/libc-pthread_rwlock_rdlock.c new file mode 100644 index 0000000..b484488 --- /dev/null +++ b/nptl/libc-pthread_rwlock_rdlock.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2015 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/>. */ + +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +# include "pthreadP.h" + +/* Make sure that it is used only when libpthread is not used. */ +asm (".secondary __pthread_rwlock_rdlock"); + +int +__pthread_rwlock_rdlock (pthread_rwlock_t *rwlock) +{ + return 0; +} +#endif diff --git a/nptl/libc-pthread_rwlock_unlock.c b/nptl/libc-pthread_rwlock_unlock.c new file mode 100644 index 0000000..b8c3e90 --- /dev/null +++ b/nptl/libc-pthread_rwlock_unlock.c @@ -0,0 +1,29 @@ +/* Copyright (C) 2015 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/>. */ + +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +# include "pthreadP.h" + +/* Make sure that it is used only when libpthread is not used. */ +asm (".secondary __pthread_rwlock_unlock"); + +int +__pthread_rwlock_unlock (pthread_rwlock_t *rwlock) +{ + return 0; +} +#endif diff --git a/nptl/libc-pthread_rwlock_wrlock.c b/nptl/libc-pthread_rwlock_wrlock.c new file mode 100644 index 0000000..25092ee --- /dev/null +++ b/nptl/libc-pthread_rwlock_wrlock.c @@ -0,0 +1,30 @@ +/* Copyright (C) 2003-2012 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Martin Schwidefsky <schwidefsky@de.ibm.com>, 2003. + + 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/>. */ + +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +# include "pthreadP.h" + +/* Make sure that it is used only when libpthread is not used. */ +asm (".secondary __pthread_rwlock_wrlock"); + +int +__pthread_rwlock_wrlock (pthread_rwlock_t *rwlock) +{ + return 0; +} +#endif diff --git a/nptl/libc-pthread_setcancelstate.c b/nptl/libc-pthread_setcancelstate.c new file mode 100644 index 0000000..c8872a9 --- /dev/null +++ b/nptl/libc-pthread_setcancelstate.c @@ -0,0 +1,34 @@ +/* Copyright (C) 2015 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/>. */ + +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +# include <errno.h> +# include "pthreadP.h" + +/* Make sure that it is used only when libpthread is not used. */ +asm (".secondary __pthread_setcancelstate"); + +int +__pthread_setcancelstate (int state, int *oldstate) +{ + return 0; +} +# ifdef SHARED +asm (".secondary pthread_setcancelstate"); +strong_alias (__pthread_setcancelstate, pthread_setcancelstate) +# endif +#endif diff --git a/nptl/libc-pthread_setspecific.c b/nptl/libc-pthread_setspecific.c new file mode 100644 index 0000000..a904f07 --- /dev/null +++ b/nptl/libc-pthread_setspecific.c @@ -0,0 +1,31 @@ +/* Copyright (C) 2015 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/>. */ + +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +#include <errno.h> +#include "pthreadP.h" + +/* Make sure that it is used only when libpthread is not used. */ +asm (".secondary __pthread_setspecific"); + +int +__pthread_setspecific (pthread_key_t key, const void *value) +{ + /* Not valid. */ + return EINVAL; +} +#endif diff --git a/nptl/libc-pthread_unwind.c b/nptl/libc-pthread_unwind.c new file mode 100644 index 0000000..9932ba7 --- /dev/null +++ b/nptl/libc-pthread_unwind.c @@ -0,0 +1,34 @@ +/* Copyright (C) 2015 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/>. */ + +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +# include <sysdep.h> +# include <safe-fatal.h> + +/* Make sure that it is used only when libpthread is not used */ +asm (".secondary __pthread_unwind"); + +void +__attribute ((noreturn)) +__cleanup_fct_attribute +attribute_compat_text_section +__pthread_unwind (__pthread_unwind_buf_t *buf) +{ + /* We cannot call abort() here. */ + __safe_fatal (); +} +#endif diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c index 1ad41c5..6397f9e 100644 --- a/nptl/nptl-init.c +++ b/nptl/nptl-init.c @@ -85,10 +85,11 @@ static void nptl_freeres (void); static const struct pthread_functions pthread_functions = { +# ifndef HAVE_ASM_SECONDARY_DIRECTIVE .ptr_pthread_attr_destroy = __pthread_attr_destroy, -# if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1) +# if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1) .ptr___pthread_attr_init_2_0 = __pthread_attr_init_2_0, -# endif +# endif .ptr___pthread_attr_init_2_1 = __pthread_attr_init_2_1, .ptr_pthread_attr_getdetachstate = __pthread_attr_getdetachstate, .ptr_pthread_attr_setdetachstate = __pthread_attr_setdetachstate, @@ -125,9 +126,8 @@ static const struct pthread_functions pthread_functions = .ptr_pthread_mutex_lock = __pthread_mutex_lock, .ptr_pthread_mutex_unlock = __pthread_mutex_unlock, .ptr_pthread_self = __pthread_self, - .ptr_pthread_setcancelstate = __pthread_setcancelstate, + .ptr___pthread_setcancelstate = __pthread_setcancelstate, .ptr_pthread_setcanceltype = __pthread_setcanceltype, - .ptr___pthread_cleanup_upto = __pthread_cleanup_upto, .ptr___pthread_once = __pthread_once, .ptr___pthread_rwlock_rdlock = __pthread_rwlock_rdlock, .ptr___pthread_rwlock_wrlock = __pthread_rwlock_wrlock, @@ -137,8 +137,10 @@ static const struct pthread_functions pthread_functions = .ptr___pthread_setspecific = __pthread_setspecific, .ptr__pthread_cleanup_push_defer = __pthread_cleanup_push_defer, .ptr__pthread_cleanup_pop_restore = __pthread_cleanup_pop_restore, - .ptr_nthreads = &__nptl_nthreads, .ptr___pthread_unwind = &__pthread_unwind, +# endif + .ptr___pthread_cleanup_upto = __pthread_cleanup_upto, + .ptr_nthreads = &__nptl_nthreads, .ptr__nptl_deallocate_tsd = __nptl_deallocate_tsd, # ifdef SIGSETXID .ptr__nptl_setxid = __nptl_setxid, diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h index 84a7105..c09f9d2 100644 --- a/nptl/pthreadP.h +++ b/nptl/pthreadP.h @@ -244,7 +244,8 @@ extern int __pthread_debug attribute_hidden; extern void __pthread_unwind (__pthread_unwind_buf_t *__buf) __cleanup_fct_attribute __attribute ((__noreturn__)) -#if !defined SHARED && !IS_IN (libpthread) +#if !defined SHARED && !IS_IN (libpthread) \ + && !defined HAVE_ASM_SECONDARY_DIRECTIVE weak_function #endif ; @@ -506,6 +507,7 @@ hidden_proto (__pthread_setspecific) hidden_proto (__pthread_once) #endif +#if !IS_IN (libc) extern int __pthread_cond_broadcast_2_0 (pthread_cond_2_0_t *cond); extern int __pthread_cond_destroy_2_0 (pthread_cond_2_0_t *cond); extern int __pthread_cond_init_2_0 (pthread_cond_2_0_t *cond, @@ -516,6 +518,7 @@ extern int __pthread_cond_timedwait_2_0 (pthread_cond_2_0_t *cond, const struct timespec *abstime); extern int __pthread_cond_wait_2_0 (pthread_cond_2_0_t *cond, pthread_mutex_t *mutex); +#endif extern int __pthread_getaffinity_np (pthread_t th, size_t cpusetsize, cpu_set_t *cpuset); diff --git a/posix/wordexp.c b/posix/wordexp.c index e3d8d6b..3a37713 100644 --- a/posix/wordexp.c +++ b/posix/wordexp.c @@ -1182,7 +1182,7 @@ parse_comm (char **word, size_t *word_length, size_t *max_length, // XXX Ideally we do want the thread being cancelable. // XXX If demand is there we'll change it. int state = PTHREAD_CANCEL_ENABLE; - __libc_ptf_call (pthread_setcancelstate, + __libc_ptf_call (__pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), 0); #endif @@ -1190,7 +1190,7 @@ parse_comm (char **word, size_t *word_length, size_t *max_length, flags, pwordexp, ifs, ifs_white); #ifdef __libc_ptf_call - __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); + __libc_ptf_call (__pthread_setcancelstate, (state, NULL), 0); #endif free (comm); diff --git a/scripts/abilist.awk b/scripts/abilist.awk index 52b5b32..cbc2686 100644 --- a/scripts/abilist.awk +++ b/scripts/abilist.awk @@ -38,7 +38,7 @@ $4 == "*UND*" { next } $2 == "l" { next } # If the target uses ST_OTHER, it will be output before the symbol name. -$2 == "g" || $2 == "w" && (NF == 7 || NF == 8) { +$2 == "g" || $2 == "w" || $2 == "s" && (NF == 7 || NF == 8) { weak = $2; type = $3; size = $5; diff --git a/stdlib/fmtmsg.c b/stdlib/fmtmsg.c index 6046744..c64eea6 100644 --- a/stdlib/fmtmsg.c +++ b/stdlib/fmtmsg.c @@ -127,8 +127,8 @@ fmtmsg (long int classification, const char *label, int severity, /* We do not want this call to be cut short by a thread cancellation. Therefore disable cancellation for now. */ int state = PTHREAD_CANCEL_ENABLE; - __libc_ptf_call (pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, &state), - 0); + __libc_ptf_call (__pthread_setcancelstate, + (PTHREAD_CANCEL_DISABLE, &state), 0); #endif __libc_lock_lock (lock); @@ -199,7 +199,7 @@ fmtmsg (long int classification, const char *label, int severity, __libc_lock_unlock (lock); #ifdef __libc_ptf_call - __libc_ptf_call (pthread_setcancelstate, (state, NULL), 0); + __libc_ptf_call (__pthread_setcancelstate, (state, NULL), 0); #endif return result; diff --git a/sysdeps/generic/localplt.data b/sysdeps/generic/localplt.data index 1a40cf9..5b1463f 100644 --- a/sysdeps/generic/localplt.data +++ b/sysdeps/generic/localplt.data @@ -1,6 +1,18 @@ # See scripts/check-localplt.awk for how this file is processed. # PLT use is required for the malloc family and for matherr because # users can define their own functions and have library internals call them. +# pthread functions may be preempted by libpthread at run-time. +libc.so: __pthread_getspecific +libc.so: __pthread_key_create +libc.so: __pthread_once +libc.so: __pthread_rwlock_rdlock +libc.so: __pthread_rwlock_unlock +libc.so: __pthread_rwlock_wrlock +libc.so: __pthread_setcancelstate +libc.so: __pthread_setspecific +libc.so: __pthread_unwind +libc.so: _pthread_cleanup_pop_restore +libc.so: _pthread_cleanup_push_defer libc.so: calloc libc.so: free libc.so: malloc diff --git a/sysdeps/nptl/bits/libc-lockP.h b/sysdeps/nptl/bits/libc-lockP.h index f55f621..f5753af 100644 --- a/sysdeps/nptl/bits/libc-lockP.h +++ b/sysdeps/nptl/bits/libc-lockP.h @@ -99,39 +99,51 @@ typedef pthread_key_t __libc_key_t; #define __rtld_lock_initialize(NAME) \ (void) ((NAME) = (__rtld_lock_recursive_t) _RTLD_LOCK_RECURSIVE_INITIALIZER) +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +/* All pthread functions are available. */ +# define PTFAVAIL(NAME) 1 + +/* When secondary symbols are used, FUNC is implemented to return ELSE so + that we can always call FUNC. */ +# define __libc_maybe_call(FUNC, ARGS, ELSE) FUNC ARGS +# define __libc_ptf_call(FUNC, ARGS, ELSE) FUNC ARGS +# define __libc_ptf_call_always(FUNC, ARGS) FUNC ARGS +#else /* If we check for a weakly referenced symbol and then perform a normal jump to it te code generated for some platforms in case of PIC is unnecessarily slow. What would happen is that the function is first referenced as data and then it is called indirectly through the PLT. We can make this a direct jump. */ -#ifdef __PIC__ -# define __libc_maybe_call(FUNC, ARGS, ELSE) \ - (__extension__ ({ __typeof (FUNC) *_fn = (FUNC); \ - _fn != NULL ? (*_fn) ARGS : ELSE; })) -#else -# define __libc_maybe_call(FUNC, ARGS, ELSE) \ - (FUNC != NULL ? FUNC ARGS : ELSE) -#endif +# ifdef __PIC__ +# define __libc_maybe_call(FUNC, ARGS, ELSE) \ + (__extension__ ({ __typeof (FUNC) *_fn = (FUNC); \ + _fn != NULL ? (*_fn) ARGS : ELSE; })) +# else +# define __libc_maybe_call(FUNC, ARGS, ELSE) \ + (FUNC != NULL ? FUNC ARGS : ELSE) +# endif /* Call thread functions through the function pointer table. */ -#if defined SHARED && IS_IN (libc) -# define PTFAVAIL(NAME) __libc_pthread_functions_init -# define __libc_ptf_call(FUNC, ARGS, ELSE) \ +# if defined SHARED && IS_IN (libc) \ + && !defined HAVE_ASM_SECONDARY_DIRECTIVE +# define PTFAVAIL(NAME) __libc_pthread_functions_init +# define __libc_ptf_call(FUNC, ARGS, ELSE) \ (__libc_pthread_functions_init ? PTHFCT_CALL (ptr_##FUNC, ARGS) : ELSE) -# define __libc_ptf_call_always(FUNC, ARGS) \ +# define __libc_ptf_call_always(FUNC, ARGS) \ PTHFCT_CALL (ptr_##FUNC, ARGS) -#elif IS_IN (libpthread) -# define PTFAVAIL(NAME) 1 -# define __libc_ptf_call(FUNC, ARGS, ELSE) \ +# elif IS_IN (libpthread) +# define PTFAVAIL(NAME) 1 +# define __libc_ptf_call(FUNC, ARGS, ELSE) \ FUNC ARGS -# define __libc_ptf_call_always(FUNC, ARGS) \ +# define __libc_ptf_call_always(FUNC, ARGS) \ FUNC ARGS -#else -# define PTFAVAIL(NAME) (NAME != NULL) -# define __libc_ptf_call(FUNC, ARGS, ELSE) \ - __libc_maybe_call (FUNC, ARGS, ELSE) -# define __libc_ptf_call_always(FUNC, ARGS) \ +# else +# define PTFAVAIL(NAME) (NAME != NULL) +# define __libc_ptf_call(FUNC, ARGS, ELSE) \ + __libc_maybe_call (FUNC, ARGS, ELSE) +# define __libc_ptf_call_always(FUNC, ARGS) \ FUNC ARGS +# endif #endif @@ -364,6 +376,8 @@ extern int __pthread_rwlock_unlock (pthread_rwlock_t *__rwlock); extern int __pthread_key_create (pthread_key_t *__key, void (*__destr_function) (void *)); +extern int __pthread_setcancelstate (int state, int *oldstate); + extern int __pthread_setspecific (pthread_key_t __key, const void *__pointer); @@ -379,8 +393,9 @@ extern int __pthread_atfork (void (*__prepare) (void), /* Make the pthread functions weak so that we can elide them from - single-threaded processes. */ -#ifndef __NO_WEAK_PTHREAD_ALIASES + single-threaded processes unless secondary symbols are used. */ +#if !defined __NO_WEAK_PTHREAD_ALIASES \ + && !defined HAVE_ASM_SECONDARY_DIRECTIVE # ifdef weak_extern weak_extern (__pthread_mutex_init) weak_extern (__pthread_mutex_destroy) @@ -405,7 +420,7 @@ weak_extern (__pthread_initialize) weak_extern (__pthread_atfork) weak_extern (_pthread_cleanup_push_defer) weak_extern (_pthread_cleanup_pop_restore) -weak_extern (pthread_setcancelstate) +weak_extern (__pthread_setcancelstate) # else # pragma weak __pthread_mutex_init # pragma weak __pthread_mutex_destroy @@ -429,7 +444,7 @@ weak_extern (pthread_setcancelstate) # pragma weak __pthread_atfork # pragma weak _pthread_cleanup_push_defer # pragma weak _pthread_cleanup_pop_restore -# pragma weak pthread_setcancelstate +# pragma weak __pthread_setcancelstate # endif #endif diff --git a/sysdeps/nptl/pthread-functions.h b/sysdeps/nptl/pthread-functions.h index 0784c59..f6238ab 100644 --- a/sysdeps/nptl/pthread-functions.h +++ b/sysdeps/nptl/pthread-functions.h @@ -30,6 +30,7 @@ struct xid_command; the thread functions. */ struct pthread_functions { +#ifndef HAVE_ASM_SECONDARY_DIRECTIVE int (*ptr_pthread_attr_destroy) (pthread_attr_t *); int (*ptr___pthread_attr_init_2_0) (pthread_attr_t *); int (*ptr___pthread_attr_init_2_1) (pthread_attr_t *); @@ -75,9 +76,8 @@ struct pthread_functions int (*ptr_pthread_mutex_lock) (pthread_mutex_t *); int (*ptr_pthread_mutex_unlock) (pthread_mutex_t *); pthread_t (*ptr_pthread_self) (void); - int (*ptr_pthread_setcancelstate) (int, int *); + int (*ptr___pthread_setcancelstate) (int, int *); int (*ptr_pthread_setcanceltype) (int, int *); - void (*ptr___pthread_cleanup_upto) (__jmp_buf, char *); int (*ptr___pthread_once) (pthread_once_t *, void (*) (void)); int (*ptr___pthread_rwlock_rdlock) (pthread_rwlock_t *); int (*ptr___pthread_rwlock_wrlock) (pthread_rwlock_t *); @@ -89,10 +89,12 @@ struct pthread_functions void (*) (void *), void *); void (*ptr__pthread_cleanup_pop_restore) (struct _pthread_cleanup_buffer *, int); -#define HAVE_PTR_NTHREADS - unsigned int *ptr_nthreads; void (*ptr___pthread_unwind) (__pthread_unwind_buf_t *) __attribute ((noreturn)) __cleanup_fct_attribute; +#endif + void (*ptr___pthread_cleanup_upto) (__jmp_buf, char *); +#define HAVE_PTR_NTHREADS + unsigned int *ptr_nthreads; void (*ptr__nptl_deallocate_tsd) (void); int (*ptr__nptl_setxid) (struct xid_command *); void (*ptr_freeres) (void); diff --git a/sysdeps/unix/sysv/linux/fatal-prepare.h b/sysdeps/unix/sysv/linux/fatal-prepare.h index 45d88ce..39cff24 100644 --- a/sysdeps/unix/sysv/linux/fatal-prepare.h +++ b/sysdeps/unix/sysv/linux/fatal-prepare.h @@ -19,19 +19,23 @@ /* We have to completely disable cancellation. assert() must not be a cancellation point but the implementation uses write() etc. */ -#ifdef SHARED -# include <pthread-functions.h> -# define FATAL_PREPARE \ - { \ - if (__libc_pthread_functions_init) \ - PTHFCT_CALL (ptr_pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, \ - NULL)); \ - } +#ifdef HAVE_ASM_SECONDARY_DIRECTIVE +# define FATAL_PREPARE __pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL); #else -# pragma weak pthread_setcancelstate -# define FATAL_PREPARE \ - { \ - if (pthread_setcancelstate != NULL) \ - pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL); \ - } +# ifdef SHARED +# include <pthread-functions.h> +# define FATAL_PREPARE \ + { \ + if (__libc_pthread_functions_init) \ + PTHFCT_CALL (ptr___pthread_setcancelstate, (PTHREAD_CANCEL_DISABLE, \ + NULL)); \ + } +# else +# pragma weak __pthread_setcancelstate +# define FATAL_PREPARE \ + { \ + if (__pthread_setcancelstate != NULL) \ + __pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL); \ + } +# endif #endif diff --git a/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S b/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S index 111e9c8..cf3f206 100644 --- a/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S +++ b/sysdeps/unix/sysv/linux/i386/i486/libc-lowlevellock.S @@ -16,4 +16,10 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#if IS_IN (libc) && !defined SHARED +/* Allow libpthread.a to override the ones in libc.a. */ + weak_extern (__lll_lock_wait_private) + weak_extern (__lll_unlock_wake_private) +#endif + #include "lowlevellock.S" diff --git a/sysdeps/unix/sysv/linux/i386/libc.abilist b/sysdeps/unix/sysv/linux/i386/libc.abilist index 3cb314d..c8a8ebd 100644 --- a/sysdeps/unix/sysv/linux/i386/libc.abilist +++ b/sysdeps/unix/sysv/linux/i386/libc.abilist @@ -189,6 +189,12 @@ GLIBC_2.0 __profile_frequency F __progname D 0x4 __progname_full D 0x4 + __pthread_getspecific F + __pthread_key_create F + __pthread_mutex_lock F + __pthread_mutex_unlock F + __pthread_once F + __pthread_setspecific F __rcmd_errstr D 0x4 __read F __realloc_hook D 0x4 @@ -269,6 +275,8 @@ GLIBC_2.0 _obstack_free F _obstack_memory_used F _obstack_newchunk F + _pthread_cleanup_pop_restore F + _pthread_cleanup_push_defer F _res D 0x200 _rpc_dtablesize F _seterr_reply F @@ -868,6 +876,7 @@ GLIBC_2.0 pthread_mutex_init F pthread_mutex_lock F pthread_mutex_unlock F + pthread_once F pthread_self F pthread_setcancelstate F pthread_setcanceltype F @@ -1882,6 +1891,9 @@ GLIBC_2.2 __lxstat64 F __nl_langinfo_l F __open64 F + __pthread_rwlock_rdlock F + __pthread_rwlock_unlock F + __pthread_rwlock_wrlock F __res_init F __res_nclose F __res_ninit F diff --git a/sysdeps/unix/sysv/linux/i386/localplt.data b/sysdeps/unix/sysv/linux/i386/localplt.data index b25abf8..a3fcb91 100644 --- a/sysdeps/unix/sysv/linux/i386/localplt.data +++ b/sysdeps/unix/sysv/linux/i386/localplt.data @@ -4,6 +4,18 @@ libc.so: free libc.so: malloc libc.so: memalign libc.so: realloc +# pthread functions may be preempted by libpthread at run-time. +libc.so: __pthread_getspecific +libc.so: __pthread_key_create +libc.so: __pthread_once +libc.so: __pthread_rwlock_rdlock +libc.so: __pthread_rwlock_unlock +libc.so: __pthread_rwlock_wrlock +libc.so: __pthread_setcancelstate +libc.so: __pthread_setspecific +libc.so: __pthread_unwind +libc.so: _pthread_cleanup_pop_restore +libc.so: _pthread_cleanup_push_defer libm.so: matherr # The dynamic loader uses __libc_memalign internally to allocate aligned # TLS storage. The other malloc family of functions are expected to allow diff --git a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist index 914b590..56d1fe0 100644 --- a/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/64/libc.abilist @@ -377,6 +377,15 @@ GLIBC_2.2.5 __profile_frequency F __progname D 0x8 __progname_full D 0x8 + __pthread_getspecific F + __pthread_key_create F + __pthread_mutex_lock F + __pthread_mutex_unlock F + __pthread_once F + __pthread_rwlock_rdlock F + __pthread_rwlock_unlock F + __pthread_rwlock_wrlock F + __pthread_setspecific F __pwrite64 F __rawmemchr F __rcmd_errstr D 0x8 @@ -527,6 +536,8 @@ GLIBC_2.2.5 _obstack_free F _obstack_memory_used F _obstack_newchunk F + _pthread_cleanup_pop_restore F + _pthread_cleanup_push_defer F _res D 0x238 _res_hconf D 0x48 _rpc_dtablesize F @@ -1299,6 +1310,7 @@ GLIBC_2.2.5 pthread_mutex_init F pthread_mutex_lock F pthread_mutex_unlock F + pthread_once F pthread_self F pthread_setcancelstate F pthread_setcanceltype F diff --git a/sysdeps/unix/sysv/linux/x86_64/cancellation.S b/sysdeps/unix/sysv/linux/x86_64/cancellation.S index 4c34beb..52a27dc 100644 --- a/sysdeps/unix/sysv/linux/x86_64/cancellation.S +++ b/sysdeps/unix/sysv/linux/x86_64/cancellation.S @@ -26,7 +26,7 @@ # define __pthread_unwind __GI___pthread_unwind # endif #else -# ifndef SHARED +# if !defined SHARED && !defined HAVE_ASM_SECONDARY_DIRECTIVE .weak __pthread_unwind # endif #endif diff --git a/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S b/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S index 111e9c8..cf3f206 100644 --- a/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S +++ b/sysdeps/unix/sysv/linux/x86_64/libc-lowlevellock.S @@ -16,4 +16,10 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ +#if IS_IN (libc) && !defined SHARED +/* Allow libpthread.a to override the ones in libc.a. */ + weak_extern (__lll_lock_wait_private) + weak_extern (__lll_unlock_wake_private) +#endif + #include "lowlevellock.S" diff --git a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist index 0f64c8d..dacadc0 100644 --- a/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist +++ b/sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist @@ -341,6 +341,15 @@ GLIBC_2.16 __profile_frequency F __progname D 0x4 __progname_full D 0x4 + __pthread_getspecific F + __pthread_key_create F + __pthread_mutex_lock F + __pthread_mutex_unlock F + __pthread_once F + __pthread_rwlock_rdlock F + __pthread_rwlock_unlock F + __pthread_rwlock_wrlock F + __pthread_setspecific F __ptsname_r_chk F __pwrite64 F __rawmemchr F @@ -543,6 +552,8 @@ GLIBC_2.16 _obstack_free F _obstack_memory_used F _obstack_newchunk F + _pthread_cleanup_pop_restore F + _pthread_cleanup_push_defer F _res D 0x200 _res_hconf D 0x30 _rpc_dtablesize F @@ -1448,6 +1459,7 @@ GLIBC_2.16 pthread_mutex_init F pthread_mutex_lock F pthread_mutex_unlock F + pthread_once F pthread_self F pthread_setcancelstate F pthread_setcanceltype F |