From patchwork Fri Sep 26 19:49:35 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 393942 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id EBCAD140188 for ; Sat, 27 Sep 2014 05:50:01 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:date:from:mime-version:to:subject :references:in-reply-to:content-type:content-transfer-encoding; q=dns; s=default; b=JQznBbItmNs7VBWJ6IEzqtPxzNl2zjprybVlfO+6YQu 7LJqagWhGttkII6Y7IO21qUtGX2qSxC6m1tpgDBnqVpPC2DMsEG7xpeekXh1va41 7iq7k964eOi1AhRy1/3gchdeYR3xGGT4f9AyCRvMdUKK0GVdsUT+nYLUeBmr+2fw = DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=sourceware.org; h=list-id :list-unsubscribe:list-subscribe:list-archive:list-post :list-help:sender:message-id:date:from:mime-version:to:subject :references:in-reply-to:content-type:content-transfer-encoding; s=default; bh=59l+znfqgjkADQno5JKfG5Nw964=; b=IRtpqxUnnFS+V9J2I 72w0RUUjR1upiIkJ1Q/41eiDrlAKcZ5Z1dS7iXP9VEgQDR/By3bFZTj13DsKSuus 82lHW7o4HM/hg/wbQa8E94q2HNL+9Lhki/7F70V7UDKIvJxkzj6y8M3g/z+DPKeq K/OkS86NdUuMdJt1w7F3R0meVU= Received: (qmail 22483 invoked by alias); 26 Sep 2014 19:49:47 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 22424 invoked by uid 89); 26 Sep 2014 19:49:46 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, UNSUBSCRIBE_BODY autolearn=no version=3.3.2 X-HELO: e24smtp03.br.ibm.com Message-ID: <5425C34F.5070703@linux.vnet.ibm.com> Date: Fri, 26 Sep 2014 16:49:35 -0300 From: Adhemerval Zanella User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.5.0 MIME-Version: 1.0 To: "GNU C. Library" Subject: [PATCH 6/7] nptl: x86_64: Fix Race conditions in pthread cancellation, (BZ#12683) References: <5425BDDA.5080807@linux.vnet.ibm.com> In-Reply-To: <5425BDDA.5080807@linux.vnet.ibm.com> X-TM-AS-MML: disable X-Content-Scanned: Fidelis XPS MAILER x-cbid: 14092619-0009-0000-0000-000001E20455 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, provide a arch-specific symbol that contains global markers to be used in SIGCANCEL handler, and remove x86_64 assembly pthread conditional and semaphore code to use default one (that already contains the cancel call fixes). Tested on x86_64 and powerpc64. --- * sysdeps/unix/sysv/linux/fcntl.c (__fcntl_nocancel): Rewrite to use new cancellation mechanism. * 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_futex_wait_cancel): New define: cancellable futex wait call. (lll_futex_wake_unlock): New define: futex wake unlock call. (lll_wait_tid): Using cancellable futex wait call. * sysdeps/unix/sysv/linux/x86_64/recv.c (__libc_recv): Remove calls to enable/disable asynchronous cancellation and use call to cancellable syscall entrypoint when required. * sysdeps/unix/sysv/linux/x86_64/send.c (__libc_send): Likewise. * sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h (PSEUDO): Likewise. * sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S: New file: cancellable syscall entrypoint. * sysdeps/unix/sysv/linux/x86_64/sysdep.h (SYSCALL_CANCEL_ERROR): New define. (SYSCALL_CANCEL_ERRNO): New define. * sysdeps/x64_64/nptl/pthreaddef.h (__pthread_get_ip): New function: return ucontext_t instruction point address. * sysdeps/x86_64/nptl/tcb-offsets.sym [TCB_CANCELING_BITMASK]: Remove. * sysdeps/x86_64/nptl/tls.h (THREAD_ATOMIC_BIT_SET): Remove define. --- diff --git a/sysdeps/unix/sysv/linux/fcntl.c b/sysdeps/unix/sysv/linux/fcntl.c index c1d33da..6b095c8 100644 --- a/sysdeps/unix/sysv/linux/fcntl.c +++ b/sysdeps/unix/sysv/linux/fcntl.c @@ -23,9 +23,8 @@ #include - -static int -do_fcntl (int fd, int cmd, void *arg) +static inline int +__fcntl_common_nocancel (int fd, int cmd, void *arg) { if (cmd != F_GETOWN) return INLINE_SYSCALL (fcntl, 3, fd, cmd, arg); @@ -40,8 +39,22 @@ do_fcntl (int fd, int cmd, void *arg) return -1; } +static inline int +__fcntl_common_cancel (int fd, int cmd, void *arg) +{ + if (cmd != F_GETOWN) + return SYSCALL_CANCEL (fcntl, fd, cmd, arg); -#ifndef NO_CANCELLATION + struct f_owner_ex fex; + int res = SYSCALL_CANCEL_NCS (fcntl, fd, F_GETOWN_EX, &fex); + if (!SYSCALL_CANCEL_ERROR (res)) + return fex.type == F_OWNER_GID ? -fex.pid : fex.pid; + + __set_errno (SYSCALL_CANCEL_ERRNO (res)); + return -1; +} + +#ifndef IS_IN_rtld int __fcntl_nocancel (int fd, int cmd, ...) { @@ -52,11 +65,10 @@ __fcntl_nocancel (int fd, int cmd, ...) arg = va_arg (ap, void *); va_end (ap); - return do_fcntl (fd, cmd, arg); + return __fcntl_common_nocancel (fd, cmd, arg); } #endif - int __libc_fcntl (int fd, int cmd, ...) { @@ -67,16 +79,10 @@ __libc_fcntl (int fd, int cmd, ...) arg = va_arg (ap, void *); va_end (ap); - if (SINGLE_THREAD_P || cmd != F_SETLKW) - return do_fcntl (fd, cmd, arg); - - int oldtype = LIBC_CANCEL_ASYNC (); - - int result = do_fcntl (fd, cmd, arg); - - LIBC_CANCEL_RESET (oldtype); + if (cmd != F_SETLKW) + return __fcntl_common_nocancel (fd, cmd, arg); - return result; + return __fcntl_common_cancel (fd, cmd, arg); } libc_hidden_def (__libc_fcntl) diff --git a/sysdeps/unix/sysv/linux/x86_64/cancellation.S b/sysdeps/unix/sysv/linux/x86_64/cancellation.S deleted file mode 100644 index 89fda5e..0000000 --- a/sysdeps/unix/sysv/linux/x86_64/cancellation.S +++ /dev/null @@ -1,117 +0,0 @@ -/* Copyright (C) 2009-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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 - . */ - -#include -#include -#include -#include "lowlevellock.h" - -#ifdef 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) diff --git a/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S b/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S deleted file mode 100644 index 019e22f..0000000 --- a/sysdeps/unix/sysv/linux/x86_64/libc-cancellation.S +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright (C) 2009-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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 - . */ - -#define __pthread_enable_asynccancel __libc_enable_asynccancel -#define __pthread_disable_asynccancel __libc_disable_asynccancel -#include "cancellation.S" diff --git a/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S b/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S deleted file mode 100644 index 02892ef..0000000 --- a/sysdeps/unix/sysv/linux/x86_64/librt-cancellation.S +++ /dev/null @@ -1,21 +0,0 @@ -/* Copyright (C) 2009-2014 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Contributed by Ulrich Drepper , 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 - . */ - -#define __pthread_enable_asynccancel __librt_enable_asynccancel -#define __pthread_disable_asynccancel __librt_disable_asynccancel -#include "cancellation.S" diff --git a/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h b/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h index 55b4e16..4857d4e 100644 --- a/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h +++ b/sysdeps/unix/sysv/linux/x86_64/lowlevellock.h @@ -124,6 +124,20 @@ __status; \ }) +#define lll_futex_wait_cancel(futexp, val, private) \ + lll_futex_timed_wait_cancel (futexp, val, NULL, private) + +#define lll_futex_timed_wait_cancel(futexp, val, timespec, private) \ + ({ \ + long int __ret; \ + int __op = FUTEX_WAIT; \ + \ + __ret = __syscall_cancel (__NR_futex, (long int) (futexp), \ + (long int)__lll_private_flag (__op, private), \ + (long int)(val), (long int)(timespec), 0, 0); \ + __ret; \ + }) + #define lll_futex_wake(futex, nr, private) \ ({ \ @@ -139,6 +153,18 @@ __status; \ }) +#define lll_futex_wake_unlock(futexp, nr_wake, nr_wake2, futexp2, private) \ + ({ \ + INTERNAL_SYSCALL_DECL (__err); \ + long int __ret; \ + \ + __ret = INTERNAL_SYSCALL (futex, __err, 6, (futexp), \ + __lll_private_flag (FUTEX_WAKE_OP, private), \ + (nr_wake), (nr_wake2), (futexp2), \ + FUTEX_OP_CLEAR_WAKE_IF_GT_ONE); \ + INTERNAL_SYSCALL_ERROR_P (__ret, __err); \ + }) + /* NB: in the lll_trylock macro we simply return the value in %eax after the cmpxchg instruction. In case the operation succeded this @@ -405,18 +431,9 @@ extern int __lll_timedlock_elision (int *futex, short *adapt_count, The macro parameter must not have any side effect. */ #define lll_wait_tid(tid) \ do { \ - int __ignore; \ - register __typeof (tid) _tid asm ("edx") = (tid); \ - if (_tid != 0) \ - __asm __volatile ("xorq %%r10, %%r10\n\t" \ - "1:\tmovq %2, %%rax\n\t" \ - "syscall\n\t" \ - "cmpl $0, (%%rdi)\n\t" \ - "jne 1b" \ - : "=&a" (__ignore) \ - : "S" (FUTEX_WAIT), "i" (SYS_futex), "D" (&tid), \ - "d" (_tid) \ - : "memory", "cc", "r10", "r11", "cx"); \ + __typeof (tid) __tid; \ + while ((__tid = (tid)) != 0) \ + lll_futex_wait_cancel (&(tid), __tid, LLL_SHARED); \ } while (0) extern int __lll_timedwait_tid (int *tid, const struct timespec *abstime) diff --git a/sysdeps/unix/sysv/linux/x86_64/recv.c b/sysdeps/unix/sysv/linux/x86_64/recv.c index 53c2381..10b5d3e 100644 --- a/sysdeps/unix/sysv/linux/x86_64/recv.c +++ b/sysdeps/unix/sysv/linux/x86_64/recv.c @@ -25,16 +25,7 @@ ssize_t __libc_recv (int fd, void *buf, size_t n, int flags) { - if (SINGLE_THREAD_P) - return INLINE_SYSCALL (recvfrom, 6, fd, buf, n, flags, NULL, NULL); - - int oldtype = LIBC_CANCEL_ASYNC (); - - ssize_t result = INLINE_SYSCALL (recvfrom, 6, fd, buf, n, flags, NULL, NULL); - - LIBC_CANCEL_RESET (oldtype); - - return result; + return SYSCALL_CANCEL (recvfrom, fd, buf, n, flags, NULL, NULL); } weak_alias (__libc_recv, __recv) diff --git a/sysdeps/unix/sysv/linux/x86_64/send.c b/sysdeps/unix/sysv/linux/x86_64/send.c index 36a1dfd..95f04f5 100644 --- a/sysdeps/unix/sysv/linux/x86_64/send.c +++ b/sysdeps/unix/sysv/linux/x86_64/send.c @@ -23,17 +23,7 @@ ssize_t __libc_send (int fd, const void *buf, size_t n, int flags) { - if (SINGLE_THREAD_P) - return INLINE_SYSCALL (sendto, 6, fd, buf, n, flags, NULL, (size_t) 0); - - int oldtype = LIBC_CANCEL_ASYNC (); - - ssize_t result = INLINE_SYSCALL (sendto, 6, fd, buf, n, flags, NULL, - (size_t) 0); - - LIBC_CANCEL_RESET (oldtype); - - return result; + return SYSCALL_CANCEL (sendto, fd, buf, n, flags, NULL, (size_t) 0); } weak_alias (__libc_send, __send) diff --git a/sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S b/sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S new file mode 100644 index 0000000..55c48c1 --- /dev/null +++ b/sysdeps/unix/sysv/linux/x86_64/syscall_cancel.S @@ -0,0 +1,49 @@ +/* Cancellable syscall wrapper - powerpc 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 + . */ + +#include + +ENTRY (__syscall_cancel_arch) + + .globl __syscall_cancel_arch_start + .type __syscall_cancel_arch_start,@function +__syscall_cancel_arch_start: + + mov (%rdi),%eax + testb $4, (%rdi) + jne __syscall_do_cancel + + 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) diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h b/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h index 83cd25f..f17f1df 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep-cancel.h @@ -24,81 +24,30 @@ #if !defined NOT_IN_libc || defined IS_IN_libpthread || defined 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. */ +# ifndef NOT_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 - - -# ifdef IS_IN_libpthread -# define CENABLE call __pthread_enable_asynccancel; -# define CDISABLE call __pthread_disable_asynccancel; -# define __local_multiple_threads __pthread_multiple_threads -# elif !defined NOT_IN_libc -# define CENABLE call __libc_enable_asynccancel; -# define CDISABLE call __libc_disable_asynccancel; -# define __local_multiple_threads __libc_multiple_threads -# elif defined IS_IN_librt -# define CENABLE call __librt_enable_asynccancel; -# define CDISABLE call __librt_disable_asynccancel; -# else -# error Unsupported library -# endif - -# if defined IS_IN_libpthread || !defined NOT_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 - -# 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 - -# endif - -#elif !defined __ASSEMBLER__ - -# define SINGLE_THREAD_P (1) -# define NO_CANCELLATION 1 + 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; #endif diff --git a/sysdeps/unix/sysv/linux/x86_64/sysdep.h b/sysdeps/unix/sysv/linux/x86_64/sysdep.h index 4a619da..e41eeea 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sysdep.h +++ b/sysdeps/unix/sysv/linux/x86_64/sysdep.h @@ -307,6 +307,15 @@ INTERNAL_SYSCALL (name, err, nr, ##args) # endif +# 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)) + + # define LOAD_ARGS_0() # define LOAD_REGS_0 # define ASM_ARGS_0 diff --git a/sysdeps/x86_64/nptl/pthreaddef.h b/sysdeps/x86_64/nptl/pthreaddef.h index 485a625..2226d1a 100644 --- a/sysdeps/x86_64/nptl/pthreaddef.h +++ b/sysdeps/x86_64/nptl/pthreaddef.h @@ -16,6 +16,9 @@ License along with the GNU C Library; if not, see . */ +#ifndef _PTHREADDEF_H +# define _PTHREADDEF_H + /* Default stack size. */ #define ARCH_STACK_DEFAULT_SIZE (2 * 1024 * 1024) @@ -42,3 +45,13 @@ /* Location of current stack frame. The frame pointer is not usable. */ #define CURRENT_STACK_FRAME \ ({ register char *frame __asm__("rsp"); frame; }) + +#ifndef __ASSEMBLER__ +static inline +long int __pthread_get_ip (const ucontext_t *uc) +{ + return (long int)uc->uc_mcontext.gregs[REG_RIP]; +} +#endif + +#endif diff --git a/sysdeps/x86_64/nptl/tcb-offsets.sym b/sysdeps/x86_64/nptl/tcb-offsets.sym index 729d1da..026c9de 100644 --- a/sysdeps/x86_64/nptl/tcb-offsets.sym +++ b/sysdeps/x86_64/nptl/tcb-offsets.sym @@ -21,7 +21,6 @@ RTLD_SAVESPACE_SSE offsetof (tcbhead_t, rtld_savespace_sse) -- 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 diff --git a/sysdeps/x86_64/nptl/tls.h b/sysdeps/x86_64/nptl/tls.h index 3e811b6..08423f6 100644 --- a/sysdeps/x86_64/nptl/tls.h +++ b/sysdeps/x86_64/nptl/tls.h @@ -325,17 +325,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" \