Index: compat/linux/linux_file.c =================================================================== RCS file: /home/ncvs/src/sys/compat/linux/linux_file.c,v retrieving revision 1.105 diff -u -r1.105 linux_file.c --- compat/linux/linux_file.c 4 Jul 2007 23:06:43 -0000 1.105 +++ compat/linux/linux_file.c 1 Sep 2007 16:29:38 -0000 @@ -47,6 +47,7 @@ #include #include #include +#include #include #include #include @@ -1131,8 +1132,28 @@ struct file *fp; long arg; int error, result; + struct socket *so; switch (args->cmd) { +#define LINUX_F_SETSIG 10 + case LINUX_F_SETSIG: + error = fget(td, args->fd, &fp); + if (error) + return (error); + if (fp->f_type == DTYPE_SOCKET) { + so = (struct socket *)fp->f_data; + if (so->so_sigio == NULL) { + error = fsetown(td->td_proc->p_pid, &so->so_sigio); + if (error) { + fdrop(fp, td); + return (error); + } + } + so->so_sigio->sig = args->arg; + } else + printf("DTYPE: %i\n", fp->f_type); + fdrop(fp, td); + return (0); case LINUX_F_DUPFD: return (kern_fcntl(td, args->fd, F_DUPFD, args->arg)); Index: compat/linux/linux_misc.c =================================================================== RCS file: /home/ncvs/src/sys/compat/linux/linux_misc.c,v retrieving revision 1.213 diff -u -r1.213 linux_misc.c --- compat/linux/linux_misc.c 12 Jun 2007 00:11:57 -0000 1.213 +++ compat/linux/linux_misc.c 8 Sep 2007 12:27:12 -0000 @@ -63,6 +63,7 @@ #include #include #include +#include #include @@ -92,6 +93,7 @@ #ifdef __i386__ #include +#include #endif #define BSD_TO_LINUX_SIGNAL(sig) \ @@ -847,18 +849,29 @@ options |= WLINUXCLONE; error = kern_wait(td, args->pid, &tmpstat, options, NULL); +#ifdef DEBUG + if (ldebug(waitpid)) + printf("waitpid: returns %d status %08x\n", error, tmpstat); +#endif if (error) return error; if (args->status) { tmpstat &= 0xffff; + if (!(td->td_proc->p_stops & S_PT_SYSGOOD)) + tmpstat &= 0x7fff; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat)); else if (WIFSTOPPED(tmpstat)) tmpstat = (tmpstat & 0xffff00ff) | (BSD_TO_LINUX_SIGNAL(WSTOPSIG(tmpstat)) << 8); - return copyout(&tmpstat, args->status, sizeof(int)); + error = copyout(&tmpstat, args->status, sizeof(int)); +#ifdef DEBUG + if (ldebug(waitpid)) + printf("waitpid: returns %d status %08x\n", error, tmpstat); +#endif + return error; } return 0; @@ -898,6 +911,8 @@ if (args->status) { tmpstat &= 0xffff; + if (!(td->td_proc->p_stops & S_PT_SYSGOOD)) + tmpstat &= 0x7fff; if (WIFSIGNALED(tmpstat)) tmpstat = (tmpstat & 0xffffff80) | BSD_TO_LINUX_SIGNAL(WTERMSIG(tmpstat)); @@ -1557,7 +1572,7 @@ int linux_nosys(struct thread *td, struct nosys_args *ignore) { - + printf("linux: unsupported syscall %d\n", td->td_frame->tf_eax); return (ENOSYS); } Index: i386/conf/GENERIC =================================================================== RCS file: /home/ncvs/src/sys/i386/conf/GENERIC,v retrieving revision 1.473 diff -u -r1.473 GENERIC --- i386/conf/GENERIC 1 Jul 2007 21:47:45 -0000 1.473 +++ i386/conf/GENERIC 2 Sep 2007 08:01:03 -0000 @@ -63,6 +63,8 @@ options STOP_NMI # Stop CPUS using NMI instead of IPI options AUDIT # Security event auditing +options KVA_PAGES=128 + # Debugging for use in -current options KDB # Enable kernel debugger support. options DDB # Support DDB. Index: i386/i386/trap.c =================================================================== RCS file: /home/ncvs/src/sys/i386/i386/trap.c,v retrieving revision 1.307 diff -u -r1.307 trap.c --- i386/i386/trap.c 26 Jul 2007 15:32:55 -0000 1.307 +++ i386/i386/trap.c 6 Sep 2007 03:03:01 -0000 @@ -1004,8 +1004,44 @@ PTRACESTOP_SC(p, td, S_PT_SCE); + if (__predict_false(p->p_sysent->sv_name[0]=='L')) { + if (code != frame->tf_eax) { + printf("linux sysctl patched: code %d return eax %d\n", code, frame->tf_eax); + /* retry */ + if (frame->tf_eax == 0) { + /* skip syscall */ + printf("skip syscall 0\n"); + p->p_stops |= S_PT_SCEMU; + } + code = frame->tf_eax; + + if (p->p_sysent->sv_prepsyscall) + /* + * The prep code is MP aware. + */ + (*p->p_sysent->sv_prepsyscall)(frame, args, &code, ¶ms); + /* else should always be null */ + + if (p->p_sysent->sv_mask) + code &= p->p_sysent->sv_mask; + + if (code >= p->p_sysent->sv_size) + callp = &p->p_sysent->sv_table[0]; + else + callp = &p->p_sysent->sv_table[code]; + + narg = callp->sy_narg; + /* retry ends */ + } + } + AUDIT_SYSCALL_ENTER(code, td); - error = (*callp->sy_call)(td, args); + if (p->p_stops & S_PT_SCEMU) { + p->p_stops &= ~S_PT_SCEMU; + error = frame->tf_eax; + /* don't syscall. It was emulated by sigtrap handler */ + } else + error = (*callp->sy_call)(td, args); AUDIT_SYSCALL_EXIT(error, td); } @@ -1084,6 +1120,7 @@ */ STOPEVENT(p, S_SCX, code); - PTRACESTOP_SC(p, td, S_PT_SCX); + if (!(p->p_stops & S_PT_SCEMU)) + PTRACESTOP_SC(p, td, S_PT_SCX); } Index: i386/include/psl.h =================================================================== RCS file: /home/ncvs/src/sys/i386/include/psl.h,v retrieving revision 1.12 diff -u -r1.12 psl.h --- i386/include/psl.h 7 Apr 2004 20:46:05 -0000 1.12 +++ i386/include/psl.h 2 Sep 2007 12:01:21 -0000 @@ -79,6 +79,6 @@ * 386's. */ #define PSL_USERCHANGE (PSL_C | PSL_PF | PSL_AF | PSL_Z | PSL_N | PSL_T \ - | PSL_D | PSL_V | PSL_NT | PSL_AC | PSL_ID) + | PSL_D | PSL_V | PSL_NT | PSL_AC | PSL_ID | PSL_RF) #endif /* !_MACHINE_PSL_H_ */ Index: i386/linux/linux_machdep.c =================================================================== RCS file: /home/ncvs/src/sys/i386/linux/linux_machdep.c,v retrieving revision 1.78 diff -u -r1.78 linux_machdep.c --- i386/linux/linux_machdep.c 20 Jul 2007 08:35:18 -0000 1.78 +++ i386/linux/linux_machdep.c 8 Sep 2007 12:14:46 -0000 @@ -616,6 +616,38 @@ } int +linux_munmap(struct thread *td, struct linux_munmap_args *uap) +{ + struct munmap_args bsd_args; + vm_map_t map; + vm_map_entry_t entry; + +#ifdef DEBUG + if (ldebug(munmap)) + printf(ARGS(munmap, "%p, %u"), + (void *)uap->addr, uap->len); +#endif + bsd_args.addr = (void *)uap->addr; + if (bsd_args.addr == NULL) { + /* XXX workarund for UMLinux trying to unlock (0;3Gb) */ + map = &td->td_proc->p_vmspace->vm_map; + while(map->root != NULL) { + entry = map->root; +#if 0 + printf("unmap start addr %08x end addr %08x \n", entry->start, entry->end); +#endif + bsd_args.addr = (void *)entry->start; + bsd_args.len = entry->end - entry->start; + munmap(td, &bsd_args); + } + return (0); + } + bsd_args.len = uap->len; +return (munmap(td, &bsd_args)); +} + + +int linux_mmap(struct thread *td, struct linux_mmap_args *args) { int error; @@ -671,8 +703,10 @@ bsd_args.flags |= MAP_FIXED; if (linux_args->flags & LINUX_MAP_ANON) bsd_args.flags |= MAP_ANON; +#if 0 else bsd_args.flags |= MAP_NOSYNC; +#endif if (linux_args->flags & LINUX_MAP_GROWSDOWN) bsd_args.flags |= MAP_STACK; @@ -681,9 +715,17 @@ * on Linux/i386. We do this to ensure maximum compatibility. * Linux/ia64 does the same in i386 emulation mode. */ - bsd_args.prot = linux_args->prot; +#ifdef DEBUGS + printf("linux prot: %08x\n", linux_args->prot); +#endif + bsd_args.prot = (linux_args->prot) & (PROT_READ | PROT_WRITE | PROT_EXEC); +#if 0 if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) bsd_args.prot |= PROT_READ | PROT_EXEC; +#endif +#ifdef DEBUGS + printf("BSD prot: %08x\n", bsd_args.prot); +#endif /* Linux does not check file descriptor when MAP_ANONYMOUS is set. */ bsd_args.fd = (bsd_args.flags & MAP_ANON) ? -1 : linux_args->fd; @@ -785,6 +827,11 @@ __func__, (void *)bsd_args.addr, bsd_args.len, bsd_args.prot, bsd_args.flags, bsd_args.fd, (int)bsd_args.pos); + if (ldebug(mmap)) + printf("%08x <= %p <= %p <= %08x? \n", vm_map_min(&(td->td_proc->p_vmspace->vm_map)), + (void *)bsd_args.addr, (void *)(bsd_args.addr + bsd_args.len), + vm_map_max(&(td->td_proc->p_vmspace->vm_map))); + #endif error = mmap(td, &bsd_args); #ifdef DEBUG @@ -874,6 +921,13 @@ struct l_descriptor ld; union descriptor desc; +#ifdef DEBUG + if(ldebug(modify_ldt)) + printf(ARGS(modify_ldt, "%d: %p %d"), + uap->func, uap->ptr, uap->bytecount); + +#endif + if (uap->ptr == NULL) return (EINVAL); @@ -885,6 +939,17 @@ error = i386_get_ldt(td, &ldt); td->td_retval[0] *= sizeof(union descriptor); break; + case 0x02: { /* read_default_ldt = 0 */ + struct l_desc_struct null_desc[5]; + int size = 5*sizeof(struct l_desc_struct); + + bzero(null_desc, size); + if (size > uap->bytecount) + size = uap->bytecount; + td->td_retval[0] = size; + error = copyout(null_desc, uap->ptr, size); + } + break; case 0x01: /* write_ldt */ case 0x11: /* write_ldt */ if (uap->bytecount != sizeof(ld)) @@ -919,6 +984,12 @@ printf("linux: modify_ldt needs kernel option USER_LDT\n"); error = ENOSYS; } +#ifdef DEBUG + if(ldebug(modify_ldt)) + printf(ARGS(modify_ldt, "returns %d"), + error); + +#endif return (error); } Index: i386/linux/linux_proto.h =================================================================== RCS file: /home/ncvs/src/sys/i386/linux/linux_proto.h,v retrieving revision 1.92 diff -u -r1.92 linux_proto.h --- i386/linux/linux_proto.h 29 Mar 2007 02:11:46 -0000 1.92 +++ i386/linux/linux_proto.h 2 Sep 2007 09:42:14 -0000 @@ -2,8 +2,8 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/i386/linux/linux_proto.h,v 1.92 2007/03/29 02:11:46 julian Exp $ - * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.86 2007/02/15 00:54:40 jkim Exp + * $FreeBSD$ + * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.87 2007/03/29 02:11:46 julian Exp */ #ifndef _LINUX_SYSPROTO_H_ @@ -283,6 +283,10 @@ struct linux_mmap_args { char ptr_l_[PADL_(struct l_mmap_argv *)]; struct l_mmap_argv * ptr; char ptr_r_[PADR_(struct l_mmap_argv *)]; }; +struct linux_munmap_args { + char addr_l_[PADL_(caddr_t)]; caddr_t addr; char addr_r_[PADR_(caddr_t)]; + char len_l_[PADL_(int)]; int len; char len_r_[PADR_(int)]; +}; struct linux_truncate_args { char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; char length_l_[PADL_(l_ulong)]; l_ulong length; char length_r_[PADR_(l_ulong)]; @@ -1009,6 +1037,7 @@ int linux_reboot(struct thread *, struct linux_reboot_args *); int linux_readdir(struct thread *, struct linux_readdir_args *); int linux_mmap(struct thread *, struct linux_mmap_args *); +int linux_munmap(struct thread *, struct linux_munmap_args *); int linux_truncate(struct thread *, struct linux_truncate_args *); int linux_ftruncate(struct thread *, struct linux_ftruncate_args *); int linux_getpriority(struct thread *, struct linux_getpriority_args *); @@ -1192,6 +1226,13 @@ #endif /* COMPAT_FREEBSD4 */ + +#ifdef COMPAT_FREEBSD6 + +#define nosys linux_nosys + +#endif /* COMPAT_FREEBSD6 */ + #define LINUX_SYS_AUE_linux_fork AUE_FORK #define LINUX_SYS_AUE_linux_open AUE_OPEN_RWTC #define LINUX_SYS_AUE_linux_waitpid AUE_WAIT4 @@ -1257,6 +1298,7 @@ #define LINUX_SYS_AUE_linux_reboot AUE_REBOOT #define LINUX_SYS_AUE_linux_readdir AUE_GETDIRENTRIES #define LINUX_SYS_AUE_linux_mmap AUE_MMAP +#define LINUX_SYS_AUE_linux_munmap AUE_MUNMAP #define LINUX_SYS_AUE_linux_truncate AUE_TRUNCATE #define LINUX_SYS_AUE_linux_ftruncate AUE_FTRUNCATE #define LINUX_SYS_AUE_linux_getpriority AUE_GETPRIORITY Index: i386/linux/linux_ptrace.c =================================================================== RCS file: /home/ncvs/src/sys/i386/linux/linux_ptrace.c,v retrieving revision 1.17 diff -u -r1.17 linux_ptrace.c --- i386/linux/linux_ptrace.c 22 Feb 2006 18:57:49 -0000 1.17 +++ i386/linux/linux_ptrace.c 8 Sep 2007 12:55:01 -0000 @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -78,6 +79,15 @@ #define PTRACE_SETFPXREGS 19 #define PTRACE_SETOPTIONS 21 +#define PTRACE_O_TRACESYSGOOD 0x00000001 + +/* Request numbers used by user mode Linux kernel */ + +#define PTRACE_SYSEMU 31 + +#define PTRACE_FAULTINFO 52 + +#define PTRACE_LDT 54 /* * Linux keeps debug registers at the following @@ -86,6 +96,11 @@ #define LINUX_DBREG_OFFSET 252 #define LINUX_DBREG_SIZE (8*sizeof(l_int)) +struct linux_pt_faultinfo { + l_int is_write; + l_long addr; +}; + static __inline int map_signum(int signum) { @@ -95,6 +110,10 @@ return ((signum == SIGSTOP)? 0 : signum); } +struct linux_pt_lreg { + l_long reg[19]; +}; + struct linux_pt_reg { l_long ebx; l_long ecx; @@ -103,17 +122,17 @@ l_long edi; l_long ebp; l_long eax; - l_int xds; - l_int xes; - l_int xfs; - l_int xgs; + l_long xds; + l_long xes; + l_long xfs; + l_long xgs; l_long orig_eax; l_long eip; - l_int xcs; + l_long xcs; l_long eflags; l_long esp; - l_int xss; -}; + l_long xss; +} __packed; /* * Translate i386 ptrace registers between Linux and FreeBSD formats. @@ -247,6 +266,7 @@ struct linux_pt_reg reg; struct linux_pt_fpreg fpreg; struct linux_pt_fpxreg fpxreg; + struct linux_pt_lreg lreg; } r; union { struct reg bsd_reg; @@ -305,9 +325,75 @@ break; case PTRACE_SETREGS: /* Linux is using data where FreeBSD is using addr */ +#ifdef DEBUG +printf("pt_setregs for pid %d\n", pid); + error = kern_ptrace(td, PT_GETREGS, pid, &u.bsd_reg, 0); +printf("getting unning values:\n"); +printf("pt_getregs reg[0], fs %08x\n", u.bsd_reg.r_fs); +printf("pt_getregs reg[1], es %08x\n", u.bsd_reg.r_es); +printf("pt_getregs reg[2], ds %08x\n", u.bsd_reg.r_ds); +printf("pt_getregs reg[3], edi %08x\n", u.bsd_reg.r_edi); +printf("pt_getregs reg[4], esi %08x\n", u.bsd_reg.r_esi); +printf("pt_getregs reg[5], ebp %08x\n", u.bsd_reg.r_ebp); +printf("pt_getregs reg[6], isp %08x\n", u.bsd_reg.r_isp); +printf("pt_getregs reg[7], ebx %08x\n", u.bsd_reg.r_ebx); +printf("pt_getregs reg[8], edx %08x\n", u.bsd_reg.r_edx); +printf("pt_getregs reg[9], ecx %08x\n", u.bsd_reg.r_ecx); +printf("pt_getregs reg[10],eax %08x\n", u.bsd_reg.r_eax); +printf("pt_getregs reg[11],trp %08x\n", u.bsd_reg.r_trapno); +printf("pt_getregs reg[12],err %08x\n", u.bsd_reg.r_err); +printf("pt_getregs reg[13],eip %08x\n", u.bsd_reg.r_eip); +printf("pt_getregs reg[14], cs %08x\n", u.bsd_reg.r_cs); +printf("pt_getregs reg[15],efl %08x\n", u.bsd_reg.r_eflags); +printf("pt_getregs reg[16],esp %08x\n", u.bsd_reg.r_esp); +printf("pt_getregs reg[17], ss %08x\n", u.bsd_reg.r_ss); +printf("pt_getregs reg[18], gs %08x\n", u.bsd_reg.r_gs); +#endif error = copyin((void *)uap->data, &r.reg, sizeof(r.reg)); if (error == 0) { map_regs_from_linux(&u.bsd_reg, &r.reg); +#ifdef DEBUG +printf("setting values:\n"); +printf("pt_setregs for pid %d\n", pid); +printf("pt_getregs reg[0], fs %08x\n", u.bsd_reg.r_fs); +printf("pt_getregs reg[1], es %08x\n", u.bsd_reg.r_es); +printf("pt_getregs reg[2], ds %08x\n", u.bsd_reg.r_ds); +printf("pt_getregs reg[3], edi %08x\n", u.bsd_reg.r_edi); +printf("pt_getregs reg[4], esi %08x\n", u.bsd_reg.r_esi); +printf("pt_getregs reg[5], ebp %08x\n", u.bsd_reg.r_ebp); +printf("pt_getregs reg[6], isp %08x\n", u.bsd_reg.r_isp); +printf("pt_getregs reg[7], ebx %08x\n", u.bsd_reg.r_ebx); +printf("pt_getregs reg[8], edx %08x\n", u.bsd_reg.r_edx); +printf("pt_getregs reg[9], ecx %08x\n", u.bsd_reg.r_ecx); +printf("pt_getregs reg[10],eax %08x\n", u.bsd_reg.r_eax); +printf("pt_getregs reg[11],trp %08x\n", u.bsd_reg.r_trapno); +printf("pt_getregs reg[12],err %08x\n", u.bsd_reg.r_err); +printf("pt_getregs reg[13],eip %08x\n", u.bsd_reg.r_eip); +printf("pt_getregs reg[14], cs %08x\n", u.bsd_reg.r_cs); +printf("pt_getregs reg[15],efl %08x\n", u.bsd_reg.r_eflags); +printf("pt_getregs reg[16],esp %08x\n", u.bsd_reg.r_esp); +printf("pt_getregs reg[17], ss %08x\n", u.bsd_reg.r_ss); +printf("pt_getregs reg[18], gs %08x\n", u.bsd_reg.r_gs); + +printf("pt_getregs lreg[00], ebx %08x\n", r.reg.ebx); +printf("pt_getregs lreg[01], ecx %08x\n", r.reg.ecx); +printf("pt_getregs lreg[02], edx %08x\n", r.reg.edx); +printf("pt_getregs lreg[03], esi %08x\n", r.reg.esi); +printf("pt_getregs lreg[04], edi %08x\n", r.reg.edi); +printf("pt_getregs lreg[05], ebp %08x\n", r.reg.ebp); +printf("pt_getregs lreg[06], eax %08x\n", r.reg.eax); +printf("pt_getregs lreg[07], xds %08x\n", r.reg.xds); +printf("pt_getregs lreg[08], xes %08x\n", r.reg.xes); +printf("pt_getregs lreg[09], xfs %08x\n", r.reg.xfs); +printf("pt_getregs lreg[10], xgs %08x\n", r.reg.xgs); +printf("pt_getregs lreg[11],oeax %08x\n", r.reg.orig_eax); +printf("pt_getregs lreg[12], eip %08x\n", r.reg.eip); +printf("pt_getregs lreg[13], xcs %08x\n", r.reg.xcs); +printf("pt_getregs lreg[14], efl %08x\n", r.reg.eflags); +printf("pt_getregs lreg[15], esp %08x\n", r.reg.esp); +printf("pt_getregs lreg[16], xss %08x\n", r.reg.xss); +printf("tp->tf_eflags %08x\n", td->td_frame->tf_eflags); +#endif error = kern_ptrace(td, PT_SETREGS, pid, &u.bsd_reg, 0); } break; @@ -429,20 +515,22 @@ * as necessary. */ if (uap->addr < sizeof(struct linux_pt_reg)) { + if (uap->addr == (11 << 2)) /* orig_eax */ + uap->addr = (6 << 2); /* eax */ + error = kern_ptrace(td, PT_GETREGS, pid, &u.bsd_reg, 0); if (error != 0) break; map_regs_to_linux(&u.bsd_reg, &r.reg); if (req == PTRACE_PEEKUSR) { - error = copyout((char *)&r.reg + uap->addr, - (void *)uap->data, sizeof(l_int)); + error = copyout((l_long*)(&r.lreg.reg[uap->addr>>2]), + (void *)uap->data, sizeof(l_long)); break; } - *(l_int *)((char *)&r.reg + uap->addr) = - (l_int)uap->data; + r.lreg.reg[uap->addr>>2] = (l_long)uap->data; map_regs_from_linux(&u.bsd_reg, &r.reg); error = kern_ptrace(td, PT_SETREGS, pid, &u.bsd_reg, 0); } @@ -470,11 +558,56 @@ error = kern_ptrace(td, PT_SETDBREGS, pid, &u.bsd_dbreg, 0); } + } + break; + case PTRACE_SETOPTIONS: { + struct proc *p; + if (uap->data == PTRACE_O_TRACESYSGOOD) { + p = td->td_proc; + PROC_LOCK(p); + p->p_stops |= S_PT_SYSGOOD; + PROC_UNLOCK(p); + break; + } + printf("linux: ptrace(21,...,%u) not implemented\n", + (unsigned int)uap->data); + error = EINVAL; + } + break; + case PTRACE_SYSEMU: + /* fallthrough */ +#if 1 + printf("linux: ptrace(%u, ...) not implemented\n", + (unsigned int)uap->req); + error = EINVAL; + break; +#endif + case PTRACE_SYSCALL: { + struct proc *p; + p = td->td_proc; + PROC_LOCK(p); + p->p_stops |= S_PT_LINUX; + if (req == PTRACE_SYSEMU) + p->p_stops |= S_PT_SCEMU; + PROC_UNLOCK(p); + + if (addr == NULL) addr = (void *)1; + error = kern_ptrace(td, PT_SYSCALL, pid, addr, uap->data); + } + break; + case PTRACE_FAULTINFO: + printf("linux: ptrace(PTRACE_FAULTINFO, ...) not implemented\n"); + error = EINVAL; break; + case PTRACE_LDT: { + struct linux_modify_ldt_args ldt; + error = copyin((void *)uap->data, &ldt, sizeof(ldt)); + if (error) + break; + error = linux_modify_ldt(td, &ldt); } - case PTRACE_SYSCALL: - /* fall through */ + break; default: printf("linux: ptrace(%u, ...) not implemented\n", (unsigned int)uap->req); Index: i386/linux/linux_syscall.h =================================================================== RCS file: /home/ncvs/src/sys/i386/linux/linux_syscall.h,v retrieving revision 1.85 diff -u -r1.85 linux_syscall.h --- i386/linux/linux_syscall.h 29 Mar 2007 02:11:46 -0000 1.85 +++ i386/linux/linux_syscall.h 2 Sep 2007 09:42:13 -0000 @@ -2,8 +2,8 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/i386/linux/linux_syscall.h,v 1.85 2007/03/29 02:11:46 julian Exp $ - * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.86 2007/02/15 00:54:40 jkim Exp + * $FreeBSD$ + * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.87 2007/03/29 02:11:46 julian Exp */ #define LINUX_SYS_exit 1 @@ -88,7 +88,7 @@ #define LINUX_SYS_linux_reboot 88 #define LINUX_SYS_linux_readdir 89 #define LINUX_SYS_linux_mmap 90 -#define LINUX_SYS_munmap 91 +#define LINUX_SYS_linux_munmap 91 #define LINUX_SYS_linux_truncate 92 #define LINUX_SYS_linux_ftruncate 93 #define LINUX_SYS_fchmod 94 Index: i386/linux/linux_sysent.c =================================================================== RCS file: /home/ncvs/src/sys/i386/linux/linux_sysent.c,v retrieving revision 1.92 diff -u -r1.92 linux_sysent.c --- i386/linux/linux_sysent.c 29 Mar 2007 02:11:46 -0000 1.92 +++ i386/linux/linux_sysent.c 2 Sep 2007 09:42:13 -0000 @@ -2,8 +2,8 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/i386/linux/linux_sysent.c,v 1.92 2007/03/29 02:11:46 julian Exp $ - * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.86 2007/02/15 00:54:40 jkim Exp + * $FreeBSD$ + * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.87 2007/03/29 02:11:46 julian Exp */ #include @@ -110,7 +110,7 @@ { AS(linux_reboot_args), (sy_call_t *)linux_reboot, AUE_REBOOT, NULL, 0, 0 }, /* 88 = linux_reboot */ { AS(linux_readdir_args), (sy_call_t *)linux_readdir, AUE_GETDIRENTRIES, NULL, 0, 0 }, /* 89 = linux_readdir */ { AS(linux_mmap_args), (sy_call_t *)linux_mmap, AUE_MMAP, NULL, 0, 0 }, /* 90 = linux_mmap */ - { AS(munmap_args), (sy_call_t *)munmap, AUE_MUNMAP, NULL, 0, 0 }, /* 91 = munmap */ + { AS(linux_munmap_args), (sy_call_t *)linux_munmap, AUE_MUNMAP, NULL, 0, 0 }, /* 91 = linux_munmap */ { AS(linux_truncate_args), (sy_call_t *)linux_truncate, AUE_TRUNCATE, NULL, 0, 0 }, /* 92 = linux_truncate */ { AS(linux_ftruncate_args), (sy_call_t *)linux_ftruncate, AUE_FTRUNCATE, NULL, 0, 0 }, /* 93 = linux_ftruncate */ { AS(fchmod_args), (sy_call_t *)fchmod, AUE_FCHMOD, NULL, 0, 0 }, /* 94 = fchmod */ Index: i386/linux/linux_sysvec.c =================================================================== RCS file: /home/ncvs/src/sys/i386/linux/linux_sysvec.c,v retrieving revision 1.149 diff -u -r1.149 linux_sysvec.c --- i386/linux/linux_sysvec.c 2 Apr 2007 18:38:13 -0000 1.149 +++ i386/linux/linux_sysvec.c 2 Sep 2007 08:12:03 -0000 @@ -359,6 +359,7 @@ frame.sf_sc.uc_mcontext.sc_esp_at_signal = regs->tf_esp; frame.sf_sc.uc_mcontext.sc_ss = regs->tf_ss; frame.sf_sc.uc_mcontext.sc_err = regs->tf_err; + frame.sf_sc.uc_mcontext.sc_cr2 = (register_t)ksi->ksi_addr; frame.sf_sc.uc_mcontext.sc_trapno = bsd_to_linux_trapcode(code); #ifdef DEBUG @@ -487,6 +488,7 @@ frame.sf_sc.sc_esp_at_signal = regs->tf_esp; frame.sf_sc.sc_ss = regs->tf_ss; frame.sf_sc.sc_err = regs->tf_err; + frame.sf_sc.sc_cr2 = (register_t)ksi->ksi_addr; frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(ksi->ksi_trapno); for (i = 0; i < (LINUX_NSIG_WORDS-1); i++) Index: i386/linux/syscalls.master =================================================================== RCS file: /home/ncvs/src/sys/i386/linux/syscalls.master,v retrieving revision 1.87 diff -u -r1.87 syscalls.master --- i386/linux/syscalls.master 29 Mar 2007 02:11:46 -0000 1.87 +++ i386/linux/syscalls.master 2 Sep 2007 09:42:06 -0000 @@ -167,7 +167,7 @@ 89 AUE_GETDIRENTRIES STD { int linux_readdir(l_uint fd, \ struct l_dirent *dent, l_uint count); } 90 AUE_MMAP STD { int linux_mmap(struct l_mmap_argv *ptr); } -91 AUE_MUNMAP NOPROTO { int munmap(caddr_t addr, int len); } +91 AUE_MUNMAP STD { int linux_munmap(caddr_t addr, int len); } 92 AUE_TRUNCATE STD { int linux_truncate(char *path, \ l_ulong length); } 93 AUE_FTRUNCATE STD { int linux_ftruncate(int fd, long length); } Index: kern/kern_descrip.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_descrip.c,v retrieving revision 1.313 diff -u -r1.313 kern_descrip.c --- kern/kern_descrip.c 6 Aug 2007 14:26:00 -0000 1.313 +++ kern/kern_descrip.c 1 Sep 2007 13:01:31 -0000 @@ -891,6 +891,7 @@ sigio->sio_pgid = pgid; sigio->sio_ucred = crhold(curthread->td_ucred); sigio->sio_myref = sigiop; + sigio->sig = 0; sx_slock(&proctree_lock); if (pgid > 0) { Index: kern/kern_sig.c =================================================================== RCS file: /home/ncvs/src/sys/kern/kern_sig.c,v retrieving revision 1.349 diff -u -r1.349 kern_sig.c --- kern/kern_sig.c 19 Jul 2007 08:49:16 -0000 1.349 +++ kern/kern_sig.c 1 Sep 2007 13:01:30 -0000 @@ -3187,6 +3187,10 @@ SIGIO_UNLOCK(); return; } + if (sigio->sig != 0) { + printf("LINUX SETSIG works\n"); + sig = sigio->sig; + } if (sigio->sio_pgid > 0) { PROC_LOCK(sigio->sio_proc); if (CANSIGIO(sigio->sio_ucred, sigio->sio_proc->p_ucred)) Index: modules/linux/Makefile =================================================================== RCS file: /home/ncvs/src/sys/modules/linux/Makefile,v retrieving revision 1.72 diff -u -r1.72 Makefile --- modules/linux/Makefile 23 May 2007 15:45:52 -0000 1.72 +++ modules/linux/Makefile 23 Aug 2007 05:49:02 -0000 @@ -4,6 +4,7 @@ SFX= 32 CFLAGS+=-DCOMPAT_IA32 -DCOMPAT_LINUX32 .endif +CFLAGS+=-DDEBUG .PATH: ${.CURDIR}/../../compat/linux ${.CURDIR}/../../${MACHINE_ARCH}/linux${SFX} Index: sys/ptrace.h =================================================================== RCS file: /home/ncvs/src/sys/sys/ptrace.h,v retrieving revision 1.28 diff -u -r1.28 ptrace.h --- sys/ptrace.h 6 Feb 2006 09:41:56 -0000 1.28 +++ sys/ptrace.h 22 Aug 2007 16:02:31 -0000 @@ -103,7 +103,12 @@ #define PTRACESTOP_SC(p, td, flag) \ if ((p)->p_flag & P_TRACED && (p)->p_stops & (flag)) { \ PROC_LOCK(p); \ - ptracestop((td), SIGTRAP); \ + if (__predict_false(p->p_sysent->sv_name[0]=='L')) { \ + (p)->p_stops &= ~(S_PT_SCE | S_PT_SCX); \ + ptracestop((td), SIGTRAP | 0x80); \ + } \ + else \ + ptracestop((td), SIGTRAP); \ PROC_UNLOCK(p); \ } /* @@ -112,6 +117,21 @@ */ #define S_PT_SCE 0x000010000 #define S_PT_SCX 0x000020000 +/* + * Linux ptrace conventions: clear S_PT_SCE and S_PT_SCX before raising + * signals + */ +#define S_PT_LINUX 0x000040000 +/* + * Linux ptrace option PTRACE_O_TRACESYSGOOD, when enabled, changes signal + * number to ( SIGTRAP | 0x80 ) + */ +#define S_PT_SYSGOOD 0x000080000 +/* + * Linux ptrace call PTRACE_SYSEMU is similar to PTRACE_SYSCALL, but native + * syscall handler will NOT be called. + */ +#define S_PT_SCEMU 0x000100000 int ptrace_set_pc(struct thread *_td, unsigned long _addr); int ptrace_single_step(struct thread *_td); Index: sys/sigio.h =================================================================== RCS file: /home/ncvs/src/sys/sys/sigio.h,v retrieving revision 1.3 diff -u -r1.3 sigio.h --- sys/sigio.h 7 Jan 2005 02:29:24 -0000 1.3 +++ sys/sigio.h 1 Sep 2007 13:01:31 -0000 @@ -53,6 +53,7 @@ * the reference to this structure */ struct ucred *sio_ucred; /* (c) current credentials */ pid_t sio_pgid; /* (c) pgid for signals */ + int sig; /* (pg) signal to be sent */ }; #define sio_proc sio_u.siu_proc #define sio_pgrp sio_u.siu_pgrp Index: vm/vm_map.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_map.c,v retrieving revision 1.386 diff -u -r1.386 vm_map.c --- vm/vm_map.c 31 May 2007 22:52:15 -0000 1.386 +++ vm/vm_map.c 8 Sep 2007 09:04:43 -0000 @@ -877,9 +877,9 @@ vm_map_entry_t cur; cur = vm_map_entry_splay(address, map->root); - if (cur == NULL) + if (cur == NULL) { *entry = &map->header; - else { + } else { map->root = cur; if (address >= cur->start) { @@ -2420,23 +2420,32 @@ vm_map_entry_t entry; vm_map_entry_t tmp_entry; - if (!vm_map_lookup_entry(map, start, &tmp_entry)) + if (!vm_map_lookup_entry(map, start, &tmp_entry)) { + printf("check_protection: !vm_map_lookup_entry started at %08x (end %08x)\n", start, end); return (FALSE); + } entry = tmp_entry; while (start < end) { - if (entry == &map->header) + if (entry == &map->header) { + printf("check_protection: entry %p is a header?\n", entry); return (FALSE); + } /* * No holes allowed! */ - if (start < entry->start) + if (start < entry->start) { + printf("check_protection: hole: start %08x < entry->start %08x, (end=%08x)\n", start, entry->start, end); return (FALSE); + } /* * Check protection associated with entry. */ - if ((entry->protection & protection) != protection) + if ((entry->protection & protection) != protection) { + printf("check_protection: wrong protection (entry) %08x (asked) %08x\n", + entry->protection, protection); return (FALSE); + } /* go to next entry */ start = entry->end; entry = entry->next; Index: vm/vm_mmap.c =================================================================== RCS file: /home/ncvs/src/sys/vm/vm_mmap.c,v retrieving revision 1.212 diff -u -r1.212 vm_mmap.c --- vm/vm_mmap.c 4 Jul 2007 22:57:21 -0000 1.212 +++ vm/vm_mmap.c 8 Sep 2007 05:45:34 -0000 @@ -545,21 +547,26 @@ addr -= pageoff; size += pageoff; size = (vm_size_t) round_page(size); - if (addr + size < addr) + if (addr + size < addr) { + printf("munmap failed: addr + size < addr (%u + %u == %u < %u)\n", addr, size, addr + size, addr); return (EINVAL); + } /* * Check for illegal addresses. Watch out for address wrap... */ map = &td->td_proc->p_vmspace->vm_map; - if (addr < vm_map_min(map) || addr + size > vm_map_max(map)) + if (addr < vm_map_min(map) || addr + size > vm_map_max(map)) { + printf("munmap failed: out of vm_map bound\n"); return (EINVAL); + } vm_map_lock(map); /* * Make sure entire range is allocated. */ if (!vm_map_check_protection(map, addr, addr + size, VM_PROT_NONE)) { vm_map_unlock(map); + printf("munmap failed: vm_map_check_protection VM_PROT_NONE failed\n"); return (EINVAL); } #ifdef HWPMC_HOOKS