[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v5 34/37] bsd-user/arm/signal.c: arm set_mcontext
From: |
Warner Losh |
Subject: |
[PATCH v5 34/37] bsd-user/arm/signal.c: arm set_mcontext |
Date: |
Sun, 7 Nov 2021 20:51:33 -0700 |
Move the machine context to the CPU state.
Signed-off-by: Stacey Son <sson@FreeBSD.org>
Signed-off-by: Kyle Evans <kevans@FreeBSD.org>
Signed-off-by: Warner Losh <imp@bsdimp.com>
---
bsd-user/arm/signal.c | 76 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 76 insertions(+)
diff --git a/bsd-user/arm/signal.c b/bsd-user/arm/signal.c
index 93c9bfc0d3..fb6228db6c 100644
--- a/bsd-user/arm/signal.c
+++ b/bsd-user/arm/signal.c
@@ -109,3 +109,79 @@ abi_long get_mcontext(CPUARMState *env, target_mcontext_t
*mcp, int flags)
}
return err;
}
+
+/* Compare to arm/arm/exec_machdep.c set_mcontext() */
+abi_long set_mcontext(CPUARMState *env, target_mcontext_t *mcp, int srflag)
+{
+ int err = 0;
+ const uint32_t *gr = mcp->__gregs;
+ uint32_t cpsr, ccpsr = cpsr_read(env);
+ uint32_t fpscr, mask;
+
+ cpsr = tswap32(gr[TARGET_REG_CPSR]);
+ /*
+ * Only allow certain bits to change, reject attempted changes to non-user
+ * bits. In addition, make sure we're headed for user mode and none of the
+ * interrupt bits are set.
+ */
+ if ((ccpsr & ~CPSR_USER) != (cpsr & ~CPSR_USER)) {
+ return -TARGET_EINVAL;
+ }
+ if ((cpsr & CPSR_M) != ARM_CPU_MODE_USR ||
+ (cpsr & (CPSR_I | CPSR_F)) != 0) {
+ return -TARGET_EINVAL;
+ }
+
+ /*
+ * The movs pc,lr instruction that implements the return to userland masks
+ * these bits out.
+ */
+ mask = cpsr & CPSR_T ? 0x1 : 0x3;
+
+ /*
+ * Make sure that we either have no vfp, or it's the correct size.
+ * FreeBSD just ignores it, though, so maybe we'll need to adjust
+ * things below instead.
+ */
+ if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_size !=
sizeof(target_mcontext_vfp_t)) {
+ return -TARGET_EINVAL;
+ }
+
+ env->regs[0] = tswap32(gr[TARGET_REG_R0]);
+ env->regs[1] = tswap32(gr[TARGET_REG_R1]);
+ env->regs[2] = tswap32(gr[TARGET_REG_R2]);
+ env->regs[3] = tswap32(gr[TARGET_REG_R3]);
+ env->regs[4] = tswap32(gr[TARGET_REG_R4]);
+ env->regs[5] = tswap32(gr[TARGET_REG_R5]);
+ env->regs[6] = tswap32(gr[TARGET_REG_R6]);
+ env->regs[7] = tswap32(gr[TARGET_REG_R7]);
+ env->regs[8] = tswap32(gr[TARGET_REG_R8]);
+ env->regs[9] = tswap32(gr[TARGET_REG_R9]);
+ env->regs[10] = tswap32(gr[TARGET_REG_R10]);
+ env->regs[11] = tswap32(gr[TARGET_REG_R11]);
+ env->regs[12] = tswap32(gr[TARGET_REG_R12]);
+
+ env->regs[13] = tswap32(gr[TARGET_REG_SP]);
+ env->regs[14] = tswap32(gr[TARGET_REG_LR]);
+ env->regs[15] = tswap32(gr[TARGET_REG_PC] & ~mask);
+ if (mcp->mc_vfp_size != 0 && mcp->mc_vfp_ptr != 0) {
+ /* see set_vfpcontext in sys/arm/arm/exec_machdep.c */
+ target_mcontext_vfp_t *vfp;
+
+ vfp = lock_user(VERIFY_READ, mcp->mc_vfp_ptr, sizeof(*vfp), 1);
+ for (int i = 0; i < 32; i++) {
+ __get_user(*aa32_vfp_dreg(env, i), &vfp->mcv_reg[i]);
+ }
+ __get_user(fpscr, &vfp->mcv_fpscr);
+ vfp_set_fpscr(env, fpscr);
+ unlock_user(vfp, mcp->mc_vfp_ptr, sizeof(target_ucontext_t));
+
+ /*
+ * linux-user sets fpexc, fpinst and fpinst2, but these aren't in
+ * FreeBSD's mcontext, what to do?
+ */
+ }
+ cpsr_write(env, cpsr, CPSR_USER | CPSR_EXEC, CPSRWriteByInstr);
+
+ return err;
+}
--
2.33.0
- [PATCH v5 16/37] bsd-user/arm/target_arch_cpu.h: CPU Loop definitions, (continued)
- [PATCH v5 16/37] bsd-user/arm/target_arch_cpu.h: CPU Loop definitions, Warner Losh, 2021/11/07
- [PATCH v5 02/37] bsd-user/freebsd: Create common target_os_ucontext.h file, Warner Losh, 2021/11/07
- [PATCH v5 28/37] bsd-user/arm/target_arch_elf.h: arm get_hwcap2 impl, Warner Losh, 2021/11/07
- [PATCH v5 35/37] bsd-user/arm/signal.c: arm get_ucontext_sigreturn, Warner Losh, 2021/11/07
- [PATCH v5 25/37] bsd-user/arm/target_arch_thread.h: Routines to create and switch to a thread, Warner Losh, 2021/11/07
- [PATCH v5 17/37] bsd-user/arm/target_arch_cpu.h: Implement target_cpu_clone_regs, Warner Losh, 2021/11/07
- [PATCH v5 03/37] bsd-user: create a per-arch signal.c file, Warner Losh, 2021/11/07
- [PATCH v5 13/37] bsd-user/arm/target_arch_sysarch.h: Use consistent include guards, Warner Losh, 2021/11/07
- [PATCH v5 14/37] bsd-user/arm/target_syscall.h: Add copyright and update name, Warner Losh, 2021/11/07
- [PATCH v5 30/37] bsd-user/arm/target_arch_signal.h: arm machine context and trapframe for signals, Warner Losh, 2021/11/07
- [PATCH v5 34/37] bsd-user/arm/signal.c: arm set_mcontext,
Warner Losh <=
- [PATCH v5 15/37] bsd-user/arm/target_arch_cpu.c: Target specific TLS routines, Warner Losh, 2021/11/07
- [PATCH v5 36/37] bsd-user/freebsd/target_os_ucontext.h: Require TARGET_*CONTEXT_SIZE, Warner Losh, 2021/11/07
- [PATCH v5 29/37] bsd-user/arm/target_arch_signal.h: arm specific signal registers and stack, Warner Losh, 2021/11/07
- [PATCH v5 32/37] bsd-user/arm/signal.c: arm set_sigtramp_args, Warner Losh, 2021/11/07
- [PATCH v5 21/37] bsd-user/arm/target_arch_cpu.h: Implement system call dispatch, Warner Losh, 2021/11/07
- [PATCH v5 22/37] bsd-user/arm/target_arch_reg.h: Implement core dump register copying, Warner Losh, 2021/11/07
- [PATCH v5 18/37] bsd-user/arm/target_arch_cpu.h: Dummy target_cpu_loop implementation, Warner Losh, 2021/11/07
- [PATCH v5 31/37] bsd-user/arm/target_arch_signal.h: Define size of *context_t, Warner Losh, 2021/11/07
- [PATCH v5 37/37] bsd-user: add arm target build, Warner Losh, 2021/11/07