From patchwork Thu Sep 17 20:04:06 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella Netto X-Patchwork-Id: 53851 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f199.google.com (mail-lb0-f199.google.com [209.85.217.199]) by patches.linaro.org (Postfix) with ESMTPS id A5CE022E57 for ; Thu, 17 Sep 2015 20:06:42 +0000 (UTC) Received: by lbbmp1 with SMTP id mp1sf9865222lbb.2 for ; Thu, 17 Sep 2015 13:06:41 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:delivered-to:mailing-list:precedence:list-id :list-unsubscribe:list-subscribe:list-archive:list-post:list-help :sender:delivered-to:from:subject:to:message-id:date:user-agent :mime-version:content-type:content-transfer-encoding :x-original-sender:x-original-authentication-results; bh=0kdj1CPyd5g06fFV9dn7rF6fJtxsCgXrbn2U145W85k=; b=dD2ZGiLkaOpRNMfPnA7PnMn72G/zebaQpoYJNJ4uHKftSmbwICQvNrPaHjWwbjMtnY MmWaVBsw/rz9uKOakuNuuZPgpPXVghiq9l+PQHo5fd3DW932mjPSCW0Xn6x+oQcCFdjl sVhXtu9xj4kaeR8lFkfTobiyCfqus4IR1IEMU/nmPn2rn26sn8RTA6ERtnNibwjkY06G oEerD9ODhjTZqsbsUdCEaelBa94/fOOfbS3ldo3gcj+BFoO9ulTIYQKXJPJr4S60GU// h8zTEuH8vSzna6PWO9QVgc7ljls7CopXpHCFVf2YxgyRvttAjcS3DIYcNWqBLCOFA8G1 dVLg== X-Gm-Message-State: ALoCoQk/JNn8VliENyL4JVd2kHdfHnF+xrQ94SJqgEp8wu8Rmt4dOI8BUnXTlHQGU/pRA6eUArAu X-Received: by 10.180.96.226 with SMTP id dv2mr1136230wib.2.1442520401577; Thu, 17 Sep 2015 13:06:41 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.245.140 with SMTP id xo12ls140543lac.73.gmail; Thu, 17 Sep 2015 13:06:41 -0700 (PDT) X-Received: by 10.152.9.162 with SMTP id a2mr1245961lab.102.1442520305742; Thu, 17 Sep 2015 13:05:05 -0700 (PDT) Received: from mail-la0-x233.google.com (mail-la0-x233.google.com. [2a00:1450:4010:c03::233]) by mx.google.com with ESMTPS id w6si3409215lal.121.2015.09.17.13.05.05 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 17 Sep 2015 13:05:05 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2a00:1450:4010:c03::233 as permitted sender) client-ip=2a00:1450:4010:c03::233; Received: by lamp12 with SMTP id p12so17867744lam.0 for ; Thu, 17 Sep 2015 13:05:05 -0700 (PDT) X-Received: by 10.112.156.167 with SMTP id wf7mr1220563lbb.88.1442520305614; Thu, 17 Sep 2015 13:05:05 -0700 (PDT) X-Forwarded-To: patchwork-forward@linaro.org X-Forwarded-For: patch@linaro.org patchwork-forward@linaro.org Delivered-To: patch@linaro.org Received: by 10.112.59.35 with SMTP id w3csp3265061lbq; Thu, 17 Sep 2015 13:05:04 -0700 (PDT) X-Received: by 10.66.101.97 with SMTP id ff1mr1781892pab.91.1442520304166; Thu, 17 Sep 2015 13:05:04 -0700 (PDT) Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id tc9si7546118pac.230.2015.09.17.13.05.03 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 17 Sep 2015 13:05:04 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-63263-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Received: (qmail 108362 invoked by alias); 17 Sep 2015 20:04:38 -0000 Mailing-List: list patchwork-forward@linaro.org; contact patchwork-forward+owners@linaro.org Precedence: list 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 107727 invoked by uid 89); 17 Sep 2015 20:04:33 -0000 X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.3 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-yk0-f179.google.com X-Received: by 10.170.44.19 with SMTP id 19mr1225728ykm.4.1442520247070; Thu, 17 Sep 2015 13:04:07 -0700 (PDT) From: Adhemerval Zanella Subject: [PATCH 05/10] nptl: i386: Fix Race conditions in pthread cancellation (BZ#12683) To: GNU C Library Message-ID: <55FB1CB6.2020901@linaro.org> Date: Thu, 17 Sep 2015 17:04:06 -0300 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.2.0 MIME-Version: 1.0 X-Original-Sender: adhemerval.zanella@linaro.org X-Original-Authentication-Results: mx.google.com; spf=pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2a00:1450:4010:c03::233 as permitted sender) smtp.mailfrom=patch+caf_=patchwork-forward=linaro.org@linaro.org; dkim=pass header.i=@sourceware.org X-Google-Group-Id: 836684582541 This patch adds the i386 modifications 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. This patch relies on default C implementation for pthread_cond, since it does not contain the required modification for the x86_64 specific assembly implementation. --- * sysdeps/i386/nptl/tls.h (THREAD_ATOMIC_BIT_SET): Remove macro. * sysdeps/unix/sysv/linux/i386/Makefile [$(subdir) = elf] (sysdep-rtld_routines): Add libc-do-syscall object. * sysdeps/unix/sysv/linux/i386/lowlevellock.h (lll_wait_tid): Use cancellable futex syscall macro. * sysdeps/unix/sysv/linux/i386/syscall_cancel.S: New file. * sysdeps/unix/sysv/linux/i386/sysdep-cancel.h (PSEUDO): Redefine to call __syscall_cancel function for cancellable syscalls. * sysdeps/unix/sysv/linux/i386/sysdep.h (SYSCALL_CANCEL_ERROR): New define. (SYSCALL_CANCEL_ERRNO): Likewise. (INTERNAL_SYSCALL_MAIN_NCS_0): Likewise. (INTERNAL_SYSCALL_MAIN_NCS_1): Likewise. (INTERNAL_SYSCALL_MAIN_NCS_2): Likewise. (INTERNAL_SYSCALL_MAIN_NCS_3): Likewise. (INTERNAL_SYSCALL_MAIN_NCS_4): Likewise. (INTERNAL_SYSCALL_MAIN_NCS_5): Likewise. (INTERNAL_SYSCALL_MAIN_NCS_6): Likewise. (INTERNAL_SYSCALL_NCS): Redefine to call it with 6-arguments. -- diff --git a/sysdeps/i386/nptl/tls.h b/sysdeps/i386/nptl/tls.h index 829cd3a..ffac3a8 100644 --- a/sysdeps/i386/nptl/tls.h +++ b/sysdeps/i386/nptl/tls.h @@ -395,17 +395,6 @@ tls_fill_user_desc (union user_desc_init *desc, abort (); }) -/* Atomic set bit. */ -#define THREAD_ATOMIC_BIT_SET(descr, member, bit) \ - (void) ({ if (sizeof ((descr)->member) == 4) \ - asm volatile (LOCK_PREFIX "orl %1, %%gs:%P0" \ - :: "i" (offsetof (struct pthread, member)), \ - "ir" (1 << (bit))); \ - else \ - /* Not necessary for other sizes in the moment. */ \ - abort (); }) - - /* Call the user-provided thread function. */ #define CALL_THREAD_FCT(descr) \ ({ void *__res; \ diff --git a/sysdeps/unix/sysv/linux/i386/Makefile b/sysdeps/unix/sysv/linux/i386/Makefile index 80da593..4f83d08 100644 --- a/sysdeps/unix/sysv/linux/i386/Makefile +++ b/sysdeps/unix/sysv/linux/i386/Makefile @@ -6,6 +6,7 @@ sysdep_routines += ioperm iopl vm86 endif ifeq ($(subdir),elf) +sysdep-rtld_routines += libc-do-syscall sysdep-others += lddlibc4 install-bin += lddlibc4 endif diff --git a/sysdeps/unix/sysv/linux/i386/lowlevellock.h b/sysdeps/unix/sysv/linux/i386/lowlevellock.h index 58f5638..02ea0fc 100644 --- a/sysdeps/unix/sysv/linux/i386/lowlevellock.h +++ b/sysdeps/unix/sysv/linux/i386/lowlevellock.h @@ -283,7 +283,7 @@ extern int __lll_timedlock_elision (int *futex, short *adapt_count, do { \ __typeof (tid) __tid; \ while ((__tid = (tid)) != 0) \ - lll_futex_wait (&(tid), __tid, LLL_SHARED);\ + 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/i386/syscall_cancel.S b/sysdeps/unix/sysv/linux/i386/syscall_cancel.S new file mode 100644 index 0000000..1ff6288 --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/syscall_cancel.S @@ -0,0 +1,105 @@ +/* Cancellable syscall wrapper - x86_64 version. + Copyright (C) 2015 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, see + . */ + +#include + +/* long int [eax] __syscall_cancel_arch (int *cancelhandling [SP], + long int nr [SP+4], + long int arg1 [SP+8], + long int arg2 [SP+12], + long int arg3 [SP+16], + long int arg4 [SP+20], + long int arg5 [SP+24], + long int arg6 [SP+28]) */ + +ENTRY (__syscall_cancel_arch) + pushl %ebp + cfi_def_cfa_offset (8) + cfi_offset (ebp, -8) + pushl %edi + cfi_def_cfa_offset (12) + cfi_offset (edi, -12) + pushl %esi + cfi_def_cfa_offset (16) + cfi_offset (esi, -16) + pushl %ebx + cfi_def_cfa_offset (20) + cfi_offset (ebx, -20) + + .globl __syscall_cancel_arch_start + .type __syscall_cancel_arch_start,@function +__syscall_cancel_arch_start: + + /* if (*cancelhandling & CANCELED_BITMASK) + __syscall_do_cancel() */ + testb $4, (%eax) + jne 1f + + /* Issue a 6 argument syscall, the nr [%eax] being the syscall + number. */ + movl 24(%esp), %eax + movl 28(%esp), %ebx + movl 32(%esp), %ecx + movl 36(%esp), %edx + movl 40(%esp), %esi + movl 44(%esp), %edi + movl 48(%esp), %ebp + + /* It can not use the vDSO __kernel_vsyscall because the cancelable + checks in libc-cancelation.c requires to know if the cancellation + IP value that was trigger between the two + __syscall_cancel_arch_{start,end} marks. */ + int $128 + + .globl __syscall_cancel_arch_end + .type __syscall_cancel_arch_end,@function +__syscall_cancel_arch_end: + + popl %ebx + cfi_restore (ebx) + cfi_def_cfa_offset (16) + popl %esi + cfi_restore (esi) + cfi_def_cfa_offset (12) + popl %edi + cfi_restore (edi) + cfi_def_cfa_offset (8) + popl %ebp + cfi_restore (ebp) + cfi_def_cfa_offset (4) + ret + +1: + /* Although the __syscall_do_cancel do not return, we need to stack + being set correctly so exceptions work correctly. */ + popl %ebx + cfi_restore (ebx) + cfi_def_cfa_offset (16) + popl %esi + cfi_restore (esi) + cfi_def_cfa_offset (12) + popl %edi + cfi_restore (edi) + cfi_def_cfa_offset (8) + popl %ebp + cfi_restore (ebp) + cfi_def_cfa_offset (4) + jmp __syscall_do_cancel + +END (__syscall_cancel_arch) +libc_hidden_def (__syscall_cancel_arch) diff --git a/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h b/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h index 1f86dae..d8cdd27 100644 --- a/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h +++ b/sysdeps/unix/sysv/linux/i386/sysdep-cancel.h @@ -24,112 +24,66 @@ #if IS_IN (libc) || IS_IN (libpthread) || IS_IN (librt) +# if IS_IN (libc) +# define JMP_STARTFUNC \ + subl $16, %esp +# define JMP_SYSCALL_CANCEL \ + HIDDEN_JUMPTARGET(__syscall_cancel) +# define JMP_ENDFUNC \ + addl $44, %esp; \ + cfi_def_cfa_offset (4) +# else +# define JMP_STARTFUNC \ + pushl %ebx; \ + cfi_def_cfa_offset (8); \ + cfi_offset (ebx, -8); \ + SETUP_PIC_REG (bx); \ + addl $_GLOBAL_OFFSET_TABLE_, %ebx; \ + subl $12, %esp +# define JMP_SYSCALL_CANCEL \ + __syscall_cancel@plt +# define JMP_ENDFUNC \ + addl $40, %esp; \ + cfi_def_cfa_offset (8); \ + popl %ebx; \ + cfi_restore (ebx); \ + cfi_def_cfa_offset (4) +# endif + # 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 \ + JMP_STARTFUNC; \ + cfi_def_cfa_offset (20); \ + pushl 40(%esp); \ + cfi_def_cfa_offset (24); \ + pushl 40(%esp); \ + cfi_def_cfa_offset (28); \ + pushl 40(%esp); \ + cfi_def_cfa_offset (32); \ + pushl 40(%esp); \ + cfi_def_cfa_offset (36); \ + pushl 40(%esp); \ + cfi_def_cfa_offset (40); \ + pushl 40(%esp); \ + cfi_def_cfa_offset (44); \ + pushl $SYS_ify (syscall_name); \ + cfi_def_cfa_offset (48); \ + call JMP_SYSCALL_CANCEL; \ + JMP_ENDFUNC; \ cmpl $-4095, %eax; \ jae SYSCALL_ERROR_LABEL -# 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 +# undef PSEUDO_RET +# define PSEUDO_RET # ifndef __ASSEMBLER__ # define SINGLE_THREAD_P \ @@ -150,4 +104,10 @@ # 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_EIP]; +} #endif diff --git a/sysdeps/unix/sysv/linux/i386/sysdep.h b/sysdeps/unix/sysv/linux/i386/sysdep.h index d76aca5..b82e6a2 100644 --- a/sysdeps/unix/sysv/linux/i386/sysdep.h +++ b/sysdeps/unix/sysv/linux/i386/sysdep.h @@ -373,6 +373,42 @@ struct libc_do_syscall_args register unsigned int resultvar; \ INTERNAL_SYSCALL_MAIN_##nr (name, err, args); \ (int) resultvar; }) + +/* Same as INTERNAL_SYSCALL, but for non-constant name argument. */ +#define INTERNAL_SYSCALL_MAIN_NCS_0(name, err, args...) \ + INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, 0, args) +#define INTERNAL_SYSCALL_MAIN_NCS_1(name, err, args...) \ + INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, 1, args) +#define INTERNAL_SYSCALL_MAIN_NCS_2(name, err, args...) \ + INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, 2, args) +#define INTERNAL_SYSCALL_MAIN_NCS_3(name, err, args...) \ + INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, 3, args) +#define INTERNAL_SYSCALL_MAIN_NCS_4(name, err, args...) \ + INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, 4, args) +#define INTERNAL_SYSCALL_MAIN_NCS_5(name, err, args...) \ + INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, 5, args) +/* The NCS version is different because it has a non-constant 'name' arg + and then requires a different asm constraint ("0" instead of "i"). */ +#define INTERNAL_SYSCALL_MAIN_NCS_6(name, err, arg1, arg2, arg3, \ + arg4, arg5, arg6) \ + struct libc_do_syscall_args _xv = \ + { \ + (int) (arg1), \ + (int) (arg5), \ + (int) (arg6) \ + }; \ + asm volatile ( \ + "movl %1, %%eax\n\t" \ + "call __libc_do_syscall" \ + : "=a" (resultvar) \ + : "0" (name), "c" (arg2), "d" (arg3), "S" (arg4), "D" (&_xv) \ + : "memory", "cc") +#define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ + ({ \ + register unsigned int resultvar; \ + INTERNAL_SYSCALL_MAIN_NCS_##nr (name, err, args); \ + (int) resultvar; }) + #ifdef I386_USE_SYSENTER # ifdef SHARED # define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \ @@ -385,9 +421,7 @@ struct libc_do_syscall_args : "=a" (resultvar) \ : "i" (__NR_##name), "i" (offsetof (tcbhead_t, sysinfo)) \ ASMFMT_##nr(args) : "memory", "cc") -# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ - ({ \ - register unsigned int resultvar; \ +# define INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, nr, args...) \ EXTRAVAR_##nr \ asm volatile ( \ LOADARGS_##nr \ @@ -395,8 +429,7 @@ struct libc_do_syscall_args RESTOREARGS_##nr \ : "=a" (resultvar) \ : "0" (name), "i" (offsetof (tcbhead_t, sysinfo)) \ - ASMFMT_##nr(args) : "memory", "cc"); \ - (int) resultvar; }) + ASMFMT_##nr(args) : "memory", "cc") # else # define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \ EXTRAVAR_##nr \ @@ -407,17 +440,14 @@ struct libc_do_syscall_args RESTOREARGS_##nr \ : "=a" (resultvar) \ : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc") -# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ - ({ \ - register unsigned int resultvar; \ +# define INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, nr, args...) \ EXTRAVAR_##nr \ asm volatile ( \ LOADARGS_##nr \ "call *_dl_sysinfo\n\t" \ RESTOREARGS_##nr \ : "=a" (resultvar) \ - : "0" (name) ASMFMT_##nr(args) : "memory", "cc"); \ - (int) resultvar; }) + : "0" (name) ASMFMT_##nr(args) : "memory", "cc") # endif #else # define INTERNAL_SYSCALL_MAIN_INLINE(name, err, nr, args...) \ @@ -429,17 +459,14 @@ struct libc_do_syscall_args RESTOREARGS_##nr \ : "=a" (resultvar) \ : "i" (__NR_##name) ASMFMT_##nr(args) : "memory", "cc") -# define INTERNAL_SYSCALL_NCS(name, err, nr, args...) \ - ({ \ - register unsigned int resultvar; \ +# define INTERNAL_SYSCALL_MAIN_INLINE_NCS(name, err, nr, args...) \ EXTRAVAR_##nr \ asm volatile ( \ LOADARGS_##nr \ "int $0x80\n\t" \ RESTOREARGS_##nr \ : "=a" (resultvar) \ - : "0" (name) ASMFMT_##nr(args) : "memory", "cc"); \ - (int) resultvar; }) + : "0" (name) ASMFMT_##nr(args) : "memory", "cc") #endif #undef INTERNAL_SYSCALL_DECL @@ -452,6 +479,14 @@ struct libc_do_syscall_args #undef INTERNAL_SYSCALL_ERRNO #define INTERNAL_SYSCALL_ERRNO(val, err) (-(val)) +#undef SYSCALL_CANCEL_ERROR +#define SYSCALL_CANCEL_ERROR(__val) \ + ((unsigned int) (__val) >= 0xfffff001u) + +#undef SYSCALL_CANCEL_ERRNO +#define SYSCALL_CANCEL_ERRNO(__val) \ + (-(__val)) + #define LOADARGS_0 #ifdef __PIC__ # if defined I386_USE_SYSENTER && defined SHARED diff --git a/sysdeps/unix/sysv/linux/socketcall.h b/sysdeps/unix/sysv/linux/socketcall.h index 007acba..1bd29fe 100644 --- a/sysdeps/unix/sysv/linux/socketcall.h +++ b/sysdeps/unix/sysv/linux/socketcall.h @@ -86,13 +86,35 @@ sc_ret; \ }) -#define SOCKETCALL_CANCEL(name, __a1, __a2, __a3, __a4, __a5, __a6) \ + +#define __SOCKETCALL_CANCEL1(__name, __a1) \ + SYSCALL_CANCEL_NCS (socketcall, __name, \ + ((long int [1]) { (long int) __a1 })) +#define __SOCKETCALL_CANCEL2(__name, __a1, __a2) \ + SYSCALL_CANCEL_NCS (socketcall, __name, \ + ((long int [2]) { (long int) __a1, (long int) __a2 })) +#define __SOCKETCALL_CANCEL3(__name, __a1, __a2, __a3) \ + SYSCALL_CANCEL_NCS (socketcall, __name, \ + ((long int [3]) { (long int) __a1, (long int) __a2, (long int) __a3 })) +#define __SOCKETCALL_CANCEL4(__name, __a1, __a2, __a3, __a4) \ + SYSCALL_CANCEL_NCS (socketcall, __name, \ + ((long int [4]) { (long int) __a1, (long int) __a2, (long int) __a3, \ + (long int) __a4 })) +#define __SOCKETCALL_CANCEL5(__name, __a1, __a2, __a3, __a4, __a5) \ + SYSCALL_CANCEL_NCS (socketcall, __name, \ + ((long int [5]) { (long int) __a1, (long int) __a2, (long int) __a3, \ + (long int) __a4, (long int) __a5 })) +#define __SOCKETCALL_CANCEL6(__name, __a1, __a2, __a3, __a4, __a5, __a6) \ + SYSCALL_CANCEL_NCS (socketcall, __name, \ + ((long int [6]) { (long int) __a1, (long int) __a2, (long int) __a3, \ + (long int) __a4, (long int) __a5, (long int) __a6 })) + +#define __SOCKETCALL_CANCEL(...) __SOCKETCALL_DISP (__SOCKETCALL_CANCEL,\ + __VA_ARGS__) + +#define SOCKETCALL_CANCEL(name, args...) \ ({ \ - __syscall_arg_t __args[6] = { __SSC (__a1), __SSC (__a2), \ - __SSC (__a3), __SSC (__a4), \ - __SSC (__a5), __SSC (__a6) }; \ - long int sc_ret = SYSCALL_CANCEL_NCS (socketcall, SOCKOP_##name, \ - __args); \ + long int sc_ret = __SOCKETCALL_CANCEL (SOCKOP_##name, args); \ if (SYSCALL_CANCEL_ERROR (sc_ret)) \ { \ __set_errno (SYSCALL_CANCEL_ERRNO (sc_ret)); \