linux-user: Add infrastructure for a signal trampoline page

Allocate a page to hold the signal trampoline(s).
Invoke a guest-specific hook to fill in the contents
of the page before marking it read-execute again.

Reviewed-by: Max Filippov <jcmvbkbc@gmail.com>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Richard Henderson <richard.henderson@linaro.org>
Message-Id: <20210929130553.121567-2-richard.henderson@linaro.org>
Signed-off-by: Laurent Vivier <laurent@vivier.eu>
This commit is contained in:
Richard Henderson 2021-09-29 09:05:28 -04:00 committed by Laurent Vivier
parent bb4aa8f59e
commit db2af69d6b
3 changed files with 27 additions and 0 deletions

View File

@ -7,6 +7,7 @@
#include "qemu.h" #include "qemu.h"
#include "user-internals.h" #include "user-internals.h"
#include "signal-common.h"
#include "loader.h" #include "loader.h"
#include "user-mmap.h" #include "user-mmap.h"
#include "disas/disas.h" #include "disas/disas.h"
@ -17,6 +18,7 @@
#include "qemu/units.h" #include "qemu/units.h"
#include "qemu/selfmap.h" #include "qemu/selfmap.h"
#include "qapi/error.h" #include "qapi/error.h"
#include "target_signal.h"
#ifdef _ARCH_PPC64 #ifdef _ARCH_PPC64
#undef ARCH_DLINFO #undef ARCH_DLINFO
@ -28,6 +30,10 @@
#undef ELF_ARCH #undef ELF_ARCH
#endif #endif
#ifndef TARGET_ARCH_HAS_SIGTRAMP_PAGE
#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
#endif
#define ELF_OSABI ELFOSABI_SYSV #define ELF_OSABI ELFOSABI_SYSV
/* from personality.h */ /* from personality.h */
@ -3249,6 +3255,18 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
#endif #endif
} }
/*
* TODO: load a vdso, which would also contain the signal trampolines.
* Otherwise, allocate a private page to hold them.
*/
if (TARGET_ARCH_HAS_SIGTRAMP_PAGE) {
abi_ulong tramp_page = target_mmap(0, TARGET_PAGE_SIZE,
PROT_READ | PROT_WRITE,
MAP_PRIVATE | MAP_ANON, -1, 0);
setup_sigtramp(tramp_page);
target_mprotect(tramp_page, TARGET_PAGE_SIZE, PROT_READ | PROT_EXEC);
}
bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &elf_ex, bprm->p = create_elf_tables(bprm->p, bprm->argc, bprm->envc, &elf_ex,
info, (elf_interpreter ? &interp_info : NULL)); info, (elf_interpreter ? &interp_info : NULL));
info->start_stack = bprm->p; info->start_stack = bprm->p;

View File

@ -20,6 +20,12 @@
#ifndef SIGNAL_COMMON_H #ifndef SIGNAL_COMMON_H
#define SIGNAL_COMMON_H #define SIGNAL_COMMON_H
/* Fallback addresses into sigtramp page. */
extern abi_ulong default_sigreturn;
extern abi_ulong default_rt_sigreturn;
void setup_sigtramp(abi_ulong tramp_page);
int on_sig_stack(unsigned long sp); int on_sig_stack(unsigned long sp);
int sas_ss_flags(unsigned long sp); int sas_ss_flags(unsigned long sp);
abi_ulong target_sigsp(abi_ulong sp, struct target_sigaction *ka); abi_ulong target_sigsp(abi_ulong sp, struct target_sigaction *ka);

View File

@ -35,6 +35,9 @@ static struct target_sigaction sigact_table[TARGET_NSIG];
static void host_signal_handler(int host_signum, siginfo_t *info, static void host_signal_handler(int host_signum, siginfo_t *info,
void *puc); void *puc);
/* Fallback addresses into sigtramp page. */
abi_ulong default_sigreturn;
abi_ulong default_rt_sigreturn;
/* /*
* System includes define _NSIG as SIGRTMAX + 1, * System includes define _NSIG as SIGRTMAX + 1,