⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 signal.c

📁 qemu性能直逼VMware的仿真器QEMU 的模擬速度約為實機的 25%;約為 Bochs 的 60 倍。Plex86、User-Mode-Linux、VMware 和 Virtual PC 則比
💻 C
📖 第 1 页 / 共 4 页
字号:
}static intsetup_return(CPUState *env, struct emulated_sigaction *ka,	     target_ulong *rc, void *frame, int usig){	target_ulong handler = (target_ulong)ka->sa._sa_handler;	target_ulong retcode;	int thumb = 0;#if defined(TARGET_CONFIG_CPU_32)#if 0	target_ulong cpsr = env->cpsr;	/*	 * Maybe we need to deliver a 32-bit signal to a 26-bit task.	 */	if (ka->sa.sa_flags & SA_THIRTYTWO)		cpsr = (cpsr & ~MODE_MASK) | USR_MODE;#ifdef CONFIG_ARM_THUMB	if (elf_hwcap & HWCAP_THUMB) {		/*		 * The LSB of the handler determines if we're going to		 * be using THUMB or ARM mode for this signal handler.		 */		thumb = handler & 1;		if (thumb)			cpsr |= T_BIT;		else			cpsr &= ~T_BIT;	}#endif#endif#endif /* TARGET_CONFIG_CPU_32 */	if (ka->sa.sa_flags & TARGET_SA_RESTORER) {		retcode = (target_ulong)ka->sa.sa_restorer;	} else {		unsigned int idx = thumb;		if (ka->sa.sa_flags & TARGET_SA_SIGINFO)			idx += 2;		if (__put_user(retcodes[idx], rc))			return 1;#if 0		flush_icache_range((target_ulong)rc,				   (target_ulong)(rc + 1));#endif		retcode = ((target_ulong)rc) + thumb;	}	env->regs[0] = usig;	env->regs[13] = h2g(frame);	env->regs[14] = retcode;	env->regs[15] = handler & (thumb ? ~1 : ~3);#if 0#ifdef TARGET_CONFIG_CPU_32	env->cpsr = cpsr;#endif#endif	return 0;}static void setup_frame(int usig, struct emulated_sigaction *ka,			target_sigset_t *set, CPUState *regs){	struct sigframe *frame = get_sigframe(ka, regs, sizeof(*frame));	int i, err = 0;	err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]);        for(i = 1; i < TARGET_NSIG_WORDS; i++) {            if (__put_user(set->sig[i], &frame->extramask[i - 1]))                return;	}	if (err == 0)            err = setup_return(regs, ka, &frame->retcode, frame, usig);        //	return err;}static void setup_rt_frame(int usig, struct emulated_sigaction *ka,                            target_siginfo_t *info,			   target_sigset_t *set, CPUState *env){	struct rt_sigframe *frame = get_sigframe(ka, env, sizeof(*frame));	int i, err = 0;	if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame)))            return /* 1 */;	__put_user_error(&frame->info, (target_ulong *)&frame->pinfo, err);	__put_user_error(&frame->uc, (target_ulong *)&frame->puc, err);	err |= copy_siginfo_to_user(&frame->info, info);	/* Clear all the bits of the ucontext we don't use.  */	memset(&frame->uc, 0, offsetof(struct target_ucontext, tuc_mcontext));	err |= setup_sigcontext(&frame->uc.tuc_mcontext, /*&frame->fpstate,*/				env, set->sig[0]);        for(i = 0; i < TARGET_NSIG_WORDS; i++) {            if (__put_user(set->sig[i], &frame->uc.tuc_sigmask.sig[i]))                return;        }	if (err == 0)		err = setup_return(env, ka, &frame->retcode, frame, usig);	if (err == 0) {		/*		 * For realtime signals we must also set the second and third		 * arguments for the signal handler.		 *   -- Peter Maydell <pmaydell@chiark.greenend.org.uk> 2000-12-06		 */            env->regs[1] = (target_ulong)frame->pinfo;            env->regs[2] = (target_ulong)frame->puc;	}        //	return err;}static intrestore_sigcontext(CPUState *env, struct target_sigcontext *sc){	int err = 0;        uint32_t cpsr;	__get_user_error(env->regs[0], &sc->arm_r0, err);	__get_user_error(env->regs[1], &sc->arm_r1, err);	__get_user_error(env->regs[2], &sc->arm_r2, err);	__get_user_error(env->regs[3], &sc->arm_r3, err);	__get_user_error(env->regs[4], &sc->arm_r4, err);	__get_user_error(env->regs[5], &sc->arm_r5, err);	__get_user_error(env->regs[6], &sc->arm_r6, err);	__get_user_error(env->regs[7], &sc->arm_r7, err);	__get_user_error(env->regs[8], &sc->arm_r8, err);	__get_user_error(env->regs[9], &sc->arm_r9, err);	__get_user_error(env->regs[10], &sc->arm_r10, err);	__get_user_error(env->regs[11], &sc->arm_fp, err);	__get_user_error(env->regs[12], &sc->arm_ip, err);	__get_user_error(env->regs[13], &sc->arm_sp, err);	__get_user_error(env->regs[14], &sc->arm_lr, err);	__get_user_error(env->regs[15], &sc->arm_pc, err);#ifdef TARGET_CONFIG_CPU_32	__get_user_error(cpsr, &sc->arm_cpsr, err);        cpsr_write(env, cpsr, 0xffffffff);#endif	err |= !valid_user_regs(env);	return err;}long do_sigreturn(CPUState *env){	struct sigframe *frame;	target_sigset_t set;        sigset_t host_set;        int i;	/*	 * Since we stacked the signal on a 64-bit boundary,	 * then 'sp' should be word aligned here.  If it's	 * not, then the user is trying to mess with us.	 */	if (env->regs[13] & 7)		goto badframe;	frame = (struct sigframe *)g2h(env->regs[13]);#if 0	if (verify_area(VERIFY_READ, frame, sizeof (*frame)))		goto badframe;#endif	if (__get_user(set.sig[0], &frame->sc.oldmask))            goto badframe;        for(i = 1; i < TARGET_NSIG_WORDS; i++) {            if (__get_user(set.sig[i], &frame->extramask[i - 1]))                goto badframe;        }        target_to_host_sigset_internal(&host_set, &set);        sigprocmask(SIG_SETMASK, &host_set, NULL);	if (restore_sigcontext(env, &frame->sc))		goto badframe;#if 0	/* Send SIGTRAP if we're single-stepping */	if (ptrace_cancel_bpt(current))		send_sig(SIGTRAP, current, 1);#endif	return env->regs[0];badframe:        force_sig(SIGSEGV /* , current */);	return 0;}long do_rt_sigreturn(CPUState *env){	struct rt_sigframe *frame;        sigset_t host_set;	/*	 * Since we stacked the signal on a 64-bit boundary,	 * then 'sp' should be word aligned here.  If it's	 * not, then the user is trying to mess with us.	 */	if (env->regs[13] & 7)		goto badframe;	frame = (struct rt_sigframe *)env->regs[13];#if 0	if (verify_area(VERIFY_READ, frame, sizeof (*frame)))		goto badframe;#endif        target_to_host_sigset(&host_set, &frame->uc.tuc_sigmask);        sigprocmask(SIG_SETMASK, &host_set, NULL);	if (restore_sigcontext(env, &frame->uc.tuc_mcontext))		goto badframe;#if 0	/* Send SIGTRAP if we're single-stepping */	if (ptrace_cancel_bpt(current))		send_sig(SIGTRAP, current, 1);#endif	return env->regs[0];badframe:        force_sig(SIGSEGV /* , current */);	return 0;}#elif defined(TARGET_SPARC)#define __SUNOS_MAXWIN   31/* This is what SunOS does, so shall I. */struct target_sigcontext {        target_ulong sigc_onstack;      /* state to restore */        target_ulong sigc_mask;         /* sigmask to restore */        target_ulong sigc_sp;           /* stack pointer */        target_ulong sigc_pc;           /* program counter */        target_ulong sigc_npc;          /* next program counter */        target_ulong sigc_psr;          /* for condition codes etc */        target_ulong sigc_g1;           /* User uses these two registers */        target_ulong sigc_o0;           /* within the trampoline code. */        /* Now comes information regarding the users window set         * at the time of the signal.         */        target_ulong sigc_oswins;       /* outstanding windows */        /* stack ptrs for each regwin buf */        char *sigc_spbuf[__SUNOS_MAXWIN];        /* Windows to restore after signal */        struct {                target_ulong locals[8];                target_ulong ins[8];        } sigc_wbuf[__SUNOS_MAXWIN];};/* A Sparc stack frame */struct sparc_stackf {        target_ulong locals[8];        target_ulong ins[6];        struct sparc_stackf *fp;        target_ulong callers_pc;        char *structptr;        target_ulong xargs[6];        target_ulong xxargs[1];};typedef struct {        struct {                target_ulong psr;                target_ulong pc;                target_ulong npc;                target_ulong y;                target_ulong u_regs[16]; /* globals and ins */        }               si_regs;        int             si_mask;} __siginfo_t;typedef struct {        unsigned   long si_float_regs [32];        unsigned   long si_fsr;        unsigned   long si_fpqdepth;        struct {                unsigned long *insn_addr;                unsigned long insn;        } si_fpqueue [16];} qemu_siginfo_fpu_t;struct target_signal_frame {	struct sparc_stackf	ss;	__siginfo_t		info;	qemu_siginfo_fpu_t 	*fpu_save;	target_ulong		insns[2] __attribute__ ((aligned (8)));	target_ulong		extramask[TARGET_NSIG_WORDS - 1];	target_ulong		extra_size; /* Should be 0 */	qemu_siginfo_fpu_t	fpu_state;};struct target_rt_signal_frame {	struct sparc_stackf	ss;	siginfo_t		info;	target_ulong		regs[20];	sigset_t		mask;	qemu_siginfo_fpu_t 	*fpu_save;	unsigned int		insns[2];	stack_t			stack;	unsigned int		extra_size; /* Should be 0 */	qemu_siginfo_fpu_t	fpu_state;};#define UREG_O0        16#define UREG_O6        22#define UREG_I0        0#define UREG_I1        1#define UREG_I2        2#define UREG_I6        6#define UREG_I7        7#define UREG_L0	       8#define UREG_FP        UREG_I6#define UREG_SP        UREG_O6static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, unsigned long framesize){	unsigned long sp;	sp = env->regwptr[UREG_FP];#if 0	/* This is the X/Open sanctioned signal stack switching.  */	if (sa->sa_flags & TARGET_SA_ONSTACK) {		if (!on_sig_stack(sp) && !((current->sas_ss_sp + current->sas_ss_size) & 7))			sp = current->sas_ss_sp + current->sas_ss_size;	}#endif	return g2h(sp - framesize);}static intsetup___siginfo(__siginfo_t *si, CPUState *env, target_ulong mask){	int err = 0, i;	err |= __put_user(env->psr, &si->si_regs.psr);	err |= __put_user(env->pc, &si->si_regs.pc);	err |= __put_user(env->npc, &si->si_regs.npc);	err |= __put_user(env->y, &si->si_regs.y);	for (i=0; i < 8; i++) {		err |= __put_user(env->gregs[i], &si->si_regs.u_regs[i]);	}	for (i=0; i < 8; i++) {		err |= __put_user(env->regwptr[UREG_I0 + i], &si->si_regs.u_regs[i+8]);	}	err |= __put_user(mask, &si->si_mask);	return err;}#if 0static intsetup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/		 CPUState *env, unsigned long mask){	int err = 0;	err |= __put_user(mask, &sc->sigc_mask);	err |= __put_user(env->regwptr[UREG_SP], &sc->sigc_sp);	err |= __put_user(env->pc, &sc->sigc_pc);	err |= __put_user(env->npc, &sc->sigc_npc);	err |= __put_user(env->psr, &sc->sigc_psr);	err |= __put_user(env->gregs[1], &sc->sigc_g1);	err |= __put_user(env->regwptr[UREG_O0], &sc->sigc_o0);	return err;}#endif#define NF_ALIGNEDSZ  (((sizeof(struct target_signal_frame) + 7) & (~7)))static void setup_frame(int sig, struct emulated_sigaction *ka,			target_sigset_t *set, CPUState *env){	struct target_signal_frame *sf;	int sigframe_size, err, i;	/* 1. Make sure everything is clean */	//synchronize_user_stack();        sigframe_size = NF_ALIGNEDSZ;	sf = (struct target_signal_frame *)		get_sigframe(ka, env, sigframe_size);	//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 (invalid_frame_pointer(sf, sigframe_size))		goto sigill_and_return;#endif	/* 2. Save the current process state */	err = setup___siginfo(&sf->info, env, set->sig[0]);	err |= __put_user(0, &sf->extra_size);	//err |= save_fpu_state(regs, &sf->fpu_state);	//err |= __put_user(&sf->fpu_state, &sf->fpu_save);	err |= __put_user(set->sig[0], &sf->info.si_mask);	for (i = 0; i < TARGET_NSIG_WORDS - 1; i++) {		err |= __put_user(set->sig[i + 1], &sf->extramask[i]);	}	for (i = 0; i < 8; i++) {	  	err |= __put_user(env->regwptr[i + UREG_L0], &sf->ss.locals[i]);	}	for (i = 0; i < 8; i++) {	  	err |= __put_user(env->regwptr[i + UREG_I0], &sf->ss.ins[i]);	}	if (err)		goto sigsegv;	/* 3. signal handler back-trampoline and parameters */	env->regwptr[UREG_FP] = h2g(sf);	env->regwptr[UREG_I0] = sig;	env->regwptr[UREG_I1] = h2g(&sf->info);	env->regwptr[UREG_I2] = h2g(&sf->info);	/* 4. signal handler */	env->pc = (unsigned long) ka->sa._sa_handler;	env->npc = (env->pc + 4);	/* 5. return to kernel instructions */	if (ka->sa.sa_restorer)		env->regwptr[UREG_I7] = (unsigned long)ka->sa.sa_restorer;	else {		env->regwptr[UREG_I7] = h2g(&(sf->insns[0]) - 2);		/* mov __NR_sigreturn, %g1 */		err |= __put_user(0x821020d8, &sf->insns[0]);		/* t 0x10 */		err |= __put_user(0x91d02010, &sf->insns[1]);		if (err)			goto sigsegv;		/* Flush instruction space. */		//flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));                //		tb_flush(env);	}	return;        //sigill_and_return:	force_sig(TARGET_SIGILL);sigsegv:	//fprintf(stderr, "force_sig\n");	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){        struct target_signal_frame *sf;        uint32_t up_psr, pc, npc;        target_sigset_t set;        sigset_t host_set;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -