freebsd-ports/emulators/qemu-devel/files/patch-z9f-bsd-user-sson003f
Juergen Lock 45aa9370f0 - Update net/usbredir to 0.6 .
- Update emulators/qemu-devel to 1.4.0 with preliminary bsd-user patches.

Thanx to:	sson, cognet, and others for much improved bsd-user support -
		it now runs at least quite a few mips64 and single-threaded
		arm binaries, see:

	https://wiki.freebsd.org/QemuUserModeHowTo
2013-03-29 17:40:38 +00:00

321 lines
9.2 KiB
Text

diff --git a/bsd-user/arm/target_signal.h b/bsd-user/arm/target_signal.h
index 6b7bb67..4a9e518 100644
--- a/bsd-user/arm/target_signal.h
+++ b/bsd-user/arm/target_signal.h
@@ -3,15 +3,57 @@
#include "cpu.h"
-static inline abi_ulong get_sp_from_cpustate(CPUARMState *state)
-{
- return state->regs[13];
-}
+#define TARGET_REG_R0 0
+#define TARGET_REG_R1 1
+#define TARGET_REG_R2 2
+#define TARGET_REG_R3 3
+#define TARGET_REG_R4 4
+#define TARGET_REG_R5 5
+#define TARGET_REG_R6 6
+#define TARGET_REG_R7 7
+#define TARGET_REG_R8 8
+#define TARGET_REG_R9 9
+#define TARGET_REG_R10 10
+#define TARGET_REG_R11 11
+#define TARGET_REG_R12 12
+#define TARGET_REG_R13 13
+#define TARGET_REG_R14 14
+#define TARGET_REG_R15 15
+#define TARGET_REG_CPSR 16
+/* Convenience synonyms */
+#define TARGET_REG_FP TARGET_REG_R11
+#define TARGET_REG_SP TARGET_REG_R13
+#define TARGET_REG_LR TARGET_REG_R14
+#define TARGET_REG_PC TARGET_REG_R15
+
+#define TARGET_GET_MC_CLEAR_RET 1
#define TARGET_MINSIGSTKSZ (1024 * 4)
#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768)
+#define TARGET__NGREG 17
+
+typedef struct {
+ uint32_t __fp_fpsr;
+ struct {
+ uint32_t __fp_exponent;
+ uint32_t __fp_mantissa_hi;
+ uint32_t __fp_mantissa_lo;
+ } __fp_fr[8];
+} target__fpregset_t;
-typedef target_ulong target_mcontext_t; /* dummy */
+typedef struct {
+ uint32_t __vfp_fpscr;
+ uint32_t __vfp_fstmx[33];
+ uint32_t __vfp_fpsid;
+} target__vfpregset_t;
+
+typedef struct {
+ uint32_t __gregs[TARGET__NGREG];
+ union {
+ target__fpregset_t __fpregs;
+ target__vfpregset_t __vfpregs;
+ } __fpu;
+} target_mcontext_t;
typedef struct target_ucontext {
target_sigset_t uc_sigmask;
@@ -22,18 +64,119 @@ typedef struct target_ucontext {
int32_t __spare__[4];
} target_ucontext_t;
+struct target_sigframe {
+ target_siginfo_t sf_si; /* saved siginfo */
+ target_ucontext_t sf_uc; /* saved ucontext */
+};
+
+#define TARGET_SZSIGCODE (8 * 4)
+
+/* Compare to arm/arm/locore.S ENTRY_NP(sigcode) */
+static inline int
+install_sigtramp(abi_ulong offset, unsigned sigf_us, uint32_t sys_sigreturn)
+{
+ int i;
+ uint32_t sys_exit = TARGET_FREEBSD_NR_exit;
+ /*
+ * The code has to load r7 manually rather than using
+ * "ldr r7, =SYS_return to make sure the size of the
+ * code is correct.
+ */
+ uint32_t sigtramp_code[] = {
+ /* 1 */ 0xE1A0000D, /* mov r0, sp */
+ /* 2 */ 0xE59F700C, /* ldr r7, [pc, #12] */
+ /* 3 */ 0xEF000000 + sys_sigreturn, /* swi (SYS_sigreturn) */
+ /* 4 */ 0xE59F7008, /* ldr r7, [pc, #8] */
+ /* 5 */ 0xEF000000 + sys_exit, /* swi (SYS_exit)*/
+ /* 6 */ 0xEAFFFFFA, /* b . -16 */
+ /* 7 */ sys_sigreturn,
+ /* 8 */ sys_exit
+ };
+
+ for(i = 0; i < 8; i++)
+ tswap32s(&sigtramp_code[i]);
+
+ return(memcpy_to_target(offset, sigtramp_code, TARGET_SZSIGCODE));
+}
+
+static inline abi_ulong
+get_sp_from_cpustate(CPUARMState *state)
+{
+ return state->regs[13]; /* sp */
+}
+
+/*
+ * Compare to arm/arm/machdep.c sendsig()
+ * Assumes that the target stack frame memory is locked.
+ */
+static inline int
+set_sigtramp_args(CPUARMState *regs, int sig, struct target_sigframe *frame,
+ abi_ulong frame_addr, struct target_sigaction *ka)
+{
+ /*
+ * Arguments to signal handler:
+ * r0 = signal number
+ * r1 = siginfo pointer
+ * r2 = ucontext pointer
+ * r5 = ucontext pointer
+ * pc = signal handler pointer
+ * sp = sigframe struct pointer
+ * lr = sigtramp at base of user stack
+ */
+
+ regs->regs[0] = sig;
+ regs->regs[1] = frame_addr +
+ offsetof(struct target_sigframe, sf_si);
+ regs->regs[2] = frame_addr +
+ offsetof(struct target_sigframe, sf_uc);
+
+ /* the trampoline uses r5 as the uc address */
+ regs->regs[5] = frame_addr +
+ offsetof(struct target_sigframe, sf_uc);
+ regs->regs[TARGET_REG_PC] = ka->_sa_handler;
+ regs->regs[TARGET_REG_SP] = frame_addr;
+ regs->regs[TARGET_REG_LR] = TARGET_PS_STRINGS - TARGET_SZSIGCODE;
+
+ return (0);
+}
+
+/* Compare to arm/arm/machdep.c get_mcontext() */
static inline int
-get_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags)
+get_mcontext(CPUARMState *regs, target_mcontext_t *mcp, int clear_ret)
{
- fprintf(stderr, "ARM doesn't have support for get_mcontext()\n");
- return (-TARGET_ENOSYS);
+ int i, err = 0;
+ uint32_t *gr = mcp->__gregs;
+
+
+ if (clear_ret & TARGET_GET_MC_CLEAR_RET)
+ gr[TARGET_REG_R0] = 0;
+ else
+ gr[TARGET_REG_R0] = tswap32(regs->regs[0]);
+ for(i = 1; i < 12; i++)
+ gr[i] = tswap32(regs->regs[i]);
+ gr[TARGET_REG_SP] = tswap32(regs->regs[13]);
+ gr[TARGET_REG_LR] = tswap32(regs->regs[14]);
+ gr[TARGET_REG_PC] = tswap32(regs->regs[15]);
+ gr[TARGET_REG_CPSR] = tswap32(regs->spsr);
+
+ return (err);
}
+/* Compare to arm/arm/machdep.c set_mcontext() */
static inline int
-set_mcontext(CPUArchState *regs, target_mcontext_t *mcp, int flags)
+set_mcontext(CPUARMState *regs, target_mcontext_t *mcp, int flags)
{
- fprintf(stderr, "ARM doesn't have support for set_mcontext()\n");
- return (-TARGET_ENOSYS);
+ int i, err = 0;
+ const uint32_t *gr = mcp->__gregs;
+
+ for(i = 0; i < 12; i++)
+ regs->regs[i] = tswap32(gr[i]);
+ regs->regs[13] = tswap32(gr[TARGET_REG_SP]);
+ regs->regs[14] = tswap32(gr[TARGET_REG_LR]);
+ regs->regs[15] = tswap32(gr[TARGET_REG_PC]);
+ regs->spsr = tswap32(gr[TARGET_REG_CPSR]);
+
+ return (err);
}
#endif /* TARGET_SIGNAL_H */
diff --git a/bsd-user/arm/target_vmparam.h b/bsd-user/arm/target_vmparam.h
index 24dca00..bc50fbb 100644
--- a/bsd-user/arm/target_vmparam.h
+++ b/bsd-user/arm/target_vmparam.h
@@ -18,8 +18,6 @@ struct target_ps_strings {
#define TARGET_PS_STRINGS (TARGET_USRSTACK - sizeof(struct target_ps_strings))
-#define TARGET_SZSIGCODE 0
-
/* Make stack size large enough to hold everything. */
#define TARGET_STACK_SIZE ((x86_stack_size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) ? \
MAX_ARG_PAGES*TARGET_PAGE_SIZE : x86_stack_size)
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index c2c3a65..76681e1 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -690,24 +690,6 @@ static abi_ulong copy_elf_strings(int argc,char ** argv, void **page,
return p;
}
-#if defined(TARGET_MIPS64)
-static inline int
-install_sigtramp(abi_ulong offset, unsigned sigf_uc, unsigned syscall)
-{
- int i;
- uint32_t sigtramp_code[] = {
- 0x67A40000 + sigf_uc, /* daddu $a0, $sp, (sigf_uc) */
- 0x24020000 + syscall, /* li $v0, (syscall) */
- 0x0000000C, /* syscall */
- 0x0000000D /* break */
- };
-
- for(i = 0; i < 4; i++)
- tswap32s(&sigtramp_code[i]);
-
- return (memcpy_to_target(offset, sigtramp_code, TARGET_SZSIGCODE));
-}
-#endif
static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm,
struct image_info *info)
diff --git a/bsd-user/mips64/target_signal.h b/bsd-user/mips64/target_signal.h
index c592136..f657909 100644
--- a/bsd-user/mips64/target_signal.h
+++ b/bsd-user/mips64/target_signal.h
@@ -5,7 +5,6 @@
#define TARGET_MINSIGSTKSZ (512 * 4)
#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768)
-#define TARGET_SZSIGCODE 16
struct target_sigcontext {
target_sigset_t sc_mask; /* signal mask to retstore */
@@ -56,9 +55,29 @@ get_sp_from_cpustate(CPUMIPSState *state)
return state->active_tc.gpr[29];
}
+#define TARGET_SZSIGCODE (4 * 4)
+
+/* Compare to mips/mips/locore.S sigcode() */
+static inline int
+install_sigtramp(abi_ulong offset, unsigned sigf_uc, unsigned sys_sigreturn)
+{
+ int i;
+ uint32_t sigtramp_code[] = {
+ /* 1 */ 0x67A40000 + sigf_uc, /* daddu $a0, $sp, (sigf_uc) */
+ /* 2 */ 0x24020000 + sys_sigreturn, /* li $v0, (sys_sigreturn) */
+ /* 3 */ 0x0000000C, /* syscall */
+ /* 4 */ 0x0000000D /* break */
+ };
+
+ for(i = 0; i < 4; i++)
+ tswap32s(&sigtramp_code[i]);
+
+ return (memcpy_to_target(offset, sigtramp_code, TARGET_SZSIGCODE));
+}
+
/*
* Compare to mips/mips/pm_machdep.c sendsig()
- * Assumes that "frame" memory is locked.
+ * Assumes that target stack frame memory is locked.
*/
static inline int
set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame,
@@ -67,6 +86,11 @@ set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame,
/* frame->sf_si.si_addr = regs->CP0_BadVAddr; */
+ /* MIPS only struct target_sigframe members: */
+ frame->sf_signum = sig;
+ frame->sf_siginfo = (abi_ulong)&frame->sf_si;
+ frame->sf_ucontext = (abi_ulong)&frame->sf_uc;
+
/*
* Arguments to signal handler:
* a0 ($4) = signal number
diff --git a/bsd-user/signal.c b/bsd-user/signal.c
index 29e8e12..b04e874 100644
--- a/bsd-user/signal.c
+++ b/bsd-user/signal.c
@@ -613,7 +613,7 @@ do_sigaction(int sig, const struct target_sigaction *act,
return (ret);
}
-#if defined(TARGET_MIPS64) /* || defined(TARGET_SPARC64) */
+#if defined(TARGET_MIPS64) || defined(TARGET_ARM)
static inline abi_ulong
get_sigframe(struct target_sigaction *ka, CPUArchState *regs, size_t frame_size)
@@ -715,17 +715,8 @@ static void setup_frame(int sig, int code, struct target_sigaction *ka,
}
#endif
- frame->sf_signum = sig;
- frame->sf_siginfo = (abi_ulong)&frame->sf_si;
- frame->sf_ucontext = (abi_ulong)&frame->sf_uc;
-
- } else {
- frame->sf_signum = sig;
- frame->sf_siginfo = 0;
- frame->sf_ucontext = 0;
}
-
if (set_sigtramp_args(regs, sig, frame, frame_addr, ka))
goto give_sigsegv;