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

📄 signal.c

📁 qemu性能直逼VMware的仿真器QEMU 的模擬速度約為實機的 25%;約為 Bochs 的 60 倍。Plex86、User-Mode-Linux、VMware 和 Virtual PC 則比
💻 C
📖 第 1 页 / 共 4 页
字号:
	struct target_xmmreg	_xmm[8];	target_ulong	padding[56];};#define X86_FXSR_MAGIC		0x0000struct target_sigcontext {	uint16_t gs, __gsh;	uint16_t fs, __fsh;	uint16_t es, __esh;	uint16_t ds, __dsh;	target_ulong edi;	target_ulong esi;	target_ulong ebp;	target_ulong esp;	target_ulong ebx;	target_ulong edx;	target_ulong ecx;	target_ulong eax;	target_ulong trapno;	target_ulong err;	target_ulong eip;	uint16_t cs, __csh;	target_ulong eflags;	target_ulong esp_at_signal;	uint16_t ss, __ssh;        target_ulong fpstate; /* pointer */	target_ulong oldmask;	target_ulong cr2;};typedef struct target_sigaltstack {	target_ulong ss_sp;	int ss_flags;	target_ulong ss_size;} target_stack_t;struct target_ucontext {        target_ulong	  tuc_flags;	target_ulong      tuc_link;	target_stack_t	  tuc_stack;	struct target_sigcontext tuc_mcontext;	target_sigset_t	  tuc_sigmask;	/* mask last for extensibility */};struct sigframe{    target_ulong pretcode;    int sig;    struct target_sigcontext sc;    struct target_fpstate fpstate;    target_ulong extramask[TARGET_NSIG_WORDS-1];    char retcode[8];};struct rt_sigframe{    target_ulong pretcode;    int sig;    target_ulong pinfo;    target_ulong puc;    struct target_siginfo info;    struct target_ucontext uc;    struct target_fpstate fpstate;    char retcode[8];};/* * Set up a signal frame. *//* XXX: save x87 state */static intsetup_sigcontext(struct target_sigcontext *sc, struct target_fpstate *fpstate,		 CPUX86State *env, unsigned long mask){	int err = 0;	err |= __put_user(env->segs[R_GS].selector, (unsigned int *)&sc->gs);	err |= __put_user(env->segs[R_FS].selector, (unsigned int *)&sc->fs);	err |= __put_user(env->segs[R_ES].selector, (unsigned int *)&sc->es);	err |= __put_user(env->segs[R_DS].selector, (unsigned int *)&sc->ds);	err |= __put_user(env->regs[R_EDI], &sc->edi);	err |= __put_user(env->regs[R_ESI], &sc->esi);	err |= __put_user(env->regs[R_EBP], &sc->ebp);	err |= __put_user(env->regs[R_ESP], &sc->esp);	err |= __put_user(env->regs[R_EBX], &sc->ebx);	err |= __put_user(env->regs[R_EDX], &sc->edx);	err |= __put_user(env->regs[R_ECX], &sc->ecx);	err |= __put_user(env->regs[R_EAX], &sc->eax);	err |= __put_user(env->exception_index, &sc->trapno);	err |= __put_user(env->error_code, &sc->err);	err |= __put_user(env->eip, &sc->eip);	err |= __put_user(env->segs[R_CS].selector, (unsigned int *)&sc->cs);	err |= __put_user(env->eflags, &sc->eflags);	err |= __put_user(env->regs[R_ESP], &sc->esp_at_signal);	err |= __put_user(env->segs[R_SS].selector, (unsigned int *)&sc->ss);        cpu_x86_fsave(env, (void *)fpstate, 1);        fpstate->status = fpstate->sw;        err |= __put_user(0xffff, &fpstate->magic);        err |= __put_user(fpstate, &sc->fpstate);	/* non-iBCS2 extensions.. */	err |= __put_user(mask, &sc->oldmask);	err |= __put_user(env->cr[2], &sc->cr2);	return err;}/* * Determine which stack to use.. */static inline void *get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size){	unsigned long esp;	/* Default to using normal stack */	esp = env->regs[R_ESP];#if 0	/* This is the X/Open sanctioned signal stack switching.  */	if (ka->sa.sa_flags & SA_ONSTACK) {		if (sas_ss_flags(esp) == 0)			esp = current->sas_ss_sp + current->sas_ss_size;	}	/* This is the legacy signal stack switching. */	else #endif        if ((env->segs[R_SS].selector & 0xffff) != __USER_DS &&            !(ka->sa.sa_flags & TARGET_SA_RESTORER) &&            ka->sa.sa_restorer) {            esp = (unsigned long) ka->sa.sa_restorer;	}        return g2h((esp - frame_size) & -8ul);}static void setup_frame(int sig, struct emulated_sigaction *ka,			target_sigset_t *set, CPUX86State *env){	struct sigframe *frame;	int i, err = 0;	frame = get_sigframe(ka, env, sizeof(*frame));	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))		goto give_sigsegv;	err |= __put_user((/*current->exec_domain		           && current->exec_domain->signal_invmap		           && sig < 32		           ? current->exec_domain->signal_invmap[sig]		           : */ sig),		          &frame->sig);	if (err)		goto give_sigsegv;	setup_sigcontext(&frame->sc, &frame->fpstate, env, set->sig[0]);	if (err)		goto give_sigsegv;        for(i = 1; i < TARGET_NSIG_WORDS; i++) {            if (__put_user(set->sig[i], &frame->extramask[i - 1]))                goto give_sigsegv;        }	/* Set up to return from userspace.  If provided, use a stub	   already in userspace.  */	if (ka->sa.sa_flags & TARGET_SA_RESTORER) {		err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);	} else {		err |= __put_user(frame->retcode, &frame->pretcode);		/* This is popl %eax ; movl $,%eax ; int $0x80 */		err |= __put_user(0xb858, (short *)(frame->retcode+0));		err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));		err |= __put_user(0x80cd, (short *)(frame->retcode+6));	}	if (err)		goto give_sigsegv;	/* Set up registers for signal handler */	env->regs[R_ESP] = h2g(frame);	env->eip = (unsigned long) ka->sa._sa_handler;        cpu_x86_load_seg(env, R_DS, __USER_DS);        cpu_x86_load_seg(env, R_ES, __USER_DS);        cpu_x86_load_seg(env, R_SS, __USER_DS);        cpu_x86_load_seg(env, R_CS, __USER_CS);	env->eflags &= ~TF_MASK;	return;give_sigsegv:	if (sig == TARGET_SIGSEGV)		ka->sa._sa_handler = TARGET_SIG_DFL;	force_sig(TARGET_SIGSEGV /* , current */);}static void setup_rt_frame(int sig, struct emulated_sigaction *ka,                            target_siginfo_t *info,			   target_sigset_t *set, CPUX86State *env){	struct rt_sigframe *frame;	int i, err = 0;	frame = get_sigframe(ka, env, sizeof(*frame));	if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))		goto give_sigsegv;	err |= __put_user((/*current->exec_domain		    	   && current->exec_domain->signal_invmap		    	   && sig < 32		    	   ? current->exec_domain->signal_invmap[sig]			   : */sig),			  &frame->sig);	err |= __put_user((target_ulong)&frame->info, &frame->pinfo);	err |= __put_user((target_ulong)&frame->uc, &frame->puc);	err |= copy_siginfo_to_user(&frame->info, info);	if (err)		goto give_sigsegv;	/* Create the ucontext.  */	err |= __put_user(0, &frame->uc.tuc_flags);	err |= __put_user(0, &frame->uc.tuc_link);	err |= __put_user(/*current->sas_ss_sp*/ 0,			  &frame->uc.tuc_stack.ss_sp);	err |= __put_user(/* sas_ss_flags(regs->esp) */ 0,			  &frame->uc.tuc_stack.ss_flags);	err |= __put_user(/* current->sas_ss_size */ 0,			  &frame->uc.tuc_stack.ss_size);	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]))                goto give_sigsegv;        }	/* Set up to return from userspace.  If provided, use a stub	   already in userspace.  */	if (ka->sa.sa_flags & TARGET_SA_RESTORER) {		err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);	} else {		err |= __put_user(frame->retcode, &frame->pretcode);		/* This is movl $,%eax ; int $0x80 */		err |= __put_user(0xb8, (char *)(frame->retcode+0));		err |= __put_user(TARGET_NR_rt_sigreturn, (int *)(frame->retcode+1));		err |= __put_user(0x80cd, (short *)(frame->retcode+5));	}	if (err)		goto give_sigsegv;	/* Set up registers for signal handler */	env->regs[R_ESP] = (unsigned long) frame;	env->eip = (unsigned long) ka->sa._sa_handler;        cpu_x86_load_seg(env, R_DS, __USER_DS);        cpu_x86_load_seg(env, R_ES, __USER_DS);        cpu_x86_load_seg(env, R_SS, __USER_DS);        cpu_x86_load_seg(env, R_CS, __USER_CS);	env->eflags &= ~TF_MASK;	return;give_sigsegv:	if (sig == TARGET_SIGSEGV)		ka->sa._sa_handler = TARGET_SIG_DFL;	force_sig(TARGET_SIGSEGV /* , current */);}static intrestore_sigcontext(CPUX86State *env, struct target_sigcontext *sc, int *peax){	unsigned int err = 0;        cpu_x86_load_seg(env, R_GS, lduw(&sc->gs));        cpu_x86_load_seg(env, R_FS, lduw(&sc->fs));        cpu_x86_load_seg(env, R_ES, lduw(&sc->es));        cpu_x86_load_seg(env, R_DS, lduw(&sc->ds));        env->regs[R_EDI] = ldl(&sc->edi);        env->regs[R_ESI] = ldl(&sc->esi);        env->regs[R_EBP] = ldl(&sc->ebp);        env->regs[R_ESP] = ldl(&sc->esp);        env->regs[R_EBX] = ldl(&sc->ebx);        env->regs[R_EDX] = ldl(&sc->edx);        env->regs[R_ECX] = ldl(&sc->ecx);        env->eip = ldl(&sc->eip);        cpu_x86_load_seg(env, R_CS, lduw(&sc->cs) | 3);        cpu_x86_load_seg(env, R_SS, lduw(&sc->ss) | 3);		{		unsigned int tmpflags;                tmpflags = ldl(&sc->eflags);		env->eflags = (env->eflags & ~0x40DD5) | (tmpflags & 0x40DD5);                //		regs->orig_eax = -1;		/* disable syscall checks */	}	{		struct _fpstate * buf;                buf = (void *)ldl(&sc->fpstate);		if (buf) {#if 0			if (verify_area(VERIFY_READ, buf, sizeof(*buf)))				goto badframe;#endif                        cpu_x86_frstor(env, (void *)buf, 1);		}	}        *peax = ldl(&sc->eax);	return err;#if 0badframe:	return 1;#endif}long do_sigreturn(CPUX86State *env){    struct sigframe *frame = (struct sigframe *)g2h(env->regs[R_ESP] - 8);    target_sigset_t target_set;    sigset_t set;    int eax, i;#if defined(DEBUG_SIGNAL)    fprintf(stderr, "do_sigreturn\n");#endif    /* set blocked signals */    if (__get_user(target_set.sig[0], &frame->sc.oldmask))        goto badframe;    for(i = 1; i < TARGET_NSIG_WORDS; i++) {        if (__get_user(target_set.sig[i], &frame->extramask[i - 1]))            goto badframe;    }    target_to_host_sigset_internal(&set, &target_set);    sigprocmask(SIG_SETMASK, &set, NULL);        /* restore registers */    if (restore_sigcontext(env, &frame->sc, &eax))        goto badframe;    return eax;badframe:    force_sig(TARGET_SIGSEGV);    return 0;}long do_rt_sigreturn(CPUX86State *env){	struct rt_sigframe *frame = (struct rt_sigframe *)g2h(env->regs[R_ESP] - 4);        sigset_t set;        //	stack_t st;	int eax;#if 0	if (verify_area(VERIFY_READ, frame, sizeof(*frame)))		goto badframe;#endif        target_to_host_sigset(&set, &frame->uc.tuc_sigmask);        sigprocmask(SIG_SETMASK, &set, NULL);		if (restore_sigcontext(env, &frame->uc.tuc_mcontext, &eax))		goto badframe;#if 0	if (__copy_from_user(&st, &frame->uc.tuc_stack, sizeof(st)))		goto badframe;	/* It is more difficult to avoid calling this function than to	   call it and ignore errors.  */	do_sigaltstack(&st, NULL, regs->esp);#endif	return eax;badframe:	force_sig(TARGET_SIGSEGV);	return 0;}#elif defined(TARGET_ARM)struct target_sigcontext {	target_ulong trap_no;	target_ulong error_code;	target_ulong oldmask;	target_ulong arm_r0;	target_ulong arm_r1;	target_ulong arm_r2;	target_ulong arm_r3;	target_ulong arm_r4;	target_ulong arm_r5;	target_ulong arm_r6;	target_ulong arm_r7;	target_ulong arm_r8;	target_ulong arm_r9;	target_ulong arm_r10;	target_ulong arm_fp;	target_ulong arm_ip;	target_ulong arm_sp;	target_ulong arm_lr;	target_ulong arm_pc;	target_ulong arm_cpsr;	target_ulong fault_address;};typedef struct target_sigaltstack {	target_ulong ss_sp;	int ss_flags;	target_ulong ss_size;} target_stack_t;struct target_ucontext {    target_ulong tuc_flags;    target_ulong tuc_link;    target_stack_t tuc_stack;    struct target_sigcontext tuc_mcontext;    target_sigset_t  tuc_sigmask;	/* mask last for extensibility */};struct sigframe{    struct target_sigcontext sc;    target_ulong extramask[TARGET_NSIG_WORDS-1];    target_ulong retcode;};struct rt_sigframe{    struct target_siginfo *pinfo;    void *puc;    struct target_siginfo info;    struct target_ucontext uc;    target_ulong retcode;};#define TARGET_CONFIG_CPU_32 1/* * For ARM syscalls, we encode the syscall number into the instruction. */#define SWI_SYS_SIGRETURN	(0xef000000|(TARGET_NR_sigreturn + ARM_SYSCALL_BASE))#define SWI_SYS_RT_SIGRETURN	(0xef000000|(TARGET_NR_rt_sigreturn + ARM_SYSCALL_BASE))/* * For Thumb syscalls, we pass the syscall number via r7.  We therefore * need two 16-bit instructions. */#define SWI_THUMB_SIGRETURN	(0xdf00 << 16 | 0x2700 | (TARGET_NR_sigreturn))#define SWI_THUMB_RT_SIGRETURN	(0xdf00 << 16 | 0x2700 | (TARGET_NR_rt_sigreturn))static const target_ulong retcodes[4] = {	SWI_SYS_SIGRETURN,	SWI_THUMB_SIGRETURN,	SWI_SYS_RT_SIGRETURN,	SWI_THUMB_RT_SIGRETURN};#define __put_user_error(x,p,e) __put_user(x, p)#define __get_user_error(x,p,e) __get_user(x, p)static inline int valid_user_regs(CPUState *regs){    return 1;}static intsetup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/		 CPUState *env, unsigned long mask){	int err = 0;	__put_user_error(env->regs[0], &sc->arm_r0, err);	__put_user_error(env->regs[1], &sc->arm_r1, err);	__put_user_error(env->regs[2], &sc->arm_r2, err);	__put_user_error(env->regs[3], &sc->arm_r3, err);	__put_user_error(env->regs[4], &sc->arm_r4, err);	__put_user_error(env->regs[5], &sc->arm_r5, err);	__put_user_error(env->regs[6], &sc->arm_r6, err);	__put_user_error(env->regs[7], &sc->arm_r7, err);	__put_user_error(env->regs[8], &sc->arm_r8, err);	__put_user_error(env->regs[9], &sc->arm_r9, err);	__put_user_error(env->regs[10], &sc->arm_r10, err);	__put_user_error(env->regs[11], &sc->arm_fp, err);	__put_user_error(env->regs[12], &sc->arm_ip, err);	__put_user_error(env->regs[13], &sc->arm_sp, err);	__put_user_error(env->regs[14], &sc->arm_lr, err);	__put_user_error(env->regs[15], &sc->arm_pc, err);#ifdef TARGET_CONFIG_CPU_32	__put_user_error(cpsr_read(env), &sc->arm_cpsr, err);#endif	__put_user_error(/* current->thread.trap_no */ 0, &sc->trap_no, err);	__put_user_error(/* current->thread.error_code */ 0, &sc->error_code, err);	__put_user_error(/* current->thread.address */ 0, &sc->fault_address, err);	__put_user_error(mask, &sc->oldmask, err);	return err;}static inline void *get_sigframe(struct emulated_sigaction *ka, CPUState *regs, int framesize){	unsigned long sp = regs->regs[13];#if 0	/*	 * This is the X/Open sanctioned signal stack switching.	 */	if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp))		sp = current->sas_ss_sp + current->sas_ss_size;#endif	/*	 * ATPCS B01 mandates 8-byte alignment	 */	return g2h((sp - framesize) & ~7);

⌨️ 快捷键说明

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