diff options
Diffstat (limited to 'emulators/qemu-devel/files/patch-z9f-bsd-user-sson003f')
-rw-r--r-- | emulators/qemu-devel/files/patch-z9f-bsd-user-sson003f | 321 |
1 files changed, 321 insertions, 0 deletions
diff --git a/emulators/qemu-devel/files/patch-z9f-bsd-user-sson003f b/emulators/qemu-devel/files/patch-z9f-bsd-user-sson003f new file mode 100644 index 000000000000..2cf57e8a1429 --- /dev/null +++ b/emulators/qemu-devel/files/patch-z9f-bsd-user-sson003f @@ -0,0 +1,321 @@ +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; + |