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

📄 signal.c

📁 qemu虚拟机代码
💻 C
📖 第 1 页 / 共 4 页
字号:
        oact->sa_restorer = tswapl(k->sa.sa_restorer);        oact->sa_mask = k->sa.sa_mask;    }    if (act) {        k->sa._sa_handler = tswapl(act->_sa_handler);        k->sa.sa_flags = tswapl(act->sa_flags);        k->sa.sa_restorer = tswapl(act->sa_restorer);        k->sa.sa_mask = act->sa_mask;        /* we update the host linux signal state */        host_sig = target_to_host_signal(sig);        if (host_sig != SIGSEGV && host_sig != SIGBUS) {            sigfillset(&act1.sa_mask);            act1.sa_flags = SA_SIGINFO;            if (k->sa.sa_flags & TARGET_SA_RESTART)                act1.sa_flags |= SA_RESTART;            /* NOTE: it is important to update the host kernel signal               ignore state to avoid getting unexpected interrupted               syscalls */            if (k->sa._sa_handler == TARGET_SIG_IGN) {                act1.sa_sigaction = (void *)SIG_IGN;            } else if (k->sa._sa_handler == TARGET_SIG_DFL) {                act1.sa_sigaction = (void *)SIG_DFL;            } else {                act1.sa_sigaction = host_signal_handler;            }            sigaction(host_sig, &act1, NULL);        }    }    return 0;}#ifndef offsetof#define offsetof(type, field) ((size_t) &((type *)0)->field)#endifstatic inline int copy_siginfo_to_user(target_siginfo_t *tinfo,                                        const target_siginfo_t *info){    tswap_siginfo(tinfo, info);    return 0;}#ifdef TARGET_I386/* from the Linux kernel */struct target_fpreg {	uint16_t significand[4];	uint16_t exponent;};struct target_fpxreg {	uint16_t significand[4];	uint16_t exponent;	uint16_t padding[3];};struct target_xmmreg {	target_ulong element[4];};struct target_fpstate {	/* Regular FPU environment */	target_ulong 	cw;	target_ulong	sw;	target_ulong	tag;	target_ulong	ipoff;	target_ulong	cssel;	target_ulong	dataoff;	target_ulong	datasel;	struct target_fpreg	_st[8];	uint16_t	status;	uint16_t	magic;		/* 0xffff = regular FPU data only */	/* FXSR FPU environment */	target_ulong	_fxsr_env[6];	/* FXSR FPU env is ignored */	target_ulong	mxcsr;	target_ulong	reserved;	struct target_fpxreg	_fxsr_st[8];	/* FXSR FPU reg data is ignored */	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){

⌨️ 快捷键说明

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