From 56b98bf1fb819b357318f39fccf2901d3c6b41ec Mon Sep 17 00:00:00 2001 From: Adhemerval Zanella Date: Tue, 11 Dec 2018 16:57:49 -0200 Subject: alpha: Use Linux generic sigaction implementation Alpha rt_sigaction syscall uses a slight different kernel ABI than generic one: arch/alpha/kernel/signal.c 90 SYSCALL_DEFINE5(rt_sigaction, int, sig, const struct sigaction __user *, act, 91 struct sigaction __user *, oact, 92 size_t, sigsetsize, void __user *, restorer) Similar as sparc, the syscall expects a restorer function. However different than sparc, alpha defines the restorer as the 5th argument (sparc defines as the 4th). This patch removes the arch-specific alpha sigaction implementation, adapt the Linux generic one to different restore placements (through STUB macro), and make alpha use the Linux generic kernel_sigaction definition. Checked on alpha-linux-gnu and x86_64-linux-gnu (for sanity). * sysdeps/unix/sysv/linux/alpha/Makefile: Update comment about __syscall_rt_sigaction. * sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h (kernel_sigaction): Use Linux generic defintion. (STUB): Define. (__syscall_rt_sigreturn, __syscall_sigreturn): Add prototype. * sysdeps/unix/sysv/linux/alpha/rt_sigaction.S (__syscall_rt_sigaction): Remove implementation. (__syscall_sigreturn, __syscall_rt_sigreturn): Define as global and hidden. * sysdeps/unix/sysv/linux/alpha/sigaction.c: Remove file. * sysdeps/unix/sysv/linux/alpha/sysdep.h (INLINE_SYSCALL, INTERNAL_SYSCALL): Remove definitions. * sysdeps/unix/sysv/linux/sigaction.c: Define STUB to accept both the action and signal set size. * sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c (STUB): Redefine. * sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c (STUB): Likewise. --- sysdeps/unix/sysv/linux/alpha/Makefile | 2 +- sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h | 19 +++++------ sysdeps/unix/sysv/linux/alpha/rt_sigaction.S | 41 +++-------------------- sysdeps/unix/sysv/linux/alpha/sigaction.c | 38 --------------------- sysdeps/unix/sysv/linux/alpha/sysdep.h | 23 ------------- sysdeps/unix/sysv/linux/sigaction.c | 4 +-- sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c | 5 +-- sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c | 5 +-- 8 files changed, 22 insertions(+), 115 deletions(-) delete mode 100644 sysdeps/unix/sysv/linux/alpha/sigaction.c (limited to 'sysdeps/unix') diff --git a/sysdeps/unix/sysv/linux/alpha/Makefile b/sysdeps/unix/sysv/linux/alpha/Makefile index 50f4fb1183..fdd089af71 100644 --- a/sysdeps/unix/sysv/linux/alpha/Makefile +++ b/sysdeps/unix/sysv/linux/alpha/Makefile @@ -31,7 +31,7 @@ libm-routines += multc3 divtc3 endif # math ifeq ($(subdir),nptl) -# pull in __syscall_error routine, __sigprocmask, __syscall_rt_sigaction +# pull in __syscall_error routine, __sigprocmask, sigaction stubs. libpthread-routines += sysdep sigprocmask rt_sigaction libpthread-shared-only-routines += sysdep sigprocmask rt_sigaction endif diff --git a/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h b/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h index 25180ff9c9..679179b563 100644 --- a/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h +++ b/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h @@ -1,12 +1,11 @@ -#ifndef _KERNEL_SIGACTION_H -# define _KERNEL_SIGACTION_H +#include -/* This is the sigaction structure from the Linux 3.2 kernel. */ -struct kernel_sigaction -{ - __sighandler_t k_sa_handler; - unsigned int sa_flags; - sigset_t sa_mask; -}; +void __syscall_rt_sigreturn (void) attribute_hidden; +void __syscall_sigreturn (void) attribute_hidden; -#endif +#define STUB(act, sigsetsize) \ + (sigsetsize), \ + (act) ? ((unsigned long)((act->sa_flags & SA_SIGINFO) \ + ? &__syscall_rt_sigreturn \ + : &__syscall_sigreturn)) \ + : 0 diff --git a/sysdeps/unix/sysv/linux/alpha/rt_sigaction.S b/sysdeps/unix/sysv/linux/alpha/rt_sigaction.S index ca25eee611..17e55239fe 100644 --- a/sysdeps/unix/sysv/linux/alpha/rt_sigaction.S +++ b/sysdeps/unix/sysv/linux/alpha/rt_sigaction.S @@ -18,43 +18,6 @@ #include -/* On Alpha we desparately want to avoid having to issue an imb. Ordinarily - the kernel would have to issue one after setting up the signal return - stack, but the Linux rt_sigaction syscall is prepared to accept a pointer - to the sigreturn syscall, instead of inlining it on the stack. - - This just about halves signal delivery time. */ - - .text - -ENTRY(__syscall_rt_sigaction) - cfi_startproc - ldgp gp,0(pv) -#ifdef PROF - .set noat - lda AT, _mcount - jsr AT, (AT), _mcount - .set at -#endif - .prologue 1 - - beq a1, 0f - ldl t0, 8(a1) # sa_flags - - ldah a4, __syscall_sigreturn(gp) !gprelhigh - ldah t1, __syscall_rt_sigreturn(gp) !gprelhigh - lda a4, __syscall_sigreturn(a4) !gprellow - lda t1, __syscall_rt_sigreturn(t1) !gprellow - and t0, 0x40, t0 # SA_SIGINFO - cmovne t0, t1, a4 - -0: ldi v0, __NR_rt_sigaction - callsys - bne a3, SYSCALL_ERROR_LABEL - ret - cfi_endproc -PSEUDO_END(__syscall_rt_sigaction) - /* To enable unwinding through the signal frame without special hackery elsewhere, describe the entire struct sigcontext with unwind info. @@ -104,6 +67,8 @@ __syscall_sigreturn: callsys .size __syscall_sigreturn, .-__syscall_sigreturn .type __syscall_sigreturn, @function + .global __syscall_sigreturn; + .hidden __syscall_sigreturn; /* See above wrt including the nop. */ cfi_def_cfa_offset (176 + 648) @@ -116,5 +81,7 @@ __syscall_rt_sigreturn: callsys .size __syscall_rt_sigreturn, .-__syscall_rt_sigreturn .type __syscall_rt_sigreturn, @function + .global __syscall_rt_sigreturn; + .hidden __syscall_rt_sigreturn; cfi_endproc diff --git a/sysdeps/unix/sysv/linux/alpha/sigaction.c b/sysdeps/unix/sysv/linux/alpha/sigaction.c deleted file mode 100644 index 8051043587..0000000000 --- a/sysdeps/unix/sysv/linux/alpha/sigaction.c +++ /dev/null @@ -1,38 +0,0 @@ -/* Copyright (C) 2003-2018 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 - -/* - * In order to get the hidden arguments for rt_sigaction set up - * properly, we need to call the assembly version. Detect this in the - * INLINE_SYSCALL macro, and fail to expand inline in that case. - */ - -#undef INLINE_SYSCALL -#define INLINE_SYSCALL(name, nr, args...) \ - (__NR_##name == __NR_rt_sigaction \ - ? __syscall_rt_sigaction(args) \ - : INLINE_SYSCALL1(name, nr, args)) - -struct kernel_sigaction; -extern int __syscall_rt_sigaction (int, const struct kernel_sigaction *, - struct kernel_sigaction *, size_t); - -#include diff --git a/sysdeps/unix/sysv/linux/alpha/sysdep.h b/sysdeps/unix/sysv/linux/alpha/sysdep.h index 080405021f..9148b4793b 100644 --- a/sysdeps/unix/sysv/linux/alpha/sysdep.h +++ b/sysdeps/unix/sysv/linux/alpha/sysdep.h @@ -72,27 +72,4 @@ #define SINGLE_THREAD_BY_GLOBAL 1 -/* - * In order to get the hidden arguments for rt_sigaction set up - * properly, we need to call the assembly version. This shouldn't - * happen except for inside sigaction.c, where we handle this - * specially. Catch other uses and error. - */ - -#undef INLINE_SYSCALL -#define INLINE_SYSCALL(name, nr, args...) \ -({ \ - extern char ChEcK[__NR_##name == __NR_rt_sigaction ? -1 : 1] \ - __attribute__((unused)); \ - INLINE_SYSCALL1(name, nr, args); \ -}) - -#undef INTERNAL_SYSCALL -#define INTERNAL_SYSCALL(name, err_out, nr, args...) \ -({ \ - extern char ChEcK[__NR_##name == __NR_rt_sigaction ? -1 : 1] \ - __attribute__((unused)); \ - INTERNAL_SYSCALL1(name, err_out, nr, args); \ -}) - #endif /* _LINUX_ALPHA_SYSDEP_H */ diff --git a/sysdeps/unix/sysv/linux/sigaction.c b/sysdeps/unix/sysv/linux/sigaction.c index 0e6851a148..233ab1fcb5 100644 --- a/sysdeps/unix/sysv/linux/sigaction.c +++ b/sysdeps/unix/sysv/linux/sigaction.c @@ -33,7 +33,7 @@ /* SPARC passes the restore function as an argument to rt_sigaction. */ #ifndef STUB -# define STUB(act) +# define STUB(act, sigsetsize) (sigsetsize) #endif /* If ACT is not NULL, change the action for SIG to *ACT. @@ -57,7 +57,7 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) real size of the user-level sigset_t. */ result = INLINE_SYSCALL_CALL (rt_sigaction, sig, act ? &kact : NULL, - oact ? &koact : NULL, STUB(act) _NSIG / 8); + oact ? &koact : NULL, STUB (act, _NSIG / 8)); if (oact && result >= 0) { diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c index 191f58729e..9f1a31a3b3 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c @@ -27,11 +27,12 @@ static void __rt_sigreturn_stub (void); static void __sigreturn_stub (void); -#define STUB(act) \ +#define STUB(act, sigsetsize) \ (act) ? ((unsigned long)((act->sa_flags & SA_SIGINFO) \ ? &__rt_sigreturn_stub \ : &__sigreturn_stub) - 8) \ - : 0, + : 0, \ + (sigsetsize) #include diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c index cfbbc6e7b4..acc76b1bf9 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c @@ -24,8 +24,9 @@ static void __rt_sigreturn_stub (void); -#define STUB(act) \ - (((unsigned long) &__rt_sigreturn_stub) - 8), +#define STUB(act, sigsetsize) \ + (((unsigned long) &__rt_sigreturn_stub) - 8), \ + (sigsetsize) #include -- cgit v1.2.3