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:
parent
bb4aa8f59e
commit
db2af69d6b
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user