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

📄 sys_ia32.c

📁 一个2.4.21版本的嵌入式linux内核
💻 C
📖 第 1 页 / 共 5 页
字号:
	set_fs (old_fs);	if (verify_area(VERIFY_WRITE, interval, sizeof(struct timespec32)) ||	    __put_user (t.tv_sec, &interval->tv_sec) ||	    __put_user (t.tv_nsec, &interval->tv_nsec))		return -EFAULT;	return ret;}extern asmlinkage long sys_sigprocmask(int how, old_sigset_t *set,				      old_sigset_t *oset);asmlinkage longsys32_sigprocmask(int how, old_sigset32_t *set, old_sigset32_t *oset){	old_sigset_t s;	int ret;	mm_segment_t old_fs = get_fs();		if (set && get_user (s, set)) return -EFAULT;	set_fs (KERNEL_DS);	ret = sys_sigprocmask(how, set ? &s : NULL, oset ? &s : NULL);	set_fs (old_fs);	if (ret) return ret;	if (oset && put_user (s, oset)) return -EFAULT;	return 0;}extern asmlinkage long sys_sigpending(old_sigset_t *set);asmlinkage longsys32_sigpending(old_sigset32_t *set){	old_sigset_t s;	int ret;	mm_segment_t old_fs = get_fs();			set_fs (KERNEL_DS);	ret = sys_sigpending(&s);	set_fs (old_fs);	if (put_user (s, set)) return -EFAULT;	return ret;}extern asmlinkage long sys_rt_sigpending(sigset_t *set, size_t sigsetsize);asmlinkage longsys32_rt_sigpending(sigset32_t *set, __kernel_size_t32 sigsetsize){	sigset_t s;	sigset32_t s32;	int ret;	mm_segment_t old_fs = get_fs();			set_fs (KERNEL_DS);	ret = sys_rt_sigpending(&s, sigsetsize);	set_fs (old_fs);	if (!ret) {		switch (_NSIG_WORDS) {		case 4: s32.sig[7] = (s.sig[3] >> 32); s32.sig[6] = s.sig[3];		case 3: s32.sig[5] = (s.sig[2] >> 32); s32.sig[4] = s.sig[2];		case 2: s32.sig[3] = (s.sig[1] >> 32); s32.sig[2] = s.sig[1];		case 1: s32.sig[1] = (s.sig[0] >> 32); s32.sig[0] = s.sig[0];		}		if (copy_to_user (set, &s32, sizeof(sigset32_t)))			return -EFAULT;	}	return ret;}siginfo_t32 *siginfo64to32(siginfo_t32 *d, siginfo_t *s){	memset (d, 0, sizeof(siginfo_t32));	d->si_signo = s->si_signo;	d->si_errno = s->si_errno;	d->si_code = s->si_code;	if (s->si_signo >= SIGRTMIN) {		d->si_pid = s->si_pid;		d->si_uid = s->si_uid;		memcpy(&d->si_int, &s->si_int, 		       sizeof(siginfo_t) - offsetof(siginfo_t,si_int));	} else switch (s->si_signo) {	/* XXX: What about POSIX1.b timers */	case SIGCHLD:		d->si_pid = s->si_pid;		d->si_status = s->si_status;		d->si_utime = s->si_utime;		d->si_stime = s->si_stime;		break;	case SIGSEGV:	case SIGBUS:	case SIGFPE:	case SIGILL:		d->si_addr = (long)(s->si_addr);//		d->si_trapno = s->si_trapno;		break;	case SIGPOLL:		d->si_band = s->si_band;		d->si_fd = s->si_fd;		break;	default:		d->si_pid = s->si_pid;		d->si_uid = s->si_uid;		break;	}	return d;}siginfo_t *siginfo32to64(siginfo_t *d, siginfo_t32 *s){	d->si_signo = s->si_signo;	d->si_errno = s->si_errno;	d->si_code = s->si_code;	if (s->si_signo >= SIGRTMIN) {		d->si_pid = s->si_pid;		d->si_uid = s->si_uid;		memcpy(&d->si_int,		       &s->si_int,		       sizeof(siginfo_t) - offsetof(siginfo_t, si_int)); 	} else switch (s->si_signo) {	/* XXX: What about POSIX1.b timers */	case SIGCHLD:		d->si_pid = s->si_pid;		d->si_status = s->si_status;		d->si_utime = s->si_utime;		d->si_stime = s->si_stime;		break;	case SIGSEGV:	case SIGBUS:	case SIGFPE:	case SIGILL:		d->si_addr = (void *)A(s->si_addr);//		d->si_trapno = s->si_trapno;		break;	case SIGPOLL:		d->si_band = s->si_band;		d->si_fd = s->si_fd;		break;	default:		d->si_pid = s->si_pid;		d->si_uid = s->si_uid;		break;	}	return d;}extern asmlinkage longsys_rt_sigtimedwait(const sigset_t *uthese, siginfo_t *uinfo,		    const struct timespec *uts, size_t sigsetsize);asmlinkage longsys32_rt_sigtimedwait(sigset32_t *uthese, siginfo_t32 *uinfo,		      struct timespec32 *uts, __kernel_size_t32 sigsetsize){	sigset_t s;	sigset32_t s32;	struct timespec t;	int ret;	mm_segment_t old_fs = get_fs();	siginfo_t info;	siginfo_t32 info32;			if (copy_from_user (&s32, uthese, sizeof(sigset32_t)))		return -EFAULT;	switch (_NSIG_WORDS) {	case 4: s.sig[3] = s32.sig[6] | (((long)s32.sig[7]) << 32);	case 3: s.sig[2] = s32.sig[4] | (((long)s32.sig[5]) << 32);	case 2: s.sig[1] = s32.sig[2] | (((long)s32.sig[3]) << 32);	case 1: s.sig[0] = s32.sig[0] | (((long)s32.sig[1]) << 32);	}	if (uts) {		if (verify_area(VERIFY_READ, uts, sizeof(struct timespec32)) ||		    __get_user (t.tv_sec, &uts->tv_sec) ||		    __get_user (t.tv_nsec, &uts->tv_nsec))			return -EFAULT;	}	set_fs (KERNEL_DS);	ret = sys_rt_sigtimedwait(&s, &info, &t, sigsetsize);	set_fs (old_fs);	if (ret >= 0 && uinfo) {		if (copy_to_user (uinfo, siginfo64to32(&info32, &info),				  sizeof(siginfo_t32)))			return -EFAULT;	}	return ret;}extern asmlinkage longsys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo);asmlinkage longsys32_rt_sigqueueinfo(int pid, int sig, siginfo_t32 *uinfo){	siginfo_t info;	siginfo_t32 info32;	int ret;	mm_segment_t old_fs = get_fs();		if (copy_from_user (&info32, uinfo, sizeof(siginfo_t32)))		return -EFAULT;	/* XXX: Is this correct? */	siginfo32to64(&info, &info32);	set_fs (KERNEL_DS);	ret = sys_rt_sigqueueinfo(pid, sig, &info);	set_fs (old_fs);	return ret;}extern void check_pending(int signum);asmlinkage long sys_utimes(char *, struct timeval *);asmlinkage longsys32_utimes(char *filename, struct timeval32 *tvs){	char *kfilename;	struct timeval ktvs[2];	mm_segment_t old_fs;	int ret;	kfilename = getname(filename);	ret = PTR_ERR(kfilename);	if (!IS_ERR(kfilename)) {		if (tvs) {			if (get_tv32(&ktvs[0], tvs) ||			    get_tv32(&ktvs[1], 1+tvs))				return -EFAULT;		}		old_fs = get_fs();		set_fs(KERNEL_DS);		ret = sys_utimes(kfilename, &ktvs[0]);		set_fs(old_fs);		putname(kfilename);	}	return ret;}/* These are here just in case some old ia32 binary calls it. */asmlinkage longsys32_pause(void){	current->state = TASK_INTERRUPTIBLE;	schedule();	return -ERESTARTNOHAND;}struct sysctl_ia32 {	unsigned int	name;	int		nlen;	unsigned int	oldval;	unsigned int	oldlenp;	unsigned int	newval;	unsigned int	newlen;	unsigned int	__unused[4];};asmlinkage longsys32_sysctl(struct sysctl_ia32 *args32){#ifndef CONFIG_SYSCTL	return -ENOSYS; #else	struct sysctl_ia32 a32;	mm_segment_t old_fs = get_fs ();	void *oldvalp, *newvalp;	size_t oldlen;	int *namep;	long ret;	extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp,		     void *newval, size_t newlen);	if (copy_from_user(&a32, args32, sizeof (a32)))		return -EFAULT;	/*	 * We need to pre-validate these because we have to disable address checking	 * before calling do_sysctl() because of OLDLEN but we can't run the risk of the	 * user specifying bad addresses here.  Well, since we're dealing with 32 bit	 * addresses, we KNOW that access_ok() will always succeed, so this is an	 * expensive NOP, but so what...	 */	namep = (int *) A(a32.name);	oldvalp = (void *) A(a32.oldval);	newvalp = (void *) A(a32.newval);	if ((oldvalp && get_user(oldlen, (int *) A(a32.oldlenp)))	    || !access_ok(VERIFY_WRITE, namep, 0)	    || !access_ok(VERIFY_WRITE, oldvalp, 0)	    || !access_ok(VERIFY_WRITE, newvalp, 0))		return -EFAULT;	set_fs(KERNEL_DS);	lock_kernel();	ret = do_sysctl(namep, a32.nlen, oldvalp, &oldlen, newvalp, (size_t) a32.newlen);	unlock_kernel();	set_fs(old_fs);	if (oldvalp && put_user (oldlen, (int *) A(a32.oldlenp)))		return -EFAULT;	return ret;#endif}extern asmlinkage ssize_t sys_pread(unsigned int fd, char * buf,				    size_t count, loff_t pos);extern asmlinkage ssize_t sys_pwrite(unsigned int fd, const char * buf,				     size_t count, loff_t pos);typedef __kernel_ssize_t32 ssize_t32;/* warning: next two assume little endian */ asmlinkage longsys32_pread(unsigned int fd, char *ubuf, __kernel_size_t32 count,	    u32 poslo, u32 poshi){	return sys_pread(fd, ubuf, count,			 ((loff_t)AA(poshi) << 32) | AA(poslo));}asmlinkage longsys32_pwrite(unsigned int fd, char *ubuf, __kernel_size_t32 count,	     u32 poslo, u32 poshi){	return sys_pwrite(fd, ubuf, count,			  ((loff_t)AA(poshi) << 32) | AA(poslo));}extern asmlinkage long sys_personality(unsigned long);asmlinkage longsys32_personality(unsigned long personality){	int ret;	if (personality(current->personality) == PER_LINUX32 && 		personality == PER_LINUX)		personality = PER_LINUX32;	ret = sys_personality(personality);	if (ret == PER_LINUX32)		ret = PER_LINUX;	return ret;}extern asmlinkage ssize_t sys_sendfile(int out_fd, int in_fd, off_t *offset,				       size_t count); asmlinkage longsys32_sendfile(int out_fd, int in_fd, __kernel_off_t32 *offset, s32 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 ? &of : NULL, count);	set_fs(old_fs);		if (!ret && offset && put_user(of, offset))		return -EFAULT;			return ret;}extern long sys_modify_ldt(int,void*,unsigned long);asmlinkage long sys32_modify_ldt(int func, void *ptr, unsigned long bytecount){        long ret;        if (func == 0x1 || func == 0x11) { 				struct modify_ldt_ldt_s info;                mm_segment_t old_fs = get_fs();                if (bytecount != sizeof(struct modify_ldt_ldt_s))                        return -EINVAL;                if (copy_from_user(&info, ptr, sizeof(struct modify_ldt_ldt_s)))                        return -EFAULT;                /* lm bit was undefined in the 32bit ABI and programs                   give it random values. Force it to zero here. */                info.lm = 0;                 set_fs(KERNEL_DS);                ret = sys_modify_ldt(func, &info, bytecount);                set_fs(old_fs);        }  else {                 ret = sys_modify_ldt(func, ptr, bytecount);         }        return ret;}/* Handle adjtimex compatability. */struct timex32 {	u32 modes;	s32 offset, freq, maxerror, esterror;	s32 status, constant, precision, tolerance;	struct timeval32 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 longsys32_adjtimex(struct timex32 *utp){	struct timex txc;	int ret;	memset(&txc, 0, sizeof(struct timex));	if(verify_area(VERIFY_READ, utp, sizeof(struct timex32)) ||	   __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(verify_area(VERIFY_WRITE, utp, sizeof(struct timex32)) ||	   __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;}asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,	unsigned long prot, unsigned long flags,	unsigned long fd, unsigned long pgoff){	struct mm_struct *mm = current->mm;	unsigned long error;	struct file * file = NULL;	flags &= ~(MAP_EXECUTABLE | MAP_DENYWRITE);	if (!(flags & MAP_ANONYMOUS)) {		file = fget(fd);		if (!file)			return -EBADF;	}	if (prot & PROT_READ)		prot |= PROT_EXEC;	down_write(&mm->mmap_sem);	error = do_mmap_pgoff(file, addr, len, prot, flags|MAP_32BIT, pgoff);	up_write(&mm->mmap_sem);	if (file)		fput(file);	return error;}asmlinkage long sys32_olduname(struct oldold_utsname * name){	int error;	if (!name)		return -EFAULT;	if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))		return -EFAULT;    	down_read(&uts_sem);	

⌨️ 快捷键说明

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