linux-user: Save/restore fpu registers to signal context on sh4
As "todo" comment in source code. And modify restore_sigcontext() to have three args as kernel's does. Signed-off-by: Takashi YOSHII <takasi-y@ops.dti.ne.jp> Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>
This commit is contained in:
parent
597c0212a7
commit
d871443692
@ -2812,6 +2812,7 @@ static int setup_sigcontext(struct target_sigcontext *sc,
|
||||
CPUState *regs, unsigned long mask)
|
||||
{
|
||||
int err = 0;
|
||||
int i;
|
||||
|
||||
#define COPY(x) err |= __put_user(regs->x, &sc->sc_##x)
|
||||
COPY(gregs[0]); COPY(gregs[1]);
|
||||
@ -2827,7 +2828,11 @@ static int setup_sigcontext(struct target_sigcontext *sc,
|
||||
COPY(sr); COPY(pc);
|
||||
#undef COPY
|
||||
|
||||
/* todo: save FPU registers here */
|
||||
for (i=0; i<16; i++) {
|
||||
err |= __put_user(regs->fregs[i], &sc->sc_fpregs[i]);
|
||||
}
|
||||
err |= __put_user(regs->fpscr, &sc->sc_fpscr);
|
||||
err |= __put_user(regs->fpul, &sc->sc_fpul);
|
||||
|
||||
/* non-iBCS2 extensions.. */
|
||||
err |= __put_user(mask, &sc->oldmask);
|
||||
@ -2835,10 +2840,11 @@ static int setup_sigcontext(struct target_sigcontext *sc,
|
||||
return err;
|
||||
}
|
||||
|
||||
static int restore_sigcontext(CPUState *regs,
|
||||
struct target_sigcontext *sc)
|
||||
static int restore_sigcontext(CPUState *regs, struct target_sigcontext *sc,
|
||||
target_ulong *r0_p)
|
||||
{
|
||||
unsigned int err = 0;
|
||||
int i;
|
||||
|
||||
#define COPY(x) err |= __get_user(regs->x, &sc->sc_##x)
|
||||
COPY(gregs[1]);
|
||||
@ -2854,9 +2860,14 @@ static int restore_sigcontext(CPUState *regs,
|
||||
COPY(sr); COPY(pc);
|
||||
#undef COPY
|
||||
|
||||
/* todo: restore FPU registers here */
|
||||
for (i=0; i<16; i++) {
|
||||
err |= __get_user(regs->fregs[i], &sc->sc_fpregs[i]);
|
||||
}
|
||||
err |= __get_user(regs->fpscr, &sc->sc_fpscr);
|
||||
err |= __get_user(regs->fpul, &sc->sc_fpul);
|
||||
|
||||
regs->tra = -1; /* disable syscall checks */
|
||||
err |= __get_user(*r0_p, &sc->sc_gregs[0]);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -2980,6 +2991,7 @@ long do_sigreturn(CPUState *regs)
|
||||
abi_ulong frame_addr;
|
||||
sigset_t blocked;
|
||||
target_sigset_t target_set;
|
||||
target_ulong r0;
|
||||
int i;
|
||||
int err = 0;
|
||||
|
||||
@ -3001,11 +3013,11 @@ long do_sigreturn(CPUState *regs)
|
||||
target_to_host_sigset_internal(&blocked, &target_set);
|
||||
sigprocmask(SIG_SETMASK, &blocked, NULL);
|
||||
|
||||
if (restore_sigcontext(regs, &frame->sc))
|
||||
if (restore_sigcontext(regs, &frame->sc, &r0))
|
||||
goto badframe;
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return regs->gregs[0];
|
||||
return r0;
|
||||
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
@ -3018,6 +3030,7 @@ long do_rt_sigreturn(CPUState *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");
|
||||
@ -3029,7 +3042,7 @@ long do_rt_sigreturn(CPUState *regs)
|
||||
target_to_host_sigset(&blocked, &frame->uc.uc_sigmask);
|
||||
sigprocmask(SIG_SETMASK, &blocked, NULL);
|
||||
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
|
||||
if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &r0))
|
||||
goto badframe;
|
||||
|
||||
if (do_sigaltstack(frame_addr +
|
||||
@ -3038,7 +3051,7 @@ long do_rt_sigreturn(CPUState *regs)
|
||||
goto badframe;
|
||||
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
return regs->gregs[0];
|
||||
return r0;
|
||||
|
||||
badframe:
|
||||
unlock_user_struct(frame, frame_addr, 0);
|
||||
|
Loading…
Reference in New Issue
Block a user