?? signal.c
字號:
#define MC_G7 10#define MC_O0 11#define MC_O1 12#define MC_O2 13#define MC_O3 14#define MC_O4 15#define MC_O5 16#define MC_O6 17#define MC_O7 18#define MC_NGREG 19typedef abi_ulong target_mc_greg_t;typedef target_mc_greg_t target_mc_gregset_t[MC_NGREG];struct target_mc_fq { abi_ulong *mcfq_addr; uint32_t mcfq_insn;};struct target_mc_fpu { union { uint32_t sregs[32]; uint64_t dregs[32]; //uint128_t qregs[16]; } mcfpu_fregs; abi_ulong mcfpu_fsr; abi_ulong mcfpu_fprs; abi_ulong mcfpu_gsr; struct target_mc_fq *mcfpu_fq; unsigned char mcfpu_qcnt; unsigned char mcfpu_qentsz; unsigned char mcfpu_enab;};typedef struct target_mc_fpu target_mc_fpu_t;typedef struct { target_mc_gregset_t mc_gregs; target_mc_greg_t mc_fp; target_mc_greg_t mc_i7; target_mc_fpu_t mc_fpregs;} target_mcontext_t;struct target_ucontext { struct target_ucontext *uc_link; abi_ulong uc_flags; target_sigset_t uc_sigmask; target_mcontext_t uc_mcontext;};/* A V9 register window */struct target_reg_window { abi_ulong locals[8]; abi_ulong ins[8];};#define TARGET_STACK_BIAS 2047/* {set, get}context() needed for 64-bit SparcLinux userland. */void sparc64_set_context(CPUSPARCState *env){ abi_ulong ucp_addr; struct target_ucontext *ucp; target_mc_gregset_t *grp; abi_ulong pc, npc, tstate; abi_ulong fp, i7, w_addr; unsigned char fenab; int err; unsigned int i; 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; err = __get_user(pc, &((*grp)[MC_PC])); err |= __get_user(npc, &((*grp)[MC_NPC])); if (err || ((pc | npc) & 3)) goto do_sigsegv; if (env->regwptr[UREG_I1]) { target_sigset_t target_set; sigset_t set; if (TARGET_NSIG_WORDS == 1) { if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0])) goto do_sigsegv; } else { abi_ulong *src, *dst; src = ucp->uc_sigmask.sig; dst = target_set.sig; for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong); i++, dst++, src++) err |= __get_user(*dst, src); if (err) goto do_sigsegv; } target_to_host_sigset_internal(&set, &target_set); sigprocmask(SIG_SETMASK, &set, NULL); } env->pc = pc; env->npc = npc; err |= __get_user(env->y, &((*grp)[MC_Y])); err |= __get_user(tstate, &((*grp)[MC_TSTATE])); env->asi = (tstate >> 24) & 0xff; PUT_CCR(env, tstate >> 32); PUT_CWP64(env, tstate & 0x1f); err |= __get_user(env->gregs[1], (&(*grp)[MC_G1])); err |= __get_user(env->gregs[2], (&(*grp)[MC_G2])); err |= __get_user(env->gregs[3], (&(*grp)[MC_G3])); err |= __get_user(env->gregs[4], (&(*grp)[MC_G4])); err |= __get_user(env->gregs[5], (&(*grp)[MC_G5])); err |= __get_user(env->gregs[6], (&(*grp)[MC_G6])); err |= __get_user(env->gregs[7], (&(*grp)[MC_G7])); err |= __get_user(env->regwptr[UREG_I0], (&(*grp)[MC_O0])); err |= __get_user(env->regwptr[UREG_I1], (&(*grp)[MC_O1])); err |= __get_user(env->regwptr[UREG_I2], (&(*grp)[MC_O2])); err |= __get_user(env->regwptr[UREG_I3], (&(*grp)[MC_O3])); err |= __get_user(env->regwptr[UREG_I4], (&(*grp)[MC_O4])); err |= __get_user(env->regwptr[UREG_I5], (&(*grp)[MC_O5])); err |= __get_user(env->regwptr[UREG_I6], (&(*grp)[MC_O6])); err |= __get_user(env->regwptr[UREG_I7], (&(*grp)[MC_O7])); err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp)); err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7)); 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(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs)); { 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++) err |= __get_user(*dst, src); } err |= __get_user(env->fsr, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr)); err |= __get_user(env->gsr, &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr)); if (err) goto do_sigsegv; unlock_user_struct(ucp, ucp_addr, 0); return; do_sigsegv: unlock_user_struct(ucp, ucp_addr, 0); force_sig(SIGSEGV);}void sparc64_get_context(CPUSPARCState *env){ abi_ulong ucp_addr; struct target_ucontext *ucp; target_mc_gregset_t *grp; target_mcontext_t *mcp; abi_ulong fp, i7, w_addr; int err; unsigned int i; target_sigset_t target_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; grp = &mcp->mc_gregs; /* Skip over the trap instruction, first. */ env->pc = env->npc; env->npc += 4; err = 0; sigprocmask(0, NULL, &set); host_to_target_sigset_internal(&target_set, &set); if (TARGET_NSIG_WORDS == 1) { err |= __put_user(target_set.sig[0], (abi_ulong *)&ucp->uc_sigmask); } else { abi_ulong *src, *dst; src = target_set.sig; dst = ucp->uc_sigmask.sig; for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong); i++, dst++, src++) err |= __put_user(*src, dst); if (err) goto do_sigsegv; } /* 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->npc, &((*grp)[MC_NPC])); err |= __put_user(env->y, &((*grp)[MC_Y])); err |= __put_user(env->gregs[1], &((*grp)[MC_G1])); err |= __put_user(env->gregs[2], &((*grp)[MC_G2])); err |= __put_user(env->gregs[3], &((*grp)[MC_G3])); err |= __put_user(env->gregs[4], &((*grp)[MC_G4])); err |= __put_user(env->gregs[5], &((*grp)[MC_G5])); err |= __put_user(env->gregs[6], &((*grp)[MC_G6])); err |= __put_user(env->gregs[7], &((*grp)[MC_G7])); err |= __put_user(env->regwptr[UREG_I0], &((*grp)[MC_O0])); err |= __put_user(env->regwptr[UREG_I1], &((*grp)[MC_O1])); err |= __put_user(env->regwptr[UREG_I2], &((*grp)[MC_O2])); err |= __put_user(env->regwptr[UREG_I3], &((*grp)[MC_O3])); err |= __put_user(env->regwptr[UREG_I4], &((*grp)[MC_O4])); err |= __put_user(env->regwptr[UREG_I5], &((*grp)[MC_O5])); err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6])); err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7])); w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6]; fp = i7 = 0; if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]), 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(i7, &(mcp->mc_i7)); { 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++) err |= __put_user(*src, dst); } err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr)); err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr)); err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs)); if (err) goto do_sigsegv; unlock_user_struct(ucp, ucp_addr, 1); return; do_sigsegv: unlock_user_struct(ucp, ucp_addr, 1); force_sig(SIGSEGV);}#endif#elif defined(TARGET_ABI_MIPSN64)# warning signal handling not implementedstatic void setup_frame(int sig, struct emulated_sigaction *ka, target_sigset_t *set, CPUState *env){ fprintf(stderr, "setup_frame: not implemented\n");}static void setup_rt_frame(int sig, struct emulated_sigaction *ka, target_siginfo_t *info, target_sigset_t *set, CPUState *env){ fprintf(stderr, "setup_rt_frame: not implemented\n");}long do_sigreturn(CPUState *env){ fprintf(stderr, "do_sigreturn: not implemented\n"); return -TARGET_ENOSYS;}long do_rt_sigreturn(CPUState *env){ fprintf(stderr, "do_rt_sigreturn: not implemented\n"); return -TARGET_ENOSYS;}#elif defined(TARGET_ABI_MIPSN32)# warning signal handling not implementedstatic void setup_frame(int sig, struct emulated_sigaction *ka, target_sigset_t *set, CPUState *env){ fprintf(stderr, "setup_frame: not implemented\n");}static void setup_rt_frame(int sig, struct emulated_sigaction *ka, target_siginfo_t *info, target_sigset_t *set, CPUState *env){ fprintf(stderr, "setup_rt_frame: not implemented\n");}long do_sigreturn(CPUState *env){ fprintf(stderr, "do_sigreturn: not implemented\n"); return -TARGET_ENOSYS;}long do_rt_sigreturn(CPUState *env){ fprintf(stderr, "do_rt_sigreturn: not implemented\n"); return -TARGET_ENOSYS;}#elif defined(TARGET_ABI_MIPSO32)struct target_sigcontext { uint32_t sc_regmask; /* Unused */ uint32_t sc_status; uint64_t sc_pc; uint64_t sc_regs[32]; uint64_t sc_fpregs[32]; uint32_t sc_ownedfp; /* Unused */ uint32_t sc_fpc_csr; uint32_t sc_fpc_eir; /* Unused */ uint32_t sc_used_math; uint32_t sc_dsp; /* dsp status, was sc_ssflags */ uint64_t sc_mdhi; uint64_t sc_mdlo; target_ulong sc_hi1; /* Was sc_cause */ target_ulong sc_lo1; /* Was sc_badvaddr */ target_ulong sc_hi2; /* Was sc_sigset[4] */ target_ulong sc_lo2; target_ulong sc_hi3; target_ulong sc_lo3;};struct sigframe { uint32_t sf_ass[4]; /* argument save space for o32 */ uint32_t sf_code[2]; /* signal trampoline */ struct target_sigcontext sf_sc; target_sigset_t sf_mask;};/* Install trampoline to jump back from signal handler */static inline int install_sigtramp(unsigned int *tramp, unsigned int syscall){ int err; /* * Set up the return code ... * * li v0, __NR__foo_sigreturn * syscall */ err = __put_user(0x24020000 + syscall, tramp + 0); err |= __put_user(0x0000000c , tramp + 1); /* flush_cache_sigtramp((unsigned long) tramp); */ return err;}static inline intsetup_sigcontext(CPUState *regs, struct target_sigcontext *sc){ int err = 0; err |= __put_user(regs->PC[regs->current_tc], &sc->sc_pc);#define save_gp_reg(i) do { \ err |= __put_user(regs->gpr[i][regs->current_tc], &sc->sc_regs[i]); \ } while(0) __put_user(0, &sc->sc_regs[0]); save_gp_reg(1); save_gp_reg(2); save_gp_reg(3); save_gp_reg(4); save_gp_reg(5); save_gp_reg(6); save_gp_reg(7); save_gp_reg(8); save_gp_reg(9); save_gp_reg(10); save_gp_reg(11); save_gp_reg(12); save_gp_reg(13); save_gp_reg(14); save_gp_reg(15); save_gp_reg(16); save_gp_reg(17); save_gp_reg(18); save_gp_reg(19); save_gp_reg(20); save_gp_reg(21); save_gp_reg(22); save_gp_reg(23); save_gp_reg(24); save_gp_reg(25); save_gp_reg(26); save_gp_reg(27); save_gp_reg(28); save_gp_reg(29); save_gp_reg(30); save_gp_reg(31);#undef save_gp_reg err |= __put_user(regs->HI[0][regs->current_tc], &sc->sc_mdhi); err |= __put_user(regs->LO[0][regs->current_tc], &sc->sc_mdlo); /* Not used yet, but might be useful if we ever have DSP suppport */#if 0 if (cpu_has_dsp) { err |= __put_user(mfhi1(), &sc->sc_hi1); err |= __put_user(mflo1(), &sc->sc_lo1); err |= __put_user(mfhi2(), &sc->sc_hi2); err |= __put_user(mflo2(), &sc->sc_lo2); err |= __put_user(mfhi3(), &sc->sc_hi3); err |= __put_user(mflo3(), &sc->sc_lo3); err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp); } /* same with 64 bit */#ifdef CONFIG_64BIT err |= __put_user(regs->hi, &sc->sc_hi[0]); err |= __put_user(regs->lo, &sc->sc_lo[0]); if (cpu_has_dsp) { err |= __put_user(mfhi1(), &sc->sc_hi[1]); err |= __put_user(mflo1(), &sc->sc_lo[1]); err |= __put_user(mfhi2(), &sc->sc_hi[2]); err |= __put_user(mflo2(), &sc->sc_lo[2]); err |= __put_user(mfhi3(), &sc->sc_hi[3]); err |= __put_user(mflo3(), &sc->sc_lo[3]); err |= __put_user(rddsp(DSP_MASK), &sc->sc_dsp); }#endif#endif#if 0 err |= __put_user(!!used_math(), &sc->sc_used_math); if (!used_math()) goto out; /* * Save FPU state to signal context. Signal handler will "inherit" * current FPU state. */ preempt_disable(); if (!is_fpu_owner()) { own_fpu(); restore_fp(current); } err |= save_fp_context(sc); preempt_enable(); out:#endif return err;}static inline intrestore_sigcontext(CPUState *regs, struct target_sigcontext *sc){ int err = 0; err |= __get_user(regs->CP0_EPC, &sc->sc_pc); err |= __get_user(regs->HI[0][regs->current_tc], &sc->sc_mdhi); err |= __get_user(regs->LO[0][regs->current_tc], &sc->sc_mdlo);#define restore_gp_reg(i) do { \ err |= _
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -