linux: Consolidate sigaction implementation

This patch consolidates all Linux sigaction implementations on the default
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 for 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 are 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").

  - The remaining arch-specific sigaction.c are to handle ABI idiosyncrasies
    (like SPARC kernel ABI for rt_sigaction that requires an additional
    stub argument).

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,
powerpc64-linux-gnu, ia64-linux-gnu and alpha-linux-gnu.  I also checked 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.
This commit is contained in:
Adhemerval Zanella 2017-11-02 11:04:18 -02:00
parent db9e55ff36
commit b4a5d26d88
22 changed files with 234 additions and 582 deletions

View File

@ -1,3 +1,30 @@
2018-04-05 Adhemerval Zanella <adhemerval.zanella@linaro.org>
* 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.
2018-04-05 Stefan Liebler <stli@linux.vnet.ibm.com>
* sysdeps/s390/fpu/libm-test-ulps: Regenerated.

View File

@ -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>
#define SET_SA_RESTORER(kact, act) \
({ \
if ((kact)->sa_flags & SA_RESTORER) \
(kact)->sa_restorer = (act)->sa_restorer; \
})
int
__libc_sigaction (int sig, const struct sigaction *act, struct sigaction *oact)
{
int result;
struct kernel_sigaction kact;
struct kernel_sigaction koact;
#define RESET_SA_RESTORER(act, kact) \
(act)->sa_restorer = (kact)->sa_restorer;
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
}
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)
#include <nptl/sigaction.c>
#include <sysdeps/unix/sysv/linux/sigaction.c>

View File

@ -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

View File

@ -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
#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; \
} \
})
/* 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;
#define RESET_SA_RESTORER(act, kact) \
(act)->sa_restorer = (kact)->sa_restorer;
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>
#include <sysdeps/unix/sysv/linux/sigaction.c>

View File

@ -16,79 +16,30 @@
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;
/* 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;
#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); \
} \
else \
(kact)->sa_restorer = NULL; \
})
struct kernel_sigaction kact, koact;
#define RESET_SA_RESTORER(act, kact) \
(act)->sa_restorer = (kact)->sa_restorer
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);
}
else
kact.sa_restorer = NULL;
}
/* 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)
#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
@ -109,10 +60,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

View File

@ -0,0 +1,7 @@
/* 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 */
};

View File

@ -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>

View File

@ -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

View File

@ -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

View File

@ -1,40 +1,12 @@
/* This is the sigaction structure from the Linux 2.1.24 kernel. */
#ifndef _KERNEL_SIGACTION_H
# define _KERNEL_SIGACTION_H
#include <sgidefs.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 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
};
#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 */
};

View File

@ -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

View File

@ -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

View File

@ -0,0 +1,9 @@
/* powerpc kernel sigaction is similar to generic Linux UAPI one,
but the architecture also 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

View File

@ -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

View File

@ -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>

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -27,43 +27,13 @@
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) \
(act) ? ((unsigned long)((act->sa_flags & SA_SIGINFO) \
? &__rt_sigreturn_stub \
: &__sigreturn_stub) - 8) \
: 0,
#include <sysdeps/unix/sysv/linux/sigaction.c>
static
inhibit_stack_protector

View File

@ -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

View File

@ -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

View File

@ -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. */
#define SA_RESTORER 0x04000000
#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
/* 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 */ \