From patchwork Mon Aug 31 21:11:15 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Adhemerval Zanella X-Patchwork-Id: 52904 Return-Path: X-Original-To: linaro@patches.linaro.org Delivered-To: linaro@patches.linaro.org Received: from mail-lb0-f197.google.com (mail-lb0-f197.google.com [209.85.217.197]) by patches.linaro.org (Postfix) with ESMTPS id C48F42127E for ; Mon, 31 Aug 2015 21:12:03 +0000 (UTC) Received: by lbcue2 with SMTP id ue2sf42337756lbc.1 for ; Mon, 31 Aug 2015 14:12:02 -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=+4DJDWJ32GprX7pMG0ogVUUza4uutt3y67NL3Nph5Sk=; b=SGesx+NkSUiGFxIAaK8gQetPcG+PurTFPpe4cszk2S3h2yv7RZ9mCNmWh2khn9N/Cm HLltGWNwDeae09YB9VpekEA4oa5INrpsf8JbswkdJzwYrPCOHHj4Kms0N7JksTdC8Tam EOsdOH44ITFrsY4vLTmtcZ0rYnH1U6c60hL2gT98PvrnvLl1QpHo6fdkvz+mx414hbdl IFolx/6UItBJZ62YK6HcBOSJSZBtw3urrNpjXiXbVlaYcP31vK/LmXMPo1245eZm00NN VyxRzbe14Zel1nOFLWiif9ou3YYL1hJIGOKjEHSGWU/djXyPTXavxLEcnQ3f2wcCZfxP H1YQ== X-Gm-Message-State: ALoCoQmpYquyKfYRLdTMVeDVnYc9tv+r07nIWJTS2PSYk0cNuFzOu4Y6GG+X/aUven+4X+mYyAFf X-Received: by 10.112.122.42 with SMTP id lp10mr6687799lbb.5.1441055522704; Mon, 31 Aug 2015 14:12:02 -0700 (PDT) X-BeenThere: patchwork-forward@linaro.org Received: by 10.152.9.164 with SMTP id a4ls458189lab.105.gmail; Mon, 31 Aug 2015 14:12:02 -0700 (PDT) X-Received: by 10.152.36.161 with SMTP id r1mr11201016laj.82.1441055522435; Mon, 31 Aug 2015 14:12:02 -0700 (PDT) Received: from mail-lb0-x231.google.com (mail-lb0-x231.google.com. [2a00:1450:4010:c04::231]) by mx.google.com with ESMTPS id k1si14495338lbc.156.2015.08.31.14.12.02 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 31 Aug 2015 14:12:02 -0700 (PDT) Received-SPF: pass (google.com: domain of patch+caf_=patchwork-forward=linaro.org@linaro.org designates 2a00:1450:4010:c04::231 as permitted sender) client-ip=2a00:1450:4010:c04::231; Received: by lbbsx3 with SMTP id sx3so67877480lbb.0 for ; Mon, 31 Aug 2015 14:12:02 -0700 (PDT) X-Received: by 10.152.18.164 with SMTP id x4mr11603784lad.35.1441055522259; Mon, 31 Aug 2015 14:12:02 -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.164.42 with SMTP id yn10csp92017lbb; Mon, 31 Aug 2015 14:12:00 -0700 (PDT) X-Received: by 10.68.109.34 with SMTP id hp2mr40087361pbb.52.1441055520794; Mon, 31 Aug 2015 14:12:00 -0700 (PDT) Received: from sourceware.org (server1.sourceware.org. [209.132.180.131]) by mx.google.com with ESMTPS id ph2si8792633pac.118.2015.08.31.14.11.59 for (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 31 Aug 2015 14:12:00 -0700 (PDT) Received-SPF: pass (google.com: domain of libc-alpha-return-62842-patch=linaro.org@sourceware.org designates 209.132.180.131 as permitted sender) client-ip=209.132.180.131; Received: (qmail 55074 invoked by alias); 31 Aug 2015 21:11: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 54991 invoked by uid 89); 31 Aug 2015 21:11:37 -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-qk0-f181.google.com X-Received: by 10.129.82.132 with SMTP id g126mr23049305ywb.21.1441055478015; Mon, 31 Aug 2015 14:11:18 -0700 (PDT) From: Adhemerval Zanella Subject: [PATCH 05/08] nptl: i386: Fix Race conditions in pthread cancellation (BZ#12683) To: GNU C Library Message-ID: <55E4C2F3.1070207@linaro.org> Date: Mon, 31 Aug 2015 18:11:15 -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:c04::231 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/libc-cancellation.c: New file. * 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. -- 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/libc-cancellation.c b/sysdeps/unix/sysv/linux/i386/libc-cancellation.c new file mode 100644 index 0000000..ff07ea4 --- /dev/null +++ b/sysdeps/unix/sysv/linux/i386/libc-cancellation.c @@ -0,0 +1,46 @@ +/* i386 cancellation definitions. + 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 + +#define INTERNAL_SYSCALL_MAIN_6_NCS(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") + +#undef INTERNAL_SYSCALL_NCS +#define INTERNAL_SYSCALL_NCS(name, err, nr, arg1, arg2, arg3, arg4, \ + arg5, arg6) \ + ({ \ + unsigned int resultvar; \ + INTERNAL_SYSCALL_MAIN_6_NCS (name, err, arg1, arg2, arg3, arg4, \ + arg5, arg6); \ + (int) resultvar; \ + }) + +#include 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..10ae7e0 100644 --- a/sysdeps/unix/sysv/linux/i386/sysdep.h +++ b/sysdeps/unix/sysv/linux/i386/sysdep.h @@ -452,6 +452,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)); \