Signed-off-by: Timothy Edward Baldwin <t.e.baldwi...@members.leeds.ac.uk> ---
Works without signals, but my signal test case crashes with or without my changes. linux-user/main.c | 6 +++++- linux-user/sh4/syscall.h | 2 ++ linux-user/signal.c | 16 ++++++---------- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/linux-user/main.c b/linux-user/main.c index 3eacc9c..b239097 100644 --- a/linux-user/main.c +++ b/linux-user/main.c @@ -2790,7 +2790,11 @@ void cpu_loop(CPUSH4State *env) env->gregs[0], env->gregs[1], 0, 0); - env->gregs[0] = ret; + if (ret == -TARGET_ERESTARTSYS) { + env->pc -= 2; + } else if (ret != -TARGET_QEMU_ESIGRETURN) { + env->gregs[0] = ret; + } break; case EXCP_INTERRUPT: /* just indicate that signals should be handled asap */ diff --git a/linux-user/sh4/syscall.h b/linux-user/sh4/syscall.h index 7aa4f23..1c0bdfd 100644 --- a/linux-user/sh4/syscall.h +++ b/linux-user/sh4/syscall.h @@ -15,3 +15,5 @@ struct target_pt_regs { #define TARGET_MINSIGSTKSZ 2048 #define TARGET_MLOCKALL_MCL_CURRENT 1 #define TARGET_MLOCKALL_MCL_FUTURE 2 + +#define TARGET_USE_ERESTARTSYS 1 diff --git a/linux-user/signal.c b/linux-user/signal.c index abc7e30..9629c72 100644 --- a/linux-user/signal.c +++ b/linux-user/signal.c @@ -3212,13 +3212,12 @@ static void setup_sigcontext(struct target_sigcontext *sc, __put_user(mask, &sc->oldmask); } -static void restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc, - target_ulong *r0_p) +static void restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc) { int i; #define COPY(x) __get_user(regs->x, &sc->sc_##x) - COPY(gregs[1]); + COPY(gregs[0]); COPY(gregs[1]); COPY(gregs[2]); COPY(gregs[3]); COPY(gregs[4]); COPY(gregs[5]); COPY(gregs[6]); COPY(gregs[7]); @@ -3238,7 +3237,6 @@ static void restore_sigcontext(CPUSH4State *regs, struct target_sigcontext *sc, __get_user(regs->fpul, &sc->sc_fpul); regs->tra = -1; /* disable syscall checks */ - __get_user(*r0_p, &sc->sc_gregs[0]); } static void setup_frame(int sig, struct target_sigaction *ka, @@ -3357,7 +3355,6 @@ long do_sigreturn(CPUSH4State *regs) abi_ulong frame_addr; sigset_t blocked; target_sigset_t target_set; - target_ulong r0; int i; int err = 0; @@ -3380,10 +3377,10 @@ long do_sigreturn(CPUSH4State *regs) target_to_host_sigset_internal(&blocked, &target_set); do_sigprocmask(SIG_SETMASK, &blocked, NULL); - restore_sigcontext(regs, &frame->sc, &r0); + restore_sigcontext(regs, &frame->sc); unlock_user_struct(frame, frame_addr, 0); - return r0; + return -TARGET_QEMU_ESIGRETURN; badframe: unlock_user_struct(frame, frame_addr, 0); @@ -3396,7 +3393,6 @@ long do_rt_sigreturn(CPUSH4State *regs) struct target_rt_sigframe *frame; abi_ulong frame_addr; sigset_t blocked; - target_ulong r0; #if defined(DEBUG_SIGNAL) fprintf(stderr, "do_rt_sigreturn\n"); @@ -3409,7 +3405,7 @@ long do_rt_sigreturn(CPUSH4State *regs) target_to_host_sigset(&blocked, &frame->uc.tuc_sigmask); do_sigprocmask(SIG_SETMASK, &blocked, NULL); - restore_sigcontext(regs, &frame->uc.tuc_mcontext, &r0); + restore_sigcontext(regs, &frame->uc.tuc_mcontext); if (do_sigaltstack(frame_addr + offsetof(struct target_rt_sigframe, uc.tuc_stack), @@ -3418,7 +3414,7 @@ long do_rt_sigreturn(CPUSH4State *regs) } unlock_user_struct(frame, frame_addr, 0); - return r0; + return -TARGET_QEMU_ESIGRETURN; badframe: unlock_user_struct(frame, frame_addr, 0); -- 2.1.4