signal.c
来自「xen虚拟机源代码安装包」· C语言 代码 · 共 2,221 行 · 第 1/5 页
C
2,221 行
val32 = 0x91d02010; err |= __put_user(val32, &sf->insns[1]); if (err) goto sigsegv; /* Flush instruction space. */ //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); // tb_flush(env); } unlock_user(sf, sf_addr, sizeof(struct target_signal_frame)); return;#if 0sigill_and_return: force_sig(TARGET_SIGILL);#endifsigsegv: //fprintf(stderr, "force_sig\n"); unlock_user(sf, sf_addr, sizeof(struct target_signal_frame)); force_sig(TARGET_SIGSEGV);}static inline intrestore_fpu_state(CPUState *env, qemu_siginfo_fpu_t *fpu){ int err;#if 0#ifdef CONFIG_SMP if (current->flags & PF_USEDFPU) regs->psr &= ~PSR_EF;#else if (current == last_task_used_math) { last_task_used_math = 0; regs->psr &= ~PSR_EF; }#endif current->used_math = 1; current->flags &= ~PF_USEDFPU;#endif#if 0 if (verify_area (VERIFY_READ, fpu, sizeof(*fpu))) return -EFAULT;#endif#if 0 /* XXX: incorrect */ err = __copy_from_user(&env->fpr[0], &fpu->si_float_regs[0], (sizeof(unsigned long) * 32));#endif err |= __get_user(env->fsr, &fpu->si_fsr);#if 0 err |= __get_user(current->thread.fpqdepth, &fpu->si_fpqdepth); if (current->thread.fpqdepth != 0) err |= __copy_from_user(¤t->thread.fpqueue[0], &fpu->si_fpqueue[0], ((sizeof(unsigned long) + (sizeof(unsigned long *)))*16));#endif return err;}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){ abi_ulong sf_addr; struct target_signal_frame *sf; uint32_t up_psr, pc, npc; target_sigset_t set; sigset_t host_set; abi_ulong fpu_save_addr; int err, i; sf_addr = env->regwptr[UREG_FP]; if (!lock_user_struct(VERIFY_READ, sf, sf_addr, 1)) goto segv_and_exit;#if 0 fprintf(stderr, "sigreturn\n"); fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);#endif //cpu_dump_state(env, stderr, fprintf, 0); /* 1. Make sure we are not getting garbage from the user */ if (sf_addr & 3) goto segv_and_exit; err = __get_user(pc, &sf->info.si_regs.pc); err |= __get_user(npc, &sf->info.si_regs.npc); if ((pc | npc) & 3) goto segv_and_exit; /* 2. Restore the state */ err |= __get_user(up_psr, &sf->info.si_regs.psr); /* User can only change condition codes and FPU enabling in %psr. */ env->psr = (up_psr & (PSR_ICC /* | PSR_EF */)) | (env->psr & ~(PSR_ICC /* | PSR_EF */)); env->pc = pc; env->npc = npc; err |= __get_user(env->y, &sf->info.si_regs.y); for (i=0; i < 8; i++) { err |= __get_user(env->gregs[i], &sf->info.si_regs.u_regs[i]); } for (i=0; i < 8; i++) { err |= __get_user(env->regwptr[i + UREG_I0], &sf->info.si_regs.u_regs[i+8]); } err |= __get_user(fpu_save_addr, &sf->fpu_save); //if (fpu_save) // err |= restore_fpu_state(env, fpu_save); /* This is pretty much atomic, no amount locking would prevent * the races which exist anyways. */ err |= __get_user(set.sig[0], &sf->info.si_mask); for(i = 1; i < TARGET_NSIG_WORDS; i++) { err |= (__get_user(set.sig[i], &sf->extramask[i - 1])); } target_to_host_sigset_internal(&host_set, &set); sigprocmask(SIG_SETMASK, &host_set, NULL); if (err) goto segv_and_exit; unlock_user_struct(sf, sf_addr, 0); return env->regwptr[0];segv_and_exit: unlock_user_struct(sf, sf_addr, 0); force_sig(TARGET_SIGSEGV);}long do_rt_sigreturn(CPUState *env){ fprintf(stderr, "do_rt_sigreturn: not implemented\n"); return -TARGET_ENOSYS;}#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)#define MC_TSTATE 0#define MC_PC 1#define MC_NPC 2#define MC_Y 3#define MC_G1 4#define MC_G2 5#define MC_G3 6#define MC_G4 7#define MC_G5 8#define MC_G6 9#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 im
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?