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

📄 sys_ia32.c

📁 Linux内核源代码 为压缩文件 是<<Linux内核>>一书中的源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
				    + 4, GFP_USER);	struct msgbuf32 *up = (struct msgbuf32 *)uptr;	mm_segment_t old_fs;	int err;	if (!p)		return -ENOMEM;	err = get_user (p->mtype, &up->mtype);	err |= __copy_from_user (p->mtext, &up->mtext, second);	if (err)		goto out;	old_fs = get_fs ();	set_fs (KERNEL_DS);	err = sys_msgsnd (first, p, second, third);	set_fs (old_fs);out:	kfree (p);	return err;}static intdo_sys32_msgrcv (int first, int second, int msgtyp, int third,		 int version, void *uptr){	struct msgbuf32 *up;	struct msgbuf *p;	mm_segment_t old_fs;	int err;	if (!version) {		struct ipc_kludge *uipck = (struct ipc_kludge *)uptr;		struct ipc_kludge ipck;		err = -EINVAL;		if (!uptr)			goto out;		err = -EFAULT;		if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge)))			goto out;		uptr = (void *)A(ipck.msgp);		msgtyp = ipck.msgtyp;	}	err = -ENOMEM;	p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);	if (!p)		goto out;	old_fs = get_fs ();	set_fs (KERNEL_DS);	err = sys_msgrcv (first, p, second + 4, msgtyp, third);	set_fs (old_fs);	if (err < 0)		goto free_then_out;	up = (struct msgbuf32 *)uptr;	if (put_user (p->mtype, &up->mtype) ||	    __copy_to_user (&up->mtext, p->mtext, err))		err = -EFAULT;free_then_out:	kfree (p);out:	return err;}static intdo_sys32_msgctl (int first, int second, void *uptr){	int err = -EINVAL, err2;	struct msqid_ds m;	struct msqid64_ds m64;	struct msqid_ds32 *up = (struct msqid_ds32 *)uptr;	mm_segment_t old_fs;	switch (second) {	case IPC_INFO:	case IPC_RMID:	case MSG_INFO:		err = sys_msgctl (first, second, (struct msqid_ds *)uptr);		break;	case IPC_SET:		err = get_user (m.msg_perm.uid, &up->msg_perm.uid);		err |= __get_user (m.msg_perm.gid, &up->msg_perm.gid);		err |= __get_user (m.msg_perm.mode, &up->msg_perm.mode);		err |= __get_user (m.msg_qbytes, &up->msg_qbytes);		if (err)			break;		old_fs = get_fs ();		set_fs (KERNEL_DS);		err = sys_msgctl (first, second, &m);		set_fs (old_fs);		break;	case IPC_STAT:	case MSG_STAT:		old_fs = get_fs ();		set_fs (KERNEL_DS);		err = sys_msgctl (first, second, (void *) &m64);		set_fs (old_fs);		err2 = put_user (m64.msg_perm.key, &up->msg_perm.key);		err2 |= __put_user(m64.msg_perm.uid, &up->msg_perm.uid);		err2 |= __put_user(m64.msg_perm.gid, &up->msg_perm.gid);		err2 |= __put_user(m64.msg_perm.cuid, &up->msg_perm.cuid);		err2 |= __put_user(m64.msg_perm.cgid, &up->msg_perm.cgid);		err2 |= __put_user(m64.msg_perm.mode, &up->msg_perm.mode);		err2 |= __put_user(m64.msg_perm.seq, &up->msg_perm.seq);		err2 |= __put_user(m64.msg_stime, &up->msg_stime);		err2 |= __put_user(m64.msg_rtime, &up->msg_rtime);		err2 |= __put_user(m64.msg_ctime, &up->msg_ctime);		err2 |= __put_user(m64.msg_cbytes, &up->msg_cbytes);		err2 |= __put_user(m64.msg_qnum, &up->msg_qnum);		err2 |= __put_user(m64.msg_qbytes, &up->msg_qbytes);		err2 |= __put_user(m64.msg_lspid, &up->msg_lspid);		err2 |= __put_user(m64.msg_lrpid, &up->msg_lrpid);		if (err2)			err = -EFAULT;		break;	}	return err;}static intdo_sys32_shmat (int first, int second, int third, int version, void *uptr){	unsigned long raddr;	u32 *uaddr = (u32 *)A((u32)third);	int err = -EINVAL;	if (version == 1)		return err;	err = sys_shmat (first, uptr, second, &raddr);	if (err)		return err;	err = put_user (raddr, uaddr);	return err;}static intdo_sys32_shmctl (int first, int second, void *uptr){	int err = -EFAULT, err2;	struct shmid_ds s;	struct shmid64_ds s64;	struct shmid_ds32 *up = (struct shmid_ds32 *)uptr;	mm_segment_t old_fs;	struct shm_info32 {		int used_ids;		u32 shm_tot, shm_rss, shm_swp;		u32 swap_attempts, swap_successes;	} *uip = (struct shm_info32 *)uptr;	struct shm_info si;	switch (second) {	case IPC_INFO:	case IPC_RMID:	case SHM_LOCK:	case SHM_UNLOCK:		err = sys_shmctl (first, second, (struct shmid_ds *)uptr);		break;	case IPC_SET:		err = get_user (s.shm_perm.uid, &up->shm_perm.uid);		err |= __get_user (s.shm_perm.gid, &up->shm_perm.gid);		err |= __get_user (s.shm_perm.mode, &up->shm_perm.mode);		if (err)			break;		old_fs = get_fs ();		set_fs (KERNEL_DS);		err = sys_shmctl (first, second, &s);		set_fs (old_fs);		break;	case IPC_STAT:	case SHM_STAT:		old_fs = get_fs ();		set_fs (KERNEL_DS);		err = sys_shmctl (first, second, (void *) &s64);		set_fs (old_fs);		if (err < 0)			break;		err2 = put_user (s64.shm_perm.key, &up->shm_perm.key);		err2 |= __put_user (s64.shm_perm.uid, &up->shm_perm.uid);		err2 |= __put_user (s64.shm_perm.gid, &up->shm_perm.gid);		err2 |= __put_user (s64.shm_perm.cuid,				    &up->shm_perm.cuid);		err2 |= __put_user (s64.shm_perm.cgid,				    &up->shm_perm.cgid);		err2 |= __put_user (s64.shm_perm.mode,				    &up->shm_perm.mode);		err2 |= __put_user (s64.shm_perm.seq, &up->shm_perm.seq);		err2 |= __put_user (s64.shm_atime, &up->shm_atime);		err2 |= __put_user (s64.shm_dtime, &up->shm_dtime);		err2 |= __put_user (s64.shm_ctime, &up->shm_ctime);		err2 |= __put_user (s64.shm_segsz, &up->shm_segsz);		err2 |= __put_user (s64.shm_nattch, &up->shm_nattch);		err2 |= __put_user (s64.shm_cpid, &up->shm_cpid);		err2 |= __put_user (s64.shm_lpid, &up->shm_lpid);		if (err2)			err = -EFAULT;		break;	case SHM_INFO:		old_fs = get_fs ();		set_fs (KERNEL_DS);		err = sys_shmctl (first, second, (void *)&si);		set_fs (old_fs);		if (err < 0)			break;		err2 = put_user (si.used_ids, &uip->used_ids);		err2 |= __put_user (si.shm_tot, &uip->shm_tot);		err2 |= __put_user (si.shm_rss, &uip->shm_rss);		err2 |= __put_user (si.shm_swp, &uip->shm_swp);		err2 |= __put_user (si.swap_attempts,				    &uip->swap_attempts);		err2 |= __put_user (si.swap_successes,				    &uip->swap_successes);		if (err2)			err = -EFAULT;		break;	}	return err;}asmlinkage longsys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth){	int version, err;	version = call >> 16; /* hack for backward compatibility */	call &= 0xffff;	switch (call) {	case SEMOP:		/* struct sembuf is the same on 32 and 64bit :)) */		err = sys_semop (first, (struct sembuf *)AA(ptr),				 second);		break;	case SEMGET:		err = sys_semget (first, second, third);		break;	case SEMCTL:		err = do_sys32_semctl (first, second, third,				       (void *)AA(ptr));		break;	case MSGSND:		err = do_sys32_msgsnd (first, second, third,				       (void *)AA(ptr));		break;	case MSGRCV:		err = do_sys32_msgrcv (first, second, fifth, third,				       version, (void *)AA(ptr));		break;	case MSGGET:		err = sys_msgget ((key_t) first, second);		break;	case MSGCTL:		err = do_sys32_msgctl (first, second, (void *)AA(ptr));		break;	case SHMAT:		err = do_sys32_shmat (first, second, third,				      version, (void *)AA(ptr));		break;	case SHMDT: 		err = sys_shmdt ((char *)AA(ptr));		break;	case SHMGET:		err = sys_shmget (first, second, third);		break;	case SHMCTL:		err = do_sys32_shmctl (first, second, (void *)AA(ptr));		break;	default:		err = -EINVAL;		break;	}	return err;}/* * sys_time() can be implemented in user-level using * sys_gettimeofday().  IA64 did this but i386 Linux did not * so we have to implement this system call here. */asmlinkage long sys32_time(int * tloc){	int i;	/* SMP: This is fairly trivial. We grab CURRENT_TIME and 	   stuff it to user space. No side effects */	i = CURRENT_TIME;	if (tloc) {		if (put_user(i,tloc))			i = -EFAULT;	}	return i;}struct rusage32 {        struct timeval32 ru_utime;        struct timeval32 ru_stime;        int    ru_maxrss;        int    ru_ixrss;        int    ru_idrss;        int    ru_isrss;        int    ru_minflt;        int    ru_majflt;        int    ru_nswap;        int    ru_inblock;        int    ru_oublock;        int    ru_msgsnd;         int    ru_msgrcv;         int    ru_nsignals;        int    ru_nvcsw;        int    ru_nivcsw;};static intput_rusage (struct rusage32 *ru, struct rusage *r){	int err;		err = put_user (r->ru_utime.tv_sec, &ru->ru_utime.tv_sec);	err |= __put_user (r->ru_utime.tv_usec, &ru->ru_utime.tv_usec);	err |= __put_user (r->ru_stime.tv_sec, &ru->ru_stime.tv_sec);	err |= __put_user (r->ru_stime.tv_usec, &ru->ru_stime.tv_usec);	err |= __put_user (r->ru_maxrss, &ru->ru_maxrss);	err |= __put_user (r->ru_ixrss, &ru->ru_ixrss);	err |= __put_user (r->ru_idrss, &ru->ru_idrss);	err |= __put_user (r->ru_isrss, &ru->ru_isrss);	err |= __put_user (r->ru_minflt, &ru->ru_minflt);	err |= __put_user (r->ru_majflt, &ru->ru_majflt);	err |= __put_user (r->ru_nswap, &ru->ru_nswap);	err |= __put_user (r->ru_inblock, &ru->ru_inblock);	err |= __put_user (r->ru_oublock, &ru->ru_oublock);	err |= __put_user (r->ru_msgsnd, &ru->ru_msgsnd);	err |= __put_user (r->ru_msgrcv, &ru->ru_msgrcv);	err |= __put_user (r->ru_nsignals, &ru->ru_nsignals);	err |= __put_user (r->ru_nvcsw, &ru->ru_nvcsw);	err |= __put_user (r->ru_nivcsw, &ru->ru_nivcsw);	return err;}extern asmlinkage long sys_wait4(pid_t pid,unsigned int * stat_addr,				int options, struct rusage * ru);asmlinkage longsys32_wait4(__kernel_pid_t32 pid, unsigned int *stat_addr, int options,	    struct rusage32 *ru){	if (!ru)		return sys_wait4(pid, stat_addr, options, NULL);	else {		struct rusage r;		int ret;		unsigned int status;		mm_segment_t old_fs = get_fs();				set_fs (KERNEL_DS);		ret = sys_wait4(pid, stat_addr ? &status : NULL, options, &r);		set_fs (old_fs);		if (put_rusage (ru, &r)) return -EFAULT;		if (stat_addr && put_user (status, stat_addr))			return -EFAULT;		return ret;	}}asmlinkage longsys32_waitpid(__kernel_pid_t32 pid, unsigned int *stat_addr, int options){	return sys32_wait4(pid, stat_addr, options, NULL);}extern asmlinkage longsys_getrusage(int who, struct rusage *ru);asmlinkage longsys32_getrusage(int who, struct rusage32 *ru){	struct rusage r;	int ret;	mm_segment_t old_fs = get_fs();			set_fs (KERNEL_DS);	ret = sys_getrusage(who, &r);	set_fs (old_fs);	if (put_rusage (ru, &r)) return -EFAULT;	return ret;}struct tms32 {	__kernel_clock_t32 tms_utime;	__kernel_clock_t32 tms_stime;	__kernel_clock_t32 tms_cutime;	__kernel_clock_t32 tms_cstime;};                                extern asmlinkage long sys_times(struct tms * tbuf);asmlinkage longsys32_times(struct tms32 *tbuf){	struct tms t;	long ret;	mm_segment_t old_fs = get_fs ();	int err;		set_fs (KERNEL_DS);	ret = sys_times(tbuf ? &t : NULL);	set_fs (old_fs);	if (tbuf) {		err = put_user (IA32_TICK(t.tms_utime), &tbuf->tms_utime);		err |= __put_user (IA32_TICK(t.tms_stime), &tbuf->tms_stime);		err |= __put_user (IA32_TICK(t.tms_cutime), &tbuf->tms_cutime);		err |= __put_user (IA32_TICK(t.tms_cstime), &tbuf->tms_cstime);		if (err)			ret = -EFAULT;	}	return IA32_TICK(ret);}unsigned intia32_peek (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int *val){	size_t copied;	unsigned int ret;	copied = access_process_vm(child, addr, val, sizeof(*val), 0);	return(copied != sizeof(ret) ? -EIO : 0);}unsigned intia32_poke (struct pt_regs *regs, struct task_struct *child, unsigned long addr, unsigned int val){	if (access_process_vm(child, addr, &val, sizeof(val), 1) != sizeof(val))		return -EIO;	return 0;}/* *  The order in which registers are stored in the ptrace regs structure */#define PT_EBX	0#define PT_ECX	1#define PT_EDX	2#define PT_ESI	3#define PT_EDI	4#define PT_EBP	5#define PT_EAX	6#define PT_DS	7#define PT_ES	8#define PT_FS	9#define PT_GS	10#define PT_ORIG_EAX 11#define PT_EIP	12#define PT_CS 	13#define PT_EFL	14#define PT_UESP	15#define PT_SS	16unsigned intgetreg(struct task_struct *child, int regno){	struct pt_regs *child_regs;	child_regs = ia64_task_regs(child);	switch (regno / sizeof(int)) {	case PT_EBX:		return(child_regs->r11);	case PT_ECX:		return(child_regs->r9);	case PT_EDX:		return(child_regs->r10);	case PT_ESI:		return(child_regs->r14);	case PT_EDI:		return(child_regs->r15);	case PT_EBP:		return(child_regs->r13);	case PT_EAX:	case PT_ORIG_EAX:		return(child_regs->r8);	case PT_EIP:		return(child_regs->cr_iip);	case PT_UESP:		return(child_regs->r12);	case PT_EFL:		return(child->thread.eflag);	case PT_DS:	case PT_ES:	case PT_FS:	case PT_GS:	case PT_SS:		return((unsigned int)__USER_DS);	case PT_CS:		return((unsigned int)__USER_CS);	default:		printk("getregs:unknown register %d\n", regno);		break;	}	return(0);}voidputreg(struct task_struct *child, int regno, unsigned int value){	struct pt_regs *child_regs;	child_regs = ia64_task_regs(child);	switch (regno / sizeof(int)) {	case PT_EBX:		child_regs->r11 = value;		break;	case PT_ECX:		child_regs->r9 = value;		break;	case PT_EDX:		child_regs->r10 = value;		break;	case PT_ESI:		child_regs->r14 = value;		break;	case PT_EDI:		child_regs->r15 = value;		break;	case PT_EBP:

⌨️ 快捷键说明

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