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(&current->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 + -
显示快捷键?