@@ -117,7 +117,7 @@ __lll_timedlock (int *futex, const struct timespec *abstime, int private)
{ \
__typeof (tid) __tid; \
while ((__tid = (tid)) != 0) \
- lll_futex_wait (&(tid), __tid, LLL_SHARED); \
+ lll_futex_wait_cancel (&(tid), __tid, LLL_SHARED); \
} \
while (0)
@@ -16,6 +16,11 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
+#include <stdint.h>
+
#define SIGCONTEXT struct sigcontext *
#define SIGCONTEXT_EXTRA_ARGS
#define GET_PC(__ctx) ((void *) ((__ctx)->si_regs.pc))
@@ -29,3 +34,50 @@
#define GET_FRAME(__ctx) ADVANCE_STACK_FRAME (GET_STACK(__ctx))
#define CALL_SIGHANDLER(handler, signo, ctx) \
(handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
+
+/* Different that other architectures, SPARC32 pass a pt_regs (or pt_regs32
+ in 32 bits compat mode) struct pointer as third argument for sa_sigaction
+ handler with SA_SIGINFO.
+
+ Also current sparc32 rt signal frame layout is:
+
+ field | size
+ ---------------------------------------| ----
+ struct rt_signal_frame { |
+ struct sparc_stackf ss; | 96
+ siginfo_t info; | 128
+ struct pt_regs regs; | 80
+ sigset_t mask; | 128
+ __siginfo_fpu_t __user *fpu_save; | 4
+ unsigned int insns[2]; | 8
+ stack_t stack; | 12
+ unsigned int extra_size; | 4
+ __siginfo_rwin_t __user *rwin_save; | 4
+ };
+
+ So to obtain a pointer to signal mask based on address of pt_regs
+ we need to add 208. */
+
+struct pt_regs32
+{
+ unsigned int psr;
+ unsigned int pc;
+ unsigned int npc;
+ unsigned int y;
+ unsigned int u_regs[16];
+};
+
+static inline uintptr_t
+ucontext_get_pc (struct pt_regs32 *regs)
+{
+ return regs->pc;
+}
+
+static inline sigset_t *
+ucontext_get_mask (const void *ctx)
+{
+ return (sigset_t *)((uintptr_t)ctx + 208);
+}
+#define UCONTEXT_SIGMASK(ctx) ucontext_get_mask (ctx)
+
+#endif /* _SIGCONTEXTINFO_H */
new file mode 100644
@@ -0,0 +1,74 @@
+/* Cancellable syscall wrapper. Linux/sparc32 version.
+ Copyright (C) 2017 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>
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+ long int nr,
+ long int arg1,
+ long int arg2,
+ long int arg3,
+ long int arg4,
+ long int arg5,
+ long int arg6) */
+
+ENTRY (__syscall_cancel_arch)
+ save %sp, -104, %sp
+
+ cfi_window_save
+ cfi_register (15, 31)
+ cfi_def_cfa_register (30)
+
+ .globl __syscall_cancel_arch_start
+__syscall_cancel_arch_start:
+
+ /* if (*cancelhandling & CANCELED_BITMASK)
+ __syscall_do_cancel() */
+ ld [%i0], %g2
+ andcc %g2, 4, %g0
+ bne,pn %icc, 2f
+
+ /* Issue a 6 argument syscall. */
+ mov %i1, %g1
+ mov %i2, %o0
+ mov %i3, %o1
+ mov %i4, %o2
+ mov %i5, %o3
+ ld [%fp+92], %o4
+ ld [%fp+96], %o5
+ ta 0x10
+
+ .globl __syscall_cancel_arch_end
+__syscall_cancel_arch_end:
+ bcc 1f
+ mov 0,%g1
+ sub %g0, %o0, %o0
+ mov 1, %g1
+
+1:
+ mov %o0, %i0
+ return %i7+8
+ nop
+
+2:
+ call __syscall_do_cancel, 0
+ nop
+ nop
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)
new file mode 100644
@@ -0,0 +1,25 @@
+/* Linux pause syscall implementation. Linux/sparc64.
+ Copyright (C) 2017 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 <sys/syscall.h>
+
+/* On sparc interrupted pause syscall returns with a PC indicating a
+ side-effect and this deviates from other architectures. Fall back to
+ ppool implementation. */
+#undef __NR_pause
+#include <sysdeps/unix/sysv/linux/pause.c>
@@ -16,6 +16,11 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#ifndef _SIGCONTEXTINFO_H
+#define _SIGCONTEXTINFO_H
+
+#include <stdint.h>
+
#ifndef STACK_BIAS
#define STACK_BIAS 2047
#endif
@@ -29,3 +34,38 @@
#define GET_FRAME(__ctx) ADVANCE_STACK_FRAME (GET_STACK (__ctx))
#define CALL_SIGHANDLER(handler, signo, ctx) \
(handler)((signo), SIGCONTEXT_EXTRA_ARGS (ctx))
+
+/* Different that other architectures, SPARC64 pass a sigcontext_t struct
+ pointer in third argument for sa_sigaction handler with SA_SIGINFO.
+
+ Also current sparc64 rt signal frame layout is:
+
+ field | size
+ ---------------------------------------| ----
+ struct rt_signal_frame { |
+ struct sparc_stackf ss; | 192
+ siginfo_t info; | 128
+ struct pt_regs regs; | 160
+ __siginfo_fpu_t __user *fpu_save; | 8
+ stack_t stack; | 24
+ sigset_t mask; | 128
+ __siginfo_rwin_t *rwin_save; | 8
+ };
+
+ So to obtain a pointer to signal mask based on address of info
+ we need to add 320. */
+
+static inline uintptr_t
+ucontext_get_pc (const struct sigcontext *sigctx)
+{
+ return sigctx->sigc_regs.tpc;
+}
+
+static inline sigset_t *
+ucontext_get_mask (const void *ctx)
+{
+ return (sigset_t *)((uintptr_t)ctx + 320);
+}
+#define UCONTEXT_SIGMASK(ctx) ucontext_get_mask (ctx)
+
+#endif /* _SIGCONTEXTINFO_H */
new file mode 100644
@@ -0,0 +1,74 @@
+/* Cancellable syscall wrapper. Linux/sparc64 version.
+ Copyright (C) 2017 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>
+
+/* long int __syscall_cancel_arch (int *cancelhandling,
+ long int nr,
+ long int arg1,
+ long int arg2,
+ long int arg3,
+ long int arg4,
+ long int arg5,
+ long int arg6) */
+
+ENTRY (__syscall_cancel_arch)
+ save %sp, -176, %sp
+
+ cfi_window_save
+ cfi_register (15, 31)
+ cfi_def_cfa_register (30)
+
+ .globl __syscall_cancel_arch_start
+__syscall_cancel_arch_start:
+
+ /* if (*cancelhandling & CANCELED_BITMASK)
+ __syscall_do_cancel() */
+ lduw [%i0], %g1
+ andcc %g1, 4, %g0
+ bne,pn %xcc, 2f
+
+ /* Issue a 6 argument syscall. */
+ mov %i1, %g1
+ mov %i2, %o0
+ mov %i3, %o1
+ mov %i4, %o2
+ mov %i5, %o3
+ ldx [%fp + STACK_BIAS + 176], %o4
+ ldx [%fp + STACK_BIAS + 184], %o5
+ ta 0x6d
+
+ .global __syscall_cancel_arch_end
+__syscall_cancel_arch_end:
+
+ bcc,pt %xcc, 1f
+ mov 0, %g1
+ sub %g0, %o0, %o0
+ mov 1, %g1
+1:
+ mov %o0, %i0
+ return %i7+8
+ nop
+
+2:
+ call __syscall_do_cancel, 0
+ nop
+ nop
+
+END (__syscall_cancel_arch)
+libc_hidden_def (__syscall_cancel_arch)