aboutsummaryrefslogtreecommitdiff
path: root/sys/amd64
diff options
context:
space:
mode:
authorTim J. Robbins <tjr@FreeBSD.org>2004-08-16 07:55:06 +0000
committerTim J. Robbins <tjr@FreeBSD.org>2004-08-16 07:55:06 +0000
commitea0fabbc4fcb15d10fbcaad14c405826d5eefea3 (patch)
tree8db1b1fe965caf91b81508b975442417a3f13b98 /sys/amd64
parent25aea0fcaa99d27cabdfaf648f97fceac8a4546d (diff)
downloadsrc-ea0fabbc4fcb15d10fbcaad14c405826d5eefea3.tar.gz
src-ea0fabbc4fcb15d10fbcaad14c405826d5eefea3.zip
Add preliminary support for running 32-bit Linux binaries on amd64, enabled
with the COMPAT_LINUX32 option. This is largely based on the i386 MD Linux emulations bits, but also builds on the 32-bit FreeBSD and generic IA-32 binary emulation work. Some of this is still a little rough around the edges, and will need to be revisited before 32-bit and 64-bit Linux emulation support can coexist in the same kernel.
Notes
Notes: svn path=/head/; revision=133819
Diffstat (limited to 'sys/amd64')
-rw-r--r--sys/amd64/conf/NOTES3
-rw-r--r--sys/amd64/linux32/Makefile15
-rw-r--r--sys/amd64/linux32/linux.h722
-rw-r--r--sys/amd64/linux32/linux32_dummy.c91
-rw-r--r--sys/amd64/linux32/linux32_genassym.c17
-rw-r--r--sys/amd64/linux32/linux32_ipc64.h145
-rw-r--r--sys/amd64/linux32/linux32_locore.s45
-rw-r--r--sys/amd64/linux32/linux32_machdep.c1019
-rw-r--r--sys/amd64/linux32/linux32_proto.h869
-rw-r--r--sys/amd64/linux32/linux32_syscall.h222
-rw-r--r--sys/amd64/linux32/linux32_sysent.c288
-rw-r--r--sys/amd64/linux32/linux32_sysvec.c1088
-rw-r--r--sys/amd64/linux32/syscalls.conf11
-rw-r--r--sys/amd64/linux32/syscalls.master345
14 files changed, 4880 insertions, 0 deletions
diff --git a/sys/amd64/conf/NOTES b/sys/amd64/conf/NOTES
index b21160c79c5b..fe0d908d0e39 100644
--- a/sys/amd64/conf/NOTES
+++ b/sys/amd64/conf/NOTES
@@ -465,6 +465,9 @@ options PMAP_SHPGPERPROC=201
# Enable Linux ABI emulation
#XXX#options COMPAT_LINUX
+# Enable 32-bit Linux ABI emulation (requires COMPAT_43 and IA32)
+options COMPAT_LINUX32
+
# Enable the linux-like proc filesystem support (requires COMPAT_LINUX
# and PSEUDOFS)
#XXX#options LINPROCFS
diff --git a/sys/amd64/linux32/Makefile b/sys/amd64/linux32/Makefile
new file mode 100644
index 000000000000..ae4f1078a2ad
--- /dev/null
+++ b/sys/amd64/linux32/Makefile
@@ -0,0 +1,15 @@
+# Makefile for syscall tables
+#
+# $FreeBSD$
+
+all:
+ @echo "make sysent only"
+
+sysent: linux32_sysent.c linux32_syscall.h linux32_proto.h
+
+linux32_sysent.c linux32_syscall.h linux32_proto.h: ../../kern/makesyscalls.sh \
+ syscalls.master syscalls.conf
+ -mv -f linux32_sysent.c linux32_sysent.c.bak
+ -mv -f linux32_syscall.h linux32_syscall.h.bak
+ -mv -f linux32_proto.h linux32_proto.h.bak
+ sh ../../kern/makesyscalls.sh syscalls.master syscalls.conf
diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h
new file mode 100644
index 000000000000..7362b228cbfb
--- /dev/null
+++ b/sys/amd64/linux32/linux.h
@@ -0,0 +1,722 @@
+/*-
+ * Copyright (c) 2004 Tim J. Robbins
+ * Copyright (c) 2001 Doug Rabson
+ * Copyright (c) 1994-1996 Søren Schmidt
+ * All rights reserved.
+ *
+ * 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
+ * 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
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _AMD64_LINUX_LINUX_H_
+#define _AMD64_LINUX_LINUX_H_
+
+#include <sys/signal.h> /* for sigval union */
+
+#include <amd64/linux32/linux32_syscall.h>
+
+/*
+ * 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
+
+#ifdef MALLOC_DECLARE
+MALLOC_DECLARE(M_LINUX);
+#endif
+
+#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 PTRIN(v) (void *)(uintptr_t)(v)
+#define PTROUT(v) (l_uintptr_t)(uintptr_t)(v)
+
+/*
+ * Provide a separate set of types for the Linux types.
+ */
+typedef int l_int;
+typedef int32_t l_long;
+typedef int64_t l_longlong;
+typedef short l_short;
+typedef unsigned int l_uint;
+typedef uint32_t l_ulong;
+typedef uint64_t l_ulonglong;
+typedef unsigned short l_ushort;
+
+typedef l_ulong l_uintptr_t;
+typedef l_long l_clock_t;
+typedef l_int l_daddr_t;
+typedef l_ushort l_dev_t;
+typedef l_uint l_gid_t;
+typedef l_ushort l_gid16_t;
+typedef l_ulong l_ino_t;
+typedef l_int l_key_t;
+typedef l_longlong l_loff_t;
+typedef l_ushort l_mode_t;
+typedef l_long l_off_t;
+typedef l_int l_pid_t;
+typedef l_uint l_size_t;
+typedef l_long l_suseconds_t;
+typedef l_long l_time_t;
+typedef l_uint l_uid_t;
+typedef l_ushort l_uid16_t;
+
+typedef struct {
+ l_int val[2];
+} __packed l_fsid_t;
+
+typedef struct {
+ l_time_t tv_sec;
+ l_suseconds_t tv_usec;
+} __packed l_timeval;
+
+#define l_fd_set fd_set
+
+/*
+ * Miscellaneous
+ */
+#define LINUX_NAME_MAX 255
+#define LINUX_MAX_UTSNAME 65
+
+#define LINUX_CTL_MAXNAME 10
+
+struct l___sysctl_args
+{
+ l_uintptr_t name;
+ l_int nlen;
+ l_uintptr_t oldval;
+ l_uintptr_t oldlenp;
+ l_uintptr_t newval;
+ l_size_t newlen;
+ l_ulong __spare[4];
+} __packed;
+
+/* Scheduling policies */
+#define LINUX_SCHED_OTHER 0
+#define LINUX_SCHED_FIFO 1
+#define LINUX_SCHED_RR 2
+
+/* Resource limits */
+#define LINUX_RLIMIT_CPU 0
+#define LINUX_RLIMIT_FSIZE 1
+#define LINUX_RLIMIT_DATA 2
+#define LINUX_RLIMIT_STACK 3
+#define LINUX_RLIMIT_CORE 4
+#define LINUX_RLIMIT_RSS 5
+#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_RLIM_NLIMITS 10
+
+struct l_rlimit {
+ l_ulong rlim_cur;
+ l_ulong rlim_max;
+} __packed;
+
+struct l_rusage {
+ l_timeval ru_utime;
+ l_timeval ru_stime;
+ l_long ru_maxrss;
+ l_long ru_ixrss;
+ l_long ru_idrss;
+ l_long ru_isrss;
+ l_long ru_minflt;
+ l_long ru_majflt;
+ l_long ru_nswap;
+ l_long ru_inblock;
+ l_long ru_oublock;
+ l_long ru_msgsnd;
+ l_long ru_msgrcv;
+ l_long ru_nsignals;
+ l_long ru_nvcsw;
+ l_long ru_nivcsw;
+} __packed;
+
+/* mmap options */
+#define LINUX_MAP_SHARED 0x0001
+#define LINUX_MAP_PRIVATE 0x0002
+#define LINUX_MAP_FIXED 0x0010
+#define LINUX_MAP_ANON 0x0020
+#define LINUX_MAP_GROWSDOWN 0x0100
+
+/*
+ * stat family of syscalls
+ */
+struct l_timespec {
+ l_ulong tv_sec;
+ l_ulong tv_nsec;
+} __packed;
+
+struct l_newstat {
+ l_ushort st_dev;
+ l_ushort __pad1;
+ 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_ushort __pad2;
+ l_ulong st_size;
+ l_ulong st_blksize;
+ l_ulong st_blocks;
+ struct l_timespec st_atimespec;
+ struct l_timespec st_mtimespec;
+ struct l_timespec st_ctimespec;
+ l_ulong __unused4;
+ l_ulong __unused5;
+} __packed;
+
+struct l_stat64 {
+ l_ushort st_dev;
+ u_char __pad0[10];
+ l_ulong __st_ino;
+ l_uint st_mode;
+ l_uint st_nlink;
+ l_ulong st_uid;
+ l_ulong st_gid;
+ l_ushort st_rdev;
+ u_char __pad3[10];
+ l_longlong st_size;
+ l_ulong st_blksize;
+ l_ulong st_blocks;
+ l_ulong __pad4;
+ struct l_timespec st_atimespec;
+ struct l_timespec st_mtimespec;
+ struct l_timespec st_ctimespec;
+ l_ulonglong st_ino;
+} __packed;
+
+struct l_new_utsname {
+ char sysname[LINUX_MAX_UTSNAME];
+ char nodename[LINUX_MAX_UTSNAME];
+ char release[LINUX_MAX_UTSNAME];
+ char version[LINUX_MAX_UTSNAME];
+ char machine[LINUX_MAX_UTSNAME];
+ char domainname[LINUX_MAX_UTSNAME];
+} __packed;
+
+/*
+ * Signalling
+ */
+#define LINUX_SIGHUP 1
+#define LINUX_SIGINT 2
+#define LINUX_SIGQUIT 3
+#define LINUX_SIGILL 4
+#define LINUX_SIGTRAP 5
+#define LINUX_SIGABRT 6
+#define LINUX_SIGIOT LINUX_SIGABRT
+#define LINUX_SIGBUS 7
+#define LINUX_SIGFPE 8
+#define LINUX_SIGKILL 9
+#define LINUX_SIGUSR1 10
+#define LINUX_SIGSEGV 11
+#define LINUX_SIGUSR2 12
+#define LINUX_SIGPIPE 13
+#define LINUX_SIGALRM 14
+#define LINUX_SIGTERM 15
+#define LINUX_SIGSTKFLT 16
+#define LINUX_SIGCHLD 17
+#define LINUX_SIGCONT 18
+#define LINUX_SIGSTOP 19
+#define LINUX_SIGTSTP 20
+#define LINUX_SIGTTIN 21
+#define LINUX_SIGTTOU 22
+#define LINUX_SIGURG 23
+#define LINUX_SIGXCPU 24
+#define LINUX_SIGXFSZ 25
+#define LINUX_SIGVTALRM 26
+#define LINUX_SIGPROF 27
+#define LINUX_SIGWINCH 28
+#define LINUX_SIGIO 29
+#define LINUX_SIGPOLL LINUX_SIGIO
+#define LINUX_SIGPWR 30
+#define LINUX_SIGSYS 31
+
+#define LINUX_SIGTBLSZ 31
+#define LINUX_NSIG_WORDS 2
+#define LINUX_NBPW 32
+#define LINUX_NSIG (LINUX_NBPW * LINUX_NSIG_WORDS)
+
+/* sigaction flags */
+#define LINUX_SA_NOCLDSTOP 0x00000001
+#define LINUX_SA_NOCLDWAIT 0x00000002
+#define LINUX_SA_SIGINFO 0x00000004
+#define LINUX_SA_RESTORER 0x04000000
+#define LINUX_SA_ONSTACK 0x08000000
+#define LINUX_SA_RESTART 0x10000000
+#define LINUX_SA_INTERRUPT 0x20000000
+#define LINUX_SA_NOMASK 0x40000000
+#define LINUX_SA_ONESHOT 0x80000000
+
+/* sigprocmask actions */
+#define LINUX_SIG_BLOCK 0
+#define LINUX_SIG_UNBLOCK 1
+#define LINUX_SIG_SETMASK 2
+
+/* sigset_t macros */
+#define LINUX_SIGEMPTYSET(set) (set).__bits[0] = (set).__bits[1] = 0
+#define LINUX_SIGISMEMBER(set, sig) SIGISMEMBER(set, sig)
+#define LINUX_SIGADDSET(set, sig) SIGADDSET(set, sig)
+
+/* sigaltstack */
+#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);
+
+typedef l_uintptr_t l_handler_t;
+typedef l_ulong l_osigset_t;
+
+typedef struct {
+ l_uint __bits[LINUX_NSIG_WORDS];
+} __packed l_sigset_t;
+
+typedef struct {
+ l_handler_t lsa_handler;
+ l_osigset_t lsa_mask;
+ l_ulong lsa_flags;
+ l_uintptr_t lsa_restorer;
+} __packed l_osigaction_t;
+
+typedef struct {
+ l_handler_t lsa_handler;
+ l_ulong lsa_flags;
+ l_uintptr_t lsa_restorer;
+ l_sigset_t lsa_mask;
+} __packed l_sigaction_t;
+
+typedef struct {
+ l_uintptr_t ss_sp;
+ l_int ss_flags;
+ l_size_t ss_size;
+} __packed l_stack_t;
+
+/* The Linux sigcontext, pretty much a standard 386 trapframe. */
+struct l_sigcontext {
+ l_int sc_gs;
+ l_int sc_fs;
+ l_int sc_es;
+ l_int sc_ds;
+ l_int sc_edi;
+ l_int sc_esi;
+ l_int sc_ebp;
+ l_int sc_esp;
+ l_int sc_ebx;
+ l_int sc_edx;
+ l_int sc_ecx;
+ l_int sc_eax;
+ l_int sc_trapno;
+ l_int sc_err;
+ l_int sc_eip;
+ l_int sc_cs;
+ l_int sc_eflags;
+ l_int sc_esp_at_signal;
+ l_int sc_ss;
+ l_int sc_387;
+ l_int sc_mask;
+ l_int sc_cr2;
+} __packed;
+
+struct l_ucontext {
+ l_ulong uc_flags;
+ l_uintptr_t uc_link;
+ l_stack_t uc_stack;
+ struct l_sigcontext uc_mcontext;
+ 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)
+
+typedef struct l_siginfo {
+ l_int lsi_signo;
+ l_int lsi_errno;
+ l_int lsi_code;
+ union {
+ l_int _pad[LINUX_SI_PAD_SIZE];
+
+ struct {
+ l_pid_t _pid;
+ l_uid16_t _uid;
+ } __packed _kill;
+
+ struct {
+ l_uint _timer1;
+ l_uint _timer2;
+ } __packed _timer;
+
+ struct {
+ l_pid_t _pid; /* sender's pid */
+ l_uid16_t _uid; /* sender's uid */
+ union sigval _sigval;
+ } __packed _rt;
+
+ struct {
+ l_pid_t _pid; /* which child */
+ l_uid16_t _uid; /* sender's uid */
+ l_int _status; /* exit code */
+ l_clock_t _utime;
+ l_clock_t _stime;
+ } __packed _sigchld;
+
+ struct {
+ l_uintptr_t _addr; /* faulting insn/memory ref. */
+ } __packed _sigfault;
+
+ struct {
+ 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
+
+struct l_fpreg {
+ 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];
+} __packed;
+
+struct l_xmmreg {
+ u_int32_t element[4];
+} __packed;
+
+struct l_fpstate {
+ /* Regular FPU environment */
+ u_int32_t cw;
+ u_int32_t sw;
+ u_int32_t tag;
+ u_int32_t ipoff;
+ u_int32_t cssel;
+ u_int32_t dataoff;
+ u_int32_t datasel;
+ struct l_fpreg _st[8];
+ u_int16_t status;
+ u_int16_t magic; /* 0xffff = regular FPU data */
+
+ /* FXSR FPU environment */
+ 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_xmmreg _xmm[8];
+ u_int32_t padding[56];
+} __packed;
+
+/*
+ * We make the stack look like Linux expects it when calling a signal
+ * handler, but use the BSD way of calling the handler and sigreturn().
+ * This means that we need to pass the pointer to the handler too.
+ * It is appended to the frame to not interfere with the rest of it.
+ */
+struct l_sigframe {
+ l_int sf_sig;
+ struct l_sigcontext sf_sc;
+ struct l_fpstate sf_fpstate;
+ l_uint sf_extramask[LINUX_NSIG_WORDS-1];
+ l_handler_t sf_handler;
+} __packed;
+
+struct l_rt_sigframe {
+ l_int sf_sig;
+ l_uintptr_t sf_siginfo;
+ l_uintptr_t sf_ucontext;
+ l_siginfo_t sf_si;
+ struct l_ucontext sf_sc;
+ l_handler_t sf_handler;
+} __packed;
+
+extern int bsd_to_linux_signal[];
+extern int linux_to_bsd_signal[];
+
+/*
+ * Pluggable ioctl handlers
+ */
+struct linux_ioctl_args;
+struct thread;
+
+typedef int linux_ioctl_function_t(struct thread *, struct linux_ioctl_args *);
+
+struct linux_ioctl_handler {
+ linux_ioctl_function_t *func;
+ int low, high;
+};
+
+int linux_ioctl_register_handler(struct linux_ioctl_handler *h);
+int linux_ioctl_unregister_handler(struct linux_ioctl_handler *h);
+
+/*
+ * 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_NDELAY LINUX_O_NONBLOCK
+#define LINUX_O_SYNC 010000
+#define LINUX_FASYNC 020000
+
+#define LINUX_F_DUPFD 0
+#define LINUX_F_GETFD 1
+#define LINUX_F_SETFD 2
+#define LINUX_F_GETFL 3
+#define LINUX_F_SETFL 4
+#define LINUX_F_GETLK 5
+#define LINUX_F_SETLK 6
+#define LINUX_F_SETLKW 7
+#define LINUX_F_SETOWN 8
+#define LINUX_F_GETOWN 9
+
+#define LINUX_F_GETLK64 12
+#define LINUX_F_SETLK64 13
+#define LINUX_F_SETLKW64 14
+
+#define LINUX_F_RDLCK 0
+#define LINUX_F_WRLCK 1
+#define LINUX_F_UNLCK 2
+
+/*
+ * 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
+
+/*
+ * SystemV IPC defines
+ */
+#define LINUX_SEMOP 1
+#define LINUX_SEMGET 2
+#define LINUX_SEMCTL 3
+#define LINUX_MSGSND 11
+#define LINUX_MSGRCV 12
+#define LINUX_MSGGET 13
+#define LINUX_MSGCTL 14
+#define LINUX_SHMAT 21
+#define LINUX_SHMDT 22
+#define LINUX_SHMGET 23
+#define LINUX_SHMCTL 24
+
+#define LINUX_IPC_RMID 0
+#define LINUX_IPC_SET 1
+#define LINUX_IPC_STAT 2
+#define LINUX_IPC_INFO 3
+
+#define LINUX_SHM_LOCK 11
+#define LINUX_SHM_UNLOCK 12
+#define LINUX_SHM_STAT 13
+#define LINUX_SHM_INFO 14
+
+#define LINUX_SHM_RDONLY 0x1000
+#define LINUX_SHM_RND 0x2000
+#define LINUX_SHM_REMAP 0x4000
+
+/* semctl commands */
+#define LINUX_GETPID 11
+#define LINUX_GETVAL 12
+#define LINUX_GETALL 13
+#define LINUX_GETNCNT 14
+#define LINUX_GETZCNT 15
+#define LINUX_SETVAL 16
+#define LINUX_SETALL 17
+#define LINUX_SEM_STAT 18
+#define LINUX_SEM_INFO 19
+
+union l_semun {
+ l_int val;
+ l_uintptr_t buf;
+ l_uintptr_t array;
+ l_uintptr_t __buf;
+ l_uintptr_t __pad;
+} __packed;
+
+/*
+ * Socket defines
+ */
+#define LINUX_SOCKET 1
+#define LINUX_BIND 2
+#define LINUX_CONNECT 3
+#define LINUX_LISTEN 4
+#define LINUX_ACCEPT 5
+#define LINUX_GETSOCKNAME 6
+#define LINUX_GETPEERNAME 7
+#define LINUX_SOCKETPAIR 8
+#define LINUX_SEND 9
+#define LINUX_RECV 10
+#define LINUX_SENDTO 11
+#define LINUX_RECVFROM 12
+#define LINUX_SHUTDOWN 13
+#define LINUX_SETSOCKOPT 14
+#define LINUX_GETSOCKOPT 15
+#define LINUX_SENDMSG 16
+#define LINUX_RECVMSG 17
+
+#define LINUX_AF_UNSPEC 0
+#define LINUX_AF_UNIX 1
+#define LINUX_AF_INET 2
+#define LINUX_AF_AX25 3
+#define LINUX_AF_IPX 4
+#define LINUX_AF_APPLETALK 5
+#define LINUX_AF_INET6 10
+
+#define LINUX_SOL_SOCKET 1
+#define LINUX_SOL_IP 0
+#define LINUX_SOL_IPX 256
+#define LINUX_SOL_AX25 257
+#define LINUX_SOL_TCP 6
+#define LINUX_SOL_UDP 17
+
+#define LINUX_SO_DEBUG 1
+#define LINUX_SO_REUSEADDR 2
+#define LINUX_SO_TYPE 3
+#define LINUX_SO_ERROR 4
+#define LINUX_SO_DONTROUTE 5
+#define LINUX_SO_BROADCAST 6
+#define LINUX_SO_SNDBUF 7
+#define LINUX_SO_RCVBUF 8
+#define LINUX_SO_KEEPALIVE 9
+#define LINUX_SO_OOBINLINE 10
+#define LINUX_SO_NO_CHECK 11
+#define LINUX_SO_PRIORITY 12
+#define LINUX_SO_LINGER 13
+
+#define LINUX_IP_TOS 1
+#define LINUX_IP_TTL 2
+#define LINUX_IP_HDRINCL 3
+#define LINUX_IP_OPTIONS 4
+
+#define LINUX_IP_MULTICAST_IF 32
+#define LINUX_IP_MULTICAST_TTL 33
+#define LINUX_IP_MULTICAST_LOOP 34
+#define LINUX_IP_ADD_MEMBERSHIP 35
+#define LINUX_IP_DROP_MEMBERSHIP 36
+
+struct l_sockaddr {
+ l_ushort sa_family;
+ char sa_data[14];
+} __packed;
+
+struct l_ifmap {
+ l_ulong mem_start;
+ l_ulong mem_end;
+ l_ushort base_addr;
+ u_char irq;
+ u_char dma;
+ u_char port;
+} __packed;
+
+#define LINUX_IFHWADDRLEN 6
+#define LINUX_IFNAMSIZ 16
+
+struct l_ifreq {
+ union {
+ char ifrn_name[LINUX_IFNAMSIZ];
+ } ifr_ifrn;
+
+ union {
+ struct l_sockaddr ifru_addr;
+ struct l_sockaddr ifru_dstaddr;
+ struct l_sockaddr ifru_broadaddr;
+ struct l_sockaddr ifru_netmask;
+ struct l_sockaddr ifru_hwaddr;
+ l_short ifru_flags[1];
+ l_int ifru_metric;
+ l_int ifru_mtu;
+ struct l_ifmap ifru_map;
+ char ifru_slave[LINUX_IFNAMSIZ];
+ l_uintptr_t ifru_data;
+ } ifr_ifru;
+} __packed;
+
+#define ifr_name ifr_ifrn.ifrn_name /* interface name */
+#define ifr_hwaddr ifr_ifru.ifru_hwaddr /* MAC address */
+
+struct l_ifconf {
+ int ifc_len;
+ union {
+ l_uintptr_t ifcu_buf;
+ l_uintptr_t ifcu_req;
+ } ifc_ifcu;
+} __packed;
+
+#define ifc_buf ifc_ifcu.ifcu_buf
+#define ifc_req ifc_ifcu.ifcu_req
+
+/*
+ * poll()
+ */
+#define LINUX_POLLIN 0x0001
+#define LINUX_POLLPRI 0x0002
+#define LINUX_POLLOUT 0x0004
+#define LINUX_POLLERR 0x0008
+#define LINUX_POLLHUP 0x0010
+#define LINUX_POLLNVAL 0x0020
+#define LINUX_POLLRDNORM 0x0040
+#define LINUX_POLLRDBAND 0x0080
+#define LINUX_POLLWRNORM 0x0100
+#define LINUX_POLLWRBAND 0x0200
+#define LINUX_POLLMSG 0x0400
+
+struct l_pollfd {
+ l_int fd;
+ l_short events;
+ l_short revents;
+} __packed;
+
+#endif /* !_AMD64_LINUX_LINUX_H_ */
diff --git a/sys/amd64/linux32/linux32_dummy.c b/sys/amd64/linux32/linux32_dummy.c
new file mode 100644
index 000000000000..5322c8e9bee5
--- /dev/null
+++ b/sys/amd64/linux32/linux32_dummy.c
@@ -0,0 +1,91 @@
+/*-
+ * Copyright (c) 1994-1995 Søren Schmidt
+ * All rights reserved.
+ *
+ * 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
+ * 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
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/proc.h>
+
+#include <amd64/linux32/linux.h>
+#include <amd64/linux32/linux32_proto.h>
+#include <compat/linux/linux_util.h>
+
+DUMMY(stime);
+DUMMY(olduname);
+DUMMY(syslog);
+DUMMY(uname);
+DUMMY(vhangup);
+DUMMY(swapoff);
+DUMMY(adjtimex);
+DUMMY(create_module);
+DUMMY(init_module);
+DUMMY(delete_module);
+DUMMY(get_kernel_syms);
+DUMMY(quotactl);
+DUMMY(bdflush);
+DUMMY(sysfs);
+DUMMY(query_module);
+DUMMY(nfsservctl);
+DUMMY(prctl);
+DUMMY(rt_sigpending);
+DUMMY(rt_sigtimedwait);
+DUMMY(rt_sigqueueinfo);
+DUMMY(capget);
+DUMMY(capset);
+DUMMY(sendfile);
+DUMMY(truncate64);
+DUMMY(setfsuid);
+DUMMY(setfsgid);
+DUMMY(pivot_root);
+DUMMY(mincore);
+DUMMY(fadvise64);
+DUMMY(ptrace);
+DUMMY(settimeofday);
+
+#define DUMMY_XATTR(s) \
+int \
+linux_ ## s ## xattr( \
+ struct thread *td, struct linux_ ## s ## xattr_args *arg) \
+{ \
+ \
+ return (ENOATTR); \
+}
+DUMMY_XATTR(set);
+DUMMY_XATTR(lset);
+DUMMY_XATTR(fset);
+DUMMY_XATTR(get);
+DUMMY_XATTR(lget);
+DUMMY_XATTR(fget);
+DUMMY_XATTR(list);
+DUMMY_XATTR(llist);
+DUMMY_XATTR(flist);
+DUMMY_XATTR(remove);
+DUMMY_XATTR(lremove);
+DUMMY_XATTR(fremove);
diff --git a/sys/amd64/linux32/linux32_genassym.c b/sys/amd64/linux32/linux32_genassym.c
new file mode 100644
index 000000000000..de7726d19c88
--- /dev/null
+++ b/sys/amd64/linux32/linux32_genassym.c
@@ -0,0 +1,17 @@
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/assym.h>
+#include <sys/systm.h>
+
+#include <amd64/linux32/linux.h>
+
+ASSYM(LINUX_SIGF_HANDLER, offsetof(struct l_sigframe, sf_handler));
+ASSYM(LINUX_SIGF_SC, offsetof(struct l_sigframe, sf_sc));
+ASSYM(LINUX_SC_GS, offsetof(struct l_sigcontext, sc_gs));
+ASSYM(LINUX_SC_FS, offsetof(struct l_sigcontext, sc_fs));
+ASSYM(LINUX_SC_ES, offsetof(struct l_sigcontext, sc_es));
+ASSYM(LINUX_SC_DS, offsetof(struct l_sigcontext, sc_ds));
+ASSYM(LINUX_RT_SIGF_HANDLER, offsetof(struct l_rt_sigframe, sf_handler));
+ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_sc));
diff --git a/sys/amd64/linux32/linux32_ipc64.h b/sys/amd64/linux32/linux32_ipc64.h
new file mode 100644
index 000000000000..f8c92c4803ec
--- /dev/null
+++ b/sys/amd64/linux32/linux32_ipc64.h
@@ -0,0 +1,145 @@
+/*-
+ * Copyright (c) 2002 Maxim Sobolev <sobomax@FreeBSD.org>
+ * All rights reserved.
+ *
+ * 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
+ * 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
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _AMD64_LINUX_LINUX_IPC64_H_
+#define _AMD64_LINUX_LINUX_IPC64_H_
+
+/*
+ * The ipc64_perm structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 32-bit mode_t and seq
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct l_ipc64_perm
+{
+ l_key_t key;
+ l_uid_t uid;
+ l_gid_t gid;
+ l_uid_t cuid;
+ l_gid_t cgid;
+ l_mode_t mode;
+ l_ushort __pad1;
+ l_ushort seq;
+ l_ushort __pad2;
+ l_ulong __unused1;
+ l_ulong __unused2;
+} __packed;
+
+/*
+ * The msqid64_ds structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct l_msqid64_ds {
+ struct l_ipc64_perm msg_perm;
+ l_time_t msg_stime; /* last msgsnd time */
+ l_ulong __unused1;
+ l_time_t msg_rtime; /* last msgrcv time */
+ l_ulong __unused2;
+ l_time_t msg_ctime; /* last change time */
+ l_ulong __unused3;
+ l_ulong msg_cbytes; /* current number of bytes on queue */
+ l_ulong msg_qnum; /* number of messages in queue */
+ l_ulong msg_qbytes; /* max number of bytes on queue */
+ l_pid_t msg_lspid; /* pid of last msgsnd */
+ l_pid_t msg_lrpid; /* last receive pid */
+ l_ulong __unused4;
+ l_ulong __unused5;
+} __packed;
+
+/*
+ * The semid64_ds structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct l_semid64_ds {
+ struct l_ipc64_perm sem_perm; /* permissions */
+ l_time_t sem_otime; /* last semop time */
+ l_ulong __unused1;
+ l_time_t sem_ctime; /* last change time */
+ l_ulong __unused2;
+ l_ulong sem_nsems; /* no. of semaphores in array */
+ l_ulong __unused3;
+ l_ulong __unused4;
+} __packed;
+
+/*
+ * The shmid64_ds structure for i386 architecture.
+ * Note extra padding because this structure is passed back and forth
+ * between kernel and user space.
+ *
+ * Pad space is left for:
+ * - 64-bit time_t to solve y2038 problem
+ * - 2 miscellaneous 32-bit values
+ */
+
+struct l_shmid64_ds {
+ struct l_ipc64_perm shm_perm; /* operation perms */
+ l_size_t shm_segsz; /* size of segment (bytes) */
+ l_time_t shm_atime; /* last attach time */
+ l_ulong __unused1;
+ l_time_t shm_dtime; /* last detach time */
+ l_ulong __unused2;
+ l_time_t shm_ctime; /* last change time */
+ l_ulong __unused3;
+ l_pid_t shm_cpid; /* pid of creator */
+ l_pid_t shm_lpid; /* pid of last operator */
+ l_ulong shm_nattch; /* no. of current attaches */
+ l_ulong __unused4;
+ l_ulong __unused5;
+} __packed;
+
+struct l_shminfo64 {
+ l_ulong shmmax;
+ l_ulong shmmin;
+ l_ulong shmmni;
+ l_ulong shmseg;
+ l_ulong shmall;
+ l_ulong __unused1;
+ l_ulong __unused2;
+ l_ulong __unused3;
+ l_ulong __unused4;
+} __packed;
+
+#endif /* !_AMD64_LINUX_LINUX_IPC64_H_ */
diff --git a/sys/amd64/linux32/linux32_locore.s b/sys/amd64/linux32/linux32_locore.s
new file mode 100644
index 000000000000..6c3d2082e87a
--- /dev/null
+++ b/sys/amd64/linux32/linux32_locore.s
@@ -0,0 +1,45 @@
+/* $FreeBSD$ */
+
+#include "linux32_assym.h" /* system definitions */
+#include <machine/asmacros.h> /* miscellaneous asm macros */
+
+#include <amd64/linux32/linux32_syscall.h> /* system call numbers */
+
+.text
+.code32
+
+NON_GPROF_ENTRY(linux_sigcode)
+ call *LINUX_SIGF_HANDLER(%esp)
+ leal LINUX_SIGF_SC(%esp),%ebx /* linux scp */
+ movl LINUX_SC_GS(%ebx),%gs
+ movl LINUX_SC_FS(%ebx),%fs
+ movl LINUX_SC_ES(%ebx),%es
+ movl LINUX_SC_DS(%ebx),%ds
+ movl %esp, %ebx /* pass sigframe */
+ push %eax /* fake ret addr */
+ movl $LINUX_SYS_linux_sigreturn,%eax /* linux_sigreturn() */
+ int $0x80 /* enter kernel with args */
+0: jmp 0b
+ ALIGN_TEXT
+/* XXXXX */
+linux_rt_sigcode:
+ call *LINUX_RT_SIGF_HANDLER(%esp)
+ leal LINUX_RT_SIGF_UC(%esp),%ebx /* linux ucp */
+ movl LINUX_SC_GS(%ebx),%gs
+ movl LINUX_SC_FS(%ebx),%fs
+ movl LINUX_SC_ES(%ebx),%es
+ movl LINUX_SC_DS(%ebx),%ds
+ push %eax /* fake ret addr */
+ movl $LINUX_SYS_linux_rt_sigreturn,%eax /* linux_rt_sigreturn() */
+ int $0x80 /* enter kernel with args */
+0: jmp 0b
+ ALIGN_TEXT
+/* XXXXX */
+linux_esigcode:
+
+ .data
+ .globl linux_szsigcode, linux_sznonrtsigcode
+linux_szsigcode:
+ .long linux_esigcode-linux_sigcode
+linux_sznonrtsigcode:
+ .long linux_rt_sigcode-linux_sigcode
diff --git a/sys/amd64/linux32/linux32_machdep.c b/sys/amd64/linux32/linux32_machdep.c
new file mode 100644
index 000000000000..3aa66bc933ba
--- /dev/null
+++ b/sys/amd64/linux32/linux32_machdep.c
@@ -0,0 +1,1019 @@
+/*-
+ * Copyright (c) 2004 Tim J. Robbins
+ * Copyright (c) 2002 Doug Rabson
+ * Copyright (c) 2000 Marcel Moolenaar
+ * All rights reserved.
+ *
+ * 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
+ * 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
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/systm.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/mman.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/resource.h>
+#include <sys/resourcevar.h>
+#include <sys/syscallsubr.h>
+#include <sys/sysproto.h>
+#include <sys/unistd.h>
+
+#include <machine/frame.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_map.h>
+
+#include <amd64/linux32/linux.h>
+#include <amd64/linux32/linux32_proto.h>
+#include <compat/linux/linux_ipc.h>
+#include <compat/linux/linux_signal.h>
+#include <compat/linux/linux_util.h>
+
+struct l_old_select_argv {
+ l_int nfds;
+ l_uintptr_t readfds;
+ l_uintptr_t writefds;
+ l_uintptr_t exceptfds;
+ l_uintptr_t timeout;
+} __packed;
+
+int
+linux_to_bsd_sigaltstack(int lsa)
+{
+ int bsa = 0;
+
+ if (lsa & LINUX_SS_DISABLE)
+ bsa |= SS_DISABLE;
+ if (lsa & LINUX_SS_ONSTACK)
+ bsa |= SS_ONSTACK;
+ return (bsa);
+}
+
+int
+bsd_to_linux_sigaltstack(int bsa)
+{
+ int lsa = 0;
+
+ if (bsa & SS_DISABLE)
+ lsa |= LINUX_SS_DISABLE;
+ if (bsa & SS_ONSTACK)
+ lsa |= LINUX_SS_ONSTACK;
+ return (lsa);
+}
+
+int
+linux_execve(struct thread *td, struct linux_execve_args *args)
+{
+ struct execve_args ap;
+ caddr_t sg;
+ int error;
+ u_int32_t *p32, arg;
+ char **p, *p64;
+ int count;
+
+ sg = stackgap_init();
+ CHECKALTEXIST(td, &sg, args->path);
+
+#ifdef DEBUG
+ if (ldebug(execve))
+ printf(ARGS(execve, "%s"), args->path);
+#endif
+
+ ap.fname = args->path;
+
+ if (args->argp != NULL) {
+ count = 0;
+ p32 = (u_int32_t *)args->argp;
+ do {
+ error = copyin(p32++, &arg, sizeof(arg));
+ if (error)
+ return error;
+ count++;
+ } while (arg != 0);
+ p = stackgap_alloc(&sg, count * sizeof(char *));
+ ap.argv = p;
+ p32 = (u_int32_t *)args->argp;
+ do {
+ error = copyin(p32++, &arg, sizeof(arg));
+ if (error)
+ return error;
+ p64 = PTRIN(arg);
+ error = copyout(&p64, p++, sizeof(p64));
+ if (error)
+ return error;
+ } while (arg != 0);
+ }
+ if (args->envp != NULL) {
+ count = 0;
+ p32 = (u_int32_t *)args->envp;
+ do {
+ error = copyin(p32++, &arg, sizeof(arg));
+ if (error)
+ return error;
+ count++;
+ } while (arg != 0);
+ p = stackgap_alloc(&sg, count * sizeof(char *));
+ ap.envv = p;
+ p32 = (u_int32_t *)args->envp;
+ do {
+ error = copyin(p32++, &arg, sizeof(arg));
+ if (error)
+ return error;
+ p64 = PTRIN(arg);
+ error = copyout(&p64, p++, sizeof(p64));
+ if (error)
+ return error;
+ } while (arg != 0);
+ }
+
+ return (execve(td, &ap));
+}
+
+struct iovec32 {
+ u_int32_t iov_base;
+ int iov_len;
+};
+#define STACKGAPLEN 400
+
+CTASSERT(sizeof(struct iovec32) == 8);
+
+int
+linux_readv(struct thread *td, struct linux_readv_args *uap)
+{
+ int error, osize, nsize, i;
+ caddr_t sg;
+ struct readv_args /* {
+ syscallarg(int) fd;
+ syscallarg(struct iovec *) iovp;
+ syscallarg(u_int) iovcnt;
+ } */ a;
+ struct iovec32 *oio;
+ struct iovec *nio;
+
+ sg = stackgap_init();
+
+ if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec)))
+ return (EINVAL);
+
+ osize = uap->iovcnt * sizeof (struct iovec32);
+ nsize = uap->iovcnt * sizeof (struct iovec);
+
+ oio = malloc(osize, M_TEMP, M_WAITOK);
+ nio = malloc(nsize, M_TEMP, M_WAITOK);
+
+ error = 0;
+ if ((error = copyin(uap->iovp, oio, osize)))
+ goto punt;
+ for (i = 0; i < uap->iovcnt; i++) {
+ nio[i].iov_base = PTRIN(oio[i].iov_base);
+ nio[i].iov_len = oio[i].iov_len;
+ }
+
+ a.fd = uap->fd;
+ a.iovp = stackgap_alloc(&sg, nsize);
+ a.iovcnt = uap->iovcnt;
+
+ if ((error = copyout(nio, (caddr_t)a.iovp, nsize)))
+ goto punt;
+ error = readv(td, &a);
+
+punt:
+ free(oio, M_TEMP);
+ free(nio, M_TEMP);
+ return (error);
+}
+
+int
+linux_writev(struct thread *td, struct linux_writev_args *uap)
+{
+ int error, i, nsize, osize;
+ caddr_t sg;
+ struct writev_args /* {
+ syscallarg(int) fd;
+ syscallarg(struct iovec *) iovp;
+ syscallarg(u_int) iovcnt;
+ } */ a;
+ struct iovec32 *oio;
+ struct iovec *nio;
+
+ sg = stackgap_init();
+
+ if (uap->iovcnt > (STACKGAPLEN / sizeof (struct iovec)))
+ return (EINVAL);
+
+ osize = uap->iovcnt * sizeof (struct iovec32);
+ nsize = uap->iovcnt * sizeof (struct iovec);
+
+ oio = malloc(osize, M_TEMP, M_WAITOK);
+ nio = malloc(nsize, M_TEMP, M_WAITOK);
+
+ error = 0;
+ if ((error = copyin(uap->iovp, oio, osize)))
+ goto punt;
+ for (i = 0; i < uap->iovcnt; i++) {
+ nio[i].iov_base = PTRIN(oio[i].iov_base);
+ nio[i].iov_len = oio[i].iov_len;
+ }
+
+ a.fd = uap->fd;
+ a.iovp = stackgap_alloc(&sg, nsize);
+ a.iovcnt = uap->iovcnt;
+
+ if ((error = copyout(nio, (caddr_t)a.iovp, nsize)))
+ goto punt;
+ error = writev(td, &a);
+
+punt:
+ free(oio, M_TEMP);
+ free(nio, M_TEMP);
+ return (error);
+}
+
+struct l_ipc_kludge {
+ l_uintptr_t msgp;
+ l_long msgtyp;
+} __packed;
+
+int
+linux_ipc(struct thread *td, struct linux_ipc_args *args)
+{
+
+ switch (args->what & 0xFFFF) {
+ case LINUX_SEMOP: {
+ struct linux_semop_args a;
+
+ a.semid = args->arg1;
+ a.tsops = args->ptr;
+ a.nsops = args->arg2;
+ return (linux_semop(td, &a));
+ }
+ case LINUX_SEMGET: {
+ struct linux_semget_args a;
+
+ a.key = args->arg1;
+ a.nsems = args->arg2;
+ a.semflg = args->arg3;
+ return (linux_semget(td, &a));
+ }
+ case LINUX_SEMCTL: {
+ struct linux_semctl_args a;
+ int error;
+
+ a.semid = args->arg1;
+ a.semnum = args->arg2;
+ a.cmd = args->arg3;
+ error = copyin(args->ptr, &a.arg, sizeof(a.arg));
+ if (error)
+ return (error);
+ return (linux_semctl(td, &a));
+ }
+ case LINUX_MSGSND: {
+ struct linux_msgsnd_args a;
+
+ a.msqid = args->arg1;
+ a.msgp = args->ptr;
+ a.msgsz = args->arg2;
+ a.msgflg = args->arg3;
+ return (linux_msgsnd(td, &a));
+ }
+ case LINUX_MSGRCV: {
+ struct linux_msgrcv_args a;
+
+ a.msqid = args->arg1;
+ a.msgsz = args->arg2;
+ a.msgflg = args->arg3;
+ if ((args->what >> 16) == 0) {
+ struct l_ipc_kludge tmp;
+ int error;
+
+ if (args->ptr == 0)
+ return (EINVAL);
+ error = copyin(args->ptr, &tmp, sizeof(tmp));
+ if (error)
+ return (error);
+ a.msgp = PTRIN(tmp.msgp);
+ a.msgtyp = tmp.msgtyp;
+ } else {
+ a.msgp = args->ptr;
+ a.msgtyp = args->arg5;
+ }
+ return (linux_msgrcv(td, &a));
+ }
+ case LINUX_MSGGET: {
+ struct linux_msgget_args a;
+
+ a.key = args->arg1;
+ a.msgflg = args->arg2;
+ return (linux_msgget(td, &a));
+ }
+ case LINUX_MSGCTL: {
+ struct linux_msgctl_args a;
+
+ a.msqid = args->arg1;
+ a.cmd = args->arg2;
+ a.buf = args->ptr;
+ return (linux_msgctl(td, &a));
+ }
+ case LINUX_SHMAT: {
+ struct linux_shmat_args a;
+
+ a.shmid = args->arg1;
+ a.shmaddr = args->ptr;
+ a.shmflg = args->arg2;
+ a.raddr = PTRIN(args->arg3);
+ return (linux_shmat(td, &a));
+ }
+ case LINUX_SHMDT: {
+ struct linux_shmdt_args a;
+
+ a.shmaddr = args->ptr;
+ return (linux_shmdt(td, &a));
+ }
+ case LINUX_SHMGET: {
+ struct linux_shmget_args a;
+
+ a.key = args->arg1;
+ a.size = args->arg2;
+ a.shmflg = args->arg3;
+ return (linux_shmget(td, &a));
+ }
+ case LINUX_SHMCTL: {
+ struct linux_shmctl_args a;
+
+ a.shmid = args->arg1;
+ a.cmd = args->arg2;
+ a.buf = args->ptr;
+ return (linux_shmctl(td, &a));
+ }
+ default:
+ break;
+ }
+
+ return (EINVAL);
+}
+
+int
+linux_old_select(struct thread *td, struct linux_old_select_args *args)
+{
+ struct l_old_select_argv linux_args;
+ struct linux_select_args newsel;
+ int error;
+
+#ifdef DEBUG
+ if (ldebug(old_select))
+ printf(ARGS(old_select, "%p"), args->ptr);
+#endif
+
+ error = copyin(args->ptr, &linux_args, sizeof(linux_args));
+ if (error)
+ return (error);
+
+ newsel.nfds = linux_args.nfds;
+ newsel.readfds = PTRIN(linux_args.readfds);
+ newsel.writefds = PTRIN(linux_args.writefds);
+ newsel.exceptfds = PTRIN(linux_args.exceptfds);
+ newsel.timeout = PTRIN(linux_args.timeout);
+ return (linux_select(td, &newsel));
+}
+
+int
+linux_fork(struct thread *td, struct linux_fork_args *args)
+{
+ int error;
+
+#ifdef DEBUG
+ if (ldebug(fork))
+ printf(ARGS(fork, ""));
+#endif
+
+ if ((error = fork(td, (struct fork_args *)args)) != 0)
+ return (error);
+
+ if (td->td_retval[1] == 1)
+ td->td_retval[0] = 0;
+ return (0);
+}
+
+int
+linux_vfork(struct thread *td, struct linux_vfork_args *args)
+{
+ int error;
+
+#ifdef DEBUG
+ if (ldebug(vfork))
+ printf(ARGS(vfork, ""));
+#endif
+
+ if ((error = vfork(td, (struct vfork_args *)args)) != 0)
+ return (error);
+ /* Are we the child? */
+ if (td->td_retval[1] == 1)
+ td->td_retval[0] = 0;
+ return (0);
+}
+
+#define CLONE_VM 0x100
+#define CLONE_FS 0x200
+#define CLONE_FILES 0x400
+#define CLONE_SIGHAND 0x800
+#define CLONE_PID 0x1000
+
+int
+linux_clone(struct thread *td, struct linux_clone_args *args)
+{
+ int error, ff = RFPROC | RFSTOPPED;
+ struct proc *p2;
+ struct thread *td2;
+ int exit_signal;
+
+#ifdef DEBUG
+ if (ldebug(clone)) {
+ printf(ARGS(clone, "flags %x, stack %x"),
+ (unsigned int)args->flags, (unsigned int)args->stack);
+ if (args->flags & CLONE_PID)
+ printf(LMSG("CLONE_PID not yet supported"));
+ }
+#endif
+
+ if (!args->stack)
+ return (EINVAL);
+
+ exit_signal = args->flags & 0x000000ff;
+ if (exit_signal >= LINUX_NSIG)
+ return (EINVAL);
+
+ if (exit_signal <= LINUX_SIGTBLSZ)
+ exit_signal = linux_to_bsd_signal[_SIG_IDX(exit_signal)];
+
+ if (args->flags & CLONE_VM)
+ ff |= RFMEM;
+ if (args->flags & CLONE_SIGHAND)
+ ff |= RFSIGSHARE;
+ if (!(args->flags & CLONE_FILES))
+ ff |= RFFDG;
+
+ error = fork1(td, ff, 0, &p2);
+ if (error)
+ return (error);
+
+
+ PROC_LOCK(p2);
+ p2->p_sigparent = exit_signal;
+ PROC_UNLOCK(p2);
+ td2 = FIRST_THREAD_IN_PROC(p2);
+ td2->td_frame->tf_rsp = PTROUT(args->stack);
+
+#ifdef DEBUG
+ if (ldebug(clone))
+ printf(LMSG("clone: successful rfork to %ld, stack %p sig = %d"),
+ (long)p2->p_pid, args->stack, exit_signal);
+#endif
+
+ /*
+ * Make this runnable after we are finished with it.
+ */
+ mtx_lock_spin(&sched_lock);
+ TD_SET_CAN_RUN(td2);
+ setrunqueue(td2);
+ mtx_unlock_spin(&sched_lock);
+
+ td->td_retval[0] = p2->p_pid;
+ td->td_retval[1] = 0;
+ return (0);
+}
+
+/* XXX move */
+struct l_mmap_argv {
+ l_ulong 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)
+
+static int linux_mmap_common(struct thread *, struct l_mmap_argv *);
+
+int
+linux_mmap2(struct thread *td, struct linux_mmap2_args *args)
+{
+ struct l_mmap_argv linux_args;
+
+#ifdef DEBUG
+ if (ldebug(mmap2))
+ printf(ARGS(mmap2, "%p, %d, %d, 0x%08x, %d, %d"),
+ (void *)args->addr, args->len, args->prot,
+ args->flags, args->fd, args->pgoff);
+#endif
+
+ linux_args.addr = PTROUT(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;
+
+ return (linux_mmap_common(td, &linux_args));
+}
+
+int
+linux_mmap(struct thread *td, struct linux_mmap_args *args)
+{
+ int error;
+ struct l_mmap_argv linux_args;
+
+ error = copyin(args->ptr, &linux_args, sizeof(linux_args));
+ if (error)
+ return (error);
+
+#ifdef DEBUG
+ 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);
+#endif
+
+ return (linux_mmap_common(td, &linux_args));
+}
+
+static int
+linux_mmap_common(struct thread *td, struct l_mmap_argv *linux_args)
+{
+ struct proc *p = td->td_proc;
+ struct mmap_args /* {
+ caddr_t addr;
+ size_t len;
+ int prot;
+ int flags;
+ int fd;
+ long pad;
+ off_t pos;
+ } */ bsd_args;
+ int error;
+
+ error = 0;
+ bsd_args.flags = 0;
+ if (linux_args->flags & LINUX_MAP_SHARED)
+ bsd_args.flags |= MAP_SHARED;
+ if (linux_args->flags & LINUX_MAP_PRIVATE)
+ bsd_args.flags |= MAP_PRIVATE;
+ if (linux_args->flags & LINUX_MAP_FIXED)
+ bsd_args.flags |= MAP_FIXED;
+ if (linux_args->flags & LINUX_MAP_ANON)
+ bsd_args.flags |= MAP_ANON;
+ else
+ bsd_args.flags |= MAP_NOSYNC;
+ if (linux_args->flags & LINUX_MAP_GROWSDOWN) {
+ bsd_args.flags |= MAP_STACK;
+
+ /* 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 to stack size of STACK_SIZE. Its just not
+ * 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
+ * in addr.
+ *
+ * If we don't use the MAP_STACK option, the effect
+ * of this code is to allocate a stack region of a
+ * 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) >
+ 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()
+ * will confuse the thread stack with the
+ * process stack and deliver a SEGV if they
+ * attempt to grow the thread stack past their
+ * current stacksize rlimit. To avoid this,
+ * adjust vm_maxsaddr upwards to reflect
+ * the current stacksize rlimit rather
+ * than the maximum possible stacksize.
+ * It would be better to adjust the
+ * mmap'ed region, but some apps do not check
+ * mmap's return value.
+ */
+ PROC_LOCK(p);
+ p->p_vmspace->vm_maxsaddr =
+ (char *)LINUX32_USRSTACK -
+ lim_cur(p, RLIMIT_STACK);
+ PROC_UNLOCK(p);
+ }
+
+ /* This gives us our maximum stack size */
+ if (linux_args->len > STACK_SIZE - GUARD_SIZE)
+ bsd_args.len = linux_args->len;
+ else
+ bsd_args.len = STACK_SIZE - GUARD_SIZE;
+
+ /* 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;
+ } 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 = linux_args->pos;
+ bsd_args.pad = 0;
+
+#ifdef DEBUG
+ if (ldebug(mmap))
+ printf("-> %s(%p, %d, %d, 0x%08x, %d, 0x%x)\n",
+ __func__,
+ (void *)bsd_args.addr, bsd_args.len, bsd_args.prot,
+ bsd_args.flags, bsd_args.fd, (int)bsd_args.pos);
+#endif
+ error = mmap(td, &bsd_args);
+#ifdef DEBUG
+ if (ldebug(mmap))
+ printf("-> %s() return: 0x%x (0x%08x)\n",
+ __func__, error, (u_int)td->td_retval[0]);
+#endif
+ return (error);
+}
+
+int
+linux_pipe(struct thread *td, struct linux_pipe_args *args)
+{
+ int pip[2];
+ int error;
+ register_t reg_rdx;
+
+#ifdef DEBUG
+ if (ldebug(pipe))
+ printf(ARGS(pipe, "*"));
+#endif
+
+ reg_rdx = td->td_retval[1];
+ error = pipe(td, 0);
+ if (error) {
+ td->td_retval[1] = reg_rdx;
+ return (error);
+ }
+
+ pip[0] = td->td_retval[0];
+ pip[1] = td->td_retval[1];
+ error = copyout(pip, args->pipefds, 2 * sizeof(int));
+ if (error) {
+ td->td_retval[1] = reg_rdx;
+ return (error);
+ }
+
+ td->td_retval[1] = reg_rdx;
+ td->td_retval[0] = 0;
+ return (0);
+}
+
+int
+linux_sigaction(struct thread *td, struct linux_sigaction_args *args)
+{
+ l_osigaction_t osa;
+ l_sigaction_t act, oact;
+ int error;
+
+#ifdef DEBUG
+ if (ldebug(sigaction))
+ printf(ARGS(sigaction, "%d, %p, %p"),
+ args->sig, (void *)args->nsa, (void *)args->osa);
+#endif
+
+ if (args->nsa != NULL) {
+ error = copyin(args->nsa, &osa, sizeof(l_osigaction_t));
+ if (error)
+ return (error);
+ act.lsa_handler = osa.lsa_handler;
+ act.lsa_flags = osa.lsa_flags;
+ act.lsa_restorer = osa.lsa_restorer;
+ LINUX_SIGEMPTYSET(act.lsa_mask);
+ act.lsa_mask.__bits[0] = osa.lsa_mask;
+ }
+
+ error = linux_do_sigaction(td, args->sig, args->nsa ? &act : NULL,
+ args->osa ? &oact : NULL);
+
+ if (args->osa != NULL && !error) {
+ osa.lsa_handler = oact.lsa_handler;
+ osa.lsa_flags = oact.lsa_flags;
+ osa.lsa_restorer = oact.lsa_restorer;
+ osa.lsa_mask = oact.lsa_mask.__bits[0];
+ error = copyout(&osa, args->osa, sizeof(l_osigaction_t));
+ }
+
+ return (error);
+}
+
+/*
+ * Linux has two extra args, restart and oldmask. We dont use these,
+ * but it seems that "restart" is actually a context pointer that
+ * enables the signal to happen with a different register set.
+ */
+int
+linux_sigsuspend(struct thread *td, struct linux_sigsuspend_args *args)
+{
+ sigset_t sigmask;
+ l_sigset_t mask;
+
+#ifdef DEBUG
+ if (ldebug(sigsuspend))
+ printf(ARGS(sigsuspend, "%08lx"), (unsigned long)args->mask);
+#endif
+
+ LINUX_SIGEMPTYSET(mask);
+ mask.__bits[0] = args->mask;
+ linux_to_bsd_sigset(&mask, &sigmask);
+ return (kern_sigsuspend(td, sigmask));
+}
+
+int
+linux_rt_sigsuspend(struct thread *td, struct linux_rt_sigsuspend_args *uap)
+{
+ l_sigset_t lmask;
+ sigset_t sigmask;
+ int error;
+
+#ifdef DEBUG
+ if (ldebug(rt_sigsuspend))
+ printf(ARGS(rt_sigsuspend, "%p, %d"),
+ (void *)uap->newset, uap->sigsetsize);
+#endif
+
+ if (uap->sigsetsize != sizeof(l_sigset_t))
+ return (EINVAL);
+
+ error = copyin(uap->newset, &lmask, sizeof(l_sigset_t));
+ if (error)
+ return (error);
+
+ linux_to_bsd_sigset(&lmask, &sigmask);
+ return (kern_sigsuspend(td, sigmask));
+}
+
+int
+linux_pause(struct thread *td, struct linux_pause_args *args)
+{
+ struct proc *p = td->td_proc;
+ sigset_t sigmask;
+
+#ifdef DEBUG
+ if (ldebug(pause))
+ printf(ARGS(pause, ""));
+#endif
+
+ PROC_LOCK(p);
+ sigmask = td->td_sigmask;
+ PROC_UNLOCK(p);
+ return (kern_sigsuspend(td, sigmask));
+}
+
+int
+linux_sigaltstack(struct thread *td, struct linux_sigaltstack_args *uap)
+{
+ stack_t ss, oss;
+ l_stack_t lss;
+ int error;
+
+#ifdef DEBUG
+ if (ldebug(sigaltstack))
+ printf(ARGS(sigaltstack, "%p, %p"), uap->uss, uap->uoss);
+#endif
+
+ if (uap->uss != NULL) {
+ error = copyin(uap->uss, &lss, sizeof(l_stack_t));
+ if (error)
+ return (error);
+
+ ss.ss_sp = PTRIN(lss.ss_sp);
+ ss.ss_size = lss.ss_size;
+ ss.ss_flags = linux_to_bsd_sigaltstack(lss.ss_flags);
+ }
+ error = kern_sigaltstack(td, (uap->uoss != NULL) ? &oss : NULL,
+ (uap->uss != NULL) ? &ss : NULL);
+ if (!error && uap->uoss != NULL) {
+ lss.ss_sp = PTROUT(oss.ss_sp);
+ lss.ss_size = oss.ss_size;
+ lss.ss_flags = bsd_to_linux_sigaltstack(oss.ss_flags);
+ error = copyout(&lss, uap->uoss, sizeof(l_stack_t));
+ }
+
+ return (error);
+}
+
+int
+linux_ftruncate64(struct thread *td, struct linux_ftruncate64_args *args)
+{
+ struct ftruncate_args sa;
+
+#ifdef DEBUG
+ if (ldebug(ftruncate64))
+ printf(ARGS(ftruncate64, "%u, %jd"), args->fd,
+ (intmax_t)args->length);
+#endif
+
+ sa.fd = args->fd;
+ sa.pad = 0;
+ sa.length = args->length;
+ return ftruncate(td, &sa);
+}
+
+int
+linux_gettimeofday(struct thread *td, struct linux_gettimeofday_args *uap)
+{
+ struct timeval atv;
+ l_timeval atv32;
+ struct timezone rtz;
+ int error = 0;
+
+ if (uap->tp) {
+ microtime(&atv);
+ atv32.tv_sec = atv.tv_sec;
+ atv32.tv_usec = atv.tv_usec;
+ 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));
+ }
+ return (error);
+}
+
+int
+linux_nanosleep(struct thread *td, struct linux_nanosleep_args *uap)
+{
+ struct timespec ats;
+ struct l_timespec ats32;
+ struct nanosleep_args bsd_args;
+ int error;
+ caddr_t sg;
+ caddr_t sarqts, sarmts;
+
+ sg = stackgap_init();
+ error = copyin(uap->rqtp, &ats32, sizeof(ats32));
+ if (error != 0)
+ return (error);
+ ats.tv_sec = ats32.tv_sec;
+ ats.tv_nsec = ats32.tv_nsec;
+ sarqts = stackgap_alloc(&sg, sizeof(ats));
+ error = copyout(&ats, sarqts, sizeof(ats));
+ if (error != 0)
+ return (error);
+ sarmts = stackgap_alloc(&sg, sizeof(ats));
+ bsd_args.rqtp = (void *)sarqts;
+ bsd_args.rmtp = (void *)sarmts;
+ error = nanosleep(td, &bsd_args);
+ if (uap->rmtp != NULL) {
+ error = copyin(sarmts, &ats, sizeof(ats));
+ if (error != 0)
+ return (error);
+ ats32.tv_sec = ats.tv_sec;
+ ats32.tv_nsec = ats.tv_nsec;
+ error = copyout(&ats32, uap->rmtp, sizeof(ats32));
+ if (error != 0)
+ return (error);
+ }
+ return (error);
+}
+
+int
+linux_getrusage(struct thread *td, struct linux_getrusage_args *uap)
+{
+ int error;
+ caddr_t sg;
+ struct l_rusage *p32, s32;
+ struct rusage *p = NULL, s;
+
+ p32 = uap->rusage;
+ if (p32 != NULL) {
+ sg = stackgap_init();
+ p = stackgap_alloc(&sg, sizeof(struct rusage));
+ uap->rusage = (struct l_rusage *)p;
+ }
+ error = getrusage(td, (struct getrusage_args *) uap);
+ if (error != 0)
+ return (error);
+ if (p32 != NULL) {
+ error = copyin(p, &s, sizeof(s));
+ if (error != 0)
+ return (error);
+ s32.ru_utime.tv_sec = s.ru_utime.tv_sec;
+ s32.ru_utime.tv_usec = s.ru_utime.tv_usec;
+ s32.ru_stime.tv_sec = s.ru_stime.tv_sec;
+ s32.ru_stime.tv_usec = s.ru_stime.tv_usec;
+ s32.ru_maxrss = s.ru_maxrss;
+ s32.ru_ixrss = s.ru_ixrss;
+ s32.ru_idrss = s.ru_idrss;
+ s32.ru_isrss = s.ru_isrss;
+ s32.ru_minflt = s.ru_minflt;
+ s32.ru_majflt = s.ru_majflt;
+ s32.ru_nswap = s.ru_nswap;
+ s32.ru_inblock = s.ru_inblock;
+ s32.ru_oublock = s.ru_oublock;
+ s32.ru_msgsnd = s.ru_msgsnd;
+ s32.ru_msgrcv = s.ru_msgrcv;
+ s32.ru_nsignals = s.ru_nsignals;
+ s32.ru_nvcsw = s.ru_nvcsw;
+ s32.ru_nivcsw = s.ru_nivcsw;
+ error = copyout(&s32, p32, sizeof(s32));
+ }
+ return (error);
+}
+
+int
+linux_sched_rr_get_interval(struct thread *td,
+ struct linux_sched_rr_get_interval_args *uap)
+{
+ struct sched_rr_get_interval_args bsd_args;
+ caddr_t sg, psgts;
+ struct timespec ts;
+ struct l_timespec ts32;
+ int error;
+
+ sg = stackgap_init();
+ psgts = stackgap_alloc(&sg, sizeof(struct timespec));
+ bsd_args.pid = uap->pid;
+ bsd_args.interval = (void *)psgts;
+ error = sched_rr_get_interval(td, &bsd_args);
+ if (error != 0)
+ return (error);
+ error = copyin(psgts, &ts, sizeof(ts));
+ if (error != 0)
+ return (error);
+ ts32.tv_sec = ts.tv_sec;
+ ts32.tv_nsec = ts.tv_nsec;
+ 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));
+}
diff --git a/sys/amd64/linux32/linux32_proto.h b/sys/amd64/linux32/linux32_proto.h
new file mode 100644
index 000000000000..f50805aeafdd
--- /dev/null
+++ b/sys/amd64/linux32/linux32_proto.h
@@ -0,0 +1,869 @@
+/*
+ * System call prototypes.
+ *
+ * DO NOT EDIT-- this file is automatically generated.
+ * $FreeBSD$
+ * created from FreeBSD
+ */
+
+#ifndef _LINUX_SYSPROTO_H_
+#define _LINUX_SYSPROTO_H_
+
+#include <sys/signal.h>
+#include <sys/acl.h>
+#include <sys/thr.h>
+#include <sys/umtx.h>
+#include <posix4/_semaphore.h>
+
+#include <sys/ucontext.h>
+
+struct proc;
+
+struct thread;
+
+#define PAD_(t) (sizeof(register_t) <= sizeof(t) ? \
+ 0 : sizeof(register_t) - sizeof(t))
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define PADL_(t) 0
+#define PADR_(t) PAD_(t)
+#else
+#define PADL_(t) PAD_(t)
+#define PADR_(t) 0
+#endif
+
+struct linux_fork_args {
+ register_t dummy;
+};
+struct linux_open_args {
+ char path_l_[PADL_(char *)]; char * path; char path_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_waitpid_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char status_l_[PADL_(l_int *)]; l_int * status; char status_r_[PADR_(l_int *)];
+ char options_l_[PADL_(l_int)]; l_int options; char options_r_[PADR_(l_int)];
+};
+struct linux_creat_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+};
+struct linux_link_args {
+ 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_unlink_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+};
+struct linux_execve_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char argp_l_[PADL_(char **)]; char ** argp; char argp_r_[PADR_(char **)];
+ char envp_l_[PADL_(char **)]; char ** envp; char envp_r_[PADR_(char **)];
+};
+struct linux_chdir_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+};
+struct linux_time_args {
+ char tm_l_[PADL_(l_time_t *)]; l_time_t * tm; char tm_r_[PADR_(l_time_t *)];
+};
+struct linux_mknod_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+ char dev_l_[PADL_(l_dev_t)]; l_dev_t dev; char dev_r_[PADR_(l_dev_t)];
+};
+struct linux_chmod_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char mode_l_[PADL_(l_mode_t)]; l_mode_t mode; char mode_r_[PADR_(l_mode_t)];
+};
+struct linux_lchown16_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ 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_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)];
+ char whence_l_[PADL_(l_int)]; l_int whence; char whence_r_[PADR_(l_int)];
+};
+struct linux_getpid_args {
+ register_t dummy;
+};
+struct linux_mount_args {
+ char specialfile_l_[PADL_(char *)]; char * specialfile; char specialfile_r_[PADR_(char *)];
+ char dir_l_[PADL_(char *)]; char * dir; char dir_r_[PADR_(char *)];
+ char filesystemtype_l_[PADL_(char *)]; char * filesystemtype; char filesystemtype_r_[PADR_(char *)];
+ char rwflag_l_[PADL_(l_ulong)]; l_ulong rwflag; char rwflag_r_[PADR_(l_ulong)];
+ char data_l_[PADL_(void *)]; void * data; char data_r_[PADR_(void *)];
+};
+struct linux_oldumount_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+};
+struct linux_setuid16_args {
+ char uid_l_[PADL_(l_uid16_t)]; l_uid16_t uid; char uid_r_[PADR_(l_uid16_t)];
+};
+struct linux_getuid16_args {
+ register_t dummy;
+};
+struct linux_stime_args {
+ register_t dummy;
+};
+struct linux_ptrace_args {
+ char req_l_[PADL_(l_long)]; l_long req; char req_r_[PADR_(l_long)];
+ char pid_l_[PADL_(l_long)]; l_long pid; char pid_r_[PADR_(l_long)];
+ char addr_l_[PADL_(l_long)]; l_long addr; char addr_r_[PADR_(l_long)];
+ char data_l_[PADL_(l_long)]; l_long data; char data_r_[PADR_(l_long)];
+};
+struct linux_alarm_args {
+ char secs_l_[PADL_(l_uint)]; l_uint secs; char secs_r_[PADR_(l_uint)];
+};
+struct linux_pause_args {
+ register_t dummy;
+};
+struct linux_utime_args {
+ char fname_l_[PADL_(char *)]; char * fname; char fname_r_[PADR_(char *)];
+ char times_l_[PADL_(struct l_utimbuf *)]; struct l_utimbuf * times; char times_r_[PADR_(struct l_utimbuf *)];
+};
+struct linux_access_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+};
+struct linux_nice_args {
+ char inc_l_[PADL_(l_int)]; l_int inc; char inc_r_[PADR_(l_int)];
+};
+struct linux_kill_args {
+ char pid_l_[PADL_(l_int)]; l_int pid; char pid_r_[PADR_(l_int)];
+ char signum_l_[PADL_(l_int)]; l_int signum; char signum_r_[PADR_(l_int)];
+};
+struct linux_rename_args {
+ char from_l_[PADL_(char *)]; char * from; char from_r_[PADR_(char *)];
+ char to_l_[PADL_(char *)]; char * to; char to_r_[PADR_(char *)];
+};
+struct linux_mkdir_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
+};
+struct linux_rmdir_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+};
+struct linux_pipe_args {
+ char pipefds_l_[PADL_(l_ulong *)]; l_ulong * pipefds; char pipefds_r_[PADR_(l_ulong *)];
+};
+struct linux_times_args {
+ char buf_l_[PADL_(struct l_times_argv *)]; struct l_times_argv * buf; char buf_r_[PADR_(struct l_times_argv *)];
+};
+struct linux_brk_args {
+ char dsend_l_[PADL_(l_ulong)]; l_ulong dsend; char dsend_r_[PADR_(l_ulong)];
+};
+struct linux_setgid16_args {
+ char gid_l_[PADL_(l_gid16_t)]; l_gid16_t gid; char gid_r_[PADR_(l_gid16_t)];
+};
+struct linux_getgid16_args {
+ register_t dummy;
+};
+struct linux_signal_args {
+ char sig_l_[PADL_(l_int)]; l_int sig; char sig_r_[PADR_(l_int)];
+ char handler_l_[PADL_(l_handler_t)]; l_handler_t handler; char handler_r_[PADR_(l_handler_t)];
+};
+struct linux_geteuid16_args {
+ register_t dummy;
+};
+struct linux_getegid16_args {
+ register_t dummy;
+};
+struct linux_umount_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+};
+struct linux_ioctl_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char cmd_l_[PADL_(l_uint)]; l_uint cmd; char cmd_r_[PADR_(l_uint)];
+ char arg_l_[PADL_(uintptr_t)]; uintptr_t arg; char arg_r_[PADR_(uintptr_t)];
+};
+struct linux_fcntl_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char cmd_l_[PADL_(l_uint)]; l_uint cmd; char cmd_r_[PADR_(l_uint)];
+ char arg_l_[PADL_(uintptr_t)]; uintptr_t arg; char arg_r_[PADR_(uintptr_t)];
+};
+struct linux_olduname_args {
+ register_t dummy;
+};
+struct linux_ustat_args {
+ char dev_l_[PADL_(l_dev_t)]; l_dev_t dev; char dev_r_[PADR_(l_dev_t)];
+ char ubuf_l_[PADL_(struct l_ustat *)]; struct l_ustat * ubuf; char ubuf_r_[PADR_(struct l_ustat *)];
+};
+struct linux_sigaction_args {
+ char sig_l_[PADL_(l_int)]; l_int sig; char sig_r_[PADR_(l_int)];
+ char nsa_l_[PADL_(l_osigaction_t *)]; l_osigaction_t * nsa; char nsa_r_[PADR_(l_osigaction_t *)];
+ char osa_l_[PADL_(l_osigaction_t *)]; l_osigaction_t * osa; char osa_r_[PADR_(l_osigaction_t *)];
+};
+struct linux_sgetmask_args {
+ register_t dummy;
+};
+struct linux_ssetmask_args {
+ char mask_l_[PADL_(l_osigset_t)]; l_osigset_t mask; char mask_r_[PADR_(l_osigset_t)];
+};
+struct linux_setreuid16_args {
+ char ruid_l_[PADL_(l_uid16_t)]; l_uid16_t ruid; char ruid_r_[PADR_(l_uid16_t)];
+ char euid_l_[PADL_(l_uid16_t)]; l_uid16_t euid; char euid_r_[PADR_(l_uid16_t)];
+};
+struct linux_setregid16_args {
+ char rgid_l_[PADL_(l_gid16_t)]; l_gid16_t rgid; char rgid_r_[PADR_(l_gid16_t)];
+ char egid_l_[PADL_(l_gid16_t)]; l_gid16_t egid; char egid_r_[PADR_(l_gid16_t)];
+};
+struct linux_sigsuspend_args {
+ char hist0_l_[PADL_(l_int)]; l_int hist0; char hist0_r_[PADR_(l_int)];
+ char hist1_l_[PADL_(l_int)]; l_int hist1; char hist1_r_[PADR_(l_int)];
+ char mask_l_[PADL_(l_osigset_t)]; l_osigset_t mask; char mask_r_[PADR_(l_osigset_t)];
+};
+struct linux_sigpending_args {
+ char mask_l_[PADL_(l_osigset_t *)]; l_osigset_t * mask; char mask_r_[PADR_(l_osigset_t *)];
+};
+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 *)];
+};
+struct linux_old_getrlimit_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 *)];
+};
+struct linux_getrusage_args {
+ char who_l_[PADL_(int)]; int who; char who_r_[PADR_(int)];
+ char rusage_l_[PADL_(struct l_rusage *)]; struct l_rusage * rusage; char rusage_r_[PADR_(struct l_rusage *)];
+};
+struct linux_gettimeofday_args {
+ char tp_l_[PADL_(struct l_timeval *)]; struct l_timeval * tp; char tp_r_[PADR_(struct l_timeval *)];
+ char tzp_l_[PADL_(struct timezone *)]; struct timezone * tzp; char tzp_r_[PADR_(struct timezone *)];
+};
+struct linux_settimeofday_args {
+ char tp_l_[PADL_(struct l_timeval *)]; struct l_timeval * tp; char tp_r_[PADR_(struct l_timeval *)];
+ char tzp_l_[PADL_(struct timezone *)]; struct timezone * tzp; char tzp_r_[PADR_(struct timezone *)];
+};
+struct linux_getgroups16_args {
+ char gidsetsize_l_[PADL_(l_uint)]; l_uint gidsetsize; char gidsetsize_r_[PADR_(l_uint)];
+ char gidset_l_[PADL_(l_gid16_t *)]; l_gid16_t * gidset; char gidset_r_[PADR_(l_gid16_t *)];
+};
+struct linux_setgroups16_args {
+ char gidsetsize_l_[PADL_(l_uint)]; l_uint gidsetsize; char gidsetsize_r_[PADR_(l_uint)];
+ char gidset_l_[PADL_(l_gid16_t *)]; l_gid16_t * gidset; char gidset_r_[PADR_(l_gid16_t *)];
+};
+struct linux_old_select_args {
+ char ptr_l_[PADL_(struct l_old_select_argv *)]; struct l_old_select_argv * ptr; char ptr_r_[PADR_(struct l_old_select_argv *)];
+};
+struct linux_symlink_args {
+ 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_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 *)];
+ char count_l_[PADL_(l_int)]; l_int count; char count_r_[PADR_(l_int)];
+};
+struct linux_reboot_args {
+ char magic1_l_[PADL_(l_int)]; l_int magic1; char magic1_r_[PADR_(l_int)];
+ char magic2_l_[PADL_(l_int)]; l_int magic2; char magic2_r_[PADR_(l_int)];
+ char cmd_l_[PADL_(l_uint)]; l_uint cmd; char cmd_r_[PADR_(l_uint)];
+ char arg_l_[PADL_(void *)]; void * arg; char arg_r_[PADR_(void *)];
+};
+struct linux_readdir_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char dent_l_[PADL_(struct l_dirent *)]; struct l_dirent * dent; char dent_r_[PADR_(struct l_dirent *)];
+ char count_l_[PADL_(l_uint)]; l_uint count; char count_r_[PADR_(l_uint)];
+};
+struct linux_mmap_args {
+ char ptr_l_[PADL_(struct l_mmap_argv *)]; struct l_mmap_argv * ptr; char ptr_r_[PADR_(struct l_mmap_argv *)];
+};
+struct linux_truncate_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char length_l_[PADL_(l_ulong)]; l_ulong length; char length_r_[PADR_(l_ulong)];
+};
+struct linux_statfs_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char buf_l_[PADL_(struct l_statfs_buf *)]; struct l_statfs_buf * buf; char buf_r_[PADR_(struct l_statfs_buf *)];
+};
+struct linux_fstatfs_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char buf_l_[PADL_(struct l_statfs_buf *)]; struct l_statfs_buf * buf; char buf_r_[PADR_(struct l_statfs_buf *)];
+};
+struct linux_socketcall_args {
+ char what_l_[PADL_(l_int)]; l_int what; char what_r_[PADR_(l_int)];
+ char args_l_[PADL_(l_ulong)]; l_ulong args; char args_r_[PADR_(l_ulong)];
+};
+struct linux_syslog_args {
+ char type_l_[PADL_(l_int)]; l_int type; char type_r_[PADR_(l_int)];
+ char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
+ char len_l_[PADL_(l_int)]; l_int len; char len_r_[PADR_(l_int)];
+};
+struct linux_setitimer_args {
+ char which_l_[PADL_(l_int)]; l_int which; char which_r_[PADR_(l_int)];
+ char itv_l_[PADL_(struct l_itimerval *)]; struct l_itimerval * itv; char itv_r_[PADR_(struct l_itimerval *)];
+ char oitv_l_[PADL_(struct l_itimerval *)]; struct l_itimerval * oitv; char oitv_r_[PADR_(struct l_itimerval *)];
+};
+struct linux_getitimer_args {
+ char which_l_[PADL_(l_int)]; l_int which; char which_r_[PADR_(l_int)];
+ char itv_l_[PADL_(struct l_itimerval *)]; struct l_itimerval * itv; char itv_r_[PADR_(struct l_itimerval *)];
+};
+struct linux_newstat_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char buf_l_[PADL_(struct l_newstat *)]; struct l_newstat * buf; char buf_r_[PADR_(struct l_newstat *)];
+};
+struct linux_newlstat_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char buf_l_[PADL_(struct l_newstat *)]; struct l_newstat * buf; char buf_r_[PADR_(struct l_newstat *)];
+};
+struct linux_newfstat_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char buf_l_[PADL_(struct l_newstat *)]; struct l_newstat * buf; char buf_r_[PADR_(struct l_newstat *)];
+};
+struct linux_uname_args {
+ register_t dummy;
+};
+struct linux_vhangup_args {
+ register_t dummy;
+};
+struct linux_wait4_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char status_l_[PADL_(l_uint *)]; l_uint * status; char status_r_[PADR_(l_uint *)];
+ char options_l_[PADL_(l_int)]; l_int options; char options_r_[PADR_(l_int)];
+ char rusage_l_[PADL_(struct l_rusage *)]; struct l_rusage * rusage; char rusage_r_[PADR_(struct l_rusage *)];
+};
+struct linux_swapoff_args {
+ register_t dummy;
+};
+struct linux_sysinfo_args {
+ char info_l_[PADL_(struct l_sysinfo *)]; struct l_sysinfo * info; char info_r_[PADR_(struct l_sysinfo *)];
+};
+struct linux_ipc_args {
+ char what_l_[PADL_(l_uint)]; l_uint what; char what_r_[PADR_(l_uint)];
+ char arg1_l_[PADL_(l_int)]; l_int arg1; char arg1_r_[PADR_(l_int)];
+ char arg2_l_[PADL_(l_int)]; l_int arg2; char arg2_r_[PADR_(l_int)];
+ char arg3_l_[PADL_(l_int)]; l_int arg3; char arg3_r_[PADR_(l_int)];
+ char ptr_l_[PADL_(void *)]; void * ptr; char ptr_r_[PADR_(void *)];
+ char arg5_l_[PADL_(l_long)]; l_long arg5; char arg5_r_[PADR_(l_long)];
+};
+struct linux_sigreturn_args {
+ char sfp_l_[PADL_(struct l_sigframe *)]; struct l_sigframe * sfp; char sfp_r_[PADR_(struct l_sigframe *)];
+};
+struct linux_clone_args {
+ char flags_l_[PADL_(l_int)]; l_int flags; char flags_r_[PADR_(l_int)];
+ char stack_l_[PADL_(void *)]; void * stack; char stack_r_[PADR_(void *)];
+};
+struct linux_newuname_args {
+ char buf_l_[PADL_(struct l_new_utsname *)]; struct l_new_utsname * buf; char buf_r_[PADR_(struct l_new_utsname *)];
+};
+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 *)];
+ char omask_l_[PADL_(l_osigset_t *)]; l_osigset_t * omask; char omask_r_[PADR_(l_osigset_t *)];
+};
+struct linux_create_module_args {
+ register_t dummy;
+};
+struct linux_init_module_args {
+ register_t dummy;
+};
+struct linux_delete_module_args {
+ register_t dummy;
+};
+struct linux_get_kernel_syms_args {
+ register_t dummy;
+};
+struct linux_quotactl_args {
+ register_t dummy;
+};
+struct linux_bdflush_args {
+ register_t dummy;
+};
+struct linux_sysfs_args {
+ char option_l_[PADL_(l_int)]; l_int option; char option_r_[PADR_(l_int)];
+ char arg1_l_[PADL_(l_ulong)]; l_ulong arg1; char arg1_r_[PADR_(l_ulong)];
+ char arg2_l_[PADL_(l_ulong)]; l_ulong arg2; char arg2_r_[PADR_(l_ulong)];
+};
+struct linux_personality_args {
+ char per_l_[PADL_(l_ulong)]; l_ulong per; char per_r_[PADR_(l_ulong)];
+};
+struct linux_setfsuid16_args {
+ char uid_l_[PADL_(l_uid16_t)]; l_uid16_t uid; char uid_r_[PADR_(l_uid16_t)];
+};
+struct linux_setfsgid16_args {
+ char gid_l_[PADL_(l_gid16_t)]; l_gid16_t gid; char gid_r_[PADR_(l_gid16_t)];
+};
+struct linux_llseek_args {
+ char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
+ char ohigh_l_[PADL_(l_ulong)]; l_ulong ohigh; char ohigh_r_[PADR_(l_ulong)];
+ char olow_l_[PADL_(l_ulong)]; l_ulong olow; char olow_r_[PADR_(l_ulong)];
+ char res_l_[PADL_(l_loff_t *)]; l_loff_t * res; char res_r_[PADR_(l_loff_t *)];
+ char whence_l_[PADL_(l_uint)]; l_uint whence; char whence_r_[PADR_(l_uint)];
+};
+struct linux_getdents_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char dent_l_[PADL_(void *)]; void * dent; char dent_r_[PADR_(void *)];
+ char count_l_[PADL_(l_uint)]; l_uint count; char count_r_[PADR_(l_uint)];
+};
+struct linux_select_args {
+ char nfds_l_[PADL_(l_int)]; l_int nfds; char nfds_r_[PADR_(l_int)];
+ char readfds_l_[PADL_(l_fd_set *)]; l_fd_set * readfds; char readfds_r_[PADR_(l_fd_set *)];
+ char writefds_l_[PADL_(l_fd_set *)]; l_fd_set * writefds; char writefds_r_[PADR_(l_fd_set *)];
+ char exceptfds_l_[PADL_(l_fd_set *)]; l_fd_set * exceptfds; char exceptfds_r_[PADR_(l_fd_set *)];
+ char timeout_l_[PADL_(struct l_timeval *)]; struct l_timeval * timeout; char timeout_r_[PADR_(struct l_timeval *)];
+};
+struct linux_msync_args {
+ char addr_l_[PADL_(l_ulong)]; l_ulong addr; char addr_r_[PADR_(l_ulong)];
+ char len_l_[PADL_(l_size_t)]; l_size_t len; char len_r_[PADR_(l_size_t)];
+ char fl_l_[PADL_(l_int)]; l_int fl; char fl_r_[PADR_(l_int)];
+};
+struct linux_readv_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char iovp_l_[PADL_(struct iovec32 *)]; struct iovec32 * iovp; char iovp_r_[PADR_(struct iovec32 *)];
+ char iovcnt_l_[PADL_(u_int)]; u_int iovcnt; char iovcnt_r_[PADR_(u_int)];
+};
+struct linux_writev_args {
+ char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
+ char iovp_l_[PADL_(struct iovec32 *)]; struct iovec32 * iovp; char iovp_r_[PADR_(struct iovec32 *)];
+ char iovcnt_l_[PADL_(u_int)]; u_int iovcnt; char iovcnt_r_[PADR_(u_int)];
+};
+struct linux_getsid_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+};
+struct linux_fdatasync_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+};
+struct linux_sysctl_args {
+ char args_l_[PADL_(struct l___sysctl_args *)]; struct l___sysctl_args * args; char args_r_[PADR_(struct l___sysctl_args *)];
+};
+struct linux_sched_setscheduler_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)];
+ char param_l_[PADL_(struct l_sched_param *)]; struct l_sched_param * param; char param_r_[PADR_(struct l_sched_param *)];
+};
+struct linux_sched_getscheduler_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+};
+struct linux_sched_get_priority_max_args {
+ char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)];
+};
+struct linux_sched_get_priority_min_args {
+ char policy_l_[PADL_(l_int)]; l_int policy; char policy_r_[PADR_(l_int)];
+};
+struct linux_sched_rr_get_interval_args {
+ char pid_l_[PADL_(l_pid_t)]; l_pid_t pid; char pid_r_[PADR_(l_pid_t)];
+ char interval_l_[PADL_(struct l_timespec *)]; struct l_timespec * interval; char interval_r_[PADR_(struct l_timespec *)];
+};
+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)];
+ char new_len_l_[PADL_(l_ulong)]; l_ulong new_len; char new_len_r_[PADR_(l_ulong)];
+ char flags_l_[PADL_(l_ulong)]; l_ulong flags; char flags_r_[PADR_(l_ulong)];
+ char new_addr_l_[PADL_(l_ulong)]; l_ulong new_addr; char new_addr_r_[PADR_(l_ulong)];
+};
+struct linux_setresuid16_args {
+ char ruid_l_[PADL_(l_uid16_t)]; l_uid16_t ruid; char ruid_r_[PADR_(l_uid16_t)];
+ char euid_l_[PADL_(l_uid16_t)]; l_uid16_t euid; char euid_r_[PADR_(l_uid16_t)];
+ char suid_l_[PADL_(l_uid16_t)]; l_uid16_t suid; char suid_r_[PADR_(l_uid16_t)];
+};
+struct linux_getresuid16_args {
+ char ruid_l_[PADL_(l_uid16_t *)]; l_uid16_t * ruid; char ruid_r_[PADR_(l_uid16_t *)];
+ char euid_l_[PADL_(l_uid16_t *)]; l_uid16_t * euid; char euid_r_[PADR_(l_uid16_t *)];
+ char suid_l_[PADL_(l_uid16_t *)]; l_uid16_t * suid; char suid_r_[PADR_(l_uid16_t *)];
+};
+struct linux_query_module_args {
+ register_t dummy;
+};
+struct linux_nfsservctl_args {
+ register_t dummy;
+};
+struct linux_setresgid16_args {
+ char rgid_l_[PADL_(l_gid16_t)]; l_gid16_t rgid; char rgid_r_[PADR_(l_gid16_t)];
+ char egid_l_[PADL_(l_gid16_t)]; l_gid16_t egid; char egid_r_[PADR_(l_gid16_t)];
+ char sgid_l_[PADL_(l_gid16_t)]; l_gid16_t sgid; char sgid_r_[PADR_(l_gid16_t)];
+};
+struct linux_getresgid16_args {
+ char rgid_l_[PADL_(l_gid16_t *)]; l_gid16_t * rgid; char rgid_r_[PADR_(l_gid16_t *)];
+ char egid_l_[PADL_(l_gid16_t *)]; l_gid16_t * egid; char egid_r_[PADR_(l_gid16_t *)];
+ char sgid_l_[PADL_(l_gid16_t *)]; l_gid16_t * sgid; char sgid_r_[PADR_(l_gid16_t *)];
+};
+struct linux_prctl_args {
+ register_t dummy;
+};
+struct linux_rt_sigreturn_args {
+ char ucp_l_[PADL_(struct l_ucontext *)]; struct l_ucontext * ucp; char ucp_r_[PADR_(struct l_ucontext *)];
+};
+struct linux_rt_sigaction_args {
+ char sig_l_[PADL_(l_int)]; l_int sig; char sig_r_[PADR_(l_int)];
+ char act_l_[PADL_(l_sigaction_t *)]; l_sigaction_t * act; char act_r_[PADR_(l_sigaction_t *)];
+ char oact_l_[PADL_(l_sigaction_t *)]; l_sigaction_t * oact; char oact_r_[PADR_(l_sigaction_t *)];
+ char sigsetsize_l_[PADL_(l_size_t)]; l_size_t sigsetsize; char sigsetsize_r_[PADR_(l_size_t)];
+};
+struct linux_rt_sigprocmask_args {
+ char how_l_[PADL_(l_int)]; l_int how; char how_r_[PADR_(l_int)];
+ char mask_l_[PADL_(l_sigset_t *)]; l_sigset_t * mask; char mask_r_[PADR_(l_sigset_t *)];
+ char omask_l_[PADL_(l_sigset_t *)]; l_sigset_t * omask; char omask_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_sigpending_args {
+ register_t dummy;
+};
+struct linux_rt_sigtimedwait_args {
+ register_t dummy;
+};
+struct linux_rt_sigqueueinfo_args {
+ register_t dummy;
+};
+struct linux_rt_sigsuspend_args {
+ char newset_l_[PADL_(l_sigset_t *)]; l_sigset_t * newset; char newset_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_pread_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
+ char nbyte_l_[PADL_(l_size_t)]; l_size_t nbyte; char nbyte_r_[PADR_(l_size_t)];
+ char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)];
+};
+struct linux_pwrite_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
+ char nbyte_l_[PADL_(l_size_t)]; l_size_t nbyte; char nbyte_r_[PADR_(l_size_t)];
+ char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)];
+};
+struct linux_chown16_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ 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_getcwd_args {
+ char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
+ char bufsize_l_[PADL_(l_ulong)]; l_ulong bufsize; char bufsize_r_[PADR_(l_ulong)];
+};
+struct linux_capget_args {
+ register_t dummy;
+};
+struct linux_capset_args {
+ register_t dummy;
+};
+struct linux_sigaltstack_args {
+ char uss_l_[PADL_(l_stack_t *)]; l_stack_t * uss; char uss_r_[PADR_(l_stack_t *)];
+ char uoss_l_[PADL_(l_stack_t *)]; l_stack_t * uoss; char uoss_r_[PADR_(l_stack_t *)];
+};
+struct linux_sendfile_args {
+ register_t dummy;
+};
+struct linux_vfork_args {
+ register_t dummy;
+};
+struct linux_getrlimit_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 *)];
+};
+struct linux_mmap2_args {
+ char addr_l_[PADL_(l_ulong)]; l_ulong addr; char addr_r_[PADR_(l_ulong)];
+ char len_l_[PADL_(l_ulong)]; l_ulong len; char len_r_[PADR_(l_ulong)];
+ char prot_l_[PADL_(l_ulong)]; l_ulong prot; char prot_r_[PADR_(l_ulong)];
+ char flags_l_[PADL_(l_ulong)]; l_ulong flags; char flags_r_[PADR_(l_ulong)];
+ char fd_l_[PADL_(l_ulong)]; l_ulong fd; char fd_r_[PADR_(l_ulong)];
+ char pgoff_l_[PADL_(l_ulong)]; l_ulong pgoff; char pgoff_r_[PADR_(l_ulong)];
+};
+struct linux_truncate64_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char length_l_[PADL_(l_loff_t)]; l_loff_t length; char length_r_[PADR_(l_loff_t)];
+};
+struct linux_ftruncate64_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char length_l_[PADL_(l_loff_t)]; l_loff_t length; char length_r_[PADR_(l_loff_t)];
+};
+struct linux_stat64_args {
+ char filename_l_[PADL_(char *)]; char * filename; char filename_r_[PADR_(char *)];
+ char statbuf_l_[PADL_(struct l_stat64 *)]; struct l_stat64 * statbuf; char statbuf_r_[PADR_(struct l_stat64 *)];
+ char flags_l_[PADL_(l_long)]; l_long flags; char flags_r_[PADR_(l_long)];
+};
+struct linux_lstat64_args {
+ char filename_l_[PADL_(char *)]; char * filename; char filename_r_[PADR_(char *)];
+ char statbuf_l_[PADL_(struct l_stat64 *)]; struct l_stat64 * statbuf; char statbuf_r_[PADR_(struct l_stat64 *)];
+ char flags_l_[PADL_(l_long)]; l_long flags; char flags_r_[PADR_(l_long)];
+};
+struct linux_fstat64_args {
+ char fd_l_[PADL_(l_ulong)]; l_ulong fd; char fd_r_[PADR_(l_ulong)];
+ char statbuf_l_[PADL_(struct l_stat64 *)]; struct l_stat64 * statbuf; char statbuf_r_[PADR_(struct l_stat64 *)];
+ char flags_l_[PADL_(l_long)]; l_long flags; char flags_r_[PADR_(l_long)];
+};
+struct linux_lchown_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char uid_l_[PADL_(l_uid_t)]; l_uid_t uid; char uid_r_[PADR_(l_uid_t)];
+ char gid_l_[PADL_(l_gid_t)]; l_gid_t gid; char gid_r_[PADR_(l_gid_t)];
+};
+struct linux_getuid_args {
+ register_t dummy;
+};
+struct linux_getgid_args {
+ register_t dummy;
+};
+struct linux_getgroups_args {
+ char gidsetsize_l_[PADL_(l_int)]; l_int gidsetsize; char gidsetsize_r_[PADR_(l_int)];
+ char grouplist_l_[PADL_(l_gid_t *)]; l_gid_t * grouplist; char grouplist_r_[PADR_(l_gid_t *)];
+};
+struct linux_setgroups_args {
+ char gidsetsize_l_[PADL_(l_int)]; l_int gidsetsize; char gidsetsize_r_[PADR_(l_int)];
+ char grouplist_l_[PADL_(l_gid_t *)]; l_gid_t * grouplist; char grouplist_r_[PADR_(l_gid_t *)];
+};
+struct linux_chown_args {
+ char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
+ char uid_l_[PADL_(l_uid_t)]; l_uid_t uid; char uid_r_[PADR_(l_uid_t)];
+ char gid_l_[PADL_(l_gid_t)]; l_gid_t gid; char gid_r_[PADR_(l_gid_t)];
+};
+struct linux_setfsuid_args {
+ char uid_l_[PADL_(l_uid_t)]; l_uid_t uid; char uid_r_[PADR_(l_uid_t)];
+};
+struct linux_setfsgid_args {
+ char gid_l_[PADL_(l_gid_t)]; l_gid_t gid; char gid_r_[PADR_(l_gid_t)];
+};
+struct linux_pivot_root_args {
+ char new_root_l_[PADL_(char *)]; char * new_root; char new_root_r_[PADR_(char *)];
+ char put_old_l_[PADL_(char *)]; char * put_old; char put_old_r_[PADR_(char *)];
+};
+struct linux_mincore_args {
+ char start_l_[PADL_(l_ulong)]; l_ulong start; char start_r_[PADR_(l_ulong)];
+ char len_l_[PADL_(l_size_t)]; l_size_t len; char len_r_[PADR_(l_size_t)];
+ char vec_l_[PADL_(u_char *)]; u_char * vec; char vec_r_[PADR_(u_char *)];
+};
+struct linux_getdents64_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char dirent_l_[PADL_(void *)]; void * dirent; char dirent_r_[PADR_(void *)];
+ char count_l_[PADL_(l_uint)]; l_uint count; char count_r_[PADR_(l_uint)];
+};
+struct linux_fcntl64_args {
+ char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
+ char cmd_l_[PADL_(l_uint)]; l_uint cmd; char cmd_r_[PADR_(l_uint)];
+ char arg_l_[PADL_(uintptr_t)]; uintptr_t arg; char arg_r_[PADR_(uintptr_t)];
+};
+struct linux_setxattr_args {
+ register_t dummy;
+};
+struct linux_lsetxattr_args {
+ register_t dummy;
+};
+struct linux_fsetxattr_args {
+ register_t dummy;
+};
+struct linux_getxattr_args {
+ register_t dummy;
+};
+struct linux_lgetxattr_args {
+ register_t dummy;
+};
+struct linux_fgetxattr_args {
+ register_t dummy;
+};
+struct linux_listxattr_args {
+ register_t dummy;
+};
+struct linux_llistxattr_args {
+ register_t dummy;
+};
+struct linux_flistxattr_args {
+ register_t dummy;
+};
+struct linux_removexattr_args {
+ register_t dummy;
+};
+struct linux_lremovexattr_args {
+ register_t dummy;
+};
+struct linux_fremovexattr_args {
+ register_t dummy;
+};
+struct linux_fadvise64_args {
+ register_t dummy;
+};
+int linux_fork(struct thread *, struct linux_fork_args *);
+int linux_open(struct thread *, struct linux_open_args *);
+int linux_waitpid(struct thread *, struct linux_waitpid_args *);
+int linux_creat(struct thread *, struct linux_creat_args *);
+int linux_link(struct thread *, struct linux_link_args *);
+int linux_unlink(struct thread *, struct linux_unlink_args *);
+int linux_execve(struct thread *, struct linux_execve_args *);
+int linux_chdir(struct thread *, struct linux_chdir_args *);
+int linux_time(struct thread *, struct linux_time_args *);
+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_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 *);
+int linux_oldumount(struct thread *, struct linux_oldumount_args *);
+int linux_setuid16(struct thread *, struct linux_setuid16_args *);
+int linux_getuid16(struct thread *, struct linux_getuid16_args *);
+int linux_stime(struct thread *, struct linux_stime_args *);
+int linux_ptrace(struct thread *, struct linux_ptrace_args *);
+int linux_alarm(struct thread *, struct linux_alarm_args *);
+int linux_pause(struct thread *, struct linux_pause_args *);
+int linux_utime(struct thread *, struct linux_utime_args *);
+int linux_access(struct thread *, struct linux_access_args *);
+int linux_nice(struct thread *, struct linux_nice_args *);
+int linux_kill(struct thread *, struct linux_kill_args *);
+int linux_rename(struct thread *, struct linux_rename_args *);
+int linux_mkdir(struct thread *, struct linux_mkdir_args *);
+int linux_rmdir(struct thread *, struct linux_rmdir_args *);
+int linux_pipe(struct thread *, struct linux_pipe_args *);
+int linux_times(struct thread *, struct linux_times_args *);
+int linux_brk(struct thread *, struct linux_brk_args *);
+int linux_setgid16(struct thread *, struct linux_setgid16_args *);
+int linux_getgid16(struct thread *, struct linux_getgid16_args *);
+int linux_signal(struct thread *, struct linux_signal_args *);
+int linux_geteuid16(struct thread *, struct linux_geteuid16_args *);
+int linux_getegid16(struct thread *, struct linux_getegid16_args *);
+int linux_umount(struct thread *, struct linux_umount_args *);
+int linux_ioctl(struct thread *, struct linux_ioctl_args *);
+int linux_fcntl(struct thread *, struct linux_fcntl_args *);
+int linux_olduname(struct thread *, struct linux_olduname_args *);
+int linux_ustat(struct thread *, struct linux_ustat_args *);
+int linux_sigaction(struct thread *, struct linux_sigaction_args *);
+int linux_sgetmask(struct thread *, struct linux_sgetmask_args *);
+int linux_ssetmask(struct thread *, struct linux_ssetmask_args *);
+int linux_setreuid16(struct thread *, struct linux_setreuid16_args *);
+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_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 *);
+int linux_gettimeofday(struct thread *, struct linux_gettimeofday_args *);
+int linux_settimeofday(struct thread *, struct linux_settimeofday_args *);
+int linux_getgroups16(struct thread *, struct linux_getgroups16_args *);
+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_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_statfs(struct thread *, struct linux_statfs_args *);
+int linux_fstatfs(struct thread *, struct linux_fstatfs_args *);
+int linux_socketcall(struct thread *, struct linux_socketcall_args *);
+int linux_syslog(struct thread *, struct linux_syslog_args *);
+int linux_setitimer(struct thread *, struct linux_setitimer_args *);
+int linux_getitimer(struct thread *, struct linux_getitimer_args *);
+int linux_newstat(struct thread *, struct linux_newstat_args *);
+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_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 *);
+int linux_sysinfo(struct thread *, struct linux_sysinfo_args *);
+int linux_ipc(struct thread *, struct linux_ipc_args *);
+int linux_sigreturn(struct thread *, struct linux_sigreturn_args *);
+int linux_clone(struct thread *, struct linux_clone_args *);
+int linux_newuname(struct thread *, struct linux_newuname_args *);
+int linux_adjtimex(struct thread *, struct linux_adjtimex_args *);
+int linux_mprotect(struct thread *, struct linux_mprotect_args *);
+int linux_sigprocmask(struct thread *, struct linux_sigprocmask_args *);
+int linux_create_module(struct thread *, struct linux_create_module_args *);
+int linux_init_module(struct thread *, struct linux_init_module_args *);
+int linux_delete_module(struct thread *, struct linux_delete_module_args *);
+int linux_get_kernel_syms(struct thread *, struct linux_get_kernel_syms_args *);
+int linux_quotactl(struct thread *, struct linux_quotactl_args *);
+int linux_bdflush(struct thread *, struct linux_bdflush_args *);
+int linux_sysfs(struct thread *, struct linux_sysfs_args *);
+int linux_personality(struct thread *, struct linux_personality_args *);
+int linux_setfsuid16(struct thread *, struct linux_setfsuid16_args *);
+int linux_setfsgid16(struct thread *, struct linux_setfsgid16_args *);
+int linux_llseek(struct thread *, struct linux_llseek_args *);
+int linux_getdents(struct thread *, struct linux_getdents_args *);
+int linux_select(struct thread *, struct linux_select_args *);
+int linux_msync(struct thread *, struct linux_msync_args *);
+int linux_readv(struct thread *, struct linux_readv_args *);
+int linux_writev(struct thread *, struct linux_writev_args *);
+int linux_getsid(struct thread *, struct linux_getsid_args *);
+int linux_fdatasync(struct thread *, struct linux_fdatasync_args *);
+int linux_sysctl(struct thread *, struct linux_sysctl_args *);
+int linux_sched_setscheduler(struct thread *, struct linux_sched_setscheduler_args *);
+int linux_sched_getscheduler(struct thread *, struct linux_sched_getscheduler_args *);
+int linux_sched_get_priority_max(struct thread *, struct linux_sched_get_priority_max_args *);
+int linux_sched_get_priority_min(struct thread *, struct linux_sched_get_priority_min_args *);
+int linux_sched_rr_get_interval(struct thread *, struct linux_sched_rr_get_interval_args *);
+int linux_nanosleep(struct thread *, struct linux_nanosleep_args *);
+int linux_mremap(struct thread *, struct linux_mremap_args *);
+int linux_setresuid16(struct thread *, struct linux_setresuid16_args *);
+int linux_getresuid16(struct thread *, struct linux_getresuid16_args *);
+int linux_query_module(struct thread *, struct linux_query_module_args *);
+int linux_nfsservctl(struct thread *, struct linux_nfsservctl_args *);
+int linux_setresgid16(struct thread *, struct linux_setresgid16_args *);
+int linux_getresgid16(struct thread *, struct linux_getresgid16_args *);
+int linux_prctl(struct thread *, struct linux_prctl_args *);
+int linux_rt_sigreturn(struct thread *, struct linux_rt_sigreturn_args *);
+int linux_rt_sigaction(struct thread *, struct linux_rt_sigaction_args *);
+int linux_rt_sigprocmask(struct thread *, struct linux_rt_sigprocmask_args *);
+int linux_rt_sigpending(struct thread *, struct linux_rt_sigpending_args *);
+int linux_rt_sigtimedwait(struct thread *, struct linux_rt_sigtimedwait_args *);
+int linux_rt_sigqueueinfo(struct thread *, struct linux_rt_sigqueueinfo_args *);
+int linux_rt_sigsuspend(struct thread *, struct linux_rt_sigsuspend_args *);
+int linux_pread(struct thread *, struct linux_pread_args *);
+int linux_pwrite(struct thread *, struct linux_pwrite_args *);
+int linux_chown16(struct thread *, struct linux_chown16_args *);
+int linux_getcwd(struct thread *, struct linux_getcwd_args *);
+int linux_capget(struct thread *, struct linux_capget_args *);
+int linux_capset(struct thread *, struct linux_capset_args *);
+int linux_sigaltstack(struct thread *, struct linux_sigaltstack_args *);
+int linux_sendfile(struct thread *, struct linux_sendfile_args *);
+int linux_vfork(struct thread *, struct linux_vfork_args *);
+int linux_getrlimit(struct thread *, struct linux_getrlimit_args *);
+int linux_mmap2(struct thread *, struct linux_mmap2_args *);
+int linux_truncate64(struct thread *, struct linux_truncate64_args *);
+int linux_ftruncate64(struct thread *, struct linux_ftruncate64_args *);
+int linux_stat64(struct thread *, struct linux_stat64_args *);
+int linux_lstat64(struct thread *, struct linux_lstat64_args *);
+int linux_fstat64(struct thread *, struct linux_fstat64_args *);
+int linux_lchown(struct thread *, struct linux_lchown_args *);
+int linux_getuid(struct thread *, struct linux_getuid_args *);
+int linux_getgid(struct thread *, struct linux_getgid_args *);
+int linux_getgroups(struct thread *, struct linux_getgroups_args *);
+int linux_setgroups(struct thread *, struct linux_setgroups_args *);
+int linux_chown(struct thread *, struct linux_chown_args *);
+int linux_setfsuid(struct thread *, struct linux_setfsuid_args *);
+int linux_setfsgid(struct thread *, struct linux_setfsgid_args *);
+int linux_pivot_root(struct thread *, struct linux_pivot_root_args *);
+int linux_mincore(struct thread *, struct linux_mincore_args *);
+int linux_getdents64(struct thread *, struct linux_getdents64_args *);
+int linux_fcntl64(struct thread *, struct linux_fcntl64_args *);
+int linux_setxattr(struct thread *, struct linux_setxattr_args *);
+int linux_lsetxattr(struct thread *, struct linux_lsetxattr_args *);
+int linux_fsetxattr(struct thread *, struct linux_fsetxattr_args *);
+int linux_getxattr(struct thread *, struct linux_getxattr_args *);
+int linux_lgetxattr(struct thread *, struct linux_lgetxattr_args *);
+int linux_fgetxattr(struct thread *, struct linux_fgetxattr_args *);
+int linux_listxattr(struct thread *, struct linux_listxattr_args *);
+int linux_llistxattr(struct thread *, struct linux_llistxattr_args *);
+int linux_flistxattr(struct thread *, struct linux_flistxattr_args *);
+int linux_removexattr(struct thread *, struct linux_removexattr_args *);
+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 *);
+
+#ifdef COMPAT_43
+
+
+#endif /* COMPAT_43 */
+
+
+#ifdef COMPAT_FREEBSD4
+
+
+#endif /* COMPAT_FREEBSD4 */
+
+#undef PAD_
+#undef PADL_
+#undef PADR_
+
+#endif /* !_LINUX_SYSPROTO_H_ */
diff --git a/sys/amd64/linux32/linux32_syscall.h b/sys/amd64/linux32/linux32_syscall.h
new file mode 100644
index 000000000000..d4a8c4a1f450
--- /dev/null
+++ b/sys/amd64/linux32/linux32_syscall.h
@@ -0,0 +1,222 @@
+/*
+ * System call numbers.
+ *
+ * DO NOT EDIT-- this file is automatically generated.
+ * $FreeBSD$
+ * created from FreeBSD
+ */
+
+#define LINUX_SYS_exit 1
+#define LINUX_SYS_linux_fork 2
+#define LINUX_SYS_read 3
+#define LINUX_SYS_write 4
+#define LINUX_SYS_linux_open 5
+#define LINUX_SYS_close 6
+#define LINUX_SYS_linux_waitpid 7
+#define LINUX_SYS_linux_creat 8
+#define LINUX_SYS_linux_link 9
+#define LINUX_SYS_linux_unlink 10
+#define LINUX_SYS_linux_execve 11
+#define LINUX_SYS_linux_chdir 12
+#define LINUX_SYS_linux_time 13
+#define LINUX_SYS_linux_mknod 14
+#define LINUX_SYS_linux_chmod 15
+#define LINUX_SYS_linux_lchown16 16
+#define LINUX_SYS_linux_lseek 19
+#define LINUX_SYS_linux_getpid 20
+#define LINUX_SYS_linux_mount 21
+#define LINUX_SYS_linux_oldumount 22
+#define LINUX_SYS_linux_setuid16 23
+#define LINUX_SYS_linux_getuid16 24
+#define LINUX_SYS_linux_stime 25
+#define LINUX_SYS_linux_ptrace 26
+#define LINUX_SYS_linux_alarm 27
+#define LINUX_SYS_linux_pause 29
+#define LINUX_SYS_linux_utime 30
+#define LINUX_SYS_linux_access 33
+#define LINUX_SYS_linux_nice 34
+#define LINUX_SYS_sync 36
+#define LINUX_SYS_linux_kill 37
+#define LINUX_SYS_linux_rename 38
+#define LINUX_SYS_linux_mkdir 39
+#define LINUX_SYS_linux_rmdir 40
+#define LINUX_SYS_dup 41
+#define LINUX_SYS_linux_pipe 42
+#define LINUX_SYS_linux_times 43
+#define LINUX_SYS_linux_brk 45
+#define LINUX_SYS_linux_setgid16 46
+#define LINUX_SYS_linux_getgid16 47
+#define LINUX_SYS_linux_signal 48
+#define LINUX_SYS_linux_geteuid16 49
+#define LINUX_SYS_linux_getegid16 50
+#define LINUX_SYS_acct 51
+#define LINUX_SYS_linux_umount 52
+#define LINUX_SYS_linux_ioctl 54
+#define LINUX_SYS_linux_fcntl 55
+#define LINUX_SYS_setpgid 57
+#define LINUX_SYS_linux_olduname 59
+#define LINUX_SYS_umask 60
+#define LINUX_SYS_chroot 61
+#define LINUX_SYS_linux_ustat 62
+#define LINUX_SYS_dup2 63
+#define LINUX_SYS_getppid 64
+#define LINUX_SYS_getpgrp 65
+#define LINUX_SYS_setsid 66
+#define LINUX_SYS_linux_sigaction 67
+#define LINUX_SYS_linux_sgetmask 68
+#define LINUX_SYS_linux_ssetmask 69
+#define LINUX_SYS_linux_setreuid16 70
+#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_setrlimit 75
+#define LINUX_SYS_linux_old_getrlimit 76
+#define LINUX_SYS_linux_getrusage 77
+#define LINUX_SYS_linux_gettimeofday 78
+#define LINUX_SYS_linux_settimeofday 79
+#define LINUX_SYS_linux_getgroups16 80
+#define LINUX_SYS_linux_setgroups16 81
+#define LINUX_SYS_linux_old_select 82
+#define LINUX_SYS_linux_symlink 83
+#define LINUX_SYS_linux_readlink 85
+#define LINUX_SYS_swapon 87
+#define LINUX_SYS_linux_reboot 88
+#define LINUX_SYS_linux_readdir 89
+#define LINUX_SYS_linux_mmap 90
+#define LINUX_SYS_munmap 91
+#define LINUX_SYS_linux_truncate 92
+#define LINUX_SYS_oftruncate 93
+#define LINUX_SYS_fchmod 94
+#define LINUX_SYS_fchown 95
+#define LINUX_SYS_getpriority 96
+#define LINUX_SYS_setpriority 97
+#define LINUX_SYS_linux_statfs 99
+#define LINUX_SYS_linux_fstatfs 100
+#define LINUX_SYS_linux_socketcall 102
+#define LINUX_SYS_linux_syslog 103
+#define LINUX_SYS_linux_setitimer 104
+#define LINUX_SYS_linux_getitimer 105
+#define LINUX_SYS_linux_newstat 106
+#define LINUX_SYS_linux_newlstat 107
+#define LINUX_SYS_linux_newfstat 108
+#define LINUX_SYS_linux_uname 109
+#define LINUX_SYS_linux_vhangup 111
+#define LINUX_SYS_linux_wait4 114
+#define LINUX_SYS_linux_swapoff 115
+#define LINUX_SYS_linux_sysinfo 116
+#define LINUX_SYS_linux_ipc 117
+#define LINUX_SYS_fsync 118
+#define LINUX_SYS_linux_sigreturn 119
+#define LINUX_SYS_linux_clone 120
+#define LINUX_SYS_setdomainname 121
+#define LINUX_SYS_linux_newuname 122
+#define LINUX_SYS_linux_adjtimex 124
+#define LINUX_SYS_linux_mprotect 125
+#define LINUX_SYS_linux_sigprocmask 126
+#define LINUX_SYS_linux_create_module 127
+#define LINUX_SYS_linux_init_module 128
+#define LINUX_SYS_linux_delete_module 129
+#define LINUX_SYS_linux_get_kernel_syms 130
+#define LINUX_SYS_linux_quotactl 131
+#define LINUX_SYS_getpgid 132
+#define LINUX_SYS_fchdir 133
+#define LINUX_SYS_linux_bdflush 134
+#define LINUX_SYS_linux_sysfs 135
+#define LINUX_SYS_linux_personality 136
+#define LINUX_SYS_linux_setfsuid16 138
+#define LINUX_SYS_linux_setfsgid16 139
+#define LINUX_SYS_linux_llseek 140
+#define LINUX_SYS_linux_getdents 141
+#define LINUX_SYS_linux_select 142
+#define LINUX_SYS_flock 143
+#define LINUX_SYS_linux_msync 144
+#define LINUX_SYS_linux_readv 145
+#define LINUX_SYS_linux_writev 146
+#define LINUX_SYS_linux_getsid 147
+#define LINUX_SYS_linux_fdatasync 148
+#define LINUX_SYS_linux_sysctl 149
+#define LINUX_SYS_mlock 150
+#define LINUX_SYS_munlock 151
+#define LINUX_SYS_mlockall 152
+#define LINUX_SYS_munlockall 153
+#define LINUX_SYS_sched_setparam 154
+#define LINUX_SYS_sched_getparam 155
+#define LINUX_SYS_linux_sched_setscheduler 156
+#define LINUX_SYS_linux_sched_getscheduler 157
+#define LINUX_SYS_sched_yield 158
+#define LINUX_SYS_linux_sched_get_priority_max 159
+#define LINUX_SYS_linux_sched_get_priority_min 160
+#define LINUX_SYS_linux_sched_rr_get_interval 161
+#define LINUX_SYS_linux_nanosleep 162
+#define LINUX_SYS_linux_mremap 163
+#define LINUX_SYS_linux_setresuid16 164
+#define LINUX_SYS_linux_getresuid16 165
+#define LINUX_SYS_linux_query_module 167
+#define LINUX_SYS_poll 168
+#define LINUX_SYS_linux_nfsservctl 169
+#define LINUX_SYS_linux_setresgid16 170
+#define LINUX_SYS_linux_getresgid16 171
+#define LINUX_SYS_linux_prctl 172
+#define LINUX_SYS_linux_rt_sigreturn 173
+#define LINUX_SYS_linux_rt_sigaction 174
+#define LINUX_SYS_linux_rt_sigprocmask 175
+#define LINUX_SYS_linux_rt_sigpending 176
+#define LINUX_SYS_linux_rt_sigtimedwait 177
+#define LINUX_SYS_linux_rt_sigqueueinfo 178
+#define LINUX_SYS_linux_rt_sigsuspend 179
+#define LINUX_SYS_linux_pread 180
+#define LINUX_SYS_linux_pwrite 181
+#define LINUX_SYS_linux_chown16 182
+#define LINUX_SYS_linux_getcwd 183
+#define LINUX_SYS_linux_capget 184
+#define LINUX_SYS_linux_capset 185
+#define LINUX_SYS_linux_sigaltstack 186
+#define LINUX_SYS_linux_sendfile 187
+#define LINUX_SYS_linux_vfork 190
+#define LINUX_SYS_linux_getrlimit 191
+#define LINUX_SYS_linux_mmap2 192
+#define LINUX_SYS_linux_truncate64 193
+#define LINUX_SYS_linux_ftruncate64 194
+#define LINUX_SYS_linux_stat64 195
+#define LINUX_SYS_linux_lstat64 196
+#define LINUX_SYS_linux_fstat64 197
+#define LINUX_SYS_linux_lchown 198
+#define LINUX_SYS_linux_getuid 199
+#define LINUX_SYS_linux_getgid 200
+#define LINUX_SYS_geteuid 201
+#define LINUX_SYS_getegid 202
+#define LINUX_SYS_setreuid 203
+#define LINUX_SYS_setregid 204
+#define LINUX_SYS_linux_getgroups 205
+#define LINUX_SYS_linux_setgroups 206
+#define LINUX_SYS_setresuid 208
+#define LINUX_SYS_getresuid 209
+#define LINUX_SYS_setresgid 210
+#define LINUX_SYS_getresgid 211
+#define LINUX_SYS_linux_chown 212
+#define LINUX_SYS_setuid 213
+#define LINUX_SYS_setgid 214
+#define LINUX_SYS_linux_setfsuid 215
+#define LINUX_SYS_linux_setfsgid 216
+#define LINUX_SYS_linux_pivot_root 217
+#define LINUX_SYS_linux_mincore 218
+#define LINUX_SYS_madvise 219
+#define LINUX_SYS_linux_getdents64 220
+#define LINUX_SYS_linux_fcntl64 221
+#define LINUX_SYS_gettid 224
+#define LINUX_SYS_linux_setxattr 226
+#define LINUX_SYS_linux_lsetxattr 227
+#define LINUX_SYS_linux_fsetxattr 228
+#define LINUX_SYS_linux_getxattr 229
+#define LINUX_SYS_linux_lgetxattr 230
+#define LINUX_SYS_linux_fgetxattr 231
+#define LINUX_SYS_linux_listxattr 232
+#define LINUX_SYS_linux_llistxattr 233
+#define LINUX_SYS_linux_flistxattr 234
+#define LINUX_SYS_linux_removexattr 235
+#define LINUX_SYS_linux_lremovexattr 236
+#define LINUX_SYS_linux_fremovexattr 237
+#define LINUX_SYS_linux_fadvise64 250
+#define LINUX_SYS_exit_group 252
+#define LINUX_SYS_MAXSYSCALL 268
diff --git a/sys/amd64/linux32/linux32_sysent.c b/sys/amd64/linux32/linux32_sysent.c
new file mode 100644
index 000000000000..2c730b88ca9d
--- /dev/null
+++ b/sys/amd64/linux32/linux32_sysent.c
@@ -0,0 +1,288 @@
+/*
+ * System call switch table.
+ *
+ * DO NOT EDIT-- this file is automatically generated.
+ * $FreeBSD$
+ * created from FreeBSD
+ */
+
+#include "opt_compat.h"
+#include <sys/param.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
+#include <amd64/linux32/linux.h>
+#include <amd64/linux32/linux32_proto.h>
+
+#define AS(name) (sizeof(struct name) / sizeof(register_t))
+
+/* The casts are bogus but will do for now. */
+struct sysent linux_sysent[] = {
+ { 0, (sy_call_t *)nosys }, /* 0 = setup */
+ { SYF_MPSAFE | AS(sys_exit_args), (sy_call_t *)sys_exit }, /* 1 = exit */
+ { SYF_MPSAFE | 0, (sy_call_t *)linux_fork }, /* 2 = linux_fork */
+ { SYF_MPSAFE | AS(read_args), (sy_call_t *)read }, /* 3 = read */
+ { SYF_MPSAFE | AS(write_args), (sy_call_t *)write }, /* 4 = write */
+ { AS(linux_open_args), (sy_call_t *)linux_open }, /* 5 = linux_open */
+ { SYF_MPSAFE | AS(close_args), (sy_call_t *)close }, /* 6 = close */
+ { SYF_MPSAFE | AS(linux_waitpid_args), (sy_call_t *)linux_waitpid }, /* 7 = linux_waitpid */
+ { AS(linux_creat_args), (sy_call_t *)linux_creat }, /* 8 = linux_creat */
+ { AS(linux_link_args), (sy_call_t *)linux_link }, /* 9 = linux_link */
+ { AS(linux_unlink_args), (sy_call_t *)linux_unlink }, /* 10 = linux_unlink */
+ { AS(linux_execve_args), (sy_call_t *)linux_execve }, /* 11 = linux_execve */
+ { AS(linux_chdir_args), (sy_call_t *)linux_chdir }, /* 12 = linux_chdir */
+ { AS(linux_time_args), (sy_call_t *)linux_time }, /* 13 = linux_time */
+ { AS(linux_mknod_args), (sy_call_t *)linux_mknod }, /* 14 = linux_mknod */
+ { AS(linux_chmod_args), (sy_call_t *)linux_chmod }, /* 15 = linux_chmod */
+ { AS(linux_lchown16_args), (sy_call_t *)linux_lchown16 }, /* 16 = linux_lchown16 */
+ { 0, (sy_call_t *)nosys }, /* 17 = break */
+ { 0, (sy_call_t *)nosys }, /* 18 = stat */
+ { AS(linux_lseek_args), (sy_call_t *)linux_lseek }, /* 19 = linux_lseek */
+ { SYF_MPSAFE | 0, (sy_call_t *)linux_getpid }, /* 20 = linux_getpid */
+ { AS(linux_mount_args), (sy_call_t *)linux_mount }, /* 21 = linux_mount */
+ { AS(linux_oldumount_args), (sy_call_t *)linux_oldumount }, /* 22 = linux_oldumount */
+ { SYF_MPSAFE | AS(linux_setuid16_args), (sy_call_t *)linux_setuid16 }, /* 23 = linux_setuid16 */
+ { SYF_MPSAFE | 0, (sy_call_t *)linux_getuid16 }, /* 24 = linux_getuid16 */
+ { 0, (sy_call_t *)linux_stime }, /* 25 = linux_stime */
+ { SYF_MPSAFE | AS(linux_ptrace_args), (sy_call_t *)linux_ptrace }, /* 26 = linux_ptrace */
+ { AS(linux_alarm_args), (sy_call_t *)linux_alarm }, /* 27 = linux_alarm */
+ { 0, (sy_call_t *)nosys }, /* 28 = fstat */
+ { SYF_MPSAFE | 0, (sy_call_t *)linux_pause }, /* 29 = linux_pause */
+ { AS(linux_utime_args), (sy_call_t *)linux_utime }, /* 30 = linux_utime */
+ { 0, (sy_call_t *)nosys }, /* 31 = stty */
+ { 0, (sy_call_t *)nosys }, /* 32 = gtty */
+ { AS(linux_access_args), (sy_call_t *)linux_access }, /* 33 = linux_access */
+ { SYF_MPSAFE | AS(linux_nice_args), (sy_call_t *)linux_nice }, /* 34 = linux_nice */
+ { 0, (sy_call_t *)nosys }, /* 35 = ftime */
+ { 0, (sy_call_t *)sync }, /* 36 = sync */
+ { SYF_MPSAFE | AS(linux_kill_args), (sy_call_t *)linux_kill }, /* 37 = linux_kill */
+ { AS(linux_rename_args), (sy_call_t *)linux_rename }, /* 38 = linux_rename */
+ { AS(linux_mkdir_args), (sy_call_t *)linux_mkdir }, /* 39 = linux_mkdir */
+ { AS(linux_rmdir_args), (sy_call_t *)linux_rmdir }, /* 40 = linux_rmdir */
+ { SYF_MPSAFE | AS(dup_args), (sy_call_t *)dup }, /* 41 = dup */
+ { SYF_MPSAFE | AS(linux_pipe_args), (sy_call_t *)linux_pipe }, /* 42 = linux_pipe */
+ { AS(linux_times_args), (sy_call_t *)linux_times }, /* 43 = linux_times */
+ { 0, (sy_call_t *)nosys }, /* 44 = prof */
+ { AS(linux_brk_args), (sy_call_t *)linux_brk }, /* 45 = linux_brk */
+ { SYF_MPSAFE | AS(linux_setgid16_args), (sy_call_t *)linux_setgid16 }, /* 46 = linux_setgid16 */
+ { SYF_MPSAFE | 0, (sy_call_t *)linux_getgid16 }, /* 47 = linux_getgid16 */
+ { SYF_MPSAFE | AS(linux_signal_args), (sy_call_t *)linux_signal }, /* 48 = linux_signal */
+ { SYF_MPSAFE | 0, (sy_call_t *)linux_geteuid16 }, /* 49 = linux_geteuid16 */
+ { SYF_MPSAFE | 0, (sy_call_t *)linux_getegid16 }, /* 50 = linux_getegid16 */
+ { SYF_MPSAFE | AS(acct_args), (sy_call_t *)acct }, /* 51 = acct */
+ { AS(linux_umount_args), (sy_call_t *)linux_umount }, /* 52 = linux_umount */
+ { 0, (sy_call_t *)nosys }, /* 53 = lock */
+ { AS(linux_ioctl_args), (sy_call_t *)linux_ioctl }, /* 54 = linux_ioctl */
+ { AS(linux_fcntl_args), (sy_call_t *)linux_fcntl }, /* 55 = linux_fcntl */
+ { 0, (sy_call_t *)nosys }, /* 56 = mpx */
+ { SYF_MPSAFE | AS(setpgid_args), (sy_call_t *)setpgid }, /* 57 = setpgid */
+ { 0, (sy_call_t *)nosys }, /* 58 = ulimit */
+ { 0, (sy_call_t *)linux_olduname }, /* 59 = linux_olduname */
+ { SYF_MPSAFE | AS(umask_args), (sy_call_t *)umask }, /* 60 = umask */
+ { AS(chroot_args), (sy_call_t *)chroot }, /* 61 = chroot */
+ { AS(linux_ustat_args), (sy_call_t *)linux_ustat }, /* 62 = linux_ustat */
+ { SYF_MPSAFE | AS(dup2_args), (sy_call_t *)dup2 }, /* 63 = dup2 */
+ { SYF_MPSAFE | 0, (sy_call_t *)getppid }, /* 64 = getppid */
+ { SYF_MPSAFE | 0, (sy_call_t *)getpgrp }, /* 65 = getpgrp */
+ { SYF_MPSAFE | 0, (sy_call_t *)setsid }, /* 66 = setsid */
+ { SYF_MPSAFE | AS(linux_sigaction_args), (sy_call_t *)linux_sigaction }, /* 67 = linux_sigaction */
+ { SYF_MPSAFE | 0, (sy_call_t *)linux_sgetmask }, /* 68 = linux_sgetmask */
+ { SYF_MPSAFE | AS(linux_ssetmask_args), (sy_call_t *)linux_ssetmask }, /* 69 = linux_ssetmask */
+ { SYF_MPSAFE | AS(linux_setreuid16_args), (sy_call_t *)linux_setreuid16 }, /* 70 = linux_setreuid16 */
+ { SYF_MPSAFE | AS(linux_setregid16_args), (sy_call_t *)linux_setregid16 }, /* 71 = linux_setregid16 */
+ { SYF_MPSAFE | AS(linux_sigsuspend_args), (sy_call_t *)linux_sigsuspend }, /* 72 = linux_sigsuspend */
+ { SYF_MPSAFE | AS(linux_sigpending_args), (sy_call_t *)linux_sigpending }, /* 73 = linux_sigpending */
+ { SYF_MPSAFE | AS(sethostname_args), (sy_call_t *)osethostname }, /* 74 = osethostname */
+ { SYF_MPSAFE | AS(linux_setrlimit_args), (sy_call_t *)linux_setrlimit }, /* 75 = linux_setrlimit */
+ { SYF_MPSAFE | AS(linux_old_getrlimit_args), (sy_call_t *)linux_old_getrlimit }, /* 76 = linux_old_getrlimit */
+ { SYF_MPSAFE | AS(linux_getrusage_args), (sy_call_t *)linux_getrusage }, /* 77 = linux_getrusage */
+ { SYF_MPSAFE | AS(linux_gettimeofday_args), (sy_call_t *)linux_gettimeofday }, /* 78 = linux_gettimeofday */
+ { SYF_MPSAFE | AS(linux_settimeofday_args), (sy_call_t *)linux_settimeofday }, /* 79 = linux_settimeofday */
+ { SYF_MPSAFE | AS(linux_getgroups16_args), (sy_call_t *)linux_getgroups16 }, /* 80 = linux_getgroups16 */
+ { SYF_MPSAFE | AS(linux_setgroups16_args), (sy_call_t *)linux_setgroups16 }, /* 81 = linux_setgroups16 */
+ { AS(linux_old_select_args), (sy_call_t *)linux_old_select }, /* 82 = linux_old_select */
+ { AS(linux_symlink_args), (sy_call_t *)linux_symlink }, /* 83 = linux_symlink */
+ { 0, (sy_call_t *)nosys }, /* 84 = ostat */
+ { AS(linux_readlink_args), (sy_call_t *)linux_readlink }, /* 85 = linux_readlink */
+ { 0, (sy_call_t *)nosys }, /* 86 = linux_uselib */
+ { AS(swapon_args), (sy_call_t *)swapon }, /* 87 = swapon */
+ { AS(linux_reboot_args), (sy_call_t *)linux_reboot }, /* 88 = linux_reboot */
+ { AS(linux_readdir_args), (sy_call_t *)linux_readdir }, /* 89 = linux_readdir */
+ { AS(linux_mmap_args), (sy_call_t *)linux_mmap }, /* 90 = linux_mmap */
+ { AS(munmap_args), (sy_call_t *)munmap }, /* 91 = munmap */
+ { AS(linux_truncate_args), (sy_call_t *)linux_truncate }, /* 92 = linux_truncate */
+ { AS(oftruncate_args), (sy_call_t *)oftruncate }, /* 93 = oftruncate */
+ { AS(fchmod_args), (sy_call_t *)fchmod }, /* 94 = fchmod */
+ { AS(fchown_args), (sy_call_t *)fchown }, /* 95 = fchown */
+ { SYF_MPSAFE | AS(getpriority_args), (sy_call_t *)getpriority }, /* 96 = getpriority */
+ { SYF_MPSAFE | AS(setpriority_args), (sy_call_t *)setpriority }, /* 97 = setpriority */
+ { 0, (sy_call_t *)nosys }, /* 98 = profil */
+ { AS(linux_statfs_args), (sy_call_t *)linux_statfs }, /* 99 = linux_statfs */
+ { AS(linux_fstatfs_args), (sy_call_t *)linux_fstatfs }, /* 100 = linux_fstatfs */
+ { 0, (sy_call_t *)nosys }, /* 101 = ioperm */
+ { AS(linux_socketcall_args), (sy_call_t *)linux_socketcall }, /* 102 = linux_socketcall */
+ { AS(linux_syslog_args), (sy_call_t *)linux_syslog }, /* 103 = linux_syslog */
+ { AS(linux_setitimer_args), (sy_call_t *)linux_setitimer }, /* 104 = linux_setitimer */
+ { AS(linux_getitimer_args), (sy_call_t *)linux_getitimer }, /* 105 = linux_getitimer */
+ { AS(linux_newstat_args), (sy_call_t *)linux_newstat }, /* 106 = linux_newstat */
+ { AS(linux_newlstat_args), (sy_call_t *)linux_newlstat }, /* 107 = linux_newlstat */
+ { AS(linux_newfstat_args), (sy_call_t *)linux_newfstat }, /* 108 = linux_newfstat */
+ { 0, (sy_call_t *)linux_uname }, /* 109 = linux_uname */
+ { 0, (sy_call_t *)nosys }, /* 110 = iopl */
+ { 0, (sy_call_t *)linux_vhangup }, /* 111 = linux_vhangup */
+ { 0, (sy_call_t *)nosys }, /* 112 = idle */
+ { 0, (sy_call_t *)nosys }, /* 113 = vm86old */
+ { SYF_MPSAFE | AS(linux_wait4_args), (sy_call_t *)linux_wait4 }, /* 114 = linux_wait4 */
+ { 0, (sy_call_t *)linux_swapoff }, /* 115 = linux_swapoff */
+ { AS(linux_sysinfo_args), (sy_call_t *)linux_sysinfo }, /* 116 = linux_sysinfo */
+ { AS(linux_ipc_args), (sy_call_t *)linux_ipc }, /* 117 = linux_ipc */
+ { AS(fsync_args), (sy_call_t *)fsync }, /* 118 = fsync */
+ { SYF_MPSAFE | AS(linux_sigreturn_args), (sy_call_t *)linux_sigreturn }, /* 119 = linux_sigreturn */
+ { SYF_MPSAFE | AS(linux_clone_args), (sy_call_t *)linux_clone }, /* 120 = linux_clone */
+ { SYF_MPSAFE | AS(setdomainname_args), (sy_call_t *)setdomainname }, /* 121 = setdomainname */
+ { AS(linux_newuname_args), (sy_call_t *)linux_newuname }, /* 122 = linux_newuname */
+ { 0, (sy_call_t *)nosys }, /* 123 = modify_ldt */
+ { 0, (sy_call_t *)linux_adjtimex }, /* 124 = linux_adjtimex */
+ { SYF_MPSAFE | AS(linux_mprotect_args), (sy_call_t *)linux_mprotect }, /* 125 = linux_mprotect */
+ { SYF_MPSAFE | AS(linux_sigprocmask_args), (sy_call_t *)linux_sigprocmask }, /* 126 = linux_sigprocmask */
+ { 0, (sy_call_t *)linux_create_module }, /* 127 = linux_create_module */
+ { 0, (sy_call_t *)linux_init_module }, /* 128 = linux_init_module */
+ { 0, (sy_call_t *)linux_delete_module }, /* 129 = linux_delete_module */
+ { 0, (sy_call_t *)linux_get_kernel_syms }, /* 130 = linux_get_kernel_syms */
+ { 0, (sy_call_t *)linux_quotactl }, /* 131 = linux_quotactl */
+ { AS(getpgid_args), (sy_call_t *)getpgid }, /* 132 = getpgid */
+ { AS(fchdir_args), (sy_call_t *)fchdir }, /* 133 = fchdir */
+ { 0, (sy_call_t *)linux_bdflush }, /* 134 = linux_bdflush */
+ { AS(linux_sysfs_args), (sy_call_t *)linux_sysfs }, /* 135 = linux_sysfs */
+ { AS(linux_personality_args), (sy_call_t *)linux_personality }, /* 136 = linux_personality */
+ { 0, (sy_call_t *)nosys }, /* 137 = afs_syscall */
+ { AS(linux_setfsuid16_args), (sy_call_t *)linux_setfsuid16 }, /* 138 = linux_setfsuid16 */
+ { AS(linux_setfsgid16_args), (sy_call_t *)linux_setfsgid16 }, /* 139 = linux_setfsgid16 */
+ { AS(linux_llseek_args), (sy_call_t *)linux_llseek }, /* 140 = linux_llseek */
+ { AS(linux_getdents_args), (sy_call_t *)linux_getdents }, /* 141 = linux_getdents */
+ { AS(linux_select_args), (sy_call_t *)linux_select }, /* 142 = linux_select */
+ { AS(flock_args), (sy_call_t *)flock }, /* 143 = flock */
+ { AS(linux_msync_args), (sy_call_t *)linux_msync }, /* 144 = linux_msync */
+ { AS(linux_readv_args), (sy_call_t *)linux_readv }, /* 145 = linux_readv */
+ { AS(linux_writev_args), (sy_call_t *)linux_writev }, /* 146 = linux_writev */
+ { SYF_MPSAFE | AS(linux_getsid_args), (sy_call_t *)linux_getsid }, /* 147 = linux_getsid */
+ { AS(linux_fdatasync_args), (sy_call_t *)linux_fdatasync }, /* 148 = linux_fdatasync */
+ { AS(linux_sysctl_args), (sy_call_t *)linux_sysctl }, /* 149 = linux_sysctl */
+ { SYF_MPSAFE | AS(mlock_args), (sy_call_t *)mlock }, /* 150 = mlock */
+ { SYF_MPSAFE | AS(munlock_args), (sy_call_t *)munlock }, /* 151 = munlock */
+ { SYF_MPSAFE | AS(mlockall_args), (sy_call_t *)mlockall }, /* 152 = mlockall */
+ { SYF_MPSAFE | 0, (sy_call_t *)munlockall }, /* 153 = munlockall */
+ { SYF_MPSAFE | AS(sched_setparam_args), (sy_call_t *)sched_setparam }, /* 154 = sched_setparam */
+ { SYF_MPSAFE | AS(sched_getparam_args), (sy_call_t *)sched_getparam }, /* 155 = sched_getparam */
+ { SYF_MPSAFE | AS(linux_sched_setscheduler_args), (sy_call_t *)linux_sched_setscheduler }, /* 156 = linux_sched_setscheduler */
+ { SYF_MPSAFE | AS(linux_sched_getscheduler_args), (sy_call_t *)linux_sched_getscheduler }, /* 157 = linux_sched_getscheduler */
+ { 0, (sy_call_t *)sched_yield }, /* 158 = sched_yield */
+ { SYF_MPSAFE | AS(linux_sched_get_priority_max_args), (sy_call_t *)linux_sched_get_priority_max }, /* 159 = linux_sched_get_priority_max */
+ { SYF_MPSAFE | AS(linux_sched_get_priority_min_args), (sy_call_t *)linux_sched_get_priority_min }, /* 160 = linux_sched_get_priority_min */
+ { SYF_MPSAFE | AS(linux_sched_rr_get_interval_args), (sy_call_t *)linux_sched_rr_get_interval }, /* 161 = linux_sched_rr_get_interval */
+ { SYF_MPSAFE | AS(linux_nanosleep_args), (sy_call_t *)linux_nanosleep }, /* 162 = linux_nanosleep */
+ { AS(linux_mremap_args), (sy_call_t *)linux_mremap }, /* 163 = linux_mremap */
+ { SYF_MPSAFE | AS(linux_setresuid16_args), (sy_call_t *)linux_setresuid16 }, /* 164 = linux_setresuid16 */
+ { SYF_MPSAFE | AS(linux_getresuid16_args), (sy_call_t *)linux_getresuid16 }, /* 165 = linux_getresuid16 */
+ { 0, (sy_call_t *)nosys }, /* 166 = vm86 */
+ { 0, (sy_call_t *)linux_query_module }, /* 167 = linux_query_module */
+ { AS(poll_args), (sy_call_t *)poll }, /* 168 = poll */
+ { 0, (sy_call_t *)linux_nfsservctl }, /* 169 = linux_nfsservctl */
+ { SYF_MPSAFE | AS(linux_setresgid16_args), (sy_call_t *)linux_setresgid16 }, /* 170 = linux_setresgid16 */
+ { SYF_MPSAFE | AS(linux_getresgid16_args), (sy_call_t *)linux_getresgid16 }, /* 171 = linux_getresgid16 */
+ { 0, (sy_call_t *)linux_prctl }, /* 172 = linux_prctl */
+ { AS(linux_rt_sigreturn_args), (sy_call_t *)linux_rt_sigreturn }, /* 173 = linux_rt_sigreturn */
+ { SYF_MPSAFE | AS(linux_rt_sigaction_args), (sy_call_t *)linux_rt_sigaction }, /* 174 = linux_rt_sigaction */
+ { SYF_MPSAFE | AS(linux_rt_sigprocmask_args), (sy_call_t *)linux_rt_sigprocmask }, /* 175 = linux_rt_sigprocmask */
+ { 0, (sy_call_t *)linux_rt_sigpending }, /* 176 = linux_rt_sigpending */
+ { 0, (sy_call_t *)linux_rt_sigtimedwait }, /* 177 = linux_rt_sigtimedwait */
+ { 0, (sy_call_t *)linux_rt_sigqueueinfo }, /* 178 = linux_rt_sigqueueinfo */
+ { SYF_MPSAFE | AS(linux_rt_sigsuspend_args), (sy_call_t *)linux_rt_sigsuspend }, /* 179 = linux_rt_sigsuspend */
+ { AS(linux_pread_args), (sy_call_t *)linux_pread }, /* 180 = linux_pread */
+ { AS(linux_pwrite_args), (sy_call_t *)linux_pwrite }, /* 181 = linux_pwrite */
+ { AS(linux_chown16_args), (sy_call_t *)linux_chown16 }, /* 182 = linux_chown16 */
+ { AS(linux_getcwd_args), (sy_call_t *)linux_getcwd }, /* 183 = linux_getcwd */
+ { 0, (sy_call_t *)linux_capget }, /* 184 = linux_capget */
+ { 0, (sy_call_t *)linux_capset }, /* 185 = linux_capset */
+ { AS(linux_sigaltstack_args), (sy_call_t *)linux_sigaltstack }, /* 186 = linux_sigaltstack */
+ { 0, (sy_call_t *)linux_sendfile }, /* 187 = linux_sendfile */
+ { 0, (sy_call_t *)nosys }, /* 188 = getpmsg */
+ { 0, (sy_call_t *)nosys }, /* 189 = putpmsg */
+ { SYF_MPSAFE | 0, (sy_call_t *)linux_vfork }, /* 190 = linux_vfork */
+ { SYF_MPSAFE | AS(linux_getrlimit_args), (sy_call_t *)linux_getrlimit }, /* 191 = linux_getrlimit */
+ { AS(linux_mmap2_args), (sy_call_t *)linux_mmap2 }, /* 192 = linux_mmap2 */
+ { AS(linux_truncate64_args), (sy_call_t *)linux_truncate64 }, /* 193 = linux_truncate64 */
+ { AS(linux_ftruncate64_args), (sy_call_t *)linux_ftruncate64 }, /* 194 = linux_ftruncate64 */
+ { AS(linux_stat64_args), (sy_call_t *)linux_stat64 }, /* 195 = linux_stat64 */
+ { AS(linux_lstat64_args), (sy_call_t *)linux_lstat64 }, /* 196 = linux_lstat64 */
+ { AS(linux_fstat64_args), (sy_call_t *)linux_fstat64 }, /* 197 = linux_fstat64 */
+ { AS(linux_lchown_args), (sy_call_t *)linux_lchown }, /* 198 = linux_lchown */
+ { SYF_MPSAFE | 0, (sy_call_t *)linux_getuid }, /* 199 = linux_getuid */
+ { SYF_MPSAFE | 0, (sy_call_t *)linux_getgid }, /* 200 = linux_getgid */
+ { SYF_MPSAFE | 0, (sy_call_t *)geteuid }, /* 201 = geteuid */
+ { SYF_MPSAFE | 0, (sy_call_t *)getegid }, /* 202 = getegid */
+ { SYF_MPSAFE | AS(setreuid_args), (sy_call_t *)setreuid }, /* 203 = setreuid */
+ { SYF_MPSAFE | AS(setregid_args), (sy_call_t *)setregid }, /* 204 = setregid */
+ { SYF_MPSAFE | AS(linux_getgroups_args), (sy_call_t *)linux_getgroups }, /* 205 = linux_getgroups */
+ { SYF_MPSAFE | AS(linux_setgroups_args), (sy_call_t *)linux_setgroups }, /* 206 = linux_setgroups */
+ { AS(fchown_args), (sy_call_t *)fchown }, /* 207 = fchown */
+ { SYF_MPSAFE | AS(setresuid_args), (sy_call_t *)setresuid }, /* 208 = setresuid */
+ { SYF_MPSAFE | AS(getresuid_args), (sy_call_t *)getresuid }, /* 209 = getresuid */
+ { SYF_MPSAFE | AS(setresgid_args), (sy_call_t *)setresgid }, /* 210 = setresgid */
+ { SYF_MPSAFE | AS(getresgid_args), (sy_call_t *)getresgid }, /* 211 = getresgid */
+ { AS(linux_chown_args), (sy_call_t *)linux_chown }, /* 212 = linux_chown */
+ { SYF_MPSAFE | AS(setuid_args), (sy_call_t *)setuid }, /* 213 = setuid */
+ { SYF_MPSAFE | AS(setgid_args), (sy_call_t *)setgid }, /* 214 = setgid */
+ { AS(linux_setfsuid_args), (sy_call_t *)linux_setfsuid }, /* 215 = linux_setfsuid */
+ { AS(linux_setfsgid_args), (sy_call_t *)linux_setfsgid }, /* 216 = linux_setfsgid */
+ { AS(linux_pivot_root_args), (sy_call_t *)linux_pivot_root }, /* 217 = linux_pivot_root */
+ { AS(linux_mincore_args), (sy_call_t *)linux_mincore }, /* 218 = linux_mincore */
+ { SYF_MPSAFE | AS(madvise_args), (sy_call_t *)madvise }, /* 219 = madvise */
+ { AS(linux_getdents64_args), (sy_call_t *)linux_getdents64 }, /* 220 = linux_getdents64 */
+ { AS(linux_fcntl64_args), (sy_call_t *)linux_fcntl64 }, /* 221 = linux_fcntl64 */
+ { 0, (sy_call_t *)nosys }, /* 222 = */
+ { 0, (sy_call_t *)nosys }, /* 223 = */
+ { SYF_MPSAFE | 0, (sy_call_t *)linux_getpid }, /* 224 = gettid */
+ { 0, (sy_call_t *)nosys }, /* 225 = linux_readahead */
+ { 0, (sy_call_t *)linux_setxattr }, /* 226 = linux_setxattr */
+ { 0, (sy_call_t *)linux_lsetxattr }, /* 227 = linux_lsetxattr */
+ { 0, (sy_call_t *)linux_fsetxattr }, /* 228 = linux_fsetxattr */
+ { 0, (sy_call_t *)linux_getxattr }, /* 229 = linux_getxattr */
+ { 0, (sy_call_t *)linux_lgetxattr }, /* 230 = linux_lgetxattr */
+ { 0, (sy_call_t *)linux_fgetxattr }, /* 231 = linux_fgetxattr */
+ { 0, (sy_call_t *)linux_listxattr }, /* 232 = linux_listxattr */
+ { 0, (sy_call_t *)linux_llistxattr }, /* 233 = linux_llistxattr */
+ { 0, (sy_call_t *)linux_flistxattr }, /* 234 = linux_flistxattr */
+ { 0, (sy_call_t *)linux_removexattr }, /* 235 = linux_removexattr */
+ { 0, (sy_call_t *)linux_lremovexattr }, /* 236 = linux_lremovexattr */
+ { 0, (sy_call_t *)linux_fremovexattr }, /* 237 = linux_fremovexattr */
+ { 0, (sy_call_t *)nosys }, /* 238 = linux_tkill */
+ { 0, (sy_call_t *)nosys }, /* 239 = linux_sendfile64 */
+ { 0, (sy_call_t *)nosys }, /* 240 = linux_futex */
+ { 0, (sy_call_t *)nosys }, /* 241 = linux_sched_setaffinity */
+ { 0, (sy_call_t *)nosys }, /* 242 = linux_sched_getaffinity */
+ { 0, (sy_call_t *)nosys }, /* 243 = linux_set_thread_area */
+ { 0, (sy_call_t *)nosys }, /* 244 = linux_get_thread_area */
+ { 0, (sy_call_t *)nosys }, /* 245 = linux_io_setup */
+ { 0, (sy_call_t *)nosys }, /* 246 = linux_io_destroy */
+ { 0, (sy_call_t *)nosys }, /* 247 = linux_io_getevents */
+ { 0, (sy_call_t *)nosys }, /* 248 = linux_io_submit */
+ { 0, (sy_call_t *)nosys }, /* 249 = linux_io_cancel */
+ { 0, (sy_call_t *)linux_fadvise64 }, /* 250 = linux_fadvise64 */
+ { 0, (sy_call_t *)nosys }, /* 251 = */
+ { SYF_MPSAFE | AS(sys_exit_args), (sy_call_t *)sys_exit }, /* 252 = exit_group */
+ { 0, (sy_call_t *)nosys }, /* 253 = linux_lookup_dcookie */
+ { 0, (sy_call_t *)nosys }, /* 254 = linux_epoll_create */
+ { 0, (sy_call_t *)nosys }, /* 255 = linux_epoll_ctl */
+ { 0, (sy_call_t *)nosys }, /* 256 = linux_epoll_wait */
+ { 0, (sy_call_t *)nosys }, /* 257 = linux_remap_file_pages */
+ { 0, (sy_call_t *)nosys }, /* 258 = linux_set_tid_address */
+ { 0, (sy_call_t *)nosys }, /* 259 = linux_timer_create */
+ { 0, (sy_call_t *)nosys }, /* 260 = linux_timer_settime */
+ { 0, (sy_call_t *)nosys }, /* 261 = linux_timer_gettime */
+ { 0, (sy_call_t *)nosys }, /* 262 = linux_timer_getoverrun */
+ { 0, (sy_call_t *)nosys }, /* 263 = linux_timer_delete */
+ { 0, (sy_call_t *)nosys }, /* 264 = linux_clock_settime */
+ { 0, (sy_call_t *)nosys }, /* 265 = linux_clock_gettime */
+ { 0, (sy_call_t *)nosys }, /* 266 = linux_clock_getres */
+ { 0, (sy_call_t *)nosys }, /* 267 = linux_clock_nanosleep */
+};
diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c
new file mode 100644
index 000000000000..aec316cc9b32
--- /dev/null
+++ b/sys/amd64/linux32/linux32_sysvec.c
@@ -0,0 +1,1088 @@
+/*-
+ * Copyright (c) 2004 Tim J. Robbins
+ * Copyright (c) 2003 Peter Wemm
+ * Copyright (c) 2002 Doug Rabson
+ * Copyright (c) 1998-1999 Andrew Gallatin
+ * Copyright (c) 1994-1996 Søren Schmidt
+ * All rights reserved.
+ *
+ * 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
+ * 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
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+/* XXX we use functions that might not exist. */
+#include "opt_compat.h"
+#include "opt_ia32.h"
+
+#ifndef COMPAT_43
+#error "Unable to compile Linux-emulator due to missing COMPAT_43 option!"
+#endif
+#ifndef IA32
+#error "Unable to compile Linux-emulator due to missing IA32 option!"
+#endif
+
+#define __ELF_WORD_SIZE 32
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/exec.h>
+#include <sys/imgact.h>
+#include <sys/imgact_elf.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/malloc.h>
+#include <sys/module.h>
+#include <sys/mutex.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/sysctl.h>
+#include <sys/syscallsubr.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
+#include <sys/user.h>
+#include <sys/vnode.h>
+
+#include <vm/vm.h>
+#include <vm/pmap.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_map.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_param.h>
+
+#include <machine/cpu.h>
+#include <machine/md_var.h>
+#include <machine/specialreg.h>
+
+#include <amd64/linux32/linux.h>
+#include <amd64/linux32/linux32_proto.h>
+#include <compat/linux/linux_mib.h>
+#include <compat/linux/linux_signal.h>
+#include <compat/linux/linux_util.h>
+
+MODULE_VERSION(linux, 1);
+MODULE_DEPEND(linux, sysvmsg, 1, 1, 1);
+MODULE_DEPEND(linux, sysvsem, 1, 1, 1);
+MODULE_DEPEND(linux, sysvshm, 1, 1, 1);
+
+MALLOC_DEFINE(M_LINUX, "linux", "Linux mode structures");
+
+#define AUXARGS_ENTRY_32(pos, id, val) \
+ do { \
+ suword32(pos++, id); \
+ suword32(pos++, val); \
+ } while (0)
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#define SHELLMAGIC 0x2123 /* #! */
+#else
+#define SHELLMAGIC 0x2321
+#endif
+
+/*
+ * Allow the sendsig functions to use the ldebug() facility
+ * even though they are not syscalls themselves. Map them
+ * to syscall 0. This is slightly less bogus than using
+ * ldebug(sigreturn).
+ */
+#define LINUX_SYS_linux_rt_sendsig 0
+#define LINUX_SYS_linux_sendsig 0
+
+extern char linux_sigcode[];
+extern int linux_szsigcode;
+
+extern struct sysent linux_sysent[LINUX_SYS_MAXSYSCALL];
+
+SET_DECLARE(linux_ioctl_handler_set, struct linux_ioctl_handler);
+
+static int elf_linux_fixup(register_t **stack_base,
+ struct image_params *iparams);
+static register_t *linux_copyout_strings(struct image_params *imgp);
+static void linux_prepsyscall(struct trapframe *tf, int *args, u_int *code,
+ caddr_t *params);
+static void linux_sendsig(sig_t catcher, int sig, sigset_t *mask,
+ u_long code);
+static void exec_linux_setregs(struct thread *td, u_long entry,
+ u_long stack, u_long ps_strings);
+static void linux32_fixlimits(struct image_params *imgp);
+
+/*
+ * Linux syscalls return negative errno's, we do positive and map them
+ */
+static int bsd_to_linux_errno[ELAST + 1] = {
+ -0, -1, -2, -3, -4, -5, -6, -7, -8, -9,
+ -10, -35, -12, -13, -14, -15, -16, -17, -18, -19,
+ -20, -21, -22, -23, -24, -25, -26, -27, -28, -29,
+ -30, -31, -32, -33, -34, -11,-115,-114, -88, -89,
+ -90, -91, -92, -93, -94, -95, -96, -97, -98, -99,
+ -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
+};
+
+int bsd_to_linux_signal[LINUX_SIGTBLSZ] = {
+ LINUX_SIGHUP, LINUX_SIGINT, LINUX_SIGQUIT, LINUX_SIGILL,
+ LINUX_SIGTRAP, LINUX_SIGABRT, 0, LINUX_SIGFPE,
+ LINUX_SIGKILL, LINUX_SIGBUS, LINUX_SIGSEGV, LINUX_SIGSYS,
+ LINUX_SIGPIPE, LINUX_SIGALRM, LINUX_SIGTERM, LINUX_SIGURG,
+ LINUX_SIGSTOP, LINUX_SIGTSTP, LINUX_SIGCONT, LINUX_SIGCHLD,
+ LINUX_SIGTTIN, LINUX_SIGTTOU, LINUX_SIGIO, LINUX_SIGXCPU,
+ LINUX_SIGXFSZ, LINUX_SIGVTALRM, LINUX_SIGPROF, LINUX_SIGWINCH,
+ 0, LINUX_SIGUSR1, LINUX_SIGUSR2
+};
+
+int linux_to_bsd_signal[LINUX_SIGTBLSZ] = {
+ SIGHUP, SIGINT, SIGQUIT, SIGILL,
+ SIGTRAP, SIGABRT, SIGBUS, SIGFPE,
+ SIGKILL, SIGUSR1, SIGSEGV, SIGUSR2,
+ SIGPIPE, SIGALRM, SIGTERM, SIGBUS,
+ SIGCHLD, SIGCONT, SIGSTOP, SIGTSTP,
+ SIGTTIN, SIGTTOU, SIGURG, SIGXCPU,
+ SIGXFSZ, SIGVTALRM, SIGPROF, SIGWINCH,
+ SIGIO, SIGURG, SIGSYS
+};
+
+#define LINUX_T_UNKNOWN 255
+static int _bsd_to_linux_trapcode[] = {
+ LINUX_T_UNKNOWN, /* 0 */
+ 6, /* 1 T_PRIVINFLT */
+ LINUX_T_UNKNOWN, /* 2 */
+ 3, /* 3 T_BPTFLT */
+ LINUX_T_UNKNOWN, /* 4 */
+ LINUX_T_UNKNOWN, /* 5 */
+ 16, /* 6 T_ARITHTRAP */
+ 254, /* 7 T_ASTFLT */
+ LINUX_T_UNKNOWN, /* 8 */
+ 13, /* 9 T_PROTFLT */
+ 1, /* 10 T_TRCTRAP */
+ LINUX_T_UNKNOWN, /* 11 */
+ 14, /* 12 T_PAGEFLT */
+ LINUX_T_UNKNOWN, /* 13 */
+ 17, /* 14 T_ALIGNFLT */
+ LINUX_T_UNKNOWN, /* 15 */
+ LINUX_T_UNKNOWN, /* 16 */
+ LINUX_T_UNKNOWN, /* 17 */
+ 0, /* 18 T_DIVIDE */
+ 2, /* 19 T_NMI */
+ 4, /* 20 T_OFLOW */
+ 5, /* 21 T_BOUND */
+ 7, /* 22 T_DNA */
+ 8, /* 23 T_DOUBLEFLT */
+ 9, /* 24 T_FPOPFLT */
+ 10, /* 25 T_TSSFLT */
+ 11, /* 26 T_SEGNPFLT */
+ 12, /* 27 T_STKFLT */
+ 18, /* 28 T_MCHK */
+ 19, /* 29 T_XMMFLT */
+ 15 /* 30 T_RESERVED */
+};
+#define bsd_to_linux_trapcode(code) \
+ ((code)<sizeof(_bsd_to_linux_trapcode)/sizeof(*_bsd_to_linux_trapcode)? \
+ _bsd_to_linux_trapcode[(code)]: \
+ LINUX_T_UNKNOWN)
+
+struct linux32_ps_strings {
+ u_int32_t ps_argvstr; /* first of 0 or more argument strings */
+ int ps_nargvstr; /* the number of argument strings */
+ u_int32_t ps_envstr; /* first of 0 or more environment strings */
+ int ps_nenvstr; /* the number of environment strings */
+};
+
+/*
+ * If FreeBSD & Linux have a difference of opinion about what a trap
+ * means, deal with it here.
+ *
+ * MPSAFE
+ */
+static int
+translate_traps(int signal, int trap_code)
+{
+ if (signal != SIGBUS)
+ return signal;
+ switch (trap_code) {
+ case T_PROTFLT:
+ case T_TSSFLT:
+ case T_DOUBLEFLT:
+ case T_PAGEFLT:
+ return SIGSEGV;
+ default:
+ return signal;
+ }
+}
+
+static int
+elf_linux_fixup(register_t **stack_base, struct image_params *imgp)
+{
+ Elf32_Auxargs *args;
+ Elf32_Addr *base;
+ Elf32_Addr *pos;
+
+ KASSERT(curthread->td_proc == imgp->proc &&
+ (curthread->td_proc->p_flag & P_SA) == 0,
+ ("unsafe elf_linux_fixup(), should be curproc"));
+ base = (Elf32_Addr *)*stack_base;
+ args = (Elf32_Auxargs *)imgp->auxargs;
+ pos = base + (imgp->argc + imgp->envc + 2);
+
+ if (args->trace)
+ AUXARGS_ENTRY_32(pos, AT_DEBUG, 1);
+ if (args->execfd != -1)
+ AUXARGS_ENTRY_32(pos, AT_EXECFD, args->execfd);
+ AUXARGS_ENTRY_32(pos, AT_PHDR, args->phdr);
+ AUXARGS_ENTRY_32(pos, AT_PHENT, args->phent);
+ AUXARGS_ENTRY_32(pos, AT_PHNUM, args->phnum);
+ AUXARGS_ENTRY_32(pos, AT_PAGESZ, args->pagesz);
+ AUXARGS_ENTRY_32(pos, AT_FLAGS, args->flags);
+ AUXARGS_ENTRY_32(pos, AT_ENTRY, args->entry);
+ AUXARGS_ENTRY_32(pos, AT_BASE, args->base);
+ AUXARGS_ENTRY_32(pos, AT_UID, imgp->proc->p_ucred->cr_ruid);
+ AUXARGS_ENTRY_32(pos, AT_EUID, imgp->proc->p_ucred->cr_svuid);
+ AUXARGS_ENTRY_32(pos, AT_GID, imgp->proc->p_ucred->cr_rgid);
+ AUXARGS_ENTRY_32(pos, AT_EGID, imgp->proc->p_ucred->cr_svgid);
+ AUXARGS_ENTRY_32(pos, AT_NULL, 0);
+
+ free(imgp->auxargs, M_TEMP);
+ imgp->auxargs = NULL;
+
+ base--;
+ suword32(base, (uint32_t)imgp->argc);
+ *stack_base = (register_t *)base;
+ return 0;
+}
+
+extern int _ucodesel, _ucode32sel, _udatasel;
+extern unsigned long linux_sznonrtsigcode;
+
+static void
+linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+{
+ struct thread *td = curthread;
+ struct proc *p = td->td_proc;
+ struct sigacts *psp;
+ struct trapframe *regs;
+ struct l_rt_sigframe *fp, frame;
+ int oonstack;
+
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ psp = p->p_sigacts;
+ mtx_assert(&psp->ps_mtx, MA_OWNED);
+ regs = td->td_frame;
+ oonstack = sigonstack(regs->tf_rsp);
+
+#ifdef DEBUG
+ if (ldebug(rt_sendsig))
+ printf(ARGS(rt_sendsig, "%p, %d, %p, %lu"),
+ catcher, sig, (void*)mask, code);
+#endif
+ /*
+ * Allocate space for the signal handler context.
+ */
+ if ((td->td_pflags & TDP_ALTSTACK) && !oonstack &&
+ SIGISMEMBER(psp->ps_sigonstack, sig)) {
+ fp = (struct l_rt_sigframe *)(td->td_sigstk.ss_sp +
+ td->td_sigstk.ss_size - sizeof(struct l_rt_sigframe));
+ } else
+ fp = (struct l_rt_sigframe *)regs->tf_rsp - 1;
+ mtx_unlock(&psp->ps_mtx);
+
+ /*
+ * Build the argument list for the signal handler.
+ */
+ if (p->p_sysent->sv_sigtbl)
+ if (sig <= p->p_sysent->sv_sigsize)
+ sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
+
+ bzero(&frame, sizeof(frame));
+
+ frame.sf_handler = PTROUT(catcher);
+ frame.sf_sig = sig;
+ frame.sf_siginfo = PTROUT(&fp->sf_si);
+ frame.sf_ucontext = PTROUT(&fp->sf_sc);
+
+ /* Fill in POSIX parts */
+ frame.sf_si.lsi_signo = sig;
+ frame.sf_si.lsi_code = code;
+ frame.sf_si.lsi_addr = PTROUT(regs->tf_err);
+
+ /*
+ * Build the signal context to be used by sigreturn.
+ */
+ frame.sf_sc.uc_flags = 0; /* XXX ??? */
+ frame.sf_sc.uc_link = 0; /* XXX ??? */
+
+ frame.sf_sc.uc_stack.ss_sp = PTROUT(td->td_sigstk.ss_sp);
+ frame.sf_sc.uc_stack.ss_size = td->td_sigstk.ss_size;
+ frame.sf_sc.uc_stack.ss_flags = (td->td_pflags & TDP_ALTSTACK)
+ ? ((oonstack) ? LINUX_SS_ONSTACK : 0) : LINUX_SS_DISABLE;
+ PROC_UNLOCK(p);
+
+ bsd_to_linux_sigset(mask, &frame.sf_sc.uc_sigmask);
+
+ frame.sf_sc.uc_mcontext.sc_mask = frame.sf_sc.uc_sigmask.__bits[0];
+ frame.sf_sc.uc_mcontext.sc_gs = rgs();
+ frame.sf_sc.uc_mcontext.sc_fs = rfs();
+ __asm __volatile("movl %%es,%0" :
+ "=rm" (frame.sf_sc.uc_mcontext.sc_es));
+ __asm __volatile("movl %%ds,%0" :
+ "=rm" (frame.sf_sc.uc_mcontext.sc_ds));
+ frame.sf_sc.uc_mcontext.sc_edi = regs->tf_rdi;
+ frame.sf_sc.uc_mcontext.sc_esi = regs->tf_rsi;
+ frame.sf_sc.uc_mcontext.sc_ebp = regs->tf_rbp;
+ frame.sf_sc.uc_mcontext.sc_ebx = regs->tf_rbx;
+ frame.sf_sc.uc_mcontext.sc_edx = regs->tf_rdx;
+ frame.sf_sc.uc_mcontext.sc_ecx = regs->tf_rcx;
+ frame.sf_sc.uc_mcontext.sc_eax = regs->tf_rax;
+ frame.sf_sc.uc_mcontext.sc_eip = regs->tf_rip;
+ frame.sf_sc.uc_mcontext.sc_cs = regs->tf_cs;
+ frame.sf_sc.uc_mcontext.sc_eflags = regs->tf_rflags;
+ frame.sf_sc.uc_mcontext.sc_esp_at_signal = regs->tf_rsp;
+ frame.sf_sc.uc_mcontext.sc_ss = regs->tf_ss;
+ frame.sf_sc.uc_mcontext.sc_err = regs->tf_err;
+ frame.sf_sc.uc_mcontext.sc_trapno = bsd_to_linux_trapcode(code);
+
+#ifdef DEBUG
+ if (ldebug(rt_sendsig))
+ printf(LMSG("rt_sendsig flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x"),
+ frame.sf_sc.uc_stack.ss_flags, td->td_sigstk.ss_sp,
+ td->td_sigstk.ss_size, frame.sf_sc.uc_mcontext.sc_mask);
+#endif
+
+ if (copyout(&frame, fp, sizeof(frame)) != 0) {
+ /*
+ * Process has trashed its stack; give it an illegal
+ * instruction to halt it in its tracks.
+ */
+#ifdef DEBUG
+ if (ldebug(rt_sendsig))
+ printf(LMSG("rt_sendsig: bad stack %p, oonstack=%x"),
+ fp, oonstack);
+#endif
+ PROC_LOCK(p);
+ sigexit(td, SIGILL);
+ }
+
+ /*
+ * Build context to run handler in.
+ */
+ regs->tf_rsp = PTROUT(fp);
+ regs->tf_rip = LINUX32_PS_STRINGS - *(p->p_sysent->sv_szsigcode) +
+ linux_sznonrtsigcode;
+ regs->tf_rflags &= ~PSL_T;
+ regs->tf_cs = _ucode32sel;
+ regs->tf_ss = _udatasel;
+ load_ds(_udatasel);
+ td->td_pcb->pcb_ds = _udatasel;
+ load_es(_udatasel);
+ td->td_pcb->pcb_es = _udatasel;
+ PROC_LOCK(p);
+ mtx_lock(&psp->ps_mtx);
+}
+
+
+/*
+ * Send an interrupt to process.
+ *
+ * Stack is set up to allow sigcode stored
+ * in u. to call routine, followed by kcall
+ * to sigreturn routine below. After sigreturn
+ * resets the signal mask, the stack, and the
+ * frame pointer, it returns to the user
+ * specified pc, psl.
+ */
+static void
+linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
+{
+ struct thread *td = curthread;
+ struct proc *p = td->td_proc;
+ struct sigacts *psp;
+ struct trapframe *regs;
+ struct l_sigframe *fp, frame;
+ l_sigset_t lmask;
+ int oonstack, i;
+
+ PROC_LOCK_ASSERT(p, MA_OWNED);
+ psp = p->p_sigacts;
+ mtx_assert(&psp->ps_mtx, MA_OWNED);
+ if (SIGISMEMBER(psp->ps_siginfo, sig)) {
+ /* Signal handler installed with SA_SIGINFO. */
+ linux_rt_sendsig(catcher, sig, mask, code);
+ return;
+ }
+
+ regs = td->td_frame;
+ oonstack = sigonstack(regs->tf_rsp);
+
+#ifdef DEBUG
+ if (ldebug(sendsig))
+ printf(ARGS(sendsig, "%p, %d, %p, %lu"),
+ catcher, sig, (void*)mask, code);
+#endif
+
+ /*
+ * Allocate space for the signal handler context.
+ */
+ if ((td->td_pflags & TDP_ALTSTACK) && !oonstack &&
+ SIGISMEMBER(psp->ps_sigonstack, sig)) {
+ fp = (struct l_sigframe *)(td->td_sigstk.ss_sp +
+ td->td_sigstk.ss_size - sizeof(struct l_sigframe));
+ } else
+ fp = (struct l_sigframe *)regs->tf_rsp - 1;
+ mtx_unlock(&psp->ps_mtx);
+ PROC_UNLOCK(p);
+
+ /*
+ * Build the argument list for the signal handler.
+ */
+ if (p->p_sysent->sv_sigtbl)
+ if (sig <= p->p_sysent->sv_sigsize)
+ sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
+
+ bzero(&frame, sizeof(frame));
+
+ frame.sf_handler = PTROUT(catcher);
+ frame.sf_sig = sig;
+
+ bsd_to_linux_sigset(mask, &lmask);
+
+ /*
+ * Build the signal context to be used by sigreturn.
+ */
+ frame.sf_sc.sc_mask = lmask.__bits[0];
+ frame.sf_sc.sc_gs = rgs();
+ frame.sf_sc.sc_fs = rfs();
+ __asm __volatile("movl %%es,%0" : "=rm" (frame.sf_sc.sc_es));
+ __asm __volatile("movl %%ds,%0" : "=rm" (frame.sf_sc.sc_ds));
+ frame.sf_sc.sc_edi = regs->tf_rdi;
+ frame.sf_sc.sc_esi = regs->tf_rsi;
+ frame.sf_sc.sc_ebp = regs->tf_rbp;
+ frame.sf_sc.sc_ebx = regs->tf_rbx;
+ frame.sf_sc.sc_edx = regs->tf_rdx;
+ frame.sf_sc.sc_ecx = regs->tf_rcx;
+ frame.sf_sc.sc_eax = regs->tf_rax;
+ frame.sf_sc.sc_eip = regs->tf_rip;
+ frame.sf_sc.sc_cs = regs->tf_cs;
+ frame.sf_sc.sc_eflags = regs->tf_rflags;
+ frame.sf_sc.sc_esp_at_signal = regs->tf_rsp;
+ frame.sf_sc.sc_ss = regs->tf_ss;
+ frame.sf_sc.sc_err = regs->tf_err;
+ frame.sf_sc.sc_trapno = bsd_to_linux_trapcode(code);
+
+ for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
+ frame.sf_extramask[i] = lmask.__bits[i+1];
+
+ if (copyout(&frame, fp, sizeof(frame)) != 0) {
+ /*
+ * Process has trashed its stack; give it an illegal
+ * instruction to halt it in its tracks.
+ */
+ PROC_LOCK(p);
+ sigexit(td, SIGILL);
+ }
+
+ /*
+ * Build context to run handler in.
+ */
+ regs->tf_rsp = PTROUT(fp);
+ regs->tf_rip = LINUX32_PS_STRINGS - *(p->p_sysent->sv_szsigcode);
+ regs->tf_rflags &= ~PSL_T;
+ regs->tf_cs = _ucode32sel;
+ regs->tf_ss = _udatasel;
+ load_ds(_udatasel);
+ td->td_pcb->pcb_ds = _udatasel;
+ load_es(_udatasel);
+ td->td_pcb->pcb_es = _udatasel;
+ PROC_LOCK(p);
+ mtx_lock(&psp->ps_mtx);
+}
+
+/*
+ * System call to cleanup state after a signal
+ * has been taken. Reset signal mask and
+ * stack state from context left by sendsig (above).
+ * Return to previous pc and psl as specified by
+ * context left by sendsig. Check carefully to
+ * make sure that the user has not modified the
+ * psl to gain improper privileges or to cause
+ * a machine fault.
+ */
+int
+linux_sigreturn(struct thread *td, struct linux_sigreturn_args *args)
+{
+ struct proc *p = td->td_proc;
+ struct l_sigframe frame;
+ struct trapframe *regs;
+ l_sigset_t lmask;
+ int eflags, i;
+
+ regs = td->td_frame;
+
+#ifdef DEBUG
+ if (ldebug(sigreturn))
+ printf(ARGS(sigreturn, "%p"), (void *)args->sfp);
+#endif
+ /*
+ * The trampoline code hands us the sigframe.
+ * It is unsafe to keep track of it ourselves, in the event that a
+ * program jumps out of a signal handler.
+ */
+ if (copyin(args->sfp, &frame, sizeof(frame)) != 0)
+ return (EFAULT);
+
+ /*
+ * Check for security violations.
+ */
+#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
+ eflags = frame.sf_sc.sc_eflags;
+ /*
+ * XXX do allow users to change the privileged flag PSL_RF. The
+ * cpu sets PSL_RF in tf_eflags for faults. Debuggers should
+ * sometimes set it there too. tf_eflags is kept in the signal
+ * context during signal handling and there is no other place
+ * to remember it, so the PSL_RF bit may be corrupted by the
+ * signal handler without us knowing. Corruption of the PSL_RF
+ * bit at worst causes one more or one less debugger trap, so
+ * allowing it is fairly harmless.
+ */
+ if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF))
+ return(EINVAL);
+
+ /*
+ * Don't allow users to load a valid privileged %cs. Let the
+ * hardware check for invalid selectors, excess privilege in
+ * other selectors, invalid %eip's and invalid %esp's.
+ */
+#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
+ if (!CS_SECURE(frame.sf_sc.sc_cs)) {
+ trapsignal(td, SIGBUS, T_PROTFLT);
+ return(EINVAL);
+ }
+
+ lmask.__bits[0] = frame.sf_sc.sc_mask;
+ for (i = 0; i < (LINUX_NSIG_WORDS-1); i++)
+ lmask.__bits[i+1] = frame.sf_extramask[i];
+ PROC_LOCK(p);
+ linux_to_bsd_sigset(&lmask, &td->td_sigmask);
+ SIG_CANTMASK(td->td_sigmask);
+ signotify(td);
+ PROC_UNLOCK(p);
+
+ /*
+ * Restore signal context.
+ */
+ /* Selectors were restored by the trampoline. */
+ regs->tf_rdi = frame.sf_sc.sc_edi;
+ regs->tf_rsi = frame.sf_sc.sc_esi;
+ regs->tf_rbp = frame.sf_sc.sc_ebp;
+ regs->tf_rbx = frame.sf_sc.sc_ebx;
+ regs->tf_rdx = frame.sf_sc.sc_edx;
+ regs->tf_rcx = frame.sf_sc.sc_ecx;
+ regs->tf_rax = frame.sf_sc.sc_eax;
+ regs->tf_rip = frame.sf_sc.sc_eip;
+ regs->tf_cs = frame.sf_sc.sc_cs;
+ regs->tf_rflags = eflags;
+ regs->tf_rsp = frame.sf_sc.sc_esp_at_signal;
+ regs->tf_ss = frame.sf_sc.sc_ss;
+
+ return (EJUSTRETURN);
+}
+
+/*
+ * System call to cleanup state after a signal
+ * has been taken. Reset signal mask and
+ * stack state from context left by rt_sendsig (above).
+ * Return to previous pc and psl as specified by
+ * context left by sendsig. Check carefully to
+ * make sure that the user has not modified the
+ * psl to gain improper privileges or to cause
+ * a machine fault.
+ */
+int
+linux_rt_sigreturn(struct thread *td, struct linux_rt_sigreturn_args *args)
+{
+ struct proc *p = td->td_proc;
+ struct l_ucontext uc;
+ struct l_sigcontext *context;
+ l_stack_t *lss;
+ stack_t ss;
+ struct trapframe *regs;
+ int eflags;
+
+ regs = td->td_frame;
+
+#ifdef DEBUG
+ if (ldebug(rt_sigreturn))
+ printf(ARGS(rt_sigreturn, "%p"), (void *)args->ucp);
+#endif
+ /*
+ * The trampoline code hands us the ucontext.
+ * It is unsafe to keep track of it ourselves, in the event that a
+ * program jumps out of a signal handler.
+ */
+ if (copyin(args->ucp, &uc, sizeof(uc)) != 0)
+ return (EFAULT);
+
+ context = &uc.uc_mcontext;
+
+ /*
+ * Check for security violations.
+ */
+#define EFLAGS_SECURE(ef, oef) ((((ef) ^ (oef)) & ~PSL_USERCHANGE) == 0)
+ eflags = context->sc_eflags;
+ /*
+ * XXX do allow users to change the privileged flag PSL_RF. The
+ * cpu sets PSL_RF in tf_eflags for faults. Debuggers should
+ * sometimes set it there too. tf_eflags is kept in the signal
+ * context during signal handling and there is no other place
+ * to remember it, so the PSL_RF bit may be corrupted by the
+ * signal handler without us knowing. Corruption of the PSL_RF
+ * bit at worst causes one more or one less debugger trap, so
+ * allowing it is fairly harmless.
+ */
+ if (!EFLAGS_SECURE(eflags & ~PSL_RF, regs->tf_rflags & ~PSL_RF))
+ return(EINVAL);
+
+ /*
+ * Don't allow users to load a valid privileged %cs. Let the
+ * hardware check for invalid selectors, excess privilege in
+ * other selectors, invalid %eip's and invalid %esp's.
+ */
+#define CS_SECURE(cs) (ISPL(cs) == SEL_UPL)
+ if (!CS_SECURE(context->sc_cs)) {
+ trapsignal(td, SIGBUS, T_PROTFLT);
+ return(EINVAL);
+ }
+
+ PROC_LOCK(p);
+ linux_to_bsd_sigset(&uc.uc_sigmask, &td->td_sigmask);
+ SIG_CANTMASK(td->td_sigmask);
+ signotify(td);
+ PROC_UNLOCK(p);
+
+ /*
+ * Restore signal context
+ */
+ /* Selectors were restored by the trampoline. */
+ regs->tf_rdi = context->sc_edi;
+ regs->tf_rsi = context->sc_esi;
+ regs->tf_rbp = context->sc_ebp;
+ regs->tf_rbx = context->sc_ebx;
+ regs->tf_rdx = context->sc_edx;
+ regs->tf_rcx = context->sc_ecx;
+ regs->tf_rax = context->sc_eax;
+ regs->tf_rip = context->sc_eip;
+ regs->tf_cs = context->sc_cs;
+ regs->tf_rflags = eflags;
+ regs->tf_rsp = context->sc_esp_at_signal;
+ regs->tf_ss = context->sc_ss;
+
+ /*
+ * call sigaltstack & ignore results..
+ */
+ lss = &uc.uc_stack;
+ ss.ss_sp = PTRIN(lss->ss_sp);
+ ss.ss_size = lss->ss_size;
+ ss.ss_flags = linux_to_bsd_sigaltstack(lss->ss_flags);
+
+#ifdef DEBUG
+ if (ldebug(rt_sigreturn))
+ printf(LMSG("rt_sigret flags: 0x%x, sp: %p, ss: 0x%x, mask: 0x%x"),
+ ss.ss_flags, ss.ss_sp, ss.ss_size, context->sc_mask);
+#endif
+ (void)kern_sigaltstack(td, &ss, NULL);
+
+ return (EJUSTRETURN);
+}
+
+/*
+ * MPSAFE
+ */
+static void
+linux_prepsyscall(struct trapframe *tf, int *args, u_int *code, caddr_t *params)
+{
+ args[0] = tf->tf_rbx;
+ args[1] = tf->tf_rcx;
+ args[2] = tf->tf_rdx;
+ args[3] = tf->tf_rsi;
+ args[4] = tf->tf_rdi;
+ args[5] = tf->tf_rbp; /* Unconfirmed */
+ *params = NULL; /* no copyin */
+}
+
+/*
+ * If a linux binary is exec'ing something, try this image activator
+ * first. We override standard shell script execution in order to
+ * be able to modify the interpreter path. We only do this if a linux
+ * binary is doing the exec, so we do not create an EXEC module for it.
+ */
+static int exec_linux_imgact_try(struct image_params *iparams);
+
+static int
+exec_linux_imgact_try(struct image_params *imgp)
+{
+ const char *head = (const char *)imgp->image_header;
+ int error = -1;
+
+ /*
+ * The interpreter for shell scripts run from a linux binary needs
+ * to be located in /compat/linux if possible in order to recursively
+ * maintain linux path emulation.
+ */
+ if (((const short *)head)[0] == SHELLMAGIC) {
+ /*
+ * Run our normal shell image activator. If it succeeds attempt
+ * to use the alternate path for the interpreter. If an alternate
+ * path is found, use our stringspace to store it.
+ */
+ if ((error = exec_shell_imgact(imgp)) == 0) {
+ char *rpath = NULL;
+
+ linux_emul_find(FIRST_THREAD_IN_PROC(imgp->proc), NULL,
+ imgp->interpreter_name, &rpath, 0);
+ if (rpath != imgp->interpreter_name) {
+ int len = strlen(rpath) + 1;
+
+ if (len <= MAXSHELLCMDLEN) {
+ memcpy(imgp->interpreter_name, rpath, len);
+ }
+ free(rpath, M_TEMP);
+ }
+ }
+ }
+ return(error);
+}
+
+/*
+ * Clear registers on exec
+ * XXX copied from ia32_signal.c.
+ */
+static void
+exec_linux_setregs(td, entry, stack, ps_strings)
+ struct thread *td;
+ u_long entry;
+ u_long stack;
+ u_long ps_strings;
+{
+ struct trapframe *regs = td->td_frame;
+ struct pcb *pcb = td->td_pcb;
+
+ wrmsr(MSR_FSBASE, 0);
+ wrmsr(MSR_KGSBASE, 0); /* User value while we're in the kernel */
+ pcb->pcb_fsbase = 0;
+ pcb->pcb_gsbase = 0;
+ load_ds(_udatasel);
+ load_es(_udatasel);
+ load_fs(_udatasel);
+ load_gs(0);
+ pcb->pcb_ds = _udatasel;
+ pcb->pcb_es = _udatasel;
+ pcb->pcb_fs = _udatasel;
+ pcb->pcb_gs = 0;
+
+ bzero((char *)regs, sizeof(struct trapframe));
+ regs->tf_rip = entry;
+ regs->tf_rsp = stack;
+ regs->tf_rflags = PSL_USER | (regs->tf_rflags & PSL_T);
+ regs->tf_ss = _udatasel;
+ regs->tf_cs = _ucode32sel;
+ regs->tf_rbx = ps_strings;
+ load_cr0(rcr0() | CR0_MP | CR0_TS);
+
+ /* Return via doreti so that we can change to a different %cs */
+ pcb->pcb_flags |= PCB_FULLCTX;
+ td->td_retval[1] = 0;
+}
+
+/*
+ * XXX copied from ia32_sysvec.c.
+ */
+static register_t *
+linux_copyout_strings(struct image_params *imgp)
+{
+ int argc, envc;
+ u_int32_t *vectp;
+ char *stringp, *destp;
+ u_int32_t *stack_base;
+ struct linux32_ps_strings *arginfo;
+ int sigcodesz;
+
+ /*
+ * Calculate string base and vector table pointers.
+ * Also deal with signal trampoline code for this exec type.
+ */
+ arginfo = (struct linux32_ps_strings *)LINUX32_PS_STRINGS;
+ sigcodesz = *(imgp->proc->p_sysent->sv_szsigcode);
+ destp = (caddr_t)arginfo - sigcodesz - SPARE_USRSPACE -
+ roundup((ARG_MAX - imgp->stringspace), sizeof(char *));
+
+ /*
+ * install sigcode
+ */
+ if (sigcodesz)
+ copyout(imgp->proc->p_sysent->sv_sigcode,
+ ((caddr_t)arginfo - sigcodesz), szsigcode);
+
+ /*
+ * If we have a valid auxargs ptr, prepare some room
+ * on the stack.
+ */
+ if (imgp->auxargs) {
+ /*
+ * 'AT_COUNT*2' is size for the ELF Auxargs data. This is for
+ * lower compatibility.
+ */
+ imgp->auxarg_size = (imgp->auxarg_size) ? imgp->auxarg_size
+ : (AT_COUNT * 2);
+ /*
+ * The '+ 2' is for the null pointers at the end of each of
+ * the arg and env vector sets,and imgp->auxarg_size is room
+ * for argument of Runtime loader.
+ */
+ vectp = (u_int32_t *) (destp - (imgp->argc + imgp->envc + 2 +
+ imgp->auxarg_size) * sizeof(u_int32_t));
+
+ } else
+ /*
+ * The '+ 2' is for the null pointers at the end of each of
+ * the arg and env vector sets
+ */
+ vectp = (u_int32_t *)
+ (destp - (imgp->argc + imgp->envc + 2) * sizeof(u_int32_t));
+
+ /*
+ * vectp also becomes our initial stack base
+ */
+ stack_base = vectp;
+
+ stringp = imgp->stringbase;
+ argc = imgp->argc;
+ envc = imgp->envc;
+ /*
+ * Copy out strings - arguments and environment.
+ */
+ copyout(stringp, destp, ARG_MAX - imgp->stringspace);
+
+ /*
+ * Fill in "ps_strings" struct for ps, w, etc.
+ */
+ suword32(&arginfo->ps_argvstr, (u_int32_t)(intptr_t)vectp);
+ suword32(&arginfo->ps_nargvstr, argc);
+
+ /*
+ * Fill in argument portion of vector table.
+ */
+ for (; argc > 0; --argc) {
+ suword32(vectp++, (u_int32_t)(intptr_t)destp);
+ while (*stringp++ != 0)
+ destp++;
+ destp++;
+ }
+
+ /* a null vector table pointer separates the argp's from the envp's */
+ suword32(vectp++, 0);
+
+ suword32(&arginfo->ps_envstr, (u_int32_t)(intptr_t)vectp);
+ suword32(&arginfo->ps_nenvstr, envc);
+
+ /*
+ * Fill in environment portion of vector table.
+ */
+ for (; envc > 0; --envc) {
+ suword32(vectp++, (u_int32_t)(intptr_t)destp);
+ while (*stringp++ != 0)
+ destp++;
+ destp++;
+ }
+
+ /* end of vector table is a null pointer */
+ suword32(vectp, 0);
+
+ return ((register_t *)stack_base);
+}
+
+SYSCTL_NODE(_compat, OID_AUTO, linux32, CTLFLAG_RW, 0,
+ "32-bit Linux emulation");
+
+static u_long linux32_maxdsiz = LINUX32_MAXDSIZ;
+SYSCTL_ULONG(_compat_linux32, OID_AUTO, maxdsiz, CTLFLAG_RW,
+ &linux32_maxdsiz, 0, "");
+static u_long linux32_maxssiz = LINUX32_MAXSSIZ;
+SYSCTL_ULONG(_compat_linux32, OID_AUTO, maxssiz, CTLFLAG_RW,
+ &linux32_maxssiz, 0, "");
+static u_long linux32_maxvmem = LINUX32_MAXVMEM;
+SYSCTL_ULONG(_compat_linux32, OID_AUTO, maxvmem, CTLFLAG_RW,
+ &linux32_maxvmem, 0, "");
+
+/*
+ * XXX copied from ia32_sysvec.c.
+ */
+static void
+linux32_fixlimits(struct image_params *imgp)
+{
+ struct proc *p = imgp->proc;
+ struct plimit *oldlim, *newlim;
+
+ if (linux32_maxdsiz == 0 && linux32_maxssiz == 0 &&
+ linux32_maxvmem == 0)
+ return;
+ newlim = lim_alloc();
+ PROC_LOCK(p);
+ oldlim = p->p_limit;
+ lim_copy(newlim, oldlim);
+ if (linux32_maxdsiz != 0) {
+ if (newlim->pl_rlimit[RLIMIT_DATA].rlim_cur > linux32_maxdsiz)
+ newlim->pl_rlimit[RLIMIT_DATA].rlim_cur = linux32_maxdsiz;
+ if (newlim->pl_rlimit[RLIMIT_DATA].rlim_max > linux32_maxdsiz)
+ newlim->pl_rlimit[RLIMIT_DATA].rlim_max = linux32_maxdsiz;
+ }
+ if (linux32_maxssiz != 0) {
+ if (newlim->pl_rlimit[RLIMIT_STACK].rlim_cur > linux32_maxssiz)
+ newlim->pl_rlimit[RLIMIT_STACK].rlim_cur = linux32_maxssiz;
+ if (newlim->pl_rlimit[RLIMIT_STACK].rlim_max > linux32_maxssiz)
+ newlim->pl_rlimit[RLIMIT_STACK].rlim_max = linux32_maxssiz;
+ }
+ if (linux32_maxvmem != 0) {
+ if (newlim->pl_rlimit[RLIMIT_VMEM].rlim_cur > linux32_maxvmem)
+ newlim->pl_rlimit[RLIMIT_VMEM].rlim_cur = linux32_maxvmem;
+ if (newlim->pl_rlimit[RLIMIT_VMEM].rlim_max > linux32_maxvmem)
+ newlim->pl_rlimit[RLIMIT_VMEM].rlim_max = linux32_maxvmem;
+ }
+ p->p_limit = newlim;
+ PROC_UNLOCK(p);
+ lim_free(oldlim);
+}
+
+struct sysentvec elf_linux_sysvec = {
+ LINUX_SYS_MAXSYSCALL,
+ linux_sysent,
+ 0xff,
+ LINUX_SIGTBLSZ,
+ bsd_to_linux_signal,
+ ELAST + 1,
+ bsd_to_linux_errno,
+ translate_traps,
+ elf_linux_fixup,
+ linux_sendsig,
+ linux_sigcode,
+ &linux_szsigcode,
+ linux_prepsyscall,
+ "Linux ELF32",
+ elf32_coredump,
+ exec_linux_imgact_try,
+ LINUX_MINSIGSTKSZ,
+ PAGE_SIZE,
+ VM_MIN_ADDRESS,
+ LINUX32_USRSTACK,
+ LINUX32_USRSTACK,
+ LINUX32_PS_STRINGS,
+ VM_PROT_ALL,
+ linux_copyout_strings,
+ exec_linux_setregs,
+ linux32_fixlimits
+};
+
+static Elf32_Brandinfo linux_brand = {
+ ELFOSABI_LINUX,
+ EM_386,
+ "Linux",
+ "/compat/linux",
+ "/lib/ld-linux.so.1",
+ &elf_linux_sysvec,
+ NULL,
+ };
+
+static Elf32_Brandinfo linux_glibc2brand = {
+ ELFOSABI_LINUX,
+ EM_386,
+ "Linux",
+ "/compat/linux",
+ "/lib/ld-linux.so.2",
+ &elf_linux_sysvec,
+ NULL,
+ };
+
+Elf32_Brandinfo *linux_brandlist[] = {
+ &linux_brand,
+ &linux_glibc2brand,
+ NULL
+ };
+
+static int
+linux_elf_modevent(module_t mod, int type, void *data)
+{
+ Elf32_Brandinfo **brandinfo;
+ int error;
+ struct linux_ioctl_handler **lihp;
+
+ error = 0;
+
+ switch(type) {
+ case MOD_LOAD:
+ for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
+ ++brandinfo)
+ if (elf32_insert_brand_entry(*brandinfo) < 0)
+ error = EINVAL;
+ if (error == 0) {
+ SET_FOREACH(lihp, linux_ioctl_handler_set)
+ linux_ioctl_register_handler(*lihp);
+ if (bootverbose)
+ printf("Linux ELF exec handler installed\n");
+ } else
+ printf("cannot insert Linux ELF brand handler\n");
+ break;
+ case MOD_UNLOAD:
+ for (brandinfo = &linux_brandlist[0]; *brandinfo != NULL;
+ ++brandinfo)
+ if (elf32_brand_inuse(*brandinfo))
+ error = EBUSY;
+ if (error == 0) {
+ for (brandinfo = &linux_brandlist[0];
+ *brandinfo != NULL; ++brandinfo)
+ if (elf32_remove_brand_entry(*brandinfo) < 0)
+ error = EINVAL;
+ }
+ if (error == 0) {
+ SET_FOREACH(lihp, linux_ioctl_handler_set)
+ linux_ioctl_unregister_handler(*lihp);
+ if (bootverbose)
+ printf("Linux ELF exec handler removed\n");
+ linux_mib_destroy();
+ } else
+ printf("Could not deinstall ELF interpreter entry\n");
+ break;
+ default:
+ break;
+ }
+ return error;
+}
+
+static moduledata_t linux_elf_mod = {
+ "linuxelf",
+ linux_elf_modevent,
+ 0
+};
+
+DECLARE_MODULE(linuxelf, linux_elf_mod, SI_SUB_EXEC, SI_ORDER_ANY);
diff --git a/sys/amd64/linux32/syscalls.conf b/sys/amd64/linux32/syscalls.conf
new file mode 100644
index 000000000000..8c57f888ab0d
--- /dev/null
+++ b/sys/amd64/linux32/syscalls.conf
@@ -0,0 +1,11 @@
+# $FreeBSD$
+sysnames="/dev/null"
+sysproto="linux32_proto.h"
+sysproto_h=_LINUX_SYSPROTO_H_
+syshdr="linux32_syscall.h"
+syssw="linux32_sysent.c"
+sysmk="/dev/null"
+syscallprefix="LINUX_SYS_"
+switchname="linux_sysent"
+namesname="linux_syscallnames"
+sysvec="\n"
diff --git a/sys/amd64/linux32/syscalls.master b/sys/amd64/linux32/syscalls.master
new file mode 100644
index 000000000000..07ce1d1bf054
--- /dev/null
+++ b/sys/amd64/linux32/syscalls.master
@@ -0,0 +1,345 @@
+ $FreeBSD$
+
+; @(#)syscalls.master 8.1 (Berkeley) 7/19/93
+; System call name/number master file (or rather, slave, from LINUX).
+; Processed to create linux_sysent.c, linux_proto.h and linux_syscall.h.
+
+; Columns: number type nargs name alt{name,tag,rtyp}/comments
+; number system call number, must be in order
+; type one of STD, OBSOL, UNIMPL, COMPAT
+; name psuedo-prototype of syscall routine
+; If one of the following alts is different, then all appear:
+; altname name of system call if different
+; alttag name of args struct tag if different from [o]`name'"_args"
+; altrtyp return type if not int (bogus - syscalls always return int)
+; for UNIMPL/OBSOL, name continues with comments
+
+; types:
+; STD always included
+; COMPAT included on COMPAT #ifdef
+; LIBCOMPAT included on COMPAT #ifdef, and placed in syscall.h
+; OBSOL obsolete, not included in system, only specifies name
+; UNIMPL not implemented, placeholder only
+
+#include "opt_compat.h"
+#include <sys/param.h>
+#include <sys/sysent.h>
+#include <sys/sysproto.h>
+#include <amd64/linux32/linux.h>
+#include <amd64/linux32/linux32_proto.h>
+
+; #ifdef's, etc. may be included, and are copied to the output files.
+
+0 UNIMPL setup
+1 MNOPROTO { void sys_exit(int rval); } exit sys_exit_args void
+2 MSTD { int linux_fork(void); }
+3 MNOPROTO { int read(int fd, char *buf, u_int nbyte); }
+4 MNOPROTO { int write(int fd, char *buf, u_int nbyte); }
+5 STD { int linux_open(char *path, l_int flags, l_int mode); }
+6 MNOPROTO { int close(int fd); }
+7 MSTD { int linux_waitpid(l_pid_t pid, l_int *status, l_int options); }
+8 STD { int linux_creat(char *path, l_int mode); }
+9 STD { int linux_link(char *path, char *to); }
+10 STD { int linux_unlink(char *path); }
+11 STD { int linux_execve(char *path, char **argp, char **envp); }
+12 STD { int linux_chdir(char *path); }
+13 STD { int linux_time(l_time_t *tm); }
+14 STD { int linux_mknod(char *path, l_int mode, l_dev_t dev); }
+15 STD { int linux_chmod(char *path, l_mode_t mode); }
+16 STD { int linux_lchown16(char *path, l_uid16_t uid, \
+ l_gid16_t gid); }
+17 UNIMPL break
+18 UNIMPL stat
+19 STD { int linux_lseek(l_uint fdes, l_off_t off, l_int whence); }
+20 MSTD { int linux_getpid(void); }
+21 STD { int linux_mount(char *specialfile, char *dir, \
+ char *filesystemtype, l_ulong rwflag, \
+ void *data); }
+22 STD { int linux_oldumount(char *path); }
+23 MSTD { int linux_setuid16(l_uid16_t uid); }
+24 MSTD { int linux_getuid16(void); }
+25 STD { int linux_stime(void); }
+26 MSTD { int linux_ptrace(l_long req, l_long pid, l_long addr, \
+ l_long data); }
+27 STD { int linux_alarm(l_uint secs); }
+28 UNIMPL fstat
+29 MSTD { int linux_pause(void); }
+30 STD { int linux_utime(char *fname, struct l_utimbuf *times); }
+31 UNIMPL stty
+32 UNIMPL gtty
+33 STD { int linux_access(char *path, l_int flags); }
+34 MSTD { int linux_nice(l_int inc); }
+35 UNIMPL ftime
+36 NOPROTO { int sync(void); }
+37 MSTD { int linux_kill(l_int pid, l_int signum); }
+38 STD { int linux_rename(char *from, char *to); }
+39 STD { int linux_mkdir(char *path, l_int mode); }
+40 STD { int linux_rmdir(char *path); }
+41 MNOPROTO { int dup(u_int fd); }
+42 MSTD { int linux_pipe(l_ulong *pipefds); }
+43 STD { int linux_times(struct l_times_argv *buf); }
+44 UNIMPL prof
+45 STD { int linux_brk(l_ulong dsend); }
+46 MSTD { int linux_setgid16(l_gid16_t gid); }
+47 MSTD { int linux_getgid16(void); }
+48 MSTD { int linux_signal(l_int sig, l_handler_t handler); }
+49 MSTD { int linux_geteuid16(void); }
+50 MSTD { int linux_getegid16(void); }
+51 MNOPROTO { int acct(char *path); }
+52 STD { int linux_umount(char *path, l_int flags); }
+53 UNIMPL lock
+54 STD { int linux_ioctl(l_uint fd, l_uint cmd, uintptr_t arg); }
+55 STD { int linux_fcntl(l_uint fd, l_uint cmd, uintptr_t arg); }
+56 UNIMPL mpx
+57 MNOPROTO { int setpgid(int pid, int pgid); }
+58 UNIMPL ulimit
+59 STD { int linux_olduname(void); }
+60 MNOPROTO { int umask(int newmask); }
+61 NOPROTO { int chroot(char *path); }
+62 STD { int linux_ustat(l_dev_t dev, struct l_ustat *ubuf); }
+63 MNOPROTO { int dup2(u_int from, u_int to); }
+64 MNOPROTO { int getppid(void); }
+65 MNOPROTO { int getpgrp(void); }
+66 MNOPROTO { int setsid(void); }
+67 MSTD { int linux_sigaction(l_int sig, l_osigaction_t *nsa, \
+ l_osigaction_t *osa); }
+68 MSTD { int linux_sgetmask(void); }
+69 MSTD { int linux_ssetmask(l_osigset_t mask); }
+70 MSTD { int linux_setreuid16(l_uid16_t ruid, l_uid16_t euid); }
+71 MSTD { int linux_setregid16(l_gid16_t rgid, l_gid16_t egid); }
+72 MSTD { int linux_sigsuspend(l_int hist0, l_int hist1, \
+ l_osigset_t mask); }
+73 MSTD { int linux_sigpending(l_osigset_t *mask); }
+74 MNOPROTO { int osethostname(char *hostname, u_int len); } \
+ osethostname sethostname_args int
+75 MSTD { int linux_setrlimit(l_uint resource, struct l_rlimit *rlim); }
+76 MSTD { int linux_old_getrlimit(l_uint resource, \
+ struct l_rlimit *rlim); }
+77 MSTD { int linux_getrusage(int who, struct l_rusage *rusage); }
+78 MSTD { int linux_gettimeofday(struct l_timeval *tp, \
+ struct timezone *tzp); }
+79 MSTD { int linux_settimeofday(struct l_timeval *tp, \
+ struct timezone *tzp); }
+80 MSTD { int linux_getgroups16(l_uint gidsetsize, l_gid16_t *gidset); }
+81 MSTD { int linux_setgroups16(l_uint gidsetsize, l_gid16_t *gidset); }
+82 STD { int linux_old_select(struct l_old_select_argv *ptr); }
+83 STD { int linux_symlink(char *path, char *to); }
+84 UNIMPL ostat
+85 STD { int linux_readlink(char *name, char *buf, l_int count); }
+86 UNIMPL linux_uselib
+87 NOPROTO { int swapon(char *name); }
+88 STD { int linux_reboot(l_int magic1, l_int magic2, l_uint cmd, \
+ void *arg); }
+89 STD { int linux_readdir(l_uint fd, struct l_dirent *dent, \
+ l_uint count); }
+90 STD { int linux_mmap(struct l_mmap_argv *ptr); }
+91 NOPROTO { int munmap(caddr_t addr, int len); }
+92 STD { int linux_truncate(char *path, l_ulong length); }
+93 NOPROTO { int oftruncate(int fd, long length); }
+94 NOPROTO { int fchmod(int fd, int mode); }
+95 NOPROTO { int fchown(int fd, int uid, int gid); }
+96 MNOPROTO { int getpriority(int which, int who); }
+97 MNOPROTO { int setpriority(int which, int who, int prio); }
+98 UNIMPL profil
+99 STD { int linux_statfs(char *path, struct l_statfs_buf *buf); }
+100 STD { int linux_fstatfs(l_uint fd, struct l_statfs_buf *buf); }
+101 UNIMPL ioperm
+102 STD { int linux_socketcall(l_int what, l_ulong args); }
+103 STD { int linux_syslog(l_int type, char *buf, l_int len); }
+104 STD { int linux_setitimer(l_int which, struct l_itimerval *itv, \
+ struct l_itimerval *oitv); }
+105 STD { int linux_getitimer(l_int which, struct l_itimerval *itv); }
+106 STD { int linux_newstat(char *path, struct l_newstat *buf); }
+107 STD { int linux_newlstat(char *path, struct l_newstat *buf); }
+108 STD { int linux_newfstat(l_uint fd, struct l_newstat *buf); }
+109 STD { int linux_uname(void); }
+110 UNIMPL iopl
+111 STD { int linux_vhangup(void); }
+112 UNIMPL idle
+113 UNIMPL vm86old
+114 MSTD { int linux_wait4(l_pid_t pid, l_uint *status, \
+ l_int options, struct l_rusage *rusage); }
+115 STD { int linux_swapoff(void); }
+116 STD { int linux_sysinfo(struct l_sysinfo *info); }
+117 STD { int linux_ipc(l_uint what, l_int arg1, l_int arg2, \
+ l_int arg3, void *ptr, l_long arg5); }
+118 NOPROTO { int fsync(int fd); }
+119 MSTD { int linux_sigreturn(struct l_sigframe *sfp); }
+120 MSTD { int linux_clone(l_int flags, void *stack); }
+121 MNOPROTO { int setdomainname(char *name, int len); }
+122 STD { int linux_newuname(struct l_new_utsname *buf); }
+123 UNIMPL modify_ldt
+124 STD { int linux_adjtimex(void); }
+125 MSTD { int linux_mprotect(caddr_t addr, int len, int prot); }
+126 MSTD { int linux_sigprocmask(l_int how, l_osigset_t *mask, \
+ l_osigset_t *omask); }
+127 STD { int linux_create_module(void); }
+128 STD { int linux_init_module(void); }
+129 STD { int linux_delete_module(void); }
+130 STD { int linux_get_kernel_syms(void); }
+131 STD { int linux_quotactl(void); }
+132 NOPROTO { int getpgid(int pid); }
+133 NOPROTO { int fchdir(int fd); }
+134 STD { int linux_bdflush(void); }
+135 STD { int linux_sysfs(l_int option, l_ulong arg1, l_ulong arg2); }
+136 STD { int linux_personality(l_ulong per); }
+137 UNIMPL afs_syscall
+138 STD { int linux_setfsuid16(l_uid16_t uid); }
+139 STD { int linux_setfsgid16(l_gid16_t gid); }
+140 STD { int linux_llseek(l_int fd, l_ulong ohigh, l_ulong olow, \
+ l_loff_t *res, l_uint whence); }
+141 STD { int linux_getdents(l_uint fd, void *dent, l_uint count); }
+142 STD { int linux_select(l_int nfds, l_fd_set *readfds, \
+ l_fd_set *writefds, l_fd_set *exceptfds, \
+ struct l_timeval *timeout); }
+143 NOPROTO { int flock(int fd, int how); }
+144 STD { int linux_msync(l_ulong addr, l_size_t len, l_int fl); }
+145 STD { int linux_readv(int fd, struct iovec32 *iovp, \
+ u_int iovcnt); }
+146 STD { int linux_writev(int fd, struct iovec32 *iovp, \
+ u_int iovcnt); }
+147 MSTD { int linux_getsid(l_pid_t pid); }
+148 STD { int linux_fdatasync(l_uint fd); }
+149 STD { int linux_sysctl(struct l___sysctl_args *args); }
+150 MNOPROTO { int mlock(const void *addr, size_t len); }
+151 MNOPROTO { int munlock(const void *addr, size_t len); }
+152 MNOPROTO { int mlockall(int how); }
+153 MNOPROTO { int munlockall(void); }
+154 MNOPROTO { int sched_setparam(pid_t pid, \
+ const struct sched_param *param); }
+155 MNOPROTO { int sched_getparam(pid_t pid, \
+ struct sched_param *param); }
+156 MSTD { int linux_sched_setscheduler(l_pid_t pid, \
+ l_int policy, struct l_sched_param *param); }
+157 MSTD { int linux_sched_getscheduler(l_pid_t pid); }
+158 NOPROTO { int sched_yield(void); }
+159 MSTD { int linux_sched_get_priority_max(l_int policy); }
+160 MSTD { int linux_sched_get_priority_min(l_int policy); }
+161 MSTD { int linux_sched_rr_get_interval(l_pid_t pid, \
+ struct l_timespec *interval); }
+162 MSTD { int linux_nanosleep(const struct l_timespec *rqtp, \
+ struct l_timespec *rmtp); }
+163 STD { int linux_mremap(l_ulong addr, l_ulong old_len, \
+ l_ulong new_len, l_ulong flags, \
+ l_ulong new_addr); }
+164 MSTD { int linux_setresuid16(l_uid16_t ruid, \
+ l_uid16_t euid, l_uid16_t suid); }
+165 MSTD { int linux_getresuid16(l_uid16_t *ruid, \
+ l_uid16_t *euid, l_uid16_t *suid); }
+166 UNIMPL vm86
+167 STD { int linux_query_module(void); }
+168 NOPROTO { int poll(struct pollfd*, unsigned int nfds, int timeout); }
+169 STD { int linux_nfsservctl(void); }
+170 MSTD { int linux_setresgid16(l_gid16_t rgid, \
+ l_gid16_t egid, l_gid16_t sgid); }
+171 MSTD { int linux_getresgid16(l_gid16_t *rgid, \
+ l_gid16_t *egid, l_gid16_t *sgid); }
+172 STD { int linux_prctl(void); }
+173 STD { int linux_rt_sigreturn(struct l_ucontext *ucp); }
+174 MSTD { int linux_rt_sigaction(l_int sig, \
+ l_sigaction_t *act, l_sigaction_t *oact, \
+ l_size_t sigsetsize); }
+175 MSTD { int linux_rt_sigprocmask(l_int how, \
+ l_sigset_t *mask, l_sigset_t *omask, \
+ l_size_t sigsetsize); }
+176 STD { int linux_rt_sigpending(void); }
+177 STD { int linux_rt_sigtimedwait(void); }
+178 STD { int linux_rt_sigqueueinfo(void); }
+179 MSTD { int linux_rt_sigsuspend(l_sigset_t *newset, \
+ l_size_t sigsetsize); }
+180 STD { int linux_pread(l_uint fd, char *buf, \
+ l_size_t nbyte, l_loff_t offset); }
+181 STD { int linux_pwrite(l_uint fd, char *buf, \
+ l_size_t nbyte, l_loff_t offset); }
+182 STD { int linux_chown16(char *path, l_uid16_t uid, l_gid16_t gid); }
+183 STD { int linux_getcwd(char *buf, l_ulong bufsize); }
+184 STD { int linux_capget(void); }
+185 STD { int linux_capset(void); }
+186 STD { int linux_sigaltstack(l_stack_t *uss, l_stack_t *uoss); }
+187 STD { int linux_sendfile(void); }
+188 UNIMPL getpmsg
+189 UNIMPL putpmsg
+190 MSTD { int linux_vfork(void); }
+191 MSTD { int linux_getrlimit(l_uint resource, struct l_rlimit *rlim); }
+192 STD { int linux_mmap2(l_ulong addr, l_ulong len, \
+ l_ulong prot, l_ulong flags, l_ulong fd, \
+ l_ulong pgoff); }
+193 STD { int linux_truncate64(char *path, l_loff_t length); }
+194 STD { int linux_ftruncate64(l_uint fd, l_loff_t length); }
+195 STD { int linux_stat64(char *filename, \
+ struct l_stat64 *statbuf, l_long flags); }
+196 STD { int linux_lstat64(char *filename, \
+ struct l_stat64 *statbuf, l_long flags); }
+197 STD { int linux_fstat64(l_ulong fd, \
+ struct l_stat64 *statbuf, l_long flags); }
+198 STD { int linux_lchown(char *path, l_uid_t uid, \
+ l_gid_t gid); }
+199 MSTD { int linux_getuid(void); }
+200 MSTD { int linux_getgid(void); }
+201 MNOPROTO { int geteuid(void); }
+202 MNOPROTO { int getegid(void); }
+203 MNOPROTO { int setreuid(uid_t ruid, uid_t euid); }
+204 MNOPROTO { int setregid(gid_t rgid, gid_t egid); }
+205 MSTD { int linux_getgroups(l_int gidsetsize, l_gid_t *grouplist); }
+206 MSTD { int linux_setgroups(l_int gidsetsize, l_gid_t *grouplist); }
+207 NODEF fchown fchown fchown_args int
+208 MNOPROTO { int setresuid(uid_t ruid, uid_t euid, uid_t suid); }
+209 MNOPROTO { int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid); }
+210 MNOPROTO { int setresgid(gid_t rgid, gid_t egid, gid_t sgid); }
+211 MNOPROTO { int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid); }
+212 STD { int linux_chown(char *path, l_uid_t uid, l_gid_t gid); }
+213 MNOPROTO { int setuid(uid_t uid); }
+214 MNOPROTO { int setgid(gid_t gid); }
+215 STD { int linux_setfsuid(l_uid_t uid); }
+216 STD { int linux_setfsgid(l_gid_t gid); }
+217 STD { int linux_pivot_root(char *new_root, char *put_old); }
+218 STD { int linux_mincore(l_ulong start, l_size_t len, u_char *vec); }
+219 MNOPROTO { int madvise(void *addr, size_t len, int behav); }
+220 STD { int linux_getdents64(l_uint fd, void *dirent, l_uint count); }
+221 STD { int linux_fcntl64(l_uint fd, l_uint cmd, uintptr_t arg); }
+222 UNIMPL
+223 UNIMPL
+224 MNOPROTO { int linux_getpid(void); } gettid linux_getpid_args void
+225 UNIMPL linux_readahead
+226 STD { int linux_setxattr(void); }
+227 STD { int linux_lsetxattr(void); }
+228 STD { int linux_fsetxattr(void); }
+229 STD { int linux_getxattr(void); }
+230 STD { int linux_lgetxattr(void); }
+231 STD { int linux_fgetxattr(void); }
+232 STD { int linux_listxattr(void); }
+233 STD { int linux_llistxattr(void); }
+234 STD { int linux_flistxattr(void); }
+235 STD { int linux_removexattr(void); }
+236 STD { int linux_lremovexattr(void); }
+237 STD { int linux_fremovexattr(void); }
+238 UNIMPL linux_tkill
+239 UNIMPL linux_sendfile64
+240 UNIMPL linux_futex
+241 UNIMPL linux_sched_setaffinity
+242 UNIMPL linux_sched_getaffinity
+243 UNIMPL linux_set_thread_area
+244 UNIMPL linux_get_thread_area
+245 UNIMPL linux_io_setup
+246 UNIMPL linux_io_destroy
+247 UNIMPL linux_io_getevents
+248 UNIMPL linux_io_submit
+249 UNIMPL linux_io_cancel
+250 STD { int linux_fadvise64(void); }
+251 UNIMPL
+252 MNOPROTO { void sys_exit(int rval); } exit_group sys_exit_args void
+253 UNIMPL linux_lookup_dcookie
+254 UNIMPL linux_epoll_create
+255 UNIMPL linux_epoll_ctl
+256 UNIMPL linux_epoll_wait
+257 UNIMPL linux_remap_file_pages
+258 UNIMPL linux_set_tid_address
+259 UNIMPL linux_timer_create
+260 UNIMPL linux_timer_settime
+261 UNIMPL linux_timer_gettime
+262 UNIMPL linux_timer_getoverrun
+263 UNIMPL linux_timer_delete
+264 UNIMPL linux_clock_settime
+265 UNIMPL linux_clock_gettime
+266 UNIMPL linux_clock_getres
+267 UNIMPL linux_clock_nanosleep