aboutsummaryrefslogtreecommitdiff
path: root/linux-user/arm/signal.c
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2023-10-31 07:12:40 +0900
committerStefan Hajnoczi <stefanha@redhat.com>2023-10-31 07:12:40 +0900
commit516fffc9933cb21fad41ca8f7bf465d238d4d375 (patch)
tree7f5e6762561bcc7bddada935879ef973246a375d /linux-user/arm/signal.c
parent235fe6d06e62d21439451ff7612458770a3df68f (diff)
parent335b8f700c42a011cf2855c47bf098be3d35bde4 (diff)
Merge tag 'pull-lu-20231030' of https://gitlab.com/rth7680/qemu into staging
linux-user: Fix guest signal remapping after adjusting SIGABRT linux-user: Implement VDSOs * tag 'pull-lu-20231030' of https://gitlab.com/rth7680/qemu: (21 commits) build: Add update-linux-vdso makefile rule linux-user: Show vdso address in /proc/pid/maps linux-user/s390x: Add vdso linux-user/s390x: Rename __SIGNAL_FRAMESIZE to STACK_FRAME_OVERHEAD linux-user/ppc: Add vdso linux-user/loongarch64: Add vdso linux-user/riscv: Add vdso linux-user/hppa: Add vdso linux-user/arm: Add vdso linux-user/aarch64: Add vdso linux-user/x86_64: Add vdso linux-user/i386: Add vdso linux-user: Add gen-vdso tool linux-user: Load vdso image if available linux-user: Replace bprm->fd with bprm->src.fd linux-user: Use ImageSource in load_symbols linux-user: Use ImageSource in load_elf_image linux-user: Do not clobber bprm_buf swapping ehdr linux-user: Tidy loader_exec linux-user: Introduce imgsrc_read, imgsrc_read_alloc ... Conflicts: linux-user/arm/signal.c Fix an #include context conflict. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
Diffstat (limited to 'linux-user/arm/signal.c')
-rw-r--r--linux-user/arm/signal.c49
1 files changed, 32 insertions, 17 deletions
diff --git a/linux-user/arm/signal.c b/linux-user/arm/signal.c
index 4020601c54..f77f692c63 100644
--- a/linux-user/arm/signal.c
+++ b/linux-user/arm/signal.c
@@ -22,6 +22,7 @@
#include "signal-common.h"
#include "linux-user/trace.h"
#include "target/arm/cpu-features.h"
+#include "vdso-asmoffset.h"
struct target_sigcontext {
abi_ulong trap_no;
@@ -103,6 +104,11 @@ struct rt_sigframe
struct sigframe sig;
};
+QEMU_BUILD_BUG_ON(offsetof(struct sigframe, retcode[3])
+ != SIGFRAME_RC3_OFFSET);
+QEMU_BUILD_BUG_ON(offsetof(struct rt_sigframe, sig.retcode[3])
+ != RT_SIGFRAME_RC3_OFFSET);
+
static abi_ptr sigreturn_fdpic_tramp;
/*
@@ -161,6 +167,9 @@ get_sigframe(struct target_sigaction *ka, CPUARMState *regs, int framesize)
return (sp - framesize) & ~7;
}
+static void write_arm_sigreturn(uint32_t *rc, int syscall);
+static void write_arm_fdpic_sigreturn(uint32_t *rc, int ofs);
+
static int
setup_return(CPUARMState *env, struct target_sigaction *ka, int usig,
struct sigframe *frame, abi_ulong sp_addr)
@@ -168,9 +177,9 @@ setup_return(CPUARMState *env, struct target_sigaction *ka, int usig,
abi_ulong handler = 0;
abi_ulong handler_fdpic_GOT = 0;
abi_ulong retcode;
- int thumb, retcode_idx;
- int is_fdpic = info_is_fdpic(((TaskState *)thread_cpu->opaque)->info);
- bool copy_retcode;
+ bool is_fdpic = info_is_fdpic(((TaskState *)thread_cpu->opaque)->info);
+ bool is_rt = ka->sa_flags & TARGET_SA_SIGINFO;
+ bool thumb;
if (is_fdpic) {
/* In FDPIC mode, ka->_sa_handler points to a function
@@ -185,9 +194,7 @@ setup_return(CPUARMState *env, struct target_sigaction *ka, int usig,
} else {
handler = ka->_sa_handler;
}
-
thumb = handler & 1;
- retcode_idx = thumb + (ka->sa_flags & TARGET_SA_SIGINFO ? 2 : 0);
uint32_t cpsr = cpsr_read(env);
@@ -203,24 +210,32 @@ setup_return(CPUARMState *env, struct target_sigaction *ka, int usig,
cpsr &= ~CPSR_E;
}
+ /* Our vdso default_sigreturn label is a table of entry points. */
+ retcode = default_sigreturn + (is_fdpic * 2 + is_rt) * 8;
+
+ /*
+ * Put the sigreturn code on the stack no matter which return
+ * mechanism we use in order to remain ABI compliant.
+ * Because this is about ABI, always use the A32 instructions,
+ * despite the fact that our actual vdso trampoline is T16.
+ */
+ if (is_fdpic) {
+ write_arm_fdpic_sigreturn(frame->retcode,
+ is_rt ? RT_SIGFRAME_RC3_OFFSET
+ : SIGFRAME_RC3_OFFSET);
+ } else {
+ write_arm_sigreturn(frame->retcode,
+ is_rt ? TARGET_NR_rt_sigreturn
+ : TARGET_NR_sigreturn);
+ }
+
if (ka->sa_flags & TARGET_SA_RESTORER) {
if (is_fdpic) {
+ /* Place the function descriptor in slot 3. */
__put_user((abi_ulong)ka->sa_restorer, &frame->retcode[3]);
- retcode = (sigreturn_fdpic_tramp +
- retcode_idx * RETCODE_BYTES + thumb);
- copy_retcode = true;
} else {
retcode = ka->sa_restorer;
- copy_retcode = false;
}
- } else {
- retcode = default_sigreturn + retcode_idx * RETCODE_BYTES + thumb;
- copy_retcode = true;
- }
-
- /* Copy the code to the stack slot for ABI compatibility. */
- if (copy_retcode) {
- memcpy(frame->retcode, g2h_untagged(retcode & ~1), RETCODE_BYTES);
}
env->regs[0] = usig;