summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdhemerval Zanella <adhemerval.zanella@linaro.org>2023-04-03 11:40:10 -0300
committerAdhemerval Zanella <adhemerval.zanella@linaro.org>2023-04-10 15:42:51 -0300
commit7df625b1cf19041fd9e29269c5729d555eab358b (patch)
tree33305b339dd58920e0b7508dfd9317df77f88753
parentf63c37ef1faa4d343e11f57b5300338951af435c (diff)
downloadglibc-7df625b1cf19041fd9e29269c5729d555eab358b.tar.gz
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 add a requirement on all architectures to support {INLINE,INTERNAL)_SYSCALL with 7 argument, mips 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). Checked on mips-linux-gnu, mips64-linux-gnu, and mips64-n32-linux-gnu.
-rw-r--r--nptl/cancellation.c11
-rw-r--r--sysdeps/nptl/pthreadP.h4
-rw-r--r--sysdeps/unix/sysdep.h69
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/syscall_cancel.S128
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/sysdep.h4
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n32/syscall_types.h28
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/syscall_cancel.S108
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/sysdep.h52
-rw-r--r--sysdeps/unix/sysv/linux/syscall_cancel.c6
9 files changed, 354 insertions, 56 deletions
diff --git a/nptl/cancellation.c b/nptl/cancellation.c
index eee5b6b758..3162492b80 100644
--- a/nptl/cancellation.c
+++ b/nptl/cancellation.c
@@ -25,6 +25,7 @@ long int
__internal_syscall_cancel (__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_CANCEL7_ARG_DEF
__syscall_arg_t nr)
{
long int result;
@@ -36,7 +37,8 @@ __internal_syscall_cancel (__syscall_arg_t a1, __syscall_arg_t a2,
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_ARCH_ARG7);
if (INTERNAL_SYSCALL_ERROR_P (result))
return -INTERNAL_SYSCALL_ERRNO (result);
return result;
@@ -45,7 +47,7 @@ __internal_syscall_cancel (__syscall_arg_t a1, __syscall_arg_t a2,
/* 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_ARCH_ARG7);
/* If the cancellable syscall was interrupted by SIGCANCEL and it has not
side-effect, cancel the thread if cancellation is enabled. */
@@ -63,9 +65,10 @@ long int
__syscall_cancel (__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 nr)
+ __SYSCALL_CANCEL7_ARG_DEF __syscall_arg_t nr)
{
- int r = __internal_syscall_cancel (a1, a2, a3, a4, a5, a6, nr);
+ int r = __internal_syscall_cancel (a1, a2, a3, a4, a5, a6,
+ __SYSCALL_CANCEL7_ARG nr);
return __glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (r))
? SYSCALL_ERROR_LABEL (INTERNAL_SYSCALL_ERRNO (r))
: r;
diff --git a/sysdeps/nptl/pthreadP.h b/sysdeps/nptl/pthreadP.h
index 15a7a063e5..a9d351b9b8 100644
--- a/sysdeps/nptl/pthreadP.h
+++ b/sysdeps/nptl/pthreadP.h
@@ -276,8 +276,8 @@ __do_cancel (void *result)
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_ARCH_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 32bc85592e..1cb1f1d9b7 100644
--- a/sysdeps/unix/sysdep.h
+++ b/sysdeps/unix/sysdep.h
@@ -137,34 +137,59 @@
/* Cancellation macros. */
#include <syscall_types.h>
+/* 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 a7,
+# define __SYSCALL_CANCEL7_ARCH_ARG_DEF ,__syscall_arg_t a7
+# define __SYSCALL_CANCEL7_ARG 0,
+# define __SYSCALL_CANCEL7_ARG7 a7,
+# define __SYSCALL_CANCEL7_ARCH_ARG7 , a7
+#else
+# define __SYSCALL_CANCEL7_ARG_DEF
+# define __SYSCALL_CANCEL7_ARCH_ARG_DEF
+# define __SYSCALL_CANCEL7_ARG
+# define __SYSCALL_CANCEL7_ARG7
+# define __SYSCALL_CANCEL7_ARCH_ARG7
+#endif
long int __internal_syscall_cancel (__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_CANCEL7_ARG_DEF
__syscall_arg_t nr) attribute_hidden;
-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) attribute_hidden;
+long int __syscall_cancel (__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_CANCEL7_ARG_DEF
+ __syscall_arg_t nr) attribute_hidden;
#define __SYSCALL_CANCEL0(name) \
- __syscall_cancel (0, 0, 0, 0, 0, 0, __NR_##name)
+ __syscall_cancel (0, 0, 0, 0, 0, 0, __SYSCALL_CANCEL7_ARG __NR_##name)
#define __SYSCALL_CANCEL1(name, a1) \
- __syscall_cancel (__SSC (a1), 0, 0, 0, 0, 0, __NR_##name)
+ __syscall_cancel (__SSC (a1), 0, 0, 0, 0, 0, \
+ __SYSCALL_CANCEL7_ARG __NR_##name)
#define __SYSCALL_CANCEL2(name, a1, a2) \
- __syscall_cancel (__SSC (a1), __SSC (a2), 0, 0, 0, 0, __NR_##name)
+ __syscall_cancel (__SSC (a1), __SSC (a2), 0, 0, 0, 0, \
+ __SYSCALL_CANCEL7_ARG __NR_##name)
#define __SYSCALL_CANCEL3(name, a1, a2, a3) \
__syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), 0, 0, 0, \
- __NR_##name)
+ __SYSCALL_CANCEL7_ARG __NR_##name)
#define __SYSCALL_CANCEL4(name, a1, a2, a3, a4) \
__syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), \
- __SSC(a4), 0, 0, __NR_##name)
+ __SSC(a4), 0, 0, __SYSCALL_CANCEL7_ARG __NR_##name)
#define __SYSCALL_CANCEL5(name, a1, a2, a3, a4, a5) \
__syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), __SSC(a4), \
- __SSC (a5), 0, __NR_##name)
+ __SSC (a5), 0, __SYSCALL_CANCEL7_ARG __NR_##name)
#define __SYSCALL_CANCEL6(name, a1, a2, a3, a4, a5, a6) \
__syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), __SSC (a4), \
- __SSC (a5), __SSC (a6), __NR_##name)
+ __SSC (a5), __SSC (a6), __SYSCALL_CANCEL7_ARG \
+ __NR_##name)
+#define __SYSCALL_CANCEL7(name, a1, a2, a3, a4, a5, a6, a7) \
+ __syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), __SSC (a4), \
+ __SSC (a5), __SSC (a6), __SSC (a7), __NR_##name)
#define __SYSCALL_CANCEL_NARGS_X(a,b,c,d,e,f,g,h,n,...) n
#define __SYSCALL_CANCEL_NARGS(...) \
@@ -181,25 +206,33 @@ long int __syscall_cancel (__syscall_arg_t nr, __syscall_arg_t arg1,
__SYSCALL_CANCEL_DISP (__SYSCALL_CANCEL, __VA_ARGS__)
#define __INTERNAL_SYSCALL_CANCEL0(name) \
- __internal_syscall_cancel (0, 0, 0, 0, 0, 0, __NR_##name)
+ __internal_syscall_cancel (0, 0, 0, 0, 0, 0, __SYSCALL_CANCEL7_ARG \
+ __NR_##name)
#define __INTERNAL_SYSCALL_CANCEL1(name, a1) \
- __internal_syscall_cancel (__SSC (a1), 0, 0, 0, 0, 0, __NR_##name)
+ __internal_syscall_cancel (__SSC (a1), 0, 0, 0, 0, 0, \
+ __SYSCALL_CANCEL7_ARG __NR_##name)
#define __INTERNAL_SYSCALL_CANCEL2(name, a1, a2) \
__internal_syscall_cancel (__SSC (a1), __SSC (a2), 0, 0, 0, 0, \
- __NR_##name)
+ __SYSCALL_CANCEL7_ARG __NR_##name)
#define __INTERNAL_SYSCALL_CANCEL3(name, a1, a2, a3) \
__internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), 0, \
- 0, 0, __NR_##name)
+ 0, 0, __SYSCALL_CANCEL7_ARG __NR_##name)
#define __INTERNAL_SYSCALL_CANCEL4(name, a1, a2, a3, a4) \
__internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), \
- __SSC(a4), 0, 0, __NR_##name)
+ __SSC(a4), 0, 0, \
+ __SYSCALL_CANCEL7_ARG __NR_##name)
#define __INTERNAL_SYSCALL_CANCEL5(name, a1, a2, a3, a4, a5) \
__internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), \
- __SSC(a4), __SSC (a5), 0, __NR_##name)
+ __SSC(a4), __SSC (a5), 0, \
+ __SYSCALL_CANCEL7_ARG __NR_##name)
#define __INTERNAL_SYSCALL_CANCEL6(name, a1, a2, a3, a4, a5, a6) \
__internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), \
__SSC (a4), __SSC (a5), __SSC (a6), \
- __NR_##name)
+ __SYSCALL_CANCEL7_ARG __NR_##name)
+#define __INTERNAL_SYSCALL_CANCEL7(name, a1, a2, a3, a4, a5, a6, a7) \
+ __internal_syscall_cancel (__SSC (a1), __SSC (a2), __SSC (a3), \
+ __SSC (a4), __SSC (a5), __SSC (a6), \
+ __SSC (a7), __NR_##name)
/* Issue a cancellable syscall defined by syscall number NAME plus any other
argument required. If an error occurs its value is returned as an negative
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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+#include <descr-const.h>
+
+/* 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 <sysdeps/unix/sysv/linux/mips/sysdep.h>
#include <sysdeps/unix/sysv/linux/sysdep.h>
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
+ <https://www.gnu.org/licenses/>. */
+
+#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..f172041324
--- /dev/null
+++ b/sysdeps/unix/sysv/linux/mips/mips64/syscall_cancel.S
@@ -0,0 +1,108 @@
+/* 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
+ <http://www.gnu.org/licenses/>. */
+
+#include <sysdep.h>
+#include <sys/asm.h>
+#include <descr-const.h>
+
+/* 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 32
+
+ .text
+NESTED (__syscall_cancel_arch, FRAME_SIZE, ra)
+ .mask 0x90010000, -SZREG
+ .fmask 0x00000000, 0
+ LONG_ADDIU sp, sp, -FRAME_SIZE
+ cfi_def_cfa_offset (FRAME_SIZE)
+ sd gp, 16(sp)
+ cfi_offset (gp, -16)
+ lui gp, %hi(%neg(%gp_rel(__syscall_cancel_arch)))
+ LONG_ADDU gp, gp, t9
+ sd ra, 24(sp)
+ sd s0, 8(sp)
+ cfi_offset (ra, -8)
+ cfi_offset (s0, -24)
+ LONG_ADDIU gp, gp, %lo(%neg(%gp_rel(__syscall_cancel_arch)))
+
+ .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:
+ ld ra, 24(sp)
+ ld gp, 16(sp)
+ ld s0, 8(sp)
+
+ .set noreorder
+ .set nomacro
+ jr ra
+ LONG_ADDIU sp, sp, FRAME_SIZE
+ .set macro
+ .set reorder
+
+ cfi_remember_state
+ cfi_def_cfa_offset (0)
+ cfi_restore (s0)
+ cfi_restore (gp)
+ cfi_restore (ra)
+ .align 3
+2:
+ cfi_restore_state
+ LONG_L t9, %got_disp(__syscall_do_cancel)(gp)
+ .reloc 3f, R_MIPS_JALR, __syscall_do_cancel
+3: jalr t9
+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 <syscall_types.h>
/* 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 260680c99f..5fa0706486 100644
--- a/sysdeps/unix/sysv/linux/syscall_cancel.c
+++ b/sysdeps/unix/sysv/linux/syscall_cancel.c
@@ -52,7 +52,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 ( \
@@ -63,7 +64,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);