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

📄 sys_ppc32.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * sys_ppc32.c: Conversion between 32bit and 64bit native syscalls. * * Copyright (C) 2001 IBM * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) * Copyright (C) 1997 David S. Miller (davem@caip.rutgers.edu) * * These routines maintain argument size conversion between 32bit and 64bit * environment. * *      This program is free software; you can redistribute it and/or *      modify it under the terms of the GNU General Public License *      as published by the Free Software Foundation; either version *      2 of the License, or (at your option) any later version. */#include <asm/ptrace.h>#include <linux/config.h>#include <linux/kernel.h>#include <linux/sched.h>#include <linux/fs.h> #include <linux/mm.h> #include <linux/file.h> #include <linux/signal.h>#include <linux/utime.h>#include <linux/resource.h>#include <linux/times.h>#include <linux/utsname.h>#include <linux/timex.h>#include <linux/smp.h>#include <linux/smp_lock.h>#include <linux/sem.h>#include <linux/msg.h>#include <linux/shm.h>#include <linux/slab.h>#include <linux/uio.h>#include <linux/nfs_fs.h>#include <linux/smb_fs.h>#include <linux/smb_mount.h>#include <linux/ncp_fs.h>#include <linux/quota.h>#include <linux/module.h>#include <linux/sunrpc/svc.h>#include <linux/nfsd/nfsd.h>#include <linux/nfsd/cache.h>#include <linux/nfsd/xdr.h>#include <linux/nfsd/syscall.h>#include <linux/poll.h>#include <linux/personality.h>#include <linux/stat.h>#include <linux/filter.h>#include <linux/highmem.h>#include <linux/highuid.h>#include <linux/mman.h>#include <linux/sysctl.h>#include <asm/types.h>#include <asm/ipc.h>#include <asm/uaccess.h>#include <asm/semaphore.h>#include <net/scm.h>#include <linux/elf.h>#include <asm/ppcdebug.h>#include <asm/time.h>#include <asm/ppc32.h>extern unsigned long wall_jiffies;#define USEC_PER_SEC (1000000)/*  * These are the flags in the MSR that the user is allowed to change * by modifying the saved value of the MSR on the stack.  SE and BE * should not be in this list since gdb may want to change these.  I.e, * you should be able to step out of a signal handler to see what * instruction executes next after the signal handler completes. * Alternately, if you stepped into a signal handler, you should be * able to continue 'til the next breakpoint from within the signal * handler, even if the handler returns. */#define MSR_USERCHANGE	(MSR_FE0 | MSR_FE1)extern asmlinkage long sys_utime(char * filename, struct utimbuf * times);struct utimbuf32 {	__kernel_time_t32 actime, modtime;};asmlinkage long sys32_utime(char * filename, struct utimbuf32 *times){	struct utimbuf t;	mm_segment_t old_fs;	int ret;	char *filenam;		PPCDBG(PPCDBG_SYS32NI, "sys32_utime - running - filename=%s, times=%p - pid=%ld, comm=%s \n", filename, times, current->pid, current->comm);	if (!times)		return sys_utime(filename, NULL);	if (get_user(t.actime, &times->actime) || __get_user(t.modtime, &times->modtime))		return -EFAULT;	filenam = getname(filename);	ret = PTR_ERR(filenam);	if (!IS_ERR(filenam)) {		old_fs = get_fs();		set_fs (KERNEL_DS); 		ret = sys_utime(filenam, &t);		set_fs (old_fs);		putname (filenam);	}	return ret;}struct iovec32 { u32 iov_base; __kernel_size_t32 iov_len; };typedef ssize_t (*IO_fn_t)(struct file *, char *, size_t, loff_t *);static long do_readv_writev32(int type, struct file *file,			      const struct iovec32 *vector, u32 count){	unsigned long tot_len;	struct iovec iovstack[UIO_FASTIOV];	struct iovec *iov=iovstack, *ivp;	struct inode *inode;	long retval, i;	IO_fn_t fn;	/* First get the "struct iovec" from user memory and	 * verify all the pointers	 */	if (!count)		return 0;	if(verify_area(VERIFY_READ, vector, sizeof(struct iovec32)*count))		return -EFAULT;	if (count > UIO_MAXIOV)		return -EINVAL;	if (count > UIO_FASTIOV) {		iov = kmalloc(count*sizeof(struct iovec), GFP_KERNEL);		if (!iov)			return -ENOMEM;	}	tot_len = 0;	i = count;	ivp = iov;	while(i > 0) {		u32 len;		u32 buf;		__get_user(len, &vector->iov_len);		__get_user(buf, &vector->iov_base);		tot_len += len;		ivp->iov_base = (void *)A(buf);		ivp->iov_len = (__kernel_size_t) len;		vector++;		ivp++;		i--;	}	inode = file->f_dentry->d_inode;	/* VERIFY_WRITE actually means a read, as we write to user space */	retval = locks_verify_area((type == VERIFY_WRITE				    ? FLOCK_VERIFY_READ : FLOCK_VERIFY_WRITE),				   inode, file, file->f_pos, tot_len);	if (retval) {		if (iov != iovstack)			kfree(iov);		return retval;	}	/* Then do the actual IO.  Note that sockets need to be handled	 * specially as they have atomicity guarantees and can handle	 * iovec's natively	 */	if (inode->i_sock) {		int err;		err = sock_readv_writev(type, inode, file, iov, count, tot_len);		if (iov != iovstack)			kfree(iov);		return err;	}	if (!file->f_op) {		if (iov != iovstack)			kfree(iov);		return -EINVAL;	}	/* VERIFY_WRITE actually means a read, as we write to user space */	fn = file->f_op->read;	if (type == VERIFY_READ)		fn = (IO_fn_t) file->f_op->write;			ivp = iov;	while (count > 0) {		void * base;		int len, nr;		base = ivp->iov_base;		len = ivp->iov_len;		ivp++;		count--;		nr = fn(file, base, len, &file->f_pos);		if (nr < 0) {			if (retval)				break;			retval = nr;			break;		}		retval += nr;		if (nr != len)			break;	}	if (iov != iovstack)		kfree(iov);	return retval;}asmlinkage long sys32_readv(u32 fd, struct iovec32 *vector, u32 count){	struct file *file;	long ret = -EBADF;		PPCDBG(PPCDBG_SYS32, "sys32_readv - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);	file = fget(fd);	if(!file)		goto bad_file;	if (file->f_op && (file->f_mode & FMODE_READ) &&     (file->f_op->readv || file->f_op->read))		ret = do_readv_writev32(VERIFY_WRITE, file, vector, count);	fput(file);bad_file:	PPCDBG(PPCDBG_SYS32, "sys32_readv - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);	return ret;}asmlinkage long sys32_writev(u32 fd, struct iovec32 *vector, u32 count){	struct file *file;	int ret = -EBADF;		PPCDBG(PPCDBG_SYS32, "sys32_writev - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);	file = fget(fd);	if(!file)		goto bad_file;	if (file->f_op && (file->f_mode & FMODE_WRITE) &&	   (file->f_op->writev || file->f_op->write))		ret = do_readv_writev32(VERIFY_READ, file, vector, count);	fput(file);bad_file:	PPCDBG(PPCDBG_SYS32, "sys32_writev - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);	return ret;}static inline int get_flock(struct flock *kfl, struct flock32 *ufl){	int err;		err = get_user(kfl->l_type, &ufl->l_type);	err |= __get_user(kfl->l_whence, &ufl->l_whence);	err |= __get_user(kfl->l_start, &ufl->l_start);	err |= __get_user(kfl->l_len, &ufl->l_len);	err |= __get_user(kfl->l_pid, &ufl->l_pid);	return err;}static inline int put_flock(struct flock *kfl, struct flock32 *ufl){	int err;		err = __put_user(kfl->l_type, &ufl->l_type);	err |= __put_user(kfl->l_whence, &ufl->l_whence);	err |= __put_user(kfl->l_start, &ufl->l_start);	err |= __put_user(kfl->l_len, &ufl->l_len);	err |= __put_user(kfl->l_pid, &ufl->l_pid);	return err;}extern asmlinkage long sys_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg);asmlinkage long sys32_fcntl(unsigned int fd, unsigned int cmd, unsigned long arg){	switch (cmd) {	case F_GETLK:	case F_SETLK:	case F_SETLKW:	{		struct flock f;		mm_segment_t old_fs;		long ret;		if(get_flock(&f, (struct flock32 *)arg))			return -EFAULT;		old_fs = get_fs(); set_fs (KERNEL_DS);		ret = sys_fcntl(fd, cmd, (unsigned long)&f);		set_fs (old_fs);		if(put_flock(&f, (struct flock32 *)arg))			return -EFAULT;		return ret;	}	default:		return sys_fcntl(fd, cmd, (unsigned long)arg);	}}struct ncp_mount_data32 {        int version;        unsigned int ncp_fd;        __kernel_uid_t32 mounted_uid;        __kernel_pid_t32 wdog_pid;        unsigned char mounted_vol[NCP_VOLNAME_LEN + 1];        unsigned int time_out;        unsigned int retry_count;        unsigned int flags;        __kernel_uid_t32 uid;        __kernel_gid_t32 gid;        __kernel_mode_t32 file_mode;        __kernel_mode_t32 dir_mode;};static void *do_ncp_super_data_conv(void *raw_data){	struct ncp_mount_data *n = (struct ncp_mount_data *)raw_data;	struct ncp_mount_data32 *n32 = (struct ncp_mount_data32 *)raw_data;	n->dir_mode = n32->dir_mode;	n->file_mode = n32->file_mode;	n->gid = n32->gid;	n->uid = n32->uid;	memmove (n->mounted_vol, n32->mounted_vol, (sizeof (n32->mounted_vol) + 3 * sizeof (unsigned int)));	n->wdog_pid = n32->wdog_pid;	n->mounted_uid = n32->mounted_uid;	return raw_data;}struct smb_mount_data32 {        int version;        __kernel_uid_t32 mounted_uid;        __kernel_uid_t32 uid;        __kernel_gid_t32 gid;        __kernel_mode_t32 file_mode;        __kernel_mode_t32 dir_mode;};static void *do_smb_super_data_conv(void *raw_data){	struct smb_mount_data *s = (struct smb_mount_data *)raw_data;	struct smb_mount_data32 *s32 = (struct smb_mount_data32 *)raw_data;	s->version = s32->version;	s->mounted_uid = s32->mounted_uid;	s->uid = s32->uid;	s->gid = s32->gid;	s->file_mode = s32->file_mode;	s->dir_mode = s32->dir_mode;	return raw_data;}static int copy_mount_stuff_to_kernel(const void *user, unsigned long *kernel){	int i;	unsigned long page;	struct vm_area_struct *vma;	*kernel = 0;	if(!user)		return 0;	vma = find_vma(current->mm, (unsigned long)user);	if(!vma || (unsigned long)user < vma->vm_start)		return -EFAULT;	if(!(vma->vm_flags & VM_READ))		return -EFAULT;	i = vma->vm_end - (unsigned long) user;	if(PAGE_SIZE <= (unsigned long) i)		i = PAGE_SIZE - 1;	if(!(page = __get_free_page(GFP_KERNEL)))		return -ENOMEM;	if(copy_from_user((void *) page, user, i)) {		free_page(page);		return -EFAULT;	}	*kernel = page;	return 0;}#define SMBFS_NAME	"smbfs"#define NCPFS_NAME	"ncpfs"asmlinkage long sys32_mount(char *dev_name, char *dir_name, char *type, unsigned long new_flags, u32 data){	unsigned long type_page = 0;	unsigned long data_page = 0;	unsigned long dev_page = 0;	unsigned long dir_page = 0;	int err, is_smb, is_ncp;		PPCDBG(PPCDBG_SYS32, "sys32_mount - entered - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);	is_smb = is_ncp = 0;	err = copy_mount_stuff_to_kernel((const void *)type, &type_page);	if (err)		goto out;	if (!type_page) {		err = -EINVAL;		goto out;	}	is_smb = !strcmp((char *)type_page, SMBFS_NAME);	is_ncp = !strcmp((char *)type_page, NCPFS_NAME);	err = copy_mount_stuff_to_kernel((const void *)AA(data), &data_page);	if (err)		goto type_out;	err = copy_mount_stuff_to_kernel(dev_name, &dev_page);	if (err)		goto data_out;	err = copy_mount_stuff_to_kernel(dir_name, &dir_page);	if (err)		goto dev_out;	if (!is_smb && !is_ncp) {		lock_kernel();		err = do_mount((char*)dev_page, (char*)dir_page,				(char*)type_page, new_flags, (char*)data_page);		unlock_kernel();	} else {		if (is_ncp)			do_ncp_super_data_conv((void *)data_page);		else			do_smb_super_data_conv((void *)data_page);		lock_kernel();		err = do_mount((char*)dev_page, (char*)dir_page,				(char*)type_page, new_flags, (char*)data_page);		unlock_kernel();	}	free_page(dir_page);dev_out:	free_page(dev_page);data_out:	free_page(data_page);type_out:	free_page(type_page);out:		PPCDBG(PPCDBG_SYS32, "sys32_mount - exited - pid=%ld current=%lx comm=%s \n", current->pid, current, current->comm);	return err;}struct dqblk32 {    __u32 dqb_bhardlimit;    __u32 dqb_bsoftlimit;    __u32 dqb_curblocks;    __u32 dqb_ihardlimit;    __u32 dqb_isoftlimit;    __u32 dqb_curinodes;    __kernel_time_t32 dqb_btime;    __kernel_time_t32 dqb_itime;};                                extern asmlinkage long sys_quotactl(int cmd, const char *special, int id, caddr_t addr);/* Note: it is necessary to treat cmd and id as unsigned ints,  * with the corresponding cast to a signed int to insure that the  * proper conversion (sign extension) between the register representation of a signed int (msr in 32-bit mode) * and the register representation of a signed int (msr in 64-bit mode) is performed. */asmlinkage long sys32_quotactl(u32 cmd_parm, const char *special, u32 id_parm, unsigned long addr){  int cmd = (int)cmd_parm;  int id  = (int)id_parm;	int cmds = cmd >> SUBCMDSHIFT;	int err;	struct dqblk d;	mm_segment_t old_fs;	char *spec;		PPCDBG(PPCDBG_SYS32, "sys32_quotactl - entered - pid=%ld current=%lx comm=%s \n",		    current->pid, current, current->comm);	switch (cmds) {	case Q_GETQUOTA:		break;	case Q_SETQUOTA:	case Q_SETUSE:	case Q_SETQLIM:

⌨️ 快捷键说明

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