[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL 31/40] bsd-user/signal.c: setup_frame
From: |
Warner Losh |
Subject: |
[PULL 31/40] bsd-user/signal.c: setup_frame |
Date: |
Mon, 31 Jan 2022 12:56:27 -0700 |
setup_frame sets up a signalled stack frame. Associated routines to
extract the pointer to the stack frame and to support alternate stacks.
Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@freebsd.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
---
bsd-user/main.c | 5 +++
bsd-user/qemu.h | 3 +-
bsd-user/signal.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 90 insertions(+), 1 deletion(-)
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 29cf4e15693..f1d58e905e7 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -217,6 +217,11 @@ void qemu_cpu_kick(CPUState *cpu)
/* Assumes contents are already zeroed. */
static void init_task_state(TaskState *ts)
{
+ ts->sigaltstack_used = (struct target_sigaltstack) {
+ .ss_sp = 0,
+ .ss_size = 0,
+ .ss_flags = TARGET_SS_DISABLE,
+ };
}
void gemu_log(const char *fmt, ...)
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 1648a509b9c..de20650a00d 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -107,7 +107,8 @@ typedef struct TaskState {
*/
sigset_t signal_mask;
- uint8_t stack[];
+ /* This thread's sigaltstack, if it has one */
+ struct target_sigaltstack sigaltstack_used;
} __attribute__((aligned(16))) TaskState;
void stop_all_tasks(void);
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 84dafa4e9fe..dbc13736073 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -35,6 +35,16 @@ static void host_signal_handler(int host_sig, siginfo_t
*info, void *puc);
static void target_to_host_sigset_internal(sigset_t *d,
const target_sigset_t *s);
+static inline int on_sig_stack(TaskState *ts, unsigned long sp)
+{
+ return sp - ts->sigaltstack_used.ss_sp < ts->sigaltstack_used.ss_size;
+}
+
+static inline int sas_ss_flags(TaskState *ts, unsigned long sp)
+{
+ return ts->sigaltstack_used.ss_size == 0 ? SS_DISABLE :
+ on_sig_stack(ts, sp) ? SS_ONSTACK : 0;
+}
/*
* The BSD ABIs use the same singal numbers across all the CPU architectures,
so
@@ -491,6 +501,79 @@ static void host_signal_handler(int host_sig, siginfo_t
*info, void *puc)
cpu_exit(thread_cpu);
}
+static inline abi_ulong get_sigframe(struct target_sigaction *ka,
+ CPUArchState *env, size_t frame_size)
+{
+ TaskState *ts = (TaskState *)thread_cpu->opaque;
+ abi_ulong sp;
+
+ /* Use default user stack */
+ sp = get_sp_from_cpustate(env);
+
+ if ((ka->sa_flags & TARGET_SA_ONSTACK) && sas_ss_flags(ts, sp) == 0) {
+ sp = ts->sigaltstack_used.ss_sp + ts->sigaltstack_used.ss_size;
+ }
+
+/* TODO: make this a target_arch function / define */
+#if defined(TARGET_ARM)
+ return (sp - frame_size) & ~7;
+#elif defined(TARGET_AARCH64)
+ return (sp - frame_size) & ~15;
+#else
+ return sp - frame_size;
+#endif
+}
+
+/* compare to $M/$M/exec_machdep.c sendsig and sys/kern/kern_sig.c sigexit */
+
+static void setup_frame(int sig, int code, struct target_sigaction *ka,
+ target_sigset_t *set, target_siginfo_t *tinfo, CPUArchState *env)
+{
+ struct target_sigframe *frame;
+ abi_ulong frame_addr;
+ int i;
+
+ frame_addr = get_sigframe(ka, env, sizeof(*frame));
+ trace_user_setup_frame(env, frame_addr);
+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) {
+ unlock_user_struct(frame, frame_addr, 1);
+ dump_core_and_abort(TARGET_SIGILL);
+ return;
+ }
+
+ memset(frame, 0, sizeof(*frame));
+ setup_sigframe_arch(env, frame_addr, frame, 0);
+
+ for (i = 0; i < TARGET_NSIG_WORDS; i++) {
+ __put_user(set->__bits[i], &frame->sf_uc.uc_sigmask.__bits[i]);
+ }
+
+ if (tinfo) {
+ frame->sf_si.si_signo = tinfo->si_signo;
+ frame->sf_si.si_errno = tinfo->si_errno;
+ frame->sf_si.si_code = tinfo->si_code;
+ frame->sf_si.si_pid = tinfo->si_pid;
+ frame->sf_si.si_uid = tinfo->si_uid;
+ frame->sf_si.si_status = tinfo->si_status;
+ frame->sf_si.si_addr = tinfo->si_addr;
+ /* see host_to_target_siginfo_noswap() for more details */
+ frame->sf_si.si_value.sival_ptr = tinfo->si_value.sival_ptr;
+ /*
+ * At this point, whatever is in the _reason union is complete
+ * and in target order, so just copy the whole thing over, even
+ * if it's too large for this specific signal.
+ * host_to_target_siginfo_noswap() and tswap_siginfo() have ensured
+ * that's so.
+ */
+ memcpy(&frame->sf_si._reason, &tinfo->_reason,
+ sizeof(tinfo->_reason));
+ }
+
+ set_sigtramp_args(env, sig, frame, frame_addr, ka);
+
+ unlock_user_struct(frame, frame_addr, 1);
+}
+
void signal_init(void)
{
TaskState *ts = (TaskState *)thread_cpu->opaque;
--
2.33.1
- [PULL 19/40] bsd-user/host/arm/host-signal.h: Implement host_signal_*, (continued)
- [PULL 19/40] bsd-user/host/arm/host-signal.h: Implement host_signal_*, Warner Losh, 2022/01/31
- [PULL 11/40] bsd-user/signal.c: implement cpu_loop_exit_sigbus, Warner Losh, 2022/01/31
- [PULL 05/40] bsd-user: Remove vestiges of signal queueing code, Warner Losh, 2022/01/31
- [PULL 12/40] bsd-user/arm/arget_arch_cpu.h: Move EXCP_DEBUG and EXCP_BKPT together, Warner Losh, 2022/01/31
- [PULL 14/40] bsd-user/arm/target_arch_cpu.h: Use force_sig_fault for EXCP_UDEF, Warner Losh, 2022/01/31
- [PULL 21/40] bsd-user/host/x86_64/host-signal.h: Implement host_signal_*, Warner Losh, 2022/01/31
- [PULL 30/40] bsd-user/signal.c: sigset manipulation routines., Warner Losh, 2022/01/31
- [PULL 39/40] bsd-user: Rename arg name for target_cpu_reset to env, Warner Losh, 2022/01/31
- [PULL 26/40] bsd-user/signal.c: Implement host_signal_handler, Warner Losh, 2022/01/31
- [PULL 23/40] bsd-user: Add trace events for bsd-user, Warner Losh, 2022/01/31
- [PULL 31/40] bsd-user/signal.c: setup_frame,
Warner Losh <=
- [PULL 17/40] bsd-user/signal.c: Implement signal_init(), Warner Losh, 2022/01/31
- [PULL 20/40] bsd-user/host/i386/host-signal.h: Implement host_signal_*, Warner Losh, 2022/01/31
- [PULL 02/40] bsd-user: Create setup_sigframe_arch to setup sigframe context, Warner Losh, 2022/01/31
- [PULL 15/40] bsd-user/arm/target_arch_cpu.h: Implement data faults, Warner Losh, 2022/01/31
- [PULL 27/40] bsd-user/strace.c: print_taken_signal, Warner Losh, 2022/01/31
- [PULL 28/40] bsd-user/signal.c: Implement dump_core_and_abort, Warner Losh, 2022/01/31
- [PULL 34/40] bsd-user/signal.c: process_pending_signals, Warner Losh, 2022/01/31
- [PULL 16/40] bsd-user/signal.c: implement abstract target / host signal translation, Warner Losh, 2022/01/31
- [PULL 13/40] bsd-user/arm/target_arch_cpu.h: Correct code pointer, Warner Losh, 2022/01/31
- [PULL 32/40] bsd-user/signal.c: handle_pending_signal, Warner Losh, 2022/01/31