aboutsummaryrefslogtreecommitdiff
path: root/linux-user/elfload.c
diff options
context:
space:
mode:
authorRichard Henderson <richard.henderson@linaro.org>2021-09-29 09:05:28 -0400
committerLaurent Vivier <laurent@vivier.eu>2021-10-01 12:03:47 +0200
commitdb2af69d6ba836a264878dbf2cf676d3c1fc46b4 (patch)
tree0d3b0e93b1f68702bfebd68c8cc5cf7cb79ea744 /linux-user/elfload.c
parentbb4aa8f59e18412cff0d69f14aee7abba153161a (diff)
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>
Diffstat (limited to 'linux-user/elfload.c')
-rw-r--r--linux-user/elfload.c18
1 files changed, 18 insertions, 0 deletions
diff --git a/linux-user/elfload.c b/linux-user/elfload.c
index 5f9e2141ad..459a26ef1d 100644
--- a/linux-user/elfload.c
+++ b/linux-user/elfload.c
@@ -7,6 +7,7 @@
#include "qemu.h"
#include "user-internals.h"
+#include "signal-common.h"
#include "loader.h"
#include "user-mmap.h"
#include "disas/disas.h"
@@ -17,6 +18,7 @@
#include "qemu/units.h"
#include "qemu/selfmap.h"
#include "qapi/error.h"
+#include "target_signal.h"
#ifdef _ARCH_PPC64
#undef ARCH_DLINFO
@@ -28,6 +30,10 @@
#undef ELF_ARCH
#endif
+#ifndef TARGET_ARCH_HAS_SIGTRAMP_PAGE
+#define TARGET_ARCH_HAS_SIGTRAMP_PAGE 0
+#endif
+
#define ELF_OSABI ELFOSABI_SYSV
/* from personality.h */
@@ -3249,6 +3255,18 @@ int load_elf_binary(struct linux_binprm *bprm, struct image_info *info)
#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,
info, (elf_interpreter ? &interp_info : NULL));
info->start_stack = bprm->p;