From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1791) id 053963858404; Fri, 7 Apr 2023 17:08:47 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 053963858404 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1680887327; bh=f6Xf8tM3HcmD4+b9yS6kS421yh6Vb+nSmnkJgFj3Cq0=; h=From:To:Subject:Date:From; b=TBczdxA9eIfY42WHuJ6AWLiYZTojUGEocGjLldyUrCX/40p8Yk5kF/tpORxq7oIfH dDjJZAyZZZxDSZ2mHr5yvG/YqT3ujF++TNTbZVWRyRUU5oBNdMNbdOvE1cpfc+XS6m IQ8zIgkLeoncpByosXQJaQEE2C7DChk3G7ZSdx9E= Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Adhemerval Zanella To: glibc-cvs@sourceware.org Subject: [glibc/azanella/bz12683] mips: Fix Race conditions in pthread cancellation [BZ#12683] X-Act-Checkin: glibc X-Git-Author: Adhemerval Zanella X-Git-Refname: refs/heads/azanella/bz12683 X-Git-Oldrev: b604fc6209bf24389b4ff82240f64fd9259b89cd X-Git-Newrev: dff30ac5678445f9e8440904ab50edb7869c31bd Message-Id: <20230407170847.053963858404@sourceware.org> Date: Fri, 7 Apr 2023 17:08:47 +0000 (GMT) List-Id: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=dff30ac5678445f9e8440904ab50edb7869c31bd commit dff30ac5678445f9e8440904ab50edb7869c31bd Author: Adhemerval Zanella Date: Mon Apr 3 11:40:10 2023 -0300 mips: Fix Race conditions in pthread cancellation [BZ#12683] It adds the arch-specific cancellation syscall bridge and adjust the cancellable syscall bridge to accept 7 arguments (as required by mips o32). To avoid code pessimization and add a requirement on all architectures to support {INLINE,INTERNAL)_SYSCALL with 7 argument, its support is added through a flag, HAVE_CANCELABLE_SYSCALL_WITH_7_ARGS, which changes the signature and prototype of the requires macros and functions (SYSCALL_CANCEL, __syscall_cancel and __syscall_cancel_arch). As default 6 arguments cancellable syscalls are use. Checked on mips-linux-gnu, mips64-linux-gnu, and mips64-n32-linux-gnu. Diff: --- nptl/cancellation.c | 7 +- sysdeps/nptl/pthreadP.h | 4 +- sysdeps/unix/sysdep.h | 36 ++++-- .../unix/sysv/linux/mips/mips32/syscall_cancel.S | 128 ++++++++++++++++++++ sysdeps/unix/sysv/linux/mips/mips32/sysdep.h | 4 + .../sysv/linux/mips/mips64/n32/syscall_types.h | 28 +++++ .../unix/sysv/linux/mips/mips64/syscall_cancel.S | 130 +++++++++++++++++++++ sysdeps/unix/sysv/linux/mips/mips64/sysdep.h | 52 ++++----- sysdeps/unix/sysv/linux/syscall_cancel.c | 6 +- 9 files changed, 350 insertions(+), 45 deletions(-) diff --git a/nptl/cancellation.c b/nptl/cancellation.c index 3f991ab9b3..c5381f764b 100644 --- a/nptl/cancellation.c +++ b/nptl/cancellation.c @@ -24,7 +24,7 @@ long int __syscall_cancel (__syscall_arg_t nr, __syscall_arg_t a1, __syscall_arg_t a2, __syscall_arg_t a3, __syscall_arg_t a4, __syscall_arg_t a5, - __syscall_arg_t a6) + __syscall_arg_t a6 __SYSCALL_CANCEL7_ARG_DEF) { long int result; struct pthread *pd = THREAD_SELF; @@ -35,7 +35,8 @@ __syscall_cancel (__syscall_arg_t nr, __syscall_arg_t a1, int ch = atomic_load_relaxed (&pd->cancelhandling); if (SINGLE_THREAD_P || !cancel_enabled (ch) || cancel_exiting (ch)) { - result = INTERNAL_SYSCALL_NCS_CALL (nr, a1, a2, a3, a4, a5, a6); + result = INTERNAL_SYSCALL_NCS_CALL (nr, a1, a2, a3, a4, a5, a6 + __SYSCALL_CANCEL7_ARG7); if (INTERNAL_SYSCALL_ERROR_P (result)) return -INTERNAL_SYSCALL_ERRNO (result); return result; @@ -44,7 +45,7 @@ __syscall_cancel (__syscall_arg_t nr, __syscall_arg_t a1, /* Call the arch-specific entry points that contains the globals markers to be checked by SIGCANCEL handler. */ result = __syscall_cancel_arch (&pd->cancelhandling, nr, a1, a2, a3, a4, a5, - a6); + a6 __SYSCALL_CANCEL7_ARG7); ch = atomic_load_relaxed (&pd->cancelhandling); if (result == -EINTR && cancel_enabled_and_canceled (ch)) diff --git a/sysdeps/nptl/pthreadP.h b/sysdeps/nptl/pthreadP.h index c893267c52..631d4a1a35 100644 --- a/sysdeps/nptl/pthreadP.h +++ b/sysdeps/nptl/pthreadP.h @@ -274,8 +274,8 @@ __do_cancel (void) extern long int __syscall_cancel_arch (volatile int *, __syscall_arg_t nr, __syscall_arg_t arg1, __syscall_arg_t arg2, __syscall_arg_t arg3, - __syscall_arg_t arg4, __syscall_arg_t arg5, __syscall_arg_t arg6) - attribute_hidden; + __syscall_arg_t arg4, __syscall_arg_t arg5, __syscall_arg_t arg6 + __SYSCALL_CANCEL7_ARG_DEF) attribute_hidden; extern _Noreturn void __syscall_do_cancel (void) attribute_hidden; diff --git a/sysdeps/unix/sysdep.h b/sysdeps/unix/sysdep.h index 78d5ab6a41..d5b01f62b2 100644 --- a/sysdeps/unix/sysdep.h +++ b/sysdeps/unix/sysdep.h @@ -137,30 +137,50 @@ /* Cancellation macros. */ #include +/* Adjust both the __syscall_cancel and the SYSCALL_CANCEL macro to support + 7 arguments instead of default 6 (curently only mip32). It avoid add + the requirement to each architecture to support 7 argument macros + {INTERNAL,INLINE}_SYSCALL. */ +#ifdef HAVE_CANCELABLE_SYSCALL_WITH_7_ARGS +# define __SYSCALL_CANCEL7_ARG_DEF , __syscall_arg_t arg7 +# define __SYSCALL_CANCEL7_ARG , 0 +# define __SYSCALL_CANCEL7_ARG7 , arg7 +#else +# define __SYSCALL_CANCEL7_ARG_DEF +# define __SYSCALL_CANCEL7_ARG +# define __SYSCALL_CANCEL7_ARG7 +#endif + long int __syscall_cancel (__syscall_arg_t nr, __syscall_arg_t arg1, __syscall_arg_t arg2, __syscall_arg_t arg3, __syscall_arg_t arg4, __syscall_arg_t arg5, - __syscall_arg_t arg6) + __syscall_arg_t arg6 __SYSCALL_CANCEL7_ARG_DEF) attribute_hidden; #define __SYSCALL_CANCEL0(name) \ - __syscall_cancel (__NR_##name, 0, 0, 0, 0, 0, 0) + __syscall_cancel (__NR_##name, 0, 0, 0, 0, 0, 0 __SYSCALL_CANCEL7_ARG) #define __SYSCALL_CANCEL1(name, a1) \ - __syscall_cancel (__NR_##name, __SSC (a1), 0, 0, 0, 0, 0) + __syscall_cancel (__NR_##name, __SSC (a1), 0, 0, 0, 0, 0 \ + __SYSCALL_CANCEL7_ARG) #define __SYSCALL_CANCEL2(name, a1, a2) \ - __syscall_cancel (__NR_##name, __SSC (a1), __SSC (a2), 0, 0, 0, 0) + __syscall_cancel (__NR_##name, __SSC (a1), __SSC (a2), 0, 0, 0, 0 \ + __SYSCALL_CANCEL7_ARG) #define __SYSCALL_CANCEL3(name, a1, a2, a3) \ __syscall_cancel (__NR_##name, __SSC (a1), __SSC (a2), __SSC (a3), \ - 0, 0, 0) + 0, 0, 0 __SYSCALL_CANCEL7_ARG) #define __SYSCALL_CANCEL4(name, a1, a2, a3, a4) \ __syscall_cancel (__NR_##name, __SSC (a1), __SSC (a2), __SSC (a3), \ - __SSC(a4), 0, 0) + __SSC(a4), 0, 0 __SYSCALL_CANCEL7_ARG) #define __SYSCALL_CANCEL5(name, a1, a2, a3, a4, a5) \ __syscall_cancel (__NR_##name, __SSC (a1), __SSC (a2), __SSC (a3), \ - __SSC(a4), __SSC (a5), 0) + __SSC(a4), __SSC (a5), 0 __SYSCALL_CANCEL7_ARG) #define __SYSCALL_CANCEL6(name, a1, a2, a3, a4, a5, a6) \ __syscall_cancel (__NR_##name, __SSC (a1), __SSC (a2), __SSC (a3), \ - __SSC (a4), __SSC (a5), __SSC (a6)) + __SSC (a4), __SSC (a5), __SSC (a6) \ + __SYSCALL_CANCEL7_ARG) +#define __SYSCALL_CANCEL7(name, a1, a2, a3, a4, a5, a6, a7) \ + __syscall_cancel (__NR_##name, __SSC (a1), __SSC (a2), __SSC (a3), \ + __SSC (a4), __SSC (a5), __SSC (a6), __SSC (a7)) #define __SYSCALL_CANCEL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n #define __SYSCALL_CANCEL_NARGS(...) \ diff --git a/sysdeps/unix/sysv/linux/mips/mips32/syscall_cancel.S b/sysdeps/unix/sysv/linux/mips/mips32/syscall_cancel.S new file mode 100644 index 0000000000..eb3b2ed005 --- /dev/null +++ b/sysdeps/unix/sysv/linux/mips/mips32/syscall_cancel.S @@ -0,0 +1,128 @@ +/* Cancellable syscall wrapper. Linux/mips32 version. + Copyright (C) 2023 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 +#include +#include + +/* long int __syscall_cancel_arch (int *cancelhandling, + __syscall_arg_t nr, + __syscall_arg_t arg1, + __syscall_arg_t arg2, + __syscall_arg_t arg3, + __syscall_arg_t arg4, + __syscall_arg_t arg5, + __syscall_arg_t arg6, + __syscall_arg_t arg7) */ + +#define FRAME_SIZE 56 + +NESTED (__syscall_cancel_arch, FRAME_SIZE, fp) + .mask 0xc0070000,-SZREG + .fmask 0x00000000,0 + + PTR_ADDIU sp, -FRAME_SIZE + cfi_def_cfa_offset (FRAME_SIZE) + + sw fp, 48(sp) + sw ra, 52(sp) + sw s2, 44(sp) + sw s1, 40(sp) + sw s0, 36(sp) +#ifdef __PIC__ + .cprestore 16 +#endif + cfi_offset (ra, -4) + cfi_offset (fp, -8) + cfi_offset (s2, -12) + cfi_offset (s1, -16) + cfi_offset (s0, -20) + + move fp ,sp + cfi_def_cfa_register (fp) + + .globl __syscall_cancel_arch_start +__syscall_cancel_arch_start: + + lw v0, 0(a0) + andi v0, v0, TCB_CANCELED_BITMASK + bne v0, zero, 2f + + addiu sp, sp, -16 + addiu v0, sp, 16 + sw v0, 24(fp) + + move s0, a1 + move a0, a2 + move a1, a3 + lw a2, 72(fp) + lw a3, 76(fp) + lw v0, 84(fp) + lw s1, 80(fp) + lw s2, 88(fp) + + .set noreorder + subu sp, 32 + sw s1, 16(sp) + sw v0, 20(sp) + sw s2, 24(sp) + move v0, s0 + syscall + + .globl __syscall_cancel_arch_end +__syscall_cancel_arch_end: + addiu sp, sp, 32 + .set reorder + + beq a3, zero, 1f + subu v0, zero, v0 +1: + move sp, fp + cfi_remember_state + cfi_def_cfa_register (sp) + lw ra, 52(fp) + lw fp, 48(sp) + lw s2, 44(sp) + lw s1, 40(sp) + lw s0, 36(sp) + + .set noreorder + .set nomacro + jr ra + addiu sp,sp,FRAME_SIZE + + .set macro + .set reorder + + cfi_def_cfa_offset (0) + cfi_restore (s0) + cfi_restore (s1) + cfi_restore (s2) + cfi_restore (fp) + cfi_restore (ra) + +2: + cfi_restore_state +#ifdef __PIC__ + PTR_LA t9, __syscall_do_cancel + jalr t9 +#else + jal __syscall_do_cancel +#endif + +END (__syscall_cancel_arch) diff --git a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h index 1318083195..3ba5334d66 100644 --- a/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h +++ b/sysdeps/unix/sysv/linux/mips/mips32/sysdep.h @@ -18,6 +18,10 @@ #ifndef _LINUX_MIPS_MIPS32_SYSDEP_H #define _LINUX_MIPS_MIPS32_SYSDEP_H 1 +/* mips32 have cancelable syscalls with 7 arguments (currently only + sync_file_range). */ +#define HAVE_CANCELABLE_SYSCALL_WITH_7_ARGS 1 + /* There is some commonality. */ #include #include diff --git a/sysdeps/unix/sysv/linux/mips/mips64/n32/syscall_types.h b/sysdeps/unix/sysv/linux/mips/mips64/n32/syscall_types.h new file mode 100644 index 0000000000..b3a8b0b634 --- /dev/null +++ b/sysdeps/unix/sysv/linux/mips/mips64/n32/syscall_types.h @@ -0,0 +1,28 @@ +/* Types and macros used for syscall issuing. MIPS64n32 version. + Copyright (C) 2023 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 + . */ + +#ifndef _SYSCALL_TYPES_H +#define _SYSCALL_TYPES_H + +typedef long long int __syscall_arg_t; + +/* Convert X to a long long, without losing any bits if it is one + already or warning if it is a 32-bit pointer. */ +#define __SSC(__x) ((__syscall_arg_t) (__typeof__ ((__x) - (__x))) (__x)) + +#endif diff --git a/sysdeps/unix/sysv/linux/mips/mips64/syscall_cancel.S b/sysdeps/unix/sysv/linux/mips/mips64/syscall_cancel.S new file mode 100644 index 0000000000..9722e58d75 --- /dev/null +++ b/sysdeps/unix/sysv/linux/mips/mips64/syscall_cancel.S @@ -0,0 +1,130 @@ +/* Cancellable syscall wrapper. Linux/mips64 version. + Copyright (C) 2023 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 +#include +#include + +/* long int __syscall_cancel_arch (int *cancelhandling, + __syscall_arg_t nr, + __syscall_arg_t arg1, + __syscall_arg_t arg2, + __syscall_arg_t arg3, + __syscall_arg_t arg4, + __syscall_arg_t arg5, + __syscall_arg_t arg6, + __syscall_arg_t arg7) */ + +#if _MIPS_SIM == _ABIN32 +# define FRAME_SIZE 16 +# define MASK 0x80010000 +# define RA_OFF 8 +# define S0_OFF 0 +#else +# define FRAME_SIZE 32 +# define MASK 0x90010000 +# define RA_OFF 24 +# define S0_OFF 8 +#endif +#define ADDIU LONG_ADDIU +#define ADDU LONG_ADDU +#define SUBU LONG_SUBU +#define LOAD_L LONG_L + + .text +NESTED (__syscall_cancel_arch, FRAME_SIZE, ra) + .mask MASK, -SZREG + .fmask 0x00000000, 0 + ADDIU sp, sp, -FRAME_SIZE + cfi_def_cfa_offset (FRAME_SIZE) + sd gp, 16(sp) + cfi_offset (gp, -16) +#if _MIPS_SIM == _ABI64 + lui gp, %hi(%neg(%gp_rel(__syscall_cancel_arch))) + ADDU gp, gp, t9 + daddiu gp, gp, %lo(%neg(%gp_rel(__syscall_cancel_arch))) +#endif + sd ra, RA_OFF(sp) + sd s0, S0_OFF(sp) + cfi_offset (ra, -RA_OFF) + cfi_offset (s0, -S0_OFF) + + .global __syscall_cancel_arch_start +__syscall_cancel_arch_start: + + lw v0, 0(a0) + andi v0, v0, TCB_CANCELED_BITMASK + .set noreorder + .set nomacro + bne v0, zero, 2f + move s0, a1 + .set macro + .set reorder + + move a0, a2 + move a1, a3 + move a2, a4 + move a3, a5 + move a4, a6 + move a5, a7 + + .set noreorder + move v0, s0 + syscall + .set reorder + + .global __syscall_cancel_arch_end +__syscall_cancel_arch_end: + + .set noreorder + .set nomacro + bnel a3, zero, 1f + SUBU v0, zero, v0 + .set macro + .set reorder + +1: +#if _MIPS_SIM == _ABI64 + ld gp, 16(sp) +#endif + ld ra, RA_OFF(sp) + ld s0, S0_OFF(sp) + + .set noreorder + .set nomacro + jr ra + daddiu sp, sp, FRAME_SIZE + .set macro + .set reorder + + cfi_remember_state + cfi_def_cfa_offset (0) +#if _MIPS_SIM == _ABI64 + cfi_restore (gp) +#endif + .align 3 +2: + cfi_restore_state +#if _MIPS_SIM == _ABI64 + ld t9, %got_disp(__syscall_do_cancel)(gp) + .reloc 3f, R_MIPS_JALR, __syscall_do_cancel +3: jalr t9 +#else + jal __syscall_do_cancel +#endif +END (__syscall_cancel_arch) diff --git a/sysdeps/unix/sysv/linux/mips/mips64/sysdep.h b/sysdeps/unix/sysv/linux/mips/mips64/sysdep.h index d7ae60f596..db27bd9e4d 100644 --- a/sysdeps/unix/sysv/linux/mips/mips64/sysdep.h +++ b/sysdeps/unix/sysv/linux/mips/mips64/sysdep.h @@ -44,15 +44,7 @@ #undef HAVE_INTERNAL_BRK_ADDR_SYMBOL #define HAVE_INTERNAL_BRK_ADDR_SYMBOL 1 -#if _MIPS_SIM == _ABIN32 -/* Convert X to a long long, without losing any bits if it is one - already or warning if it is a 32-bit pointer. */ -# define ARGIFY(X) ((long long int) (__typeof__ ((X) - (X))) (X)) -typedef long long int __syscall_arg_t; -#else -# define ARGIFY(X) ((long int) (X)) -typedef long int __syscall_arg_t; -#endif +#include /* Note that the original Linux syscall restart convention required the instruction immediately preceding SYSCALL to initialize $v0 with the @@ -120,7 +112,7 @@ typedef long int __syscall_arg_t; long int _sys_result; \ \ { \ - __syscall_arg_t _arg1 = ARGIFY (arg1); \ + __syscall_arg_t _arg1 = __SSC (arg1); \ register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\ = (number); \ register __syscall_arg_t __v0 asm ("$2"); \ @@ -144,8 +136,8 @@ typedef long int __syscall_arg_t; long int _sys_result; \ \ { \ - __syscall_arg_t _arg1 = ARGIFY (arg1); \ - __syscall_arg_t _arg2 = ARGIFY (arg2); \ + __syscall_arg_t _arg1 = __SSC (arg1); \ + __syscall_arg_t _arg2 = __SSC (arg2); \ register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\ = (number); \ register __syscall_arg_t __v0 asm ("$2"); \ @@ -170,9 +162,9 @@ typedef long int __syscall_arg_t; long int _sys_result; \ \ { \ - __syscall_arg_t _arg1 = ARGIFY (arg1); \ - __syscall_arg_t _arg2 = ARGIFY (arg2); \ - __syscall_arg_t _arg3 = ARGIFY (arg3); \ + __syscall_arg_t _arg1 = __SSC (arg1); \ + __syscall_arg_t _arg2 = __SSC (arg2); \ + __syscall_arg_t _arg3 = __SSC (arg3); \ register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\ = (number); \ register __syscall_arg_t __v0 asm ("$2"); \ @@ -199,10 +191,10 @@ typedef long int __syscall_arg_t; long int _sys_result; \ \ { \ - __syscall_arg_t _arg1 = ARGIFY (arg1); \ - __syscall_arg_t _arg2 = ARGIFY (arg2); \ - __syscall_arg_t _arg3 = ARGIFY (arg3); \ - __syscall_arg_t _arg4 = ARGIFY (arg4); \ + __syscall_arg_t _arg1 = __SSC (arg1); \ + __syscall_arg_t _arg2 = __SSC (arg2); \ + __syscall_arg_t _arg3 = __SSC (arg3); \ + __syscall_arg_t _arg4 = __SSC (arg4); \ register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\ = (number); \ register __syscall_arg_t __v0 asm ("$2"); \ @@ -229,11 +221,11 @@ typedef long int __syscall_arg_t; long int _sys_result; \ \ { \ - __syscall_arg_t _arg1 = ARGIFY (arg1); \ - __syscall_arg_t _arg2 = ARGIFY (arg2); \ - __syscall_arg_t _arg3 = ARGIFY (arg3); \ - __syscall_arg_t _arg4 = ARGIFY (arg4); \ - __syscall_arg_t _arg5 = ARGIFY (arg5); \ + __syscall_arg_t _arg1 = __SSC (arg1); \ + __syscall_arg_t _arg2 = __SSC (arg2); \ + __syscall_arg_t _arg3 = __SSC (arg3); \ + __syscall_arg_t _arg4 = __SSC (arg4); \ + __syscall_arg_t _arg5 = __SSC (arg5); \ register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\ = (number); \ register __syscall_arg_t __v0 asm ("$2"); \ @@ -261,12 +253,12 @@ typedef long int __syscall_arg_t; long int _sys_result; \ \ { \ - __syscall_arg_t _arg1 = ARGIFY (arg1); \ - __syscall_arg_t _arg2 = ARGIFY (arg2); \ - __syscall_arg_t _arg3 = ARGIFY (arg3); \ - __syscall_arg_t _arg4 = ARGIFY (arg4); \ - __syscall_arg_t _arg5 = ARGIFY (arg5); \ - __syscall_arg_t _arg6 = ARGIFY (arg6); \ + __syscall_arg_t _arg1 = __SSC (arg1); \ + __syscall_arg_t _arg2 = __SSC (arg2); \ + __syscall_arg_t _arg3 = __SSC (arg3); \ + __syscall_arg_t _arg4 = __SSC (arg4); \ + __syscall_arg_t _arg5 = __SSC (arg5); \ + __syscall_arg_t _arg6 = __SSC (arg6); \ register __syscall_arg_t __s0 asm ("$16") __attribute__ ((unused))\ = (number); \ register __syscall_arg_t __v0 asm ("$2"); \ diff --git a/sysdeps/unix/sysv/linux/syscall_cancel.c b/sysdeps/unix/sysv/linux/syscall_cancel.c index c4d9d4e8bb..af04ef031a 100644 --- a/sysdeps/unix/sysv/linux/syscall_cancel.c +++ b/sysdeps/unix/sysv/linux/syscall_cancel.c @@ -42,7 +42,8 @@ long int __syscall_cancel_arch (volatile int *ch, __syscall_arg_t nr, __syscall_arg_t a1, __syscall_arg_t a2, __syscall_arg_t a3, __syscall_arg_t a4, - __syscall_arg_t a5, __syscall_arg_t a6) + __syscall_arg_t a5, __syscall_arg_t a6 + __SYSCALL_CANCEL7_ARG_DEF) { #define ADD_LABEL(__label) \ asm volatile ( \ @@ -53,7 +54,8 @@ __syscall_cancel_arch (volatile int *ch, __syscall_arg_t nr, if (__glibc_unlikely (*ch & CANCELED_BITMASK)) __syscall_do_cancel(); - long int result = INTERNAL_SYSCALL_NCS_CALL (nr, a1, a2, a3, a4, a5, a6); + long int result = INTERNAL_SYSCALL_NCS_CALL (nr, a1, a2, a3, a4, a5, a6 + __SYSCALL_CANCEL7_ARG7); ADD_LABEL ("__syscall_cancel_arch_end"); if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result))) return -INTERNAL_SYSCALL_ERRNO (result);