Index: sys/amd64/linux32/linux.h =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/amd64/linux32/linux.h,v retrieving revision 1.1 diff -u -u -r1.1 linux.h --- sys/amd64/linux32/linux.h 16 Aug 2004 07:55:06 -0000 1.1 +++ sys/amd64/linux32/linux.h 29 Jun 2007 06:39:37 -0000 @@ -8,7 +8,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer + * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the @@ -30,10 +30,8 @@ * $FreeBSD: src/sys/amd64/linux32/linux.h,v 1.1 2004/08/16 07:55:06 tjr Exp $ */ -#ifndef _AMD64_LINUX_LINUX_H_ -#define _AMD64_LINUX_LINUX_H_ - -#include /* for sigval union */ +#ifndef _AMD64_LINUX_H_ +#define _AMD64_LINUX_H_ #include @@ -41,20 +39,20 @@ * debugging support */ extern u_char linux_debug_map[]; -#define ldebug(name) isclr(linux_debug_map, LINUX_SYS_linux_ ## name) -#define ARGS(nm, fmt) "linux(%ld): "#nm"("fmt")\n", (long)td->td_proc->p_pid -#define LMSG(fmt) "linux(%ld): "fmt"\n", (long)td->td_proc->p_pid +#define ldebug(name) isclr(linux_debug_map, LINUX_SYS_linux_ ## name) +#define ARGS(nm, fmt) "linux(%ld): "#nm"("fmt")\n", (long)td->td_proc->p_pid +#define LMSG(fmt) "linux(%ld): "fmt"\n", (long)td->td_proc->p_pid #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_LINUX); #endif -#define LINUX32_USRSTACK ((1ul << 32) - PAGE_SIZE) +#define LINUX32_USRSTACK ((1ul << 32) - PAGE_SIZE) /* XXX 16 = sizeof(linux32_ps_strings) */ -#define LINUX32_PS_STRINGS (LINUX32_USRSTACK - 16) -#define LINUX32_MAXDSIZ (512*1024*1024) /* 512MB */ -#define LINUX32_MAXSSIZ (64*1024*1024) /* 64MB */ -#define LINUX32_MAXVMEM 0 /* Unlimited */ +#define LINUX32_PS_STRINGS (LINUX32_USRSTACK - 16) +#define LINUX32_MAXDSIZ (512 * 1024 * 1024) /* 512MB */ +#define LINUX32_MAXSSIZ (64 * 1024 * 1024) /* 64MB */ +#define LINUX32_MAXVMEM 0 /* Unlimited */ #define PTRIN(v) (void *)(uintptr_t)(v) #define PTROUT(v) (l_uintptr_t)(uintptr_t)(v) @@ -134,7 +132,7 @@ #define LINUX_RLIMIT_NPROC 6 #define LINUX_RLIMIT_NOFILE 7 #define LINUX_RLIMIT_MEMLOCK 8 -#define LINUX_RLIMIT_AS 9 /* address space limit */ +#define LINUX_RLIMIT_AS 9 /* Address space limit */ #define LINUX_RLIM_NLIMITS 10 @@ -169,12 +167,21 @@ #define LINUX_MAP_ANON 0x0020 #define LINUX_MAP_GROWSDOWN 0x0100 +struct l_mmap_argv { + l_uintptr_t addr; + l_size_t len; + l_int prot; + l_int flags; + l_int fd; + l_off_t pgoff; +} __packed; + /* * stat family of syscalls */ struct l_timespec { - l_ulong tv_sec; - l_ulong tv_nsec; + l_time_t tv_sec; + l_long tv_nsec; } __packed; struct l_newstat { @@ -197,6 +204,24 @@ l_ulong __unused5; } __packed; +struct l_stat { + l_ushort st_dev; + l_ulong st_ino; + l_ushort st_mode; + l_ushort st_nlink; + l_ushort st_uid; + l_ushort st_gid; + l_ushort st_rdev; + l_long st_size; + struct l_timespec st_atimespec; + struct l_timespec st_mtimespec; + struct l_timespec st_ctimespec; + l_long st_blksize; + l_long st_blocks; + l_ulong st_flags; + l_ulong st_gen; +}; + struct l_stat64 { l_ushort st_dev; u_char __pad0[10]; @@ -290,9 +315,9 @@ #define LINUX_SIGADDSET(set, sig) SIGADDSET(set, sig) /* sigaltstack */ -#define LINUX_MINSIGSTKSZ 2048 -#define LINUX_SS_ONSTACK 1 -#define LINUX_SS_DISABLE 2 +#define LINUX_MINSIGSTKSZ 2048 +#define LINUX_SS_ONSTACK 1 +#define LINUX_SS_DISABLE 2 int linux_to_bsd_sigaltstack(int lsa); int bsd_to_linux_sigaltstack(int bsa); @@ -355,11 +380,16 @@ l_uintptr_t uc_link; l_stack_t uc_stack; struct l_sigcontext uc_mcontext; - l_sigset_t uc_sigmask; + l_sigset_t uc_sigmask; } __packed; -#define LINUX_SI_MAX_SIZE 128 -#define LINUX_SI_PAD_SIZE ((LINUX_SI_MAX_SIZE/sizeof(l_int)) - 3) +#define LINUX_SI_MAX_SIZE 128 +#define LINUX_SI_PAD_SIZE ((LINUX_SI_MAX_SIZE/sizeof(l_int)) - 3) + +union l_sigval { + l_int sival_int; + l_uintptr_t sival_ptr; +}; typedef struct l_siginfo { l_int lsi_signo; @@ -381,7 +411,7 @@ struct { l_pid_t _pid; /* sender's pid */ l_uid16_t _uid; /* sender's uid */ - union sigval _sigval; + union l_sigval _sigval; } __packed _rt; struct { @@ -393,41 +423,41 @@ } __packed _sigchld; struct { - l_uintptr_t _addr; /* faulting insn/memory ref. */ + l_uintptr_t _addr; /* Faulting insn/memory ref. */ } __packed _sigfault; struct { - l_int _band; /* POLL_IN,POLL_OUT,POLL_MSG */ + l_int _band; /* POLL_IN,POLL_OUT,POLL_MSG */ l_int _fd; } __packed _sigpoll; } _sifields; } __packed l_siginfo_t; -#define lsi_pid _sifields._kill._pid -#define lsi_uid _sifields._kill._uid -#define lsi_status _sifields._sigchld._status -#define lsi_utime _sifields._sigchld._utime -#define lsi_stime _sifields._sigchld._stime -#define lsi_value _sifields._rt._sigval -#define lsi_int _sifields._rt._sigval.sival_int -#define lsi_ptr _sifields._rt._sigval.sival_ptr -#define lsi_addr _sifields._sigfault._addr -#define lsi_band _sifields._sigpoll._band -#define lsi_fd _sifields._sigpoll._fd +#define lsi_pid _sifields._kill._pid +#define lsi_uid _sifields._kill._uid +#define lsi_status _sifields._sigchld._status +#define lsi_utime _sifields._sigchld._utime +#define lsi_stime _sifields._sigchld._stime +#define lsi_value _sifields._rt._sigval +#define lsi_int _sifields._rt._sigval.sival_int +#define lsi_ptr _sifields._rt._sigval.sival_ptr +#define lsi_addr _sifields._sigfault._addr +#define lsi_band _sifields._sigpoll._band +#define lsi_fd _sifields._sigpoll._fd struct l_fpreg { - u_int16_t significand[4]; - u_int16_t exponent; + u_int16_t significand[4]; + u_int16_t exponent; } __packed; struct l_fpxreg { - u_int16_t significand[4]; - u_int16_t exponent; - u_int16_t padding[3]; + u_int16_t significand[4]; + u_int16_t exponent; + u_int16_t padding[3]; } __packed; struct l_xmmreg { - u_int32_t element[4]; + u_int32_t element[4]; } __packed; struct l_fpstate { @@ -441,13 +471,13 @@ u_int32_t datasel; struct l_fpreg _st[8]; u_int16_t status; - u_int16_t magic; /* 0xffff = regular FPU data */ + u_int16_t magic; /* 0xffff = regular FPU data */ /* FXSR FPU environment */ - u_int32_t _fxsr_env[6]; /* env is ignored */ + u_int32_t _fxsr_env[6]; /* env is ignored. */ u_int32_t mxcsr; u_int32_t reserved; - struct l_fpxreg _fxsr_st[8]; /* reg data is ignored */ + struct l_fpxreg _fxsr_st[8]; /* reg data is ignored. */ struct l_xmmreg _xmm[8]; u_int32_t padding[56]; } __packed; @@ -497,18 +527,24 @@ /* * open/fcntl flags */ -#define LINUX_O_RDONLY 00 -#define LINUX_O_WRONLY 01 -#define LINUX_O_RDWR 02 -#define LINUX_O_CREAT 0100 -#define LINUX_O_EXCL 0200 -#define LINUX_O_NOCTTY 0400 -#define LINUX_O_TRUNC 01000 -#define LINUX_O_APPEND 02000 -#define LINUX_O_NONBLOCK 04000 +#define LINUX_O_RDONLY 00000000 +#define LINUX_O_WRONLY 00000001 +#define LINUX_O_RDWR 00000002 +#define LINUX_O_ACCMODE 00000003 +#define LINUX_O_CREAT 00000100 +#define LINUX_O_EXCL 00000200 +#define LINUX_O_NOCTTY 00000400 +#define LINUX_O_TRUNC 00001000 +#define LINUX_O_APPEND 00002000 +#define LINUX_O_NONBLOCK 00004000 #define LINUX_O_NDELAY LINUX_O_NONBLOCK -#define LINUX_O_SYNC 010000 -#define LINUX_FASYNC 020000 +#define LINUX_O_SYNC 00010000 +#define LINUX_FASYNC 00020000 +#define LINUX_O_DIRECT 00040000 /* Direct disk access hint */ +#define LINUX_O_LARGEFILE 00100000 +#define LINUX_O_DIRECTORY 00200000 /* Must be a directory */ +#define LINUX_O_NOFOLLOW 00400000 /* Do not follow links */ +#define LINUX_O_NOATIME 01000000 #define LINUX_F_DUPFD 0 #define LINUX_F_GETFD 1 @@ -529,15 +565,17 @@ #define LINUX_F_WRLCK 1 #define LINUX_F_UNLCK 2 +#define LINUX_AT_FDCWD -100 + /* * mount flags */ -#define LINUX_MS_RDONLY 0x0001 -#define LINUX_MS_NOSUID 0x0002 -#define LINUX_MS_NODEV 0x0004 -#define LINUX_MS_NOEXEC 0x0008 -#define LINUX_MS_REMOUNT 0x0020 - +#define LINUX_MS_RDONLY 0x0001 +#define LINUX_MS_NOSUID 0x0002 +#define LINUX_MS_NODEV 0x0004 +#define LINUX_MS_NOEXEC 0x0008 +#define LINUX_MS_REMOUNT 0x0020 + /* * SystemV IPC defines */ @@ -635,6 +673,13 @@ #define LINUX_SO_NO_CHECK 11 #define LINUX_SO_PRIORITY 12 #define LINUX_SO_LINGER 13 +#define LINUX_SO_PEERCRED 17 +#define LINUX_SO_RCVLOWAT 18 +#define LINUX_SO_SNDLOWAT 19 +#define LINUX_SO_RCVTIMEO 20 +#define LINUX_SO_SNDTIMEO 21 +#define LINUX_SO_TIMESTAMP 29 +#define LINUX_SO_ACCEPTCONN 30 #define LINUX_IP_TOS 1 #define LINUX_IP_TTL 2 @@ -684,7 +729,7 @@ } ifr_ifru; } __packed; -#define ifr_name ifr_ifrn.ifrn_name /* interface name */ +#define ifr_name ifr_ifrn.ifrn_name /* Interface name */ #define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ struct l_ifconf { @@ -719,4 +764,11 @@ l_short revents; } __packed; +#define LINUX_CLOCK_REALTIME 0 +#define LINUX_CLOCK_MONOTONIC 1 +#define LINUX_CLOCK_PROCESS_CPUTIME_ID 2 +#define LINUX_CLOCK_THREAD_CPUTIME_ID 3 +#define LINUX_CLOCK_REALTIME_HR 4 +#define LINUX_CLOCK_MONOTONIC_HR 5 + #endif /* !_AMD64_LINUX_LINUX_H_ */ Index: sys/amd64/linux32/linux32_dummy.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/amd64/linux32/linux32_dummy.c,v retrieving revision 1.1 diff -u -u -r1.1 linux32_dummy.c --- sys/amd64/linux32/linux32_dummy.c 16 Aug 2004 07:55:06 -0000 1.1 +++ sys/amd64/linux32/linux32_dummy.c 29 Jun 2007 06:46:16 -0000 @@ -67,7 +67,46 @@ DUMMY(mincore); DUMMY(fadvise64); DUMMY(ptrace); -DUMMY(settimeofday); +DUMMY(mq_open); +DUMMY(mq_unlink); +DUMMY(mq_timedsend); +DUMMY(mq_timedreceive); +DUMMY(mq_notify); +DUMMY(mq_getsetattr); +DUMMY(fstatfs64); +DUMMY(tgkill); +DUMMY(fadvise64_64); +DUMMY(mbind); +DUMMY(get_mempolicy); +DUMMY(set_mempolicy); +DUMMY(kexec_load); +DUMMY(waitid); +DUMMY(add_key); +DUMMY(request_key); +DUMMY(keyctl); +DUMMY(ioprio_set); +DUMMY(ioprio_get); +DUMMY(inotify_init); +DUMMY(inotify_add_watch); +DUMMY(inotify_rm_watch); +DUMMY(migrate_pages); +DUMMY(mkdirat); +DUMMY(mknodat); +DUMMY(fchownat); +DUMMY(futimesat); +DUMMY(fstatat64); +DUMMY(unlinkat); +DUMMY(renameat); +DUMMY(linkat); +DUMMY(symlinkat); +DUMMY(readlinkat); +DUMMY(fchmodat); +DUMMY(faccessat); +DUMMY(pselect6); +DUMMY(ppoll); +DUMMY(unshare); +DUMMY(tgkill); +DUMMY(openat); #define DUMMY_XATTR(s) \ int \ Index: sys/amd64/linux32/linux32_machdep.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/amd64/linux32/linux32_machdep.c,v retrieving revision 1.10 diff -u -u -r1.10 linux32_machdep.c --- sys/amd64/linux32/linux32_machdep.c 24 Jun 2005 17:41:27 -0000 1.10 +++ sys/amd64/linux32/linux32_machdep.c 29 Jun 2007 06:43:36 -0000 @@ -34,6 +34,8 @@ #include #include #include +#include +#include #include #include #include @@ -47,6 +49,7 @@ #include #include +#include #include #include @@ -113,7 +116,7 @@ * Allocate temporary demand zeroed space for argument and * environment strings */ - args->buf = (char *) kmem_alloc_wait(exec_map, + args->buf = (char *)kmem_alloc_wait(exec_map, PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); if (args->buf == NULL) return (ENOMEM); @@ -130,7 +133,7 @@ copystr(fname, args->fname, PATH_MAX, &length) : copyinstr(fname, args->fname, PATH_MAX, &length); if (error != 0) - return (error); + goto err_exit; /* * extract arguments first @@ -139,22 +142,22 @@ for (;;) { error = copyin(p32++, &arg, sizeof(arg)); if (error) - return (error); + goto err_exit; if (arg == 0) break; argp = PTRIN(arg); error = copyinstr(argp, args->endp, args->stringspace, &length); if (error) { if (error == ENAMETOOLONG) - return (E2BIG); - else - return (error); + error = E2BIG; + + goto err_exit; } args->stringspace -= length; args->endp += length; args->argc++; } - + args->begin_envv = args->endp; /* @@ -165,7 +168,7 @@ for (;;) { error = copyin(p32++, &arg, sizeof(arg)); if (error) - return (error); + goto err_exit; if (arg == 0) break; envp = PTRIN(arg); @@ -173,9 +176,8 @@ &length); if (error) { if (error == ENAMETOOLONG) - return (E2BIG); - else - return (error); + error = E2BIG; + goto err_exit; } args->stringspace -= length; args->endp += length; @@ -184,6 +186,12 @@ } return (0); + +err_exit: + kmem_free_wakeup(exec_map, (vm_offset_t)args->buf, + PATH_MAX + ARG_MAX + MAXSHELLCMDLEN); + args->buf = NULL; + return (error); } int @@ -229,7 +237,7 @@ if (iovcnt > UIO_MAXIOV) return (EINVAL); iovlen = iovcnt * sizeof(struct iovec); - uio = malloc(iovlen + sizeof *uio, M_IOV, M_WAITOK); + uio = malloc(iovlen + sizeof(*uio), M_IOV, M_WAITOK); iov = (struct iovec *)(uio + 1); for (i = 0; i < iovcnt; i++) { error = copyin(&iovp[i], &iov32, sizeof(struct iovec32)); @@ -539,16 +547,6 @@ return (0); } -/* XXX move */ -struct l_mmap_argv { - l_ulong addr; - l_ulong len; - l_ulong prot; - l_ulong flags; - l_ulong fd; - l_ulong pgoff; -}; - #define STACK_SIZE (2 * 1024 * 1024) #define GUARD_SIZE (4 * PAGE_SIZE) @@ -561,8 +559,8 @@ #ifdef DEBUG if (ldebug(mmap2)) - printf(ARGS(mmap2, "%p, %d, %d, 0x%08x, %d, %d"), - (void *)(intptr_t)args->addr, args->len, args->prot, + printf(ARGS(mmap2, "0x%08x, %d, %d, 0x%08x, %d, %d"), + args->addr, args->len, args->prot, args->flags, args->fd, args->pgoff); #endif @@ -588,10 +586,9 @@ #ifdef DEBUG if (ldebug(mmap)) - printf(ARGS(mmap, "%p, %d, %d, 0x%08x, %d, %d"), - (void *)(intptr_t)linux_args.addr, linux_args.len, - linux_args.prot, linux_args.flags, linux_args.fd, - linux_args.pgoff); + printf(ARGS(mmap, "0x%08x, %d, %d, 0x%08x, %d, %d"), + linux_args.addr, linux_args.len, linux_args.prot, + linux_args.flags, linux_args.fd, linux_args.pgoff); #endif if ((linux_args.pgoff % PAGE_SIZE) != 0) return (EINVAL); @@ -614,9 +611,20 @@ off_t pos; } */ bsd_args; int error; + struct file *fp; error = 0; bsd_args.flags = 0; + fp = NULL; + + /* + * Linux mmap(2): + * You must specify exactly one of MAP_SHARED and MAP_PRIVATE + */ + if (! ((linux_args->flags & LINUX_MAP_SHARED) ^ + (linux_args->flags & LINUX_MAP_PRIVATE))) + return (EINVAL); + if (linux_args->flags & LINUX_MAP_SHARED) bsd_args.flags |= MAP_SHARED; if (linux_args->flags & LINUX_MAP_PRIVATE) @@ -627,23 +635,60 @@ bsd_args.flags |= MAP_ANON; else bsd_args.flags |= MAP_NOSYNC; - if (linux_args->flags & LINUX_MAP_GROWSDOWN) { + if (linux_args->flags & LINUX_MAP_GROWSDOWN) bsd_args.flags |= MAP_STACK; - /* The linux MAP_GROWSDOWN option does not limit auto + /* + * PROT_READ, PROT_WRITE, or PROT_EXEC implies PROT_READ and PROT_EXEC + * 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; + if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) + bsd_args.prot |= PROT_READ | PROT_EXEC; + + /* Linux does not check file descriptor when MAP_ANONYMOUS is set. */ + bsd_args.fd = (bsd_args.flags & MAP_ANON) ? -1 : linux_args->fd; + if (bsd_args.fd != -1) { + /* + * Linux follows Solaris mmap(2) description: + * The file descriptor fildes is opened with + * read permission, regardless of the + * protection options specified. + */ + + if ((error = fget(td, bsd_args.fd, &fp)) != 0) + return (error); + if (fp->f_type != DTYPE_VNODE) { + fdrop(fp, td); + return (EINVAL); + } + + /* Linux mmap() just fails for O_WRONLY files */ + if (!(fp->f_flag & FREAD)) { + fdrop(fp, td); + return (EACCES); + } + + fdrop(fp, td); + } + + if (linux_args->flags & LINUX_MAP_GROWSDOWN) { + /* + * The Linux MAP_GROWSDOWN option does not limit auto * growth of the region. Linux mmap with this option * takes as addr the inital BOS, and as len, the initial * region size. It can then grow down from addr without - * limit. However, linux threads has an implicit internal + * limit. However, Linux threads has an implicit internal * limit to stack size of STACK_SIZE. Its just not - * enforced explicitly in linux. But, here we impose + * enforced explicitly in Linux. But, here we impose * a limit of (STACK_SIZE - GUARD_SIZE) on the stack * region, since we can do this with our mmap. * * Our mmap with MAP_STACK takes addr as the maximum * downsize limit on BOS, and as len the max size of - * the region. It them maps the top SGROWSIZ bytes, - * and autgrows the region down, up to the limit + * the region. It then maps the top SGROWSIZ bytes, + * and auto grows the region down, up to the limit * in addr. * * If we don't use the MAP_STACK option, the effect @@ -651,13 +696,10 @@ * fixed size of (STACK_SIZE - GUARD_SIZE). */ - /* This gives us TOS */ - bsd_args.addr = (caddr_t)PTRIN(linux_args->addr) + - linux_args->len; - - if ((caddr_t)PTRIN(bsd_args.addr) > + if ((caddr_t)PTRIN(linux_args->addr) + linux_args->len > p->p_vmspace->vm_maxsaddr) { - /* Some linux apps will attempt to mmap + /* + * Some Linux apps will attempt to mmap * thread stacks near the top of their * address space. If their TOS is greater * than vm_maxsaddr, vm_map_growstack() @@ -673,8 +715,7 @@ * mmap's return value. */ PROC_LOCK(p); - p->p_vmspace->vm_maxsaddr = - (char *)LINUX32_USRSTACK - + p->p_vmspace->vm_maxsaddr = (char *)LINUX32_USRSTACK - lim_cur(p, RLIMIT_STACK); PROC_UNLOCK(p); } @@ -685,28 +726,19 @@ else bsd_args.len = STACK_SIZE - GUARD_SIZE; - /* This gives us a new BOS. If we're using VM_STACK, then + /* + * This gives us a new BOS. If we're using VM_STACK, then * mmap will just map the top SGROWSIZ bytes, and let * the stack grow down to the limit at BOS. If we're * not using VM_STACK we map the full stack, since we * don't have a way to autogrow it. */ - bsd_args.addr -= bsd_args.len; + bsd_args.addr = (caddr_t)PTRIN(linux_args->addr) - + bsd_args.len; } else { bsd_args.addr = (caddr_t)PTRIN(linux_args->addr); bsd_args.len = linux_args->len; } - /* - * XXX i386 Linux always emulator forces PROT_READ on (why?) - * so we do the same. We add PROT_EXEC to work around buggy - * applications (e.g. Java) that take advantage of the fact - * that execute permissions are not enforced by x86 CPUs. - */ - bsd_args.prot = linux_args->prot | PROT_EXEC | PROT_READ; - if (linux_args->flags & LINUX_MAP_ANON) - bsd_args.fd = -1; - else - bsd_args.fd = linux_args->fd; bsd_args.pos = (off_t)linux_args->pgoff * PAGE_SIZE; bsd_args.pad = 0; @@ -727,6 +759,36 @@ } int +linux_mprotect(struct thread *td, struct linux_mprotect_args *uap) +{ + struct mprotect_args bsd_args; + + bsd_args.addr = uap->addr; + bsd_args.len = uap->len; + bsd_args.prot = uap->prot; + if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) + bsd_args.prot |= PROT_READ | PROT_EXEC; + return (mprotect(td, &bsd_args)); +} + +int +linux_iopl(struct thread *td, struct linux_iopl_args *args) +{ + int error; + + if (args->level < 0 || args->level > 3) + return (EINVAL); + if ((error = suser(td)) != 0) + return (error); + if ((error = securelevel_gt(td->td_ucred, 0)) != 0) + return (error); + td->td_frame->tf_rflags = (td->td_frame->tf_rflags & ~PSL_IOPL) | + (args->level * (PSL_IOPL / 3)); + + return (0); +} + +int linux_pipe(struct thread *td, struct linux_pipe_args *args) { int pip[2]; @@ -797,7 +859,7 @@ } /* - * Linux has two extra args, restart and oldmask. We dont use these, + * Linux has two extra args, restart and oldmask. We don't use these, * but it seems that "restart" is actually a context pointer that * enables the signal to happen with a different register set. */ @@ -921,35 +983,41 @@ microtime(&atv); atv32.tv_sec = atv.tv_sec; atv32.tv_usec = atv.tv_usec; - error = copyout(&atv32, uap->tp, sizeof (atv32)); + error = copyout(&atv32, uap->tp, sizeof(atv32)); } if (error == 0 && uap->tzp != NULL) { rtz.tz_minuteswest = tz_minuteswest; rtz.tz_dsttime = tz_dsttime; - error = copyout(&rtz, uap->tzp, sizeof (rtz)); + error = copyout(&rtz, uap->tzp, sizeof(rtz)); } return (error); } int -linux_nanosleep(struct thread *td, struct linux_nanosleep_args *uap) +linux_settimeofday(struct thread *td, struct linux_settimeofday_args *uap) { - struct timespec rqt, rmt; - struct l_timespec ats32; + l_timeval atv32; + struct timeval atv, *tvp; + struct timezone atz, *tzp; int error; - error = copyin(uap->rqtp, &ats32, sizeof(ats32)); - if (error != 0) - return (error); - rqt.tv_sec = ats32.tv_sec; - rqt.tv_nsec = ats32.tv_nsec; - error = kern_nanosleep(td, &rqt, &rmt); - if (uap->rmtp != NULL) { - ats32.tv_sec = rmt.tv_sec; - ats32.tv_nsec = rmt.tv_nsec; - error = copyout(&ats32, uap->rmtp, sizeof(ats32)); - } - return (error); + if (uap->tp) { + error = copyin(uap->tp, &atv32, sizeof(atv32)); + if (error) + return (error); + atv.tv_sec = atv32.tv_sec; + atv.tv_usec = atv32.tv_usec; + tvp = &atv; + } else + tvp = NULL; + if (uap->tzp) { + error = copyin(uap->tzp, &atz, sizeof(atz)); + if (error) + return (error); + tzp = &atz; + } else + tzp = NULL; + return (kern_settimeofday(td, tvp, tzp)); } int @@ -1002,16 +1070,3 @@ return (copyout(&ts32, uap->interval, sizeof(ts32))); } -int -linux_mprotect(struct thread *td, struct linux_mprotect_args *uap) -{ - struct mprotect_args bsd_args; - - bsd_args.addr = uap->addr; - bsd_args.len = uap->len; - bsd_args.prot = uap->prot; - /* XXX PROT_READ implies PROT_EXEC; see linux_mmap_common(). */ - if ((bsd_args.prot & PROT_READ) != 0) - bsd_args.prot |= PROT_EXEC; - return (mprotect(td, &bsd_args)); -} Index: sys/amd64/linux32/linux32_proto.h =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/amd64/linux32/linux32_proto.h,v retrieving revision 1.5.2.1 diff -u -u -r1.5.2.1 linux32_proto.h --- sys/amd64/linux32/linux32_proto.h 20 Jul 2005 17:43:52 -0000 1.5.2.1 +++ sys/amd64/linux32/linux32_proto.h 29 Jun 2007 06:50:07 -0000 @@ -2,7 +2,7 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/amd64/linux32/linux32_proto.h,v 1.5.2.1 2005/07/20 17:43:52 jhb Exp $ + * $FreeBSD$ * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.4.2.1 2005/07/20 17:42:14 jhb Exp */ @@ -82,6 +82,10 @@ char uid_l_[PADL_(l_uid16_t)]; l_uid16_t uid; char uid_r_[PADR_(l_uid16_t)]; char gid_l_[PADL_(l_gid16_t)]; l_gid16_t gid; char gid_r_[PADR_(l_gid16_t)]; }; +struct linux_stat_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char up_l_[PADL_(struct linux_stat *)]; struct linux_stat * up; char up_r_[PADR_(struct linux_stat *)]; +}; struct linux_lseek_args { char fdes_l_[PADL_(l_uint)]; l_uint fdes; char fdes_r_[PADR_(l_uint)]; char off_l_[PADL_(l_off_t)]; l_off_t off; char off_r_[PADR_(l_off_t)]; @@ -220,6 +224,10 @@ struct linux_sigpending_args { char mask_l_[PADL_(l_osigset_t *)]; l_osigset_t * mask; char mask_r_[PADR_(l_osigset_t *)]; }; +struct linux_sethostname_args { + char hostname_l_[PADL_(char *)]; char * hostname; char hostname_r_[PADR_(char *)]; + char len_l_[PADL_(u_int)]; u_int len; char len_r_[PADR_(u_int)]; +}; struct linux_setrlimit_args { char resource_l_[PADL_(l_uint)]; l_uint resource; char resource_r_[PADR_(l_uint)]; char rlim_l_[PADL_(struct l_rlimit *)]; struct l_rlimit * rlim; char rlim_r_[PADR_(struct l_rlimit *)]; @@ -255,6 +263,10 @@ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; char to_l_[PADL_(char *)]; char * to; char to_r_[PADR_(char *)]; }; +struct linux_lstat_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char up_l_[PADL_(struct ostat *)]; struct ostat * up; char up_r_[PADR_(struct ostat *)]; +}; struct linux_readlink_args { char name_l_[PADL_(char *)]; char * name; char name_r_[PADR_(char *)]; char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; @@ -278,6 +290,10 @@ 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)]; }; +struct linux_ftruncate_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char length_l_[PADL_(long)]; long length; char length_r_[PADR_(long)]; +}; struct linux_getpriority_args { char which_l_[PADL_(int)]; int which; char which_r_[PADR_(int)]; char who_l_[PADL_(int)]; int who; char who_r_[PADR_(int)]; @@ -323,6 +339,9 @@ struct linux_uname_args { register_t dummy; }; +struct linux_iopl_args { + char level_l_[PADL_(l_ulong)]; l_ulong level; char level_r_[PADR_(l_ulong)]; +}; struct linux_vhangup_args { register_t dummy; }; @@ -690,6 +709,154 @@ struct linux_fadvise64_args { register_t dummy; }; +struct linux_clock_settime_args { + char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)]; + char tp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tp; char tp_r_[PADR_(struct l_timespec *)]; +}; +struct linux_clock_gettime_args { + char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)]; + char tp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tp; char tp_r_[PADR_(struct l_timespec *)]; +}; +struct linux_clock_getres_args { + char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)]; + char tp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tp; char tp_r_[PADR_(struct l_timespec *)]; +}; +struct linux_clock_nanosleep_args { + char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)]; + char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)]; + char rqtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rqtp; char rqtp_r_[PADR_(struct l_timespec *)]; + char rmtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rmtp; char rmtp_r_[PADR_(struct l_timespec *)]; +}; +struct linux_statfs64_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char buf_l_[PADL_(struct l_statfs64_buf *)]; struct l_statfs64_buf * buf; char buf_r_[PADR_(struct l_statfs64_buf *)]; +}; +struct linux_fstatfs64_args { + register_t dummy; +}; +struct linux_tgkill_args { + char tgid_l_[PADL_(int)]; int tgid; char tgid_r_[PADR_(int)]; + char pid_l_[PADL_(int)]; int pid; char pid_r_[PADR_(int)]; + char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)]; +}; +struct linux_utimes_args { + char fname_l_[PADL_(char *)]; char * fname; char fname_r_[PADR_(char *)]; + char tptr_l_[PADL_(struct l_timeval *)]; struct l_timeval * tptr; char tptr_r_[PADR_(struct l_timeval *)]; +}; +struct linux_fadvise64_64_args { + register_t dummy; +}; +struct linux_mbind_args { + register_t dummy; +}; +struct linux_get_mempolicy_args { + register_t dummy; +}; +struct linux_set_mempolicy_args { + register_t dummy; +}; +struct linux_mq_open_args { + register_t dummy; +}; +struct linux_mq_unlink_args { + register_t dummy; +}; +struct linux_mq_timedsend_args { + register_t dummy; +}; +struct linux_mq_timedreceive_args { + register_t dummy; +}; +struct linux_mq_notify_args { + register_t dummy; +}; +struct linux_mq_getsetattr_args { + register_t dummy; +}; +struct linux_kexec_load_args { + register_t dummy; +}; +struct linux_waitid_args { + register_t dummy; +}; +struct linux_add_key_args { + register_t dummy; +}; +struct linux_request_key_args { + register_t dummy; +}; +struct linux_keyctl_args { + register_t dummy; +}; +struct linux_ioprio_set_args { + register_t dummy; +}; +struct linux_ioprio_get_args { + register_t dummy; +}; +struct linux_inotify_init_args { + register_t dummy; +}; +struct linux_inotify_add_watch_args { + register_t dummy; +}; +struct linux_inotify_rm_watch_args { + register_t dummy; +}; +struct linux_migrate_pages_args { + register_t dummy; +}; +struct linux_openat_args { + char dfd_l_[PADL_(l_int)]; l_int dfd; char dfd_r_[PADR_(l_int)]; + char filename_l_[PADL_(char *)]; char * filename; char filename_r_[PADR_(char *)]; + char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)]; + char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)]; +}; +struct linux_mkdirat_args { + register_t dummy; +}; +struct linux_mknodat_args { + register_t dummy; +}; +struct linux_fchownat_args { + register_t dummy; +}; +struct linux_futimesat_args { + register_t dummy; +}; +struct linux_fstatat64_args { + register_t dummy; +}; +struct linux_unlinkat_args { + register_t dummy; +}; +struct linux_renameat_args { + register_t dummy; +}; +struct linux_linkat_args { + register_t dummy; +}; +struct linux_symlinkat_args { + register_t dummy; +}; +struct linux_readlinkat_args { + register_t dummy; +}; +struct linux_fchmodat_args { + register_t dummy; +}; +struct linux_faccessat_args { + register_t dummy; +}; +struct linux_pselect6_args { + register_t dummy; +}; +struct linux_ppoll_args { + register_t dummy; +}; +struct linux_unshare_args { + register_t dummy; +}; #define nosys linux_nosys int linux_fork(struct thread *, struct linux_fork_args *); int linux_open(struct thread *, struct linux_open_args *); @@ -703,6 +870,7 @@ int linux_mknod(struct thread *, struct linux_mknod_args *); int linux_chmod(struct thread *, struct linux_chmod_args *); int linux_lchown16(struct thread *, struct linux_lchown16_args *); +int linux_stat(struct thread *, struct linux_stat_args *); int linux_lseek(struct thread *, struct linux_lseek_args *); int linux_getpid(struct thread *, struct linux_getpid_args *); int linux_mount(struct thread *, struct linux_mount_args *); @@ -740,6 +908,7 @@ int linux_setregid16(struct thread *, struct linux_setregid16_args *); int linux_sigsuspend(struct thread *, struct linux_sigsuspend_args *); int linux_sigpending(struct thread *, struct linux_sigpending_args *); +int linux_sethostname(struct thread *, struct linux_sethostname_args *); int linux_setrlimit(struct thread *, struct linux_setrlimit_args *); int linux_old_getrlimit(struct thread *, struct linux_old_getrlimit_args *); int linux_getrusage(struct thread *, struct linux_getrusage_args *); @@ -749,11 +918,13 @@ int linux_setgroups16(struct thread *, struct linux_setgroups16_args *); int linux_old_select(struct thread *, struct linux_old_select_args *); int linux_symlink(struct thread *, struct linux_symlink_args *); +int linux_lstat(struct thread *, struct linux_lstat_args *); int linux_readlink(struct thread *, struct linux_readlink_args *); 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_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 *); int linux_statfs(struct thread *, struct linux_statfs_args *); int linux_fstatfs(struct thread *, struct linux_fstatfs_args *); @@ -765,6 +936,7 @@ int linux_newlstat(struct thread *, struct linux_newlstat_args *); int linux_newfstat(struct thread *, struct linux_newfstat_args *); int linux_uname(struct thread *, struct linux_uname_args *); +int linux_iopl(struct thread *, struct linux_iopl_args *); int linux_vhangup(struct thread *, struct linux_vhangup_args *); int linux_wait4(struct thread *, struct linux_wait4_args *); int linux_swapoff(struct thread *, struct linux_swapoff_args *); @@ -857,6 +1029,51 @@ int linux_lremovexattr(struct thread *, struct linux_lremovexattr_args *); int linux_fremovexattr(struct thread *, struct linux_fremovexattr_args *); int linux_fadvise64(struct thread *, struct linux_fadvise64_args *); +int linux_clock_settime(struct thread *, struct linux_clock_settime_args *); +int linux_clock_gettime(struct thread *, struct linux_clock_gettime_args *); +int linux_clock_getres(struct thread *, struct linux_clock_getres_args *); +int linux_clock_nanosleep(struct thread *, struct linux_clock_nanosleep_args *); +int linux_statfs64(struct thread *, struct linux_statfs64_args *); +int linux_fstatfs64(struct thread *, struct linux_fstatfs64_args *); +int linux_tgkill(struct thread *, struct linux_tgkill_args *); +int linux_utimes(struct thread *, struct linux_utimes_args *); +int linux_fadvise64_64(struct thread *, struct linux_fadvise64_64_args *); +int linux_mbind(struct thread *, struct linux_mbind_args *); +int linux_get_mempolicy(struct thread *, struct linux_get_mempolicy_args *); +int linux_set_mempolicy(struct thread *, struct linux_set_mempolicy_args *); +int linux_mq_open(struct thread *, struct linux_mq_open_args *); +int linux_mq_unlink(struct thread *, struct linux_mq_unlink_args *); +int linux_mq_timedsend(struct thread *, struct linux_mq_timedsend_args *); +int linux_mq_timedreceive(struct thread *, struct linux_mq_timedreceive_args *); +int linux_mq_notify(struct thread *, struct linux_mq_notify_args *); +int linux_mq_getsetattr(struct thread *, struct linux_mq_getsetattr_args *); +int linux_kexec_load(struct thread *, struct linux_kexec_load_args *); +int linux_waitid(struct thread *, struct linux_waitid_args *); +int linux_add_key(struct thread *, struct linux_add_key_args *); +int linux_request_key(struct thread *, struct linux_request_key_args *); +int linux_keyctl(struct thread *, struct linux_keyctl_args *); +int linux_ioprio_set(struct thread *, struct linux_ioprio_set_args *); +int linux_ioprio_get(struct thread *, struct linux_ioprio_get_args *); +int linux_inotify_init(struct thread *, struct linux_inotify_init_args *); +int linux_inotify_add_watch(struct thread *, struct linux_inotify_add_watch_args *); +int linux_inotify_rm_watch(struct thread *, struct linux_inotify_rm_watch_args *); +int linux_migrate_pages(struct thread *, struct linux_migrate_pages_args *); +int linux_openat(struct thread *, struct linux_openat_args *); +int linux_mkdirat(struct thread *, struct linux_mkdirat_args *); +int linux_mknodat(struct thread *, struct linux_mknodat_args *); +int linux_fchownat(struct thread *, struct linux_fchownat_args *); +int linux_futimesat(struct thread *, struct linux_futimesat_args *); +int linux_fstatat64(struct thread *, struct linux_fstatat64_args *); +int linux_unlinkat(struct thread *, struct linux_unlinkat_args *); +int linux_renameat(struct thread *, struct linux_renameat_args *); +int linux_linkat(struct thread *, struct linux_linkat_args *); +int linux_symlinkat(struct thread *, struct linux_symlinkat_args *); +int linux_readlinkat(struct thread *, struct linux_readlinkat_args *); +int linux_fchmodat(struct thread *, struct linux_fchmodat_args *); +int linux_faccessat(struct thread *, struct linux_faccessat_args *); +int linux_pselect6(struct thread *, struct linux_pselect6_args *); +int linux_ppoll(struct thread *, struct linux_ppoll_args *); +int linux_unshare(struct thread *, struct linux_unshare_args *); #ifdef COMPAT_43 Index: sys/amd64/linux32/linux32_syscall.h =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/amd64/linux32/linux32_syscall.h,v retrieving revision 1.5.2.1 diff -u -u -r1.5.2.1 linux32_syscall.h --- sys/amd64/linux32/linux32_syscall.h 20 Jul 2005 17:43:52 -0000 1.5.2.1 +++ sys/amd64/linux32/linux32_syscall.h 29 Jun 2007 06:50:07 -0000 @@ -2,7 +2,7 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/amd64/linux32/linux32_syscall.h,v 1.5.2.1 2005/07/20 17:43:52 jhb Exp $ + * $FreeBSD$ * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.4.2.1 2005/07/20 17:42:14 jhb Exp */ @@ -22,6 +22,7 @@ #define LINUX_SYS_linux_mknod 14 #define LINUX_SYS_linux_chmod 15 #define LINUX_SYS_linux_lchown16 16 +#define LINUX_SYS_linux_stat 18 #define LINUX_SYS_linux_lseek 19 #define LINUX_SYS_linux_getpid 20 #define LINUX_SYS_linux_mount 21 @@ -69,7 +70,7 @@ #define LINUX_SYS_linux_setregid16 71 #define LINUX_SYS_linux_sigsuspend 72 #define LINUX_SYS_linux_sigpending 73 -#define LINUX_SYS_osethostname 74 +#define LINUX_SYS_linux_sethostname 74 #define LINUX_SYS_linux_setrlimit 75 #define LINUX_SYS_linux_old_getrlimit 76 #define LINUX_SYS_linux_getrusage 77 @@ -79,6 +80,7 @@ #define LINUX_SYS_linux_setgroups16 81 #define LINUX_SYS_linux_old_select 82 #define LINUX_SYS_linux_symlink 83 +#define LINUX_SYS_linux_lstat 84 #define LINUX_SYS_linux_readlink 85 #define LINUX_SYS_swapon 87 #define LINUX_SYS_linux_reboot 88 @@ -86,7 +88,7 @@ #define LINUX_SYS_linux_mmap 90 #define LINUX_SYS_munmap 91 #define LINUX_SYS_linux_truncate 92 -#define LINUX_SYS_oftruncate 93 +#define LINUX_SYS_linux_ftruncate 93 #define LINUX_SYS_fchmod 94 #define LINUX_SYS_fchown 95 #define LINUX_SYS_linux_getpriority 96 @@ -101,6 +103,7 @@ #define LINUX_SYS_linux_newlstat 107 #define LINUX_SYS_linux_newfstat 108 #define LINUX_SYS_linux_uname 109 +#define LINUX_SYS_linux_iopl 110 #define LINUX_SYS_linux_vhangup 111 #define LINUX_SYS_linux_wait4 114 #define LINUX_SYS_linux_swapoff 115 @@ -219,4 +222,49 @@ #define LINUX_SYS_linux_fremovexattr 237 #define LINUX_SYS_linux_fadvise64 250 #define LINUX_SYS_exit_group 252 -#define LINUX_SYS_MAXSYSCALL 268 +#define LINUX_SYS_linux_clock_settime 264 +#define LINUX_SYS_linux_clock_gettime 265 +#define LINUX_SYS_linux_clock_getres 266 +#define LINUX_SYS_linux_clock_nanosleep 267 +#define LINUX_SYS_linux_statfs64 268 +#define LINUX_SYS_linux_fstatfs64 269 +#define LINUX_SYS_linux_tgkill 270 +#define LINUX_SYS_linux_utimes 271 +#define LINUX_SYS_linux_fadvise64_64 272 +#define LINUX_SYS_linux_mbind 274 +#define LINUX_SYS_linux_get_mempolicy 275 +#define LINUX_SYS_linux_set_mempolicy 276 +#define LINUX_SYS_linux_mq_open 277 +#define LINUX_SYS_linux_mq_unlink 278 +#define LINUX_SYS_linux_mq_timedsend 279 +#define LINUX_SYS_linux_mq_timedreceive 280 +#define LINUX_SYS_linux_mq_notify 281 +#define LINUX_SYS_linux_mq_getsetattr 282 +#define LINUX_SYS_linux_kexec_load 283 +#define LINUX_SYS_linux_waitid 284 +#define LINUX_SYS_linux_add_key 286 +#define LINUX_SYS_linux_request_key 287 +#define LINUX_SYS_linux_keyctl 288 +#define LINUX_SYS_linux_ioprio_set 289 +#define LINUX_SYS_linux_ioprio_get 290 +#define LINUX_SYS_linux_inotify_init 291 +#define LINUX_SYS_linux_inotify_add_watch 292 +#define LINUX_SYS_linux_inotify_rm_watch 293 +#define LINUX_SYS_linux_migrate_pages 294 +#define LINUX_SYS_linux_openat 295 +#define LINUX_SYS_linux_mkdirat 296 +#define LINUX_SYS_linux_mknodat 297 +#define LINUX_SYS_linux_fchownat 298 +#define LINUX_SYS_linux_futimesat 299 +#define LINUX_SYS_linux_fstatat64 300 +#define LINUX_SYS_linux_unlinkat 301 +#define LINUX_SYS_linux_renameat 302 +#define LINUX_SYS_linux_linkat 303 +#define LINUX_SYS_linux_symlinkat 304 +#define LINUX_SYS_linux_readlinkat 305 +#define LINUX_SYS_linux_fchmodat 306 +#define LINUX_SYS_linux_faccessat 307 +#define LINUX_SYS_linux_pselect6 308 +#define LINUX_SYS_linux_ppoll 309 +#define LINUX_SYS_linux_unshare 310 +#define LINUX_SYS_MAXSYSCALL 311 Index: sys/amd64/linux32/linux32_sysent.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/amd64/linux32/linux32_sysent.c,v retrieving revision 1.5.2.1 diff -u -u -r1.5.2.1 linux32_sysent.c --- sys/amd64/linux32/linux32_sysent.c 20 Jul 2005 17:43:52 -0000 1.5.2.1 +++ sys/amd64/linux32/linux32_sysent.c 29 Jun 2007 06:50:07 -0000 @@ -2,7 +2,7 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/amd64/linux32/linux32_sysent.c,v 1.5.2.1 2005/07/20 17:43:52 jhb Exp $ + * $FreeBSD$ * created from FreeBSD: src/sys/amd64/linux32/syscalls.master,v 1.4.2.1 2005/07/20 17:42:14 jhb Exp */ @@ -38,7 +38,7 @@ { SYF_MPSAFE | AS(linux_chmod_args), (sy_call_t *)linux_chmod, AUE_NULL }, /* 15 = linux_chmod */ { SYF_MPSAFE | AS(linux_lchown16_args), (sy_call_t *)linux_lchown16, AUE_NULL }, /* 16 = linux_lchown16 */ { 0, (sy_call_t *)nosys, AUE_NULL }, /* 17 = break */ - { 0, (sy_call_t *)nosys, AUE_NULL }, /* 18 = stat */ + { SYF_MPSAFE | AS(linux_stat_args), (sy_call_t *)linux_stat, AUE_NULL }, /* 18 = linux_stat */ { SYF_MPSAFE | AS(linux_lseek_args), (sy_call_t *)linux_lseek, AUE_NULL }, /* 19 = linux_lseek */ { SYF_MPSAFE | 0, (sy_call_t *)linux_getpid, AUE_NULL }, /* 20 = linux_getpid */ { AS(linux_mount_args), (sy_call_t *)linux_mount, AUE_NULL }, /* 21 = linux_mount */ @@ -94,7 +94,7 @@ { SYF_MPSAFE | AS(linux_setregid16_args), (sy_call_t *)linux_setregid16, AUE_NULL }, /* 71 = linux_setregid16 */ { SYF_MPSAFE | AS(linux_sigsuspend_args), (sy_call_t *)linux_sigsuspend, AUE_NULL }, /* 72 = linux_sigsuspend */ { SYF_MPSAFE | AS(linux_sigpending_args), (sy_call_t *)linux_sigpending, AUE_NULL }, /* 73 = linux_sigpending */ - { SYF_MPSAFE | AS(sethostname_args), (sy_call_t *)osethostname, AUE_NULL }, /* 74 = osethostname */ + { SYF_MPSAFE | AS(linux_sethostname_args), (sy_call_t *)linux_sethostname, AUE_NULL }, /* 74 = linux_sethostname */ { SYF_MPSAFE | AS(linux_setrlimit_args), (sy_call_t *)linux_setrlimit, AUE_NULL }, /* 75 = linux_setrlimit */ { SYF_MPSAFE | AS(linux_old_getrlimit_args), (sy_call_t *)linux_old_getrlimit, AUE_NULL }, /* 76 = linux_old_getrlimit */ { SYF_MPSAFE | AS(linux_getrusage_args), (sy_call_t *)linux_getrusage, AUE_NULL }, /* 77 = linux_getrusage */ @@ -104,7 +104,7 @@ { SYF_MPSAFE | AS(linux_setgroups16_args), (sy_call_t *)linux_setgroups16, AUE_NULL }, /* 81 = linux_setgroups16 */ { SYF_MPSAFE | AS(linux_old_select_args), (sy_call_t *)linux_old_select, AUE_NULL }, /* 82 = linux_old_select */ { SYF_MPSAFE | AS(linux_symlink_args), (sy_call_t *)linux_symlink, AUE_NULL }, /* 83 = linux_symlink */ - { 0, (sy_call_t *)nosys, AUE_NULL }, /* 84 = ostat */ + { SYF_MPSAFE | AS(linux_lstat_args), (sy_call_t *)linux_lstat, AUE_NULL }, /* 84 = linux_lstat */ { SYF_MPSAFE | AS(linux_readlink_args), (sy_call_t *)linux_readlink, AUE_NULL }, /* 85 = linux_readlink */ { 0, (sy_call_t *)nosys, AUE_NULL }, /* 86 = linux_uselib */ { SYF_MPSAFE | AS(swapon_args), (sy_call_t *)swapon, AUE_NULL }, /* 87 = swapon */ @@ -113,7 +113,7 @@ { SYF_MPSAFE | AS(linux_mmap_args), (sy_call_t *)linux_mmap, AUE_NULL }, /* 90 = linux_mmap */ { SYF_MPSAFE | AS(munmap_args), (sy_call_t *)munmap, AUE_NULL }, /* 91 = munmap */ { SYF_MPSAFE | AS(linux_truncate_args), (sy_call_t *)linux_truncate, AUE_NULL }, /* 92 = linux_truncate */ - { SYF_MPSAFE | AS(oftruncate_args), (sy_call_t *)oftruncate, AUE_NULL }, /* 93 = oftruncate */ + { SYF_MPSAFE | AS(linux_ftruncate_args), (sy_call_t *)linux_ftruncate, AUE_NULL }, /* 93 = linux_ftruncate */ { SYF_MPSAFE | AS(fchmod_args), (sy_call_t *)fchmod, AUE_NULL }, /* 94 = fchmod */ { SYF_MPSAFE | AS(fchown_args), (sy_call_t *)fchown, AUE_NULL }, /* 95 = fchown */ { SYF_MPSAFE | AS(linux_getpriority_args), (sy_call_t *)linux_getpriority, AUE_NULL }, /* 96 = linux_getpriority */ @@ -130,7 +130,7 @@ { SYF_MPSAFE | AS(linux_newlstat_args), (sy_call_t *)linux_newlstat, AUE_NULL }, /* 107 = linux_newlstat */ { SYF_MPSAFE | AS(linux_newfstat_args), (sy_call_t *)linux_newfstat, AUE_NULL }, /* 108 = linux_newfstat */ { SYF_MPSAFE | 0, (sy_call_t *)linux_uname, AUE_NULL }, /* 109 = linux_uname */ - { 0, (sy_call_t *)nosys, AUE_NULL }, /* 110 = iopl */ + { SYF_MPSAFE | AS(linux_iopl_args), (sy_call_t *)linux_iopl, AUE_NULL }, /* 110 = linux_iopl */ { SYF_MPSAFE | 0, (sy_call_t *)linux_vhangup, AUE_NULL }, /* 111 = linux_vhangup */ { 0, (sy_call_t *)nosys, AUE_NULL }, /* 112 = idle */ { 0, (sy_call_t *)nosys, AUE_NULL }, /* 113 = vm86old */ @@ -284,8 +284,51 @@ { 0, (sy_call_t *)nosys, AUE_NULL }, /* 261 = linux_timer_gettime */ { 0, (sy_call_t *)nosys, AUE_NULL }, /* 262 = linux_timer_getoverrun */ { 0, (sy_call_t *)nosys, AUE_NULL }, /* 263 = linux_timer_delete */ - { 0, (sy_call_t *)nosys, AUE_NULL }, /* 264 = linux_clock_settime */ - { 0, (sy_call_t *)nosys, AUE_NULL }, /* 265 = linux_clock_gettime */ - { 0, (sy_call_t *)nosys, AUE_NULL }, /* 266 = linux_clock_getres */ - { 0, (sy_call_t *)nosys, AUE_NULL }, /* 267 = linux_clock_nanosleep */ + { SYF_MPSAFE | AS(linux_clock_settime_args), (sy_call_t *)linux_clock_settime, AUE_NULL }, /* 264 = linux_clock_settime */ + { SYF_MPSAFE | AS(linux_clock_gettime_args), (sy_call_t *)linux_clock_gettime, AUE_NULL }, /* 265 = linux_clock_gettime */ + { SYF_MPSAFE | AS(linux_clock_getres_args), (sy_call_t *)linux_clock_getres, AUE_NULL }, /* 266 = linux_clock_getres */ + { SYF_MPSAFE | AS(linux_clock_nanosleep_args), (sy_call_t *)linux_clock_nanosleep, AUE_NULL }, /* 267 = linux_clock_nanosleep */ + { SYF_MPSAFE | AS(linux_statfs64_args), (sy_call_t *)linux_statfs64, AUE_NULL }, /* 268 = linux_statfs64 */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_fstatfs64, AUE_NULL }, /* 269 = linux_fstatfs64 */ + { SYF_MPSAFE | AS(linux_tgkill_args), (sy_call_t *)linux_tgkill, AUE_NULL }, /* 270 = linux_tgkill */ + { SYF_MPSAFE | AS(linux_utimes_args), (sy_call_t *)linux_utimes, AUE_NULL }, /* 271 = linux_utimes */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_fadvise64_64, AUE_NULL }, /* 272 = linux_fadvise64_64 */ + { 0, (sy_call_t *)nosys, AUE_NULL }, /* 273 = */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_mbind, AUE_NULL }, /* 274 = linux_mbind */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_get_mempolicy, AUE_NULL }, /* 275 = linux_get_mempolicy */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_set_mempolicy, AUE_NULL }, /* 276 = linux_set_mempolicy */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_mq_open, AUE_NULL }, /* 277 = linux_mq_open */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_mq_unlink, AUE_NULL }, /* 278 = linux_mq_unlink */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_mq_timedsend, AUE_NULL }, /* 279 = linux_mq_timedsend */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_mq_timedreceive, AUE_NULL }, /* 280 = linux_mq_timedreceive */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_mq_notify, AUE_NULL }, /* 281 = linux_mq_notify */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_mq_getsetattr, AUE_NULL }, /* 282 = linux_mq_getsetattr */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_kexec_load, AUE_NULL }, /* 283 = linux_kexec_load */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_waitid, AUE_NULL }, /* 284 = linux_waitid */ + { 0, (sy_call_t *)nosys, AUE_NULL }, /* 285 = */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_add_key, AUE_NULL }, /* 286 = linux_add_key */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_request_key, AUE_NULL }, /* 287 = linux_request_key */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_keyctl, AUE_NULL }, /* 288 = linux_keyctl */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_ioprio_set, AUE_NULL }, /* 289 = linux_ioprio_set */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_ioprio_get, AUE_NULL }, /* 290 = linux_ioprio_get */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_inotify_init, AUE_NULL }, /* 291 = linux_inotify_init */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_inotify_add_watch, AUE_NULL }, /* 292 = linux_inotify_add_watch */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_inotify_rm_watch, AUE_NULL }, /* 293 = linux_inotify_rm_watch */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_migrate_pages, AUE_NULL }, /* 294 = linux_migrate_pages */ + { SYF_MPSAFE | AS(linux_openat_args), (sy_call_t *)linux_openat, AUE_NULL }, /* 295 = linux_openat */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_mkdirat, AUE_NULL }, /* 296 = linux_mkdirat */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_mknodat, AUE_NULL }, /* 297 = linux_mknodat */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_fchownat, AUE_NULL }, /* 298 = linux_fchownat */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_futimesat, AUE_NULL }, /* 299 = linux_futimesat */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_fstatat64, AUE_NULL }, /* 300 = linux_fstatat64 */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_unlinkat, AUE_NULL }, /* 301 = linux_unlinkat */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_renameat, AUE_NULL }, /* 302 = linux_renameat */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_linkat, AUE_NULL }, /* 303 = linux_linkat */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_symlinkat, AUE_NULL }, /* 304 = linux_symlinkat */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_readlinkat, AUE_NULL }, /* 305 = linux_readlinkat */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_fchmodat, AUE_NULL }, /* 306 = linux_fchmodat */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_faccessat, AUE_NULL }, /* 307 = linux_faccessat */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_pselect6, AUE_NULL }, /* 308 = linux_pselect6 */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_ppoll, AUE_NULL }, /* 309 = linux_ppoll */ + { SYF_MPSAFE | 0, (sy_call_t *)linux_unshare, AUE_NULL }, /* 310 = linux_unshare */ }; Index: sys/amd64/linux32/linux32_sysvec.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/amd64/linux32/linux32_sysvec.c,v retrieving revision 1.7.2.5 diff -u -u -r1.7.2.5 linux32_sysvec.c --- sys/amd64/linux32/linux32_sysvec.c 23 May 2007 18:24:42 -0000 1.7.2.5 +++ sys/amd64/linux32/linux32_sysvec.c 25 Jun 2007 07:10:58 -0000 @@ -36,9 +36,6 @@ /* XXX we use functions that might not exist. */ #include "opt_compat.h" -#ifndef COMPAT_43 -#error "Unable to compile Linux-emulator due to missing COMPAT_43 option!" -#endif #ifndef COMPAT_IA32 #error "Unable to compile Linux-emulator due to missing COMPAT_IA32 option!" #endif @@ -142,7 +139,8 @@ -100,-101,-102,-103,-104,-105,-106,-107,-108,-109, -110,-111, -40, -36,-112,-113, -39, -11, -87,-122, -116, -66, -6, -6, -6, -6, -6, -37, -38, -9, - -6, -6, -43, -42, -75, -6, -84 + -6, -6, -43, -42, -75,-125, -84, -95, -16, -74, + -72, -67, -71 }; int bsd_to_linux_signal[LINUX_SIGTBLSZ] = { @@ -399,6 +397,7 @@ td->td_pcb->pcb_ds = _udatasel; load_es(_udatasel); td->td_pcb->pcb_es = _udatasel; + /* leave user %fs and %gs untouched */ PROC_LOCK(p); mtx_lock(&psp->ps_mtx); } @@ -516,6 +515,7 @@ td->td_pcb->pcb_ds = _udatasel; load_es(_udatasel); td->td_pcb->pcb_es = _udatasel; + /* leave user %fs and %gs untouched */ PROC_LOCK(p); mtx_lock(&psp->ps_mtx); } @@ -789,18 +789,20 @@ struct trapframe *regs = td->td_frame; struct pcb *pcb = td->td_pcb; + critical_enter(); wrmsr(MSR_FSBASE, 0); wrmsr(MSR_KGSBASE, 0); /* User value while we're in the kernel */ pcb->pcb_fsbase = 0; pcb->pcb_gsbase = 0; + critical_exit(); load_ds(_udatasel); load_es(_udatasel); load_fs(_udatasel); - load_gs(0); + load_gs(_udatasel); pcb->pcb_ds = _udatasel; pcb->pcb_es = _udatasel; pcb->pcb_fs = _udatasel; - pcb->pcb_gs = 0; + pcb->pcb_gs = _udatasel; bzero((char *)regs, sizeof(struct trapframe)); regs->tf_rip = entry; @@ -972,7 +974,7 @@ struct sysentvec elf_linux_sysvec = { LINUX_SYS_MAXSYSCALL, linux_sysent, - 0xff, + 0, LINUX_SIGTBLSZ, bsd_to_linux_signal, ELAST + 1, Index: sys/amd64/linux32/syscalls.master =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/amd64/linux32/syscalls.master,v retrieving revision 1.4.2.1 diff -u -u -r1.4.2.1 syscalls.master --- sys/amd64/linux32/syscalls.master 20 Jul 2005 17:42:14 -0000 1.4.2.1 +++ sys/amd64/linux32/syscalls.master 29 Jun 2007 06:50:04 -0000 @@ -66,7 +66,8 @@ 16 AUE_NULL MSTD { int linux_lchown16(char *path, \ l_uid16_t uid, l_gid16_t gid); } 17 AUE_NULL UNIMPL break -18 AUE_NULL UNIMPL stat +18 AUE_NULL MSTD { int linux_stat(char *path, \ + struct linux_stat *up); } 19 AUE_NULL MSTD { int linux_lseek(l_uint fdes, l_off_t off, \ l_int whence); } 20 AUE_NULL MSTD { int linux_getpid(void); } @@ -136,9 +137,8 @@ 72 AUE_NULL MSTD { int linux_sigsuspend(l_int hist0, \ l_int hist1, l_osigset_t mask); } 73 AUE_NULL MSTD { int linux_sigpending(l_osigset_t *mask); } -74 AUE_NULL MNOPROTO { int osethostname(char *hostname, \ - u_int len); } osethostname \ - sethostname_args int +74 AUE_NULL MSTD { int linux_sethostname(char *hostname, \ + u_int len); } 75 AUE_NULL MSTD { int linux_setrlimit(l_uint resource, \ struct l_rlimit *rlim); } 76 AUE_NULL MSTD { int linux_old_getrlimit(l_uint resource, \ @@ -159,7 +159,8 @@ struct l_old_select_argv *ptr); } 83 AUE_NULL MSTD { int linux_symlink(char *path, \ char *to); } -84 AUE_NULL UNIMPL ostat +84 AUE_NULL MSTD { int linux_lstat(char *path, \ + struct ostat *up); } 85 AUE_NULL MSTD { int linux_readlink(char *name, \ char *buf, l_int count); } 86 AUE_NULL UNIMPL linux_uselib @@ -173,7 +174,7 @@ 91 AUE_NULL MNOPROTO { int munmap(caddr_t addr, int len); } 92 AUE_NULL MSTD { int linux_truncate(char *path, \ l_ulong length); } -93 AUE_NULL MNOPROTO { int oftruncate(int fd, long length); } +93 AUE_NULL MSTD { int linux_ftruncate(int fd, long length); } 94 AUE_NULL MNOPROTO { int fchmod(int fd, int mode); } 95 AUE_NULL MNOPROTO { int fchown(int fd, int uid, int gid); } 96 AUE_NULL MSTD { int linux_getpriority(int which, int who); } @@ -201,7 +202,7 @@ 108 AUE_NULL MSTD { int linux_newfstat(l_uint fd, \ struct l_newstat *buf); } 109 AUE_NULL MSTD { int linux_uname(void); } -110 AUE_NULL UNIMPL iopl +110 AUE_NULL MSTD { int linux_iopl(l_ulong level); } 111 AUE_NULL MSTD { int linux_vhangup(void); } 112 AUE_NULL UNIMPL idle 113 AUE_NULL UNIMPL vm86old @@ -428,7 +429,58 @@ 261 AUE_NULL UNIMPL linux_timer_gettime 262 AUE_NULL UNIMPL linux_timer_getoverrun 263 AUE_NULL UNIMPL linux_timer_delete -264 AUE_NULL UNIMPL linux_clock_settime -265 AUE_NULL UNIMPL linux_clock_gettime -266 AUE_NULL UNIMPL linux_clock_getres -267 AUE_NULL UNIMPL linux_clock_nanosleep +264 AUE_NULL MSTD { int linux_clock_settime(clockid_t which, \ + struct l_timespec *tp); } +265 AUE_NULL MSTD { int linux_clock_gettime(clockid_t which, \ + struct l_timespec *tp); } +266 AUE_NULL MSTD { int linux_clock_getres(clockid_t which, \ + struct l_timespec *tp); } +267 AUE_NULL MSTD { int linux_clock_nanosleep(clockid_t which, \ + int flags, struct l_timespec *rqtp, \ + struct l_timespec *rmtp); } +268 AUE_NULL MSTD { int linux_statfs64(char *path, \ + struct l_statfs64_buf *buf); } +269 AUE_NULL MSTD { int linux_fstatfs64(void); } +270 AUE_NULL MSTD { int linux_tgkill(int tgid, int pid, int sig); } +271 AUE_NULL MSTD { int linux_utimes(char *fname, \ + struct l_timeval *tptr); } +272 AUE_NULL MSTD { int linux_fadvise64_64(void); } +273 AUE_NULL UNIMPL +274 AUE_NULL MSTD { int linux_mbind(void); } +275 AUE_NULL MSTD { int linux_get_mempolicy(void); } +276 AUE_NULL MSTD { int linux_set_mempolicy(void); } +277 AUE_NULL MSTD { int linux_mq_open(void); } +278 AUE_NULL MSTD { int linux_mq_unlink(void); } +279 AUE_NULL MSTD { int linux_mq_timedsend(void); } +280 AUE_NULL MSTD { int linux_mq_timedreceive(void); } +281 AUE_NULL MSTD { int linux_mq_notify(void); } +282 AUE_NULL MSTD { int linux_mq_getsetattr(void); } +283 AUE_NULL MSTD { int linux_kexec_load(void); } +284 AUE_NULL MSTD { int linux_waitid(void); } +285 AUE_NULL UNIMPL +286 AUE_NULL MSTD { int linux_add_key(void); } +287 AUE_NULL MSTD { int linux_request_key(void); } +288 AUE_NULL MSTD { int linux_keyctl(void); } +289 AUE_NULL MSTD { int linux_ioprio_set(void); } +290 AUE_NULL MSTD { int linux_ioprio_get(void); } +291 AUE_NULL MSTD { int linux_inotify_init(void); } +292 AUE_NULL MSTD { int linux_inotify_add_watch(void); } +293 AUE_NULL MSTD { int linux_inotify_rm_watch(void); } +294 AUE_NULL MSTD { int linux_migrate_pages(void); } +295 AUE_NULL MSTD { int linux_openat(l_int dfd, char *filename, \ + l_int flags, l_int mode); } +296 AUE_NULL MSTD { int linux_mkdirat(void); } +297 AUE_NULL MSTD { int linux_mknodat(void); } +298 AUE_NULL MSTD { int linux_fchownat(void); } +299 AUE_NULL MSTD { int linux_futimesat(void); } +300 AUE_NULL MSTD { int linux_fstatat64(void); } +301 AUE_NULL MSTD { int linux_unlinkat(void); } +302 AUE_NULL MSTD { int linux_renameat(void); } +303 AUE_NULL MSTD { int linux_linkat(void); } +304 AUE_NULL MSTD { int linux_symlinkat(void); } +305 AUE_NULL MSTD { int linux_readlinkat(void); } +306 AUE_NULL MSTD { int linux_fchmodat(void); } +307 AUE_NULL MSTD { int linux_faccessat(void); } +308 AUE_NULL MSTD { int linux_pselect6(void); } +309 AUE_NULL MSTD { int linux_ppoll(void); } +310 AUE_NULL MSTD { int linux_unshare(void); } Index: sys/compat/linprocfs/linprocfs.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/compat/linprocfs/linprocfs.c,v retrieving revision 1.89.2.5 diff -u -u -r1.89.2.5 linprocfs.c --- sys/compat/linprocfs/linprocfs.c 22 Aug 2006 11:04:01 -0000 1.89.2.5 +++ sys/compat/linprocfs/linprocfs.c 23 Jun 2007 15:42:17 -0000 @@ -54,11 +54,13 @@ #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -128,7 +130,7 @@ * This character array is used with ki_stati-1 as an index and tries to * map our states to suitable linux states. */ -static char *linux_state = "RRSTZDD"; +static char linux_state[] = "RRSTZDD"; /* * Filler function for proc/meminfo @@ -494,6 +496,57 @@ } /* + * Get OS build date + */ +static void +linprocfs_osbuild(struct thread *td, struct sbuf *sb) +{ +#if 0 + char osbuild[256]; + char *cp1, *cp2; + + strncpy(osbuild, version, 256); + osbuild[255] = '\0'; + cp1 = strstr(osbuild, "\n"); + cp2 = strstr(osbuild, ":"); + if (cp1 && cp2) { + *cp1 = *cp2 = '\0'; + cp1 = strstr(osbuild, "#"); + } else + cp1 = NULL; + if (cp1) + sbuf_printf(sb, "%s%s", cp1, cp2 + 1); + else +#endif + sbuf_cat(sb, "#4 Sun Dec 18 04:30:00 CET 1977"); +} + +/* + * Get OS builder + */ +static void +linprocfs_osbuilder(struct thread *td, struct sbuf *sb) +{ +#if 0 + char builder[256]; + char *cp; + + cp = strstr(version, "\n "); + if (cp) { + strncpy(builder, cp + 5, 256); + builder[255] = '\0'; + cp = strstr(builder, ":"); + if (cp) + *cp = '\0'; + } + if (cp) + sbuf_cat(sb, builder); + else +#endif + sbuf_cat(sb, "des@freebsd.org"); +} + +/* * Filler function for proc/version */ static int @@ -504,10 +557,12 @@ linux_get_osname(td, osname); linux_get_osrelease(td, osrelease); + sbuf_printf(sb, "%s version %s (", osname, osrelease); + linprocfs_osbuilder(td, sb); + sbuf_cat(sb, ") (gcc version " __VERSION__ ") "); + linprocfs_osbuild(td, sb); + sbuf_cat(sb, "\n"); - sbuf_printf(sb, - "%s version %s (des@freebsd.org) (gcc version " __VERSION__ ")" - " #4 Sun Dec 18 04:30:00 CET 1977\n", osname, osrelease); return (0); } @@ -517,6 +572,7 @@ static int linprocfs_doloadavg(PFS_FILL_ARGS) { + sbuf_printf(sb, "%d.%02d %d.%02d %d.%02d %d/%d %d\n", (int)(averunnable.ldavg[0] / averunnable.fscale), @@ -529,7 +585,6 @@ nprocs, /* number of tasks */ lastpid /* the last pid */ ); - return (0); } @@ -540,15 +595,25 @@ linprocfs_doprocstat(PFS_FILL_ARGS) { struct kinfo_proc kp; + char state; + static int ratelimit = 0; PROC_LOCK(p); fill_kinfo_proc(p, &kp); sbuf_printf(sb, "%d", p->p_pid); #define PS_ADD(name, fmt, arg) sbuf_printf(sb, " " fmt, arg) PS_ADD("comm", "(%s)", p->p_comm); - KASSERT(kp.ki_stat <= sizeof(linux_state), - ("linprocfs: don't know how to handle unknown FreeBSD state")); - PS_ADD("state", "%c", linux_state[kp.ki_stat - 1]); + if (kp.ki_stat > sizeof(linux_state)) { + state = 'R'; + + if (ratelimit == 0) { + printf("linprocfs: don't know how to handle unknown FreeBSD state %d/%zd, mapping to R\n", + kp.ki_stat, sizeof(linux_state)); + ++ratelimit; + } + } else + state = linux_state[kp.ki_stat - 1]; + PS_ADD("state", "%c", state); PS_ADD("ppid", "%d", p->p_pptr ? p->p_pptr->p_pid : 0); PS_ADD("pgrp", "%d", p->p_pgid); PS_ADD("session", "%d", p->p_session->s_sid); @@ -858,8 +923,8 @@ static int linprocfs_doprocenviron(PFS_FILL_ARGS) { - sbuf_printf(sb, "doprocenviron\n%c", '\0'); + sbuf_printf(sb, "doprocenviron\n%c", '\0'); return (0); } @@ -937,9 +1002,9 @@ ref_count = 0; shadow_count = 0; } - + /* - * format: + * format: * start, end, access, offset, major, minor, inode, name. */ snprintf(mebuffer, sizeof mebuffer, @@ -1003,11 +1068,86 @@ } /* + * Filler function for proc/sys/kernel/osrelease + */ +static int +linprocfs_doosrelease(PFS_FILL_ARGS) +{ + char osrelease[LINUX_MAX_UTSNAME]; + + linux_get_osrelease(td, osrelease); + sbuf_printf(sb, "%s\n", osrelease); + + return (0); +} + +/* + * Filler function for proc/sys/kernel/ostype + */ +static int +linprocfs_doostype(PFS_FILL_ARGS) +{ + char osname[LINUX_MAX_UTSNAME]; + + linux_get_osname(td, osname); + sbuf_printf(sb, "%s\n", osname); + + return (0); +} + +/* + * Filler function for proc/sys/kernel/version + */ +static int +linprocfs_doosbuild(PFS_FILL_ARGS) +{ + + linprocfs_osbuild(td, sb); + sbuf_cat(sb, "\n"); + return (0); +} + +/* + * Filler function for proc/sys/kernel/msgmni + */ +static int +linprocfs_domsgmni(PFS_FILL_ARGS) +{ + + sbuf_printf(sb, "%d\n", msginfo.msgmni); + return (0); +} + +/* + * Filler function for proc/sys/kernel/pid_max + */ +static int +linprocfs_dopid_max(PFS_FILL_ARGS) +{ + + sbuf_printf(sb, "%i\n", PID_MAX); + return (0); +} + +/* + * Filler function for proc/sys/kernel/sem + */ +static int +linprocfs_dosem(PFS_FILL_ARGS) +{ + + sbuf_printf(sb, "%d %d %d %d\n", seminfo.semmsl, seminfo.semmns, + seminfo.semopm, seminfo.semmni); + return (0); +} + +/* * Filler function for proc/scsi/device_info */ static int linprocfs_doscsidevinfo(PFS_FILL_ARGS) { + return (0); } @@ -1017,6 +1157,7 @@ static int linprocfs_doscsiscsi(PFS_FILL_ARGS) { + return (0); } @@ -1046,6 +1187,7 @@ static int linprocfs_docmdline(PFS_FILL_ARGS) { + sbuf_printf(sb, "BOOT_IMAGE=%s", kernelname); sbuf_printf(sb, " ro root=302\n"); return (0); @@ -1141,6 +1283,24 @@ NULL, NULL, PFS_RD); pfs_create_file(dir, "scsi", &linprocfs_doscsiscsi, NULL, NULL, PFS_RD); + + /* /proc/sys/... */ + dir = pfs_create_dir(root, "sys", NULL, NULL, 0); + /* /proc/sys/kernel/... */ + dir = pfs_create_dir(dir, "kernel", NULL, NULL, 0); + pfs_create_file(dir, "osrelease", &linprocfs_doosrelease, + NULL, NULL, PFS_RD); + pfs_create_file(dir, "ostype", &linprocfs_doostype, + NULL, NULL, PFS_RD); + pfs_create_file(dir, "version", &linprocfs_doosbuild, + NULL, NULL, PFS_RD); + pfs_create_file(dir, "msgmni", &linprocfs_domsgmni, + NULL, NULL, PFS_RD); + pfs_create_file(dir, "pid_max", &linprocfs_dopid_max, + NULL, NULL, PFS_RD); + pfs_create_file(dir, "sem", &linprocfs_dosem, + NULL, NULL, PFS_RD); + return (0); } @@ -1158,3 +1318,5 @@ PSEUDOFS(linprocfs, 1); MODULE_DEPEND(linprocfs, linux, 1, 1, 1); MODULE_DEPEND(linprocfs, procfs, 1, 1, 1); +MODULE_DEPEND(linprocfs, sysvmsg, 1, 1, 1); +MODULE_DEPEND(linprocfs, sysvsem, 1, 1, 1); Index: sys/compat/linux/linux_file.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/compat/linux/linux_file.c,v retrieving revision 1.91.2.1 diff -u -u -r1.91.2.1 linux_file.c --- sys/compat/linux/linux_file.c 17 Sep 2006 10:56:15 -0000 1.91.2.1 +++ sys/compat/linux/linux_file.c 20 Jun 2007 11:18:30 -0000 @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -268,7 +269,17 @@ struct l_dirent64 linux_dirent64; int buflen, error, eofflag, nbytes, justone; u_long *cookies = NULL, *cookiep; - int ncookies; + int ncookies, vfslocked; + + nbytes = args->count; + if (nbytes == 1) { + /* readdir(2) case. Always struct dirent. */ + if (is64bit) + return (EINVAL); + nbytes = sizeof(linux_dirent); + justone = 1; + } else + justone = 0; if ((error = getvnode(td->td_proc->p_fd, args->fd, &fp)) != 0) return (error); @@ -279,23 +290,13 @@ } vp = fp->f_vnode; + vfslocked = VFS_LOCK_GIANT(vp->v_mount); if (vp->v_type != VDIR) { + VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); return (EINVAL); } - nbytes = args->count; - if (nbytes == 1) { - /* readdir(2) case. Always struct dirent. */ - if (is64bit) { - fdrop(fp, td); - return (EINVAL); - } - nbytes = sizeof(linux_dirent); - justone = 1; - } else - justone = 0; - off = fp->f_offset; buflen = max(LINUX_DIRBLKSIZ, nbytes); @@ -448,6 +449,7 @@ free(cookies, M_TEMP); VOP_UNLOCK(vp, 0, td); + VFS_UNLOCK_GIANT(vfslocked); fdrop(fp, td); free(buf, M_TEMP); return (error); @@ -487,6 +489,10 @@ char *path; int error; + /* linux convention */ + if (args->flags & ~(F_OK | X_OK | W_OK | R_OK)) + return (EINVAL); + LCONVPATHEXIST(td, args->path, &path); #ifdef DEBUG @@ -495,6 +501,7 @@ #endif error = kern_access(td, path, UIO_SYSSPACE, args->flags); LFREEPATH(path); + return (error); } @@ -676,6 +683,21 @@ } int +linux_ftruncate(struct thread *td, struct linux_ftruncate_args *args) +{ + struct ftruncate_args /* { + int fd; + int pad; + off_t length; + } */ nuap; + + nuap.fd = args->fd; + nuap.pad = 0; + nuap.length = args->length; + return (ftruncate(td, &nuap)); +} + +int linux_link(struct thread *td, struct linux_link_args *args) { char *path, *to; @@ -718,12 +740,28 @@ struct linux_pread_args *uap; { struct pread_args bsd; + struct vnode *vp; + int error; bsd.fd = uap->fd; bsd.buf = uap->buf; bsd.nbyte = uap->nbyte; bsd.offset = uap->offset; - return pread(td, &bsd); + + error = pread(td, &bsd); + + if (error == 0) { + /* This seems to violate POSIX but linux does it */ + if ((error = fgetvp(td, uap->fd, &vp)) != 0) + return (error); + if (vp->v_type == VDIR) { + vrele(vp); + return (EISDIR); + } + vrele(vp); + } + + return (error); } int Index: sys/compat/linux/linux_getcwd.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/compat/linux/linux_getcwd.c,v retrieving revision 1.19.2.1 diff -u -u -r1.19.2.1 linux_getcwd.c --- sys/compat/linux/linux_getcwd.c 13 Mar 2006 03:04:04 -0000 1.19.2.1 +++ sys/compat/linux/linux_getcwd.c 11 May 2007 13:49:38 -0000 @@ -386,7 +386,7 @@ error = linux_getcwd_scandir(&lvp, &uvp, &bp, bufp, td); if (error) goto out; -#if DIAGNOSTIC +#ifdef DIAGNOSTIC if (lvp != NULL) panic("getcwd: oops, forgot to null lvp"); if (bufp && (bp <= bufp)) { @@ -426,8 +426,8 @@ int error, len, lenused; #ifdef DEBUG - printf("Linux-emul(%ld): getcwd(%p, %ld)\n", (long)td->td_proc->p_pid, - args->buf, (long)args->bufsize); + if (ldebug(getcwd)) + printf(ARGS(getcwd, "%p, %ld"), args->buf, (long)args->bufsize); #endif len = args->bufsize; Index: sys/compat/linux/linux_ioctl.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/compat/linux/linux_ioctl.c,v retrieving revision 1.127.2.4 diff -u -u -r1.127.2.4 linux_ioctl.c --- sys/compat/linux/linux_ioctl.c 10 Apr 2007 21:44:17 -0000 1.127.2.4 +++ sys/compat/linux/linux_ioctl.c 20 Jun 2007 11:27:49 -0000 @@ -1014,7 +1014,15 @@ args->cmd = TIOCCBRK; error = (ioctl(td, (struct ioctl_args *)args)); break; - + case LINUX_TIOCGPTN: { + int nb; + + error = fo_ioctl(fp, LINUX_TIOCGPTN, (caddr_t)&nb, td->td_ucred, td); + if (!error) + error = copyout(&nb, (void *)args->arg, + sizeof(int)); + break; + } default: error = ENOIOCTL; break; @@ -2281,6 +2289,29 @@ return (ENOENT); } + + /* +* If we fault in bsd_to_linux_ifreq() then we will fault when we call +* the native ioctl(). Thus, we don't really need to check the return +* value of this function. +*/ +static int +bsd_to_linux_ifreq(struct ifreq *arg) +{ + struct ifreq ifr; + size_t ifr_len = sizeof(struct ifreq); + int error; + + if ((error = copyin(arg, &ifr, ifr_len))) + return (error); + + *(u_short *)&ifr.ifr_addr = ifr.ifr_addr.sa_family; + + error = copyout(&ifr, arg, ifr_len); + + return (error); +} + /* * Socket related ioctls */ @@ -2412,8 +2443,9 @@ break; case LINUX_SIOCGIFADDR: - args->cmd = OSIOCGIFADDR; + args->cmd = SIOCGIFADDR; error = ioctl(td, (struct ioctl_args *)args); + bsd_to_linux_ifreq((struct ifreq *)args->arg); break; case LINUX_SIOCSIFADDR: @@ -2423,18 +2455,21 @@ break; case LINUX_SIOCGIFDSTADDR: - args->cmd = OSIOCGIFDSTADDR; + args->cmd = SIOCGIFDSTADDR; error = ioctl(td, (struct ioctl_args *)args); + bsd_to_linux_ifreq((struct ifreq *)args->arg); break; case LINUX_SIOCGIFBRDADDR: - args->cmd = OSIOCGIFBRDADDR; + args->cmd = SIOCGIFBRDADDR; error = ioctl(td, (struct ioctl_args *)args); + bsd_to_linux_ifreq((struct ifreq *)args->arg); break; case LINUX_SIOCGIFNETMASK: - args->cmd = OSIOCGIFNETMASK; + args->cmd = SIOCGIFNETMASK; error = ioctl(td, (struct ioctl_args *)args); + bsd_to_linux_ifreq((struct ifreq *)args->arg); break; case LINUX_SIOCSIFNETMASK: Index: sys/compat/linux/linux_ioctl.h =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/compat/linux/linux_ioctl.h,v retrieving revision 1.22.2.1 diff -u -u -r1.22.2.1 linux_ioctl.h --- sys/compat/linux/linux_ioctl.h 10 Apr 2007 21:44:17 -0000 1.22.2.1 +++ sys/compat/linux/linux_ioctl.h 20 Jun 2007 11:23:47 -0000 @@ -396,6 +396,8 @@ #define LINUX_TIOCSBRK 0x5427 #define LINUX_TIOCCBRK 0x5428 +#define LINUX_TIOCGPTN 0x5430 + #ifdef __alpha__ #define LINUX_FIOCLEX 0x6601 #define LINUX_FIONCLEX 0x6602 Index: sys/compat/linux/linux_misc.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/compat/linux/linux_misc.c,v retrieving revision 1.170.2.2 diff -u -u -r1.170.2.2 linux_misc.c --- sys/compat/linux/linux_misc.c 23 Sep 2006 10:36:57 -0000 1.170.2.2 +++ sys/compat/linux/linux_misc.c 25 Jun 2007 07:25:55 -0000 @@ -102,7 +102,7 @@ static unsigned int linux_to_bsd_resource[LINUX_RLIM_NLIMITS] = { RLIMIT_CPU, RLIMIT_FSIZE, RLIMIT_DATA, RLIMIT_STACK, RLIMIT_CORE, RLIMIT_RSS, RLIMIT_NPROC, RLIMIT_NOFILE, - RLIMIT_MEMLOCK, -1 + RLIMIT_MEMLOCK, RLIMIT_AS }; #endif /*!__alpha__*/ @@ -155,7 +155,7 @@ sysinfo.bufferram = 0; swap_pager_status(&i, &j); - sysinfo.totalswap= i * PAGE_SIZE; + sysinfo.totalswap = i * PAGE_SIZE; sysinfo.freeswap = (i - j) * PAGE_SIZE; sysinfo.procs = nprocs; @@ -215,7 +215,7 @@ #endif old = (vm_offset_t)vm->vm_daddr + ctob(vm->vm_dsize); new = (vm_offset_t)args->dsend; - tmp.nsize = (char *) new; + tmp.nsize = (char *)new; if (((caddr_t)new > vm->vm_daddr) && !obreak(td, &tmp)) td->td_retval[0] = (long)new; else @@ -291,6 +291,7 @@ if ((vp->v_mount->mnt_flag & MNT_NOEXEC) || ((attr.va_mode & 0111) == 0) || (attr.va_type != VREG)) { + /* EACCESS is what exec(2) returns. */ error = ENOEXEC; goto cleanup; } @@ -343,10 +344,10 @@ /* Set file/virtual offset based on a.out variant. */ switch ((int)(a_out->a_magic & 0xffff)) { - case 0413: /* ZMAGIC */ + case 0413: /* ZMAGIC */ file_offset = 1024; break; - case 0314: /* QMAGIC */ + case 0314: /* QMAGIC */ file_offset = 0; break; default: @@ -446,8 +447,8 @@ goto cleanup; } #ifdef DEBUG - printf("mem=%08lx = %08lx %08lx\n", (long)vmaddr, ((long*)vmaddr)[0], - ((long*)vmaddr)[1]); + printf("mem=%08lx = %08lx %08lx\n", (long)vmaddr, ((long *)vmaddr)[0], + ((long *)vmaddr)[1]); #endif if (bss_size != 0) { /* Calculate BSS start address */ @@ -501,8 +502,8 @@ utv.tv_usec = ltv.tv_usec; #ifdef DEBUG if (ldebug(select)) - printf(LMSG("incoming timeout (%ld/%ld)"), - utv.tv_sec, utv.tv_usec); + printf(LMSG("incoming timeout (%jd/%ld)"), + (intmax_t)utv.tv_sec, utv.tv_usec); #endif if (itimerfix(&utv)) { @@ -558,8 +559,8 @@ timevalclear(&utv); #ifdef DEBUG if (ldebug(select)) - printf(LMSG("outgoing timeout (%ld/%ld)"), - utv.tv_sec, utv.tv_usec); + printf(LMSG("outgoing timeout (%jd/%ld)"), + (intmax_t)utv.tv_sec, utv.tv_usec); #endif ltv.tv_sec = utv.tv_sec; ltv.tv_usec = utv.tv_usec; @@ -728,6 +729,7 @@ #ifdef __i386__ { const char *class; + switch (cpu_class) { case CPUCLASS_686: class = "i686"; @@ -795,6 +797,38 @@ LFREEPATH(fname); return (error); } + +int +linux_utimes(struct thread *td, struct linux_utimes_args *args) +{ + l_timeval ltv[2]; + struct timeval tv[2], *tvp = NULL; + char *fname; + int error; + + LCONVPATHEXIST(td, args->fname, &fname); + +#ifdef DEBUG + if (ldebug(utimes)) + printf(ARGS(utimes, "%s, *"), fname); +#endif + + if (args->tptr != NULL) { + if ((error = copyin(args->tptr, ltv, sizeof ltv))) { + LFREEPATH(fname); + return (error); + } + tv[0].tv_sec = ltv[0].tv_sec; + tv[0].tv_usec = ltv[0].tv_usec; + tv[1].tv_sec = ltv[1].tv_sec; + tv[1].tv_usec = ltv[1].tv_usec; + tvp = tv; + } + + error = kern_utimes(td, fname, UIO_SYSSPACE, tvp, UIO_SYSSPACE); + LFREEPATH(fname); + return (error); +} #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */ #define __WCLONE 0x80000000 @@ -810,6 +844,12 @@ printf(ARGS(waitpid, "%d, %p, %d"), args->pid, (void *)args->status, args->options); #endif + /* + * this is necessary because the test in kern_wait doesn't work + * because we mess with the options here + */ + if (args->options & ~(WUNTRACED | WNOHANG | WCONTINUED | __WCLONE)) + return (EINVAL); options = (args->options & (WNOHANG | WUNTRACED)); /* WLINUXCLONE should be equal to __WCLONE, but we make sure */ @@ -896,11 +936,34 @@ printf(ARGS(mknod, "%s, %d, %d"), path, args->mode, args->dev); #endif - if (args->mode & S_IFIFO) + switch (args->mode & S_IFMT) { + case S_IFIFO: + case S_IFSOCK: error = kern_mkfifo(td, path, UIO_SYSSPACE, args->mode); - else + break; + + case S_IFCHR: + case S_IFBLK: error = kern_mknod(td, path, UIO_SYSSPACE, args->mode, args->dev); + break; + + case S_IFDIR: + error = EPERM; + break; + + case 0: + args->mode |= S_IFREG; + /* FALLTHROUGH */ + case S_IFREG: + error = kern_open(td, path, UIO_SYSSPACE, + O_WRONLY | O_CREAT | O_TRUNC, args->mode); + break; + + default: + error = EINVAL; + break; + } LFREEPATH(path); return (error); } @@ -960,10 +1023,10 @@ B2L_ITIMERVAL(&aitv, &ls); #ifdef DEBUG if (ldebug(setitimer)) { - printf("setitimer: value: sec: %ld, usec: %ld\n", - aitv.it_value.tv_sec, aitv.it_value.tv_usec); - printf("setitimer: interval: sec: %ld, usec: %ld\n", - aitv.it_interval.tv_sec, aitv.it_interval.tv_usec); + printf("setitimer: value: sec: %jd, usec: %ld\n", + (intmax_t)aitv.it_value.tv_sec, aitv.it_value.tv_usec); + printf("setitimer: interval: sec: %jd, usec: %ld\n", + (intmax_t)aitv.it_interval.tv_sec, aitv.it_interval.tv_usec); } #endif error = kern_setitimer(td, uap->which, &aitv, &oitv); @@ -1047,8 +1110,7 @@ bsd_gidset[ngrp + 1] = linux_gidset[ngrp]; ngrp--; } - } - else + } else newcred->cr_ngroups = 1; setsugid(p); @@ -1438,3 +1500,20 @@ td->td_retval[0] = 20 - td->td_retval[0]; return error; } + +int +linux_sethostname(struct thread *td, struct linux_sethostname_args *args) +{ + int name[2]; + +#ifdef DEBUG + if (ldebug(sethostname)) + printf(ARGS(sethostname, "*, %i"), args->len); +#endif + + name[0] = CTL_KERN; + name[1] = KERN_HOSTNAME; + return (userland_sysctl(td, name, 2, 0, 0, 0, args->hostname, + args->len, 0, 0)); +} + Index: sys/compat/linux/linux_signal.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/compat/linux/linux_signal.c,v retrieving revision 1.51 diff -u -u -r1.51 linux_signal.c --- sys/compat/linux/linux_signal.c 13 Feb 2005 19:50:57 -0000 1.51 +++ sys/compat/linux/linux_signal.c 11 May 2007 13:49:38 -0000 @@ -150,7 +150,7 @@ struct sigaction act, oact, *nsa, *osa; int error, sig; - if (linux_sig <= 0 || linux_sig > LINUX_NSIG) + if (!LINUX_SIG_VALID(linux_sig)) return (EINVAL); osa = (linux_osa != NULL) ? &oact : NULL; Index: sys/compat/linux/linux_signal.h =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/compat/linux/linux_signal.h,v retrieving revision 1.6 diff -u -u -r1.6 linux_signal.h --- sys/compat/linux/linux_signal.h 20 Mar 2002 05:42:02 -0000 1.6 +++ sys/compat/linux/linux_signal.h 11 May 2007 13:49:38 -0000 @@ -35,4 +35,6 @@ void bsd_to_linux_sigset(sigset_t *, l_sigset_t *); int linux_do_sigaction(struct thread *, int, l_sigaction_t *, l_sigaction_t *); +#define LINUX_SIG_VALID(sig) ((sig) <= LINUX_NSIG && (sig) > 0) + #endif /* _LINUX_SIGNAL_H_ */ Index: sys/compat/linux/linux_socket.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/compat/linux/linux_socket.c,v retrieving revision 1.59.2.1 diff -u -u -r1.59.2.1 linux_socket.c --- sys/compat/linux/linux_socket.c 10 Jan 2006 10:12:55 -0000 1.59.2.1 +++ sys/compat/linux/linux_socket.c 11 May 2007 13:49:38 -0000 @@ -53,6 +53,7 @@ #include #include #include +#include #include #include @@ -299,6 +300,20 @@ return (SO_OOBINLINE); case LINUX_SO_LINGER: return (SO_LINGER); + case LINUX_SO_PEERCRED: + return (LOCAL_PEERCRED); + case LINUX_SO_RCVLOWAT: + return (SO_RCVLOWAT); + case LINUX_SO_SNDLOWAT: + return (SO_SNDLOWAT); + case LINUX_SO_RCVTIMEO: + return (SO_RCVTIMEO); + case LINUX_SO_SNDTIMEO: + return (SO_SNDTIMEO); + case LINUX_SO_TIMESTAMP: + return (SO_TIMESTAMP); + case LINUX_SO_ACCEPTCONN: + return (SO_ACCEPTCONN); } return (-1); } @@ -343,6 +358,48 @@ return ret_flags; } +/* +* If bsd_to_linux_sockaddr() or linux_to_bsd_sockaddr() faults, then the +* native syscall will fault. Thus, we don't really need to check the +* return values for these functions. +*/ + +static int +bsd_to_linux_sockaddr(struct sockaddr *arg) +{ + struct sockaddr sa; + size_t sa_len = sizeof(struct sockaddr); + int error; + + if ((error = copyin(arg, &sa, sa_len))) + return (error); + + *(u_short *)&sa = sa.sa_family; + + error = copyout(&sa, arg, sa_len); + + return (error); +} + +static int +linux_to_bsd_sockaddr(struct sockaddr *arg, int len) +{ + struct sockaddr sa; + size_t sa_len = sizeof(struct sockaddr); + int error; + + if ((error = copyin(arg, &sa, sa_len))) + return (error); + + sa.sa_family = *(sa_family_t *)&sa; + sa.sa_len = len; + + error = copyout(&sa, arg, sa_len); + + return (error); +} + + static int linux_sa_put(struct osockaddr *osa) { @@ -574,7 +631,11 @@ if (error) return (error); - return (kern_bind(td, linux_args.s, sa)); + error = kern_bind(td, linux_args.s, sa); + free(sa, M_SONAME); + if (error == EADDRNOTAVAIL && linux_args.namelen != sizeof(struct sockaddr_in)) + return (EINVAL); + return (error); } struct linux_connect_args { @@ -608,6 +669,7 @@ return (error); error = kern_connect(td, linux_args.s, sa); + free(sa, M_SONAME); if (error != EISCONN) return (error); @@ -615,6 +677,10 @@ * Linux doesn't return EISCONN the first time it occurs, * when on a non-blocking socket. Instead it returns the * error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD. + * + * XXXRW: Instead of using fgetsock(), check that it is a + * socket and use the file descriptor reference instead of + * creating a new one. */ NET_LOCK_GIANT(); error = fgetsock(td, linux_args.s, &so, &fflag); @@ -673,9 +739,6 @@ struct sockaddr * __restrict name; socklen_t * __restrict anamelen; } */ bsd_args; - struct close_args /* { - int fd; - } */ c_args; int error, fd; if ((error = copyin(args, &linux_args, sizeof(linux_args)))) @@ -685,14 +748,17 @@ /* XXX: */ bsd_args.name = (struct sockaddr * __restrict)PTRIN(linux_args.addr); bsd_args.anamelen = PTRIN(linux_args.namelen);/* XXX */ - error = oaccept(td, &bsd_args); - if (error) + error = accept(td, &bsd_args); + bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.name); + if (error) { + if (error == EFAULT && linux_args.namelen != sizeof(struct sockaddr_in)) + return (EINVAL); return (error); + } if (linux_args.addr) { error = linux_sa_put(PTRIN(linux_args.addr)); if (error) { - c_args.fd = td->td_retval[0]; - (void)close(td, &c_args); + (void)kern_close(td, td->td_retval[0]); return (error); } } @@ -732,7 +798,8 @@ /* XXX: */ bsd_args.asa = (struct sockaddr * __restrict)PTRIN(linux_args.addr); bsd_args.alen = PTRIN(linux_args.namelen); /* XXX */ - error = ogetsockname(td, &bsd_args); + error = getsockname(td, &bsd_args); + bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.asa); if (error) return (error); error = linux_sa_put(PTRIN(linux_args.addr)); @@ -751,7 +818,7 @@ linux_getpeername(struct thread *td, struct linux_getpeername_args *args) { struct linux_getpeername_args linux_args; - struct ogetpeername_args /* { + struct getpeername_args /* { int fdes; caddr_t asa; int *alen; @@ -762,9 +829,10 @@ return (error); bsd_args.fdes = linux_args.s; - bsd_args.asa = (caddr_t)PTRIN(linux_args.addr); + bsd_args.asa = (struct sockaddr *)PTRIN(linux_args.addr); bsd_args.alen = (int *)PTRIN(linux_args.namelen); - error = ogetpeername(td, &bsd_args); + error = getpeername(td, &bsd_args); + bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.asa); if (error) return (error); error = linux_sa_put(PTRIN(linux_args.addr)); @@ -920,11 +988,15 @@ struct sockaddr * __restrict from; socklen_t * __restrict fromlenaddr; } */ bsd_args; + size_t len; int error; if ((error = copyin(args, &linux_args, sizeof(linux_args)))) return (error); + if ((error = copyin(PTRIN(linux_args.fromlen), &len, sizeof(size_t)))) + return (error); + bsd_args.s = linux_args.s; bsd_args.buf = PTRIN(linux_args.buf); bsd_args.len = linux_args.len; @@ -932,7 +1004,11 @@ /* XXX: */ bsd_args.from = (struct sockaddr * __restrict)PTRIN(linux_args.from); bsd_args.fromlenaddr = PTRIN(linux_args.fromlen);/* XXX */ - error = orecvfrom(td, &bsd_args); + + linux_to_bsd_sockaddr((struct sockaddr *)bsd_args.from, len); + error = recvfrom(td, &bsd_args); + bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.from); + if (error) return (error); if (linux_args.from) { @@ -966,6 +1042,16 @@ error = copyin(PTRIN(linux_args.msg), &msg, sizeof(msg)); if (error) return (error); + + /* + * Some Linux applications (ping) define a non-NULL control data + * pointer, but a msg_controllen of 0, which is not allowed in the + * FreeBSD system call interface. NULL the msg_control pointer in + * order to handle this case. This should be checked, but allows the + * Linux ping to work. + */ + if (msg.msg_control != NULL && msg.msg_controllen == 0) + msg.msg_control = NULL; error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE); if (error) return (error); @@ -1001,10 +1087,19 @@ if ((error = copyin(args, &linux_args, sizeof(linux_args)))) return (error); + if ((error = copyin(PTRIN(args->msg), &msg, sizeof (msg)))) + return (error); + bsd_args.s = linux_args.s; bsd_args.msg = PTRIN(linux_args.msg); bsd_args.flags = linux_to_bsd_msg_flags(linux_args.flags); - error = recvmsg(td, &bsd_args); + if (msg.msg_name) { + linux_to_bsd_sockaddr((struct sockaddr *)msg.msg_name, + msg.msg_namelen); + error = recvmsg(td, &bsd_args); + bsd_to_linux_sockaddr((struct sockaddr *)msg.msg_name); + } else + error = recvmsg(td, &bsd_args); if (error) return (error); @@ -1087,12 +1182,21 @@ break; } if (name == -1) - return (EINVAL); + return (ENOPROTOOPT); bsd_args.name = name; bsd_args.val = PTRIN(linux_args.optval); bsd_args.valsize = linux_args.optlen; - return (setsockopt(td, &bsd_args)); + + if (name == IPV6_NEXTHOP) { + linux_to_bsd_sockaddr((struct sockaddr *)bsd_args.val, + bsd_args.valsize); + error = setsockopt(td, &bsd_args); + bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.val); + } else + error = setsockopt(td, &bsd_args); + + return (error); } struct linux_getsockopt_args { @@ -1142,7 +1246,14 @@ bsd_args.name = name; bsd_args.val = PTRIN(linux_args.optval); bsd_args.avalsize = PTRIN(linux_args.optlen); - return (getsockopt(td, &bsd_args)); + + if (name == IPV6_NEXTHOP) { + error = getsockopt(td, &bsd_args); + bsd_to_linux_sockaddr((struct sockaddr *)bsd_args.val); + } else + error = getsockopt(td, &bsd_args); + + return (error); } int Index: sys/compat/linux/linux_stats.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/compat/linux/linux_stats.c,v retrieving revision 1.72.2.3 diff -u -u -r1.72.2.3 linux_stats.c --- sys/compat/linux/linux_stats.c 15 Jun 2006 19:08:03 -0000 1.72.2.3 +++ sys/compat/linux/linux_stats.c 11 May 2007 13:49:38 -0000 @@ -211,7 +211,8 @@ #endif error = kern_lstat(td, path, UIO_SYSSPACE, &sb); - translate_path_major_minor(td, path, &sb); + if (!error) + translate_path_major_minor(td, path, &sb); LFREEPATH(path); if (error) return (error); @@ -237,6 +238,67 @@ return (error); } +static int +stat_copyout(struct stat *buf, void *ubuf) +{ + struct l_stat lbuf; + + bzero(&lbuf, sizeof(lbuf)); + lbuf.st_dev = buf->st_dev; + lbuf.st_ino = buf->st_ino; + lbuf.st_mode = buf->st_mode; + lbuf.st_nlink = buf->st_nlink; + lbuf.st_uid = buf->st_uid; + lbuf.st_gid = buf->st_gid; + lbuf.st_rdev = buf->st_rdev; + if (buf->st_size < (quad_t)1 << 32) + lbuf.st_size = buf->st_size; + else + lbuf.st_size = -2; + lbuf.st_atime = buf->st_atime; + lbuf.st_mtime = buf->st_mtime; + lbuf.st_ctime = buf->st_ctime; + lbuf.st_blksize = buf->st_blksize; + lbuf.st_blocks = buf->st_blocks; + lbuf.st_flags = buf->st_flags; + lbuf.st_gen = buf->st_gen; + + return (copyout(&lbuf, ubuf, sizeof(lbuf))); +} + +int +linux_stat(struct thread *td, struct linux_stat_args *args) +{ + struct stat buf; + int error; +#ifdef DEBUG + if (ldebug(stat)) + printf(ARGS(stat, "%s, *"), args->path); +#endif + error = kern_stat(td, args->path, UIO_SYSSPACE, &buf); + if (error) + return (error); + translate_path_major_minor(td, args->path, &buf); + return(stat_copyout(&buf, args->up)); +} + +int +linux_lstat(struct thread *td, struct linux_lstat_args *args) +{ + struct stat buf; + int error; + +#ifdef DEBUG + if (ldebug(lstat)) + printf(ARGS(lstat, "%s, *"), args->path); +#endif + error = kern_lstat(td, args->path, UIO_SYSSPACE, &buf); + if (error) + return (error); + translate_path_major_minor(td, args->path, &buf); + return(stat_copyout(&buf, args->up)); +} + /* XXX - All fields of type l_int are defined as l_long on i386 */ struct l_statfs { l_int f_type; @@ -251,6 +313,19 @@ l_int f_spare[6]; }; +struct l_statfs64 { + l_int f_type; + l_int f_bsize; + uint64_t f_blocks; + uint64_t f_bfree; + uint64_t f_bavail; + uint64_t f_files; + uint64_t f_ffree; + l_fsid_t f_fsid; + l_int f_namelen; + l_int f_spare[6]; +}; + #define LINUX_CODA_SUPER_MAGIC 0x73757245L #define LINUX_EXT2_SUPER_MAGIC 0xEF53L #define LINUX_HPFS_SUPER_MAGIC 0xf995e849L @@ -261,6 +336,7 @@ #define LINUX_NTFS_SUPER_MAGIC 0x5346544EL #define LINUX_PROC_SUPER_MAGIC 0x9fa0L #define LINUX_UFS_SUPER_MAGIC 0x00011954L /* XXX - UFS_MAGIC in Linux */ +#define LINUX_DEVFS_SUPER_MAGIC 0x1373L static long bsd_to_linux_ftype(const char *fstypename) @@ -277,6 +353,7 @@ {"nwfs", LINUX_NCP_SUPER_MAGIC}, {"hpfs", LINUX_HPFS_SUPER_MAGIC}, {"coda", LINUX_CODA_SUPER_MAGIC}, + {"devfs", LINUX_DEVFS_SUPER_MAGIC}, {NULL, 0L}}; for (i = 0; b2l_tbl[i].bsd_name != NULL; i++) @@ -324,6 +401,44 @@ return copyout(&linux_statfs, args->buf, sizeof(linux_statfs)); } +static void +bsd_to_linux_statfs64(struct statfs *bsd_statfs, struct l_statfs64 *linux_statfs) +{ + + linux_statfs->f_type = bsd_to_linux_ftype(bsd_statfs->f_fstypename); + linux_statfs->f_bsize = bsd_statfs->f_bsize; + linux_statfs->f_blocks = bsd_statfs->f_blocks; + linux_statfs->f_bfree = bsd_statfs->f_bfree; + linux_statfs->f_bavail = bsd_statfs->f_bavail; + linux_statfs->f_ffree = bsd_statfs->f_ffree; + linux_statfs->f_files = bsd_statfs->f_files; + linux_statfs->f_fsid.val[0] = bsd_statfs->f_fsid.val[0]; + linux_statfs->f_fsid.val[1] = bsd_statfs->f_fsid.val[1]; + linux_statfs->f_namelen = MAXNAMLEN; +} + +int +linux_statfs64(struct thread *td, struct linux_statfs64_args *args) +{ + struct l_statfs64 linux_statfs; + struct statfs bsd_statfs; + char *path; + int error; + + LCONVPATHEXIST(td, args->path, &path); + +#ifdef DEBUG + if (ldebug(statfs64)) + printf(ARGS(statfs64, "%s, *"), path); +#endif + error = kern_statfs(td, path, UIO_SYSSPACE, &bsd_statfs); + LFREEPATH(path); + if (error) + return (error); + bsd_to_linux_statfs64(&bsd_statfs, &linux_statfs); + return copyout(&linux_statfs, args->buf, sizeof(linux_statfs)); +} + int linux_fstatfs(struct thread *td, struct linux_fstatfs_args *args) { @@ -409,18 +524,19 @@ #endif error = kern_stat(td, filename, UIO_SYSSPACE, &buf); - if (!error && strlen(filename) > strlen("/dev/pts/") && - !strncmp(filename, "/dev/pts/", strlen("/dev/pts/")) - && filename[9] >= '0' && filename[9] <= '9') { - /* - * Linux checks major and minors of the slave device to make - * sure it's a pty deivce, so let's make him believe it is. - */ - buf.st_rdev = (136 << 8); + if (!error) { + if (strlen(filename) > strlen("/dev/pts/") && + !strncmp(filename, "/dev/pts/", strlen("/dev/pts/")) && + filename[9] >= '0' && filename[9] <= '9') { + /* + * Linux checks major and minors of the slave device + * to make sure it's a pty deivce, so let's make him + * believe it is. + */ + buf.st_rdev = (136 << 8); + } else + translate_path_major_minor(td, filename, &buf); } - - translate_path_major_minor(td, filename, &buf); - LFREEPATH(filename); if (error) return (error); @@ -442,7 +558,8 @@ #endif error = kern_lstat(td, filename, UIO_SYSSPACE, &sb); - translate_path_major_minor(td, filename, &sb); + if (!error) + translate_path_major_minor(td, filename, &sb); LFREEPATH(filename); if (error) return (error); Index: sys/compat/linux/linux_time.c =================================================================== RCS file: sys/compat/linux/linux_time.c diff -N sys/compat/linux/linux_time.c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ sys/compat/linux/linux_time.c 26 Jun 2007 11:13:59 -0000 @@ -0,0 +1,246 @@ +/* $NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $ */ + +/*- + * Copyright (c) 2001 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Emmanuel Dreyfus. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); +#if 0 +__KERNEL_RCSID(0, "$NetBSD: linux_time.c,v 1.14 2006/05/14 03:40:54 christos Exp $"); +#endif + +#include "opt_compat.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef COMPAT_LINUX32 +#include +#include +#else +#include +#include +#endif + +static void native_to_linux_timespec(struct l_timespec *, + struct timespec *); +static int linux_to_native_timespec(struct timespec *, + struct l_timespec *); +static int linux_to_native_clockid(clockid_t *, clockid_t); + +static void +native_to_linux_timespec(struct l_timespec *ltp, struct timespec *ntp) +{ + ltp->tv_sec = ntp->tv_sec; + ltp->tv_nsec = ntp->tv_nsec; +} + +static int +linux_to_native_timespec(struct timespec *ntp, struct l_timespec *ltp) +{ + if (ltp->tv_sec < 0 || ltp->tv_nsec > (l_long)999999999L) + return (EINVAL); + ntp->tv_sec = ltp->tv_sec; + ntp->tv_nsec = ltp->tv_nsec; + + return (0); +} + +static int +linux_to_native_clockid(clockid_t *n, clockid_t l) +{ + switch (l) { + case LINUX_CLOCK_REALTIME: + *n = CLOCK_REALTIME; + break; + case LINUX_CLOCK_MONOTONIC: + *n = CLOCK_MONOTONIC; + break; + case LINUX_CLOCK_PROCESS_CPUTIME_ID: + case LINUX_CLOCK_THREAD_CPUTIME_ID: + case LINUX_CLOCK_REALTIME_HR: + case LINUX_CLOCK_MONOTONIC_HR: + default: + return (EINVAL); + break; + } + + return (0); +} + +int +linux_clock_gettime(struct thread *td, struct linux_clock_gettime_args *args) +{ + struct l_timespec lts; + int error; + clockid_t nwhich = 0; /* XXX: GCC */ + struct timespec tp; + + error = linux_to_native_clockid(&nwhich, args->which); + if (error != 0) + return (error); + error = kern_clock_gettime(td, nwhich, &tp); + if (error != 0) + return (error); + native_to_linux_timespec(<s, &tp); + + return (copyout(<s, args->tp, sizeof lts)); +} + +int +linux_clock_settime(struct thread *td, struct linux_clock_settime_args *args) +{ + struct timespec ts; + struct l_timespec lts; + int error; + clockid_t nwhich = 0; /* XXX: GCC */ + + error = linux_to_native_clockid(&nwhich, args->which); + if (error != 0) + return (error); + error = copyin(args->tp, <s, sizeof lts); + if (error != 0) + return (error); + error = linux_to_native_timespec(&ts, <s); + if (error != 0) + return (error); + + return (kern_clock_settime(td, nwhich, &ts)); +} + +int +linux_clock_getres(struct thread *td, struct linux_clock_getres_args *args) +{ + struct timespec ts; + struct l_timespec lts; + int error; + clockid_t nwhich = 0; /* XXX: GCC */ + + if (args->tp == NULL) + return (0); + + error = linux_to_native_clockid(&nwhich, args->which); + if (error != 0) + return (error); + error = kern_clock_getres(td, nwhich, &ts); + if (error != 0) + return (error); + native_to_linux_timespec(<s, &ts); + + return (copyout(<s, args->tp, sizeof lts)); +} + +int +linux_nanosleep(struct thread *td, struct linux_nanosleep_args *args) +{ + struct timespec *rmtp; + struct l_timespec lrqts, lrmts; + struct timespec rqts, rmts; + int error; + + error = copyin(args->rqtp, &lrqts, sizeof lrqts); + if (error != 0) + return (error); + + if (args->rmtp != NULL) + rmtp = &rmts; + else + rmtp = NULL; + + error = linux_to_native_timespec(&rqts, &lrqts); + if (error != 0) + return (error); + error = kern_nanosleep(td, &rqts, rmtp); + if (error != 0) + return (error); + + if (args->rmtp != NULL) { + native_to_linux_timespec(&lrmts, rmtp); + error = copyout(&lrmts, args->rmtp, sizeof(lrmts)); + if (error != 0) + return (error); + } + + return (0); +} + +int +linux_clock_nanosleep(struct thread *td, struct linux_clock_nanosleep_args *args) +{ + struct timespec *rmtp; + struct l_timespec lrqts, lrmts; + struct timespec rqts, rmts; + int error; + + if (args->flags != 0) + return (EINVAL); /* XXX deal with TIMER_ABSTIME */ + + if (args->which != LINUX_CLOCK_REALTIME) + return (EINVAL); + + error = copyin(args->rqtp, &lrqts, sizeof lrqts); + if (error != 0) + return (error); + + if (args->rmtp != NULL) + rmtp = &rmts; + else + rmtp = NULL; + + error = linux_to_native_timespec(&rqts, &lrqts); + if (error != 0) + return (error); + error = kern_nanosleep(td, &rqts, rmtp); + if (error != 0) + return (error); + + if (args->rmtp != NULL) { + native_to_linux_timespec(&lrmts, rmtp); + error = copyout(&lrmts, args->rmtp, sizeof lrmts ); + if (error != 0) + return (error); + } + + return (0); +} Index: sys/compat/linux/linux_uid16.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/compat/linux/linux_uid16.c,v retrieving revision 1.16 diff -u -u -r1.16 linux_uid16.c --- sys/compat/linux/linux_uid16.c 14 Jan 2005 04:44:56 -0000 1.16 +++ sys/compat/linux/linux_uid16.c 11 May 2007 13:49:38 -0000 @@ -197,10 +197,9 @@ /* * The FreeBSD native getgid(2) and getuid(2) also modify td->td_retval[1] - * when COMPAT_43 is defined. This globbers registers that - * are assumed to be preserved. The following lightweight syscalls fixes - * this. See also linux_getpid(2), linux_getgid(2) and linux_getuid(2) in - * linux_misc.c + * when COMPAT_43 is defined. This clobbers registers that are assumed to + * be preserved. The following lightweight syscalls fixes this. See also + * linux_getpid(2), linux_getgid(2) and linux_getuid(2) in linux_misc.c * * linux_getgid16() - MP SAFE * linux_getuid16() - MP SAFE Index: sys/conf/files.amd64 =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/conf/files.amd64,v retrieving revision 1.71.2.13 diff -u -u -r1.71.2.13 files.amd64 --- sys/conf/files.amd64 6 Jun 2007 15:59:29 -0000 1.71.2.13 +++ sys/conf/files.amd64 26 Jun 2007 11:14:58 -0000 @@ -246,6 +246,7 @@ compat/linux/linux_socket.c optional compat_linux32 compat/linux/linux_stats.c optional compat_linux32 compat/linux/linux_sysctl.c optional compat_linux32 +compat/linux/linux_time.c optional compat_linux32 compat/linux/linux_uid16.c optional compat_linux32 compat/linux/linux_util.c optional compat_linux32 # Index: sys/conf/files.i386 =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/conf/files.i386,v retrieving revision 1.538.2.13 diff -u -u -r1.538.2.13 files.i386 --- sys/conf/files.i386 31 Mar 2007 20:21:14 -0000 1.538.2.13 +++ sys/conf/files.i386 26 Jun 2007 11:15:35 -0000 @@ -93,6 +93,7 @@ compat/linux/linux_socket.c optional compat_linux compat/linux/linux_stats.c optional compat_linux compat/linux/linux_sysctl.c optional compat_linux +compat/linux/linux_time.c optional compat_linux compat/linux/linux_uid16.c optional compat_linux compat/linux/linux_util.c optional compat_linux compat/ndis/kern_ndis.c optional ndisapi pci Index: sys/conf/files.pc98 =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/conf/files.pc98,v retrieving revision 1.327.2.7 diff -u -u -r1.327.2.7 files.pc98 --- sys/conf/files.pc98 4 Apr 2007 15:51:09 -0000 1.327.2.7 +++ sys/conf/files.pc98 26 Jun 2007 11:15:18 -0000 @@ -63,6 +63,7 @@ compat/linux/linux_socket.c optional compat_linux compat/linux/linux_stats.c optional compat_linux compat/linux/linux_sysctl.c optional compat_linux +compat/linux/linux_time.c optional compat_linux compat/linux/linux_uid16.c optional compat_linux compat/linux/linux_util.c optional compat_linux compat/pecoff/imgact_pecoff.c optional pecoff_support Index: sys/i386/linux/imgact_linux.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/i386/linux/imgact_linux.c,v retrieving revision 1.54 diff -u -u -r1.54 imgact_linux.c --- sys/i386/linux/imgact_linux.c 1 Apr 2005 20:00:10 -0000 1.54 +++ sys/i386/linux/imgact_linux.c 11 May 2007 13:49:38 -0000 @@ -124,7 +124,7 @@ /* * Check if file_offset page aligned,. - * Currently we cannot handle misalinged file offsets, + * Currently we cannot handle misaligned file offsets, * and so we read in the entire image (what a waste). */ if (file_offset & PAGE_MASK) { Index: sys/i386/linux/linux.h =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/i386/linux/linux.h,v retrieving revision 1.64 diff -u -u -r1.64 linux.h --- sys/i386/linux/linux.h 13 Apr 2005 04:31:43 -0000 1.64 +++ sys/i386/linux/linux.h 7 Jun 2007 14:19:26 -0000 @@ -6,7 +6,7 @@ * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer + * notice, this list of conditions and the following disclaimer * in this position and unchanged. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the @@ -28,10 +28,10 @@ * $FreeBSD: src/sys/i386/linux/linux.h,v 1.64 2005/04/13 04:31:43 mdodd Exp $ */ -#ifndef _I386_LINUX_LINUX_H_ -#define _I386_LINUX_LINUX_H_ +#ifndef _I386_LINUX_H_ +#define _I386_LINUX_H_ -#include /* for sigval union */ +#include /* for sigval union */ #include @@ -39,9 +39,9 @@ * debugging support */ extern u_char linux_debug_map[]; -#define ldebug(name) isclr(linux_debug_map, LINUX_SYS_linux_ ## name) -#define ARGS(nm, fmt) "linux(%ld): "#nm"("fmt")\n", (long)td->td_proc->p_pid -#define LMSG(fmt) "linux(%ld): "fmt"\n", (long)td->td_proc->p_pid +#define ldebug(name) isclr(linux_debug_map, LINUX_SYS_linux_ ## name) +#define ARGS(nm, fmt) "linux(%ld): "#nm"("fmt")\n", (long)td->td_proc->p_pid +#define LMSG(fmt) "linux(%ld): "fmt"\n", (long)td->td_proc->p_pid #ifdef MALLOC_DECLARE MALLOC_DECLARE(M_LINUX); @@ -126,7 +126,7 @@ #define LINUX_RLIMIT_NPROC 6 #define LINUX_RLIMIT_NOFILE 7 #define LINUX_RLIMIT_MEMLOCK 8 -#define LINUX_RLIMIT_AS 9 /* address space limit */ +#define LINUX_RLIMIT_AS 9 /* Address space limit */ #define LINUX_RLIM_NLIMITS 10 @@ -142,12 +142,21 @@ #define LINUX_MAP_ANON 0x0020 #define LINUX_MAP_GROWSDOWN 0x0100 +struct l_mmap_argv { + l_uintptr_t addr; + l_size_t len; + l_int prot; + l_int flags; + l_int fd; + l_off_t pgoff; +} __packed; + /* * stat family of syscalls */ struct l_timespec { - l_ulong tv_sec; - l_ulong tv_nsec; + l_time_t tv_sec; + l_long tv_nsec; }; struct l_newstat { @@ -170,6 +179,24 @@ l_ulong __unused5; }; +struct l_stat { + l_ushort st_dev; + l_ulong st_ino; + l_ushort st_mode; + l_ushort st_nlink; + l_ushort st_uid; + l_ushort st_gid; + l_ushort st_rdev; + l_long st_size; + struct l_timespec st_atimespec; + struct l_timespec st_mtimespec; + struct l_timespec st_ctimespec; + l_long st_blksize; + l_long st_blocks; + l_ulong st_flags; + l_ulong st_gen; +}; + struct l_stat64 { l_ushort st_dev; u_char __pad0[10]; @@ -263,9 +290,9 @@ #define LINUX_SIGADDSET(set, sig) SIGADDSET(set, sig) /* sigaltstack */ -#define LINUX_MINSIGSTKSZ 2048 -#define LINUX_SS_ONSTACK 1 -#define LINUX_SS_DISABLE 2 +#define LINUX_MINSIGSTKSZ 2048 +#define LINUX_SS_ONSTACK 1 +#define LINUX_SS_DISABLE 2 int linux_to_bsd_sigaltstack(int lsa); int bsd_to_linux_sigaltstack(int bsa); @@ -328,11 +355,11 @@ void *uc_link; l_stack_t uc_stack; struct l_sigcontext uc_mcontext; - l_sigset_t uc_sigmask; + l_sigset_t uc_sigmask; }; -#define LINUX_SI_MAX_SIZE 128 -#define LINUX_SI_PAD_SIZE ((LINUX_SI_MAX_SIZE/sizeof(l_int)) - 3) +#define LINUX_SI_MAX_SIZE 128 +#define LINUX_SI_PAD_SIZE ((LINUX_SI_MAX_SIZE/sizeof(l_int)) - 3) typedef struct l_siginfo { l_int lsi_signo; @@ -366,41 +393,41 @@ } _sigchld; struct { - void *_addr; /* faulting insn/memory ref. */ + void *_addr; /* Faulting insn/memory ref. */ } _sigfault; struct { - l_int _band; /* POLL_IN,POLL_OUT,POLL_MSG */ + l_int _band; /* POLL_IN,POLL_OUT,POLL_MSG */ l_int _fd; } _sigpoll; } _sifields; } l_siginfo_t; -#define lsi_pid _sifields._kill._pid -#define lsi_uid _sifields._kill._uid -#define lsi_status _sifields._sigchld._status -#define lsi_utime _sifields._sigchld._utime -#define lsi_stime _sifields._sigchld._stime -#define lsi_value _sifields._rt._sigval -#define lsi_int _sifields._rt._sigval.sival_int -#define lsi_ptr _sifields._rt._sigval.sival_ptr -#define lsi_addr _sifields._sigfault._addr -#define lsi_band _sifields._sigpoll._band -#define lsi_fd _sifields._sigpoll._fd +#define lsi_pid _sifields._kill._pid +#define lsi_uid _sifields._kill._uid +#define lsi_status _sifields._sigchld._status +#define lsi_utime _sifields._sigchld._utime +#define lsi_stime _sifields._sigchld._stime +#define lsi_value _sifields._rt._sigval +#define lsi_int _sifields._rt._sigval.sival_int +#define lsi_ptr _sifields._rt._sigval.sival_ptr +#define lsi_addr _sifields._sigfault._addr +#define lsi_band _sifields._sigpoll._band +#define lsi_fd _sifields._sigpoll._fd struct l_fpreg { - u_int16_t significand[4]; - u_int16_t exponent; + u_int16_t significand[4]; + u_int16_t exponent; }; struct l_fpxreg { - u_int16_t significand[4]; - u_int16_t exponent; - u_int16_t padding[3]; + u_int16_t significand[4]; + u_int16_t exponent; + u_int16_t padding[3]; }; struct l_xmmreg { - u_int32_t element[4]; + u_int32_t element[4]; }; struct l_fpstate { @@ -414,13 +441,13 @@ u_int32_t datasel; struct l_fpreg _st[8]; u_int16_t status; - u_int16_t magic; /* 0xffff = regular FPU data */ + u_int16_t magic; /* 0xffff = regular FPU data */ /* FXSR FPU environment */ - u_int32_t _fxsr_env[6]; /* env is ignored */ + u_int32_t _fxsr_env[6]; /* env is ignored. */ u_int32_t mxcsr; u_int32_t reserved; - struct l_fpxreg _fxsr_st[8]; /* reg data is ignored */ + struct l_fpxreg _fxsr_st[8]; /* reg data is ignored. */ struct l_xmmreg _xmm[8]; u_int32_t padding[56]; }; @@ -472,22 +499,23 @@ /* * open/fcntl flags */ -#define LINUX_O_RDONLY 00 -#define LINUX_O_WRONLY 01 -#define LINUX_O_RDWR 02 -#define LINUX_O_CREAT 0100 -#define LINUX_O_EXCL 0200 -#define LINUX_O_NOCTTY 0400 -#define LINUX_O_TRUNC 01000 -#define LINUX_O_APPEND 02000 -#define LINUX_O_NONBLOCK 04000 +#define LINUX_O_RDONLY 00000000 +#define LINUX_O_WRONLY 00000001 +#define LINUX_O_RDWR 00000002 +#define LINUX_O_ACCMODE 00000003 +#define LINUX_O_CREAT 00000100 +#define LINUX_O_EXCL 00000200 +#define LINUX_O_NOCTTY 00000400 +#define LINUX_O_TRUNC 00001000 +#define LINUX_O_APPEND 00002000 +#define LINUX_O_NONBLOCK 00004000 #define LINUX_O_NDELAY LINUX_O_NONBLOCK -#define LINUX_O_SYNC 010000 -#define LINUX_FASYNC 020000 -#define LINUX_O_DIRECT 040000 /* direct disk access hint */ -#define LINUX_O_LARGEFILE 0100000 -#define LINUX_O_DIRECTORY 0200000 /* must be a directory */ -#define LINUX_O_NOFOLLOW 0400000 /* don't follow links */ +#define LINUX_O_SYNC 00010000 +#define LINUX_FASYNC 00020000 +#define LINUX_O_DIRECT 00040000 /* Direct disk access hint */ +#define LINUX_O_LARGEFILE 00100000 +#define LINUX_O_DIRECTORY 00200000 /* Must be a directory */ +#define LINUX_O_NOFOLLOW 00400000 /* Do not follow links */ #define LINUX_O_NOATIME 01000000 #define LINUX_F_DUPFD 0 @@ -509,15 +537,17 @@ #define LINUX_F_WRLCK 1 #define LINUX_F_UNLCK 2 +#define LINUX_AT_FDCWD -100 + /* * mount flags */ -#define LINUX_MS_RDONLY 0x0001 -#define LINUX_MS_NOSUID 0x0002 -#define LINUX_MS_NODEV 0x0004 -#define LINUX_MS_NOEXEC 0x0008 -#define LINUX_MS_REMOUNT 0x0020 - +#define LINUX_MS_RDONLY 0x0001 +#define LINUX_MS_NOSUID 0x0002 +#define LINUX_MS_NODEV 0x0004 +#define LINUX_MS_NOEXEC 0x0008 +#define LINUX_MS_REMOUNT 0x0020 + /* * SystemV IPC defines */ @@ -615,6 +645,13 @@ #define LINUX_SO_NO_CHECK 11 #define LINUX_SO_PRIORITY 12 #define LINUX_SO_LINGER 13 +#define LINUX_SO_PEERCRED 17 +#define LINUX_SO_RCVLOWAT 18 +#define LINUX_SO_SNDLOWAT 19 +#define LINUX_SO_RCVTIMEO 20 +#define LINUX_SO_SNDTIMEO 21 +#define LINUX_SO_TIMESTAMP 29 +#define LINUX_SO_ACCEPTCONN 30 #define LINUX_IP_TOS 1 #define LINUX_IP_TTL 2 @@ -664,7 +701,7 @@ } ifr_ifru; }; -#define ifr_name ifr_ifrn.ifrn_name /* interface name */ +#define ifr_name ifr_ifrn.ifrn_name /* Interface name */ #define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */ /* @@ -688,4 +725,14 @@ l_short revents; }; -#endif /* !_I386_LINUX_LINUX_H_ */ +#define LINUX_CLOCK_REALTIME 0 +#define LINUX_CLOCK_MONOTONIC 1 +#define LINUX_CLOCK_PROCESS_CPUTIME_ID 2 +#define LINUX_CLOCK_THREAD_CPUTIME_ID 3 +#define LINUX_CLOCK_REALTIME_HR 4 +#define LINUX_CLOCK_MONOTONIC_HR 5 + +typedef int l_timer_t; +typedef int l_mqd_t; + +#endif /* !_I386_LINUX_H_ */ Index: sys/i386/linux/linux_dummy.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/i386/linux/linux_dummy.c,v retrieving revision 1.38 diff -u -u -r1.38 linux_dummy.c --- sys/i386/linux/linux_dummy.c 28 Mar 2004 21:43:27 -0000 1.38 +++ sys/i386/linux/linux_dummy.c 3 Jul 2007 07:48:18 -0000 @@ -37,7 +37,6 @@ #include #include -DUMMY(stat); DUMMY(stime); DUMMY(fstat); DUMMY(olduname); @@ -70,6 +69,56 @@ DUMMY(pivot_root); DUMMY(mincore); DUMMY(fadvise64); +DUMMY(set_tid_address); +DUMMY(lookup_dcookie); +DUMMY(epoll_create); +DUMMY(epoll_ctl); +DUMMY(epoll_wait); +DUMMY(remap_file_pages); +DUMMY(fstatfs64); +DUMMY(tgkill); +DUMMY(fadvise64_64); +DUMMY(mbind); +DUMMY(get_mempolicy); +DUMMY(set_mempolicy); +DUMMY(kexec_load); +DUMMY(waitid); +DUMMY(add_key); +DUMMY(request_key); +DUMMY(keyctl); +DUMMY(ioprio_set); +DUMMY(ioprio_get); +DUMMY(inotify_init); +DUMMY(inotify_add_watch); +DUMMY(inotify_rm_watch); +DUMMY(migrate_pages); +DUMMY(openat); +DUMMY(mkdirat); +DUMMY(mknodat); +DUMMY(fchownat); +DUMMY(futimesat); +DUMMY(fstatat64); +DUMMY(unlinkat); +DUMMY(renameat); +DUMMY(linkat); +DUMMY(symlinkat); +DUMMY(readlinkat); +DUMMY(fchmodat); +DUMMY(faccessat); +DUMMY(pselect6); +DUMMY(ppoll); +DUMMY(unshare); +DUMMY(timer_create); +DUMMY(timer_settime); +DUMMY(timer_gettime); +DUMMY(timer_getoverrun); +DUMMY(timer_delete); +DUMMY(mq_open); +DUMMY(mq_unlink); +DUMMY(mq_timedsend); +DUMMY(mq_timedreceive); +DUMMY(mq_notify); +DUMMY(mq_getsetattr); #define DUMMY_XATTR(s) \ int \ Index: sys/i386/linux/linux_machdep.c =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/i386/linux/linux_machdep.c,v retrieving revision 1.48.2.3 diff -u -u -r1.48.2.3 linux_machdep.c --- sys/i386/linux/linux_machdep.c 29 Sep 2006 19:05:24 -0000 1.48.2.3 +++ sys/i386/linux/linux_machdep.c 29 Jun 2007 05:43:46 -0000 @@ -359,7 +359,7 @@ * kernel threads. Unfortunately despite the existence of the * CLONE_THREAD flag, version of linuxthreads package used in * most popular distros as of beginning of 2005 doesn't make - * any use of it. Therefore, this detection relay fully on + * any use of it. Therefore, this detection relies on * empirical observation that linuxthreads sets certain * combination of flags, so that we can make more or less * precise detection and notify the FreeBSD kernel that several @@ -400,16 +400,6 @@ return (0); } -/* XXX move */ -struct l_mmap_argv { - l_caddr_t addr; - l_int len; - l_int prot; - l_int flags; - l_int fd; - l_int pos; -}; - #define STACK_SIZE (2 * 1024 * 1024) #define GUARD_SIZE (4 * PAGE_SIZE) @@ -427,12 +417,12 @@ args->flags, args->fd, args->pgoff); #endif - linux_args.addr = (l_caddr_t)args->addr; + linux_args.addr = args->addr; linux_args.len = args->len; linux_args.prot = args->prot; linux_args.flags = args->flags; linux_args.fd = args->fd; - linux_args.pos = args->pgoff * PAGE_SIZE; + linux_args.pgoff = args->pgoff * PAGE_SIZE; return (linux_mmap_common(td, &linux_args)); } @@ -451,7 +441,7 @@ if (ldebug(mmap)) printf(ARGS(mmap, "%p, %d, %d, 0x%08x, %d, %d"), (void *)linux_args.addr, linux_args.len, linux_args.prot, - linux_args.flags, linux_args.fd, linux_args.pos); + linux_args.flags, linux_args.fd, linux_args.pgoff); #endif return (linux_mmap_common(td, &linux_args)); @@ -495,10 +485,47 @@ bsd_args.flags |= MAP_ANON; else bsd_args.flags |= MAP_NOSYNC; - if (linux_args->flags & LINUX_MAP_GROWSDOWN) { + if (linux_args->flags & LINUX_MAP_GROWSDOWN) bsd_args.flags |= MAP_STACK; - /* The linux MAP_GROWSDOWN option does not limit auto + /* + * PROT_READ, PROT_WRITE, or PROT_EXEC implies PROT_READ and PROT_EXEC + * 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; + if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) + bsd_args.prot |= PROT_READ | PROT_EXEC; + + /* Linux does not check file descriptor when MAP_ANONYMOUS is set. */ + bsd_args.fd = (bsd_args.flags & MAP_ANON) ? -1 : linux_args->fd; + if (bsd_args.fd != -1) { + /* + * Linux follows Solaris mmap(2) description: + * The file descriptor fildes is opened with + * read permission, regardless of the + * protection options specified. + */ + + if ((error = fget(td, bsd_args.fd, &fp)) != 0) + return (error); + if (fp->f_type != DTYPE_VNODE) { + fdrop(fp, td); + return (EINVAL); + } + + /* Linux mmap() just fails for O_WRONLY files */ + if (!(fp->f_flag & FREAD)) { + fdrop(fp, td); + return (EACCES); + } + + fdrop(fp, td); + } + + if (linux_args->flags & LINUX_MAP_GROWSDOWN) { + /* + * The linux MAP_GROWSDOWN option does not limit auto * growth of the region. Linux mmap with this option * takes as addr the inital BOS, and as len, the initial * region size. It can then grow down from addr without @@ -511,7 +538,7 @@ * Our mmap with MAP_STACK takes addr as the maximum * downsize limit on BOS, and as len the max size of * the region. It them maps the top SGROWSIZ bytes, - * and autgrows the region down, up to the limit + * and auto grows the region down, up to the limit * in addr. * * If we don't use the MAP_STACK option, the effect @@ -519,11 +546,10 @@ * fixed size of (STACK_SIZE - GUARD_SIZE). */ - /* This gives us TOS */ - bsd_args.addr = linux_args->addr + linux_args->len; - - if (bsd_args.addr > p->p_vmspace->vm_maxsaddr) { - /* Some linux apps will attempt to mmap + if ((caddr_t)PTRIN(linux_args->addr) + linux_args->len > + p->p_vmspace->vm_maxsaddr) { + /* + * Some linux apps will attempt to mmap * thread stacks near the top of their * address space. If their TOS is greater * than vm_maxsaddr, vm_map_growstack() @@ -550,51 +576,20 @@ else bsd_args.len = STACK_SIZE - GUARD_SIZE; - /* This gives us a new BOS. If we're using VM_STACK, then + /* + * This gives us a new BOS. If we're using VM_STACK, then * mmap will just map the top SGROWSIZ bytes, and let * the stack grow down to the limit at BOS. If we're * not using VM_STACK we map the full stack, since we * don't have a way to autogrow it. */ - bsd_args.addr -= bsd_args.len; + bsd_args.addr = (caddr_t)PTRIN(linux_args->addr) - + bsd_args.len; } else { - bsd_args.addr = linux_args->addr; + bsd_args.addr = (caddr_t)PTRIN(linux_args->addr); bsd_args.len = linux_args->len; } - - bsd_args.prot = linux_args->prot; - if (linux_args->flags & LINUX_MAP_ANON) - bsd_args.fd = -1; - else { - /* - * Linux follows Solaris mmap(2) description: - * The file descriptor fildes is opened with - * read permission, regardless of the - * protection options specified. - * If PROT_WRITE is specified, the application - * must have opened the file descriptor - * fildes with write permission unless - * MAP_PRIVATE is specified in the flag - * argument as described below. - */ - - if ((error = fget(td, linux_args->fd, &fp)) != 0) - return (error); - if (fp->f_type != DTYPE_VNODE) { - fdrop(fp, td); - return (EINVAL); - } - - /* Linux mmap() just fails for O_WRONLY files */ - if (! (fp->f_flag & FREAD)) { - fdrop(fp, td); - return (EACCES); - } - - bsd_args.fd = linux_args->fd; - fdrop(fp, td); - } - bsd_args.pos = linux_args->pos; + bsd_args.pos = linux_args->pgoff; bsd_args.pad = 0; #ifdef DEBUG @@ -614,6 +609,19 @@ } int +linux_mprotect(struct thread *td, struct linux_mprotect_args *uap) +{ + struct mprotect_args bsd_args; + + bsd_args.addr = uap->addr; + bsd_args.len = uap->len; + bsd_args.prot = uap->prot; + if (bsd_args.prot & (PROT_READ | PROT_WRITE | PROT_EXEC)) + bsd_args.prot |= PROT_READ | PROT_EXEC; + return (mprotect(td, &bsd_args)); +} + +int linux_pipe(struct thread *td, struct linux_pipe_args *args) { int error; Index: sys/i386/linux/linux_proto.h =================================================================== RCS file: /import/FreeBSD-CVS/src/sys/i386/linux/linux_proto.h,v retrieving revision 1.64.2.1 diff -u -u -r1.64.2.1 linux_proto.h --- sys/i386/linux/linux_proto.h 20 Jul 2005 17:43:53 -0000 1.64.2.1 +++ sys/i386/linux/linux_proto.h 26 Jun 2007 10:57:48 -0000 @@ -2,7 +2,7 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $FreeBSD: src/sys/i386/linux/linux_proto.h,v 1.64.2.1 2005/07/20 17:43:53 jhb Exp $ + * $FreeBSD$ * created from FreeBSD: src/sys/i386/linux/syscalls.master,v 1.61.2.1 2005/07/20 17:42:15 jhb Exp */ @@ -84,7 +84,7 @@ }; struct linux_stat_args { char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; - char up_l_[PADL_(struct ostat *)]; struct ostat * up; char up_r_[PADR_(struct ostat *)]; + char up_l_[PADL_(struct linux_stat *)]; struct linux_stat * up; char up_r_[PADR_(struct linux_stat *)]; }; struct linux_lseek_args { char fdes_l_[PADL_(l_uint)]; l_uint fdes; char fdes_r_[PADR_(l_uint)]; @@ -124,7 +124,7 @@ }; struct linux_fstat_args { char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)]; - char up_l_[PADL_(struct ostat *)]; struct ostat * up; char up_r_[PADR_(struct ostat *)]; + char up_l_[PADL_(struct linux_stat *)]; struct linux_stat * up; char up_r_[PADR_(struct linux_stat *)]; }; struct linux_pause_args { register_t dummy; @@ -228,6 +228,10 @@ struct linux_sigpending_args { char mask_l_[PADL_(l_osigset_t *)]; l_osigset_t * mask; char mask_r_[PADR_(l_osigset_t *)]; }; +struct linux_sethostname_args { + char hostname_l_[PADL_(char *)]; char * hostname; char hostname_r_[PADR_(char *)]; + char len_l_[PADL_(u_int)]; u_int len; char len_r_[PADR_(u_int)]; +}; struct linux_setrlimit_args { char resource_l_[PADL_(l_uint)]; l_uint resource; char resource_r_[PADR_(l_uint)]; char rlim_l_[PADL_(struct l_rlimit *)]; struct l_rlimit * rlim; char rlim_r_[PADR_(struct l_rlimit *)]; @@ -251,6 +255,10 @@ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; char to_l_[PADL_(char *)]; char * to; char to_r_[PADR_(char *)]; }; +struct linux_lstat_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char up_l_[PADL_(struct ostat *)]; struct ostat * up; char up_r_[PADR_(struct ostat *)]; +}; struct linux_readlink_args { char name_l_[PADL_(char *)]; char * name; char name_r_[PADR_(char *)]; char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)]; @@ -277,6 +285,10 @@ 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)]; }; +struct linux_ftruncate_args { + char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)]; + char length_l_[PADL_(long)]; long length; char length_r_[PADR_(long)]; +}; struct linux_getpriority_args { char which_l_[PADL_(int)]; int which; char which_r_[PADR_(int)]; char who_l_[PADL_(int)]; int who; char who_r_[PADR_(int)]; @@ -374,6 +386,11 @@ struct linux_adjtimex_args { register_t dummy; }; +struct linux_mprotect_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)]; + char prot_l_[PADL_(int)]; int prot; char prot_r_[PADR_(int)]; +}; struct linux_sigprocmask_args { char how_l_[PADL_(l_int)]; l_int how; char how_r_[PADR_(l_int)]; char mask_l_[PADL_(l_osigset_t *)]; l_osigset_t * mask; char mask_r_[PADR_(l_osigset_t *)]; @@ -458,6 +475,10 @@ struct linux_sched_get_priority_min_args { char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)]; }; +struct linux_nanosleep_args { + char rqtp_l_[PADL_(const struct l_timespec *)]; const struct l_timespec * rqtp; char rqtp_r_[PADR_(const struct l_timespec *)]; + char rmtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rmtp; char rmtp_r_[PADR_(struct l_timespec *)]; +}; struct linux_mremap_args { char addr_l_[PADL_(l_ulong)]; l_ulong addr; char addr_r_[PADR_(l_ulong)]; char old_len_l_[PADL_(l_ulong)]; l_ulong old_len; char old_len_r_[PADR_(l_ulong)]; @@ -513,10 +534,14 @@ char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)]; }; struct linux_rt_sigpending_args { - register_t dummy; + char set_l_[PADL_(l_sigset_t *)]; l_sigset_t * set; char set_r_[PADR_(l_sigset_t *)]; + char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)]; }; struct linux_rt_sigtimedwait_args { - register_t dummy; + char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)]; + char ptr_l_[PADL_(l_siginfo_t *)]; l_siginfo_t * ptr; char ptr_r_[PADR_(l_siginfo_t *)]; + char timeout_l_[PADL_(struct l_timeval *)]; struct l_timeval * timeout; char timeout_r_[PADR_(struct l_timeval *)]; + char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)]; }; struct linux_rt_sigqueueinfo_args { register_t dummy; @@ -695,6 +720,206 @@ struct linux_fadvise64_args { register_t dummy; }; +struct linux_lookup_dcookie_args { + register_t dummy; +}; +struct linux_epoll_create_args { + register_t dummy; +}; +struct linux_epoll_ctl_args { + register_t dummy; +}; +struct linux_epoll_wait_args { + register_t dummy; +}; +struct linux_remap_file_pages_args { + register_t dummy; +}; +struct linux_set_tid_address_args { + char tidptr_l_[PADL_(int *)]; int * tidptr; char tidptr_r_[PADR_(int *)]; +}; +struct linux_timer_create_args { + char clock_id_l_[PADL_(clockid_t)]; clockid_t clock_id; char clock_id_r_[PADR_(clockid_t)]; + char evp_l_[PADL_(struct sigevent *)]; struct sigevent * evp; char evp_r_[PADR_(struct sigevent *)]; + char timerid_l_[PADL_(l_timer_t *)]; l_timer_t * timerid; char timerid_r_[PADR_(l_timer_t *)]; +}; +struct linux_timer_settime_args { + char timerid_l_[PADL_(l_timer_t)]; l_timer_t timerid; char timerid_r_[PADR_(l_timer_t)]; + char new_l_[PADL_(const struct itimerspec *)]; const struct itimerspec * new; char new_r_[PADR_(const struct itimerspec *)]; + char old_l_[PADL_(struct itimerspec *)]; struct itimerspec * old; char old_r_[PADR_(struct itimerspec *)]; +}; +struct linux_timer_gettime_args { + char timerid_l_[PADL_(l_timer_t)]; l_timer_t timerid; char timerid_r_[PADR_(l_timer_t)]; + char setting_l_[PADL_(struct itimerspec *)]; struct itimerspec * setting; char setting_r_[PADR_(struct itimerspec *)]; +}; +struct linux_timer_getoverrun_args { + char timerid_l_[PADL_(l_timer_t)]; l_timer_t timerid; char timerid_r_[PADR_(l_timer_t)]; +}; +struct linux_timer_delete_args { + char timerid_l_[PADL_(l_timer_t)]; l_timer_t timerid; char timerid_r_[PADR_(l_timer_t)]; +}; +struct linux_clock_settime_args { + char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)]; + char tp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tp; char tp_r_[PADR_(struct l_timespec *)]; +}; +struct linux_clock_gettime_args { + char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)]; + char tp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tp; char tp_r_[PADR_(struct l_timespec *)]; +}; +struct linux_clock_getres_args { + char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)]; + char tp_l_[PADL_(struct l_timespec *)]; struct l_timespec * tp; char tp_r_[PADR_(struct l_timespec *)]; +}; +struct linux_clock_nanosleep_args { + char which_l_[PADL_(clockid_t)]; clockid_t which; char which_r_[PADR_(clockid_t)]; + char flags_l_[PADL_(int)]; int flags; char flags_r_[PADR_(int)]; + char rqtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rqtp; char rqtp_r_[PADR_(struct l_timespec *)]; + char rmtp_l_[PADL_(struct l_timespec *)]; struct l_timespec * rmtp; char rmtp_r_[PADR_(struct l_timespec *)]; +}; +struct linux_statfs64_args { + char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)]; + char buf_l_[PADL_(struct l_statfs64_buf *)]; struct l_statfs64_buf * buf; char buf_r_[PADR_(struct l_statfs64_buf *)]; +}; +struct linux_fstatfs64_args { + register_t dummy; +}; +struct linux_tgkill_args { + char tgid_l_[PADL_(int)]; int tgid; char tgid_r_[PADR_(int)]; + char pid_l_[PADL_(int)]; int pid; char pid_r_[PADR_(int)]; + char sig_l_[PADL_(int)]; int sig; char sig_r_[PADR_(int)]; +}; +struct linux_utimes_args { + char fname_l_[PADL_(char *)]; char * fname; char fname_r_[PADR_(char *)]; + char tptr_l_[PADL_(struct l_timeval *)]; struct l_timeval * tptr; char tptr_r_[PADR_(struct l_timeval *)]; +}; +struct linux_fadvise64_64_args { + register_t dummy; +}; +struct linux_mbind_args { + register_t dummy; +}; +struct linux_get_mempolicy_args { + register_t dummy; +}; +struct linux_set_mempolicy_args { + register_t dummy; +}; +struct linux_mq_open_args { + char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)]; + char oflag_l_[PADL_(int)]; int oflag; char oflag_r_[PADR_(int)]; + char mode_l_[PADL_(mode_t)]; mode_t mode; char mode_r_[PADR_(mode_t)]; + char attr_l_[PADL_(struct mq_attr *)]; struct mq_attr * attr; char attr_r_[PADR_(struct mq_attr *)]; +}; +struct linux_mq_unlink_args { + char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)]; +}; +struct linux_mq_timedsend_args { + char mqd_l_[PADL_(l_mqd_t)]; l_mqd_t mqd; char mqd_r_[PADR_(l_mqd_t)]; + char msg_ptr_l_[PADL_(const char *)]; const char * msg_ptr; char msg_ptr_r_[PADR_(const char *)]; + char msg_len_l_[PADL_(size_t)]; size_t msg_len; char msg_len_r_[PADR_(size_t)]; + char msg_prio_l_[PADL_(unsigned int)]; unsigned int msg_prio; char msg_prio_r_[PADR_(unsigned int)]; + char abs_timeout_l_[PADL_(const struct l_timespec *)]; const struct l_timespec * abs_timeout; char abs_timeout_r_[PADR_(const struct l_timespec *)]; +}; +struct linux_mq_timedreceive_args { + char mqd_l_[PADL_(l_mqd_t)]; l_mqd_t mqd; char mqd_r_[PADR_(l_mqd_t)]; + char msg_ptr_l_[PADL_(char *)]; char * msg_ptr; char msg_ptr_r_[PADR_(char *)]; + char msg_len_l_[PADL_(size_t)]; size_t msg_len; char msg_len_r_[PADR_(size_t)]; + char msg_prio_l_[PADL_(unsigned int)]; unsigned int msg_prio; char msg_prio_r_[PADR_(unsigned int)]; + char abs_timeout_l_[PADL_(const struct l_timespec *)]; const struct l_timespec * abs_timeout; char abs_timeout_r_[PADR_(const struct l_timespec *)]; +}; +struct linux_mq_notify_args { + char mqd_l_[PADL_(l_mqd_t)]; l_mqd_t mqd; char mqd_r_[PADR_(l_mqd_t)]; + char abs_timeout_l_[PADL_(const struct l_timespec *)]; const struct l_timespec * abs_timeout; char abs_timeout_r_[PADR_(const struct l_timespec *)]; +}; +struct linux_mq_getsetattr_args { + char mqd_l_[PADL_(l_mqd_t)]; l_mqd_t mqd; char mqd_r_[PADR_(l_mqd_t)]; + char attr_l_[PADL_(const struct mq_attr *)]; const struct mq_attr * attr; char attr_r_[PADR_(const struct mq_attr *)]; + char oattr_l_[PADL_(struct mq_attr *)]; struct mq_attr * oattr; char oattr_r_[PADR_(struct mq_attr *)]; +}; +struct linux_kexec_load_args { + register_t dummy; +}; +struct linux_waitid_args { + register_t dummy; +}; +struct linux_add_key_args { + register_t dummy; +}; +struct linux_request_key_args { + register_t dummy; +}; +struct linux_keyctl_args { + register_t dummy; +}; +struct linux_ioprio_set_args { + register_t dummy; +}; +struct linux_ioprio_get_args { + register_t dummy; +}; +struct linux_inotify_init_args { + register_t dummy; +}; +struct linux_inotify_add_watch_args { + register_t dummy; +}; +struct linux_inotify_rm_watch_args { + register_t dummy; +}; +struct linux_migrate_pages_args { + register_t dummy; +}; +struct linux_openat_args { + char dfd_l_[PADL_(l_int)]; l_i