diff options
author | Tim J. Robbins <tjr@FreeBSD.org> | 2004-08-16 07:55:06 +0000 |
---|---|---|
committer | Tim J. Robbins <tjr@FreeBSD.org> | 2004-08-16 07:55:06 +0000 |
commit | ea0fabbc4fcb15d10fbcaad14c405826d5eefea3 (patch) | |
tree | 8db1b1fe965caf91b81508b975442417a3f13b98 | |
parent | 25aea0fcaa99d27cabdfaf648f97fceac8a4546d (diff) | |
download | src-test2-ea0fabbc4fcb15d10fbcaad14c405826d5eefea3.tar.gz src-test2-ea0fabbc4fcb15d10fbcaad14c405826d5eefea3.zip |
Notes
-rw-r--r-- | sys/amd64/conf/NOTES | 3 | ||||
-rw-r--r-- | sys/amd64/linux32/Makefile | 15 | ||||
-rw-r--r-- | sys/amd64/linux32/linux.h | 722 | ||||
-rw-r--r-- | sys/amd64/linux32/linux32_dummy.c | 91 | ||||
-rw-r--r-- | sys/amd64/linux32/linux32_genassym.c | 17 | ||||
-rw-r--r-- | sys/amd64/linux32/linux32_ipc64.h | 145 | ||||
-rw-r--r-- | sys/amd64/linux32/linux32_locore.s | 45 | ||||
-rw-r--r-- | sys/amd64/linux32/linux32_machdep.c | 1019 | ||||
-rw-r--r-- | sys/amd64/linux32/linux32_proto.h | 869 | ||||
-rw-r--r-- | sys/amd64/linux32/linux32_syscall.h | 222 | ||||
-rw-r--r-- | sys/amd64/linux32/linux32_sysent.c | 288 | ||||
-rw-r--r-- | sys/amd64/linux32/linux32_sysvec.c | 1088 | ||||
-rw-r--r-- | sys/amd64/linux32/syscalls.conf | 11 | ||||
-rw-r--r-- | sys/amd64/linux32/syscalls.master | 345 | ||||
-rw-r--r-- | sys/conf/files.amd64 | 35 | ||||
-rw-r--r-- | sys/conf/options.amd64 | 1 |
16 files changed, 4915 insertions, 1 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 diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64 index 0af15c038891..4fad97d4c355 100644 --- a/sys/conf/files.amd64 +++ b/sys/conf/files.amd64 @@ -7,7 +7,19 @@ # limitations in config: backslash-newline doesn't work in strings, and # dependency lines other than the first are silently ignored. # - +# +linux32_genassym.o optional compat_linux32 \ + dependency "$S/amd64/linux32/linux32_genassym.c" \ + compile-with "${CC} ${CFLAGS:N-fno-common} -c ${.IMPSRC}" \ + no-obj no-implicit-rule \ + clean "linux32_genassym.o" +# +linux32_assym.h optional compat_linux32 \ + dependency "$S/kern/genassym.sh linux32_genassym.o" \ + compile-with "sh $S/kern/genassym.sh linux32_genassym.o > ${.TARGET}" \ + no-obj no-implicit-rule before-depend \ + clean "linux32_assym.h" +# ia32_genassym.o standard \ dependency "$S/compat/ia32/ia32_genassym.c" \ compile-with "${CC} ${CFLAGS:N-fno-common} -c ${.IMPSRC}" \ @@ -156,3 +168,24 @@ compat/freebsd32/freebsd32_syscalls.c optional ia32 compat/freebsd32/freebsd32_sysent.c optional ia32 compat/ia32/ia32_sysvec.c optional ia32 kern/imgact_elf32.c optional ia32 +# +# Linux/i386 binary support +# +amd64/linux32/linux32_dummy.c optional compat_linux32 +amd64/linux32/linux32_locore.s optional compat_linux32 \ + dependency "linux32_assym.h" +amd64/linux32/linux32_machdep.c optional compat_linux32 +amd64/linux32/linux32_sysent.c optional compat_linux32 +amd64/linux32/linux32_sysvec.c optional compat_linux32 +compat/linux/linux_file.c optional compat_linux32 +compat/linux/linux_getcwd.c optional compat_linux32 +compat/linux/linux_ioctl.c optional compat_linux32 +compat/linux/linux_ipc.c optional compat_linux32 +compat/linux/linux_mib.c optional compat_linux32 +compat/linux/linux_misc.c optional compat_linux32 +compat/linux/linux_signal.c optional compat_linux32 +compat/linux/linux_socket.c optional compat_linux32 +compat/linux/linux_stats.c optional compat_linux32 +compat/linux/linux_sysctl.c optional compat_linux32 +compat/linux/linux_uid16.c optional compat_linux32 +compat/linux/linux_util.c optional compat_linux32 diff --git a/sys/conf/options.amd64 b/sys/conf/options.amd64 index 097b62237c2b..a383137bc6ea 100644 --- a/sys/conf/options.amd64 +++ b/sys/conf/options.amd64 @@ -12,6 +12,7 @@ PMAP_SHPGPERPROC opt_pmap.h # (see src/sys/conf/options), except for broken debugging options. #IBCS2 opt_dontuse.h #COMPAT_LINUX opt_dontuse.h +COMPAT_LINUX32 opt_compat.h #COMPAT_SVR4 opt_dontuse.h #DEBUG_SVR4 opt_svr4.h #NDISAPI opt_dontuse.h |