Message ID | 1518439345-6013-3-git-send-email-adhemerval.zanella@linaro.org |
---|---|
State | Accepted |
Commit | b4a5d26d8835d972995f0a0a2f805a8845bafa0b |
Headers | show |
Series | [v4,1/4] Rename nptl-signals.h to internal-signals.h | expand |
Ping. On 12/02/2018 10:42, Adhemerval Zanella wrote: > This patch consolidates all Linux sigaction implementation on a default > one at sysdeps/unix/sysv/linux/sigaction.c. The idea is remove redundant > code and simplify new ports addition by following the current generic > Linux User API (UAPI). > > The UAPI for new ports defines a generic extensible sigaction struct as: > > struct sigaction > { > __sighandler_t sa_handler; > unsigned long sa_flags; > #ifdef SA_RESTORER > void (*sa_restorer) (void); > #endif > sigset_t sa_mask; > }; > > Where SA_RESTORER is just placed to compatibility reasons, news ports > should not add it. A similar definition is used on generic > kernel_sigaction.h. > > The user exported sigaction definition is not changed, so for most > architectures it requires an adjustment to kernel expected one for the > syscall. > > The main changes are: > > - All architectures now define and use a kernel_sigaction struct meant > for the syscall, even for the architectures where the user sigaction > has the same layout of the kernel expected one (s390-64 and ia64). > Although it requires more work for these architectures, it simplifies > the generic implementation. Also, sigaction is hardly a hotspot where > micro optimization would play an important role. > > - The generic kernel_sigaction definition is now aligned with expected > UAPI one for newer ports, where SA_RESTORER and sa_restorer is not > expected to be defined. This means adding kernel_sigaction for > current architectures that does define it (m68k, nios2, powerpc, s390, > sh, sparc, and tile) and which rely on previous generic definition. > > - Remove old MIPS usage of sa_restorer. This was removed since 2.6.27 > (2957c9e61ee9c - "[MIPS] IRIX: Goodbye and thanks for all the fish"). > > So for new ports the generic implementation should work if its uses > Linux UAPI. If SA_RESTORER is still required (due some architecture > limitation), it should define its own kernel_sigaction.h, define it and > include generic header (assuming it still uses the default generic kernel > layout). > > Checked on x86_64-linux-gnu, i686-linux-gnu, arm-linux-gnueabihf, > aarch64-linux-gnu, sparc64-linux-gnu, sparcv9-linux-gnu, powerpc-linux-gnu, > and powerpc64-linux-gnu. I also check the build on all remaining affected > ABIs. > > * sysdeps/unix/sysv/linux/aarch64/sigaction.c: Use default Linux version > as base implementation. > * sysdeps/unix/sysv/linux/arm/sigaction.c: Likewise. > * sysdeps/unix/sysv/linux/i386/sigaction.c: Likewise. > * sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c: Likewise. > * sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c: Likewise. > * sysdeps/unix/sysv/linux/x86_64/sigaction.c: Likewise. > * sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h: Add include guards, > remove unrequired definitions and update comments. > * sysdeps/unix/sysv/linux/kernel_sigaction.h: Likewise. > * sysdeps/unix/sysv/linux/mips/kernel_sigaction.h: Likewise. > * sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h: New file. > * sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h: Likewise. > * sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h: Likewise. > * sysdeps/unix/sysv/linux/powerpc/kernel_sigaction: Likewise. > * sysdeps/unix/sysv/linux/s390/kernel_sigaction.h: Likewise. > * sysdeps/unix/sysv/linux/sh/kernel_sigaction.h: Likewise. > * sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h: Likewise. > * sysdeps/unix/sysv/linux/tile/kernel_sigaction.h: Likewise. > * sysdeps/unix/sysv/linux/ia64/sigaction.c: Remove file. > * sysdeps/unix/sysv/linux/mips/sigaction.c: Likewise. > * sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c: Likewise. > * sysdeps/unix/sysv/linux/sigaction.c: Add STUB, SET_SA_RESTORER, > and RESET_SA_RESTORER hooks. > > Signed-off-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> > --- > ChangeLog | 25 +++++ > sysdeps/unix/sysv/linux/aarch64/sigaction.c | 58 ++--------- > sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h | 21 ++-- > sysdeps/unix/sysv/linux/arm/sigaction.c | 79 +++----------- > sysdeps/unix/sysv/linux/i386/sigaction.c | 76 +++----------- > sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h | 6 ++ > sysdeps/unix/sysv/linux/ia64/sigaction.c | 45 -------- > sysdeps/unix/sysv/linux/kernel_sigaction.h | 31 +++--- > sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h | 22 ++++ > sysdeps/unix/sysv/linux/mips/kernel_sigaction.h | 48 ++------- > sysdeps/unix/sysv/linux/mips/sigaction.c | 116 --------------------- > sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h | 8 ++ > sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h | 8 ++ > sysdeps/unix/sysv/linux/s390/kernel_sigaction.h | 28 +++++ > sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c | 43 -------- > sysdeps/unix/sysv/linux/sh/kernel_sigaction.h | 8 ++ > sysdeps/unix/sysv/linux/sigaction.c | 28 ++--- > sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h | 10 ++ > sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c | 41 +------- > sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c | 43 +------- > sysdeps/unix/sysv/linux/tile/kernel_sigaction.h | 9 ++ > sysdeps/unix/sysv/linux/x86_64/sigaction.c | 61 ++--------- > 22 files changed, 230 insertions(+), 584 deletions(-) > create mode 100644 sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h > delete mode 100644 sysdeps/unix/sysv/linux/ia64/sigaction.c > create mode 100644 sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h > delete mode 100644 sysdeps/unix/sysv/linux/mips/sigaction.c > create mode 100644 sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h > create mode 100644 sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h > create mode 100644 sysdeps/unix/sysv/linux/s390/kernel_sigaction.h > delete mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c > create mode 100644 sysdeps/unix/sysv/linux/sh/kernel_sigaction.h > create mode 100644 sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h > create mode 100644 sysdeps/unix/sysv/linux/tile/kernel_sigaction.h > > diff --git a/sysdeps/unix/sysv/linux/aarch64/sigaction.c b/sysdeps/unix/sysv/linux/aarch64/sigaction.c > index 73f4eb7..83d5b4f 100644 > --- a/sysdeps/unix/sysv/linux/aarch64/sigaction.c > +++ b/sysdeps/unix/sysv/linux/aarch64/sigaction.c > @@ -1,5 +1,4 @@ > /* Copyright (C) 1997-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 > @@ -16,55 +15,16 @@ > License along with the GNU C Library; if not, see > <http://www.gnu.org/licenses/>. */ > > -#include <errno.h> > -#include <signal.h> > -#include <string.h> > - > -#include <sysdep.h> > -#include <sys/syscall.h> > - > +/* Required for AArch32 compatibility. */ > #define SA_RESTORER 0x04000000 > > -/* The difference here is that the sigaction structure used in the > - kernel is not the same as we use in the libc. Therefore we must > - translate it here. */ > -#include <kernel_sigaction.h> > - > -int > -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) > -{ > - int result; > - struct kernel_sigaction kact; > - struct kernel_sigaction koact; > - > - if (act) > - { > - kact.k_sa_handler = act->sa_handler; > - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); > - kact.sa_flags = act->sa_flags; > -#ifdef HAVE_SA_RESTORER > - if (kact.sa_flags & SA_RESTORER) > - kact.sa_restorer = act->sa_restorer; > -#endif > - } > +#define SET_SA_RESTORER(kact, act) \ > + ({ \ > + if ((kact)->sa_flags & SA_RESTORER) \ > + (kact)->sa_restorer = (act)->sa_restorer; \ > + }) > > - result = INLINE_SYSCALL (rt_sigaction, 4, sig, > - act ? &kact : NULL, > - oact ? &koact : NULL, _NSIG / 8); > - if (result >= 0 || errno != ENOSYS) > - { > - if (oact && result >= 0) > - { > - oact->sa_handler = koact.k_sa_handler; > - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); > - oact->sa_flags = koact.sa_flags; > -#ifdef HAVE_SA_RESTORER > - oact->sa_restorer = koact.sa_restorer; > -#endif > - } > - } > - return result; > -} > -libc_hidden_def (__libc_sigaction) > +#define RESET_SA_RESTORER(act, kact) \ > + (act)->sa_restorer = (kact)->sa_restorer; > > -#include <nptl/sigaction.c> > +#include <sysdeps/unix/sysv/linux/sigaction.c> > diff --git a/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h b/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h > index 4c35d96..25180ff 100644 > --- a/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h > +++ b/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h > @@ -1,15 +1,12 @@ > -/* This is the sigaction struction from the Linux 2.1.20 kernel. */ > +#ifndef _KERNEL_SIGACTION_H > +# define _KERNEL_SIGACTION_H > > -struct old_kernel_sigaction { > - __sighandler_t k_sa_handler; > - unsigned long sa_mask; > - unsigned int sa_flags; > +/* 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; > }; > > -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ > - > -struct kernel_sigaction { > - __sighandler_t k_sa_handler; > - unsigned int sa_flags; > - sigset_t sa_mask; > -}; > +#endif > diff --git a/sysdeps/unix/sysv/linux/arm/sigaction.c b/sysdeps/unix/sysv/linux/arm/sigaction.c > index e4d80de..c828250 100644 > --- a/sysdeps/unix/sysv/linux/arm/sigaction.c > +++ b/sysdeps/unix/sysv/linux/arm/sigaction.c > @@ -15,70 +15,25 @@ > License along with the GNU C Library. If not, see > <http://www.gnu.org/licenses/>. */ > > -#include <errno.h> > -#include <signal.h> > -#include <string.h> > - > -#include <sysdep.h> > -#include <sys/syscall.h> > - > -/* The difference here is that the sigaction structure used in the > - kernel is not the same as we use in the libc. Therefore we must > - translate it here. */ > -#include <kernel_sigaction.h> > - > #define SA_RESTORER 0x04000000 > > extern void __default_sa_restorer (void); > extern void __default_rt_sa_restorer (void); > > -/* When RT signals are in use we need to use a different return stub. */ > -#define choose_restorer(flags) \ > - (flags & SA_SIGINFO) ? __default_rt_sa_restorer \ > - : __default_sa_restorer > - > -/* If ACT is not NULL, change the action for SIG to *ACT. > - If OACT is not NULL, put the old action for SIG in *OACT. */ > -int > -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) > -{ > - int result; > - > - struct kernel_sigaction kact, koact; > - > - if (act) > - { > - kact.k_sa_handler = act->sa_handler; > - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); > - kact.sa_flags = act->sa_flags; > -#ifdef HAVE_SA_RESTORER > - if (kact.sa_flags & SA_RESTORER) > - kact.sa_restorer = act->sa_restorer; > - else > - { > - kact.sa_restorer = choose_restorer (kact.sa_flags); > - kact.sa_flags |= SA_RESTORER; > - } > -#endif > - } > - > - /* XXX The size argument hopefully will have to be changed to the > - real size of the user-level sigset_t. */ > - result = INLINE_SYSCALL (rt_sigaction, 4, sig, > - act ? &kact : NULL, > - oact ? &koact : NULL, _NSIG / 8); > - > - if (oact && result >= 0) > - { > - oact->sa_handler = koact.k_sa_handler; > - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); > - oact->sa_flags = koact.sa_flags; > -#ifdef HAVE_SA_RESTORER > - oact->sa_restorer = koact.sa_restorer; > -#endif > - } > - return result; > -} > -libc_hidden_def (__libc_sigaction) > - > -#include <nptl/sigaction.c> > +#define SET_SA_RESTORER(kact, act) \ > + ({ \ > + if ((kact)->sa_flags & SA_RESTORER) \ > + (kact)->sa_restorer = (act)->sa_restorer; \ > + else \ > + { \ > + (kact)->sa_restorer = ((kact)->sa_flags & SA_SIGINFO) \ > + ? __default_rt_sa_restorer \ > + : __default_sa_restorer; \ > + (kact)->sa_flags |= SA_RESTORER; \ > + } \ > + }) > + > +#define RESET_SA_RESTORER(act, kact) \ > + (act)->sa_restorer = (kact)->sa_restorer; > + > +#include <sysdeps/unix/sysv/linux/sigaction.c> > diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c > index a5eb9e0..137c73b 100644 > --- a/sysdeps/unix/sysv/linux/i386/sigaction.c > +++ b/sysdeps/unix/sysv/linux/i386/sigaction.c > @@ -16,78 +16,28 @@ > License along with the GNU C Library; if not, see > <http://www.gnu.org/licenses/>. */ > > -#include <sysdep.h> > -#include <errno.h> > -#include <stddef.h> > #include <signal.h> > -#include <string.h> > - > -#include <sysdep.h> > -#include <sys/syscall.h> > #include <ldsodefs.h> > > -/* The difference here is that the sigaction structure used in the > - kernel is not the same as we use in the libc. Therefore we must > - translate it here. */ > -#include <kernel_sigaction.h> > - > -/* We do not globally define the SA_RESTORER flag so do it here. */ > #define SA_RESTORER 0x04000000 > > - > -/* Using the hidden attribute here does not change the code but it > - helps to avoid warnings. */ > -#ifdef __NR_rt_sigaction > extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; > -#endif > extern void restore (void) asm ("__restore") attribute_hidden; > > +#define SET_SA_RESTORER(kact, act) \ > + ({ \ > + if (GLRO(dl_sysinfo_dso) == NULL) \ > + { \ > + (kact)->sa_flags |= SA_RESTORER; \ > + (kact)->sa_restorer = (((act)->sa_flags & SA_SIGINFO) \ > + ? &restore_rt : &restore); \ > + } \ > + }) > > -/* If ACT is not NULL, change the action for SIG to *ACT. > - If OACT is not NULL, put the old action for SIG in *OACT. */ > -int > -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) > -{ > - int result; > - > - struct kernel_sigaction kact, koact; > - > - if (act) > - { > - kact.k_sa_handler = act->sa_handler; > - kact.sa_flags = act->sa_flags; > - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); > - > - if (GLRO(dl_sysinfo_dso) == NULL) > - { > - kact.sa_flags |= SA_RESTORER; > - > - kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) > - ? &restore_rt : &restore); > - } > - } > - > - /* XXX The size argument hopefully will have to be changed to the > - real size of the user-level sigset_t. */ > - INTERNAL_SYSCALL_DECL (err); > - result = INTERNAL_SYSCALL (rt_sigaction, err, 4, > - sig, act ? &kact : NULL, > - oact ? &koact : NULL, _NSIG / 8); > - if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err))) > - return INLINE_SYSCALL_ERROR_RETURN_VALUE (INTERNAL_SYSCALL_ERRNO (result, > - err)); > - else if (oact && result >= 0) > - { > - oact->sa_handler = koact.k_sa_handler; > - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); > - oact->sa_flags = koact.sa_flags; > - oact->sa_restorer = koact.sa_restorer; > - } > - return result; > -} > -libc_hidden_def (__libc_sigaction) > +#define RESET_SA_RESTORER(act, kact) \ > + (act)->sa_restorer = (kact)->sa_restorer > > -#include <nptl/sigaction.c> > +#include <sysdeps/unix/sysv/linux/sigaction.c> > > /* NOTE: Please think twice before making any changes to the bits of > code below. GDB needs some intimate knowledge about it to > @@ -108,10 +58,8 @@ asm \ > " int $0x80" \ > ); > > -#ifdef __NR_rt_sigaction > /* The return code for realtime-signals. */ > RESTORE (restore_rt, __NR_rt_sigreturn) > -#endif > > /* For the boring old signals. */ > #undef RESTORE2 > diff --git a/sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h b/sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h > new file mode 100644 > index 0000000..05813db > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h > @@ -0,0 +1,6 @@ > +/* This is the sigaction structure from the Linux 3.2 kernel. */ > +struct kernel_sigaction { > + __sighandler_t k_sa_handler; > + unsigned long sa_flags; > + sigset_t sa_mask; /* mask last for extensibility */ > +}; > diff --git a/sysdeps/unix/sysv/linux/ia64/sigaction.c b/sysdeps/unix/sysv/linux/ia64/sigaction.c > deleted file mode 100644 > index e7fb8cd..0000000 > --- a/sysdeps/unix/sysv/linux/ia64/sigaction.c > +++ /dev/null > @@ -1,45 +0,0 @@ > -/* Copyright (C) 1997-2018 Free Software Foundation, Inc. > - This file is part of the GNU C Library. > - Linux/IA64 specific sigaction > - Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999. > - > - 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/>. */ > - > -/* Linux/ia64 only has rt signals, thus we do not even want to try falling > - back to the old style signals as the default Linux handler does. */ > - > -#include <errno.h> > -#include <signal.h> > -#include <string.h> > - > -#include <sysdep.h> > -#include <sys/syscall.h> > - > -/* The variable is shared between all wrappers around signal handling > - functions which have RT equivalents. This is the definition. */ > - > - > -/* If ACT is not NULL, change the action for SIG to *ACT. > - If OACT is not NULL, put the old action for SIG in *OACT. */ > -int > -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) > -{ > - /* XXX The size argument hopefully will have to be changed to the > - real size of the user-level sigset_t. */ > - return INLINE_SYSCALL (rt_sigaction, 4, sig, act, oact, _NSIG / 8); > -} > -libc_hidden_def (__libc_sigaction) > - > -#include <nptl/sigaction.c> > diff --git a/sysdeps/unix/sysv/linux/kernel_sigaction.h b/sysdeps/unix/sysv/linux/kernel_sigaction.h > index d005cbc..2dbec08 100644 > --- a/sysdeps/unix/sysv/linux/kernel_sigaction.h > +++ b/sysdeps/unix/sysv/linux/kernel_sigaction.h > @@ -1,19 +1,20 @@ > -/* This is the sigaction structure from the Linux 2.1.20 kernel. */ > +#ifndef _KERNEL_SIGACTION_H > +# define _KERNEL_SIGACTION_H > > -#define HAVE_SA_RESTORER > - > -struct old_kernel_sigaction { > - __sighandler_t k_sa_handler; > - unsigned long sa_mask; > - unsigned long sa_flags; > - void (*sa_restorer) (void); > +/* This is the sigaction structure from the Linux 3.2 kernel. */ > +struct kernel_sigaction > +{ > + __sighandler_t k_sa_handler; > + unsigned long sa_flags; > +#ifdef SA_RESTORER > + void (*sa_restorer) (void); > +#endif > + sigset_t sa_mask; > }; > > -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ > +#ifndef SA_RESTORER > +# define SET_SA_RESTORER(kact, act) > +# define RESET_SA_RESTORER(act, kact) > +#endif > > -struct kernel_sigaction { > - __sighandler_t k_sa_handler; > - unsigned long sa_flags; > - void (*sa_restorer) (void); > - sigset_t sa_mask; > -}; > +#endif > diff --git a/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h b/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h > new file mode 100644 > index 0000000..54972fe > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h > @@ -0,0 +1,22 @@ > +#ifndef _KERNEL_SIGACTION_H > +# define _KERNEL_SIGACTION_H > + > +#include <signal.h> > + > +#define SA_RESTORER 0x04000000 > + > +/* This is the sigaction structure from the Linux 3.2 kernel. */ > +struct kernel_sigaction > +{ > + __sighandler_t k_sa_handler; > + sigset_t sa_mask; > + unsigned long sa_flags; > + void (*sa_restorer) (void); > +}; > + > +#define SET_SA_RESTORER(kact, act) \ > + (kact)->sa_restorer = (act)->sa_restorer > +#define RESET_SA_RESTORER(act, kact) \ > + (act)->sa_restorer = (kact)->sa_restorer > + > +#endif > diff --git a/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h b/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h > index b6f52cc..beef976 100644 > --- a/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h > +++ b/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h > @@ -1,40 +1,12 @@ > -/* This is the sigaction structure from the Linux 2.1.24 kernel. */ > - > -#include <sgidefs.h> > - > -#define HAVE_SA_RESTORER > - > -struct old_kernel_sigaction { > - unsigned int sa_flags; > - __sighandler_t k_sa_handler; > - unsigned long sa_mask; > - unsigned int __pad0[3]; /* reserved, keep size constant */ > - > - /* Abi says here follows reserved int[2] */ > - void (*sa_restorer)(void); > -#if (_MIPS_SZPTR < 64) > - /* > - * For 32 bit code we have to pad struct sigaction to get > - * constant size for the ABI > - */ > - int pad1[1]; /* reserved */ > -#endif > +#ifndef _KERNEL_SIGACTION_H > +# define _KERNEL_SIGACTION_H > + > +/* This is the sigaction structure from the Linux 3.2 kernel. */ > +struct kernel_sigaction > +{ > + unsigned int sa_flags; > + __sighandler_t k_sa_handler; > + sigset_t sa_mask; > }; > > - > -#define _KERNEL_NSIG 128 > -#define _KERNEL_NSIG_BPW _MIPS_SZLONG > -#define _KERNEL_NSIG_WORDS (_KERNEL_NSIG / _KERNEL_NSIG_BPW) > - > -typedef struct { > - unsigned long sig[_KERNEL_NSIG_WORDS]; > -} kernel_sigset_t; > - > -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ > -struct kernel_sigaction { > - unsigned int sa_flags; > - __sighandler_t k_sa_handler; > - kernel_sigset_t sa_mask; > - void (*sa_restorer)(void); > - int s_resv[1]; /* reserved */ > -}; > +#endif > diff --git a/sysdeps/unix/sysv/linux/mips/sigaction.c b/sysdeps/unix/sysv/linux/mips/sigaction.c > deleted file mode 100644 > index 008b688..0000000 > --- a/sysdeps/unix/sysv/linux/mips/sigaction.c > +++ /dev/null > @@ -1,116 +0,0 @@ > -/* Copyright (C) 1997-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 > - <http://www.gnu.org/licenses/>. */ > - > -#include <errno.h> > -#include <sgidefs.h> > -#include <signal.h> > -#include <string.h> > - > -#include <sysdep.h> > -#include <sys/syscall.h> > - > -#include <sgidefs.h> > - > -/* The difference here is that the sigaction structure used in the > - kernel is not the same as we use in the libc. Therefore we must > - translate it here. */ > -#include <kernel_sigaction.h> > - > -#if _MIPS_SIM != _ABIO32 > - > -# ifdef __NR_rt_sigreturn > -static void restore_rt (void) asm ("__restore_rt"); > -# endif > -# ifdef __NR_sigreturn > -static void restore (void) asm ("__restore"); > -# endif > -#endif > - > -/* If ACT is not NULL, change the action for SIG to *ACT. > - If OACT is not NULL, put the old action for SIG in *OACT. */ > -int > -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) > -{ > - int result; > - > - struct kernel_sigaction kact, koact; > - > - if (act) > - { > - kact.k_sa_handler = act->sa_handler; > - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kernel_sigset_t)); > - kact.sa_flags = act->sa_flags; > -#ifdef HAVE_SA_RESTORER > -# if _MIPS_SIM == _ABIO32 > - kact.sa_restorer = act->sa_restorer; > -# else > - kact.sa_restorer = &restore_rt; > -# endif > -#endif > - } > - > - /* XXX The size argument hopefully will have to be changed to the > - real size of the user-level sigset_t. */ > - result = INLINE_SYSCALL (rt_sigaction, 4, sig, > - act ? &kact : NULL, > - oact ? &koact : NULL, > - sizeof (kernel_sigset_t)); > - > - if (oact && result >= 0) > - { > - oact->sa_handler = koact.k_sa_handler; > - memcpy (&oact->sa_mask, &koact.sa_mask, > - sizeof (kernel_sigset_t)); > - oact->sa_flags = koact.sa_flags; > -#ifdef HAVE_SA_RESTORER > - oact->sa_restorer = koact.sa_restorer; > -#endif > - } > - return result; > -} > -libc_hidden_def (__libc_sigaction) > - > -#include <nptl/sigaction.c> > - > - > -/* NOTE: Please think twice before making any changes to the bits of > - code below. GDB needs some intimate knowledge about it to > - recognize them as signal trampolines, and make backtraces through > - signal handlers work right. Important are both the names > - (__restore_rt) and the exact instruction sequence. > - If you ever feel the need to make any changes, please notify the > - appropriate GDB maintainer. */ > - > -#define RESTORE(name, syscall) RESTORE2 (name, syscall) > -#define RESTORE2(name, syscall) \ > -asm \ > - ( \ > - ".align 4\n" \ > - "__" #name ":\n" \ > - " li $2, " #syscall "\n" \ > - " syscall\n" \ > - ); > - > -/* The return code for realtime-signals. */ > -#if _MIPS_SIM != _ABIO32 > -# ifdef __NR_rt_sigreturn > -RESTORE (restore_rt, __NR_rt_sigreturn) > -# endif > -# ifdef __NR_sigreturn > -RESTORE (restore, __NR_sigreturn) > -# endif > -#endif > diff --git a/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h b/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h > new file mode 100644 > index 0000000..4ada322 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h > @@ -0,0 +1,8 @@ > +/* NIOS2 uses the generic Linux UAPI but defines SA_RESTORER. */ > +#define SA_RESTORER 0x04000000 > +#include <sysdeps/unix/sysv/linux/kernel_sigaction.h> > + > +#define SET_SA_RESTORER(kact, act) \ > + (kact)->sa_restorer = (act)->sa_restorer > +#define RESET_SA_RESTORER(act, kact) \ > + (act)->sa_restorer = (kact)->sa_restorer > diff --git a/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h b/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h > new file mode 100644 > index 0000000..c5213f2 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h > @@ -0,0 +1,8 @@ > +/* powerpc kernel sigaction is similar to generic Linux UAPI one. */ > +#define SA_RESTORER 0x04000000 > +#include <sysdeps/unix/sysv/linux/kernel_sigaction.h> > + > +#define SET_SA_RESTORER(kact, act) \ > + (kact)->sa_restorer = (act)->sa_restorer > +#define RESET_SA_RESTORER(act, kact) \ > + (act)->sa_restorer = (kact)->sa_restorer > diff --git a/sysdeps/unix/sysv/linux/s390/kernel_sigaction.h b/sysdeps/unix/sysv/linux/s390/kernel_sigaction.h > new file mode 100644 > index 0000000..a8beaf7 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/s390/kernel_sigaction.h > @@ -0,0 +1,28 @@ > +#include <bits/types/siginfo_t.h> > + > +#define SA_RESTORER 0x04000000 > + > +/* This is the sigaction structure from the Linux 3.2 kernel. */ > +struct kernel_sigaction > +{ > + union > + { > + __sighandler_t _sa_handler; > + void (*_sa_sigaction)(int, siginfo_t *, void *); > + } _u; > +#define k_sa_handler _u._sa_handler > +#ifndef __s390x__ > + sigset_t sa_mask; > + unsigned long sa_flags; > + void (*sa_restorer)(void); > +#else > + unsigned long sa_flags; > + void (*sa_restorer)(void); > + sigset_t sa_mask; > +#endif > +}; > + > +#define SET_SA_RESTORER(kact, act) \ > + (kact)->sa_restorer = (act)->sa_restorer > +#define RESET_SA_RESTORER(act, kact) \ > + (act)->sa_restorer = (kact)->sa_restorer > diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c b/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c > deleted file mode 100644 > index c13927c..0000000 > --- a/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c > +++ /dev/null > @@ -1,43 +0,0 @@ > -/* Copyright (C) 2001-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 > - <http://www.gnu.org/licenses/>. */ > - > -/* 64 bit Linux for S/390 only has rt signals, thus we do not even want to try > - falling back to the old style signals as the default Linux handler does. */ > - > -#include <errno.h> > -#include <signal.h> > -#include <string.h> > - > -#include <sysdep.h> > -#include <sys/syscall.h> > - > -/* The variable is shared between all wrappers around signal handling > - functions which have RT equivalents. This is the definition. */ > - > - > -/* If ACT is not NULL, change the action for SIG to *ACT. > - If OACT is not NULL, put the old action for SIG in *OACT. */ > -int > -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) > -{ > - /* XXX The size argument hopefully will have to be changed to the > - real size of the user-level sigset_t. */ > - return INLINE_SYSCALL (rt_sigaction, 4, sig, act, oact, _NSIG / 8); > -} > -libc_hidden_def (__libc_sigaction) > - > -#include <nptl/sigaction.c> > diff --git a/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h b/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h > new file mode 100644 > index 0000000..7ebcd08 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h > @@ -0,0 +1,8 @@ > +/* SH uses the generic Linux UAPI but defines SA_RESTORER. */ > +#define SA_RESTORER 0x04000000 > +#include <sysdeps/unix/sysv/linux/kernel_sigaction.h> > + > +#define SET_SA_RESTORER(kact, act) \ > + (kact)->sa_restorer = (act)->sa_restorer > +#define RESET_SA_RESTORER(act, kact) \ > + (act)->sa_restorer = (kact)->sa_restorer > diff --git a/sysdeps/unix/sysv/linux/sigaction.c b/sysdeps/unix/sysv/linux/sigaction.c > index 40a311a..0e6851a 100644 > --- a/sysdeps/unix/sysv/linux/sigaction.c > +++ b/sysdeps/unix/sysv/linux/sigaction.c > @@ -22,11 +22,19 @@ > #include <sysdep.h> > #include <sys/syscall.h> > > -/* The difference here is that the sigaction structure used in the > - kernel is not the same as we use in the libc. Therefore we must > - translate it here. */ > +/* New ports should not define the obsolete SA_RESTORER, however some > + architecture requires for compat mode and/or due old ABI. */ > #include <kernel_sigaction.h> > > +#ifndef SA_RESTORER > +# define SET_SA_RESTORER(kact, act) > +# define RESET_SA_RESTORER(act, kact) > +#endif > + > +/* SPARC passes the restore function as an argument to rt_sigaction. */ > +#ifndef STUB > +# define STUB(act) > +#endif > > /* If ACT is not NULL, change the action for SIG to *ACT. > If OACT is not NULL, put the old action for SIG in *OACT. */ > @@ -42,25 +50,21 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) > kact.k_sa_handler = act->sa_handler; > memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); > kact.sa_flags = act->sa_flags; > -#ifdef HAVE_SA_RESTORER > - kact.sa_restorer = act->sa_restorer; > -#endif > + SET_SA_RESTORER (&kact, act); > } > > /* XXX The size argument hopefully will have to be changed to the > real size of the user-level sigset_t. */ > - result = INLINE_SYSCALL (rt_sigaction, 4, sig, > - act ? &kact : NULL, > - oact ? &koact : NULL, _NSIG / 8); > + result = INLINE_SYSCALL_CALL (rt_sigaction, sig, > + act ? &kact : NULL, > + oact ? &koact : NULL, STUB(act) _NSIG / 8); > > if (oact && result >= 0) > { > oact->sa_handler = koact.k_sa_handler; > memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); > oact->sa_flags = koact.sa_flags; > -#ifdef HAVE_SA_RESTORER > - oact->sa_restorer = koact.sa_restorer; > -#endif > + RESET_SA_RESTORER (oact, &koact); > } > return result; > } > diff --git a/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h > new file mode 100644 > index 0000000..bee7e9c > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h > @@ -0,0 +1,10 @@ > +/* SPARC 'struct __new_sigaction' is similar to generic Linux UAPI with > + a sa_restorer field, even though function is passed as an argument > + to rt_sigaction syscall. */ > +#define SA_RESTORER 0x04000000 > +#include <sysdeps/unix/sysv/linux/kernel_sigaction.h> > + > +#define SET_SA_RESTORER(kact, act) \ > + (kact)->sa_restorer = NULL > +#define RESET_SA_RESTORER(act, kact) \ > + (act)->sa_restorer = (kact)->sa_restorer > diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c > index 204a5d8..c1d8f45 100644 > --- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c > +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c > @@ -27,43 +27,12 @@ > static void __rt_sigreturn_stub (void); > static void __sigreturn_stub (void); > > -int > -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) > -{ > - struct kernel_sigaction kact, koact; > - unsigned long stub = 0; > - int ret; > - > - if (act) > - { > - kact.k_sa_handler = act->sa_handler; > - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); > - if (((kact.sa_flags = act->sa_flags) & SA_SIGINFO) != 0) > - stub = (unsigned long) &__rt_sigreturn_stub; > - else > - stub = (unsigned long) &__sigreturn_stub; > - stub -= 8; > - kact.sa_restorer = NULL; > - } > - > - /* XXX The size argument hopefully will have to be changed to the > - real size of the user-level sigset_t. */ > - ret = INLINE_SYSCALL (rt_sigaction, 5, sig, act ? &kact : 0, > - oact ? &koact : 0, stub, _NSIG / 8); > - > - if (oact && ret >= 0) > - { > - oact->sa_handler = koact.k_sa_handler; > - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); > - oact->sa_flags = koact.sa_flags; > - oact->sa_restorer = koact.sa_restorer; > - } > - return ret; > -} > -libc_hidden_def (__libc_sigaction) > - > -#include <nptl/sigaction.c> > +#define STUB(act) \ > + ((unsigned long)((act->sa_flags & SA_SIGINFO) \ > + ? &__rt_sigreturn_stub \ > + : &__sigreturn_stub) - 8), > > +#include <sysdeps/unix/sysv/linux/sigaction.c> > > static > inhibit_stack_protector > diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c > index 73cda4c..cfbbc6e 100644 > --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c > +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c > @@ -21,50 +21,13 @@ > #include <string.h> > #include <syscall.h> > #include <sysdep.h> > -#include <sys/signal.h> > -#include <errno.h> > - > -#include <kernel_sigaction.h> > - > -/* SPARC 64bit userland requires a kernel that has rt signals anyway. */ > > static void __rt_sigreturn_stub (void); > > -int > -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) > -{ > - int ret; > - struct kernel_sigaction kact, koact; > - unsigned long stub = ((unsigned long) &__rt_sigreturn_stub) - 8; > - > - if (act) > - { > - kact.k_sa_handler = act->sa_handler; > - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); > - kact.sa_flags = act->sa_flags; > - kact.sa_restorer = NULL; > - } > - > - /* XXX The size argument hopefully will have to be changed to the > - real size of the user-level sigset_t. */ > - ret = INLINE_SYSCALL (rt_sigaction, 5, sig, > - act ? &kact : 0, > - oact ? &koact : 0, stub, _NSIG / 8); > - > - if (oact && ret >= 0) > - { > - oact->sa_handler = koact.k_sa_handler; > - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); > - oact->sa_flags = koact.sa_flags; > - oact->sa_restorer = koact.sa_restorer; > - } > - > - return ret; > -} > -libc_hidden_def (__libc_sigaction) > - > -#include <nptl/sigaction.c> > +#define STUB(act) \ > + (((unsigned long) &__rt_sigreturn_stub) - 8), > > +#include <sysdeps/unix/sysv/linux/sigaction.c> > > static > inhibit_stack_protector > diff --git a/sysdeps/unix/sysv/linux/tile/kernel_sigaction.h b/sysdeps/unix/sysv/linux/tile/kernel_sigaction.h > new file mode 100644 > index 0000000..a943d52 > --- /dev/null > +++ b/sysdeps/unix/sysv/linux/tile/kernel_sigaction.h > @@ -0,0 +1,9 @@ > +/* tile kernel sigaction is similar to generic Linux UAPI one > + and SA_RESTORER is used only for binary compatibility. */ > +#define SA_RESTORER 0x04000000 > +#include <sysdeps/unix/sysv/linux/kernel_sigaction.h> > + > +#define SET_SA_RESTORER(kact, act) \ > + (kact)->sa_restorer = (act)->sa_restorer > +#define RESET_SA_RESTORER(act, kact) \ > + (act)->sa_restorer = (kact)->sa_restorer > diff --git a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c > index 2f7459f..4e6d9cc 100644 > --- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c > +++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c > @@ -16,65 +16,20 @@ > License along with the GNU C Library; if not, see > <http://www.gnu.org/licenses/>. */ > > -#include <sysdep.h> > -#include <errno.h> > -#include <stddef.h> > #include <signal.h> > -#include <string.h> > - > -#include <sysdep.h> > -#include <sys/syscall.h> > - > -/* The difference here is that the sigaction structure used in the > - kernel is not the same as we use in the libc. Therefore we must > - translate it here. */ > -#include <kernel_sigaction.h> > - > -#include "ucontext_i.h" > - > -/* We do not globally define the SA_RESTORER flag so do it here. */ > #define SA_RESTORER 0x04000000 > +#include <kernel_sigaction.h> > > -/* Using the hidden attribute here does not change the code but it > - helps to avoid warnings. */ > extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; > > +#define SET_SA_RESTORER(kact, act) \ > + (kact)->sa_flags = (act)->sa_flags | SA_RESTORER; \ > + (kact)->sa_restorer = &restore_rt > > -/* If ACT is not NULL, change the action for SIG to *ACT. > - If OACT is not NULL, put the old action for SIG in *OACT. */ > -int > -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) > -{ > - int result; > - struct kernel_sigaction kact, koact; > - > - if (act) > - { > - kact.k_sa_handler = act->sa_handler; > - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); > - kact.sa_flags = act->sa_flags | SA_RESTORER; > - > - kact.sa_restorer = &restore_rt; > - } > - > - /* XXX The size argument hopefully will have to be changed to the > - real size of the user-level sigset_t. */ > - result = INLINE_SYSCALL (rt_sigaction, 4, > - sig, act ? &kact : NULL, > - oact ? &koact : NULL, _NSIG / 8); > - if (oact && result >= 0) > - { > - oact->sa_handler = koact.k_sa_handler; > - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); > - oact->sa_flags = koact.sa_flags; > - oact->sa_restorer = koact.sa_restorer; > - } > - return result; > -} > -libc_hidden_def (__libc_sigaction) > - > -#include <nptl/sigaction.c> > +#define RESET_SA_RESTORER(act, kact) \ > + (act)->sa_restorer = (kact)->sa_restorer > > +#include <sysdeps/unix/sysv/linux/sigaction.c> > > /* NOTE: Please think twice before making any changes to the bits of > code below. GDB needs some intimate knowledge about it to > @@ -93,6 +48,8 @@ libc_hidden_def (__libc_sigaction) > a bit tricky. We don't use the gas cfi directives, so that we can > reliably add .cfi_signal_frame. */ > > +#include "ucontext_i.h" > + > #define do_cfa_expr \ > " .byte 0x0f\n" /* DW_CFA_def_cfa_expression */ \ > " .uleb128 2f-1f\n" /* length */ \ >
If no one opposes it, I will commit this shortly. On 19/02/2018 14:50, Adhemerval Zanella wrote: > Ping. > > On 12/02/2018 10:42, Adhemerval Zanella wrote: >> This patch consolidates all Linux sigaction implementation on a default >> one at sysdeps/unix/sysv/linux/sigaction.c. The idea is remove redundant >> code and simplify new ports addition by following the current generic >> Linux User API (UAPI). >> >> The UAPI for new ports defines a generic extensible sigaction struct as: >> >> struct sigaction >> { >> __sighandler_t sa_handler; >> unsigned long sa_flags; >> #ifdef SA_RESTORER >> void (*sa_restorer) (void); >> #endif >> sigset_t sa_mask; >> }; >> >> Where SA_RESTORER is just placed to compatibility reasons, news ports >> should not add it. A similar definition is used on generic >> kernel_sigaction.h. >> >> The user exported sigaction definition is not changed, so for most >> architectures it requires an adjustment to kernel expected one for the >> syscall. >> >> The main changes are: >> >> - All architectures now define and use a kernel_sigaction struct meant >> for the syscall, even for the architectures where the user sigaction >> has the same layout of the kernel expected one (s390-64 and ia64). >> Although it requires more work for these architectures, it simplifies >> the generic implementation. Also, sigaction is hardly a hotspot where >> micro optimization would play an important role. >> >> - The generic kernel_sigaction definition is now aligned with expected >> UAPI one for newer ports, where SA_RESTORER and sa_restorer is not >> expected to be defined. This means adding kernel_sigaction for >> current architectures that does define it (m68k, nios2, powerpc, s390, >> sh, sparc, and tile) and which rely on previous generic definition. >> >> - Remove old MIPS usage of sa_restorer. This was removed since 2.6.27 >> (2957c9e61ee9c - "[MIPS] IRIX: Goodbye and thanks for all the fish"). >> >> So for new ports the generic implementation should work if its uses >> Linux UAPI. If SA_RESTORER is still required (due some architecture >> limitation), it should define its own kernel_sigaction.h, define it and >> include generic header (assuming it still uses the default generic kernel >> layout). >> >> Checked on x86_64-linux-gnu, i686-linux-gnu, arm-linux-gnueabihf, >> aarch64-linux-gnu, sparc64-linux-gnu, sparcv9-linux-gnu, powerpc-linux-gnu, >> and powerpc64-linux-gnu. I also check the build on all remaining affected >> ABIs. >> >> * sysdeps/unix/sysv/linux/aarch64/sigaction.c: Use default Linux version >> as base implementation. >> * sysdeps/unix/sysv/linux/arm/sigaction.c: Likewise. >> * sysdeps/unix/sysv/linux/i386/sigaction.c: Likewise. >> * sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c: Likewise. >> * sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c: Likewise. >> * sysdeps/unix/sysv/linux/x86_64/sigaction.c: Likewise. >> * sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h: Add include guards, >> remove unrequired definitions and update comments. >> * sysdeps/unix/sysv/linux/kernel_sigaction.h: Likewise. >> * sysdeps/unix/sysv/linux/mips/kernel_sigaction.h: Likewise. >> * sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h: New file. >> * sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h: Likewise. >> * sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h: Likewise. >> * sysdeps/unix/sysv/linux/powerpc/kernel_sigaction: Likewise. >> * sysdeps/unix/sysv/linux/s390/kernel_sigaction.h: Likewise. >> * sysdeps/unix/sysv/linux/sh/kernel_sigaction.h: Likewise. >> * sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h: Likewise. >> * sysdeps/unix/sysv/linux/tile/kernel_sigaction.h: Likewise. >> * sysdeps/unix/sysv/linux/ia64/sigaction.c: Remove file. >> * sysdeps/unix/sysv/linux/mips/sigaction.c: Likewise. >> * sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c: Likewise. >> * sysdeps/unix/sysv/linux/sigaction.c: Add STUB, SET_SA_RESTORER, >> and RESET_SA_RESTORER hooks. >> >> Signed-off-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> >> --- >> ChangeLog | 25 +++++ >> sysdeps/unix/sysv/linux/aarch64/sigaction.c | 58 ++--------- >> sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h | 21 ++-- >> sysdeps/unix/sysv/linux/arm/sigaction.c | 79 +++----------- >> sysdeps/unix/sysv/linux/i386/sigaction.c | 76 +++----------- >> sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h | 6 ++ >> sysdeps/unix/sysv/linux/ia64/sigaction.c | 45 -------- >> sysdeps/unix/sysv/linux/kernel_sigaction.h | 31 +++--- >> sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h | 22 ++++ >> sysdeps/unix/sysv/linux/mips/kernel_sigaction.h | 48 ++------- >> sysdeps/unix/sysv/linux/mips/sigaction.c | 116 --------------------- >> sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h | 8 ++ >> sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h | 8 ++ >> sysdeps/unix/sysv/linux/s390/kernel_sigaction.h | 28 +++++ >> sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c | 43 -------- >> sysdeps/unix/sysv/linux/sh/kernel_sigaction.h | 8 ++ >> sysdeps/unix/sysv/linux/sigaction.c | 28 ++--- >> sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h | 10 ++ >> sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c | 41 +------- >> sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c | 43 +------- >> sysdeps/unix/sysv/linux/tile/kernel_sigaction.h | 9 ++ >> sysdeps/unix/sysv/linux/x86_64/sigaction.c | 61 ++--------- >> 22 files changed, 230 insertions(+), 584 deletions(-) >> create mode 100644 sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h >> delete mode 100644 sysdeps/unix/sysv/linux/ia64/sigaction.c >> create mode 100644 sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h >> delete mode 100644 sysdeps/unix/sysv/linux/mips/sigaction.c >> create mode 100644 sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h >> create mode 100644 sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h >> create mode 100644 sysdeps/unix/sysv/linux/s390/kernel_sigaction.h >> delete mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c >> create mode 100644 sysdeps/unix/sysv/linux/sh/kernel_sigaction.h >> create mode 100644 sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h >> create mode 100644 sysdeps/unix/sysv/linux/tile/kernel_sigaction.h >> >> diff --git a/sysdeps/unix/sysv/linux/aarch64/sigaction.c b/sysdeps/unix/sysv/linux/aarch64/sigaction.c >> index 73f4eb7..83d5b4f 100644 >> --- a/sysdeps/unix/sysv/linux/aarch64/sigaction.c >> +++ b/sysdeps/unix/sysv/linux/aarch64/sigaction.c >> @@ -1,5 +1,4 @@ >> /* Copyright (C) 1997-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 >> @@ -16,55 +15,16 @@ >> License along with the GNU C Library; if not, see >> <http://www.gnu.org/licenses/>. */ >> >> -#include <errno.h> >> -#include <signal.h> >> -#include <string.h> >> - >> -#include <sysdep.h> >> -#include <sys/syscall.h> >> - >> +/* Required for AArch32 compatibility. */ >> #define SA_RESTORER 0x04000000 >> >> -/* The difference here is that the sigaction structure used in the >> - kernel is not the same as we use in the libc. Therefore we must >> - translate it here. */ >> -#include <kernel_sigaction.h> >> - >> -int >> -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) >> -{ >> - int result; >> - struct kernel_sigaction kact; >> - struct kernel_sigaction koact; >> - >> - if (act) >> - { >> - kact.k_sa_handler = act->sa_handler; >> - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); >> - kact.sa_flags = act->sa_flags; >> -#ifdef HAVE_SA_RESTORER >> - if (kact.sa_flags & SA_RESTORER) >> - kact.sa_restorer = act->sa_restorer; >> -#endif >> - } >> +#define SET_SA_RESTORER(kact, act) \ >> + ({ \ >> + if ((kact)->sa_flags & SA_RESTORER) \ >> + (kact)->sa_restorer = (act)->sa_restorer; \ >> + }) >> >> - result = INLINE_SYSCALL (rt_sigaction, 4, sig, >> - act ? &kact : NULL, >> - oact ? &koact : NULL, _NSIG / 8); >> - if (result >= 0 || errno != ENOSYS) >> - { >> - if (oact && result >= 0) >> - { >> - oact->sa_handler = koact.k_sa_handler; >> - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); >> - oact->sa_flags = koact.sa_flags; >> -#ifdef HAVE_SA_RESTORER >> - oact->sa_restorer = koact.sa_restorer; >> -#endif >> - } >> - } >> - return result; >> -} >> -libc_hidden_def (__libc_sigaction) >> +#define RESET_SA_RESTORER(act, kact) \ >> + (act)->sa_restorer = (kact)->sa_restorer; >> >> -#include <nptl/sigaction.c> >> +#include <sysdeps/unix/sysv/linux/sigaction.c> >> diff --git a/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h b/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h >> index 4c35d96..25180ff 100644 >> --- a/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h >> +++ b/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h >> @@ -1,15 +1,12 @@ >> -/* This is the sigaction struction from the Linux 2.1.20 kernel. */ >> +#ifndef _KERNEL_SIGACTION_H >> +# define _KERNEL_SIGACTION_H >> >> -struct old_kernel_sigaction { >> - __sighandler_t k_sa_handler; >> - unsigned long sa_mask; >> - unsigned int sa_flags; >> +/* 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; >> }; >> >> -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ >> - >> -struct kernel_sigaction { >> - __sighandler_t k_sa_handler; >> - unsigned int sa_flags; >> - sigset_t sa_mask; >> -}; >> +#endif >> diff --git a/sysdeps/unix/sysv/linux/arm/sigaction.c b/sysdeps/unix/sysv/linux/arm/sigaction.c >> index e4d80de..c828250 100644 >> --- a/sysdeps/unix/sysv/linux/arm/sigaction.c >> +++ b/sysdeps/unix/sysv/linux/arm/sigaction.c >> @@ -15,70 +15,25 @@ >> License along with the GNU C Library. If not, see >> <http://www.gnu.org/licenses/>. */ >> >> -#include <errno.h> >> -#include <signal.h> >> -#include <string.h> >> - >> -#include <sysdep.h> >> -#include <sys/syscall.h> >> - >> -/* The difference here is that the sigaction structure used in the >> - kernel is not the same as we use in the libc. Therefore we must >> - translate it here. */ >> -#include <kernel_sigaction.h> >> - >> #define SA_RESTORER 0x04000000 >> >> extern void __default_sa_restorer (void); >> extern void __default_rt_sa_restorer (void); >> >> -/* When RT signals are in use we need to use a different return stub. */ >> -#define choose_restorer(flags) \ >> - (flags & SA_SIGINFO) ? __default_rt_sa_restorer \ >> - : __default_sa_restorer >> - >> -/* If ACT is not NULL, change the action for SIG to *ACT. >> - If OACT is not NULL, put the old action for SIG in *OACT. */ >> -int >> -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) >> -{ >> - int result; >> - >> - struct kernel_sigaction kact, koact; >> - >> - if (act) >> - { >> - kact.k_sa_handler = act->sa_handler; >> - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); >> - kact.sa_flags = act->sa_flags; >> -#ifdef HAVE_SA_RESTORER >> - if (kact.sa_flags & SA_RESTORER) >> - kact.sa_restorer = act->sa_restorer; >> - else >> - { >> - kact.sa_restorer = choose_restorer (kact.sa_flags); >> - kact.sa_flags |= SA_RESTORER; >> - } >> -#endif >> - } >> - >> - /* XXX The size argument hopefully will have to be changed to the >> - real size of the user-level sigset_t. */ >> - result = INLINE_SYSCALL (rt_sigaction, 4, sig, >> - act ? &kact : NULL, >> - oact ? &koact : NULL, _NSIG / 8); >> - >> - if (oact && result >= 0) >> - { >> - oact->sa_handler = koact.k_sa_handler; >> - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); >> - oact->sa_flags = koact.sa_flags; >> -#ifdef HAVE_SA_RESTORER >> - oact->sa_restorer = koact.sa_restorer; >> -#endif >> - } >> - return result; >> -} >> -libc_hidden_def (__libc_sigaction) >> - >> -#include <nptl/sigaction.c> >> +#define SET_SA_RESTORER(kact, act) \ >> + ({ \ >> + if ((kact)->sa_flags & SA_RESTORER) \ >> + (kact)->sa_restorer = (act)->sa_restorer; \ >> + else \ >> + { \ >> + (kact)->sa_restorer = ((kact)->sa_flags & SA_SIGINFO) \ >> + ? __default_rt_sa_restorer \ >> + : __default_sa_restorer; \ >> + (kact)->sa_flags |= SA_RESTORER; \ >> + } \ >> + }) >> + >> +#define RESET_SA_RESTORER(act, kact) \ >> + (act)->sa_restorer = (kact)->sa_restorer; >> + >> +#include <sysdeps/unix/sysv/linux/sigaction.c> >> diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c >> index a5eb9e0..137c73b 100644 >> --- a/sysdeps/unix/sysv/linux/i386/sigaction.c >> +++ b/sysdeps/unix/sysv/linux/i386/sigaction.c >> @@ -16,78 +16,28 @@ >> License along with the GNU C Library; if not, see >> <http://www.gnu.org/licenses/>. */ >> >> -#include <sysdep.h> >> -#include <errno.h> >> -#include <stddef.h> >> #include <signal.h> >> -#include <string.h> >> - >> -#include <sysdep.h> >> -#include <sys/syscall.h> >> #include <ldsodefs.h> >> >> -/* The difference here is that the sigaction structure used in the >> - kernel is not the same as we use in the libc. Therefore we must >> - translate it here. */ >> -#include <kernel_sigaction.h> >> - >> -/* We do not globally define the SA_RESTORER flag so do it here. */ >> #define SA_RESTORER 0x04000000 >> >> - >> -/* Using the hidden attribute here does not change the code but it >> - helps to avoid warnings. */ >> -#ifdef __NR_rt_sigaction >> extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; >> -#endif >> extern void restore (void) asm ("__restore") attribute_hidden; >> >> +#define SET_SA_RESTORER(kact, act) \ >> + ({ \ >> + if (GLRO(dl_sysinfo_dso) == NULL) \ >> + { \ >> + (kact)->sa_flags |= SA_RESTORER; \ >> + (kact)->sa_restorer = (((act)->sa_flags & SA_SIGINFO) \ >> + ? &restore_rt : &restore); \ >> + } \ >> + }) >> >> -/* If ACT is not NULL, change the action for SIG to *ACT. >> - If OACT is not NULL, put the old action for SIG in *OACT. */ >> -int >> -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) >> -{ >> - int result; >> - >> - struct kernel_sigaction kact, koact; >> - >> - if (act) >> - { >> - kact.k_sa_handler = act->sa_handler; >> - kact.sa_flags = act->sa_flags; >> - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); >> - >> - if (GLRO(dl_sysinfo_dso) == NULL) >> - { >> - kact.sa_flags |= SA_RESTORER; >> - >> - kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) >> - ? &restore_rt : &restore); >> - } >> - } >> - >> - /* XXX The size argument hopefully will have to be changed to the >> - real size of the user-level sigset_t. */ >> - INTERNAL_SYSCALL_DECL (err); >> - result = INTERNAL_SYSCALL (rt_sigaction, err, 4, >> - sig, act ? &kact : NULL, >> - oact ? &koact : NULL, _NSIG / 8); >> - if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err))) >> - return INLINE_SYSCALL_ERROR_RETURN_VALUE (INTERNAL_SYSCALL_ERRNO (result, >> - err)); >> - else if (oact && result >= 0) >> - { >> - oact->sa_handler = koact.k_sa_handler; >> - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); >> - oact->sa_flags = koact.sa_flags; >> - oact->sa_restorer = koact.sa_restorer; >> - } >> - return result; >> -} >> -libc_hidden_def (__libc_sigaction) >> +#define RESET_SA_RESTORER(act, kact) \ >> + (act)->sa_restorer = (kact)->sa_restorer >> >> -#include <nptl/sigaction.c> >> +#include <sysdeps/unix/sysv/linux/sigaction.c> >> >> /* NOTE: Please think twice before making any changes to the bits of >> code below. GDB needs some intimate knowledge about it to >> @@ -108,10 +58,8 @@ asm \ >> " int $0x80" \ >> ); >> >> -#ifdef __NR_rt_sigaction >> /* The return code for realtime-signals. */ >> RESTORE (restore_rt, __NR_rt_sigreturn) >> -#endif >> >> /* For the boring old signals. */ >> #undef RESTORE2 >> diff --git a/sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h b/sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h >> new file mode 100644 >> index 0000000..05813db >> --- /dev/null >> +++ b/sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h >> @@ -0,0 +1,6 @@ >> +/* This is the sigaction structure from the Linux 3.2 kernel. */ >> +struct kernel_sigaction { >> + __sighandler_t k_sa_handler; >> + unsigned long sa_flags; >> + sigset_t sa_mask; /* mask last for extensibility */ >> +}; >> diff --git a/sysdeps/unix/sysv/linux/ia64/sigaction.c b/sysdeps/unix/sysv/linux/ia64/sigaction.c >> deleted file mode 100644 >> index e7fb8cd..0000000 >> --- a/sysdeps/unix/sysv/linux/ia64/sigaction.c >> +++ /dev/null >> @@ -1,45 +0,0 @@ >> -/* Copyright (C) 1997-2018 Free Software Foundation, Inc. >> - This file is part of the GNU C Library. >> - Linux/IA64 specific sigaction >> - Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999. >> - >> - 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/>. */ >> - >> -/* Linux/ia64 only has rt signals, thus we do not even want to try falling >> - back to the old style signals as the default Linux handler does. */ >> - >> -#include <errno.h> >> -#include <signal.h> >> -#include <string.h> >> - >> -#include <sysdep.h> >> -#include <sys/syscall.h> >> - >> -/* The variable is shared between all wrappers around signal handling >> - functions which have RT equivalents. This is the definition. */ >> - >> - >> -/* If ACT is not NULL, change the action for SIG to *ACT. >> - If OACT is not NULL, put the old action for SIG in *OACT. */ >> -int >> -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) >> -{ >> - /* XXX The size argument hopefully will have to be changed to the >> - real size of the user-level sigset_t. */ >> - return INLINE_SYSCALL (rt_sigaction, 4, sig, act, oact, _NSIG / 8); >> -} >> -libc_hidden_def (__libc_sigaction) >> - >> -#include <nptl/sigaction.c> >> diff --git a/sysdeps/unix/sysv/linux/kernel_sigaction.h b/sysdeps/unix/sysv/linux/kernel_sigaction.h >> index d005cbc..2dbec08 100644 >> --- a/sysdeps/unix/sysv/linux/kernel_sigaction.h >> +++ b/sysdeps/unix/sysv/linux/kernel_sigaction.h >> @@ -1,19 +1,20 @@ >> -/* This is the sigaction structure from the Linux 2.1.20 kernel. */ >> +#ifndef _KERNEL_SIGACTION_H >> +# define _KERNEL_SIGACTION_H >> >> -#define HAVE_SA_RESTORER >> - >> -struct old_kernel_sigaction { >> - __sighandler_t k_sa_handler; >> - unsigned long sa_mask; >> - unsigned long sa_flags; >> - void (*sa_restorer) (void); >> +/* This is the sigaction structure from the Linux 3.2 kernel. */ >> +struct kernel_sigaction >> +{ >> + __sighandler_t k_sa_handler; >> + unsigned long sa_flags; >> +#ifdef SA_RESTORER >> + void (*sa_restorer) (void); >> +#endif >> + sigset_t sa_mask; >> }; >> >> -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ >> +#ifndef SA_RESTORER >> +# define SET_SA_RESTORER(kact, act) >> +# define RESET_SA_RESTORER(act, kact) >> +#endif >> >> -struct kernel_sigaction { >> - __sighandler_t k_sa_handler; >> - unsigned long sa_flags; >> - void (*sa_restorer) (void); >> - sigset_t sa_mask; >> -}; >> +#endif >> diff --git a/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h b/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h >> new file mode 100644 >> index 0000000..54972fe >> --- /dev/null >> +++ b/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h >> @@ -0,0 +1,22 @@ >> +#ifndef _KERNEL_SIGACTION_H >> +# define _KERNEL_SIGACTION_H >> + >> +#include <signal.h> >> + >> +#define SA_RESTORER 0x04000000 >> + >> +/* This is the sigaction structure from the Linux 3.2 kernel. */ >> +struct kernel_sigaction >> +{ >> + __sighandler_t k_sa_handler; >> + sigset_t sa_mask; >> + unsigned long sa_flags; >> + void (*sa_restorer) (void); >> +}; >> + >> +#define SET_SA_RESTORER(kact, act) \ >> + (kact)->sa_restorer = (act)->sa_restorer >> +#define RESET_SA_RESTORER(act, kact) \ >> + (act)->sa_restorer = (kact)->sa_restorer >> + >> +#endif >> diff --git a/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h b/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h >> index b6f52cc..beef976 100644 >> --- a/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h >> +++ b/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h >> @@ -1,40 +1,12 @@ >> -/* This is the sigaction structure from the Linux 2.1.24 kernel. */ >> - >> -#include <sgidefs.h> >> - >> -#define HAVE_SA_RESTORER >> - >> -struct old_kernel_sigaction { >> - unsigned int sa_flags; >> - __sighandler_t k_sa_handler; >> - unsigned long sa_mask; >> - unsigned int __pad0[3]; /* reserved, keep size constant */ >> - >> - /* Abi says here follows reserved int[2] */ >> - void (*sa_restorer)(void); >> -#if (_MIPS_SZPTR < 64) >> - /* >> - * For 32 bit code we have to pad struct sigaction to get >> - * constant size for the ABI >> - */ >> - int pad1[1]; /* reserved */ >> -#endif >> +#ifndef _KERNEL_SIGACTION_H >> +# define _KERNEL_SIGACTION_H >> + >> +/* This is the sigaction structure from the Linux 3.2 kernel. */ >> +struct kernel_sigaction >> +{ >> + unsigned int sa_flags; >> + __sighandler_t k_sa_handler; >> + sigset_t sa_mask; >> }; >> >> - >> -#define _KERNEL_NSIG 128 >> -#define _KERNEL_NSIG_BPW _MIPS_SZLONG >> -#define _KERNEL_NSIG_WORDS (_KERNEL_NSIG / _KERNEL_NSIG_BPW) >> - >> -typedef struct { >> - unsigned long sig[_KERNEL_NSIG_WORDS]; >> -} kernel_sigset_t; >> - >> -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ >> -struct kernel_sigaction { >> - unsigned int sa_flags; >> - __sighandler_t k_sa_handler; >> - kernel_sigset_t sa_mask; >> - void (*sa_restorer)(void); >> - int s_resv[1]; /* reserved */ >> -}; >> +#endif >> diff --git a/sysdeps/unix/sysv/linux/mips/sigaction.c b/sysdeps/unix/sysv/linux/mips/sigaction.c >> deleted file mode 100644 >> index 008b688..0000000 >> --- a/sysdeps/unix/sysv/linux/mips/sigaction.c >> +++ /dev/null >> @@ -1,116 +0,0 @@ >> -/* Copyright (C) 1997-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 >> - <http://www.gnu.org/licenses/>. */ >> - >> -#include <errno.h> >> -#include <sgidefs.h> >> -#include <signal.h> >> -#include <string.h> >> - >> -#include <sysdep.h> >> -#include <sys/syscall.h> >> - >> -#include <sgidefs.h> >> - >> -/* The difference here is that the sigaction structure used in the >> - kernel is not the same as we use in the libc. Therefore we must >> - translate it here. */ >> -#include <kernel_sigaction.h> >> - >> -#if _MIPS_SIM != _ABIO32 >> - >> -# ifdef __NR_rt_sigreturn >> -static void restore_rt (void) asm ("__restore_rt"); >> -# endif >> -# ifdef __NR_sigreturn >> -static void restore (void) asm ("__restore"); >> -# endif >> -#endif >> - >> -/* If ACT is not NULL, change the action for SIG to *ACT. >> - If OACT is not NULL, put the old action for SIG in *OACT. */ >> -int >> -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) >> -{ >> - int result; >> - >> - struct kernel_sigaction kact, koact; >> - >> - if (act) >> - { >> - kact.k_sa_handler = act->sa_handler; >> - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kernel_sigset_t)); >> - kact.sa_flags = act->sa_flags; >> -#ifdef HAVE_SA_RESTORER >> -# if _MIPS_SIM == _ABIO32 >> - kact.sa_restorer = act->sa_restorer; >> -# else >> - kact.sa_restorer = &restore_rt; >> -# endif >> -#endif >> - } >> - >> - /* XXX The size argument hopefully will have to be changed to the >> - real size of the user-level sigset_t. */ >> - result = INLINE_SYSCALL (rt_sigaction, 4, sig, >> - act ? &kact : NULL, >> - oact ? &koact : NULL, >> - sizeof (kernel_sigset_t)); >> - >> - if (oact && result >= 0) >> - { >> - oact->sa_handler = koact.k_sa_handler; >> - memcpy (&oact->sa_mask, &koact.sa_mask, >> - sizeof (kernel_sigset_t)); >> - oact->sa_flags = koact.sa_flags; >> -#ifdef HAVE_SA_RESTORER >> - oact->sa_restorer = koact.sa_restorer; >> -#endif >> - } >> - return result; >> -} >> -libc_hidden_def (__libc_sigaction) >> - >> -#include <nptl/sigaction.c> >> - >> - >> -/* NOTE: Please think twice before making any changes to the bits of >> - code below. GDB needs some intimate knowledge about it to >> - recognize them as signal trampolines, and make backtraces through >> - signal handlers work right. Important are both the names >> - (__restore_rt) and the exact instruction sequence. >> - If you ever feel the need to make any changes, please notify the >> - appropriate GDB maintainer. */ >> - >> -#define RESTORE(name, syscall) RESTORE2 (name, syscall) >> -#define RESTORE2(name, syscall) \ >> -asm \ >> - ( \ >> - ".align 4\n" \ >> - "__" #name ":\n" \ >> - " li $2, " #syscall "\n" \ >> - " syscall\n" \ >> - ); >> - >> -/* The return code for realtime-signals. */ >> -#if _MIPS_SIM != _ABIO32 >> -# ifdef __NR_rt_sigreturn >> -RESTORE (restore_rt, __NR_rt_sigreturn) >> -# endif >> -# ifdef __NR_sigreturn >> -RESTORE (restore, __NR_sigreturn) >> -# endif >> -#endif >> diff --git a/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h b/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h >> new file mode 100644 >> index 0000000..4ada322 >> --- /dev/null >> +++ b/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h >> @@ -0,0 +1,8 @@ >> +/* NIOS2 uses the generic Linux UAPI but defines SA_RESTORER. */ >> +#define SA_RESTORER 0x04000000 >> +#include <sysdeps/unix/sysv/linux/kernel_sigaction.h> >> + >> +#define SET_SA_RESTORER(kact, act) \ >> + (kact)->sa_restorer = (act)->sa_restorer >> +#define RESET_SA_RESTORER(act, kact) \ >> + (act)->sa_restorer = (kact)->sa_restorer >> diff --git a/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h b/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h >> new file mode 100644 >> index 0000000..c5213f2 >> --- /dev/null >> +++ b/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h >> @@ -0,0 +1,8 @@ >> +/* powerpc kernel sigaction is similar to generic Linux UAPI one. */ >> +#define SA_RESTORER 0x04000000 >> +#include <sysdeps/unix/sysv/linux/kernel_sigaction.h> >> + >> +#define SET_SA_RESTORER(kact, act) \ >> + (kact)->sa_restorer = (act)->sa_restorer >> +#define RESET_SA_RESTORER(act, kact) \ >> + (act)->sa_restorer = (kact)->sa_restorer >> diff --git a/sysdeps/unix/sysv/linux/s390/kernel_sigaction.h b/sysdeps/unix/sysv/linux/s390/kernel_sigaction.h >> new file mode 100644 >> index 0000000..a8beaf7 >> --- /dev/null >> +++ b/sysdeps/unix/sysv/linux/s390/kernel_sigaction.h >> @@ -0,0 +1,28 @@ >> +#include <bits/types/siginfo_t.h> >> + >> +#define SA_RESTORER 0x04000000 >> + >> +/* This is the sigaction structure from the Linux 3.2 kernel. */ >> +struct kernel_sigaction >> +{ >> + union >> + { >> + __sighandler_t _sa_handler; >> + void (*_sa_sigaction)(int, siginfo_t *, void *); >> + } _u; >> +#define k_sa_handler _u._sa_handler >> +#ifndef __s390x__ >> + sigset_t sa_mask; >> + unsigned long sa_flags; >> + void (*sa_restorer)(void); >> +#else >> + unsigned long sa_flags; >> + void (*sa_restorer)(void); >> + sigset_t sa_mask; >> +#endif >> +}; >> + >> +#define SET_SA_RESTORER(kact, act) \ >> + (kact)->sa_restorer = (act)->sa_restorer >> +#define RESET_SA_RESTORER(act, kact) \ >> + (act)->sa_restorer = (kact)->sa_restorer >> diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c b/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c >> deleted file mode 100644 >> index c13927c..0000000 >> --- a/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c >> +++ /dev/null >> @@ -1,43 +0,0 @@ >> -/* Copyright (C) 2001-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 >> - <http://www.gnu.org/licenses/>. */ >> - >> -/* 64 bit Linux for S/390 only has rt signals, thus we do not even want to try >> - falling back to the old style signals as the default Linux handler does. */ >> - >> -#include <errno.h> >> -#include <signal.h> >> -#include <string.h> >> - >> -#include <sysdep.h> >> -#include <sys/syscall.h> >> - >> -/* The variable is shared between all wrappers around signal handling >> - functions which have RT equivalents. This is the definition. */ >> - >> - >> -/* If ACT is not NULL, change the action for SIG to *ACT. >> - If OACT is not NULL, put the old action for SIG in *OACT. */ >> -int >> -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) >> -{ >> - /* XXX The size argument hopefully will have to be changed to the >> - real size of the user-level sigset_t. */ >> - return INLINE_SYSCALL (rt_sigaction, 4, sig, act, oact, _NSIG / 8); >> -} >> -libc_hidden_def (__libc_sigaction) >> - >> -#include <nptl/sigaction.c> >> diff --git a/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h b/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h >> new file mode 100644 >> index 0000000..7ebcd08 >> --- /dev/null >> +++ b/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h >> @@ -0,0 +1,8 @@ >> +/* SH uses the generic Linux UAPI but defines SA_RESTORER. */ >> +#define SA_RESTORER 0x04000000 >> +#include <sysdeps/unix/sysv/linux/kernel_sigaction.h> >> + >> +#define SET_SA_RESTORER(kact, act) \ >> + (kact)->sa_restorer = (act)->sa_restorer >> +#define RESET_SA_RESTORER(act, kact) \ >> + (act)->sa_restorer = (kact)->sa_restorer >> diff --git a/sysdeps/unix/sysv/linux/sigaction.c b/sysdeps/unix/sysv/linux/sigaction.c >> index 40a311a..0e6851a 100644 >> --- a/sysdeps/unix/sysv/linux/sigaction.c >> +++ b/sysdeps/unix/sysv/linux/sigaction.c >> @@ -22,11 +22,19 @@ >> #include <sysdep.h> >> #include <sys/syscall.h> >> >> -/* The difference here is that the sigaction structure used in the >> - kernel is not the same as we use in the libc. Therefore we must >> - translate it here. */ >> +/* New ports should not define the obsolete SA_RESTORER, however some >> + architecture requires for compat mode and/or due old ABI. */ >> #include <kernel_sigaction.h> >> >> +#ifndef SA_RESTORER >> +# define SET_SA_RESTORER(kact, act) >> +# define RESET_SA_RESTORER(act, kact) >> +#endif >> + >> +/* SPARC passes the restore function as an argument to rt_sigaction. */ >> +#ifndef STUB >> +# define STUB(act) >> +#endif >> >> /* If ACT is not NULL, change the action for SIG to *ACT. >> If OACT is not NULL, put the old action for SIG in *OACT. */ >> @@ -42,25 +50,21 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) >> kact.k_sa_handler = act->sa_handler; >> memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); >> kact.sa_flags = act->sa_flags; >> -#ifdef HAVE_SA_RESTORER >> - kact.sa_restorer = act->sa_restorer; >> -#endif >> + SET_SA_RESTORER (&kact, act); >> } >> >> /* XXX The size argument hopefully will have to be changed to the >> real size of the user-level sigset_t. */ >> - result = INLINE_SYSCALL (rt_sigaction, 4, sig, >> - act ? &kact : NULL, >> - oact ? &koact : NULL, _NSIG / 8); >> + result = INLINE_SYSCALL_CALL (rt_sigaction, sig, >> + act ? &kact : NULL, >> + oact ? &koact : NULL, STUB(act) _NSIG / 8); >> >> if (oact && result >= 0) >> { >> oact->sa_handler = koact.k_sa_handler; >> memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); >> oact->sa_flags = koact.sa_flags; >> -#ifdef HAVE_SA_RESTORER >> - oact->sa_restorer = koact.sa_restorer; >> -#endif >> + RESET_SA_RESTORER (oact, &koact); >> } >> return result; >> } >> diff --git a/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h >> new file mode 100644 >> index 0000000..bee7e9c >> --- /dev/null >> +++ b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h >> @@ -0,0 +1,10 @@ >> +/* SPARC 'struct __new_sigaction' is similar to generic Linux UAPI with >> + a sa_restorer field, even though function is passed as an argument >> + to rt_sigaction syscall. */ >> +#define SA_RESTORER 0x04000000 >> +#include <sysdeps/unix/sysv/linux/kernel_sigaction.h> >> + >> +#define SET_SA_RESTORER(kact, act) \ >> + (kact)->sa_restorer = NULL >> +#define RESET_SA_RESTORER(act, kact) \ >> + (act)->sa_restorer = (kact)->sa_restorer >> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c >> index 204a5d8..c1d8f45 100644 >> --- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c >> +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c >> @@ -27,43 +27,12 @@ >> static void __rt_sigreturn_stub (void); >> static void __sigreturn_stub (void); >> >> -int >> -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) >> -{ >> - struct kernel_sigaction kact, koact; >> - unsigned long stub = 0; >> - int ret; >> - >> - if (act) >> - { >> - kact.k_sa_handler = act->sa_handler; >> - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); >> - if (((kact.sa_flags = act->sa_flags) & SA_SIGINFO) != 0) >> - stub = (unsigned long) &__rt_sigreturn_stub; >> - else >> - stub = (unsigned long) &__sigreturn_stub; >> - stub -= 8; >> - kact.sa_restorer = NULL; >> - } >> - >> - /* XXX The size argument hopefully will have to be changed to the >> - real size of the user-level sigset_t. */ >> - ret = INLINE_SYSCALL (rt_sigaction, 5, sig, act ? &kact : 0, >> - oact ? &koact : 0, stub, _NSIG / 8); >> - >> - if (oact && ret >= 0) >> - { >> - oact->sa_handler = koact.k_sa_handler; >> - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); >> - oact->sa_flags = koact.sa_flags; >> - oact->sa_restorer = koact.sa_restorer; >> - } >> - return ret; >> -} >> -libc_hidden_def (__libc_sigaction) >> - >> -#include <nptl/sigaction.c> >> +#define STUB(act) \ >> + ((unsigned long)((act->sa_flags & SA_SIGINFO) \ >> + ? &__rt_sigreturn_stub \ >> + : &__sigreturn_stub) - 8), >> >> +#include <sysdeps/unix/sysv/linux/sigaction.c> >> >> static >> inhibit_stack_protector >> diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c >> index 73cda4c..cfbbc6e 100644 >> --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c >> +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c >> @@ -21,50 +21,13 @@ >> #include <string.h> >> #include <syscall.h> >> #include <sysdep.h> >> -#include <sys/signal.h> >> -#include <errno.h> >> - >> -#include <kernel_sigaction.h> >> - >> -/* SPARC 64bit userland requires a kernel that has rt signals anyway. */ >> >> static void __rt_sigreturn_stub (void); >> >> -int >> -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) >> -{ >> - int ret; >> - struct kernel_sigaction kact, koact; >> - unsigned long stub = ((unsigned long) &__rt_sigreturn_stub) - 8; >> - >> - if (act) >> - { >> - kact.k_sa_handler = act->sa_handler; >> - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); >> - kact.sa_flags = act->sa_flags; >> - kact.sa_restorer = NULL; >> - } >> - >> - /* XXX The size argument hopefully will have to be changed to the >> - real size of the user-level sigset_t. */ >> - ret = INLINE_SYSCALL (rt_sigaction, 5, sig, >> - act ? &kact : 0, >> - oact ? &koact : 0, stub, _NSIG / 8); >> - >> - if (oact && ret >= 0) >> - { >> - oact->sa_handler = koact.k_sa_handler; >> - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); >> - oact->sa_flags = koact.sa_flags; >> - oact->sa_restorer = koact.sa_restorer; >> - } >> - >> - return ret; >> -} >> -libc_hidden_def (__libc_sigaction) >> - >> -#include <nptl/sigaction.c> >> +#define STUB(act) \ >> + (((unsigned long) &__rt_sigreturn_stub) - 8), >> >> +#include <sysdeps/unix/sysv/linux/sigaction.c> >> >> static >> inhibit_stack_protector >> diff --git a/sysdeps/unix/sysv/linux/tile/kernel_sigaction.h b/sysdeps/unix/sysv/linux/tile/kernel_sigaction.h >> new file mode 100644 >> index 0000000..a943d52 >> --- /dev/null >> +++ b/sysdeps/unix/sysv/linux/tile/kernel_sigaction.h >> @@ -0,0 +1,9 @@ >> +/* tile kernel sigaction is similar to generic Linux UAPI one >> + and SA_RESTORER is used only for binary compatibility. */ >> +#define SA_RESTORER 0x04000000 >> +#include <sysdeps/unix/sysv/linux/kernel_sigaction.h> >> + >> +#define SET_SA_RESTORER(kact, act) \ >> + (kact)->sa_restorer = (act)->sa_restorer >> +#define RESET_SA_RESTORER(act, kact) \ >> + (act)->sa_restorer = (kact)->sa_restorer >> diff --git a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c >> index 2f7459f..4e6d9cc 100644 >> --- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c >> +++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c >> @@ -16,65 +16,20 @@ >> License along with the GNU C Library; if not, see >> <http://www.gnu.org/licenses/>. */ >> >> -#include <sysdep.h> >> -#include <errno.h> >> -#include <stddef.h> >> #include <signal.h> >> -#include <string.h> >> - >> -#include <sysdep.h> >> -#include <sys/syscall.h> >> - >> -/* The difference here is that the sigaction structure used in the >> - kernel is not the same as we use in the libc. Therefore we must >> - translate it here. */ >> -#include <kernel_sigaction.h> >> - >> -#include "ucontext_i.h" >> - >> -/* We do not globally define the SA_RESTORER flag so do it here. */ >> #define SA_RESTORER 0x04000000 >> +#include <kernel_sigaction.h> >> >> -/* Using the hidden attribute here does not change the code but it >> - helps to avoid warnings. */ >> extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; >> >> +#define SET_SA_RESTORER(kact, act) \ >> + (kact)->sa_flags = (act)->sa_flags | SA_RESTORER; \ >> + (kact)->sa_restorer = &restore_rt >> >> -/* If ACT is not NULL, change the action for SIG to *ACT. >> - If OACT is not NULL, put the old action for SIG in *OACT. */ >> -int >> -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) >> -{ >> - int result; >> - struct kernel_sigaction kact, koact; >> - >> - if (act) >> - { >> - kact.k_sa_handler = act->sa_handler; >> - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); >> - kact.sa_flags = act->sa_flags | SA_RESTORER; >> - >> - kact.sa_restorer = &restore_rt; >> - } >> - >> - /* XXX The size argument hopefully will have to be changed to the >> - real size of the user-level sigset_t. */ >> - result = INLINE_SYSCALL (rt_sigaction, 4, >> - sig, act ? &kact : NULL, >> - oact ? &koact : NULL, _NSIG / 8); >> - if (oact && result >= 0) >> - { >> - oact->sa_handler = koact.k_sa_handler; >> - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); >> - oact->sa_flags = koact.sa_flags; >> - oact->sa_restorer = koact.sa_restorer; >> - } >> - return result; >> -} >> -libc_hidden_def (__libc_sigaction) >> - >> -#include <nptl/sigaction.c> >> +#define RESET_SA_RESTORER(act, kact) \ >> + (act)->sa_restorer = (kact)->sa_restorer >> >> +#include <sysdeps/unix/sysv/linux/sigaction.c> >> >> /* NOTE: Please think twice before making any changes to the bits of >> code below. GDB needs some intimate knowledge about it to >> @@ -93,6 +48,8 @@ libc_hidden_def (__libc_sigaction) >> a bit tricky. We don't use the gas cfi directives, so that we can >> reliably add .cfi_signal_frame. */ >> >> +#include "ucontext_i.h" >> + >> #define do_cfa_expr \ >> " .byte 0x0f\n" /* DW_CFA_def_cfa_expression */ \ >> " .uleb128 2f-1f\n" /* length */ \ >>
diff --git a/sysdeps/unix/sysv/linux/aarch64/sigaction.c b/sysdeps/unix/sysv/linux/aarch64/sigaction.c index 73f4eb7..83d5b4f 100644 --- a/sysdeps/unix/sysv/linux/aarch64/sigaction.c +++ b/sysdeps/unix/sysv/linux/aarch64/sigaction.c @@ -1,5 +1,4 @@ /* Copyright (C) 1997-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 @@ -16,55 +15,16 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <errno.h> -#include <signal.h> -#include <string.h> - -#include <sysdep.h> -#include <sys/syscall.h> - +/* Required for AArch32 compatibility. */ #define SA_RESTORER 0x04000000 -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include <kernel_sigaction.h> - -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - struct kernel_sigaction kact; - struct kernel_sigaction koact; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - kact.sa_flags = act->sa_flags; -#ifdef HAVE_SA_RESTORER - if (kact.sa_flags & SA_RESTORER) - kact.sa_restorer = act->sa_restorer; -#endif - } +#define SET_SA_RESTORER(kact, act) \ + ({ \ + if ((kact)->sa_flags & SA_RESTORER) \ + (kact)->sa_restorer = (act)->sa_restorer; \ + }) - result = INLINE_SYSCALL (rt_sigaction, 4, sig, - act ? &kact : NULL, - oact ? &koact : NULL, _NSIG / 8); - if (result >= 0 || errno != ENOSYS) - { - if (oact && result >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; -#ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; -#endif - } - } - return result; -} -libc_hidden_def (__libc_sigaction) +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer; -#include <nptl/sigaction.c> +#include <sysdeps/unix/sysv/linux/sigaction.c> diff --git a/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h b/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h index 4c35d96..25180ff 100644 --- a/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h +++ b/sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h @@ -1,15 +1,12 @@ -/* This is the sigaction struction from the Linux 2.1.20 kernel. */ +#ifndef _KERNEL_SIGACTION_H +# define _KERNEL_SIGACTION_H -struct old_kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned long sa_mask; - unsigned int sa_flags; +/* 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; }; -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ - -struct kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned int sa_flags; - sigset_t sa_mask; -}; +#endif diff --git a/sysdeps/unix/sysv/linux/arm/sigaction.c b/sysdeps/unix/sysv/linux/arm/sigaction.c index e4d80de..c828250 100644 --- a/sysdeps/unix/sysv/linux/arm/sigaction.c +++ b/sysdeps/unix/sysv/linux/arm/sigaction.c @@ -15,70 +15,25 @@ License along with the GNU C Library. If not, see <http://www.gnu.org/licenses/>. */ -#include <errno.h> -#include <signal.h> -#include <string.h> - -#include <sysdep.h> -#include <sys/syscall.h> - -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include <kernel_sigaction.h> - #define SA_RESTORER 0x04000000 extern void __default_sa_restorer (void); extern void __default_rt_sa_restorer (void); -/* When RT signals are in use we need to use a different return stub. */ -#define choose_restorer(flags) \ - (flags & SA_SIGINFO) ? __default_rt_sa_restorer \ - : __default_sa_restorer - -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - - struct kernel_sigaction kact, koact; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - kact.sa_flags = act->sa_flags; -#ifdef HAVE_SA_RESTORER - if (kact.sa_flags & SA_RESTORER) - kact.sa_restorer = act->sa_restorer; - else - { - kact.sa_restorer = choose_restorer (kact.sa_flags); - kact.sa_flags |= SA_RESTORER; - } -#endif - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - result = INLINE_SYSCALL (rt_sigaction, 4, sig, - act ? &kact : NULL, - oact ? &koact : NULL, _NSIG / 8); - - if (oact && result >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; -#ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; -#endif - } - return result; -} -libc_hidden_def (__libc_sigaction) - -#include <nptl/sigaction.c> +#define SET_SA_RESTORER(kact, act) \ + ({ \ + if ((kact)->sa_flags & SA_RESTORER) \ + (kact)->sa_restorer = (act)->sa_restorer; \ + else \ + { \ + (kact)->sa_restorer = ((kact)->sa_flags & SA_SIGINFO) \ + ? __default_rt_sa_restorer \ + : __default_sa_restorer; \ + (kact)->sa_flags |= SA_RESTORER; \ + } \ + }) + +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer; + +#include <sysdeps/unix/sysv/linux/sigaction.c> diff --git a/sysdeps/unix/sysv/linux/i386/sigaction.c b/sysdeps/unix/sysv/linux/i386/sigaction.c index a5eb9e0..137c73b 100644 --- a/sysdeps/unix/sysv/linux/i386/sigaction.c +++ b/sysdeps/unix/sysv/linux/i386/sigaction.c @@ -16,78 +16,28 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <sysdep.h> -#include <errno.h> -#include <stddef.h> #include <signal.h> -#include <string.h> - -#include <sysdep.h> -#include <sys/syscall.h> #include <ldsodefs.h> -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include <kernel_sigaction.h> - -/* We do not globally define the SA_RESTORER flag so do it here. */ #define SA_RESTORER 0x04000000 - -/* Using the hidden attribute here does not change the code but it - helps to avoid warnings. */ -#ifdef __NR_rt_sigaction extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; -#endif extern void restore (void) asm ("__restore") attribute_hidden; +#define SET_SA_RESTORER(kact, act) \ + ({ \ + if (GLRO(dl_sysinfo_dso) == NULL) \ + { \ + (kact)->sa_flags |= SA_RESTORER; \ + (kact)->sa_restorer = (((act)->sa_flags & SA_SIGINFO) \ + ? &restore_rt : &restore); \ + } \ + }) -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - - struct kernel_sigaction kact, koact; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - kact.sa_flags = act->sa_flags; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - - if (GLRO(dl_sysinfo_dso) == NULL) - { - kact.sa_flags |= SA_RESTORER; - - kact.sa_restorer = ((act->sa_flags & SA_SIGINFO) - ? &restore_rt : &restore); - } - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - INTERNAL_SYSCALL_DECL (err); - result = INTERNAL_SYSCALL (rt_sigaction, err, 4, - sig, act ? &kact : NULL, - oact ? &koact : NULL, _NSIG / 8); - if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (result, err))) - return INLINE_SYSCALL_ERROR_RETURN_VALUE (INTERNAL_SYSCALL_ERRNO (result, - err)); - else if (oact && result >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; - oact->sa_restorer = koact.sa_restorer; - } - return result; -} -libc_hidden_def (__libc_sigaction) +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer -#include <nptl/sigaction.c> +#include <sysdeps/unix/sysv/linux/sigaction.c> /* NOTE: Please think twice before making any changes to the bits of code below. GDB needs some intimate knowledge about it to @@ -108,10 +58,8 @@ asm \ " int $0x80" \ ); -#ifdef __NR_rt_sigaction /* The return code for realtime-signals. */ RESTORE (restore_rt, __NR_rt_sigreturn) -#endif /* For the boring old signals. */ #undef RESTORE2 diff --git a/sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h b/sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h new file mode 100644 index 0000000..05813db --- /dev/null +++ b/sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h @@ -0,0 +1,6 @@ +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction { + __sighandler_t k_sa_handler; + unsigned long sa_flags; + sigset_t sa_mask; /* mask last for extensibility */ +}; diff --git a/sysdeps/unix/sysv/linux/ia64/sigaction.c b/sysdeps/unix/sysv/linux/ia64/sigaction.c deleted file mode 100644 index e7fb8cd..0000000 --- a/sysdeps/unix/sysv/linux/ia64/sigaction.c +++ /dev/null @@ -1,45 +0,0 @@ -/* Copyright (C) 1997-2018 Free Software Foundation, Inc. - This file is part of the GNU C Library. - Linux/IA64 specific sigaction - Written by Jes Sorensen, <Jes.Sorensen@cern.ch>, April 1999. - - 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/>. */ - -/* Linux/ia64 only has rt signals, thus we do not even want to try falling - back to the old style signals as the default Linux handler does. */ - -#include <errno.h> -#include <signal.h> -#include <string.h> - -#include <sysdep.h> -#include <sys/syscall.h> - -/* The variable is shared between all wrappers around signal handling - functions which have RT equivalents. This is the definition. */ - - -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - return INLINE_SYSCALL (rt_sigaction, 4, sig, act, oact, _NSIG / 8); -} -libc_hidden_def (__libc_sigaction) - -#include <nptl/sigaction.c> diff --git a/sysdeps/unix/sysv/linux/kernel_sigaction.h b/sysdeps/unix/sysv/linux/kernel_sigaction.h index d005cbc..2dbec08 100644 --- a/sysdeps/unix/sysv/linux/kernel_sigaction.h +++ b/sysdeps/unix/sysv/linux/kernel_sigaction.h @@ -1,19 +1,20 @@ -/* This is the sigaction structure from the Linux 2.1.20 kernel. */ +#ifndef _KERNEL_SIGACTION_H +# define _KERNEL_SIGACTION_H -#define HAVE_SA_RESTORER - -struct old_kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned long sa_mask; - unsigned long sa_flags; - void (*sa_restorer) (void); +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction +{ + __sighandler_t k_sa_handler; + unsigned long sa_flags; +#ifdef SA_RESTORER + void (*sa_restorer) (void); +#endif + sigset_t sa_mask; }; -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ +#ifndef SA_RESTORER +# define SET_SA_RESTORER(kact, act) +# define RESET_SA_RESTORER(act, kact) +#endif -struct kernel_sigaction { - __sighandler_t k_sa_handler; - unsigned long sa_flags; - void (*sa_restorer) (void); - sigset_t sa_mask; -}; +#endif diff --git a/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h b/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h new file mode 100644 index 0000000..54972fe --- /dev/null +++ b/sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h @@ -0,0 +1,22 @@ +#ifndef _KERNEL_SIGACTION_H +# define _KERNEL_SIGACTION_H + +#include <signal.h> + +#define SA_RESTORER 0x04000000 + +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction +{ + __sighandler_t k_sa_handler; + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer) (void); +}; + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer + +#endif diff --git a/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h b/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h index b6f52cc..beef976 100644 --- a/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h +++ b/sysdeps/unix/sysv/linux/mips/kernel_sigaction.h @@ -1,40 +1,12 @@ -/* This is the sigaction structure from the Linux 2.1.24 kernel. */ - -#include <sgidefs.h> - -#define HAVE_SA_RESTORER - -struct old_kernel_sigaction { - unsigned int sa_flags; - __sighandler_t k_sa_handler; - unsigned long sa_mask; - unsigned int __pad0[3]; /* reserved, keep size constant */ - - /* Abi says here follows reserved int[2] */ - void (*sa_restorer)(void); -#if (_MIPS_SZPTR < 64) - /* - * For 32 bit code we have to pad struct sigaction to get - * constant size for the ABI - */ - int pad1[1]; /* reserved */ -#endif +#ifndef _KERNEL_SIGACTION_H +# define _KERNEL_SIGACTION_H + +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction +{ + unsigned int sa_flags; + __sighandler_t k_sa_handler; + sigset_t sa_mask; }; - -#define _KERNEL_NSIG 128 -#define _KERNEL_NSIG_BPW _MIPS_SZLONG -#define _KERNEL_NSIG_WORDS (_KERNEL_NSIG / _KERNEL_NSIG_BPW) - -typedef struct { - unsigned long sig[_KERNEL_NSIG_WORDS]; -} kernel_sigset_t; - -/* This is the sigaction structure from the Linux 2.1.68 kernel. */ -struct kernel_sigaction { - unsigned int sa_flags; - __sighandler_t k_sa_handler; - kernel_sigset_t sa_mask; - void (*sa_restorer)(void); - int s_resv[1]; /* reserved */ -}; +#endif diff --git a/sysdeps/unix/sysv/linux/mips/sigaction.c b/sysdeps/unix/sysv/linux/mips/sigaction.c deleted file mode 100644 index 008b688..0000000 --- a/sysdeps/unix/sysv/linux/mips/sigaction.c +++ /dev/null @@ -1,116 +0,0 @@ -/* Copyright (C) 1997-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 - <http://www.gnu.org/licenses/>. */ - -#include <errno.h> -#include <sgidefs.h> -#include <signal.h> -#include <string.h> - -#include <sysdep.h> -#include <sys/syscall.h> - -#include <sgidefs.h> - -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include <kernel_sigaction.h> - -#if _MIPS_SIM != _ABIO32 - -# ifdef __NR_rt_sigreturn -static void restore_rt (void) asm ("__restore_rt"); -# endif -# ifdef __NR_sigreturn -static void restore (void) asm ("__restore"); -# endif -#endif - -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - - struct kernel_sigaction kact, koact; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (kernel_sigset_t)); - kact.sa_flags = act->sa_flags; -#ifdef HAVE_SA_RESTORER -# if _MIPS_SIM == _ABIO32 - kact.sa_restorer = act->sa_restorer; -# else - kact.sa_restorer = &restore_rt; -# endif -#endif - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - result = INLINE_SYSCALL (rt_sigaction, 4, sig, - act ? &kact : NULL, - oact ? &koact : NULL, - sizeof (kernel_sigset_t)); - - if (oact && result >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, - sizeof (kernel_sigset_t)); - oact->sa_flags = koact.sa_flags; -#ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; -#endif - } - return result; -} -libc_hidden_def (__libc_sigaction) - -#include <nptl/sigaction.c> - - -/* NOTE: Please think twice before making any changes to the bits of - code below. GDB needs some intimate knowledge about it to - recognize them as signal trampolines, and make backtraces through - signal handlers work right. Important are both the names - (__restore_rt) and the exact instruction sequence. - If you ever feel the need to make any changes, please notify the - appropriate GDB maintainer. */ - -#define RESTORE(name, syscall) RESTORE2 (name, syscall) -#define RESTORE2(name, syscall) \ -asm \ - ( \ - ".align 4\n" \ - "__" #name ":\n" \ - " li $2, " #syscall "\n" \ - " syscall\n" \ - ); - -/* The return code for realtime-signals. */ -#if _MIPS_SIM != _ABIO32 -# ifdef __NR_rt_sigreturn -RESTORE (restore_rt, __NR_rt_sigreturn) -# endif -# ifdef __NR_sigreturn -RESTORE (restore, __NR_sigreturn) -# endif -#endif diff --git a/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h b/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h new file mode 100644 index 0000000..4ada322 --- /dev/null +++ b/sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h @@ -0,0 +1,8 @@ +/* NIOS2 uses the generic Linux UAPI but defines SA_RESTORER. */ +#define SA_RESTORER 0x04000000 +#include <sysdeps/unix/sysv/linux/kernel_sigaction.h> + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h b/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h new file mode 100644 index 0000000..c5213f2 --- /dev/null +++ b/sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h @@ -0,0 +1,8 @@ +/* powerpc kernel sigaction is similar to generic Linux UAPI one. */ +#define SA_RESTORER 0x04000000 +#include <sysdeps/unix/sysv/linux/kernel_sigaction.h> + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/s390/kernel_sigaction.h b/sysdeps/unix/sysv/linux/s390/kernel_sigaction.h new file mode 100644 index 0000000..a8beaf7 --- /dev/null +++ b/sysdeps/unix/sysv/linux/s390/kernel_sigaction.h @@ -0,0 +1,28 @@ +#include <bits/types/siginfo_t.h> + +#define SA_RESTORER 0x04000000 + +/* This is the sigaction structure from the Linux 3.2 kernel. */ +struct kernel_sigaction +{ + union + { + __sighandler_t _sa_handler; + void (*_sa_sigaction)(int, siginfo_t *, void *); + } _u; +#define k_sa_handler _u._sa_handler +#ifndef __s390x__ + sigset_t sa_mask; + unsigned long sa_flags; + void (*sa_restorer)(void); +#else + unsigned long sa_flags; + void (*sa_restorer)(void); + sigset_t sa_mask; +#endif +}; + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c b/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c deleted file mode 100644 index c13927c..0000000 --- a/sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c +++ /dev/null @@ -1,43 +0,0 @@ -/* Copyright (C) 2001-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 - <http://www.gnu.org/licenses/>. */ - -/* 64 bit Linux for S/390 only has rt signals, thus we do not even want to try - falling back to the old style signals as the default Linux handler does. */ - -#include <errno.h> -#include <signal.h> -#include <string.h> - -#include <sysdep.h> -#include <sys/syscall.h> - -/* The variable is shared between all wrappers around signal handling - functions which have RT equivalents. This is the definition. */ - - -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - return INLINE_SYSCALL (rt_sigaction, 4, sig, act, oact, _NSIG / 8); -} -libc_hidden_def (__libc_sigaction) - -#include <nptl/sigaction.c> diff --git a/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h b/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h new file mode 100644 index 0000000..7ebcd08 --- /dev/null +++ b/sysdeps/unix/sysv/linux/sh/kernel_sigaction.h @@ -0,0 +1,8 @@ +/* SH uses the generic Linux UAPI but defines SA_RESTORER. */ +#define SA_RESTORER 0x04000000 +#include <sysdeps/unix/sysv/linux/kernel_sigaction.h> + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/sigaction.c b/sysdeps/unix/sysv/linux/sigaction.c index 40a311a..0e6851a 100644 --- a/sysdeps/unix/sysv/linux/sigaction.c +++ b/sysdeps/unix/sysv/linux/sigaction.c @@ -22,11 +22,19 @@ #include <sysdep.h> #include <sys/syscall.h> -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ +/* New ports should not define the obsolete SA_RESTORER, however some + architecture requires for compat mode and/or due old ABI. */ #include <kernel_sigaction.h> +#ifndef SA_RESTORER +# define SET_SA_RESTORER(kact, act) +# define RESET_SA_RESTORER(act, kact) +#endif + +/* SPARC passes the restore function as an argument to rt_sigaction. */ +#ifndef STUB +# define STUB(act) +#endif /* If ACT is not NULL, change the action for SIG to *ACT. If OACT is not NULL, put the old action for SIG in *OACT. */ @@ -42,25 +50,21 @@ __libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) kact.k_sa_handler = act->sa_handler; memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); kact.sa_flags = act->sa_flags; -#ifdef HAVE_SA_RESTORER - kact.sa_restorer = act->sa_restorer; -#endif + SET_SA_RESTORER (&kact, act); } /* XXX The size argument hopefully will have to be changed to the real size of the user-level sigset_t. */ - result = INLINE_SYSCALL (rt_sigaction, 4, sig, - act ? &kact : NULL, - oact ? &koact : NULL, _NSIG / 8); + result = INLINE_SYSCALL_CALL (rt_sigaction, sig, + act ? &kact : NULL, + oact ? &koact : NULL, STUB(act) _NSIG / 8); if (oact && result >= 0) { oact->sa_handler = koact.k_sa_handler; memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); oact->sa_flags = koact.sa_flags; -#ifdef HAVE_SA_RESTORER - oact->sa_restorer = koact.sa_restorer; -#endif + RESET_SA_RESTORER (oact, &koact); } return result; } diff --git a/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h new file mode 100644 index 0000000..bee7e9c --- /dev/null +++ b/sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h @@ -0,0 +1,10 @@ +/* SPARC 'struct __new_sigaction' is similar to generic Linux UAPI with + a sa_restorer field, even though function is passed as an argument + to rt_sigaction syscall. */ +#define SA_RESTORER 0x04000000 +#include <sysdeps/unix/sysv/linux/kernel_sigaction.h> + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = NULL +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c index 204a5d8..c1d8f45 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c @@ -27,43 +27,12 @@ static void __rt_sigreturn_stub (void); static void __sigreturn_stub (void); -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - struct kernel_sigaction kact, koact; - unsigned long stub = 0; - int ret; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - if (((kact.sa_flags = act->sa_flags) & SA_SIGINFO) != 0) - stub = (unsigned long) &__rt_sigreturn_stub; - else - stub = (unsigned long) &__sigreturn_stub; - stub -= 8; - kact.sa_restorer = NULL; - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - ret = INLINE_SYSCALL (rt_sigaction, 5, sig, act ? &kact : 0, - oact ? &koact : 0, stub, _NSIG / 8); - - if (oact && ret >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; - oact->sa_restorer = koact.sa_restorer; - } - return ret; -} -libc_hidden_def (__libc_sigaction) - -#include <nptl/sigaction.c> +#define STUB(act) \ + ((unsigned long)((act->sa_flags & SA_SIGINFO) \ + ? &__rt_sigreturn_stub \ + : &__sigreturn_stub) - 8), +#include <sysdeps/unix/sysv/linux/sigaction.c> static inhibit_stack_protector diff --git a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c index 73cda4c..cfbbc6e 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c +++ b/sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c @@ -21,50 +21,13 @@ #include <string.h> #include <syscall.h> #include <sysdep.h> -#include <sys/signal.h> -#include <errno.h> - -#include <kernel_sigaction.h> - -/* SPARC 64bit userland requires a kernel that has rt signals anyway. */ static void __rt_sigreturn_stub (void); -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int ret; - struct kernel_sigaction kact, koact; - unsigned long stub = ((unsigned long) &__rt_sigreturn_stub) - 8; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - kact.sa_flags = act->sa_flags; - kact.sa_restorer = NULL; - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - ret = INLINE_SYSCALL (rt_sigaction, 5, sig, - act ? &kact : 0, - oact ? &koact : 0, stub, _NSIG / 8); - - if (oact && ret >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; - oact->sa_restorer = koact.sa_restorer; - } - - return ret; -} -libc_hidden_def (__libc_sigaction) - -#include <nptl/sigaction.c> +#define STUB(act) \ + (((unsigned long) &__rt_sigreturn_stub) - 8), +#include <sysdeps/unix/sysv/linux/sigaction.c> static inhibit_stack_protector diff --git a/sysdeps/unix/sysv/linux/tile/kernel_sigaction.h b/sysdeps/unix/sysv/linux/tile/kernel_sigaction.h new file mode 100644 index 0000000..a943d52 --- /dev/null +++ b/sysdeps/unix/sysv/linux/tile/kernel_sigaction.h @@ -0,0 +1,9 @@ +/* tile kernel sigaction is similar to generic Linux UAPI one + and SA_RESTORER is used only for binary compatibility. */ +#define SA_RESTORER 0x04000000 +#include <sysdeps/unix/sysv/linux/kernel_sigaction.h> + +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_restorer = (act)->sa_restorer +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer diff --git a/sysdeps/unix/sysv/linux/x86_64/sigaction.c b/sysdeps/unix/sysv/linux/x86_64/sigaction.c index 2f7459f..4e6d9cc 100644 --- a/sysdeps/unix/sysv/linux/x86_64/sigaction.c +++ b/sysdeps/unix/sysv/linux/x86_64/sigaction.c @@ -16,65 +16,20 @@ License along with the GNU C Library; if not, see <http://www.gnu.org/licenses/>. */ -#include <sysdep.h> -#include <errno.h> -#include <stddef.h> #include <signal.h> -#include <string.h> - -#include <sysdep.h> -#include <sys/syscall.h> - -/* The difference here is that the sigaction structure used in the - kernel is not the same as we use in the libc. Therefore we must - translate it here. */ -#include <kernel_sigaction.h> - -#include "ucontext_i.h" - -/* We do not globally define the SA_RESTORER flag so do it here. */ #define SA_RESTORER 0x04000000 +#include <kernel_sigaction.h> -/* Using the hidden attribute here does not change the code but it - helps to avoid warnings. */ extern void restore_rt (void) asm ("__restore_rt") attribute_hidden; +#define SET_SA_RESTORER(kact, act) \ + (kact)->sa_flags = (act)->sa_flags | SA_RESTORER; \ + (kact)->sa_restorer = &restore_rt -/* If ACT is not NULL, change the action for SIG to *ACT. - If OACT is not NULL, put the old action for SIG in *OACT. */ -int -__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact) -{ - int result; - struct kernel_sigaction kact, koact; - - if (act) - { - kact.k_sa_handler = act->sa_handler; - memcpy (&kact.sa_mask, &act->sa_mask, sizeof (sigset_t)); - kact.sa_flags = act->sa_flags | SA_RESTORER; - - kact.sa_restorer = &restore_rt; - } - - /* XXX The size argument hopefully will have to be changed to the - real size of the user-level sigset_t. */ - result = INLINE_SYSCALL (rt_sigaction, 4, - sig, act ? &kact : NULL, - oact ? &koact : NULL, _NSIG / 8); - if (oact && result >= 0) - { - oact->sa_handler = koact.k_sa_handler; - memcpy (&oact->sa_mask, &koact.sa_mask, sizeof (sigset_t)); - oact->sa_flags = koact.sa_flags; - oact->sa_restorer = koact.sa_restorer; - } - return result; -} -libc_hidden_def (__libc_sigaction) - -#include <nptl/sigaction.c> +#define RESET_SA_RESTORER(act, kact) \ + (act)->sa_restorer = (kact)->sa_restorer +#include <sysdeps/unix/sysv/linux/sigaction.c> /* NOTE: Please think twice before making any changes to the bits of code below. GDB needs some intimate knowledge about it to @@ -93,6 +48,8 @@ libc_hidden_def (__libc_sigaction) a bit tricky. We don't use the gas cfi directives, so that we can reliably add .cfi_signal_frame. */ +#include "ucontext_i.h" + #define do_cfa_expr \ " .byte 0x0f\n" /* DW_CFA_def_cfa_expression */ \ " .uleb128 2f-1f\n" /* length */ \
This patch consolidates all Linux sigaction implementation on a default one at sysdeps/unix/sysv/linux/sigaction.c. The idea is remove redundant code and simplify new ports addition by following the current generic Linux User API (UAPI). The UAPI for new ports defines a generic extensible sigaction struct as: struct sigaction { __sighandler_t sa_handler; unsigned long sa_flags; #ifdef SA_RESTORER void (*sa_restorer) (void); #endif sigset_t sa_mask; }; Where SA_RESTORER is just placed to compatibility reasons, news ports should not add it. A similar definition is used on generic kernel_sigaction.h. The user exported sigaction definition is not changed, so for most architectures it requires an adjustment to kernel expected one for the syscall. The main changes are: - All architectures now define and use a kernel_sigaction struct meant for the syscall, even for the architectures where the user sigaction has the same layout of the kernel expected one (s390-64 and ia64). Although it requires more work for these architectures, it simplifies the generic implementation. Also, sigaction is hardly a hotspot where micro optimization would play an important role. - The generic kernel_sigaction definition is now aligned with expected UAPI one for newer ports, where SA_RESTORER and sa_restorer is not expected to be defined. This means adding kernel_sigaction for current architectures that does define it (m68k, nios2, powerpc, s390, sh, sparc, and tile) and which rely on previous generic definition. - Remove old MIPS usage of sa_restorer. This was removed since 2.6.27 (2957c9e61ee9c - "[MIPS] IRIX: Goodbye and thanks for all the fish"). So for new ports the generic implementation should work if its uses Linux UAPI. If SA_RESTORER is still required (due some architecture limitation), it should define its own kernel_sigaction.h, define it and include generic header (assuming it still uses the default generic kernel layout). Checked on x86_64-linux-gnu, i686-linux-gnu, arm-linux-gnueabihf, aarch64-linux-gnu, sparc64-linux-gnu, sparcv9-linux-gnu, powerpc-linux-gnu, and powerpc64-linux-gnu. I also check the build on all remaining affected ABIs. * sysdeps/unix/sysv/linux/aarch64/sigaction.c: Use default Linux version as base implementation. * sysdeps/unix/sysv/linux/arm/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/i386/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/x86_64/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h: Add include guards, remove unrequired definitions and update comments. * sysdeps/unix/sysv/linux/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/mips/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h: New file. * sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/powerpc/kernel_sigaction: Likewise. * sysdeps/unix/sysv/linux/s390/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/sh/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/tile/kernel_sigaction.h: Likewise. * sysdeps/unix/sysv/linux/ia64/sigaction.c: Remove file. * sysdeps/unix/sysv/linux/mips/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c: Likewise. * sysdeps/unix/sysv/linux/sigaction.c: Add STUB, SET_SA_RESTORER, and RESET_SA_RESTORER hooks. Signed-off-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> --- ChangeLog | 25 +++++ sysdeps/unix/sysv/linux/aarch64/sigaction.c | 58 ++--------- sysdeps/unix/sysv/linux/alpha/kernel_sigaction.h | 21 ++-- sysdeps/unix/sysv/linux/arm/sigaction.c | 79 +++----------- sysdeps/unix/sysv/linux/i386/sigaction.c | 76 +++----------- sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h | 6 ++ sysdeps/unix/sysv/linux/ia64/sigaction.c | 45 -------- sysdeps/unix/sysv/linux/kernel_sigaction.h | 31 +++--- sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h | 22 ++++ sysdeps/unix/sysv/linux/mips/kernel_sigaction.h | 48 ++------- sysdeps/unix/sysv/linux/mips/sigaction.c | 116 --------------------- sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h | 8 ++ sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h | 8 ++ sysdeps/unix/sysv/linux/s390/kernel_sigaction.h | 28 +++++ sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c | 43 -------- sysdeps/unix/sysv/linux/sh/kernel_sigaction.h | 8 ++ sysdeps/unix/sysv/linux/sigaction.c | 28 ++--- sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h | 10 ++ sysdeps/unix/sysv/linux/sparc/sparc32/sigaction.c | 41 +------- sysdeps/unix/sysv/linux/sparc/sparc64/sigaction.c | 43 +------- sysdeps/unix/sysv/linux/tile/kernel_sigaction.h | 9 ++ sysdeps/unix/sysv/linux/x86_64/sigaction.c | 61 ++--------- 22 files changed, 230 insertions(+), 584 deletions(-) create mode 100644 sysdeps/unix/sysv/linux/ia64/kernel_sigaction.h delete mode 100644 sysdeps/unix/sysv/linux/ia64/sigaction.c create mode 100644 sysdeps/unix/sysv/linux/m68k/kernel_sigaction.h delete mode 100644 sysdeps/unix/sysv/linux/mips/sigaction.c create mode 100644 sysdeps/unix/sysv/linux/nios2/kernel_sigaction.h create mode 100644 sysdeps/unix/sysv/linux/powerpc/kernel_sigaction.h create mode 100644 sysdeps/unix/sysv/linux/s390/kernel_sigaction.h delete mode 100644 sysdeps/unix/sysv/linux/s390/s390-64/sigaction.c create mode 100644 sysdeps/unix/sysv/linux/sh/kernel_sigaction.h create mode 100644 sysdeps/unix/sysv/linux/sparc/kernel_sigaction.h create mode 100644 sysdeps/unix/sysv/linux/tile/kernel_sigaction.h -- 2.7.4