signal32.c

来自「LINUX 2.6.17.4的源码」· C语言 代码 · 共 501 行 · 第 1/2 页

C
501
字号
	DBG(2,"restore_sigcontext32: upper_half & sar = %#lx\n", compat_regt);		DBG(2,"restore_sigcontext32: sar is %#lx\n", regs->sar);			DBG(2,"restore_sigcontext32: r28 is %ld\n", regs->gr[28]);		return err;}/* * Set up the sigcontext structure for this process. * This is not an easy task if the kernel is 64-bit, it will require * that we examine the process personality to determine if we need to * truncate for a 32-bit userspace. */longsetup_sigcontext32(struct compat_sigcontext __user *sc, struct compat_regfile __user * rf, 		struct pt_regs *regs, int in_syscall)		 {	compat_int_t flags = 0;	long err = 0;	compat_uint_t compat_reg;	compat_uint_t compat_regb;	int regn;		if (on_sig_stack((unsigned long) sc))		flags |= PARISC_SC_FLAG_ONSTACK;		if (in_syscall) {				DBG(1,"setup_sigcontext32: in_syscall\n");				flags |= PARISC_SC_FLAG_IN_SYSCALL;		/* Truncate gr31 */		compat_reg = (compat_uint_t)(regs->gr[31]);		/* regs->iaoq is undefined in the syscall return path */		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",				&sc->sc_iaoq[0], compat_reg);				/* Store upper half */		compat_reg = (compat_uint_t)(regs->gr[32] >> 32);		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);		DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);						compat_reg = (compat_uint_t)(regs->gr[31]+4);		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",				&sc->sc_iaoq[1], compat_reg);		/* Store upper half */		compat_reg = (compat_uint_t)((regs->gr[32]+4) >> 32);		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);				/* Truncate sr3 */		compat_reg = (compat_uint_t)(regs->sr[3]);		err |= __put_user(compat_reg, &sc->sc_iasq[0]);		err |= __put_user(compat_reg, &sc->sc_iasq[1]);						/* Store upper half */		compat_reg = (compat_uint_t)(regs->sr[3] >> 32);		err |= __put_user(compat_reg, &rf->rf_iasq[0]);		err |= __put_user(compat_reg, &rf->rf_iasq[1]);						DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);				DBG(1,"setup_sigcontext32: iaoq %#lx / %#lx\n",							regs->gr[31], regs->gr[31]+4);			} else {				compat_reg = (compat_uint_t)(regs->iaoq[0]);		err |= __put_user(compat_reg, &sc->sc_iaoq[0]);		DBG(2,"setup_sigcontext32: sc->sc_iaoq[0] = %p <= %#x\n",				&sc->sc_iaoq[0], compat_reg);		/* Store upper half */		compat_reg = (compat_uint_t)(regs->iaoq[0] >> 32);		err |= __put_user(compat_reg, &rf->rf_iaoq[0]);			DBG(2,"setup_sigcontext32: upper half iaoq[0] = %#x\n", compat_reg);				compat_reg = (compat_uint_t)(regs->iaoq[1]);		err |= __put_user(compat_reg, &sc->sc_iaoq[1]);		DBG(2,"setup_sigcontext32: sc->sc_iaoq[1] = %p <= %#x\n",				&sc->sc_iaoq[1], compat_reg);		/* Store upper half */		compat_reg = (compat_uint_t)(regs->iaoq[1] >> 32);		err |= __put_user(compat_reg, &rf->rf_iaoq[1]);		DBG(2,"setup_sigcontext32: upper half iaoq[1] = %#x\n", compat_reg);						compat_reg = (compat_uint_t)(regs->iasq[0]);		err |= __put_user(compat_reg, &sc->sc_iasq[0]);		DBG(2,"setup_sigcontext32: sc->sc_iasq[0] = %p <= %#x\n",				&sc->sc_iasq[0], compat_reg);		/* Store upper half */		compat_reg = (compat_uint_t)(regs->iasq[0] >> 32);		err |= __put_user(compat_reg, &rf->rf_iasq[0]);		DBG(2,"setup_sigcontext32: upper half iasq[0] = %#x\n", compat_reg);						compat_reg = (compat_uint_t)(regs->iasq[1]);		err |= __put_user(compat_reg, &sc->sc_iasq[1]);		DBG(2,"setup_sigcontext32: sc->sc_iasq[1] = %p <= %#x\n",				&sc->sc_iasq[1], compat_reg);		/* Store upper half */		compat_reg = (compat_uint_t)(regs->iasq[1] >> 32);		err |= __put_user(compat_reg, &rf->rf_iasq[1]);		DBG(2,"setup_sigcontext32: upper half iasq[1] = %#x\n", compat_reg);		/* Print out the IAOQ for debugging */				DBG(1,"setup_sigcontext32: ia0q %#lx / %#lx\n", 			regs->iaoq[0], regs->iaoq[1]);	}	err |= __put_user(flags, &sc->sc_flags);		DBG(1,"setup_sigcontext32: Truncating general registers.\n");		for(regn=0; regn < 32; regn++){		/* Truncate a general register */		compat_reg = (compat_uint_t)(regs->gr[regn]);		err |= __put_user(compat_reg, &sc->sc_gr[regn]);		/* Store upper half */		compat_regb = (compat_uint_t)(regs->gr[regn] >> 32);		err |= __put_user(compat_regb, &rf->rf_gr[regn]);		/* DEBUG: Write out the "upper / lower" register data */		DBG(2,"setup_sigcontext32: gr%02d = %#x / %#x\n", regn, 				compat_regb, compat_reg);	}		/* Copy the floating point registers (same size)	   XXX: BE WARNED FR's are 64-BIT! */		DBG(1,"setup_sigcontext32: Copying from regs to sc, "	      "sc->sc_fr size = %#lx, regs->fr size = %#lx\n",		sizeof(regs->fr), sizeof(sc->sc_fr));	err |= __copy_to_user(sc->sc_fr, regs->fr, sizeof(regs->fr));	compat_reg = (compat_uint_t)(regs->sar);	err |= __put_user(compat_reg, &sc->sc_sar);	DBG(2,"setup_sigcontext32: sar is %#x\n", compat_reg);	/* Store upper half */	compat_reg = (compat_uint_t)(regs->sar >> 32);	err |= __put_user(compat_reg, &rf->rf_sar);		DBG(2,"setup_sigcontext32: upper half sar = %#x\n", compat_reg);	DBG(1,"setup_sigcontext32: r28 is %ld\n", regs->gr[28]);	return err;}intcopy_siginfo_from_user32 (siginfo_t *to, compat_siginfo_t __user *from){	unsigned long tmp;	int err;	if (!access_ok(VERIFY_READ, from, sizeof(compat_siginfo_t)))		return -EFAULT;	err = __get_user(to->si_signo, &from->si_signo);	err |= __get_user(to->si_errno, &from->si_errno);	err |= __get_user(to->si_code, &from->si_code);	if (to->si_code < 0)		err |= __copy_from_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);	else {		switch (to->si_code >> 16) {		      case __SI_CHLD >> 16:			err |= __get_user(to->si_utime, &from->si_utime);			err |= __get_user(to->si_stime, &from->si_stime);			err |= __get_user(to->si_status, &from->si_status);		      default:			err |= __get_user(to->si_pid, &from->si_pid);			err |= __get_user(to->si_uid, &from->si_uid);			break;		      case __SI_FAULT >> 16:			err |= __get_user(tmp, &from->si_addr);			to->si_addr = (void __user *) tmp;			break;		      case __SI_POLL >> 16:			err |= __get_user(to->si_band, &from->si_band);			err |= __get_user(to->si_fd, &from->si_fd);			break;		      case __SI_RT >> 16: /* This is not generated by the kernel as of now.  */		      case __SI_MESGQ >> 16:			err |= __get_user(to->si_pid, &from->si_pid);			err |= __get_user(to->si_uid, &from->si_uid);			err |= __get_user(to->si_int, &from->si_int);			break;		}	}	return err;}intcopy_siginfo_to_user32 (compat_siginfo_t __user *to, siginfo_t *from){	unsigned int addr;	int err;	if (!access_ok(VERIFY_WRITE, to, sizeof(compat_siginfo_t)))		return -EFAULT;	/* If you change siginfo_t structure, please be sure	   this code is fixed accordingly.	   It should never copy any pad contained in the structure	   to avoid security leaks, but must copy the generic	   3 ints plus the relevant union member.	   This routine must convert siginfo from 64bit to 32bit as well	   at the same time.  */	err = __put_user(from->si_signo, &to->si_signo);	err |= __put_user(from->si_errno, &to->si_errno);	err |= __put_user((short)from->si_code, &to->si_code);	if (from->si_code < 0)		err |= __copy_to_user(&to->_sifields._pad, &from->_sifields._pad, SI_PAD_SIZE);	else {		switch (from->si_code >> 16) {		case __SI_CHLD >> 16:			err |= __put_user(from->si_utime, &to->si_utime);			err |= __put_user(from->si_stime, &to->si_stime);			err |= __put_user(from->si_status, &to->si_status);		default:			err |= __put_user(from->si_pid, &to->si_pid);			err |= __put_user(from->si_uid, &to->si_uid);			break;		case __SI_FAULT >> 16:			/* avoid type-checking warnings by copying _pad[0] in lieu of si_addr... */			err |= __put_user(from->_sifields._pad[0], &to->si_addr);			break;		case __SI_POLL >> 16:			err |= __put_user(from->si_band, &to->si_band);			err |= __put_user(from->si_fd, &to->si_fd);			break;		case __SI_TIMER >> 16:			err |= __put_user(from->si_tid, &to->si_tid);			err |= __put_user(from->si_overrun, &to->si_overrun);			addr = (unsigned long) from->si_ptr;			err |= __put_user(addr, &to->si_ptr);			break;		case __SI_RT >> 16:	/* Not generated by the kernel as of now.  */		case __SI_MESGQ >> 16:			err |= __put_user(from->si_uid, &to->si_uid);			err |= __put_user(from->si_pid, &to->si_pid);			addr = (unsigned long) from->si_ptr;			err |= __put_user(addr, &to->si_ptr);			break;		}	}	return err;}

⌨️ 快捷键说明

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