c126e97c4c
- Add support for the wait6(2) system call. [1] - Add stubs for the new cap_*() system calls. [1] - Add support for new socket system calls. [1] - Add support for pipe2(2) and chflagsat(2) system calls. [1] - Add stubs for the new aio_*() system calls. [1] - Add stub for the new procctl(2) system call. [1] - Add JHB's ioctl decoding to unknown ioctl message. [1] - Disable shebang script handling in qemu for head now that the the kernel image activators can be run independantly there; this allows /bin/sh to be used as a static amd64 binary on head poudriere jails. [2] - Some other small non-user-visible fixes. - Bump PORTREVISION. Submitted by: sson [1], sbruno [2] Obtained from: https://github.com/seanbruno/qemu-bsd-user/commits/bsd-user
224 lines
8 KiB
Text
224 lines
8 KiB
Text
From c9c55ac786f09ce575b5f67b35241ce9452896c9 Mon Sep 17 00:00:00 2001
|
|
From: Stacey Son <sson@FreeBSD.org>
|
|
Date: Tue, 4 Nov 2014 23:38:38 +0000
|
|
Subject: [PATCH] Add support for new socket system calls.
|
|
|
|
This change adds support for bindat(2), connectat(2), and accept4(2)
|
|
system calls.
|
|
---
|
|
bsd-user/freebsd/os-socket.h | 106 +++++++++++++++++++++++++++++++++++++++++-
|
|
bsd-user/freebsd/strace.list | 13 ++++++
|
|
bsd-user/freebsd/syscall_nr.h | 6 ++-
|
|
bsd-user/syscall.c | 12 +++++
|
|
4 files changed, 135 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/bsd-user/freebsd/os-socket.h b/bsd-user/freebsd/os-socket.h
|
|
index 6530a07..61e3440 100644
|
|
--- a/bsd-user/freebsd/os-socket.h
|
|
+++ b/bsd-user/freebsd/os-socket.h
|
|
@@ -1,7 +1,7 @@
|
|
/*
|
|
* FreeBSD socket related system call shims
|
|
*
|
|
- * Copyright (c) 2013 Stacey D. Son
|
|
+ * Copyright (c) 2013-14 Stacey D. Son
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
@@ -557,4 +557,108 @@ static inline abi_long do_freebsd_sendfile(abi_long fd, abi_long s,
|
|
return -TARGET_ENOSYS;
|
|
}
|
|
|
|
+#if defined(__FreeBSD_version) && __FreeBSD_version > 1100000
|
|
+/* bindat(2) */
|
|
+static inline abi_long do_bsd_bindat(int fd, int sockfd, abi_ulong target_addr,
|
|
+ socklen_t addrlen)
|
|
+{
|
|
+ abi_long ret;
|
|
+ void *addr;
|
|
+
|
|
+ if ((int)addrlen < 0) {
|
|
+ return -TARGET_EINVAL;
|
|
+ }
|
|
+
|
|
+ addr = alloca(addrlen + 1);
|
|
+ ret = target_to_host_sockaddr(addr, target_addr, addrlen);
|
|
+ if (is_error(ret)) {
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ return get_errno(bindat(fd, sockfd, addr, addrlen));
|
|
+}
|
|
+
|
|
+/* connectat(2) */
|
|
+static inline abi_long do_bsd_connectat(int fd, int sockfd,
|
|
+ abi_ulong target_addr, socklen_t addrlen)
|
|
+{
|
|
+ abi_long ret;
|
|
+ void *addr;
|
|
+
|
|
+ if ((int)addrlen < 0) {
|
|
+ return -TARGET_EINVAL;
|
|
+ }
|
|
+ addr = alloca(addrlen);
|
|
+
|
|
+ ret = target_to_host_sockaddr(addr, target_addr, addrlen);
|
|
+
|
|
+ if (is_error(ret)) {
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ return get_errno(connectat(fd, sockfd, addr, addrlen));
|
|
+}
|
|
+
|
|
+/* accept4(2) */
|
|
+static inline abi_long do_bsd_accept4(int fd, abi_ulong target_addr,
|
|
+ abi_ulong target_addrlen_addr, int flags)
|
|
+{
|
|
+ socklen_t addrlen;
|
|
+ void *addr;
|
|
+ abi_long ret;
|
|
+
|
|
+ if (target_addr == 0) {
|
|
+ return get_errno(accept(fd, NULL, NULL));
|
|
+ }
|
|
+ /* return EINVAL if addrlen pointer is invalid */
|
|
+ if (get_user_u32(addrlen, target_addrlen_addr)) {
|
|
+ return -TARGET_EINVAL;
|
|
+ }
|
|
+ if ((int)addrlen < 0) {
|
|
+ return -TARGET_EINVAL;
|
|
+ }
|
|
+ if (!access_ok(VERIFY_WRITE, target_addr, addrlen)) {
|
|
+ return -TARGET_EINVAL;
|
|
+ }
|
|
+ addr = alloca(addrlen);
|
|
+
|
|
+ ret = get_errno(accept4(fd, addr, &addrlen, flags));
|
|
+ if (!is_error(ret)) {
|
|
+ host_to_target_sockaddr(target_addr, addr, addrlen);
|
|
+ if (put_user_u32(addrlen, target_addrlen_addr)) {
|
|
+ ret = -TARGET_EFAULT;
|
|
+ }
|
|
+ }
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+#else /* ! __FreeBSD_version > 1100000 */
|
|
+
|
|
+/* bindat(2) */
|
|
+static inline abi_long do_bsd_bindat(__unused int sockfd,
|
|
+ __unused abi_ulong target_addr, __unused socklen_t addrlen)
|
|
+{
|
|
+
|
|
+ qemu_log("qemu: Unsupported syscall bindat()\n");
|
|
+ return -TARGET_ENOSYS;
|
|
+}
|
|
+
|
|
+/* connectat(2) */
|
|
+static inline abi_long do_bsd_connectat(__unused int sockfd,
|
|
+ __unused abi_ulong target_addr, __unused socklen_t addrlen)
|
|
+{
|
|
+
|
|
+ qemu_log("qemu: Unsupported syscall connectat()\n");
|
|
+ return -TARGET_ENOSYS;
|
|
+}
|
|
+
|
|
+static inline abi_long do_bsd_accept4(__unused int fd,
|
|
+ __unused abi_ulong target_addr, __unused abi_ulong target_addrlen_addr,
|
|
+ __unused int flags)
|
|
+{
|
|
+
|
|
+ qemu_log("qemu: Unsupported syscall accept4()\n");
|
|
+ return -TARGET_ENOSYS;
|
|
+}
|
|
+#endif /* ! __FreeBSD_version > 1100000 */
|
|
#endif /* !__FREEBSD_SOCKET_H_ */
|
|
diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list
|
|
index f8858aa..991cbe2 100644
|
|
--- a/bsd-user/freebsd/strace.list
|
|
+++ b/bsd-user/freebsd/strace.list
|
|
@@ -34,11 +34,22 @@
|
|
{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, print_sysctl, NULL },
|
|
{ TARGET_FREEBSD_NR__umtx_op, "_umtx_op", "%s(%#x, %d, %d, %#x, %#x)", NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_accept, "accept", "%s(%d,%#x,%#x)", NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_accept4, "accept4", "%s(%d,%d,%#x,%#x)", NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_access, "access", "%s(\"%s\",%#o)", NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_acct, "acct", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_adjtime, "adjtime", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_bind, "bind", NULL, NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_bindat, "bindat", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_break, "break", NULL, NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_cap_enter, "cap_enter", NULL, NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_cap_fcntls_get, "cap_fcntls_get", NULL, NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_cap_fcntls_limit, "cap_fcntls_limit", NULL, NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_cap_getmode, "cap_getmode", NULL, NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_cap_getrights, "cap_getrights", NULL, NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_cap_ioctls_get, "cap_ioctls_get", NULL, NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_cap_ioctls_limit, "cap_ioctls_limit", NULL, NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_cap_new, "cap_new", NULL, NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_cap_rights_limit, "cap_rights_limit", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_chdir, "chdir", "%s(\"%s\")", NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_chflags, "chflags", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_chmod, "chmod", "%s(\"%s\",%#o)", NULL, NULL },
|
|
@@ -49,6 +60,7 @@
|
|
{ TARGET_FREEBSD_NR_clock_settime, "clock_settime", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_close, "close", "%s(%d)", NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_connect, "connect", "%s(%d,%#x,%d)", NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_connectat, "connectat", "%s(%d,%d,%#x,%d)", NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_dup, "dup", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_dup2, "dup2", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_eaccess, "eaccess", "%s(\"%s\",%#x)", NULL, NULL },
|
|
@@ -228,6 +240,7 @@
|
|
{ TARGET_FREEBSD_NR_utimes, "utimes", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_vfork, "vfork", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_wait4, "wait4", NULL, NULL, NULL },
|
|
+{ TARGET_FREEBSD_NR_wait6, "wait6", NULL, NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_write, "write", "%s(%d,%#x,%d)", NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_writev, "writev", "%s(%d,%p,%#x)", NULL, NULL },
|
|
{ TARGET_FREEBSD_NR_posix_openpt, "posix_openpt", "%s(%d)", NULL, NULL },
|
|
diff --git a/bsd-user/freebsd/syscall_nr.h b/bsd-user/freebsd/syscall_nr.h
|
|
index 2ab3e1e..260fd82 100644
|
|
--- a/bsd-user/freebsd/syscall_nr.h
|
|
+++ b/bsd-user/freebsd/syscall_nr.h
|
|
@@ -453,4 +453,8 @@
|
|
#define TARGET_FREEBSD_NR_cap_ioctls_get 535
|
|
#define TARGET_FREEBSD_NR_cap_fcntls_limit 536
|
|
#define TARGET_FREEBSD_NR_cap_fcntls_get 537
|
|
-#define TARGET_FREEBSD_NR_MAXSYSCALL 538
|
|
+#define TARGET_FREEBSD_NR_bindat 538
|
|
+#define TARGET_FREEBSD_NR_connectat 539
|
|
+#define TARGET_FREEBSD_NR_chflagsat 540
|
|
+#define TARGET_FREEBSD_NR_accept4 541
|
|
+#define TARGET_FREEBSD_NR_MAXSYSCALL 542
|
|
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
|
|
index c615bb8..e043396 100644
|
|
--- a/bsd-user/syscall.c
|
|
+++ b/bsd-user/syscall.c
|
|
@@ -1056,14 +1056,26 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
|
|
ret = do_bsd_accept(arg1, arg2, arg3);
|
|
break;
|
|
|
|
+ case TARGET_FREEBSD_NR_accept4: /* accept4(2) */
|
|
+ ret = do_bsd_accept4(arg1, arg2, arg3, arg4);
|
|
+ break;
|
|
+
|
|
case TARGET_FREEBSD_NR_bind: /* bind(2) */
|
|
ret = do_bsd_bind(arg1, arg2, arg3);
|
|
break;
|
|
|
|
+ case TARGET_FREEBSD_NR_bindat: /* bindat(2) */
|
|
+ ret = do_bsd_bindat(arg1, arg2, arg3, arg4);
|
|
+ break;
|
|
+
|
|
case TARGET_FREEBSD_NR_connect: /* connect(2) */
|
|
ret = do_bsd_connect(arg1, arg2, arg3);
|
|
break;
|
|
|
|
+ case TARGET_FREEBSD_NR_connectat: /* connectat(2) */
|
|
+ ret = do_bsd_connectat(arg1, arg2, arg3, arg4);
|
|
+ break;
|
|
+
|
|
case TARGET_FREEBSD_NR_getpeername: /* getpeername(2) */
|
|
ret = do_bsd_getpeername(arg1, arg2, arg3);
|
|
break;
|