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:
Adhemerval Zanella 2015-11-12 14:01:36 -02:00
parent 8aa48656bb
commit ebd6f0076a
25 changed files with 348 additions and 2766 deletions

176
ChangeLog
View File

@ -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.

View File

@ -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>'; \\"

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View 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)

View File

@ -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)

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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

View 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)

View File

@ -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)

View File

@ -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)