📄 sys_ia32.c
字号:
+ 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 + -