提交 459a4017 编写于 作者: B bellard

removed warnings - improved sparc32/64 signal frame setup - disabled x86 frame setup for x86_64


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3608 c046a42c-6fe2-441c-8c8c-71466251a162
上级 eeeac3f3
...@@ -143,7 +143,7 @@ static void host_to_target_sigset_internal(target_sigset_t *d, ...@@ -143,7 +143,7 @@ static void host_to_target_sigset_internal(target_sigset_t *d,
d->sig[0] = target_sigmask; d->sig[0] = target_sigmask;
d->sig[1] = sigmask >> 32; d->sig[1] = sigmask >> 32;
#else #else
#warning host_to_target_sigset /* XXX: do it */
#endif #endif
} }
...@@ -177,7 +177,7 @@ void target_to_host_sigset_internal(sigset_t *d, const target_sigset_t *s) ...@@ -177,7 +177,7 @@ void target_to_host_sigset_internal(sigset_t *d, const target_sigset_t *s)
#elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2
((unsigned long *)d)[0] = sigmask | ((unsigned long)(s->sig[1]) << 32); ((unsigned long *)d)[0] = sigmask | ((unsigned long)(s->sig[1]) << 32);
#else #else
#warning target_to_host_sigset /* XXX: do it */
#endif /* TARGET_ABI_BITS */ #endif /* TARGET_ABI_BITS */
} }
...@@ -233,7 +233,7 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, ...@@ -233,7 +233,7 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
tinfo->_sifields._rt._uid = info->si_uid; tinfo->_sifields._rt._uid = info->si_uid;
/* XXX: potential problem if 64 bit */ /* XXX: potential problem if 64 bit */
tinfo->_sifields._rt._sigval.sival_ptr = tinfo->_sifields._rt._sigval.sival_ptr =
(abi_ulong)info->si_value.sival_ptr; (abi_ulong)(unsigned long)info->si_value.sival_ptr;
} }
} }
...@@ -276,7 +276,7 @@ void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo) ...@@ -276,7 +276,7 @@ void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
info->si_pid = tswap32(tinfo->_sifields._rt._pid); info->si_pid = tswap32(tinfo->_sifields._rt._pid);
info->si_uid = tswap32(tinfo->_sifields._rt._uid); info->si_uid = tswap32(tinfo->_sifields._rt._uid);
info->si_value.sival_ptr = info->si_value.sival_ptr =
(void *)tswapl(tinfo->_sifields._rt._sigval.sival_ptr); (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
} }
void signal_init(void) void signal_init(void)
...@@ -562,7 +562,7 @@ static inline int copy_siginfo_to_user(target_siginfo_t *tinfo, ...@@ -562,7 +562,7 @@ static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
return 0; return 0;
} }
#ifdef TARGET_I386 #if defined(TARGET_I386) && TARGET_ABI_BITS == 32
/* from the Linux kernel */ /* from the Linux kernel */
...@@ -773,11 +773,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, ...@@ -773,11 +773,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
/* This is popl %eax ; movl $,%eax ; int $0x80 */ /* This is popl %eax ; movl $,%eax ; int $0x80 */
val16 = 0xb858; val16 = 0xb858;
err |= __put_user(val16, (uint16_t *)(frame->retcode+0)); err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
#if defined(TARGET_X86_64)
#warning "Fix this !"
#else
err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2)); err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
#endif
val16 = 0x80cd; val16 = 0x80cd;
err |= __put_user(val16, (uint16_t *)(frame->retcode+6)); err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
} }
...@@ -1486,9 +1482,10 @@ struct target_rt_signal_frame { ...@@ -1486,9 +1482,10 @@ struct target_rt_signal_frame {
#define UREG_FP UREG_I6 #define UREG_FP UREG_I6
#define UREG_SP UREG_O6 #define UREG_SP UREG_O6
static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, unsigned long framesize) static inline abi_ulong get_sigframe(struct emulated_sigaction *sa,
CPUState *env, unsigned long framesize)
{ {
unsigned long sp; abi_ulong sp;
sp = env->regwptr[UREG_FP]; sp = env->regwptr[UREG_FP];
...@@ -1498,7 +1495,7 @@ static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, u ...@@ -1498,7 +1495,7 @@ static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, u
&& !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7)) && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
} }
return g2h(sp - framesize); return sp - framesize;
} }
static int static int
...@@ -1543,6 +1540,7 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/ ...@@ -1543,6 +1540,7 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
static void setup_frame(int sig, struct emulated_sigaction *ka, static void setup_frame(int sig, struct emulated_sigaction *ka,
target_sigset_t *set, CPUState *env) target_sigset_t *set, CPUState *env)
{ {
abi_ulong sf_addr;
struct target_signal_frame *sf; struct target_signal_frame *sf;
int sigframe_size, err, i; int sigframe_size, err, i;
...@@ -1550,9 +1548,12 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, ...@@ -1550,9 +1548,12 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
//synchronize_user_stack(); //synchronize_user_stack();
sigframe_size = NF_ALIGNEDSZ; sigframe_size = NF_ALIGNEDSZ;
sf_addr = get_sigframe(ka, env, sigframe_size);
sf = (struct target_signal_frame *) sf = lock_user(VERIFY_WRITE, sf_addr,
get_sigframe(ka, env, sigframe_size); sizeof(struct target_signal_frame), 0);
if (!sf)
goto sigsegv;
//fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]); //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
#if 0 #if 0
...@@ -1581,20 +1582,24 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, ...@@ -1581,20 +1582,24 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
goto sigsegv; goto sigsegv;
/* 3. signal handler back-trampoline and parameters */ /* 3. signal handler back-trampoline and parameters */
env->regwptr[UREG_FP] = h2g(sf); env->regwptr[UREG_FP] = sf_addr;
env->regwptr[UREG_I0] = sig; env->regwptr[UREG_I0] = sig;
env->regwptr[UREG_I1] = h2g(&sf->info); env->regwptr[UREG_I1] = sf_addr +
env->regwptr[UREG_I2] = h2g(&sf->info); offsetof(struct target_signal_frame, info);
env->regwptr[UREG_I2] = sf_addr +
offsetof(struct target_signal_frame, info);
/* 4. signal handler */ /* 4. signal handler */
env->pc = (unsigned long) ka->sa._sa_handler; env->pc = ka->sa._sa_handler;
env->npc = (env->pc + 4); env->npc = (env->pc + 4);
/* 5. return to kernel instructions */ /* 5. return to kernel instructions */
if (ka->sa.sa_restorer) if (ka->sa.sa_restorer)
env->regwptr[UREG_I7] = (unsigned long)ka->sa.sa_restorer; env->regwptr[UREG_I7] = ka->sa.sa_restorer;
else { else {
uint32_t val32; uint32_t val32;
env->regwptr[UREG_I7] = h2g(&(sf->insns[0]) - 2);
env->regwptr[UREG_I7] = sf_addr +
offsetof(struct target_signal_frame, insns) - 2 * 4;
/* mov __NR_sigreturn, %g1 */ /* mov __NR_sigreturn, %g1 */
val32 = 0x821020d8; val32 = 0x821020d8;
...@@ -1610,12 +1615,15 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, ...@@ -1610,12 +1615,15 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
//flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
// tb_flush(env); // tb_flush(env);
} }
unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
return; return;
#if 0
//sigill_and_return: sigill_and_return:
force_sig(TARGET_SIGILL); force_sig(TARGET_SIGILL);
#endif
sigsegv: sigsegv:
//fprintf(stderr, "force_sig\n"); //fprintf(stderr, "force_sig\n");
unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
force_sig(TARGET_SIGSEGV); force_sig(TARGET_SIGSEGV);
} }
static inline int static inline int
...@@ -1744,7 +1752,7 @@ long do_rt_sigreturn(CPUState *env) ...@@ -1744,7 +1752,7 @@ long do_rt_sigreturn(CPUState *env)
return -ENOSYS; return -ENOSYS;
} }
#ifdef TARGET_SPARC64 #if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
#define MC_TSTATE 0 #define MC_TSTATE 0
#define MC_PC 1 #define MC_PC 1
#define MC_NPC 2 #define MC_NPC 2
...@@ -1815,16 +1823,18 @@ struct target_reg_window { ...@@ -1815,16 +1823,18 @@ struct target_reg_window {
/* {set, get}context() needed for 64-bit SparcLinux userland. */ /* {set, get}context() needed for 64-bit SparcLinux userland. */
void sparc64_set_context(CPUSPARCState *env) void sparc64_set_context(CPUSPARCState *env)
{ {
struct target_ucontext *ucp = (struct target_ucontext *) abi_ulong ucp_addr;
env->regwptr[UREG_I0]; struct target_ucontext *ucp;
target_mc_gregset_t *grp; target_mc_gregset_t *grp;
abi_ulong pc, npc, tstate; abi_ulong pc, npc, tstate;
abi_ulong fp, i7; abi_ulong fp, i7, w_addr;
unsigned char fenab; unsigned char fenab;
int err; int err;
unsigned int i; unsigned int i;
abi_ulong *src, *dst;
ucp_addr = env->regwptr[UREG_I0];
if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
goto do_sigsegv;
grp = &ucp->uc_mcontext.mc_gregs; grp = &ucp->uc_mcontext.mc_gregs;
err = __get_user(pc, &((*grp)[MC_PC])); err = __get_user(pc, &((*grp)[MC_PC]));
err |= __get_user(npc, &((*grp)[MC_NPC])); err |= __get_user(npc, &((*grp)[MC_NPC]));
...@@ -1838,11 +1848,12 @@ void sparc64_set_context(CPUSPARCState *env) ...@@ -1838,11 +1848,12 @@ void sparc64_set_context(CPUSPARCState *env)
if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0])) if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
goto do_sigsegv; goto do_sigsegv;
} else { } else {
src = &ucp->uc_sigmask; abi_ulong *src, *dst;
dst = &target_set; src = ucp->uc_sigmask.sig;
dst = target_set.sig;
for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong); for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
i++, dst++, src++) i++, dst++, src++)
err |= __get_user(dst, src); err |= __get_user(*dst, src);
if (err) if (err)
goto do_sigsegv; goto do_sigsegv;
} }
...@@ -1874,42 +1885,53 @@ void sparc64_set_context(CPUSPARCState *env) ...@@ -1874,42 +1885,53 @@ void sparc64_set_context(CPUSPARCState *env)
err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp)); err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7)); err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
err |= __put_user(fp,
(&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));
err |= __put_user(i7,
(&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));
w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
abi_ulong) != 0)
goto do_sigsegv;
if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
abi_ulong) != 0)
goto do_sigsegv;
err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab)); err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs)); err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
src = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs); {
dst = &env->fpr; uint32_t *src, *dst;
src = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
dst = env->fpr;
/* XXX: check that the CPU storage is the same as user context */
for (i = 0; i < 64; i++, dst++, src++) for (i = 0; i < 64; i++, dst++, src++)
err |= __get_user(dst, src); err |= __get_user(*dst, src);
}
err |= __get_user(env->fsr, err |= __get_user(env->fsr,
&(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr)); &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
err |= __get_user(env->gsr, err |= __get_user(env->gsr,
&(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr)); &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
if (err) if (err)
goto do_sigsegv; goto do_sigsegv;
unlock_user_struct(ucp, ucp_addr, 0);
return; return;
do_sigsegv: do_sigsegv:
unlock_user_struct(ucp, ucp_addr, 0);
force_sig(SIGSEGV); force_sig(SIGSEGV);
} }
void sparc64_get_context(CPUSPARCState *env) void sparc64_get_context(CPUSPARCState *env)
{ {
struct target_ucontext *ucp = (struct target_ucontext *) abi_ulong ucp_addr;
env->regwptr[UREG_I0]; struct target_ucontext *ucp;
target_mc_gregset_t *grp; target_mc_gregset_t *grp;
target_mcontext_t *mcp; target_mcontext_t *mcp;
abi_ulong fp, i7; abi_ulong fp, i7, w_addr;
int err; int err;
unsigned int i; unsigned int i;
abi_ulong *src, *dst;
target_sigset_t target_set; target_sigset_t target_set;
sigset_t set; sigset_t set;
ucp_addr = env->regwptr[UREG_I0];
if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
goto do_sigsegv;
mcp = &ucp->uc_mcontext; mcp = &ucp->uc_mcontext;
grp = &mcp->mc_gregs; grp = &mcp->mc_gregs;
...@@ -1921,20 +1943,22 @@ void sparc64_get_context(CPUSPARCState *env) ...@@ -1921,20 +1943,22 @@ void sparc64_get_context(CPUSPARCState *env)
sigprocmask(0, NULL, &set); sigprocmask(0, NULL, &set);
host_to_target_sigset_internal(&target_set, &set); host_to_target_sigset_internal(&target_set, &set);
if (TARGET_NSIG_WORDS == 1) if (TARGET_NSIG_WORDS == 1) {
err |= __put_user(target_set.sig[0], err |= __put_user(target_set.sig[0],
(abi_ulong *)&ucp->uc_sigmask); (abi_ulong *)&ucp->uc_sigmask);
else { } else {
src = &target_set; abi_ulong *src, *dst;
dst = &ucp->uc_sigmask; src = target_set.sig;
dst = ucp->uc_sigmask.sig;
for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong); for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
i++, dst++, src++) i++, dst++, src++)
err |= __put_user(src, dst); err |= __put_user(*src, dst);
if (err) if (err)
goto do_sigsegv; goto do_sigsegv;
} }
err |= __put_user(env->tstate, &((*grp)[MC_TSTATE])); /* XXX: tstate must be saved properly */
// err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
err |= __put_user(env->pc, &((*grp)[MC_PC])); err |= __put_user(env->pc, &((*grp)[MC_PC]));
err |= __put_user(env->npc, &((*grp)[MC_NPC])); err |= __put_user(env->npc, &((*grp)[MC_NPC]));
err |= __put_user(env->y, &((*grp)[MC_Y])); err |= __put_user(env->y, &((*grp)[MC_Y]));
...@@ -1954,26 +1978,35 @@ void sparc64_get_context(CPUSPARCState *env) ...@@ -1954,26 +1978,35 @@ void sparc64_get_context(CPUSPARCState *env)
err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6])); err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7])); err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
err |= __get_user(fp, w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
(&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6]))); fp = i7 = 0;
err |= __get_user(i7, if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
(&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7]))); abi_ulong) != 0)
goto do_sigsegv;
if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
abi_ulong) != 0)
goto do_sigsegv;
err |= __put_user(fp, &(mcp->mc_fp)); err |= __put_user(fp, &(mcp->mc_fp));
err |= __put_user(i7, &(mcp->mc_i7)); err |= __put_user(i7, &(mcp->mc_i7));
src = &env->fpr; {
dst = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs); uint32_t *src, *dst;
src = env->fpr;
dst = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
/* XXX: check that the CPU storage is the same as user context */
for (i = 0; i < 64; i++, dst++, src++) for (i = 0; i < 64; i++, dst++, src++)
err |= __put_user(src, dst); err |= __put_user(*src, dst);
}
err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr)); err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr)); err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs)); err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
if (err) if (err)
goto do_sigsegv; goto do_sigsegv;
unlock_user_struct(ucp, ucp_addr, 1);
return; return;
do_sigsegv: do_sigsegv:
unlock_user_struct(ucp, ucp_addr, 1);
force_sig(SIGSEGV); force_sig(SIGSEGV);
} }
#endif #endif
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册