From 4f4fc7daef6cbb357d082fa0287b1b23423d4752 Mon Sep 17 00:00:00 2001 From: dchagin Date: Wed, 22 Feb 2017 19:57:59 +0000 Subject: MFC r313284: Update syscall.master to 4.10-rc6. Also fix comments, a typo, and wrong numbering for a few unimplemented syscalls. For 32-bit Linuxulator, socketcall() syscall was historically the entry point for the sockets API. Starting in Linux 4.3, direct syscalls are provided for the sockets API. Enable it. The initial version of patch was provided by trasz@ and extended by me. MFC r313285: Regen after r313284. MFC r313684: Fix r313284. Members of the syscall argument structures are padded to a word size. So, for COMPAT_LINUX32 we should convert user supplied system call arguments which is 32-bit in that case to the array of register_t. MFC r313912: Finish r313684. Convert linux_recv(), linux_send() and linux_accept() system call arguments to the register_t type too. --- sys/compat/linux/linux_socket.c | 62 ++++++++++++++++++++++------------------- 1 file changed, 34 insertions(+), 28 deletions(-) (limited to 'sys/compat/linux/linux_socket.c') diff --git a/sys/compat/linux/linux_socket.c b/sys/compat/linux/linux_socket.c index 680f3c0..7e65332 100644 --- a/sys/compat/linux/linux_socket.c +++ b/sys/compat/linux/linux_socket.c @@ -971,10 +971,10 @@ linux_socketpair(struct thread *td, struct linux_socketpair_args *args) #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) struct linux_send_args { - int s; - l_uintptr_t msg; - int len; - int flags; + register_t s; + register_t msg; + register_t len; + register_t flags; }; static int @@ -999,10 +999,10 @@ linux_send(struct thread *td, struct linux_send_args *args) } struct linux_recv_args { - int s; - l_uintptr_t msg; - int len; - int flags; + register_t s; + register_t msg; + register_t len; + register_t flags; }; static int @@ -1701,39 +1701,45 @@ linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args) #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32)) /* Argument list sizes for linux_socketcall */ - -#define LINUX_AL(x) ((x) * sizeof(l_ulong)) - -static const unsigned char lxs_args[] = { - LINUX_AL(0) /* unused*/, LINUX_AL(3) /* socket */, - LINUX_AL(3) /* bind */, LINUX_AL(3) /* connect */, - LINUX_AL(2) /* listen */, LINUX_AL(3) /* accept */, - LINUX_AL(3) /* getsockname */, LINUX_AL(3) /* getpeername */, - LINUX_AL(4) /* socketpair */, LINUX_AL(4) /* send */, - LINUX_AL(4) /* recv */, LINUX_AL(6) /* sendto */, - LINUX_AL(6) /* recvfrom */, LINUX_AL(2) /* shutdown */, - LINUX_AL(5) /* setsockopt */, LINUX_AL(5) /* getsockopt */, - LINUX_AL(3) /* sendmsg */, LINUX_AL(3) /* recvmsg */, - LINUX_AL(4) /* accept4 */, LINUX_AL(5) /* recvmmsg */, - LINUX_AL(4) /* sendmmsg */ +static const unsigned char lxs_args_cnt[] = { + 0 /* unused*/, 3 /* socket */, + 3 /* bind */, 3 /* connect */, + 2 /* listen */, 3 /* accept */, + 3 /* getsockname */, 3 /* getpeername */, + 4 /* socketpair */, 4 /* send */, + 4 /* recv */, 6 /* sendto */, + 6 /* recvfrom */, 2 /* shutdown */, + 5 /* setsockopt */, 5 /* getsockopt */, + 3 /* sendmsg */, 3 /* recvmsg */, + 4 /* accept4 */, 5 /* recvmmsg */, + 4 /* sendmmsg */ }; - -#define LINUX_AL_SIZE (nitems(lxs_args) - 1) +#define LINUX_ARGS_CNT (nitems(lxs_args_cnt) - 1) +#define LINUX_ARG_SIZE(x) (lxs_args_cnt[x] * sizeof(l_ulong)) int linux_socketcall(struct thread *td, struct linux_socketcall_args *args) { l_ulong a[6]; +#if defined(__amd64__) && defined(COMPAT_LINUX32) + register_t l_args[6]; +#endif void *arg; int error; - if (args->what < LINUX_SOCKET || args->what > LINUX_AL_SIZE) + if (args->what < LINUX_SOCKET || args->what > LINUX_ARGS_CNT) return (EINVAL); - error = copyin(PTRIN(args->args), a, lxs_args[args->what]); - if (error) + error = copyin(PTRIN(args->args), a, LINUX_ARG_SIZE(args->what)); + if (error != 0) return (error); +#if defined(__amd64__) && defined(COMPAT_LINUX32) + for (int i = 0; i < lxs_args_cnt[args->what]; ++i) + l_args[i] = a[i]; + arg = l_args; +#else arg = a; +#endif switch (args->what) { case LINUX_SOCKET: return (linux_socket(td, arg)); -- cgit v1.1