klibc-bot for Jessica Clarke
2020-Aug-28 19:36 UTC
[klibc] [klibc:ia64-signal-fix] ia64: Fix sigaction struct layout and function implementation
Commit-ID: 454901a0c733986bee36da111a08fe7df0ff0b98 Gitweb: http://git.kernel.org/?p=libs/klibc/klibc.git;a=commit;h=454901a0c733986bee36da111a08fe7df0ff0b98 Author: Jessica Clarke <jrtc27 at jrtc27.com> AuthorDate: Fri, 28 Aug 2020 19:48:32 +0100 Committer: Ben Hutchings <ben at decadent.org.uk> CommitDate: Fri, 28 Aug 2020 20:22:50 +0100 [klibc] ia64: Fix sigaction struct layout and function implementation Commit 8418552 ("[klibc] ia64: Fix shared build") switched to the function descriptor-less ABI. However, when passing a function pointer to the kernel for signal handling, it always expects a descriptor, and -mno-pic does not set any ELF flags that the kernel could detect. Thus to fix this regression we must construct descriptors solely for passing to/from the kernel. [bwh: Moved the fix-up into an arch-specific source file and defined _KLIBC_NEEDS_SIGACTION_FIXUP] --- usr/include/arch/ia64/klibc/archconfig.h | 3 ++ usr/klibc/SYSCALLS.def | 3 +- usr/klibc/arch/ia64/Kbuild | 2 +- usr/klibc/arch/ia64/sigaction.c | 50 ++++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 2 deletions(-) diff --git a/usr/include/arch/ia64/klibc/archconfig.h b/usr/include/arch/ia64/klibc/archconfig.h index adbd1ee4..9bf3c071 100644 --- a/usr/include/arch/ia64/klibc/archconfig.h +++ b/usr/include/arch/ia64/klibc/archconfig.h @@ -13,5 +13,8 @@ #define _KLIBC_NO_MMU 0 /* IA64 doesn't have sys_vfork, it has architecture-specific code */ #define _KLIBC_REAL_VFORK 1 +/* Need to fix-up function pointers to function descriptor pointers + * in struct sigaction */ +#define _KLIBC_NEEDS_SIGACTION_FIXUP 1 #endif /* _KLIBC_ARCHCONFIG_H */ diff --git a/usr/klibc/SYSCALLS.def b/usr/klibc/SYSCALLS.def index 16ad3830..c8ac9e0d 100644 --- a/usr/klibc/SYSCALLS.def +++ b/usr/klibc/SYSCALLS.def @@ -206,9 +206,10 @@ ssize_t sendfile64,sendfile::sendfile(int, int, off_t *, size_t, off_t); * sanitizing <signal.h> for all architectures, sigh. See <klibc/config.h>. */ #if _KLIBC_USE_RT_SIG -<!sparc,sparc64,alpha> int rt_sigaction::__rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t); +<!sparc,sparc64,alpha,ia64> int rt_sigaction::__rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t); <sparc,sparc64> int rt_sigaction::____rt_sigaction(int, const struct sigaction *, struct sigaction *, void *, size_t); <alpha> int rt_sigaction::____rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t, void *); +<ia64> int rt_sigaction::____rt_sigaction(int, const struct sigaction *, struct sigaction *, size_t); int rt_sigsuspend::__rt_sigsuspend(const sigset_t *, size_t); int rt_sigpending::__rt_sigpending(sigset_t *, size_t); int rt_sigprocmask::__rt_sigprocmask(int, const sigset_t *, sigset_t *, size_t); diff --git a/usr/klibc/arch/ia64/Kbuild b/usr/klibc/arch/ia64/Kbuild index 49070ff3..41b8ca06 100644 --- a/usr/klibc/arch/ia64/Kbuild +++ b/usr/klibc/arch/ia64/Kbuild @@ -2,7 +2,7 @@ # klibc files for ia64 # -klib-y := vfork.o setjmp.o pipe.o syscall.o +klib-y := vfork.o setjmp.o sigaction.o pipe.o syscall.o klib-y += ../../libgcc/__divdi3.o ../../libgcc/__divsi3.o klib-y += ../../libgcc/__udivdi3.o ../../libgcc/__udivsi3.o diff --git a/usr/klibc/arch/ia64/sigaction.c b/usr/klibc/arch/ia64/sigaction.c new file mode 100644 index 00000000..e512bdcd --- /dev/null +++ b/usr/klibc/arch/ia64/sigaction.c @@ -0,0 +1,50 @@ +/* + * sigaction.c + */ + +#include <signal.h> +#include <sys/syscall.h> + +/* We use -mno-pic so our function pointers are straight to the function entry + point, but the kernel always expects a descriptor. Thus we create a fake + descriptor for each possible signal, update it, and pass that to the kernel + instead (the descriptor must remain valid after returning from sigaction + until it is replaced). */ +static struct { + uintptr_t entry; + uintptr_t gp; +} signal_descriptors[_NSIG]; + +__extern int ____rt_sigaction(int, const struct sigaction *, struct sigaction *, + size_t); + +int __rt_sigaction(int sig, const struct sigaction *act, + struct sigaction *oact, size_t size) +{ + uintptr_t old_entry; + int rv; + + if (sig < 0 || sig >= _NSIG) { + errno = EINVAL; + return -1; + } + + if (oact) { + old_entry = signal_descriptors[sig].entry; + } + + if (act && act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL) { + signal_descriptors[sig].entry = (uintptr_t)act->sa_handler; + act->sa_handler + (__sighandler_t)(uintptr_t)&signal_descriptors[sig]; + } + + rv = ____rt_sigaction(sig, act, oact, size); + + if (oact && oact->sa_handler != SIG_IGN && + oact->sa_handler != SIG_DFL) { + oact->sa_handler = (__sighandler_t)old_entry; + } + + return rv; +}
Reasonably Related Threads
- [klibc:master] ia64: Fix sigaction function implementation
- [klibc:ia64-signal-fix] ia64: sigaction: Make signal updates atomic
- [klibc:master] ia64: sigaction: Make signal updates atomic
- [PATCH 2/2] ia64: Fix sigaction struct layout and function implementation
- [klibc:master] alpha: Pass restorer to rt_sigaction() and disable executable stack