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

📄 sys_sparc32.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
	int ret;	mm_segment_t old_fs = get_fs();		if (copy_siginfo_from_user32(&info, uinfo))		return -EFAULT;	set_fs (KERNEL_DS);	ret = sys_rt_sigqueueinfo(pid, sig, (siginfo_t __user *) &info);	set_fs (old_fs);	return ret;}asmlinkage long compat_sys_sigaction(int sig, struct old_sigaction32 __user *act,				     struct old_sigaction32 __user *oact){        struct k_sigaction new_ka, old_ka;        int ret;	if (sig < 0) {		set_thread_flag(TIF_NEWSIGNALS);		sig = -sig;	}        if (act) {		compat_old_sigset_t mask;		u32 u_handler, u_restorer;				ret = get_user(u_handler, &act->sa_handler);		new_ka.sa.sa_handler =  compat_ptr(u_handler);		ret |= __get_user(u_restorer, &act->sa_restorer);		new_ka.sa.sa_restorer = compat_ptr(u_restorer);		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);		ret |= __get_user(mask, &act->sa_mask);		if (ret)			return ret;		new_ka.ka_restorer = NULL;		siginitset(&new_ka.sa.sa_mask, mask);        }        ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);	if (!ret && oact) {		ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler);		ret |= __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer);		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);		ret |= __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);        }	return ret;}asmlinkage long compat_sys_rt_sigaction(int sig,					struct sigaction32 __user *act,					struct sigaction32 __user *oact,					void __user *restorer,					compat_size_t sigsetsize){        struct k_sigaction new_ka, old_ka;        int ret;	compat_sigset_t set32;        /* XXX: Don't preclude handling different sized sigset_t's.  */        if (sigsetsize != sizeof(compat_sigset_t))                return -EINVAL;	/* All tasks which use RT signals (effectively) use	 * new style signals.	 */	set_thread_flag(TIF_NEWSIGNALS);        if (act) {		u32 u_handler, u_restorer;		new_ka.ka_restorer = restorer;		ret = get_user(u_handler, &act->sa_handler);		new_ka.sa.sa_handler =  compat_ptr(u_handler);		ret |= __copy_from_user(&set32, &act->sa_mask, sizeof(compat_sigset_t));		switch (_NSIG_WORDS) {		case 4: new_ka.sa.sa_mask.sig[3] = set32.sig[6] | (((long)set32.sig[7]) << 32);		case 3: new_ka.sa.sa_mask.sig[2] = set32.sig[4] | (((long)set32.sig[5]) << 32);		case 2: new_ka.sa.sa_mask.sig[1] = set32.sig[2] | (((long)set32.sig[3]) << 32);		case 1: new_ka.sa.sa_mask.sig[0] = set32.sig[0] | (((long)set32.sig[1]) << 32);		}		ret |= __get_user(new_ka.sa.sa_flags, &act->sa_flags);		ret |= __get_user(u_restorer, &act->sa_restorer);		new_ka.sa.sa_restorer = compat_ptr(u_restorer);                if (ret)                	return -EFAULT;	}	ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL);	if (!ret && oact) {		switch (_NSIG_WORDS) {		case 4: set32.sig[7] = (old_ka.sa.sa_mask.sig[3] >> 32); set32.sig[6] = old_ka.sa.sa_mask.sig[3];		case 3: set32.sig[5] = (old_ka.sa.sa_mask.sig[2] >> 32); set32.sig[4] = old_ka.sa.sa_mask.sig[2];		case 2: set32.sig[3] = (old_ka.sa.sa_mask.sig[1] >> 32); set32.sig[2] = old_ka.sa.sa_mask.sig[1];		case 1: set32.sig[1] = (old_ka.sa.sa_mask.sig[0] >> 32); set32.sig[0] = old_ka.sa.sa_mask.sig[0];		}		ret = put_user(ptr_to_compat(old_ka.sa.sa_handler), &oact->sa_handler);		ret |= __copy_to_user(&oact->sa_mask, &set32, sizeof(compat_sigset_t));		ret |= __put_user(old_ka.sa.sa_flags, &oact->sa_flags);		ret |= __put_user(ptr_to_compat(old_ka.sa.sa_restorer), &oact->sa_restorer);		if (ret)			ret = -EFAULT;        }        return ret;}/* * sparc32_execve() executes a new program after the asm stub has set * things up for us.  This should basically do what I want it to. */asmlinkage long sparc32_execve(struct pt_regs *regs){	int error, base = 0;	char *filename;	/* User register window flush is done by entry.S */	/* Check for indirect call. */	if ((u32)regs->u_regs[UREG_G1] == 0)		base = 1;	filename = getname(compat_ptr(regs->u_regs[base + UREG_I0]));	error = PTR_ERR(filename);	if (IS_ERR(filename))		goto out;	error = compat_do_execve(filename,				 compat_ptr(regs->u_regs[base + UREG_I1]),				 compat_ptr(regs->u_regs[base + UREG_I2]), regs);	putname(filename);	if (!error) {		fprs_write(0);		current_thread_info()->xfsr[0] = 0;		current_thread_info()->fpsaved[0] = 0;		regs->tstate &= ~TSTATE_PEF;		task_lock(current);		current->ptrace &= ~PT_DTRACE;		task_unlock(current);	}out:	return error;}#ifdef CONFIG_MODULESasmlinkage long sys32_init_module(void __user *umod, u32 len,				  const char __user *uargs){	return sys_init_module(umod, len, uargs);}asmlinkage long sys32_delete_module(const char __user *name_user,				    unsigned int flags){	return sys_delete_module(name_user, flags);}#else /* CONFIG_MODULES */asmlinkage long sys32_init_module(const char __user *name_user,				  struct module __user *mod_user){	return -ENOSYS;}asmlinkage long sys32_delete_module(const char __user *name_user){	return -ENOSYS;}#endif  /* CONFIG_MODULES *//* Translations due to time_t size differences.  Which affects all   sorts of things, like timeval and itimerval.  */extern struct timezone sys_tz;asmlinkage long sys32_gettimeofday(struct compat_timeval __user *tv,				   struct timezone __user *tz){	if (tv) {		struct timeval ktv;		do_gettimeofday(&ktv);		if (put_tv32(tv, &ktv))			return -EFAULT;	}	if (tz) {		if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))			return -EFAULT;	}	return 0;}static inline long get_ts32(struct timespec *o, struct compat_timeval __user *i){	long usec;	if (!access_ok(VERIFY_READ, i, sizeof(*i)))		return -EFAULT;	if (__get_user(o->tv_sec, &i->tv_sec))		return -EFAULT;	if (__get_user(usec, &i->tv_usec))		return -EFAULT;	o->tv_nsec = usec * 1000;	return 0;}asmlinkage long sys32_settimeofday(struct compat_timeval __user *tv,				   struct timezone __user *tz){	struct timespec kts;	struct timezone ktz; 	if (tv) {		if (get_ts32(&kts, tv))			return -EFAULT;	}	if (tz) {		if (copy_from_user(&ktz, tz, sizeof(ktz)))			return -EFAULT;	}	return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);}asmlinkage long sys32_utimes(char __user *filename,			     struct compat_timeval __user *tvs){	struct timeval ktvs[2];	if (tvs) {		if (get_tv32(&ktvs[0], tvs) ||		    get_tv32(&ktvs[1], 1+tvs))			return -EFAULT;	}	return do_utimes(filename, (tvs ? &ktvs[0] : NULL));}/* These are here just in case some old sparc32 binary calls it. */asmlinkage long sys32_pause(void){	current->state = TASK_INTERRUPTIBLE;	schedule();	return -ERESTARTNOHAND;}asmlinkage compat_ssize_t sys32_pread64(unsigned int fd,					char __user *ubuf,					compat_size_t count,					unsigned long poshi,					unsigned long poslo){	return sys_pread64(fd, ubuf, count, (poshi << 32) | poslo);}asmlinkage compat_ssize_t sys32_pwrite64(unsigned int fd,					 char __user *ubuf,					 compat_size_t count,					 unsigned long poshi,					 unsigned long poslo){	return sys_pwrite64(fd, ubuf, count, (poshi << 32) | poslo);}asmlinkage long compat_sys_readahead(int fd,				     unsigned long offhi,				     unsigned long offlo,				     compat_size_t count){	return sys_readahead(fd, (offhi << 32) | offlo, count);}long compat_sys_fadvise64(int fd,			  unsigned long offhi,			  unsigned long offlo,			  compat_size_t len, int advice){	return sys_fadvise64_64(fd, (offhi << 32) | offlo, len, advice);}long compat_sys_fadvise64_64(int fd,			     unsigned long offhi, unsigned long offlo,			     unsigned long lenhi, unsigned long lenlo,			     int advice){	return sys_fadvise64_64(fd,				(offhi << 32) | offlo,				(lenhi << 32) | lenlo,				advice);}asmlinkage long compat_sys_sendfile(int out_fd, int in_fd,				    compat_off_t __user *offset,				    compat_size_t count){	mm_segment_t old_fs = get_fs();	int ret;	off_t of;		if (offset && get_user(of, offset))		return -EFAULT;			set_fs(KERNEL_DS);	ret = sys_sendfile(out_fd, in_fd,			   offset ? (off_t __user *) &of : NULL,			   count);	set_fs(old_fs);		if (offset && put_user(of, offset))		return -EFAULT;			return ret;}asmlinkage long compat_sys_sendfile64(int out_fd, int in_fd,				      compat_loff_t __user *offset,				      compat_size_t count){	mm_segment_t old_fs = get_fs();	int ret;	loff_t lof;		if (offset && get_user(lof, offset))		return -EFAULT;			set_fs(KERNEL_DS);	ret = sys_sendfile64(out_fd, in_fd,			     offset ? (loff_t __user *) &lof : NULL,			     count);	set_fs(old_fs);		if (offset && put_user(lof, offset))		return -EFAULT;			return ret;}/* Handle adjtimex compatibility. */struct timex32 {	u32 modes;	s32 offset, freq, maxerror, esterror;	s32 status, constant, precision, tolerance;	struct compat_timeval time;	s32 tick;	s32 ppsfreq, jitter, shift, stabil;	s32 jitcnt, calcnt, errcnt, stbcnt;	s32  :32; s32  :32; s32  :32; s32  :32;	s32  :32; s32  :32; s32  :32; s32  :32;	s32  :32; s32  :32; s32  :32; s32  :32;};extern int do_adjtimex(struct timex *);asmlinkage long sys32_adjtimex(struct timex32 __user *utp){	struct timex txc;	int ret;	memset(&txc, 0, sizeof(struct timex));	if (get_user(txc.modes, &utp->modes) ||	    __get_user(txc.offset, &utp->offset) ||	    __get_user(txc.freq, &utp->freq) ||	    __get_user(txc.maxerror, &utp->maxerror) ||	    __get_user(txc.esterror, &utp->esterror) ||	    __get_user(txc.status, &utp->status) ||	    __get_user(txc.constant, &utp->constant) ||	    __get_user(txc.precision, &utp->precision) ||	    __get_user(txc.tolerance, &utp->tolerance) ||	    __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||	    __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||	    __get_user(txc.tick, &utp->tick) ||	    __get_user(txc.ppsfreq, &utp->ppsfreq) ||	    __get_user(txc.jitter, &utp->jitter) ||	    __get_user(txc.shift, &utp->shift) ||	    __get_user(txc.stabil, &utp->stabil) ||	    __get_user(txc.jitcnt, &utp->jitcnt) ||	    __get_user(txc.calcnt, &utp->calcnt) ||	    __get_user(txc.errcnt, &utp->errcnt) ||	    __get_user(txc.stbcnt, &utp->stbcnt))		return -EFAULT;	ret = do_adjtimex(&txc);	if (put_user(txc.modes, &utp->modes) ||	    __put_user(txc.offset, &utp->offset) ||	    __put_user(txc.freq, &utp->freq) ||	    __put_user(txc.maxerror, &utp->maxerror) ||	    __put_user(txc.esterror, &utp->esterror) ||	    __put_user(txc.status, &utp->status) ||	    __put_user(txc.constant, &utp->constant) ||	    __put_user(txc.precision, &utp->precision) ||	    __put_user(txc.tolerance, &utp->tolerance) ||	    __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||	    __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||	    __put_user(txc.tick, &utp->tick) ||	    __put_user(txc.ppsfreq, &utp->ppsfreq) ||	    __put_user(txc.jitter, &utp->jitter) ||	    __put_user(txc.shift, &utp->shift) ||	    __put_user(txc.stabil, &utp->stabil) ||	    __put_user(txc.jitcnt, &utp->jitcnt) ||	    __put_user(txc.calcnt, &utp->calcnt) ||	    __put_user(txc.errcnt, &utp->errcnt) ||	    __put_user(txc.stbcnt, &utp->stbcnt))		ret = -EFAULT;	return ret;}/* This is just a version for 32-bit applications which does * not force O_LARGEFILE on. */asmlinkage long sparc32_open(const char __user *filename,			     int flags, int mode){	return do_sys_open(filename, flags, mode);}extern unsigned long do_mremap(unsigned long addr,	unsigned long old_len, unsigned long new_len,	unsigned long flags, unsigned long new_addr);                asmlinkage unsigned long sys32_mremap(unsigned long addr,	unsigned long old_len, unsigned long new_len,	unsigned long flags, u32 __new_addr){	struct vm_area_struct *vma;	unsigned long ret = -EINVAL;	unsigned long new_addr = __new_addr;	if (old_len > 0xf0000000UL || new_len > 0xf0000000UL)		goto out;	if (addr > 0xf0000000UL - old_len)		goto out;	down_write(&current->mm->mmap_sem);	if (flags & MREMAP_FIXED) {		if (new_addr > 0xf0000000UL - new_len)			goto out_sem;	} else if (addr > 0xf0000000UL - new_len) {		unsigned long map_flags = 0;		struct file *file = NULL;		ret = -ENOMEM;		if (!(flags & MREMAP_MAYMOVE))			goto out_sem;		vma = find_vma(current->mm, addr);		if (vma) {			if (vma->vm_flags & VM_SHARED)				map_flags |= MAP_SHARED;			file = vma->vm_file;		}		/* MREMAP_FIXED checked above. */		new_addr = get_unmapped_area(file, addr, new_len,				    vma ? vma->vm_pgoff : 0,				    map_flags);		ret = new_addr;		if (new_addr & ~PAGE_MASK)			goto out_sem;		flags |= MREMAP_FIXED;	}	ret = do_mremap(addr, old_len, new_len, flags, new_addr);out_sem:	up_write(&current->mm->mmap_sem);out:	return ret;       }struct __sysctl_args32 {	u32 name;	int nlen;	u32 oldval;	u32 oldlenp;	u32 newval;	u32 newlen;	u32 __unused[4];};asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args){#ifndef CONFIG_SYSCTL	return -ENOSYS;#else	struct __sysctl_args32 tmp;	int error;	size_t oldlen, __user *oldlenp = NULL;	unsigned long addr = (((unsigned long)&args->__unused[0]) + 7UL) & ~7UL;	if (copy_from_user(&tmp, args, sizeof(tmp)))		return -EFAULT;	if (tmp.oldval && tmp.oldlenp) {		/* Duh, this is ugly and might not work if sysctl_args		   is in read-only memory, but do_sysctl does indirectly		   a lot of uaccess in both directions and we'd have to		   basically copy the whole sysctl.c here, and		   glibc's __sysctl uses rw memory for the structure		   anyway.  */		if (get_user(oldlen, (u32 __user *)(unsigned long)tmp.oldlenp) ||		    put_user(oldlen, (size_t __user *)addr))			return -EFAULT;		oldlenp = (size_t __user *)addr;	}	lock_kernel();	error = do_sysctl((int __user *)(unsigned long) tmp.name,			  tmp.nlen,			  (void __user *)(unsigned long) tmp.oldval,			  oldlenp,			  (void __user *)(unsigned long) tmp.newval,			  tmp.newlen);	unlock_kernel();	if (oldlenp) {		if (!error) {			if (get_user(oldlen, (size_t __user *)addr) ||			    put_user(oldlen, (u32 __user *)(unsigned long) tmp.oldlenp))				error = -EFAULT;		}		if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused)))			error = -EFAULT;	}	return error;#endif}long sys32_lookup_dcookie(unsigned long cookie_high,			  unsigned long cookie_low,			  char __user *buf, size_t len){	return sys_lookup_dcookie((cookie_high << 32) | cookie_low,				  buf, len);}extern asmlinkage longsys_timer_create(clockid_t which_clock,		 struct sigevent __user *timer_event_spec,		 timer_t __user *created_timer_id);longsys32_timer_create(u32 clock, struct compat_sigevent __user *se32,		   timer_t __user *timer_id){	struct sigevent se;	mm_segment_t oldfs;	timer_t t;	long err;	if (se32 == NULL)		return sys_timer_create(clock, NULL, timer_id);	if (get_compat_sigevent(&se, se32))		return -EFAULT;	if (!access_ok(VERIFY_WRITE,timer_id,sizeof(timer_t)))		return -EFAULT;	oldfs = get_fs();	set_fs(KERNEL_DS);	err = sys_timer_create(clock,			       (struct sigevent __user *) &se,			       (timer_t __user *) &t);	set_fs(oldfs);	if (!err)		err = __put_user (t, timer_id);	return err;}

⌨️ 快捷键说明

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