@@ -1,5 +1,25 @@
2015-10-07 Adhemerval Zanella <adhemerval.zanella@linaro.org>
+ * sysdeps/unix/sysv/linux/x86_64/cancellation.S: Remove file.
+ * sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S: Remove file.
+ * sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S: Remove file.
+ * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (lll_wait_tid):
+ Use cancellable futex wait call.
+ * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (PSEUDO): Likewise.
+ * sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S: New file.
+ * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (PSEUDO): Redefine to
+ call __syscall_cancel function for cancellable syscalls.
+ (CENABLE): Remove definition.
+ (CDISABLE): Likewise.
+ (__pthread_get_ip): Add implementation.
+ * sysdeps/unix/sysv/linux/x86_64/sysdep.h (SYSCALL_CANCEL_ERROR): New
+ define.
+ (SYSCALL_CANCEL_ERRNO): Likewise.
+ * sysdeps/x86_64/nptl/tcb-offsets.sym [TCB_CANCELING_BITMASK]:
+ Remove.
+ * sysdeps/x86_64/nptl/tls.h (THREAD_ATOMIC_BIT_SET): Remove
+ macro.
+
* sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c (__libc_fnctl):
Remove CANCEL_ASYNC/CANCEL_RESET usage.
* sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep-cancel.h (PSEUDO):
deleted file mode 100644
@@ -1,117 +0,0 @@
-/* Copyright (C) 2009-2015 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
-
- 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 <tcb-offsets.h>
-#include <kernel-features.h>
-#include "lowlevellock.h"
-
-#if IS_IN (libpthread)
-# if defined SHARED && !defined NO_HIDDEN
-# define __pthread_unwind __GI___pthread_unwind
-# endif
-#else
-# ifndef SHARED
- .weak __pthread_unwind
-# endif
-#endif
-
-
-#ifdef __ASSUME_PRIVATE_FUTEX
-# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
- movl $(FUTEX_WAIT | FUTEX_PRIVATE_FLAG), reg
-#else
-# if FUTEX_WAIT == 0
-# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
- movl %fs:PRIVATE_FUTEX, reg
-# else
-# define LOAD_PRIVATE_FUTEX_WAIT(reg) \
- movl %fs:PRIVATE_FUTEX, reg ; \
- orl $FUTEX_WAIT, reg
-# endif
-#endif
-
-/* It is crucial that the functions in this file don't modify registers
- other than %rax and %r11. The syscall wrapper code depends on this
- because it doesn't explicitly save the other registers which hold
- relevant values. */
- .text
-
- .hidden __pthread_enable_asynccancel
-ENTRY(__pthread_enable_asynccancel)
- movl %fs:CANCELHANDLING, %eax
-2: movl %eax, %r11d
- orl $TCB_CANCELTYPE_BITMASK, %r11d
- cmpl %eax, %r11d
- je 1f
-
- lock
- cmpxchgl %r11d, %fs:CANCELHANDLING
- jnz 2b
-
- andl $(TCB_CANCELSTATE_BITMASK|TCB_CANCELTYPE_BITMASK|TCB_CANCELED_BITMASK|TCB_EXITING_BITMASK|TCB_CANCEL_RESTMASK|TCB_TERMINATED_BITMASK), %r11d
- cmpl $(TCB_CANCELTYPE_BITMASK|TCB_CANCELED_BITMASK), %r11d
- je 3f
-
-1: ret
-
-3: subq $8, %rsp
- cfi_adjust_cfa_offset(8)
- LP_OP(mov) $TCB_PTHREAD_CANCELED, %fs:RESULT
- lock
- orl $TCB_EXITING_BITMASK, %fs:CANCELHANDLING
- mov %fs:CLEANUP_JMP_BUF, %RDI_LP
-#ifdef SHARED
- call __pthread_unwind@PLT
-#else
- call __pthread_unwind
-#endif
- hlt
-END(__pthread_enable_asynccancel)
-
-
- .hidden __pthread_disable_asynccancel
-ENTRY(__pthread_disable_asynccancel)
- testl $TCB_CANCELTYPE_BITMASK, %edi
- jnz 1f
-
- movl %fs:CANCELHANDLING, %eax
-2: movl %eax, %r11d
- andl $~TCB_CANCELTYPE_BITMASK, %r11d
- lock
- cmpxchgl %r11d, %fs:CANCELHANDLING
- jnz 2b
-
- movl %r11d, %eax
-3: andl $(TCB_CANCELING_BITMASK|TCB_CANCELED_BITMASK), %eax
- cmpl $TCB_CANCELING_BITMASK, %eax
- je 4f
-1: ret
-
- /* Performance doesn't matter in this loop. We will
- delay until the thread is canceled. And we will unlikely
- enter the loop twice. */
-4: mov %fs:0, %RDI_LP
- movl $__NR_futex, %eax
- xorq %r10, %r10
- addq $CANCELHANDLING, %rdi
- LOAD_PRIVATE_FUTEX_WAIT (%esi)
- syscall
- movl %fs:CANCELHANDLING, %eax
- jmp 3b
-END(__pthread_disable_asynccancel)
deleted file mode 100644
@@ -1,21 +0,0 @@
-/* Copyright (C) 2009-2015 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
-
- 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/>. */
-
-#define __pthread_enable_asynccancel __libc_enable_asynccancel
-#define __pthread_disable_asynccancel __libc_disable_asynccancel
-#include "cancellation.S"
deleted file mode 100644
@@ -1,21 +0,0 @@
-/* Copyright (C) 2009-2015 Free Software Foundation, Inc.
- This file is part of the GNU C Library.
- Contributed by Ulrich Drepper <drepper@redhat.com>, 2009.
-
- 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/>. */
-
-#define __pthread_enable_asynccancel __librt_enable_asynccancel
-#define __pthread_disable_asynccancel __librt_disable_asynccancel
-#include "cancellation.S"
@@ -306,10 +306,10 @@ extern int __lll_timedlock_elision (int *futex, short *adapt_count,
afterwards. The kernel up to version 3.16.3 does not use the private futex
operations for futex wake-up when the clone terminates. */
#define lll_wait_tid(tid) \
- do { \
- __typeof (tid) __tid; \
- while ((__tid = (tid)) != 0) \
- lll_futex_wait (&(tid), __tid, LLL_SHARED);\
+ do { \
+ __typeof (tid) __tid; \
+ while ((__tid = (tid)) != 0) \
+ lll_futex_wait_cancel (&(tid), __tid, LLL_SHARED); \
} while (0)
extern int __lll_timedwait_tid (int *, const struct timespec *)
new file mode 100644
@@ -0,0 +1,62 @@
+/* Cancellable syscall wrapper - x86_64 version.
+ Copyright (C) 2014 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>
+
+/* long int [rax] __syscall_cancel_arch (int *cancelhandling [%rdi],
+ long int nr [%rsi],
+ long int arg1 [%rdx],
+ long int arg2 [%rcx],
+ long int arg3 [%r8],
+ long int arg4 [%r9],
+ long int arg5 [SP+8],
+ long int arg6 [SP+16]) */
+
+ENTRY (__syscall_cancel_arch)
+
+ .globl __syscall_cancel_arch_start
+ .type __syscall_cancel_arch_start,@function
+__syscall_cancel_arch_start:
+
+ /* if (*cancelhandling & CANCELED_BITMASK)
+ __syscall_do_cancel() */
+ mov (%rdi),%eax
+ testb $4, (%rdi)
+ jne __syscall_do_cancel
+
+ /* Issue a 6 argument syscall, the nr [%rax] being the syscall
+ number. */
+ mov %rdi,%r11
+ mov %rsi,%rax
+ mov %rdx,%rdi
+ mov %rcx,%rsi
+ mov %r8,%rdx
+ mov %r9,%r10
+ mov 8(%rsp),%r8
+ mov 16(%rsp),%r9
+ mov %r11,8(%rsp)
+ syscall
+
+ .globl __syscall_cancel_arch_end
+ .type __syscall_cancel_arch_end,@function
+__syscall_cancel_arch_end:
+
+ ret
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
@@ -24,53 +24,43 @@
#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. */
+# if IS_IN (libc)
+# define JMP_SYSCALL_CANCEL HIDDEN_JUMPTARGET(__syscall_cancel)
+# else
+# define JMP_SYSCALL_CANCEL __syscall_cancel@plt
+# endif
+
# 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
-
+ subq $24, %rsp; \
+ cfi_def_cfa_offset (32); \
+ movq %r9, (%rsp); \
+ movq %r8, %r9; \
+ movq %rcx, %r8; \
+ movq %rdx, %rcx; \
+ movq %rsi, %rdx; \
+ movq %rdi, %rsi; \
+ lea SYS_ify (syscall_name), %edi; \
+ call JMP_SYSCALL_CANCEL; \
+ cfi_def_cfa_offset (8); \
+ addq $24, %rsp; \
+ 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
+# elif !IS_IN (librt)
# error Unsupported library
# endif
@@ -78,7 +68,7 @@
# ifndef __ASSEMBLER__
extern int __local_multiple_threads attribute_hidden;
# define SINGLE_THREAD_P \
- __builtin_expect (__local_multiple_threads == 0, 1)
+ __builtin_expect (__local_multiple_threads == 0, 1)
# else
# define SINGLE_THREAD_P cmpl $0, __local_multiple_threads(%rip)
# endif
@@ -87,18 +77,13 @@ extern int __local_multiple_threads attribute_hidden;
# ifndef __ASSEMBLER__
# define SINGLE_THREAD_P \
- __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
- header.multiple_threads) == 0, 1)
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ header.multiple_threads) == 0, 1)
# else
# define SINGLE_THREAD_P cmpl $0, %fs:MULTIPLE_THREADS_OFFSET
-# endif
+# endif /* __ASSEMBLER */
-# endif
-
-#elif !defined __ASSEMBLER__
-
-# define SINGLE_THREAD_P (1)
-# define NO_CANCELLATION 1
+# endif /* IS_IN (libpthread) || IS_IN (libc) */
#endif
@@ -106,4 +91,10 @@ extern int __local_multiple_threads attribute_hidden;
# define RTLD_SINGLE_THREAD_P \
__builtin_expect (THREAD_GETMEM (THREAD_SELF, \
header.multiple_threads) == 0, 1)
+
+static inline
+long int __pthread_get_ip (const ucontext_t *uc)
+{
+ return (long int)uc->uc_mcontext.gregs[REG_RIP];
+}
#endif
@@ -252,6 +252,14 @@
# undef INTERNAL_SYSCALL_ERRNO
# define INTERNAL_SYSCALL_ERRNO(val, err) (-(val))
+# undef SYSCALL_CANCEL_ERROR
+# define SYSCALL_CANCEL_ERROR(__val) \
+ ((unsigned long int) (long int) (__val) >= -4095L)
+
+# undef SYSCALL_CANCEL_ERRNO
+# define SYSCALL_CANCEL_ERRNO(__val) \
+ (-(__val))
+
/* List of system calls which are supported as vsyscalls. */
# define HAVE_CLOCK_GETTIME_VSYSCALL 1
# define HAVE_GETTIMEOFDAY_VSYSCALL 1
@@ -20,7 +20,6 @@ PRIVATE_FUTEX offsetof (tcbhead_t, private_futex)
-- Not strictly offsets, but these values are also used in the TCB.
TCB_CANCELSTATE_BITMASK CANCELSTATE_BITMASK
TCB_CANCELTYPE_BITMASK CANCELTYPE_BITMASK
-TCB_CANCELING_BITMASK CANCELING_BITMASK
TCB_CANCELED_BITMASK CANCELED_BITMASK
TCB_EXITING_BITMASK EXITING_BITMASK
TCB_CANCEL_RESTMASK CANCEL_RESTMASK
@@ -326,17 +326,6 @@ typedef struct
abort (); })
-/* Atomic set bit. */
-# define THREAD_ATOMIC_BIT_SET(descr, member, bit) \
- (void) ({ if (sizeof ((descr)->member) == 4) \
- asm volatile (LOCK_PREFIX "orl %1, %%fs:%P0" \
- :: "i" (offsetof (struct pthread, member)), \
- "ir" (1 << (bit))); \
- else \
- /* Not necessary for other sizes in the moment. */ \
- abort (); })
-
-
# define CALL_THREAD_FCT(descr) \
({ void *__res; \
asm volatile ("movq %%fs:%P2, %%rdi\n\t" \
From: Adhemerval Zanella <azanella@linux.vnet.ibm.com> This patches adds the x86_64 modification required for the BZ#12683 fix. It basically removes the enable_asynccancel/disable_asynccancel function usage on code used on x86_64, and provide a arch-specific symbol that contains global markers to be used in SIGCANCEL handler. Checked on x86_64. * sysdeps/unix/sysv/linux/x86_64/cancellation.S: Remove file. * sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S: Remove file. * sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S: Remove file. * sysdeps/unix/sysv/linux/x86_64/lowlevellock.h (lll_wait_tid): Use cancellable futex wait call. * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (PSEUDO): Likewise. * sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S: New file. * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (PSEUDO): Redefine to call __syscall_cancel function for cancellable syscalls. (CENABLE): Remove definition. (CDISABLE): Likewise. (__pthread_get_ip): Add implementation. * sysdeps/unix/sysv/linux/x86_64/sysdep.h (SYSCALL_CANCEL_ERROR): New define. (SYSCALL_CANCEL_ERRNO): Likewise. * sysdeps/x86_64/nptl/tcb-offsets.sym [TCB_CANCELING_BITMASK]: Remove. * sysdeps/x86_64/nptl/tls.h (THREAD_ATOMIC_BIT_SET): Remove macro. --- ChangeLog | 20 ++++ sysdeps/unix/sysv/linux/x86_64/cancellation.S | 117 --------------------- sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S | 21 ---- .../unix/sysv/linux/x86_64/librt-cancellation.S | 21 ---- sysdeps/unix/sysv/linux/x86_64/lowlevellock.h | 8 +- sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S | 62 +++++++++++ sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h | 73 ++++++------- sysdeps/unix/sysv/linux/x86_64/sysdep.h | 8 ++ sysdeps/x86_64/nptl/tcb-offsets.sym | 1 - sysdeps/x86_64/nptl/tls.h | 11 -- 10 files changed, 126 insertions(+), 216 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/x86_64/cancellation.S delete mode 100644 sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S delete mode 100644 sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S create mode 100644 sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S