signal.c

来自「xen虚拟机源代码安装包」· C语言 代码 · 共 2,221 行 · 第 1/5 页

C
2,221
字号
        setup_rt_frame_v1(usig, ka, info, set, env);    }}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, CPSR_USER | CPSR_EXEC);#endif	err |= !valid_user_regs(env);	return err;}long do_sigreturn_v1(CPUState *env){        abi_ulong frame_addr;	struct sigframe_v1 *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_addr = env->regs[13];	if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))                goto badframe;	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	unlock_user_struct(frame, frame_addr, 0);        return env->regs[0];badframe:	unlock_user_struct(frame, frame_addr, 0);        force_sig(SIGSEGV /* , current */);	return 0;}static int do_sigframe_return_v2(CPUState *env, target_ulong frame_addr,                                 struct target_ucontext_v2 *uc){    sigset_t host_set;    target_to_host_sigset(&host_set, &uc->tuc_sigmask);    sigprocmask(SIG_SETMASK, &host_set, NULL);    if (restore_sigcontext(env, &uc->tuc_mcontext))        return 1;    if (do_sigaltstack(frame_addr + offsetof(struct target_ucontext_v2, tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)        return 1;#if 0    /* Send SIGTRAP if we're single-stepping */    if (ptrace_cancel_bpt(current))            send_sig(SIGTRAP, current, 1);#endif    return 0;}long do_sigreturn_v2(CPUState *env){        abi_ulong frame_addr;	struct sigframe_v2 *frame;	/*	 * 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_addr = env->regs[13];	if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))                goto badframe;        if (do_sigframe_return_v2(env, frame_addr, &frame->uc))                goto badframe;	unlock_user_struct(frame, frame_addr, 0);	return env->regs[0];badframe:	unlock_user_struct(frame, frame_addr, 0);        force_sig(SIGSEGV /* , current */);	return 0;}long do_sigreturn(CPUState *env){    if (get_osversion() >= 0x020612) {        return do_sigreturn_v2(env);    } else {        return do_sigreturn_v1(env);    }}long do_rt_sigreturn_v1(CPUState *env){        abi_ulong frame_addr;	struct rt_sigframe_v1 *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_addr = env->regs[13];	if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))                goto badframe;        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 (do_sigaltstack(frame_addr + offsetof(struct rt_sigframe_v1, uc.tuc_stack), 0, get_sp_from_cpustate(env)) == -EFAULT)		goto badframe;#if 0	/* Send SIGTRAP if we're single-stepping */	if (ptrace_cancel_bpt(current))		send_sig(SIGTRAP, current, 1);#endif	unlock_user_struct(frame, frame_addr, 0);	return env->regs[0];badframe:	unlock_user_struct(frame, frame_addr, 0);        force_sig(SIGSEGV /* , current */);	return 0;}long do_rt_sigreturn_v2(CPUState *env){        abi_ulong frame_addr;	struct rt_sigframe_v2 *frame;	/*	 * 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_addr = env->regs[13];	if (!lock_user_struct(VERIFY_READ, frame, frame_addr, 1))                goto badframe;        if (do_sigframe_return_v2(env, frame_addr, &frame->uc))                goto badframe;	unlock_user_struct(frame, frame_addr, 0);	return env->regs[0];badframe:	unlock_user_struct(frame, frame_addr, 0);        force_sig(SIGSEGV /* , current */);	return 0;}long do_rt_sigreturn(CPUState *env){    if (get_osversion() >= 0x020612) {        return do_rt_sigreturn_v2(env);    } else {        return do_rt_sigreturn_v1(env);    }}#elif defined(TARGET_SPARC)#define __SUNOS_MAXWIN   31/* This is what SunOS does, so shall I. */struct target_sigcontext {        abi_ulong sigc_onstack;      /* state to restore */        abi_ulong sigc_mask;         /* sigmask to restore */        abi_ulong sigc_sp;           /* stack pointer */        abi_ulong sigc_pc;           /* program counter */        abi_ulong sigc_npc;          /* next program counter */        abi_ulong sigc_psr;          /* for condition codes etc */        abi_ulong sigc_g1;           /* User uses these two registers */        abi_ulong sigc_o0;           /* within the trampoline code. */        /* Now comes information regarding the users window set         * at the time of the signal.         */        abi_ulong sigc_oswins;       /* outstanding windows */        /* stack ptrs for each regwin buf */        char *sigc_spbuf[__SUNOS_MAXWIN];        /* Windows to restore after signal */        struct {                abi_ulong locals[8];                abi_ulong ins[8];        } sigc_wbuf[__SUNOS_MAXWIN];};/* A Sparc stack frame */struct sparc_stackf {        abi_ulong locals[8];        abi_ulong ins[6];        struct sparc_stackf *fp;        abi_ulong callers_pc;        char *structptr;        abi_ulong xargs[6];        abi_ulong xxargs[1];};typedef struct {        struct {                abi_ulong psr;                abi_ulong pc;                abi_ulong npc;                abi_ulong y;                abi_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;	abi_ulong               fpu_save;	abi_ulong		insns[2] __attribute__ ((aligned (8)));	abi_ulong		extramask[TARGET_NSIG_WORDS - 1];	abi_ulong		extra_size; /* Should be 0 */	qemu_siginfo_fpu_t	fpu_state;};struct target_rt_signal_frame {	struct sparc_stackf	ss;	siginfo_t		info;	abi_ulong		regs[20];	sigset_t		mask;	abi_ulong               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_I3        3#define UREG_I4        4#define UREG_I5        5#define UREG_I6        6#define UREG_I7        7#define UREG_L0	       8#define UREG_FP        UREG_I6#define UREG_SP        UREG_O6static inline abi_ulong get_sigframe(struct emulated_sigaction *sa,                                      CPUState *env, unsigned long framesize){	abi_ulong sp;	sp = env->regwptr[UREG_FP];	/* This is the X/Open sanctioned signal stack switching.  */	if (sa->sa.sa_flags & TARGET_SA_ONSTACK) {            if (!on_sig_stack(sp)                && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))                sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;	}	return sp - framesize;}static intsetup___siginfo(__siginfo_t *si, CPUState *env, abi_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){        abi_ulong sf_addr;	struct target_signal_frame *sf;	int sigframe_size, err, i;	/* 1. Make sure everything is clean */	//synchronize_user_stack();        sigframe_size = NF_ALIGNEDSZ;	sf_addr = get_sigframe(ka, env, sigframe_size);        sf = lock_user(VERIFY_WRITE, sf_addr,                        sizeof(struct target_signal_frame), 0);        if (!sf)		goto sigsegv;                	//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] = sf_addr;	env->regwptr[UREG_I0] = sig;	env->regwptr[UREG_I1] = sf_addr +                 offsetof(struct target_signal_frame, info);	env->regwptr[UREG_I2] = sf_addr +                 offsetof(struct target_signal_frame, info);	/* 4. signal handler */	env->pc = ka->sa._sa_handler;	env->npc = (env->pc + 4);	/* 5. return to kernel instructions */	if (ka->sa.sa_restorer)		env->regwptr[UREG_I7] = ka->sa.sa_restorer;	else {                uint32_t val32;		env->regwptr[UREG_I7] = sf_addr +                         offsetof(struct target_signal_frame, insns) - 2 * 4;		/* mov __NR_sigreturn, %g1 */                val32 = 0x821020d8;		err |= __put_user(val32, &sf->insns[0]);		/* t 0x10 */

⌨️ 快捷键说明

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