mirror of
https://sourceware.org/git/glibc.git
synced 2024-12-22 19:00:07 +00:00
Remove cancellation support for syscall generation
This patch removes the cancellation mark from the auto-generation syscall script. Now all the cancellable syscalls are done throught C code using the SYSCALL_CANCEL macro. It simplifies the assembly required to each architecture port, since the SYSCALL_CANCEL uses the already defined INLINE_SYSCALL macros, and allows a more straigh fix on cancellation machanism (since no more specific assembly fixes will be required). Checked on i686-linux-gnu, x86_64-linux-gnu, x86_64-linux-gnux32, aarch64-linux-gnu, arm-linux-gnueabihf, and powerpc64le-linux-gnu.A Also with build-many-glibc.py with remaning touched architectures. * sysdeps/unix/make-syscalls.sh: Remove cancellable tagging for syscall definitions. * sysdeps/unix/syscall-template.S (SYSCALL_CANCELLABLE): Remove definition. * sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h (PSEUDO): Remove definition. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (CENABLE): Likewise. [IS_IN (libpthread)] (CDISABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise. * sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h (PSEUDO): Remove definition. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (__local_enable_asynccancel): Likewise. [IS_IN (libpthread)] (__local_disable_asynccancel): Likewise. [IS_IN (libc)] (__local_enable_asynccancel): Likewise. [IS_IN (libc)] (__local_enable_asynccancel): Likewise. [IS_IN (librt)] (__local_disable_asynccancel): Likewise. [IS_IN (librt)] (__local_disable_asynccancel): Likewise. (CENABLE): Likewise. (CDISABLE): Likewise. [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise. * sysdeps/unix/sysv/linux/arm/sysdep-cancel.h (PSEUDO): Remove defintion. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (CENABLE): Likewise. [IS_IN (libpthread)] (CDISABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise. * sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h (PSEUDO): Remove definition. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (CENABLE): Likewise. [IS_IN (libpthread)] (CDISABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise. * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (PSEUDO): Remove definition. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (CENABLE): Likewise. [IS_IN (libpthread)] (CDISABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise. * sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h (PSEUDO): Remove definition. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (CENABLE): Likewise. [IS_IN (libpthread)] (CDISABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise. * sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h (PSEUDO): Remove definition. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (CENABLE): Likewise. [IS_IN (libpthread)] (CDISABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise. * sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h (PSEUDO): Remove definition. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (CENABLE): Likewise. [IS_IN (libpthread)] (CDISABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise. * sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h (PSEUDO): Remove definition. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (CENABLE): Likewise. [IS_IN (libpthread)] (CDISABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. (SINGLE_THREAD_P): Likewise. * sysdeps/unix/sysv/linux/mips/sysdep-cancel.h (PSEUDO): Remove definition. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (CENABLE): Likewise. [IS_IN (libpthread)] (CDISABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise. * sysdeps/unix/sysv/linux/nios2/sysdep-cancel.h (PSEUDO): Remove definition. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (CENABLE): Likewise. [IS_IN (libpthread)] (CDISABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise. * sysdeps/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: Remove file. * sysdeps/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/sysdep-cancel.h: New file. * sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h (PSEUDO): Remove definition. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (CENABLE): Likewise. [IS_IN (libpthread)] (CDISABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h (PSEUDO): Remove definition. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (CENABLE): Likewise. [IS_IN (libpthread)] (CDISABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise. * sysdeps/unix/sysv/linux/sh/sysdep-cancel.h (PSEUDO): Remove definition. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (CENABLE): Likewise. [IS_IN (libpthread)] (CDISABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h: Remove file. * sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h: Likewise. * sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h: New file. * sysdeps/unix/sysv/linux/tile/sysdep-cancel.h (PSEUDO): Remove definition. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (CENABLE): Likewise. [IS_IN (libpthread)] (CDISABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise. * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (PSEUDO): Remove definition. (PSEUDO_END): Likewise. [IS_IN (libpthread)] (CENABLE): Likewise. [IS_IN (libpthread)] (CDISABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (libc)] (CENABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [IS_IN (librt)] (CDISABLE): Likewise. [__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
This commit is contained in:
parent
8aa48656bb
commit
ebd6f0076a
176
ChangeLog
176
ChangeLog
@ -1,3 +1,179 @@
|
||||
2017-08-24 Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
* sysdeps/unix/make-syscalls.sh: Remove cancellable tagging for
|
||||
syscall definitions and replace __builtin_expect with __glibc_likely.
|
||||
* sysdeps/unix/syscall-template.S: Update comment about cancellable
|
||||
syscall.
|
||||
(SYSCALL_CANCELLABLE): Removedefinition
|
||||
* sysdeps/unix/sysv/linux/aarch64/sysdep-cancel.h (PSEUDO): Remove
|
||||
definition.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (CENABLE): Likewise.
|
||||
[IS_IN (libpthread)] (CDISABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
|
||||
* sysdeps/unix/sysv/linux/alpha/sysdep-cancel.h (PSEUDO): Remove
|
||||
definition.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (__local_enable_asynccancel): Likewise.
|
||||
[IS_IN (libpthread)] (__local_disable_asynccancel): Likewise.
|
||||
[IS_IN (libc)] (__local_enable_asynccancel): Likewise.
|
||||
[IS_IN (libc)] (__local_enable_asynccancel): Likewise.
|
||||
[IS_IN (librt)] (__local_disable_asynccancel): Likewise.
|
||||
[IS_IN (librt)] (__local_disable_asynccancel): Likewise.
|
||||
(CENABLE): Likewise.
|
||||
(CDISABLE): Likewise.
|
||||
[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
|
||||
* sysdeps/unix/sysv/linux/arm/sysdep-cancel.h (PSEUDO): Remove
|
||||
defintion.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (CENABLE): Likewise.
|
||||
[IS_IN (libpthread)] (CDISABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
|
||||
* sysdeps/unix/sysv/linux/hppa/sysdep-cancel.h (PSEUDO): Remove
|
||||
definition.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (CENABLE): Likewise.
|
||||
[IS_IN (libpthread)] (CDISABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
|
||||
* sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (PSEUDO): Remove
|
||||
definition.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (CENABLE): Likewise.
|
||||
[IS_IN (libpthread)] (CDISABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
|
||||
* sysdeps/unix/sysv/linux/ia64/sysdep-cancel.h (PSEUDO): Remove
|
||||
definition.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (CENABLE): Likewise.
|
||||
[IS_IN (libpthread)] (CDISABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
|
||||
* sysdeps/unix/sysv/linux/m68k/sysdep-cancel.h (PSEUDO): Remove
|
||||
definition.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (CENABLE): Likewise.
|
||||
[IS_IN (libpthread)] (CDISABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
|
||||
* sysdeps/unix/sysv/linux/microblaze/sysdep-cancel.h (PSEUDO): Remove
|
||||
definition.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (CENABLE): Likewise.
|
||||
[IS_IN (libpthread)] (CDISABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/mips64/sysdep-cancel.h (PSEUDO):
|
||||
Remove definition.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (CENABLE): Likewise.
|
||||
[IS_IN (libpthread)] (CDISABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
(SINGLE_THREAD_P): Likewise.
|
||||
* sysdeps/unix/sysv/linux/mips/sysdep-cancel.h (PSEUDO): Remove
|
||||
definition.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (CENABLE): Likewise.
|
||||
[IS_IN (libpthread)] (CDISABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
|
||||
* sysdeps/unix/sysv/linux/nios2/sysdep-cancel.h (PSEUDO): Remove
|
||||
definition.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (CENABLE): Likewise.
|
||||
[IS_IN (libpthread)] (CDISABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
|
||||
* sysdeps/sysv/linux/powerpc/powerpc32/sysdep-cancel.h: Remove file.
|
||||
* sysdeps/sysv/linux/powerpc/powerpc64/sysdep-cancel.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/powerpc/sysdep-cancel.h: New file.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-32/sysdep-cancel.h (PSEUDO): Remove
|
||||
definition.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (CENABLE): Likewise.
|
||||
[IS_IN (libpthread)] (CDISABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
|
||||
* sysdeps/unix/sysv/linux/s390/s390-64/sysdep-cancel.h (PSEUDO): Remove
|
||||
definition.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (CENABLE): Likewise.
|
||||
[IS_IN (libpthread)] (CDISABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sh/sysdep-cancel.h (PSEUDO): Remove
|
||||
definition.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (CENABLE): Likewise.
|
||||
[IS_IN (libpthread)] (CDISABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc32/sysdep-cancel.h: Remove file.
|
||||
* sysdeps/unix/sysv/linux/sparc/sparc64/sysdep-cancel.h: Likewise.
|
||||
* sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h: New file.
|
||||
* sysdeps/unix/sysv/linux/tile/sysdep-cancel.h (PSEUDO): Remove
|
||||
definition.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (CENABLE): Likewise.
|
||||
[IS_IN (libpthread)] (CDISABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
|
||||
* sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (PSEUDO): Remove
|
||||
definition.
|
||||
(PSEUDO_END): Likewise.
|
||||
[IS_IN (libpthread)] (CENABLE): Likewise.
|
||||
[IS_IN (libpthread)] (CDISABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (libc)] (CENABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[IS_IN (librt)] (CDISABLE): Likewise.
|
||||
[__ASSEMBLER__] (SINGLE_THREAD_P): Likewise.
|
||||
|
||||
2017-08-24 Szabolcs Nagy <szabolcs.nagy@arm.com>
|
||||
|
||||
* sysdeps/ieee754/dbl-64/Makefile: Don't override CFLAGS.
|
||||
|
@ -12,7 +12,6 @@
|
||||
#
|
||||
# Syscall Signature Prefixes:
|
||||
#
|
||||
# C: cancellable (i.e., this syscall is a cancellation point)
|
||||
# E: errno and return value are not set by the call
|
||||
# V: errno is not set, but errno or zero (success) is returned from the call
|
||||
#
|
||||
@ -171,11 +170,9 @@ while read file srcfile caller syscall args strong weak; do
|
||||
;;
|
||||
esac
|
||||
|
||||
cancellable=0
|
||||
noerrno=0
|
||||
errval=0
|
||||
case $args in
|
||||
C*) cancellable=1; args=`echo $args | sed 's/C:\?//'`;;
|
||||
E*) noerrno=1; args=`echo $args | sed 's/E:\?//'`;;
|
||||
V*) errval=1; args=`echo $args | sed 's/V:\?//'`;;
|
||||
esac
|
||||
@ -258,7 +255,6 @@ while read file srcfile caller syscall args strong weak; do
|
||||
(echo '#define SYSCALL_NAME $syscall'; \\
|
||||
echo '#define SYSCALL_NARGS $nargs'; \\
|
||||
echo '#define SYSCALL_SYMBOL $strong'; \\
|
||||
echo '#define SYSCALL_CANCELLABLE $cancellable'; \\
|
||||
echo '#define SYSCALL_NOERRNO $noerrno'; \\
|
||||
echo '#define SYSCALL_ERRVAL $errval'; \\
|
||||
echo '#include <syscall-template.S>'; \\"
|
||||
|
@ -17,9 +17,8 @@
|
||||
<http://www.gnu.org/licenses/>. */
|
||||
|
||||
/* The real guts of this work are in the macros defined in the
|
||||
machine- and kernel-specific sysdep.h header file. When we
|
||||
are defining a cancellable system call, the sysdep-cancel.h
|
||||
versions of those macros are what we really use.
|
||||
machine- and kernel-specific sysdep.h header file. Cancellable syscalls
|
||||
should be implemented using C implementation with SYSCALL_CANCEL macro.
|
||||
|
||||
Each system call's object is built by a rule in sysd-syscalls
|
||||
generated by make-syscalls.sh that #include's this file after
|
||||
@ -27,7 +26,6 @@
|
||||
SYSCALL_NAME syscall name
|
||||
SYSCALL_NARGS number of arguments this call takes
|
||||
SYSCALL_SYMBOL primary symbol name
|
||||
SYSCALL_CANCELLABLE 1 if the call is a cancelation point
|
||||
SYSCALL_NOERRNO 1 to define a no-errno version (see below)
|
||||
SYSCALL_ERRVAL 1 to define an error-value version (see below)
|
||||
|
||||
@ -41,11 +39,7 @@
|
||||
instructions long and the untrained eye might not distinguish them from
|
||||
some compiled code that inexplicably lacks source line information. */
|
||||
|
||||
#if SYSCALL_CANCELLABLE
|
||||
# include <sysdep-cancel.h>
|
||||
#else
|
||||
# include <sysdep.h>
|
||||
#endif
|
||||
#include <sysdep.h>
|
||||
|
||||
/* This indirection is needed so that SYMBOL gets macro-expanded. */
|
||||
#define syscall_hidden_def(SYMBOL) hidden_def (SYMBOL)
|
||||
|
@ -18,108 +18,26 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.section ".text"; \
|
||||
ENTRY (__##syscall_name##_nocancel); \
|
||||
.Lpseudo_nocancel: \
|
||||
DO_CALL (syscall_name, args); \
|
||||
.Lpseudo_finish: \
|
||||
cmn x0, 4095; \
|
||||
b.cs .Lsyscall_error; \
|
||||
.subsection 2; \
|
||||
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
||||
ENTRY (name); \
|
||||
SINGLE_THREAD_P(16); \
|
||||
cbz w16, .Lpseudo_nocancel; \
|
||||
/* Setup common stack frame no matter the number of args. \
|
||||
Also save the first arg, since it's basically free. */ \
|
||||
stp x30, x0, [sp, -64]!; \
|
||||
cfi_adjust_cfa_offset (64); \
|
||||
cfi_rel_offset (x30, 0); \
|
||||
DOCARGS_##args; /* save syscall args around CENABLE. */ \
|
||||
CENABLE; \
|
||||
mov x16, x0; /* save mask around syscall. */ \
|
||||
UNDOCARGS_##args; /* restore syscall args. */ \
|
||||
DO_CALL (syscall_name, args); \
|
||||
str x0, [sp, 8]; /* save result around CDISABLE. */ \
|
||||
mov x0, x16; /* restore mask for CDISABLE. */ \
|
||||
CDISABLE; \
|
||||
/* Break down the stack frame, restoring result at once. */ \
|
||||
ldp x30, x0, [sp], 64; \
|
||||
cfi_adjust_cfa_offset (-64); \
|
||||
cfi_restore (x30); \
|
||||
b .Lpseudo_finish; \
|
||||
cfi_endproc; \
|
||||
.size name, .-name; \
|
||||
.previous
|
||||
|
||||
# undef PSEUDO_END
|
||||
# define PSEUDO_END(name) \
|
||||
SYSCALL_ERROR_HANDLER; \
|
||||
cfi_endproc
|
||||
|
||||
# define DOCARGS_0
|
||||
# define DOCARGS_1
|
||||
# define DOCARGS_2 str x1, [sp, 16]
|
||||
# define DOCARGS_3 stp x1, x2, [sp, 16]
|
||||
# define DOCARGS_4 DOCARGS_3; str x3, [sp, 32]
|
||||
# define DOCARGS_5 DOCARGS_3; stp x3, x4, [sp, 32]
|
||||
# define DOCARGS_6 DOCARGS_5; str x5, [sp, 48]
|
||||
|
||||
# define UNDOCARGS_0
|
||||
# define UNDOCARGS_1 ldr x0, [sp, 8]
|
||||
# define UNDOCARGS_2 ldp x0, x1, [sp, 8]
|
||||
# define UNDOCARGS_3 UNDOCARGS_1; ldp x1, x2, [sp, 16]
|
||||
# define UNDOCARGS_4 UNDOCARGS_2; ldp x2, x3, [sp, 24]
|
||||
# define UNDOCARGS_5 UNDOCARGS_3; ldp x3, x4, [sp, 32]
|
||||
# define UNDOCARGS_6 UNDOCARGS_4; ldp x4, x5, [sp, 40]
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE bl __pthread_enable_asynccancel
|
||||
# define CDISABLE bl __pthread_disable_asynccancel
|
||||
# define __local_multiple_threads __pthread_multiple_threads
|
||||
# elif IS_IN (libc)
|
||||
# define CENABLE bl __libc_enable_asynccancel
|
||||
# define CDISABLE bl __libc_disable_asynccancel
|
||||
# define __local_multiple_threads __libc_multiple_threads
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE bl __librt_enable_asynccancel
|
||||
# define CDISABLE bl __librt_disable_asynccancel
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
# if IS_IN (libpthread) || IS_IN (libc)
|
||||
# ifndef __ASSEMBLER__
|
||||
extern int __local_multiple_threads attribute_hidden;
|
||||
# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P(R) \
|
||||
adrp x##R, __local_multiple_threads; \
|
||||
ldr w##R, [x##R, :lo12:__local_multiple_threads]
|
||||
# endif
|
||||
# define SINGLE_THREAD_P __glibc_likely (__local_multiple_threads == 0)
|
||||
# else
|
||||
/* There is no __local_multiple_threads for librt, so use the TCB. */
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P(R) \
|
||||
mrs x##R, tpidr_el0; \
|
||||
sub x##R, x##R, PTHREAD_SIZEOF; \
|
||||
ldr w##R, [x##R, PTHREAD_MULTIPLE_THREADS_OFFSET]
|
||||
# endif
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
# endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
#else
|
||||
|
||||
/* For rtld, et cetera. */
|
||||
# define SINGLE_THREAD_P 1
|
||||
@ -127,8 +45,5 @@ extern int __local_multiple_threads attribute_hidden;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
@ -17,147 +17,23 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
/* ??? Assumes that nothing comes between PSEUDO and PSEUDO_END
|
||||
besides "ret". */
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
.type __##syscall_name##_nocancel, @function; \
|
||||
.usepv __##syscall_name##_nocancel, std; \
|
||||
.align 4; \
|
||||
cfi_startproc; \
|
||||
__LABEL(__##syscall_name##_nocancel) \
|
||||
ldgp gp, 0(pv); \
|
||||
PSEUDO_PROF; \
|
||||
__LABEL($pseudo_nocancel) \
|
||||
PSEUDO_PREPARE_ARGS; \
|
||||
lda v0, SYS_ify(syscall_name); \
|
||||
call_pal PAL_callsys; \
|
||||
bne a3, SYSCALL_ERROR_LABEL; \
|
||||
__LABEL($pseudo_ret) \
|
||||
.subsection 2; \
|
||||
.size __##syscall_name##_nocancel, .-__##syscall_name##_nocancel; \
|
||||
.globl name; \
|
||||
.type name, @function; \
|
||||
.usepv name, std; \
|
||||
.align 4; \
|
||||
cfi_startproc; \
|
||||
__LABEL(name) \
|
||||
ldgp gp, 0(pv); \
|
||||
PSEUDO_PROF; \
|
||||
SINGLE_THREAD_P(t0); \
|
||||
beq t0, $pseudo_nocancel; \
|
||||
subq sp, 64, sp; \
|
||||
cfi_def_cfa_offset(64); \
|
||||
stq ra, 0(sp); \
|
||||
cfi_offset(ra, -64); \
|
||||
SAVE_ARGS_##args; \
|
||||
CENABLE; \
|
||||
LOAD_ARGS_##args; \
|
||||
/* Save the CENABLE return value in RA. That register \
|
||||
is preserved across syscall and the real return \
|
||||
address is saved on the stack. */ \
|
||||
mov v0, ra; \
|
||||
lda v0, SYS_ify(syscall_name); \
|
||||
call_pal PAL_callsys; \
|
||||
stq v0, 8(sp); \
|
||||
mov ra, a0; \
|
||||
bne a3, $multi_error; \
|
||||
CDISABLE; \
|
||||
ldq ra, 0(sp); \
|
||||
ldq v0, 8(sp); \
|
||||
addq sp, 64, sp; \
|
||||
cfi_remember_state; \
|
||||
cfi_restore(ra); \
|
||||
cfi_def_cfa_offset(0); \
|
||||
ret; \
|
||||
cfi_restore_state; \
|
||||
__LABEL($multi_error) \
|
||||
CDISABLE; \
|
||||
ldq ra, 0(sp); \
|
||||
ldq v0, 8(sp); \
|
||||
addq sp, 64, sp; \
|
||||
cfi_restore(ra); \
|
||||
cfi_def_cfa_offset(0); \
|
||||
SYSCALL_ERROR_FALLTHRU; \
|
||||
SYSCALL_ERROR_HANDLER; \
|
||||
cfi_endproc; \
|
||||
.previous
|
||||
|
||||
# undef PSEUDO_END
|
||||
# define PSEUDO_END(sym) \
|
||||
cfi_endproc; \
|
||||
.subsection 2; \
|
||||
.size sym, .-sym
|
||||
|
||||
# define SAVE_ARGS_0 /* Nothing. */
|
||||
# define SAVE_ARGS_1 SAVE_ARGS_0; stq a0, 8(sp)
|
||||
# define SAVE_ARGS_2 SAVE_ARGS_1; stq a1, 16(sp)
|
||||
# define SAVE_ARGS_3 SAVE_ARGS_2; stq a2, 24(sp)
|
||||
# define SAVE_ARGS_4 SAVE_ARGS_3; stq a3, 32(sp)
|
||||
# define SAVE_ARGS_5 SAVE_ARGS_4; stq a4, 40(sp)
|
||||
# define SAVE_ARGS_6 SAVE_ARGS_5; stq a5, 48(sp)
|
||||
|
||||
# define LOAD_ARGS_0 /* Nothing. */
|
||||
# define LOAD_ARGS_1 LOAD_ARGS_0; ldq a0, 8(sp)
|
||||
# define LOAD_ARGS_2 LOAD_ARGS_1; ldq a1, 16(sp)
|
||||
# define LOAD_ARGS_3 LOAD_ARGS_2; ldq a2, 24(sp)
|
||||
# define LOAD_ARGS_4 LOAD_ARGS_3; ldq a3, 32(sp)
|
||||
# define LOAD_ARGS_5 LOAD_ARGS_4; ldq a4, 40(sp)
|
||||
# define LOAD_ARGS_6 LOAD_ARGS_5; ldq a5, 48(sp)
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define __local_enable_asynccancel __pthread_enable_asynccancel
|
||||
# define __local_disable_asynccancel __pthread_disable_asynccancel
|
||||
# define __local_multiple_threads __pthread_multiple_threads
|
||||
# elif IS_IN (libc)
|
||||
# define __local_enable_asynccancel __libc_enable_asynccancel
|
||||
# define __local_disable_asynccancel __libc_disable_asynccancel
|
||||
# define __local_multiple_threads __libc_multiple_threads
|
||||
# elif IS_IN (librt)
|
||||
# define __local_enable_asynccancel __librt_enable_asynccancel
|
||||
# define __local_disable_asynccancel __librt_disable_asynccancel
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
# ifdef PIC
|
||||
# define CENABLE bsr ra, __local_enable_asynccancel !samegp
|
||||
# define CDISABLE bsr ra, __local_disable_asynccancel !samegp
|
||||
# else
|
||||
# define CENABLE jsr ra, __local_enable_asynccancel; ldgp ra, 0(gp)
|
||||
# define CDISABLE jsr ra, __local_disable_asynccancel; ldgp ra, 0(gp)
|
||||
# endif
|
||||
|
||||
# if IS_IN (libpthread) || IS_IN (libc)
|
||||
# ifndef __ASSEMBLER__
|
||||
extern int __local_multiple_threads attribute_hidden;
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (__local_multiple_threads == 0, 1)
|
||||
# elif defined(PIC)
|
||||
# define SINGLE_THREAD_P(reg) ldl reg, __local_multiple_threads(gp) !gprel
|
||||
# else
|
||||
# define SINGLE_THREAD_P(reg) \
|
||||
ldah reg, __local_multiple_threads(gp) !gprelhigh; \
|
||||
ldl reg, __local_multiple_threads(reg) !gprellow
|
||||
# endif
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (__local_multiple_threads == 0)
|
||||
# else
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P(reg) \
|
||||
call_pal PAL_rduniq; \
|
||||
ldl reg, MULTIPLE_THREADS_OFFSET($0)
|
||||
# endif
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
# endif
|
||||
|
||||
#else
|
||||
@ -167,8 +43,5 @@ extern int __local_multiple_threads attribute_hidden;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
@ -17,216 +17,26 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
/* NOTE: We do mark syscalls with unwind annotations, for the benefit of
|
||||
cancellation; but they're really only accurate at the point of the
|
||||
syscall. The ARM unwind directives are not rich enough without adding
|
||||
a custom personality function. */
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.text; \
|
||||
ENTRY (__##syscall_name##_nocancel); \
|
||||
CFI_SECTIONS; \
|
||||
DO_CALL (syscall_name, args); \
|
||||
cmn r0, $4096; \
|
||||
PSEUDO_RET; \
|
||||
END (__##syscall_name##_nocancel); \
|
||||
ENTRY (name); \
|
||||
SINGLE_THREAD_P; \
|
||||
DOARGS_##args; \
|
||||
bne .Lpseudo_cancel; \
|
||||
cfi_remember_state; \
|
||||
ldr r7, =SYS_ify (syscall_name); \
|
||||
swi 0x0; \
|
||||
UNDOARGS_##args; \
|
||||
cmn r0, $4096; \
|
||||
PSEUDO_RET; \
|
||||
cfi_restore_state; \
|
||||
.Lpseudo_cancel: \
|
||||
.fnstart; /* matched by the .fnend in UNDOARGS below. */ \
|
||||
DOCARGS_##args; /* save syscall args etc. around CENABLE. */ \
|
||||
CENABLE; \
|
||||
mov ip, r0; /* put mask in safe place. */ \
|
||||
UNDOCARGS_##args; /* restore syscall args. */ \
|
||||
ldr r7, =SYS_ify (syscall_name); \
|
||||
swi 0x0; /* do the call. */ \
|
||||
mov r7, r0; /* save syscall return value. */ \
|
||||
mov r0, ip; /* get mask back. */ \
|
||||
CDISABLE; \
|
||||
mov r0, r7; /* retrieve return value. */ \
|
||||
RESTORE_LR_##args; \
|
||||
UNDOARGS_##args; \
|
||||
cmn r0, $4096
|
||||
|
||||
/* DOARGS pushes eight bytes on the stack for five arguments, twelve bytes for
|
||||
six arguments, and four bytes for fewer. In order to preserve doubleword
|
||||
alignment, sometimes we must save an extra register. */
|
||||
|
||||
# define RESTART_UNWIND \
|
||||
.fnend; \
|
||||
.fnstart; \
|
||||
.save {r7}; \
|
||||
.save {lr}
|
||||
|
||||
# define DOCARGS_0 \
|
||||
.save {r7}; \
|
||||
push {lr}; \
|
||||
cfi_adjust_cfa_offset (4); \
|
||||
cfi_rel_offset (lr, 0); \
|
||||
.save {lr}
|
||||
# define UNDOCARGS_0
|
||||
# define RESTORE_LR_0 \
|
||||
pop {lr}; \
|
||||
cfi_adjust_cfa_offset (-4); \
|
||||
cfi_restore (lr)
|
||||
|
||||
# define DOCARGS_1 \
|
||||
.save {r7}; \
|
||||
push {r0, r1, lr}; \
|
||||
cfi_adjust_cfa_offset (12); \
|
||||
cfi_rel_offset (lr, 8); \
|
||||
.save {lr}; \
|
||||
.pad #8
|
||||
# define UNDOCARGS_1 \
|
||||
ldr r0, [sp], #8; \
|
||||
cfi_adjust_cfa_offset (-8); \
|
||||
RESTART_UNWIND
|
||||
# define RESTORE_LR_1 \
|
||||
RESTORE_LR_0
|
||||
|
||||
# define DOCARGS_2 \
|
||||
.save {r7}; \
|
||||
push {r0, r1, lr}; \
|
||||
cfi_adjust_cfa_offset (12); \
|
||||
cfi_rel_offset (lr, 8); \
|
||||
.save {lr}; \
|
||||
.pad #8
|
||||
# define UNDOCARGS_2 \
|
||||
pop {r0, r1}; \
|
||||
cfi_adjust_cfa_offset (-8); \
|
||||
RESTART_UNWIND
|
||||
# define RESTORE_LR_2 \
|
||||
RESTORE_LR_0
|
||||
|
||||
# define DOCARGS_3 \
|
||||
.save {r7}; \
|
||||
push {r0, r1, r2, r3, lr}; \
|
||||
cfi_adjust_cfa_offset (20); \
|
||||
cfi_rel_offset (lr, 16); \
|
||||
.save {lr}; \
|
||||
.pad #16
|
||||
# define UNDOCARGS_3 \
|
||||
pop {r0, r1, r2, r3}; \
|
||||
cfi_adjust_cfa_offset (-16); \
|
||||
RESTART_UNWIND
|
||||
# define RESTORE_LR_3 \
|
||||
RESTORE_LR_0
|
||||
|
||||
# define DOCARGS_4 \
|
||||
.save {r7}; \
|
||||
push {r0, r1, r2, r3, lr}; \
|
||||
cfi_adjust_cfa_offset (20); \
|
||||
cfi_rel_offset (lr, 16); \
|
||||
.save {lr}; \
|
||||
.pad #16
|
||||
# define UNDOCARGS_4 \
|
||||
pop {r0, r1, r2, r3}; \
|
||||
cfi_adjust_cfa_offset (-16); \
|
||||
RESTART_UNWIND
|
||||
# define RESTORE_LR_4 \
|
||||
RESTORE_LR_0
|
||||
|
||||
/* r4 is only stmfd'ed for correct stack alignment. */
|
||||
# define DOCARGS_5 \
|
||||
.save {r4, r7}; \
|
||||
push {r0, r1, r2, r3, r4, lr}; \
|
||||
cfi_adjust_cfa_offset (24); \
|
||||
cfi_rel_offset (lr, 20); \
|
||||
.save {lr}; \
|
||||
.pad #20
|
||||
# define UNDOCARGS_5 \
|
||||
pop {r0, r1, r2, r3}; \
|
||||
cfi_adjust_cfa_offset (-16); \
|
||||
.fnend; \
|
||||
.fnstart; \
|
||||
.save {r4, r7}; \
|
||||
.save {lr}; \
|
||||
.pad #4
|
||||
# define RESTORE_LR_5 \
|
||||
pop {r4, lr}; \
|
||||
cfi_adjust_cfa_offset (-8); \
|
||||
/* r4 will be marked as restored later. */ \
|
||||
cfi_restore (lr)
|
||||
|
||||
# define DOCARGS_6 \
|
||||
.save {r4, r5, r7}; \
|
||||
push {r0, r1, r2, r3, lr}; \
|
||||
cfi_adjust_cfa_offset (20); \
|
||||
cfi_rel_offset (lr, 16); \
|
||||
.save {lr}; \
|
||||
.pad #16
|
||||
# define UNDOCARGS_6 \
|
||||
pop {r0, r1, r2, r3}; \
|
||||
cfi_adjust_cfa_offset (-16); \
|
||||
.fnend; \
|
||||
.fnstart; \
|
||||
.save {r4, r5, r7}; \
|
||||
.save {lr};
|
||||
# define RESTORE_LR_6 \
|
||||
RESTORE_LR_0
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE bl PLTJMP(__pthread_enable_asynccancel)
|
||||
# define CDISABLE bl PLTJMP(__pthread_disable_asynccancel)
|
||||
# define __local_multiple_threads __pthread_multiple_threads
|
||||
# elif IS_IN (libc)
|
||||
# define CENABLE bl PLTJMP(__libc_enable_asynccancel)
|
||||
# define CDISABLE bl PLTJMP(__libc_disable_asynccancel)
|
||||
# define __local_multiple_threads __libc_multiple_threads
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE bl PLTJMP(__librt_enable_asynccancel)
|
||||
# define CDISABLE bl PLTJMP(__librt_disable_asynccancel)
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
# if IS_IN (libpthread) || IS_IN (libc)
|
||||
# ifndef __ASSEMBLER__
|
||||
extern int __local_multiple_threads attribute_hidden;
|
||||
# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P \
|
||||
LDST_PCREL(ldr, ip, ip, __local_multiple_threads); \
|
||||
teq ip, #0
|
||||
# endif
|
||||
# define SINGLE_THREAD_P __glibc_likely (__local_multiple_threads == 0)
|
||||
# else
|
||||
/* There is no __local_multiple_threads for librt, so use the TCB. */
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P \
|
||||
push {r0, lr}; \
|
||||
cfi_adjust_cfa_offset (8); \
|
||||
cfi_rel_offset (lr, 4); \
|
||||
GET_TLS (lr); \
|
||||
NEGOFF_ADJ_BASE (r0, MULTIPLE_THREADS_OFFSET); \
|
||||
ldr ip, NEGOFF_OFF1 (r0, MULTIPLE_THREADS_OFFSET); \
|
||||
pop {r0, lr}; \
|
||||
cfi_adjust_cfa_offset (-8); \
|
||||
cfi_restore (lr); \
|
||||
teq ip, #0
|
||||
# endif
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
# endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
#else
|
||||
|
||||
/* For rtld, et cetera. */
|
||||
# define SINGLE_THREAD_P 1
|
||||
@ -234,8 +44,5 @@ extern int __local_multiple_threads attribute_hidden;
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
||||
#define RTLD_SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
@ -17,221 +17,10 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# ifndef NO_ERROR
|
||||
# define NO_ERROR -0x1000
|
||||
# endif
|
||||
|
||||
/* The syscall cancellation mechanism requires userspace
|
||||
assistance, the following code does roughly this:
|
||||
|
||||
do arguments (read arg5 and arg6 to registers)
|
||||
setup frame
|
||||
|
||||
check if there are threads, yes jump to pseudo_cancel
|
||||
|
||||
unthreaded:
|
||||
syscall
|
||||
check syscall return (jump to pre_end)
|
||||
set errno
|
||||
set return to -1
|
||||
(jump to pre_end)
|
||||
|
||||
pseudo_cancel:
|
||||
cenable
|
||||
syscall
|
||||
cdisable
|
||||
check syscall return (jump to pre_end)
|
||||
set errno
|
||||
set return to -1
|
||||
|
||||
pre_end
|
||||
restore stack
|
||||
|
||||
It is expected that 'ret' and 'END' macros will
|
||||
append an 'undo arguments' and 'return' to the
|
||||
this PSEUDO macro. */
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
ENTRY (__##syscall_name##_nocancel) \
|
||||
DOARGS_##args ASM_LINE_SEP \
|
||||
stwm TREG, 64(%sp) ASM_LINE_SEP \
|
||||
.cfi_def_cfa_offset -64 ASM_LINE_SEP \
|
||||
.cfi_offset TREG, 0 ASM_LINE_SEP \
|
||||
stw %sp, -4(%sp) ASM_LINE_SEP \
|
||||
stw %r19, -32(%sp) ASM_LINE_SEP \
|
||||
.cfi_offset 19, 32 ASM_LINE_SEP \
|
||||
/* Save r19 */ ASM_LINE_SEP \
|
||||
SAVE_PIC(TREG) ASM_LINE_SEP \
|
||||
/* Do syscall, delay loads # */ ASM_LINE_SEP \
|
||||
ble 0x100(%sr2,%r0) ASM_LINE_SEP \
|
||||
ldi SYS_ify (syscall_name), %r20 /* delay */ ASM_LINE_SEP \
|
||||
ldi NO_ERROR,%r1 ASM_LINE_SEP \
|
||||
cmpb,>>=,n %r1,%ret0,L(pre_nc_end) ASM_LINE_SEP \
|
||||
/* Restore r19 from TREG */ ASM_LINE_SEP \
|
||||
LOAD_PIC(TREG) /* delay */ ASM_LINE_SEP \
|
||||
SYSCALL_ERROR_HANDLER ASM_LINE_SEP \
|
||||
/* Use TREG for temp storage */ ASM_LINE_SEP \
|
||||
copy %ret0, TREG /* delay */ ASM_LINE_SEP \
|
||||
/* OPTIMIZE: Don't reload r19 */ ASM_LINE_SEP \
|
||||
/* do a -1*syscall_ret0 */ ASM_LINE_SEP \
|
||||
sub %r0, TREG, TREG ASM_LINE_SEP \
|
||||
/* Store into errno location */ ASM_LINE_SEP \
|
||||
stw TREG, 0(%sr0,%ret0) ASM_LINE_SEP \
|
||||
/* return -1 as error */ ASM_LINE_SEP \
|
||||
ldi -1, %ret0 ASM_LINE_SEP \
|
||||
L(pre_nc_end): ASM_LINE_SEP \
|
||||
/* No need to LOAD_PIC */ ASM_LINE_SEP \
|
||||
/* Undo frame */ ASM_LINE_SEP \
|
||||
ldwm -64(%sp),TREG ASM_LINE_SEP \
|
||||
/* Restore rp before exit */ ASM_LINE_SEP \
|
||||
ldw -20(%sp), %rp ASM_LINE_SEP \
|
||||
ret ASM_LINE_SEP \
|
||||
END(__##syscall_name##_nocancel) ASM_LINE_SEP \
|
||||
/**********************************************/ASM_LINE_SEP \
|
||||
ENTRY (name) \
|
||||
DOARGS_##args ASM_LINE_SEP \
|
||||
stwm TREG, 64(%sp) ASM_LINE_SEP \
|
||||
.cfi_def_cfa_offset -64 ASM_LINE_SEP \
|
||||
.cfi_offset TREG, 0 ASM_LINE_SEP \
|
||||
stw %sp, -4(%sp) ASM_LINE_SEP \
|
||||
stw %r19, -32(%sp) ASM_LINE_SEP \
|
||||
.cfi_offset 19, 32 ASM_LINE_SEP \
|
||||
/* Done setting up frame, continue... */ ASM_LINE_SEP \
|
||||
SINGLE_THREAD_P ASM_LINE_SEP \
|
||||
cmpib,<>,n 0,%ret0,L(pseudo_cancel) ASM_LINE_SEP \
|
||||
L(unthreaded): ASM_LINE_SEP \
|
||||
/* Save r19 */ ASM_LINE_SEP \
|
||||
SAVE_PIC(TREG) ASM_LINE_SEP \
|
||||
/* Do syscall, delay loads # */ ASM_LINE_SEP \
|
||||
ble 0x100(%sr2,%r0) ASM_LINE_SEP \
|
||||
ldi SYS_ify (syscall_name), %r20 /* delay */ ASM_LINE_SEP \
|
||||
ldi NO_ERROR,%r1 ASM_LINE_SEP \
|
||||
cmpb,>>=,n %r1,%ret0,L(pre_end) ASM_LINE_SEP \
|
||||
/* Restore r19 from TREG */ ASM_LINE_SEP \
|
||||
LOAD_PIC(TREG) /* delay */ ASM_LINE_SEP \
|
||||
SYSCALL_ERROR_HANDLER ASM_LINE_SEP \
|
||||
/* Use TREG for temp storage */ ASM_LINE_SEP \
|
||||
copy %ret0, TREG /* delay */ ASM_LINE_SEP \
|
||||
/* OPTIMIZE: Don't reload r19 */ ASM_LINE_SEP \
|
||||
/* do a -1*syscall_ret0 */ ASM_LINE_SEP \
|
||||
sub %r0, TREG, TREG ASM_LINE_SEP \
|
||||
/* Store into errno location */ ASM_LINE_SEP \
|
||||
stw TREG, 0(%sr0,%ret0) ASM_LINE_SEP \
|
||||
b L(pre_end) ASM_LINE_SEP \
|
||||
/* return -1 as error */ ASM_LINE_SEP \
|
||||
ldi -1, %ret0 /* delay */ ASM_LINE_SEP \
|
||||
L(pseudo_cancel): ASM_LINE_SEP \
|
||||
PUSHARGS_##args /* Save args */ ASM_LINE_SEP \
|
||||
/* Save r19 into TREG */ ASM_LINE_SEP \
|
||||
CENABLE /* FUNC CALL */ ASM_LINE_SEP \
|
||||
SAVE_PIC(TREG) /* delay */ ASM_LINE_SEP \
|
||||
/* restore syscall args */ ASM_LINE_SEP \
|
||||
POPARGS_##args ASM_LINE_SEP \
|
||||
/* save mask from cenable (use stub rp slot) */ ASM_LINE_SEP \
|
||||
stw %ret0, -24(%sp) ASM_LINE_SEP \
|
||||
/* ... SYSCALL ... */ ASM_LINE_SEP \
|
||||
ble 0x100(%sr2,%r0) ASM_LINE_SEP \
|
||||
ldi SYS_ify (syscall_name), %r20 /* delay */ ASM_LINE_SEP \
|
||||
/* ............... */ ASM_LINE_SEP \
|
||||
LOAD_PIC(TREG) ASM_LINE_SEP \
|
||||
/* pass mask as arg0 to cdisable */ ASM_LINE_SEP \
|
||||
ldw -24(%sp), %r26 ASM_LINE_SEP \
|
||||
CDISABLE ASM_LINE_SEP \
|
||||
stw %ret0, -24(%sp) /* delay */ ASM_LINE_SEP \
|
||||
/* Restore syscall return */ ASM_LINE_SEP \
|
||||
ldw -24(%sp), %ret0 ASM_LINE_SEP \
|
||||
/* compare error */ ASM_LINE_SEP \
|
||||
ldi NO_ERROR,%r1 ASM_LINE_SEP \
|
||||
/* branch if no error */ ASM_LINE_SEP \
|
||||
cmpb,>>=,n %r1,%ret0,L(pre_end) ASM_LINE_SEP \
|
||||
LOAD_PIC(TREG) /* cond. nullify */ ASM_LINE_SEP \
|
||||
copy %ret0, TREG /* save syscall return */ ASM_LINE_SEP \
|
||||
SYSCALL_ERROR_HANDLER ASM_LINE_SEP \
|
||||
/* make syscall res value positive */ ASM_LINE_SEP \
|
||||
sub %r0, TREG, TREG /* delay */ ASM_LINE_SEP \
|
||||
/* No need to LOAD_PIC */ ASM_LINE_SEP \
|
||||
/* store into errno location */ ASM_LINE_SEP \
|
||||
stw TREG, 0(%sr0,%ret0) ASM_LINE_SEP \
|
||||
/* return -1 */ ASM_LINE_SEP \
|
||||
ldi -1, %ret0 ASM_LINE_SEP \
|
||||
L(pre_end): ASM_LINE_SEP \
|
||||
/* No need to LOAD_PIC */ ASM_LINE_SEP \
|
||||
/* Undo frame */ ASM_LINE_SEP \
|
||||
ldwm -64(%sp),TREG ASM_LINE_SEP \
|
||||
/* Restore rp before exit */ ASM_LINE_SEP \
|
||||
ldw -20(%sp), %rp ASM_LINE_SEP
|
||||
|
||||
/* Save arguments into our frame */
|
||||
# define PUSHARGS_0 /* nothing to do */
|
||||
# define PUSHARGS_1 PUSHARGS_0 stw %r26, -36(%sr0,%sp) ASM_LINE_SEP \
|
||||
.cfi_offset 26, 28 ASM_LINE_SEP
|
||||
# define PUSHARGS_2 PUSHARGS_1 stw %r25, -40(%sr0,%sp) ASM_LINE_SEP \
|
||||
.cfi_offset 25, 24 ASM_LINE_SEP
|
||||
# define PUSHARGS_3 PUSHARGS_2 stw %r24, -44(%sr0,%sp) ASM_LINE_SEP \
|
||||
.cfi_offset 24, 20 ASM_LINE_SEP
|
||||
# define PUSHARGS_4 PUSHARGS_3 stw %r23, -48(%sr0,%sp) ASM_LINE_SEP \
|
||||
.cfi_offset 23, 16 ASM_LINE_SEP
|
||||
# define PUSHARGS_5 PUSHARGS_4 stw %r22, -52(%sr0,%sp) ASM_LINE_SEP \
|
||||
.cfi_offset 22, 12 ASM_LINE_SEP
|
||||
# define PUSHARGS_6 PUSHARGS_5 stw %r21, -56(%sr0,%sp) ASM_LINE_SEP \
|
||||
.cfi_offset 21, 8 ASM_LINE_SEP
|
||||
|
||||
/* Bring them back from the stack */
|
||||
# define POPARGS_0 /* nothing to do */
|
||||
# define POPARGS_1 POPARGS_0 ldw -36(%sr0,%sp), %r26 ASM_LINE_SEP
|
||||
# define POPARGS_2 POPARGS_1 ldw -40(%sr0,%sp), %r25 ASM_LINE_SEP
|
||||
# define POPARGS_3 POPARGS_2 ldw -44(%sr0,%sp), %r24 ASM_LINE_SEP
|
||||
# define POPARGS_4 POPARGS_3 ldw -48(%sr0,%sp), %r23 ASM_LINE_SEP
|
||||
# define POPARGS_5 POPARGS_4 ldw -52(%sr0,%sp), %r22 ASM_LINE_SEP
|
||||
# define POPARGS_6 POPARGS_5 ldw -56(%sr0,%sp), %r21 ASM_LINE_SEP
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# ifdef PIC
|
||||
# define CENABLE .import __pthread_enable_asynccancel,code ASM_LINE_SEP \
|
||||
bl __pthread_enable_asynccancel,%r2 ASM_LINE_SEP
|
||||
# define CDISABLE .import __pthread_disable_asynccancel,code ASM_LINE_SEP \
|
||||
bl __pthread_disable_asynccancel,%r2 ASM_LINE_SEP
|
||||
# else
|
||||
# define CENABLE .import __pthread_enable_asynccancel,code ASM_LINE_SEP \
|
||||
bl __pthread_enable_asynccancel,%r2 ASM_LINE_SEP
|
||||
# define CDISABLE .import __pthread_disable_asynccancel,code ASM_LINE_SEP \
|
||||
bl __pthread_disable_asynccancel,%r2 ASM_LINE_SEP
|
||||
# endif
|
||||
# elif IS_IN (libc)
|
||||
# ifdef PIC
|
||||
# define CENABLE .import __libc_enable_asynccancel,code ASM_LINE_SEP \
|
||||
bl __libc_enable_asynccancel,%r2 ASM_LINE_SEP
|
||||
# define CDISABLE .import __libc_disable_asynccancel,code ASM_LINE_SEP \
|
||||
bl __libc_disable_asynccancel,%r2 ASM_LINE_SEP
|
||||
# else
|
||||
# define CENABLE .import __libc_enable_asynccancel,code ASM_LINE_SEP \
|
||||
bl __libc_enable_asynccancel,%r2 ASM_LINE_SEP
|
||||
# define CDISABLE .import __libc_disable_asynccancel,code ASM_LINE_SEP \
|
||||
bl __libc_disable_asynccancel,%r2 ASM_LINE_SEP
|
||||
# endif
|
||||
# elif IS_IN (librt)
|
||||
# ifdef PIC
|
||||
# define CENABLE .import __librt_enable_asynccancel,code ASM_LINE_SEP \
|
||||
bl __librt_enable_asynccancel,%r2 ASM_LINE_SEP
|
||||
# define CDISABLE .import __librt_disable_asynccancel,code ASM_LINE_SEP \
|
||||
bl __librt_disable_asynccancel,%r2 ASM_LINE_SEP
|
||||
# else
|
||||
# define CENABLE .import __librt_enable_asynccancel,code ASM_LINE_SEP \
|
||||
bl __librt_enable_asynccancel,%r2 ASM_LINE_SEP
|
||||
# define CDISABLE .import __librt_disable_asynccancel,code ASM_LINE_SEP \
|
||||
bl __librt_disable_asynccancel,%r2 ASM_LINE_SEP
|
||||
# endif
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define __local_multiple_threads __pthread_multiple_threads
|
||||
# elif IS_IN (libc)
|
||||
@ -242,17 +31,10 @@ L(pre_end): ASM_LINE_SEP \
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
/* Read the value of header.multiple_threads from the thread pointer */
|
||||
# define SINGLE_THREAD_P \
|
||||
mfctl %cr27, %ret0 ASM_LINE_SEP \
|
||||
ldw MULTIPLE_THREADS_THREAD_OFFSET(%sr0,%ret0),%ret0 ASM_LINE_SEP
|
||||
# endif
|
||||
#elif !defined __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
||||
#else
|
||||
|
||||
/* This code should never be used but we define it anyhow. */
|
||||
# define SINGLE_THREAD_P (1)
|
||||
@ -261,8 +43,5 @@ L(pre_end): ASM_LINE_SEP \
|
||||
#endif
|
||||
/* IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) */
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
||||
#define RTLD_SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
@ -18,136 +18,19 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.text; \
|
||||
ENTRY (name) \
|
||||
cmpl $0, %gs:MULTIPLE_THREADS_OFFSET; \
|
||||
jne L(pseudo_cancel); \
|
||||
.type __##syscall_name##_nocancel,@function; \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
__##syscall_name##_nocancel: \
|
||||
DO_CALL (syscall_name, args); \
|
||||
cmpl $-4095, %eax; \
|
||||
jae SYSCALL_ERROR_LABEL; \
|
||||
ret; \
|
||||
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
||||
L(pseudo_cancel): \
|
||||
CENABLE \
|
||||
SAVE_OLDTYPE_##args \
|
||||
PUSHCARGS_##args \
|
||||
DOCARGS_##args \
|
||||
movl $SYS_ify (syscall_name), %eax; \
|
||||
ENTER_KERNEL; \
|
||||
POPCARGS_##args; \
|
||||
POPSTATE_##args \
|
||||
cmpl $-4095, %eax; \
|
||||
jae SYSCALL_ERROR_LABEL
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
||||
# define SAVE_OLDTYPE_0 movl %eax, %ecx;
|
||||
# define SAVE_OLDTYPE_1 SAVE_OLDTYPE_0
|
||||
# define SAVE_OLDTYPE_2 pushl %eax; cfi_adjust_cfa_offset (4);
|
||||
# define SAVE_OLDTYPE_3 SAVE_OLDTYPE_2
|
||||
# define SAVE_OLDTYPE_4 SAVE_OLDTYPE_2
|
||||
# define SAVE_OLDTYPE_5 SAVE_OLDTYPE_2
|
||||
# define SAVE_OLDTYPE_6 SAVE_OLDTYPE_2
|
||||
|
||||
# define PUSHCARGS_0 /* No arguments to push. */
|
||||
# define DOCARGS_0 /* No arguments to frob. */
|
||||
# define POPCARGS_0 /* No arguments to pop. */
|
||||
# define _PUSHCARGS_0 /* No arguments to push. */
|
||||
# define _POPCARGS_0 /* No arguments to pop. */
|
||||
|
||||
# define PUSHCARGS_1 movl %ebx, %edx; cfi_register (ebx, edx); PUSHCARGS_0
|
||||
# define DOCARGS_1 _DOARGS_1 (4)
|
||||
# define POPCARGS_1 POPCARGS_0; movl %edx, %ebx; cfi_restore (ebx);
|
||||
# define _PUSHCARGS_1 pushl %ebx; cfi_adjust_cfa_offset (4); \
|
||||
cfi_rel_offset (ebx, 0); _PUSHCARGS_0
|
||||
# define _POPCARGS_1 _POPCARGS_0; popl %ebx; \
|
||||
cfi_adjust_cfa_offset (-4); cfi_restore (ebx);
|
||||
|
||||
# define PUSHCARGS_2 PUSHCARGS_1
|
||||
# define DOCARGS_2 _DOARGS_2 (12)
|
||||
# define POPCARGS_2 POPCARGS_1
|
||||
# define _PUSHCARGS_2 _PUSHCARGS_1
|
||||
# define _POPCARGS_2 _POPCARGS_1
|
||||
|
||||
# define PUSHCARGS_3 _PUSHCARGS_2
|
||||
# define DOCARGS_3 _DOARGS_3 (20)
|
||||
# define POPCARGS_3 _POPCARGS_3
|
||||
# define _PUSHCARGS_3 _PUSHCARGS_2
|
||||
# define _POPCARGS_3 _POPCARGS_2
|
||||
|
||||
# define PUSHCARGS_4 _PUSHCARGS_4
|
||||
# define DOCARGS_4 _DOARGS_4 (28)
|
||||
# define POPCARGS_4 _POPCARGS_4
|
||||
# define _PUSHCARGS_4 pushl %esi; cfi_adjust_cfa_offset (4); \
|
||||
cfi_rel_offset (esi, 0); _PUSHCARGS_3
|
||||
# define _POPCARGS_4 _POPCARGS_3; popl %esi; \
|
||||
cfi_adjust_cfa_offset (-4); cfi_restore (esi);
|
||||
|
||||
# define PUSHCARGS_5 _PUSHCARGS_5
|
||||
# define DOCARGS_5 _DOARGS_5 (36)
|
||||
# define POPCARGS_5 _POPCARGS_5
|
||||
# define _PUSHCARGS_5 pushl %edi; cfi_adjust_cfa_offset (4); \
|
||||
cfi_rel_offset (edi, 0); _PUSHCARGS_4
|
||||
# define _POPCARGS_5 _POPCARGS_4; popl %edi; \
|
||||
cfi_adjust_cfa_offset (-4); cfi_restore (edi);
|
||||
|
||||
# define PUSHCARGS_6 _PUSHCARGS_6
|
||||
# define DOCARGS_6 _DOARGS_6 (44)
|
||||
# define POPCARGS_6 _POPCARGS_6
|
||||
# define _PUSHCARGS_6 pushl %ebp; cfi_adjust_cfa_offset (4); \
|
||||
cfi_rel_offset (ebp, 0); _PUSHCARGS_5
|
||||
# define _POPCARGS_6 _POPCARGS_5; popl %ebp; \
|
||||
cfi_adjust_cfa_offset (-4); cfi_restore (ebp);
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE call __pthread_enable_asynccancel;
|
||||
# define CDISABLE call __pthread_disable_asynccancel
|
||||
# elif IS_IN (libc)
|
||||
# define CENABLE call __libc_enable_asynccancel;
|
||||
# define CDISABLE call __libc_disable_asynccancel
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE call __librt_enable_asynccancel;
|
||||
# define CDISABLE call __librt_disable_asynccancel
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
# define POPSTATE_0 \
|
||||
pushl %eax; cfi_adjust_cfa_offset (4); movl %ecx, %eax; \
|
||||
CDISABLE; popl %eax; cfi_adjust_cfa_offset (-4);
|
||||
# define POPSTATE_1 POPSTATE_0
|
||||
# define POPSTATE_2 xchgl (%esp), %eax; CDISABLE; popl %eax; \
|
||||
cfi_adjust_cfa_offset (-4);
|
||||
# define POPSTATE_3 POPSTATE_2
|
||||
# define POPSTATE_4 POPSTATE_3
|
||||
# define POPSTATE_5 POPSTATE_4
|
||||
# define POPSTATE_6 POPSTATE_5
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P cmpl $0, %gs:MULTIPLE_THREADS_OFFSET
|
||||
# endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
#else
|
||||
|
||||
# define SINGLE_THREAD_P (1)
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
||||
#define RTLD_SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
@ -18,206 +18,15 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# undef PSEUDO
|
||||
|
||||
# if IS_IN (libc)
|
||||
# define SYSDEP_CANCEL_ERRNO __libc_errno
|
||||
# else
|
||||
# define SYSDEP_CANCEL_ERRNO errno
|
||||
# endif
|
||||
# define SYSDEP_CANCEL_ERROR(args) \
|
||||
.section .gnu.linkonce.t.__syscall_error_##args, "ax"; \
|
||||
.align 32; \
|
||||
.proc __syscall_error_##args; \
|
||||
.global __syscall_error_##args; \
|
||||
.hidden __syscall_error_##args; \
|
||||
.size __syscall_error_##args, 64; \
|
||||
__syscall_error_##args: \
|
||||
.prologue; \
|
||||
.regstk args, 5, args, 0; \
|
||||
.save ar.pfs, loc0; \
|
||||
.save rp, loc1; \
|
||||
.body; \
|
||||
addl loc4 = @ltoff(@tprel(SYSDEP_CANCEL_ERRNO)), gp;; \
|
||||
ld8 loc4 = [loc4]; \
|
||||
mov rp = loc1;; \
|
||||
mov r8 = -1; \
|
||||
add loc4 = loc4, r13;; \
|
||||
st4 [loc4] = loc3; \
|
||||
mov ar.pfs = loc0
|
||||
|
||||
# ifndef USE_DL_SYSINFO
|
||||
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.text; \
|
||||
ENTRY (name) \
|
||||
adds r14 = MULTIPLE_THREADS_OFFSET, r13;; \
|
||||
ld4 r14 = [r14]; \
|
||||
mov r15 = SYS_ify(syscall_name);; \
|
||||
cmp4.ne p6, p7 = 0, r14; \
|
||||
(p6) br.cond.spnt .Lpseudo_cancel;; \
|
||||
break __BREAK_SYSCALL;; \
|
||||
cmp.eq p6,p0=-1,r10; \
|
||||
(p6) br.cond.spnt.few __syscall_error; \
|
||||
ret;; \
|
||||
.endp name; \
|
||||
.proc __GC_##name; \
|
||||
.globl __GC_##name; \
|
||||
.hidden __GC_##name; \
|
||||
__GC_##name: \
|
||||
.Lpseudo_cancel: \
|
||||
.prologue; \
|
||||
.regstk args, 5, args, 0; \
|
||||
.save ar.pfs, loc0; \
|
||||
alloc loc0 = ar.pfs, args, 5, args, 0; \
|
||||
.save rp, loc1; \
|
||||
mov loc1 = rp;; \
|
||||
.body; \
|
||||
CENABLE;; \
|
||||
mov loc2 = r8; \
|
||||
COPY_ARGS_##args \
|
||||
mov r15 = SYS_ify(syscall_name); \
|
||||
break __BREAK_SYSCALL;; \
|
||||
mov loc3 = r8; \
|
||||
mov loc4 = r10; \
|
||||
mov out0 = loc2; \
|
||||
CDISABLE;; \
|
||||
cmp.eq p6,p0=-1,loc4; \
|
||||
(p6) br.cond.spnt.few __syscall_error_##args; \
|
||||
mov r8 = loc3; \
|
||||
mov rp = loc1; \
|
||||
mov ar.pfs = loc0; \
|
||||
.Lpseudo_end: \
|
||||
ret; \
|
||||
.endp __GC_##name; \
|
||||
SYSDEP_CANCEL_ERROR(args)
|
||||
|
||||
# else /* USE_DL_SYSINFO */
|
||||
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.text; \
|
||||
ENTRY (name) \
|
||||
.prologue; \
|
||||
adds r2 = SYSINFO_OFFSET, r13; \
|
||||
adds r14 = MULTIPLE_THREADS_OFFSET, r13; \
|
||||
.save ar.pfs, r11; \
|
||||
mov r11 = ar.pfs;; \
|
||||
.body; \
|
||||
ld4 r14 = [r14]; \
|
||||
ld8 r2 = [r2]; \
|
||||
mov r15 = SYS_ify(syscall_name);; \
|
||||
cmp4.ne p6, p7 = 0, r14; \
|
||||
mov b7 = r2; \
|
||||
(p6) br.cond.spnt .Lpseudo_cancel; \
|
||||
br.call.sptk.many b6 = b7;; \
|
||||
mov ar.pfs = r11; \
|
||||
cmp.eq p6,p0 = -1, r10; \
|
||||
(p6) br.cond.spnt.few __syscall_error; \
|
||||
ret;; \
|
||||
.endp name; \
|
||||
\
|
||||
.proc __##syscall_name##_nocancel; \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
__##syscall_name##_nocancel: \
|
||||
.prologue; \
|
||||
adds r2 = SYSINFO_OFFSET, r13; \
|
||||
.save ar.pfs, r11; \
|
||||
mov r11 = ar.pfs;; \
|
||||
.body; \
|
||||
ld8 r2 = [r2]; \
|
||||
mov r15 = SYS_ify(syscall_name);; \
|
||||
mov b7 = r2; \
|
||||
br.call.sptk.many b6 = b7;; \
|
||||
mov ar.pfs = r11; \
|
||||
cmp.eq p6,p0 = -1, r10; \
|
||||
(p6) br.cond.spnt.few __syscall_error; \
|
||||
ret;; \
|
||||
.endp __##syscall_name##_nocancel; \
|
||||
\
|
||||
.proc __GC_##name; \
|
||||
.globl __GC_##name; \
|
||||
.hidden __GC_##name; \
|
||||
__GC_##name: \
|
||||
.Lpseudo_cancel: \
|
||||
.prologue; \
|
||||
.regstk args, 5, args, 0; \
|
||||
.save ar.pfs, loc0; \
|
||||
alloc loc0 = ar.pfs, args, 5, args, 0; \
|
||||
adds loc4 = SYSINFO_OFFSET, r13; \
|
||||
.save rp, loc1; \
|
||||
mov loc1 = rp;; \
|
||||
.body; \
|
||||
ld8 loc4 = [loc4]; \
|
||||
CENABLE;; \
|
||||
mov loc2 = r8; \
|
||||
mov b7 = loc4; \
|
||||
COPY_ARGS_##args \
|
||||
mov r15 = SYS_ify(syscall_name); \
|
||||
br.call.sptk.many b6 = b7;; \
|
||||
mov loc3 = r8; \
|
||||
mov loc4 = r10; \
|
||||
mov out0 = loc2; \
|
||||
CDISABLE;; \
|
||||
cmp.eq p6,p0=-1,loc4; \
|
||||
(p6) br.cond.spnt.few __syscall_error_##args; \
|
||||
mov r8 = loc3; \
|
||||
mov rp = loc1; \
|
||||
mov ar.pfs = loc0; \
|
||||
.Lpseudo_end: \
|
||||
ret; \
|
||||
.endp __GC_##name; \
|
||||
SYSDEP_CANCEL_ERROR(args)
|
||||
|
||||
# endif /* USE_DL_SYSINFO */
|
||||
|
||||
# undef PSEUDO_END
|
||||
# define PSEUDO_END(name) .endp
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE br.call.sptk.many b0 = __pthread_enable_asynccancel
|
||||
# define CDISABLE br.call.sptk.many b0 = __pthread_disable_asynccancel
|
||||
# elif IS_IN (libc)
|
||||
# define CENABLE br.call.sptk.many b0 = __libc_enable_asynccancel
|
||||
# define CDISABLE br.call.sptk.many b0 = __libc_disable_asynccancel
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE br.call.sptk.many b0 = __librt_enable_asynccancel
|
||||
# define CDISABLE br.call.sptk.many b0 = __librt_disable_asynccancel
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
# define COPY_ARGS_0 /* Nothing */
|
||||
# define COPY_ARGS_1 COPY_ARGS_0 mov out0 = in0;
|
||||
# define COPY_ARGS_2 COPY_ARGS_1 mov out1 = in1;
|
||||
# define COPY_ARGS_3 COPY_ARGS_2 mov out2 = in2;
|
||||
# define COPY_ARGS_4 COPY_ARGS_3 mov out3 = in3;
|
||||
# define COPY_ARGS_5 COPY_ARGS_4 mov out4 = in4;
|
||||
# define COPY_ARGS_6 COPY_ARGS_5 mov out5 = in5;
|
||||
# define COPY_ARGS_7 COPY_ARGS_6 mov out6 = in6;
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P \
|
||||
adds r14 = MULTIPLE_THREADS_OFFSET, r13 ;; ld4 r14 = [r14] ;; cmp4.ne p6, p7 = 0, r14
|
||||
# endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
#else
|
||||
# define SINGLE_THREAD_P (1)
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
||||
#define RTLD_SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
@ -18,121 +18,18 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.text; \
|
||||
ENTRY (name) \
|
||||
SINGLE_THREAD_P; \
|
||||
jne .Lpseudo_cancel; \
|
||||
.type __##syscall_name##_nocancel,@function; \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
__##syscall_name##_nocancel: \
|
||||
DO_CALL (syscall_name, args); \
|
||||
cmp.l &-4095, %d0; \
|
||||
jcc SYSCALL_ERROR_LABEL; \
|
||||
rts; \
|
||||
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
||||
.Lpseudo_cancel: \
|
||||
CENABLE; \
|
||||
DOCARGS_##args \
|
||||
move.l %d0, -(%sp); /* Save result of CENABLE. */ \
|
||||
cfi_adjust_cfa_offset (4); \
|
||||
move.l &SYS_ify (syscall_name), %d0; \
|
||||
trap &0; \
|
||||
move.l %d0, %d2; \
|
||||
CDISABLE; \
|
||||
addq.l &4, %sp; /* Remove result of CENABLE from the stack. */ \
|
||||
cfi_adjust_cfa_offset (-4); \
|
||||
move.l %d2, %d0; \
|
||||
UNDOCARGS_##args \
|
||||
cmp.l &-4095, %d0; \
|
||||
jcc SYSCALL_ERROR_LABEL
|
||||
|
||||
/* Note: we use D2 to save syscall's return value as D0 will be clobbered in
|
||||
CDISABLE. */
|
||||
# define DOCARGS_0 move.l %d2, -(%sp); \
|
||||
cfi_adjust_cfa_offset (4); cfi_rel_offset (%d2, 0);
|
||||
# define UNDOCARGS_0 move.l (%sp)+, %d2; \
|
||||
cfi_adjust_cfa_offset (-4); cfi_restore (%d2);
|
||||
|
||||
# define DOCARGS_1 _DOCARGS_1 (4); DOCARGS_0
|
||||
# define _DOCARGS_1(n) move.l n(%sp), %d1;
|
||||
# define UNDOCARGS_1 UNDOCARGS_0
|
||||
|
||||
# define DOCARGS_2 _DOCARGS_2 (8)
|
||||
# define _DOCARGS_2(n) DOCARGS_0 move.l n+4(%sp), %d2; _DOCARGS_1 (n)
|
||||
# define UNDOCARGS_2 UNDOCARGS_0
|
||||
|
||||
# define DOCARGS_3 _DOCARGS_3 (12)
|
||||
# define _DOCARGS_3(n) move.l %d3, -(%sp); \
|
||||
cfi_adjust_cfa_offset (4); cfi_rel_offset (%d3, 0); \
|
||||
move.l n+4(%sp), %d3; _DOCARGS_2 (n)
|
||||
# define UNDOCARGS_3 UNDOCARGS_2 move.l (%sp)+, %d3; \
|
||||
cfi_adjust_cfa_offset (-4); cfi_restore (%d3);
|
||||
|
||||
# define DOCARGS_4 _DOCARGS_4 (16)
|
||||
# define _DOCARGS_4(n) move.l %d4, -(%sp); \
|
||||
cfi_adjust_cfa_offset (4); cfi_rel_offset (%d4, 0); \
|
||||
move.l n+4(%sp), %d4; _DOCARGS_3 (n)
|
||||
# define UNDOCARGS_4 UNDOCARGS_3 move.l (%sp)+, %d4; \
|
||||
cfi_adjust_cfa_offset (-4); cfi_restore (%d4);
|
||||
|
||||
# define DOCARGS_5 _DOCARGS_5 (20)
|
||||
# define _DOCARGS_5(n) move.l %d5, -(%sp); \
|
||||
cfi_adjust_cfa_offset (4); cfi_rel_offset (%d5, 0); \
|
||||
move.l n+4(%sp), %d5; _DOCARGS_4 (n)
|
||||
# define UNDOCARGS_5 UNDOCARGS_4 move.l (%sp)+, %d5; \
|
||||
cfi_adjust_cfa_offset (-4); cfi_restore (%d5);
|
||||
|
||||
# define DOCARGS_6 _DOCARGS_6 (24)
|
||||
# define _DOCARGS_6(n) move.l n(%sp), %a0; _DOCARGS_5 (n-4)
|
||||
# define UNDOCARGS_6 UNDOCARGS_5
|
||||
|
||||
# ifdef PIC
|
||||
# define PSEUDO_JMP(sym) jbsr sym ## @PLTPC
|
||||
# else
|
||||
# define PSEUDO_JMP(sym) jbsr sym
|
||||
# endif
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE PSEUDO_JMP (__pthread_enable_asynccancel)
|
||||
# define CDISABLE PSEUDO_JMP (__pthread_disable_asynccancel)
|
||||
# elif IS_IN (libc)
|
||||
# define CENABLE PSEUDO_JMP (__libc_enable_asynccancel)
|
||||
# define CDISABLE PSEUDO_JMP (__libc_disable_asynccancel)
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE PSEUDO_JMP (__librt_enable_asynccancel)
|
||||
# define CDISABLE PSEUDO_JMP (__librt_disable_asynccancel)
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P \
|
||||
PSEUDO_JMP (__m68k_read_tp); \
|
||||
tst.l MULTIPLE_THREADS_OFFSET(%a0)
|
||||
# endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
#else
|
||||
|
||||
# define SINGLE_THREAD_P (1)
|
||||
# define NO_CANCELLATION (1)
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, \
|
||||
1)
|
||||
#endif
|
||||
#define RTLD_SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
@ -17,142 +17,30 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# if !IS_IN (librt) || !defined(PIC)
|
||||
# define AC_STACK_SIZE 16 /* space for r15, async_cancel arg and 2 temp words */
|
||||
# define AC_SET_GOT /* empty */
|
||||
# define AC_RESTORE_GOT /* empty */
|
||||
# else
|
||||
# define AC_STACK_SIZE 20 /* extra 4 bytes for r20 */
|
||||
# define AC_SET_GOT \
|
||||
swi r20, r1, AC_STACK_SIZE-4; \
|
||||
mfs r20, rpc; \
|
||||
addik r20, r20, _GLOBAL_OFFSET_TABLE_+8;
|
||||
# define AC_RESTORE_GOT \
|
||||
lwi r20, r1, AC_STACK_SIZE-4;
|
||||
# endif
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.text; \
|
||||
ENTRY (name) \
|
||||
SINGLE_THREAD_P(r12); \
|
||||
bnei r12, L(pseudo_cancel); \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
.type __##syscall_name##_nocancel,@function; \
|
||||
__##syscall_name##_nocancel: \
|
||||
DO_CALL (syscall_name, args); \
|
||||
addik r4, r0, -4095; \
|
||||
cmpu r4, r4, r3; \
|
||||
bgei r4, SYSCALL_ERROR_LABEL; \
|
||||
rtsd r15, 8; \
|
||||
nop; \
|
||||
.size __##syscall_name##_nocancel, .-__##syscall_name##_nocancel; \
|
||||
L(pseudo_cancel): \
|
||||
addik r1, r1, -AC_STACK_SIZE; \
|
||||
swi r15, r1, 0; \
|
||||
AC_SET_GOT \
|
||||
DOCARGS_##args \
|
||||
CENABLE; \
|
||||
swi r3, r1, 8; \
|
||||
UNDOCARGS_##args \
|
||||
DO_CALL (syscall_name, args); \
|
||||
swi r3, r1, 12; \
|
||||
lwi r5, r1, 8; \
|
||||
CDISABLE; \
|
||||
lwi r3, r1, 12; \
|
||||
lwi r15, r1, 0; \
|
||||
AC_RESTORE_GOT \
|
||||
addik r1, r1, AC_STACK_SIZE; \
|
||||
addik r4, r0, -4095; \
|
||||
cmpu r4, r4, r3; \
|
||||
bgei r4, SYSCALL_ERROR_LABEL; \
|
||||
rtsd r15, 8; \
|
||||
nop;
|
||||
|
||||
/*
|
||||
* Macros to save/restore syscall arguments across CENABLE
|
||||
* The arguments are saved into the caller's stack (original r1 + 4)
|
||||
*/
|
||||
|
||||
# define DOCARGS_0
|
||||
# define DOCARGS_1 swi r5, r1, AC_STACK_SIZE + 4;
|
||||
# define DOCARGS_2 swi r6, r1, AC_STACK_SIZE + 8; DOCARGS_1
|
||||
# define DOCARGS_3 swi r7, r1, AC_STACK_SIZE + 12; DOCARGS_2
|
||||
# define DOCARGS_4 swi r8, r1, AC_STACK_SIZE + 16; DOCARGS_3
|
||||
# define DOCARGS_5 swi r9, r1, AC_STACK_SIZE + 20; DOCARGS_4
|
||||
# define DOCARGS_6 swi r10, r1, AC_STACK_SIZE + 24; DOCARGS_5
|
||||
|
||||
# define UNDOCARGS_0
|
||||
# define UNDOCARGS_1 lwi r5, r1, AC_STACK_SIZE + 4;
|
||||
# define UNDOCARGS_2 UNDOCARGS_1 lwi r6, r1, AC_STACK_SIZE + 8;
|
||||
# define UNDOCARGS_3 UNDOCARGS_2 lwi r7, r1, AC_STACK_SIZE + 12;
|
||||
# define UNDOCARGS_4 UNDOCARGS_3 lwi r8, r1, AC_STACK_SIZE + 16;
|
||||
# define UNDOCARGS_5 UNDOCARGS_4 lwi r9, r1, AC_STACK_SIZE + 20;
|
||||
# define UNDOCARGS_6 UNDOCARGS_5 lwi r10, r1, AC_STACK_SIZE + 24;
|
||||
|
||||
# ifdef PIC
|
||||
# define PSEUDO_JMP(sym) brlid r15, sym##@PLTPC; addk r0, r0, r0
|
||||
# else
|
||||
# define PSEUDO_JMP(sym) brlid r15, sym; addk r0, r0, r0
|
||||
# endif
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE PSEUDO_JMP (__pthread_enable_asynccancel)
|
||||
# define CDISABLE PSEUDO_JMP (__pthread_disable_asynccancel)
|
||||
# define __local_multiple_threads __pthread_multiple_threads
|
||||
# elif IS_IN (libc)
|
||||
# define CENABLE PSEUDO_JMP (__libc_enable_asynccancel)
|
||||
# define CDISABLE PSEUDO_JMP (__libc_disable_asynccancel)
|
||||
# define __local_multiple_threads __libc_multiple_threads
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE PSEUDO_JMP (__librt_enable_asynccancel)
|
||||
# define CDISABLE PSEUDO_JMP (__librt_disable_asynccancel)
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
|
||||
# if IS_IN (libpthread) || IS_IN (libc)
|
||||
# ifndef __ASSEMBLER__
|
||||
extern int __local_multiple_threads attribute_hidden;
|
||||
# define SINGLE_THREAD_P __builtin_expect (__local_multiple_threads == 0, 1)
|
||||
# else
|
||||
# if !defined PIC
|
||||
# define SINGLE_THREAD_P(reg) lwi reg, r0, __local_multiple_threads;
|
||||
# else
|
||||
# define SINGLE_THREAD_P(reg) \
|
||||
mfs reg, rpc; \
|
||||
addik reg, reg, _GLOBAL_OFFSET_TABLE_+8; \
|
||||
lwi reg, reg, __local_multiple_threads@GOT; \
|
||||
lwi reg, reg, 0;
|
||||
# endif
|
||||
# endif
|
||||
# define SINGLE_THREAD_P __glibc_likely (__local_multiple_threads == 0)
|
||||
# else
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P(reg) \
|
||||
lwi reg, r0, MULTIPLE_THREADS_OFFSET(reg)
|
||||
# endif
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
# endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
#else
|
||||
|
||||
# define SINGLE_THREAD_P (1)
|
||||
# define NO_CANCELLATION (1)
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
||||
#define RTLD_SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
@ -1,249 +0,0 @@
|
||||
/* Copyright (C) 2003-2017 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 <sysdep.h>
|
||||
#include <sysdeps/generic/sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <sys/asm.h>
|
||||
|
||||
/* Gas will put the initial save of $gp into the CIE, because it appears to
|
||||
happen before any instructions. So we use cfi_same_value instead of
|
||||
cfi_restore. */
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
#ifdef __PIC__
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.align 2; \
|
||||
L(pseudo_start): \
|
||||
cfi_startproc; \
|
||||
cfi_adjust_cfa_offset (STKSPACE); \
|
||||
cfi_rel_offset (gp, STKOFF_GP); \
|
||||
99: PTR_LA t9,__syscall_error; \
|
||||
/* manual cpreturn */ \
|
||||
REG_L gp, STKOFF_GP(sp); \
|
||||
cfi_same_value (gp); \
|
||||
RESTORESTK; \
|
||||
jr t9; \
|
||||
.type __##syscall_name##_nocancel, @function; \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
__##syscall_name##_nocancel: \
|
||||
SAVESTK; \
|
||||
.cpsetup t9, STKOFF_GP, __##syscall_name##_nocancel; \
|
||||
cfi_rel_offset (gp, STKOFF_GP); \
|
||||
li v0, SYS_ify(syscall_name); \
|
||||
syscall; \
|
||||
bne a3, zero, SYSCALL_ERROR_LABEL; \
|
||||
/* manual cpreturn */ \
|
||||
REG_L gp, STKOFF_GP(sp); \
|
||||
cfi_same_value (gp); \
|
||||
RESTORESTK; \
|
||||
ret; \
|
||||
cfi_endproc; \
|
||||
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
||||
ENTRY (name) \
|
||||
SAVESTK; \
|
||||
.cpsetup t9, STKOFF_GP, name; \
|
||||
cfi_rel_offset (gp, STKOFF_GP); \
|
||||
SINGLE_THREAD_P(v1); \
|
||||
bne zero, v1, L(pseudo_cancel); \
|
||||
.set noreorder; \
|
||||
li v0, SYS_ify(syscall_name); \
|
||||
syscall; \
|
||||
.set reorder; \
|
||||
bne a3, zero, SYSCALL_ERROR_LABEL; \
|
||||
/* manual cpreturn */ \
|
||||
REG_L gp, STKOFF_GP(sp); \
|
||||
cfi_same_value (gp); \
|
||||
RESTORESTK; \
|
||||
ret; \
|
||||
L(pseudo_cancel): \
|
||||
cfi_adjust_cfa_offset (STKSPACE); \
|
||||
cfi_rel_offset (gp, STKOFF_GP); \
|
||||
REG_S ra, STKOFF_RA(sp); \
|
||||
cfi_rel_offset (ra, STKOFF_RA); \
|
||||
PUSHARGS_##args; /* save syscall args */ \
|
||||
CENABLE; \
|
||||
REG_S v0, STKOFF_SVMSK(sp); /* save mask */ \
|
||||
POPARGS_##args; /* restore syscall args */ \
|
||||
.set noreorder; \
|
||||
li v0, SYS_ify (syscall_name); \
|
||||
syscall; \
|
||||
.set reorder; \
|
||||
REG_S v0, STKOFF_SC_V0(sp); /* save syscall result */ \
|
||||
REG_S a3, STKOFF_SC_ERR(sp); /* save syscall error flag */ \
|
||||
REG_L a0, STKOFF_SVMSK(sp); /* pass mask as arg1 */ \
|
||||
CDISABLE; \
|
||||
REG_L a3, STKOFF_SC_ERR(sp); /* restore syscall error flag */ \
|
||||
REG_L ra, STKOFF_RA(sp); /* restore return address */ \
|
||||
REG_L v0, STKOFF_SC_V0(sp); /* restore syscall result */ \
|
||||
bne a3, zero, SYSCALL_ERROR_LABEL; \
|
||||
/* manual cpreturn */ \
|
||||
REG_L gp, STKOFF_GP(sp); \
|
||||
cfi_same_value (gp); \
|
||||
RESTORESTK; \
|
||||
L(pseudo_end):
|
||||
#else
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.align 2; \
|
||||
L(pseudo_start): \
|
||||
cfi_startproc; \
|
||||
cfi_adjust_cfa_offset (STKSPACE); \
|
||||
99: RESTORESTK; \
|
||||
j __syscall_error; \
|
||||
.type __##syscall_name##_nocancel, @function; \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
__##syscall_name##_nocancel: \
|
||||
SAVESTK; \
|
||||
li v0, SYS_ify(syscall_name); \
|
||||
syscall; \
|
||||
bne a3, zero, SYSCALL_ERROR_LABEL; \
|
||||
RESTORESTK; \
|
||||
ret; \
|
||||
cfi_endproc; \
|
||||
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
||||
ENTRY (name) \
|
||||
SAVESTK; \
|
||||
SINGLE_THREAD_P(v1); \
|
||||
bne zero, v1, L(pseudo_cancel); \
|
||||
.set noreorder; \
|
||||
li v0, SYS_ify(syscall_name); \
|
||||
syscall; \
|
||||
.set reorder; \
|
||||
bne a3, zero, SYSCALL_ERROR_LABEL; \
|
||||
RESTORESTK; \
|
||||
ret; \
|
||||
L(pseudo_cancel): \
|
||||
cfi_adjust_cfa_offset (STKSPACE); \
|
||||
REG_S ra, STKOFF_RA(sp); \
|
||||
cfi_rel_offset (ra, STKOFF_RA); \
|
||||
PUSHARGS_##args; /* save syscall args */ \
|
||||
CENABLE; \
|
||||
REG_S v0, STKOFF_SVMSK(sp); /* save mask */ \
|
||||
POPARGS_##args; /* restore syscall args */ \
|
||||
.set noreorder; \
|
||||
li v0, SYS_ify (syscall_name); \
|
||||
syscall; \
|
||||
.set reorder; \
|
||||
REG_S v0, STKOFF_SC_V0(sp); /* save syscall result */ \
|
||||
REG_S a3, STKOFF_SC_ERR(sp); /* save syscall error flag */ \
|
||||
REG_L a0, STKOFF_SVMSK(sp); /* pass mask as arg1 */ \
|
||||
CDISABLE; \
|
||||
REG_L a3, STKOFF_SC_ERR(sp); /* restore syscall error flag */ \
|
||||
REG_L ra, STKOFF_RA(sp); /* restore return address */ \
|
||||
REG_L v0, STKOFF_SC_V0(sp); /* restore syscall result */ \
|
||||
bne a3, zero, SYSCALL_ERROR_LABEL; \
|
||||
RESTORESTK; \
|
||||
L(pseudo_end):
|
||||
#endif
|
||||
|
||||
# undef PSEUDO_END
|
||||
# define PSEUDO_END(sym) cfi_endproc; .end sym; .size sym,.-sym
|
||||
|
||||
# define PUSHARGS_0 /* nothing to do */
|
||||
# define PUSHARGS_1 PUSHARGS_0 REG_S a0, STKOFF_A0(sp); cfi_rel_offset (a0, STKOFF_A0);
|
||||
# define PUSHARGS_2 PUSHARGS_1 REG_S a1, STKOFF_A1(sp); cfi_rel_offset (a1, STKOFF_A1);
|
||||
# define PUSHARGS_3 PUSHARGS_2 REG_S a2, STKOFF_A2(sp); cfi_rel_offset (a2, STKOFF_A2);
|
||||
# define PUSHARGS_4 PUSHARGS_3 REG_S a3, STKOFF_A3(sp); cfi_rel_offset (a3, STKOFF_A3);
|
||||
# define PUSHARGS_5 PUSHARGS_4 REG_S a4, STKOFF_A4(sp); cfi_rel_offset (a3, STKOFF_A4);
|
||||
# define PUSHARGS_6 PUSHARGS_5 REG_S a5, STKOFF_A5(sp); cfi_rel_offset (a3, STKOFF_A5);
|
||||
|
||||
# define POPARGS_0 /* nothing to do */
|
||||
# define POPARGS_1 POPARGS_0 REG_L a0, STKOFF_A0(sp);
|
||||
# define POPARGS_2 POPARGS_1 REG_L a1, STKOFF_A1(sp);
|
||||
# define POPARGS_3 POPARGS_2 REG_L a2, STKOFF_A2(sp);
|
||||
# define POPARGS_4 POPARGS_3 REG_L a3, STKOFF_A3(sp);
|
||||
# define POPARGS_5 POPARGS_4 REG_L a4, STKOFF_A4(sp);
|
||||
# define POPARGS_6 POPARGS_5 REG_L a5, STKOFF_A5(sp);
|
||||
|
||||
/* Save an even number of slots. Should be 0 if an even number of slots
|
||||
are used below, or SZREG if an odd number are used. */
|
||||
# ifdef __PIC__
|
||||
# define STK_PAD SZREG
|
||||
# else
|
||||
# define STK_PAD 0
|
||||
# endif
|
||||
|
||||
/* Place values that we are more likely to use later in this sequence, i.e.
|
||||
closer to the SP at function entry. If you do that, the are more
|
||||
likely to already be in your d-cache. */
|
||||
# define STKOFF_A5 (STK_PAD)
|
||||
# define STKOFF_A4 (STKOFF_A5 + SZREG)
|
||||
# define STKOFF_A3 (STKOFF_A4 + SZREG)
|
||||
# define STKOFF_A2 (STKOFF_A3 + SZREG) /* MT and more args. */
|
||||
# define STKOFF_A1 (STKOFF_A2 + SZREG) /* MT and 2 args. */
|
||||
# define STKOFF_A0 (STKOFF_A1 + SZREG) /* MT and 1 arg. */
|
||||
# define STKOFF_RA (STKOFF_A0 + SZREG) /* Used if MT. */
|
||||
# define STKOFF_SC_V0 (STKOFF_RA + SZREG) /* Used if MT. */
|
||||
# define STKOFF_SC_ERR (STKOFF_SC_V0 + SZREG) /* Used if MT. */
|
||||
# define STKOFF_SVMSK (STKOFF_SC_ERR + SZREG) /* Used if MT. */
|
||||
|
||||
# ifdef __PIC__
|
||||
# define STKOFF_GP (STKOFF_SVMSK + SZREG) /* Always used. */
|
||||
# define STKSPACE (STKOFF_GP + SZREG)
|
||||
# else
|
||||
# define STKSPACE (STKOFF_SVMSK + SZREG)
|
||||
# endif
|
||||
|
||||
# define SAVESTK PTR_SUBU sp, STKSPACE; cfi_adjust_cfa_offset(STKSPACE)
|
||||
# define RESTORESTK PTR_ADDU sp, STKSPACE; cfi_adjust_cfa_offset(-STKSPACE)
|
||||
|
||||
# ifdef __PIC__
|
||||
# define PSEUDO_JMP(sym) PTR_LA t9, sym; jalr t9
|
||||
# else
|
||||
# define PSEUDO_JMP(sym) jal sym
|
||||
# endif
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE PSEUDO_JMP (__pthread_enable_asynccancel)
|
||||
# define CDISABLE PSEUDO_JMP (__pthread_disable_asynccancel)
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE PSEUDO_JMP (__librt_enable_asynccancel)
|
||||
# define CDISABLE PSEUDO_JMP (__librt_disable_asynccancel)
|
||||
# else
|
||||
# define CENABLE PSEUDO_JMP (__libc_enable_asynccancel)
|
||||
# define CDISABLE PSEUDO_JMP (__libc_disable_asynccancel)
|
||||
# endif
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) \
|
||||
== 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P(reg) \
|
||||
READ_THREAD_POINTER(reg); \
|
||||
lw reg, MULTIPLE_THREADS_OFFSET(reg)
|
||||
#endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
|
||||
# define SINGLE_THREAD_P 1
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
@ -18,173 +18,19 @@
|
||||
#include <sysdep.h>
|
||||
#include <sysdeps/generic/sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# ifdef __PIC__
|
||||
# define PSEUDO_CPLOAD .cpload t9;
|
||||
# define PSEUDO_ERRJMP la t9, __syscall_error; jr t9;
|
||||
# define PSEUDO_SAVEGP sw gp, 32(sp); cfi_rel_offset (gp, 32);
|
||||
# define PSEUDO_LOADGP lw gp, 32(sp);
|
||||
# else
|
||||
# define PSEUDO_CPLOAD
|
||||
# define PSEUDO_ERRJMP j __syscall_error;
|
||||
# define PSEUDO_SAVEGP
|
||||
# define PSEUDO_LOADGP
|
||||
# endif
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.align 2; \
|
||||
.set nomips16; \
|
||||
L(pseudo_start): \
|
||||
cfi_startproc; \
|
||||
99: PSEUDO_ERRJMP \
|
||||
.type __##syscall_name##_nocancel, @function; \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
__##syscall_name##_nocancel: \
|
||||
.set noreorder; \
|
||||
PSEUDO_CPLOAD \
|
||||
li v0, SYS_ify(syscall_name); \
|
||||
syscall; \
|
||||
.set reorder; \
|
||||
bne a3, zero, 99b; \
|
||||
ret; \
|
||||
cfi_endproc; \
|
||||
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
||||
ENTRY (name) \
|
||||
.set noreorder; \
|
||||
PSEUDO_CPLOAD \
|
||||
.set reorder; \
|
||||
SINGLE_THREAD_P(v1); \
|
||||
bne zero, v1, L(pseudo_cancel); \
|
||||
.set noreorder; \
|
||||
li v0, SYS_ify(syscall_name); \
|
||||
syscall; \
|
||||
.set reorder; \
|
||||
bne a3, zero, 99b; \
|
||||
ret; \
|
||||
L(pseudo_cancel): \
|
||||
SAVESTK_##args; \
|
||||
sw ra, 28(sp); \
|
||||
cfi_rel_offset (ra, 28); \
|
||||
PSEUDO_SAVEGP \
|
||||
PUSHARGS_##args; /* save syscall args */ \
|
||||
CENABLE; \
|
||||
PSEUDO_LOADGP \
|
||||
sw v0, 44(sp); /* save mask */ \
|
||||
POPARGS_##args; /* restore syscall args */ \
|
||||
.set noreorder; \
|
||||
li v0, SYS_ify (syscall_name); \
|
||||
syscall; \
|
||||
.set reorder; \
|
||||
sw v0, 36(sp); /* save syscall result */ \
|
||||
sw a3, 40(sp); /* save syscall error flag */ \
|
||||
lw a0, 44(sp); /* pass mask as arg1 */ \
|
||||
CDISABLE; \
|
||||
PSEUDO_LOADGP \
|
||||
lw v0, 36(sp); /* restore syscall result */ \
|
||||
lw a3, 40(sp); /* restore syscall error flag */ \
|
||||
lw ra, 28(sp); /* restore return address */ \
|
||||
.set noreorder; \
|
||||
bne a3, zero, 99b; \
|
||||
RESTORESTK; \
|
||||
L(pseudo_end): \
|
||||
.set reorder;
|
||||
|
||||
# undef PSEUDO_END
|
||||
# define PSEUDO_END(sym) cfi_endproc; .end sym; .size sym,.-sym
|
||||
|
||||
# define PUSHARGS_0 /* nothing to do */
|
||||
# define PUSHARGS_1 PUSHARGS_0 sw a0, 0(sp); cfi_rel_offset (a0, 0);
|
||||
# define PUSHARGS_2 PUSHARGS_1 sw a1, 4(sp); cfi_rel_offset (a1, 4);
|
||||
# define PUSHARGS_3 PUSHARGS_2 sw a2, 8(sp); cfi_rel_offset (a2, 8);
|
||||
# define PUSHARGS_4 PUSHARGS_3 sw a3, 12(sp); cfi_rel_offset (a3, 12);
|
||||
# define PUSHARGS_5 PUSHARGS_4 /* handled by SAVESTK_## */
|
||||
# define PUSHARGS_6 PUSHARGS_5
|
||||
# define PUSHARGS_7 PUSHARGS_6
|
||||
|
||||
# define POPARGS_0 /* nothing to do */
|
||||
# define POPARGS_1 POPARGS_0 lw a0, 0(sp);
|
||||
# define POPARGS_2 POPARGS_1 lw a1, 4(sp);
|
||||
# define POPARGS_3 POPARGS_2 lw a2, 8(sp);
|
||||
# define POPARGS_4 POPARGS_3 lw a3, 12(sp);
|
||||
# define POPARGS_5 POPARGS_4 /* args already in new stackframe */
|
||||
# define POPARGS_6 POPARGS_5
|
||||
# define POPARGS_7 POPARGS_6
|
||||
|
||||
|
||||
# define STKSPACE 48
|
||||
# define SAVESTK_0 subu sp, STKSPACE; cfi_adjust_cfa_offset(STKSPACE)
|
||||
# define SAVESTK_1 SAVESTK_0
|
||||
# define SAVESTK_2 SAVESTK_1
|
||||
# define SAVESTK_3 SAVESTK_2
|
||||
# define SAVESTK_4 SAVESTK_3
|
||||
# define SAVESTK_5 lw t0, 16(sp); \
|
||||
SAVESTK_0; \
|
||||
sw t0, 16(sp)
|
||||
|
||||
# define SAVESTK_6 lw t0, 16(sp); \
|
||||
lw t1, 20(sp); \
|
||||
SAVESTK_0; \
|
||||
sw t0, 16(sp); \
|
||||
sw t1, 20(sp)
|
||||
|
||||
# define SAVESTK_7 lw t0, 16(sp); \
|
||||
lw t1, 20(sp); \
|
||||
lw t2, 24(sp); \
|
||||
SAVESTK_0; \
|
||||
sw t0, 16(sp); \
|
||||
sw t1, 20(sp); \
|
||||
sw t2, 24(sp)
|
||||
|
||||
# define RESTORESTK addu sp, STKSPACE; cfi_adjust_cfa_offset(-STKSPACE)
|
||||
|
||||
|
||||
# ifdef __PIC__
|
||||
/* We use jalr rather than jal. This means that the assembler will not
|
||||
automatically restore $gp (in case libc has multiple GOTs) so we must
|
||||
do it manually - which we have to do anyway since we don't use .cprestore.
|
||||
It also shuts up the assembler warning about not using .cprestore. */
|
||||
# define PSEUDO_JMP(sym) la t9, sym; jalr t9;
|
||||
# else
|
||||
# define PSEUDO_JMP(sym) jal sym;
|
||||
# endif
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE PSEUDO_JMP (__pthread_enable_asynccancel)
|
||||
# define CDISABLE PSEUDO_JMP (__pthread_disable_asynccancel)
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE PSEUDO_JMP (__librt_enable_asynccancel)
|
||||
# define CDISABLE PSEUDO_JMP (__librt_disable_asynccancel)
|
||||
# else
|
||||
# define CENABLE PSEUDO_JMP (__libc_enable_asynccancel)
|
||||
# define CDISABLE PSEUDO_JMP (__libc_disable_asynccancel)
|
||||
# endif
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) \
|
||||
== 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P(reg) \
|
||||
READ_THREAD_POINTER(reg); \
|
||||
lw reg, MULTIPLE_THREADS_OFFSET(reg)
|
||||
#endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
#else
|
||||
|
||||
# define SINGLE_THREAD_P 1
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
||||
#define RTLD_SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
@ -18,124 +18,19 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.type __##syscall_name##_nocancel, @function; \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
__##syscall_name##_nocancel: \
|
||||
cfi_startproc; \
|
||||
DO_CALL (syscall_name, args); \
|
||||
bne r7, zero, SYSCALL_ERROR_LABEL; \
|
||||
ret; \
|
||||
cfi_endproc; \
|
||||
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
||||
ENTRY (name) \
|
||||
SINGLE_THREAD_P(r2); \
|
||||
bne r2, zero, pseudo_cancel; \
|
||||
DO_CALL (syscall_name, args); \
|
||||
bne r7, zero, SYSCALL_ERROR_LABEL; \
|
||||
ret; \
|
||||
pseudo_cancel: \
|
||||
SAVESTK_##args; /* save syscall args and adjust stack */ \
|
||||
SAVEREG(ra, 0); /* save return address */ \
|
||||
SAVEREG(r22, 4); /* save GOT pointer */ \
|
||||
nextpc r22; \
|
||||
1: movhi r2, %hiadj(_gp_got - 1b); \
|
||||
addi r2, r2, %lo(_gp_got - 1b); \
|
||||
add r22, r22, r2; \
|
||||
CENABLE; \
|
||||
callr r3; \
|
||||
stw r2, 8(sp); /* save mask */ \
|
||||
LOADARGS_##args; \
|
||||
movi r2, SYS_ify(syscall_name); \
|
||||
trap; \
|
||||
stw r2, 12(sp); /* save syscall result */ \
|
||||
stw r7, 16(sp); /* save syscall error flag */ \
|
||||
ldw r4, 8(sp); /* pass mask as argument 1 */ \
|
||||
CDISABLE; \
|
||||
callr r3; \
|
||||
ldw r7, 16(sp); /* restore syscall error flag */ \
|
||||
ldw r2, 12(sp); /* restore syscall result */ \
|
||||
ldw ra, 0(sp); /* restore return address */ \
|
||||
ldw r22, 4(sp); /* restore GOT pointer */ \
|
||||
RESTORESTK_##args; \
|
||||
bne r7, zero, SYSCALL_ERROR_LABEL;
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
||||
|
||||
# undef PSEUDO_END
|
||||
# define PSEUDO_END(sym) \
|
||||
SYSCALL_ERROR_HANDLER \
|
||||
END (sym)
|
||||
|
||||
#define SAVEREG(REG, LOC) stw REG, LOC(sp); cfi_rel_offset (REG, LOC)
|
||||
#define SAVESTK(X) subi sp, sp, X; cfi_adjust_cfa_offset(X)
|
||||
#define SAVESTK_0 SAVESTK(20)
|
||||
#define SAVEARG_1 SAVEREG(r4, 20)
|
||||
#define SAVESTK_1 SAVESTK(24); SAVEARG_1
|
||||
#define SAVEARG_2 SAVEREG(r5, 24); SAVEARG_1
|
||||
#define SAVESTK_2 SAVESTK(28); SAVEARG_2
|
||||
#define SAVEARG_3 SAVEREG(r6, 28); SAVEARG_2
|
||||
#define SAVESTK_3 SAVESTK(32); SAVEARG_3
|
||||
#define SAVEARG_4 SAVEREG(r7, 32); SAVEARG_3
|
||||
#define SAVESTK_4 SAVESTK(36); SAVEARG_4
|
||||
#define SAVESTK_5 SAVESTK_4
|
||||
#define SAVESTK_6 SAVESTK_5
|
||||
|
||||
#define LOADARGS_0
|
||||
#define LOADARGS_1 ldw r4, 20(sp)
|
||||
#define LOADARGS_2 LOADARGS_1; ldw r5, 24(sp)
|
||||
#define LOADARGS_3 LOADARGS_2; ldw r6, 28(sp)
|
||||
#define LOADARGS_4 LOADARGS_3; ldw r7, 32(sp)
|
||||
#define LOADARGS_5 LOADARGS_4; ldw r8, 36(sp)
|
||||
#define LOADARGS_6 LOADARGS_5; ldw r9, 40(sp)
|
||||
|
||||
#define RESTORESTK(X) addi sp, sp, X; cfi_adjust_cfa_offset(-X)
|
||||
#define RESTORESTK_0 RESTORESTK(20)
|
||||
#define RESTORESTK_1 RESTORESTK(24)
|
||||
#define RESTORESTK_2 RESTORESTK(28)
|
||||
#define RESTORESTK_3 RESTORESTK(32)
|
||||
#define RESTORESTK_4 RESTORESTK(36)
|
||||
#define RESTORESTK_5 RESTORESTK(36)
|
||||
#define RESTORESTK_6 RESTORESTK(36)
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE ldw r3, %call(__pthread_enable_asynccancel)(r22)
|
||||
# define CDISABLE ldw r3, %call(__pthread_disable_asynccancel)(r22)
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE ldw r3, %call(__librt_enable_asynccancel)(r22)
|
||||
# define CDISABLE ldw r3, %call(__librt_disable_asynccancel)(r22)
|
||||
# elif IS_IN (libc)
|
||||
# define CENABLE ldw r3, %call(__libc_enable_asynccancel)(r22)
|
||||
# define CDISABLE ldw r3, %call(__libc_disable_asynccancel)(r22)
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) \
|
||||
== 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P(reg) \
|
||||
ldw reg, MULTIPLE_THREADS_OFFSET(r23)
|
||||
#endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
#else
|
||||
|
||||
# define SINGLE_THREAD_P 1
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
||||
#define RTLD_SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
@ -1,118 +0,0 @@
|
||||
/* Cancellable system call stubs. Linux/PowerPC version.
|
||||
Copyright (C) 2003-2017 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.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/>. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.section ".text"; \
|
||||
ENTRY (name) \
|
||||
SINGLE_THREAD_P; \
|
||||
bne- .Lpseudo_cancel; \
|
||||
.type __##syscall_name##_nocancel,@function; \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
__##syscall_name##_nocancel: \
|
||||
DO_CALL (SYS_ify (syscall_name)); \
|
||||
PSEUDO_RET; \
|
||||
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
||||
.Lpseudo_cancel: \
|
||||
stwu 1,-48(1); \
|
||||
cfi_adjust_cfa_offset (48); \
|
||||
mflr 9; \
|
||||
stw 9,52(1); \
|
||||
cfi_offset (lr, 4); \
|
||||
DOCARGS_##args; /* save syscall args around CENABLE. */ \
|
||||
CENABLE; \
|
||||
stw 3,16(1); /* store CENABLE return value (MASK). */ \
|
||||
UNDOCARGS_##args; /* restore syscall args. */ \
|
||||
DO_CALL (SYS_ify (syscall_name)); \
|
||||
mfcr 0; /* save CR/R3 around CDISABLE. */ \
|
||||
stw 3,8(1); \
|
||||
stw 0,12(1); \
|
||||
lwz 3,16(1); /* pass MASK to CDISABLE. */ \
|
||||
CDISABLE; \
|
||||
lwz 4,52(1); \
|
||||
lwz 0,12(1); /* restore CR/R3. */ \
|
||||
lwz 3,8(1); \
|
||||
mtlr 4; \
|
||||
mtcr 0; \
|
||||
addi 1,1,48;
|
||||
|
||||
# define DOCARGS_0
|
||||
# define UNDOCARGS_0
|
||||
|
||||
# define DOCARGS_1 stw 3,20(1); DOCARGS_0
|
||||
# define UNDOCARGS_1 lwz 3,20(1); UNDOCARGS_0
|
||||
|
||||
# define DOCARGS_2 stw 4,24(1); DOCARGS_1
|
||||
# define UNDOCARGS_2 lwz 4,24(1); UNDOCARGS_1
|
||||
|
||||
# define DOCARGS_3 stw 5,28(1); DOCARGS_2
|
||||
# define UNDOCARGS_3 lwz 5,28(1); UNDOCARGS_2
|
||||
|
||||
# define DOCARGS_4 stw 6,32(1); DOCARGS_3
|
||||
# define UNDOCARGS_4 lwz 6,32(1); UNDOCARGS_3
|
||||
|
||||
# define DOCARGS_5 stw 7,36(1); DOCARGS_4
|
||||
# define UNDOCARGS_5 lwz 7,36(1); UNDOCARGS_4
|
||||
|
||||
# define DOCARGS_6 stw 8,40(1); DOCARGS_5
|
||||
# define UNDOCARGS_6 lwz 8,40(1); UNDOCARGS_5
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE bl __pthread_enable_asynccancel@local
|
||||
# define CDISABLE bl __pthread_disable_asynccancel@local
|
||||
# elif IS_IN (libc)
|
||||
# define CENABLE bl __libc_enable_asynccancel@local
|
||||
# define CDISABLE bl __libc_disable_asynccancel@local
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE bl __librt_enable_asynccancel@local
|
||||
# define CDISABLE bl __librt_disable_asynccancel@local
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P \
|
||||
lwz 10,MULTIPLE_THREADS_OFFSET(2); \
|
||||
cmpwi 10,0
|
||||
# endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
|
||||
# define SINGLE_THREAD_P (1)
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
@ -1,147 +0,0 @@
|
||||
/* Cancellable system call stubs. Linux/PowerPC64 version.
|
||||
Copyright (C) 2003-2017 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Franz Sirl <Franz.Sirl-kernel@lauterbach.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/>. */
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# define DASHDASHPFX(str) __##str
|
||||
|
||||
#if _CALL_ELF == 2
|
||||
#define CANCEL_FRAMESIZE (FRAME_MIN_SIZE+16+48)
|
||||
#define CANCEL_PARM_SAVE (FRAME_MIN_SIZE+16)
|
||||
#else
|
||||
#define CANCEL_FRAMESIZE (FRAME_MIN_SIZE+16)
|
||||
#define CANCEL_PARM_SAVE (CANCEL_FRAMESIZE+FRAME_PARM_SAVE)
|
||||
#endif
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.section ".text"; \
|
||||
ENTRY (name) \
|
||||
SINGLE_THREAD_P; \
|
||||
bne- .Lpseudo_cancel; \
|
||||
.type DASHDASHPFX(syscall_name##_nocancel),@function; \
|
||||
.globl DASHDASHPFX(syscall_name##_nocancel); \
|
||||
DASHDASHPFX(syscall_name##_nocancel): \
|
||||
DO_CALL (SYS_ify (syscall_name)); \
|
||||
PSEUDO_RET; \
|
||||
.size DASHDASHPFX(syscall_name##_nocancel),.-DASHDASHPFX(syscall_name##_nocancel); \
|
||||
.Lpseudo_cancel: \
|
||||
stdu 1,-CANCEL_FRAMESIZE(1); \
|
||||
cfi_adjust_cfa_offset (CANCEL_FRAMESIZE); \
|
||||
mflr 9; \
|
||||
std 9,CANCEL_FRAMESIZE+FRAME_LR_SAVE(1); \
|
||||
cfi_offset (lr, FRAME_LR_SAVE); \
|
||||
DOCARGS_##args; /* save syscall args around CENABLE. */ \
|
||||
CENABLE; \
|
||||
std 3,FRAME_MIN_SIZE(1); /* store CENABLE return value (MASK). */ \
|
||||
UNDOCARGS_##args; /* restore syscall args. */ \
|
||||
DO_CALL (SYS_ify (syscall_name)); \
|
||||
mfcr 0; /* save CR/R3 around CDISABLE. */ \
|
||||
std 3,FRAME_MIN_SIZE+8(1); \
|
||||
std 0,CANCEL_FRAMESIZE+FRAME_CR_SAVE(1); \
|
||||
cfi_offset (cr, FRAME_CR_SAVE); \
|
||||
ld 3,FRAME_MIN_SIZE(1); /* pass MASK to CDISABLE. */ \
|
||||
CDISABLE; \
|
||||
ld 9,CANCEL_FRAMESIZE+FRAME_LR_SAVE(1); \
|
||||
ld 0,CANCEL_FRAMESIZE+FRAME_CR_SAVE(1); /* restore CR/R3. */ \
|
||||
ld 3,FRAME_MIN_SIZE+8(1); \
|
||||
mtlr 9; \
|
||||
mtcr 0; \
|
||||
addi 1,1,CANCEL_FRAMESIZE; \
|
||||
cfi_adjust_cfa_offset (-CANCEL_FRAMESIZE); \
|
||||
cfi_restore (lr); \
|
||||
cfi_restore (cr)
|
||||
|
||||
# define DOCARGS_0
|
||||
# define UNDOCARGS_0
|
||||
|
||||
# define DOCARGS_1 std 3,CANCEL_PARM_SAVE(1); DOCARGS_0
|
||||
# define UNDOCARGS_1 ld 3,CANCEL_PARM_SAVE(1); UNDOCARGS_0
|
||||
|
||||
# define DOCARGS_2 std 4,CANCEL_PARM_SAVE+8(1); DOCARGS_1
|
||||
# define UNDOCARGS_2 ld 4,CANCEL_PARM_SAVE+8(1); UNDOCARGS_1
|
||||
|
||||
# define DOCARGS_3 std 5,CANCEL_PARM_SAVE+16(1); DOCARGS_2
|
||||
# define UNDOCARGS_3 ld 5,CANCEL_PARM_SAVE+16(1); UNDOCARGS_2
|
||||
|
||||
# define DOCARGS_4 std 6,CANCEL_PARM_SAVE+24(1); DOCARGS_3
|
||||
# define UNDOCARGS_4 ld 6,CANCEL_PARM_SAVE+24(1); UNDOCARGS_3
|
||||
|
||||
# define DOCARGS_5 std 7,CANCEL_PARM_SAVE+32(1); DOCARGS_4
|
||||
# define UNDOCARGS_5 ld 7,CANCEL_PARM_SAVE+32(1); UNDOCARGS_4
|
||||
|
||||
# define DOCARGS_6 std 8,CANCEL_PARM_SAVE+40(1); DOCARGS_5
|
||||
# define UNDOCARGS_6 ld 8,CANCEL_PARM_SAVE+40(1); UNDOCARGS_5
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# ifdef SHARED
|
||||
# define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel)
|
||||
# define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel)
|
||||
# else
|
||||
# define CENABLE bl JUMPTARGET(__pthread_enable_asynccancel); nop
|
||||
# define CDISABLE bl JUMPTARGET(__pthread_disable_asynccancel); nop
|
||||
# endif
|
||||
# elif IS_IN (libc)
|
||||
# ifdef SHARED
|
||||
# define CENABLE bl JUMPTARGET(__libc_enable_asynccancel)
|
||||
# define CDISABLE bl JUMPTARGET(__libc_disable_asynccancel)
|
||||
# else
|
||||
# define CENABLE bl JUMPTARGET(__libc_enable_asynccancel); nop
|
||||
# define CDISABLE bl JUMPTARGET(__libc_disable_asynccancel); nop
|
||||
# endif
|
||||
# elif IS_IN (librt)
|
||||
# ifdef SHARED
|
||||
# define CENABLE bl JUMPTARGET(__librt_enable_asynccancel)
|
||||
# define CDISABLE bl JUMPTARGET(__librt_disable_asynccancel)
|
||||
# else
|
||||
# define CENABLE bl JUMPTARGET(__librt_enable_asynccancel); nop
|
||||
# define CDISABLE bl JUMPTARGET(__librt_disable_asynccancel); nop
|
||||
# endif
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P \
|
||||
lwz 10,MULTIPLE_THREADS_OFFSET(13); \
|
||||
cmpwi 10,0
|
||||
# endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
|
||||
# define SINGLE_THREAD_P (1)
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
36
sysdeps/unix/sysv/linux/powerpc/sysdep-cancel.h
Normal file
36
sysdeps/unix/sysv/linux/powerpc/sysdep-cancel.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* Cancellable system call stubs. Linux/PowerPC version.
|
||||
Copyright (C) 2017 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 <sysdep.h>
|
||||
#include <tls.h>
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
||||
#else
|
||||
|
||||
# define SINGLE_THREAD_P (1)
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#define RTLD_SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
@ -18,122 +18,19 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.text; \
|
||||
L(pseudo_cancel): \
|
||||
cfi_startproc; \
|
||||
STM_##args \
|
||||
stm %r12,%r15,48(%r15); \
|
||||
cfi_offset (%r15, -36); \
|
||||
cfi_offset (%r14, -40); \
|
||||
cfi_offset (%r13, -44); \
|
||||
cfi_offset (%r12, -48); \
|
||||
lr %r14,%r15; \
|
||||
ahi %r15,-96; \
|
||||
cfi_adjust_cfa_offset (96); \
|
||||
st %r14,0(%r15); \
|
||||
basr %r13,0; \
|
||||
0: l %r1,1f-0b(%r13); \
|
||||
bas %r14,0(%r1,%r13); \
|
||||
lr %r0,%r2; \
|
||||
LM_##args \
|
||||
.if SYS_ify (syscall_name) < 256; \
|
||||
svc SYS_ify (syscall_name); \
|
||||
.else; \
|
||||
lhi %r1,SYS_ify (syscall_name); \
|
||||
svc 0; \
|
||||
.endif; \
|
||||
LR7_##args \
|
||||
l %r1,2f-0b(%r13); \
|
||||
lr %r12,%r2; \
|
||||
lr %r2,%r0; \
|
||||
bas %r14,0(%r1,%r13); \
|
||||
lr %r2,%r12; \
|
||||
lm %r12,%r15,48+96(%r15); \
|
||||
cfi_endproc; \
|
||||
j L(pseudo_check); \
|
||||
1: .long CENABLE-0b; \
|
||||
2: .long CDISABLE-0b; \
|
||||
ENTRY(name) \
|
||||
SINGLE_THREAD_P(%r1) \
|
||||
jne L(pseudo_cancel); \
|
||||
.type __##syscall_name##_nocancel,@function; \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
__##syscall_name##_nocancel: \
|
||||
DO_CALL(syscall_name, args); \
|
||||
L(pseudo_check): \
|
||||
lhi %r4,-4095; \
|
||||
clr %r2,%r4; \
|
||||
jnl SYSCALL_ERROR_LABEL; \
|
||||
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
||||
L(pseudo_end):
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE __pthread_enable_asynccancel
|
||||
# define CDISABLE __pthread_disable_asynccancel
|
||||
# elif IS_IN (libc)
|
||||
# define CENABLE __libc_enable_asynccancel
|
||||
# define CDISABLE __libc_disable_asynccancel
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE __librt_enable_asynccancel
|
||||
# define CDISABLE __librt_disable_asynccancel
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
#define STM_0 /* Nothing */
|
||||
#define STM_1 st %r2,8(%r15);
|
||||
#define STM_2 stm %r2,%r3,8(%r15);
|
||||
#define STM_3 stm %r2,%r4,8(%r15);
|
||||
#define STM_4 stm %r2,%r5,8(%r15);
|
||||
#define STM_5 stm %r2,%r5,8(%r15);
|
||||
#define STM_6 stm %r2,%r7,8(%r15);
|
||||
|
||||
#define LM_0 /* Nothing */
|
||||
#define LM_1 l %r2,8+96(%r15);
|
||||
#define LM_2 lm %r2,%r3,8+96(%r15);
|
||||
#define LM_3 lm %r2,%r4,8+96(%r15);
|
||||
#define LM_4 lm %r2,%r5,8+96(%r15);
|
||||
#define LM_5 lm %r2,%r5,8+96(%r15);
|
||||
#define LM_6 lm %r2,%r5,8+96(%r15); \
|
||||
cfi_offset (%r7, -68); \
|
||||
l %r7,96+96(%r15);
|
||||
|
||||
#define LR7_0 /* Nothing */
|
||||
#define LR7_1 /* Nothing */
|
||||
#define LR7_2 /* Nothing */
|
||||
#define LR7_3 /* Nothing */
|
||||
#define LR7_4 /* Nothing */
|
||||
#define LR7_5 /* Nothing */
|
||||
#define LR7_6 l %r7,28+96(%r15); \
|
||||
cfi_restore (%r7);
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P(reg) \
|
||||
ear reg,%a0; \
|
||||
icm reg,15,MULTIPLE_THREADS_OFFSET(reg);
|
||||
# endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
#else
|
||||
|
||||
# define SINGLE_THREAD_P (1)
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
||||
#define RTLD_SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
@ -18,135 +18,34 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.text; \
|
||||
L(pseudo_cancel): \
|
||||
cfi_startproc; \
|
||||
STM_##args \
|
||||
stmg %r13,%r15,104(%r15); \
|
||||
cfi_offset (%r15,-40); \
|
||||
cfi_offset (%r14,-48); \
|
||||
cfi_offset (%r13,-56); \
|
||||
lgr %r14,%r15; \
|
||||
aghi %r15,-160; \
|
||||
cfi_adjust_cfa_offset (160); \
|
||||
stg %r14,0(%r15); \
|
||||
brasl %r14,CENABLE; \
|
||||
lgr %r0,%r2; \
|
||||
LM_##args \
|
||||
.if SYS_ify (syscall_name) < 256; \
|
||||
svc SYS_ify (syscall_name); \
|
||||
.else; \
|
||||
lghi %r1,SYS_ify (syscall_name); \
|
||||
svc 0; \
|
||||
.endif; \
|
||||
LR7_##args \
|
||||
lgr %r13,%r2; \
|
||||
lgr %r2,%r0; \
|
||||
brasl %r14,CDISABLE; \
|
||||
lgr %r2,%r13; \
|
||||
lmg %r13,%r15,104+160(%r15); \
|
||||
cfi_endproc; \
|
||||
j L(pseudo_check); \
|
||||
ENTRY(name) \
|
||||
SINGLE_THREAD_P \
|
||||
jne L(pseudo_cancel); \
|
||||
.type __##syscall_name##_nocancel,@function; \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
__##syscall_name##_nocancel: \
|
||||
DO_CALL(syscall_name, args); \
|
||||
L(pseudo_check): \
|
||||
lghi %r4,-4095; \
|
||||
clgr %r2,%r4; \
|
||||
jgnl SYSCALL_ERROR_LABEL; \
|
||||
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
||||
L(pseudo_end):
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE __pthread_enable_asynccancel
|
||||
# define CDISABLE __pthread_disable_asynccancel
|
||||
# define __local_multiple_threads __pthread_multiple_threads
|
||||
# elif IS_IN (libc)
|
||||
# define CENABLE __libc_enable_asynccancel
|
||||
# define CDISABLE __libc_disable_asynccancel
|
||||
# define __local_multiple_threads __libc_multiple_threads
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE __librt_enable_asynccancel
|
||||
# define CDISABLE __librt_disable_asynccancel
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
#define STM_0 /* Nothing */
|
||||
#define STM_1 stg %r2,16(%r15);
|
||||
#define STM_2 stmg %r2,%r3,16(%r15);
|
||||
#define STM_3 stmg %r2,%r4,16(%r15);
|
||||
#define STM_4 stmg %r2,%r5,16(%r15);
|
||||
#define STM_5 stmg %r2,%r5,16(%r15);
|
||||
#define STM_6 stmg %r2,%r7,16(%r15);
|
||||
|
||||
#define LM_0 /* Nothing */
|
||||
#define LM_1 lg %r2,16+160(%r15);
|
||||
#define LM_2 lmg %r2,%r3,16+160(%r15);
|
||||
#define LM_3 lmg %r2,%r4,16+160(%r15);
|
||||
#define LM_4 lmg %r2,%r5,16+160(%r15);
|
||||
#define LM_5 lmg %r2,%r5,16+160(%r15);
|
||||
#define LM_6 lmg %r2,%r5,16+160(%r15); \
|
||||
cfi_offset (%r7, -104); \
|
||||
lg %r7,160+160(%r15);
|
||||
|
||||
#define LR7_0 /* Nothing */
|
||||
#define LR7_1 /* Nothing */
|
||||
#define LR7_2 /* Nothing */
|
||||
#define LR7_3 /* Nothing */
|
||||
#define LR7_4 /* Nothing */
|
||||
#define LR7_5 /* Nothing */
|
||||
#define LR7_6 lg %r7,56+160(%r15); \
|
||||
cfi_restore (%r7);
|
||||
|
||||
# if IS_IN (libpthread) || IS_IN (libc)
|
||||
# ifndef __ASSEMBLER__
|
||||
extern int __local_multiple_threads attribute_hidden;
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (__local_multiple_threads == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P \
|
||||
larl %r1,__local_multiple_threads; \
|
||||
icm %r0,15,0(%r1);
|
||||
# endif
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (__local_multiple_threads == 0)
|
||||
|
||||
# else
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P \
|
||||
ear %r1,%a0; \
|
||||
sllg %r1,%r1,32; \
|
||||
ear %r1,%a1; \
|
||||
icm %r1,15,MULTIPLE_THREADS_OFFSET(%r1);
|
||||
# endif
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
||||
# endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
#else
|
||||
|
||||
# define SINGLE_THREAD_P (1)
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
||||
#define RTLD_SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
@ -17,153 +17,19 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# define _IMM12 #-12
|
||||
# define _IMM16 #-16
|
||||
# define _IMP16 #16
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.text; \
|
||||
ENTRY (name); \
|
||||
.Lpseudo_start: \
|
||||
SINGLE_THREAD_P; \
|
||||
bf .Lpseudo_cancel; \
|
||||
.type __##syscall_name##_nocancel,@function; \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
__##syscall_name##_nocancel: \
|
||||
DO_CALL (syscall_name, args); \
|
||||
mov r0,r1; \
|
||||
mov _IMM12,r2; \
|
||||
shad r2,r1; \
|
||||
not r1,r1; \
|
||||
tst r1,r1; \
|
||||
bt .Lsyscall_error; \
|
||||
bra .Lpseudo_end; \
|
||||
nop; \
|
||||
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
||||
.Lpseudo_cancel: \
|
||||
sts.l pr,@-r15; \
|
||||
cfi_adjust_cfa_offset (4); \
|
||||
cfi_rel_offset (pr, 0); \
|
||||
add _IMM16,r15; \
|
||||
cfi_adjust_cfa_offset (16); \
|
||||
SAVE_ARGS_##args; \
|
||||
CENABLE; \
|
||||
LOAD_ARGS_##args; \
|
||||
add _IMP16,r15; \
|
||||
cfi_adjust_cfa_offset (-16); \
|
||||
lds.l @r15+,pr; \
|
||||
cfi_adjust_cfa_offset (-4); \
|
||||
cfi_restore (pr); \
|
||||
DO_CALL(syscall_name, args); \
|
||||
SYSCALL_INST_PAD; \
|
||||
sts.l pr,@-r15; \
|
||||
cfi_adjust_cfa_offset (4); \
|
||||
cfi_rel_offset (pr, 0); \
|
||||
mov.l r0,@-r15; \
|
||||
cfi_adjust_cfa_offset (4); \
|
||||
cfi_rel_offset (r0, 0); \
|
||||
CDISABLE; \
|
||||
mov.l @r15+,r0; \
|
||||
cfi_adjust_cfa_offset (-4); \
|
||||
cfi_restore (r0); \
|
||||
lds.l @r15+,pr; \
|
||||
cfi_adjust_cfa_offset (-4); \
|
||||
cfi_restore (pr); \
|
||||
mov r0,r1; \
|
||||
mov _IMM12,r2; \
|
||||
shad r2,r1; \
|
||||
not r1,r1; \
|
||||
tst r1,r1; \
|
||||
bf .Lpseudo_end; \
|
||||
.Lsyscall_error: \
|
||||
SYSCALL_ERROR_HANDLER; \
|
||||
.Lpseudo_end:
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
||||
# undef PSEUDO_END
|
||||
# define PSEUDO_END(sym) \
|
||||
END (sym)
|
||||
|
||||
# define SAVE_ARGS_0 /* Nothing. */
|
||||
# define SAVE_ARGS_1 SAVE_ARGS_0; mov.l r4,@(0,r15); cfi_offset (r4,-4)
|
||||
# define SAVE_ARGS_2 SAVE_ARGS_1; mov.l r5,@(4,r15); cfi_offset (r5,-8)
|
||||
# define SAVE_ARGS_3 SAVE_ARGS_2; mov.l r6,@(8,r15); cfi_offset (r6,-12)
|
||||
# define SAVE_ARGS_4 SAVE_ARGS_3; mov.l r7,@(12,r15); cfi_offset (r7,-16)
|
||||
# define SAVE_ARGS_5 SAVE_ARGS_4
|
||||
# define SAVE_ARGS_6 SAVE_ARGS_5
|
||||
|
||||
# define LOAD_ARGS_0 /* Nothing. */
|
||||
# define LOAD_ARGS_1 LOAD_ARGS_0; mov.l @(0,r15),r4; cfi_restore (r4)
|
||||
# define LOAD_ARGS_2 LOAD_ARGS_1; mov.l @(4,r15),r5; cfi_restore (r5)
|
||||
# define LOAD_ARGS_3 LOAD_ARGS_2; mov.l @(8,r15),r6; cfi_restore (r6)
|
||||
# define LOAD_ARGS_4 LOAD_ARGS_3; mov.l @(12,r15),r7; cfi_restore (r7)
|
||||
# define LOAD_ARGS_5 LOAD_ARGS_4
|
||||
# define LOAD_ARGS_6 LOAD_ARGS_5
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define __local_enable_asynccancel __pthread_enable_asynccancel
|
||||
# define __local_disable_asynccancel __pthread_disable_asynccancel
|
||||
# elif IS_IN (libc)
|
||||
# define __local_enable_asynccancel __libc_enable_asynccancel
|
||||
# define __local_disable_asynccancel __libc_disable_asynccancel
|
||||
# elif IS_IN (librt)
|
||||
# define __local_enable_asynccancel __librt_enable_asynccancel
|
||||
# define __local_disable_asynccancel __librt_disable_asynccancel
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
# define CENABLE \
|
||||
mov.l 1f,r0; \
|
||||
bsrf r0; \
|
||||
nop; \
|
||||
0: bra 2f; \
|
||||
mov r0,r2; \
|
||||
.align 2; \
|
||||
1: .long __local_enable_asynccancel - 0b; \
|
||||
2:
|
||||
|
||||
# define CDISABLE \
|
||||
mov.l 1f,r0; \
|
||||
bsrf r0; \
|
||||
mov r2,r4; \
|
||||
0: bra 2f; \
|
||||
nop; \
|
||||
.align 2; \
|
||||
1: .long __local_disable_asynccancel - 0b; \
|
||||
2:
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P \
|
||||
stc gbr,r0; \
|
||||
mov.w 0f,r1; \
|
||||
sub r1,r0; \
|
||||
mov.l @(MULTIPLE_THREADS_OFFSET,r0),r0; \
|
||||
bra 1f; \
|
||||
tst r0,r0; \
|
||||
0: .word TLS_PRE_TCB_SIZE; \
|
||||
1:
|
||||
|
||||
# endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
#else
|
||||
|
||||
# define SINGLE_THREAD_P (1)
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
||||
#define RTLD_SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
@ -1,111 +0,0 @@
|
||||
/* Copyright (C) 2002-2017 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
|
||||
|
||||
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 <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.text; \
|
||||
.globl __syscall_error; \
|
||||
ENTRY(name) \
|
||||
ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;\
|
||||
cmp %g1, 0; \
|
||||
bne 1f; \
|
||||
.type __##syscall_name##_nocancel,@function; \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
__##syscall_name##_nocancel: \
|
||||
mov SYS_ify(syscall_name), %g1; \
|
||||
ta 0x10; \
|
||||
bcc 8f; \
|
||||
mov %o7, %g1; \
|
||||
call __syscall_error; \
|
||||
mov %g1, %o7; \
|
||||
8: jmpl %o7 + 8, %g0; \
|
||||
nop; \
|
||||
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;\
|
||||
1: save %sp, -96, %sp; \
|
||||
cfi_def_cfa_register(%fp); \
|
||||
cfi_window_save; \
|
||||
cfi_register(%o7, %i7); \
|
||||
CENABLE; \
|
||||
nop; \
|
||||
mov %o0, %l0; \
|
||||
COPY_ARGS_##args \
|
||||
mov SYS_ify(syscall_name), %g1; \
|
||||
ta 0x10; \
|
||||
bcc 1f; \
|
||||
mov %o0, %l1; \
|
||||
CDISABLE; \
|
||||
mov %l0, %o0; \
|
||||
call __syscall_error; \
|
||||
mov %l1, %o0; \
|
||||
b 2f; \
|
||||
mov -1, %l1; \
|
||||
1: CDISABLE; \
|
||||
mov %l0, %o0; \
|
||||
2: jmpl %i7 + 8, %g0; \
|
||||
restore %g0, %l1, %o0;
|
||||
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE call __pthread_enable_asynccancel
|
||||
# define CDISABLE call __pthread_disable_asynccancel
|
||||
# elif IS_IN (libc)
|
||||
# define CENABLE call __libc_enable_asynccancel
|
||||
# define CDISABLE call __libc_disable_asynccancel
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE call __librt_enable_asynccancel
|
||||
# define CDISABLE call __librt_disable_asynccancel
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
#define COPY_ARGS_0 /* Nothing */
|
||||
#define COPY_ARGS_1 COPY_ARGS_0 mov %i0, %o0;
|
||||
#define COPY_ARGS_2 COPY_ARGS_1 mov %i1, %o1;
|
||||
#define COPY_ARGS_3 COPY_ARGS_2 mov %i2, %o2;
|
||||
#define COPY_ARGS_4 COPY_ARGS_3 mov %i3, %o3;
|
||||
#define COPY_ARGS_5 COPY_ARGS_4 mov %i4, %o4;
|
||||
#define COPY_ARGS_6 COPY_ARGS_5 mov %i5, %o5;
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1
|
||||
# endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
|
||||
# define SINGLE_THREAD_P (1)
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
@ -1,109 +0,0 @@
|
||||
/* Copyright (C) 2002-2017 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
|
||||
|
||||
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 <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.text; \
|
||||
.globl __syscall_error; \
|
||||
ENTRY(name) \
|
||||
ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1;\
|
||||
brnz,pn %g1, 1f; \
|
||||
.type __##syscall_name##_nocancel,@function; \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
__##syscall_name##_nocancel: \
|
||||
mov SYS_ify(syscall_name), %g1; \
|
||||
ta 0x6d; \
|
||||
bcc,pt %xcc, 8f; \
|
||||
mov %o7, %g1; \
|
||||
call __syscall_error; \
|
||||
mov %g1, %o7; \
|
||||
8: jmpl %o7 + 8, %g0; \
|
||||
nop; \
|
||||
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel;\
|
||||
1: save %sp, -192, %sp; \
|
||||
cfi_def_cfa_register(%fp); \
|
||||
cfi_window_save; \
|
||||
cfi_register(%o7, %i7); \
|
||||
CENABLE; \
|
||||
nop; \
|
||||
mov %o0, %l0; \
|
||||
COPY_ARGS_##args \
|
||||
mov SYS_ify(syscall_name), %g1; \
|
||||
ta 0x6d; \
|
||||
bcc,pt %xcc, 1f; \
|
||||
mov %o0, %l1; \
|
||||
CDISABLE; \
|
||||
mov %l0, %o0; \
|
||||
call __syscall_error; \
|
||||
mov %l1, %o0; \
|
||||
ba,pt %xcc, 2f; \
|
||||
mov -1, %l1; \
|
||||
1: CDISABLE; \
|
||||
mov %l0, %o0; \
|
||||
2: jmpl %i7 + 8, %g0; \
|
||||
restore %g0, %l1, %o0;
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE call __pthread_enable_asynccancel
|
||||
# define CDISABLE call __pthread_disable_asynccancel
|
||||
# elif IS_IN (libc)
|
||||
# define CENABLE call __libc_enable_asynccancel
|
||||
# define CDISABLE call __libc_disable_asynccancel
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE call __librt_enable_asynccancel
|
||||
# define CDISABLE call __librt_disable_asynccancel
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
#define COPY_ARGS_0 /* Nothing */
|
||||
#define COPY_ARGS_1 COPY_ARGS_0 mov %i0, %o0;
|
||||
#define COPY_ARGS_2 COPY_ARGS_1 mov %i1, %o1;
|
||||
#define COPY_ARGS_3 COPY_ARGS_2 mov %i2, %o2;
|
||||
#define COPY_ARGS_4 COPY_ARGS_3 mov %i3, %o3;
|
||||
#define COPY_ARGS_5 COPY_ARGS_4 mov %i4, %o4;
|
||||
#define COPY_ARGS_6 COPY_ARGS_5 mov %i5, %o5;
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P ld [%g7 + MULTIPLE_THREADS_OFFSET], %g1
|
||||
# endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
|
||||
# define SINGLE_THREAD_P (1)
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
36
sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h
Normal file
36
sysdeps/unix/sysv/linux/sparc/sysdep-cancel.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* Cancellable system call stubs. Linux/Sparc version.
|
||||
Copyright (C) 2017 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 <sysdep.h>
|
||||
#include <tls.h>
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
||||
#else
|
||||
|
||||
# define SINGLE_THREAD_P (1)
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#define RTLD_SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
@ -18,137 +18,19 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
/* Allow hacking in some extra code if desired. */
|
||||
#ifndef PSEUDO_EXTRA
|
||||
#define PSEUDO_EXTRA
|
||||
#endif
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
||||
#undef PSEUDO
|
||||
#define PSEUDO(name, syscall_name, args) \
|
||||
ENTRY(__##syscall_name##_nocancel); \
|
||||
PSEUDO_EXTRA \
|
||||
moveli TREG_SYSCALL_NR_NAME, SYS_ify(syscall_name); \
|
||||
swint1; \
|
||||
BNEZ r1, 0f; \
|
||||
jrp lr; \
|
||||
END(__##syscall_name##_nocancel); \
|
||||
ENTRY (name) \
|
||||
SINGLE_THREAD_P(r11); \
|
||||
BEQZ r11, L(pseudo_cancel); \
|
||||
PSEUDO_EXTRA \
|
||||
moveli TREG_SYSCALL_NR_NAME, SYS_ify(syscall_name); \
|
||||
swint1; \
|
||||
BNEZ r1, 0f; \
|
||||
jrp lr; \
|
||||
L(pseudo_cancel): \
|
||||
{ \
|
||||
move r11, sp; \
|
||||
ST sp, lr; \
|
||||
ADDI_PTR sp, sp, -STKSPACE; \
|
||||
}; \
|
||||
cfi_offset (lr, 0); \
|
||||
cfi_def_cfa_offset (STKSPACE); \
|
||||
{ \
|
||||
ADDI_PTR r12, sp, REGSIZE; \
|
||||
ADDI_PTR r13, sp, 2 * REGSIZE; /* set up for PUSHARGS_0 */ \
|
||||
}; \
|
||||
ST r12, r11; \
|
||||
PUSHARGS_##args /* save syscall args */ \
|
||||
CENABLE; \
|
||||
ADDI_PTR r12, sp, 10 * REGSIZE; \
|
||||
{ \
|
||||
ST r12, r0; /* save mask */ \
|
||||
ADDI_PTR r13, sp, 2 * REGSIZE; /* set up for POPARGS_0 */ \
|
||||
}; \
|
||||
POPARGS_##args /* restore syscall args */ \
|
||||
PSEUDO_EXTRA \
|
||||
moveli TREG_SYSCALL_NR_NAME, SYS_ify(syscall_name); \
|
||||
swint1; \
|
||||
ADDI_PTR r12, sp, 12 * REGSIZE; \
|
||||
{ \
|
||||
ST r12, r1; /* save syscall result */ \
|
||||
ADDI_PTR r12, sp, 11 * REGSIZE; \
|
||||
}; \
|
||||
{ \
|
||||
ST r12, r0; \
|
||||
ADDI_PTR r13, sp, 10 * REGSIZE; \
|
||||
}; \
|
||||
LD r0, r13; /* pass mask as arg1 */ \
|
||||
CDISABLE; \
|
||||
{ \
|
||||
ADDI_PTR lr, sp, STKSPACE; \
|
||||
ADDI_PTR r0, sp, 11 * REGSIZE; \
|
||||
}; \
|
||||
{ \
|
||||
LD r0, r0; \
|
||||
ADDI_PTR r1, sp, 12 * REGSIZE; \
|
||||
}; \
|
||||
LD r1, r1; \
|
||||
{ \
|
||||
LD lr, lr; \
|
||||
ADDI_PTR sp, sp, STKSPACE; \
|
||||
}; \
|
||||
cfi_def_cfa_offset (0); \
|
||||
BNEZ r1, 0f
|
||||
|
||||
# define PUSHARGS_0 /* nothing to do */
|
||||
# define PUSHARGS_1 PUSHARGS_0 { ADDI_PTR r14, sp, 3 * REGSIZE; ST r13, r0 };
|
||||
# define PUSHARGS_2 PUSHARGS_1 { ADDI_PTR r13, sp, 4 * REGSIZE; ST r14, r1 };
|
||||
# define PUSHARGS_3 PUSHARGS_2 { ADDI_PTR r14, sp, 5 * REGSIZE; ST r13, r2 };
|
||||
# define PUSHARGS_4 PUSHARGS_3 { ADDI_PTR r13, sp, 6 * REGSIZE; ST r14, r3 };
|
||||
# define PUSHARGS_5 PUSHARGS_4 { ADDI_PTR r14, sp, 7 * REGSIZE; ST r13, r4 };
|
||||
# define PUSHARGS_6 PUSHARGS_5 { ADDI_PTR r13, sp, 8 * REGSIZE; ST r14, r5 };
|
||||
# define PUSHARGS_7 PUSHARGS_6 { ADDI_PTR r14, sp, 9 * REGSIZE; ST r13, r6 };
|
||||
|
||||
# define POPARGS_0 /* nothing to do */
|
||||
# define POPARGS_1 POPARGS_0 { ADDI_PTR r14, sp, 3 * REGSIZE; LD r0, r13 };
|
||||
# define POPARGS_2 POPARGS_1 { ADDI_PTR r13, sp, 4 * REGSIZE; LD r1, r14 };
|
||||
# define POPARGS_3 POPARGS_2 { ADDI_PTR r14, sp, 5 * REGSIZE; LD r2, r13 };
|
||||
# define POPARGS_4 POPARGS_3 { ADDI_PTR r13, sp, 6 * REGSIZE; LD r3, r14 };
|
||||
# define POPARGS_5 POPARGS_4 { ADDI_PTR r14, sp, 7 * REGSIZE; LD r4, r13 };
|
||||
# define POPARGS_6 POPARGS_5 { ADDI_PTR r13, sp, 8 * REGSIZE; LD r5, r14 };
|
||||
# define POPARGS_7 POPARGS_6 { ADDI_PTR r14, sp, 9 * REGSIZE; LD r6, r13 };
|
||||
|
||||
# define STKSPACE (13 * REGSIZE)
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE jal __pthread_enable_asynccancel
|
||||
# define CDISABLE jal __pthread_disable_asynccancel
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE jal __librt_enable_asynccancel
|
||||
# define CDISABLE jal __librt_disable_asynccancel
|
||||
# else
|
||||
# define CENABLE jal __libc_enable_asynccancel
|
||||
# define CDISABLE jal __libc_disable_asynccancel
|
||||
# endif
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) \
|
||||
== 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P(reg) \
|
||||
ADDLI_PTR reg, tp, MULTIPLE_THREADS_OFFSET; \
|
||||
LD reg, reg; \
|
||||
CMPEQI reg, reg, 0
|
||||
#endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
#else
|
||||
|
||||
# define SINGLE_THREAD_P 1
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
||||
#define RTLD_SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
@ -18,92 +18,34 @@
|
||||
|
||||
#include <sysdep.h>
|
||||
#include <tls.h>
|
||||
#ifndef __ASSEMBLER__
|
||||
# include <nptl/pthreadP.h>
|
||||
#endif
|
||||
#include <nptl/pthreadP.h>
|
||||
|
||||
#if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt)
|
||||
|
||||
/* The code to disable cancellation depends on the fact that the called
|
||||
functions are special. They don't modify registers other than %rax
|
||||
and %r11 if they return. Therefore we don't have to preserve other
|
||||
registers around these calls. */
|
||||
# undef PSEUDO
|
||||
# define PSEUDO(name, syscall_name, args) \
|
||||
.text; \
|
||||
ENTRY (name) \
|
||||
SINGLE_THREAD_P; \
|
||||
jne L(pseudo_cancel); \
|
||||
.type __##syscall_name##_nocancel,@function; \
|
||||
.globl __##syscall_name##_nocancel; \
|
||||
__##syscall_name##_nocancel: \
|
||||
DO_CALL (syscall_name, args); \
|
||||
cmpq $-4095, %rax; \
|
||||
jae SYSCALL_ERROR_LABEL; \
|
||||
ret; \
|
||||
.size __##syscall_name##_nocancel,.-__##syscall_name##_nocancel; \
|
||||
L(pseudo_cancel): \
|
||||
/* We always have to align the stack before calling a function. */ \
|
||||
subq $8, %rsp; cfi_adjust_cfa_offset (8); \
|
||||
CENABLE \
|
||||
/* The return value from CENABLE is argument for CDISABLE. */ \
|
||||
movq %rax, (%rsp); \
|
||||
DO_CALL (syscall_name, args); \
|
||||
movq (%rsp), %rdi; \
|
||||
/* Save %rax since it's the error code from the syscall. */ \
|
||||
movq %rax, %rdx; \
|
||||
CDISABLE \
|
||||
movq %rdx, %rax; \
|
||||
addq $8,%rsp; cfi_adjust_cfa_offset (-8); \
|
||||
cmpq $-4095, %rax; \
|
||||
jae SYSCALL_ERROR_LABEL
|
||||
|
||||
|
||||
# if IS_IN (libpthread)
|
||||
# define CENABLE call __pthread_enable_asynccancel;
|
||||
# define CDISABLE call __pthread_disable_asynccancel;
|
||||
# define __local_multiple_threads __pthread_multiple_threads
|
||||
# elif IS_IN (libc)
|
||||
# define CENABLE call __libc_enable_asynccancel;
|
||||
# define CDISABLE call __libc_disable_asynccancel;
|
||||
# define __local_multiple_threads __libc_multiple_threads
|
||||
# elif IS_IN (librt)
|
||||
# define CENABLE call __librt_enable_asynccancel;
|
||||
# define CDISABLE call __librt_disable_asynccancel;
|
||||
# else
|
||||
# error Unsupported library
|
||||
# endif
|
||||
|
||||
# if IS_IN (libpthread) || IS_IN (libc)
|
||||
# ifndef __ASSEMBLER__
|
||||
extern int __local_multiple_threads attribute_hidden;
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (__local_multiple_threads == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P cmpl $0, __local_multiple_threads(%rip)
|
||||
# endif
|
||||
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (__local_multiple_threads == 0)
|
||||
# else
|
||||
|
||||
# ifndef __ASSEMBLER__
|
||||
# define SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
# else
|
||||
# define SINGLE_THREAD_P cmpl $0, %fs:MULTIPLE_THREADS_OFFSET
|
||||
# endif
|
||||
|
||||
# define SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
# endif
|
||||
|
||||
#elif !defined __ASSEMBLER__
|
||||
#else
|
||||
|
||||
# define SINGLE_THREAD_P (1)
|
||||
# define NO_CANCELLATION 1
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLER__
|
||||
# define RTLD_SINGLE_THREAD_P \
|
||||
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
|
||||
header.multiple_threads) == 0, 1)
|
||||
#endif
|
||||
#define RTLD_SINGLE_THREAD_P \
|
||||
__glibc_likely (THREAD_GETMEM (THREAD_SELF, header.multiple_threads) == 0)
|
||||
|
Loading…
Reference in New Issue
Block a user