[v4,3/4] linux: Consolidate sigaction implementation

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
Related show

Commit Message

Adhemerval Zanella Feb. 12, 2018, 12:42 p.m.
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

Comments

Adhemerval Zanella Feb. 19, 2018, 5:50 p.m. | #1
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 */			\

>
Adhemerval Zanella April 5, 2018, 6:22 p.m. | #2
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 */			\

>>

Patch

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 */			\