qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Qemu-devel] [PATCH v3 06/19] bsd-user: add support for freebsd time rel


From: Stacey Son
Subject: [Qemu-devel] [PATCH v3 06/19] bsd-user: add support for freebsd time related system calls
Date: Tue, 17 Dec 2013 05:52:25 -0600

This change adds support or stubs for time related system calls
including nanosleep(2), clock_gettime(2), clock_settime(2),
clock_getres(2), gettimeofday(2), settimeofday(2), adjtime(2),
ntp_adjtime(2), ntp_gettime(2), utimes(2), lutimes(2), futimes(2),
futimesat(2), select(2), pselect(2), kqueue(2), kevent(2),
setitimer(2), getitimer(2), and the undocumented ktimer_*() calls.
---
 bsd-user/Makefile.objs     |    3 +-
 bsd-user/freebsd/os-time.c |  205 ++++++++++++
 bsd-user/freebsd/os-time.h |  643 +++++++++++++++++++++++++++++++++++
 bsd-user/freebsd/qemu-os.h |   53 +++
 bsd-user/netbsd/os-time.c  |    1 +
 bsd-user/netbsd/os-time.h  |  179 ++++++++++
 bsd-user/netbsd/qemu-os.h  |    1 +
 bsd-user/openbsd/os-time.c |    1 +
 bsd-user/openbsd/os-time.h |  179 ++++++++++
 bsd-user/openbsd/qemu-os.h |    1 +
 bsd-user/syscall.c         |  102 ++++++
 bsd-user/syscall_defs.h    |  796 ++++++++++++++++++++++++++++++++++++++------
 12 files changed, 2061 insertions(+), 103 deletions(-)
 create mode 100644 bsd-user/freebsd/os-time.c
 create mode 100644 bsd-user/freebsd/os-time.h
 create mode 100644 bsd-user/freebsd/qemu-os.h
 create mode 100644 bsd-user/netbsd/os-time.c
 create mode 100644 bsd-user/netbsd/os-time.h
 create mode 100644 bsd-user/netbsd/qemu-os.h
 create mode 100644 bsd-user/openbsd/os-time.c
 create mode 100644 bsd-user/openbsd/os-time.h
 create mode 100644 bsd-user/openbsd/qemu-os.h

diff --git a/bsd-user/Makefile.objs b/bsd-user/Makefile.objs
index a4dca8e..ac69be7 100644
--- a/bsd-user/Makefile.objs
+++ b/bsd-user/Makefile.objs
@@ -1,2 +1,3 @@
 obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \
-               uaccess.o $(HOST_VARIANT_DIR)/os-sys.o 
$(TARGET_ABI_DIR)/target_arch_cpu.o
+               uaccess.o $(HOST_VARIANT_DIR)/os-sys.o \
+                       $(HOST_VARIANT_DIR)/os-time.o 
$(TARGET_ABI_DIR)/target_arch_cpu.o
diff --git a/bsd-user/freebsd/os-time.c b/bsd-user/freebsd/os-time.c
new file mode 100644
index 0000000..7ac4397
--- /dev/null
+++ b/bsd-user/freebsd/os-time.c
@@ -0,0 +1,205 @@
+/*
+ *  FreeBSD time related system call helpers
+ *
+ *  Copyright (c) 2013 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
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <time.h>
+#include <sys/timex.h>
+#include <sys/select.h>
+
+#include "qemu.h"
+#include "qemu-os.h"
+
+/*
+ * FreeBSD time conversion functions
+ */
+abi_long t2h_freebsd_timeval(struct timeval *tv, abi_ulong target_tv_addr)
+{
+    struct target_freebsd_timeval *target_tv;
+
+    if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+    __get_user(tv->tv_sec, &target_tv->tv_sec);
+    __get_user(tv->tv_usec, &target_tv->tv_usec);
+    unlock_user_struct(target_tv, target_tv_addr, 1);
+
+    return 0;
+}
+
+abi_long h2t_freebsd_timeval(struct timeval *tv, abi_ulong target_tv_addr)
+{
+    struct target_freebsd_timeval *target_tv;
+
+    if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+    __put_user(tv->tv_sec, &target_tv->tv_sec);
+    __put_user(tv->tv_usec, &target_tv->tv_usec);
+    unlock_user_struct(target_tv, target_tv_addr, 1);
+
+    return 0;
+}
+
+abi_long t2h_freebsd_timespec(struct timespec *ts, abi_ulong target_ts_addr)
+{
+    struct target_freebsd_timespec *target_ts;
+
+    if (!lock_user_struct(VERIFY_READ, target_ts, target_ts_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+    __get_user(ts->tv_sec, &target_ts->tv_sec);
+    __get_user(ts->tv_nsec, &target_ts->tv_nsec);
+    unlock_user_struct(target_ts, target_ts_addr, 1);
+
+    return 0;
+}
+
+abi_long h2t_freebsd_timespec(abi_ulong target_ts_addr, struct timespec *ts)
+{
+    struct target_freebsd_timespec *target_ts;
+
+    if (!lock_user_struct(VERIFY_WRITE, target_ts, target_ts_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+    __put_user(ts->tv_sec, &target_ts->tv_sec);
+    __put_user(ts->tv_nsec, &target_ts->tv_nsec);
+    unlock_user_struct(target_ts, target_ts_addr, 1);
+
+    return 0;
+}
+
+abi_long t2h_freebsd_timex(struct timex *host_tx, abi_ulong target_tx_addr)
+{
+    struct target_freebsd_timex *target_tx;
+
+    if (!lock_user_struct(VERIFY_READ, target_tx, target_tx_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+    __get_user(host_tx->modes, &target_tx->modes);
+    __get_user(host_tx->offset, &target_tx->offset);
+    __get_user(host_tx->freq, &target_tx->freq);
+    __get_user(host_tx->maxerror, &target_tx->maxerror);
+    __get_user(host_tx->esterror, &target_tx->esterror);
+    __get_user(host_tx->status, &target_tx->status);
+    __get_user(host_tx->constant, &target_tx->constant);
+    __get_user(host_tx->precision, &target_tx->precision);
+    __get_user(host_tx->ppsfreq, &target_tx->ppsfreq);
+    __get_user(host_tx->jitter, &target_tx->jitter);
+    __get_user(host_tx->shift, &target_tx->shift);
+    __get_user(host_tx->stabil, &target_tx->stabil);
+    __get_user(host_tx->jitcnt, &target_tx->jitcnt);
+    __get_user(host_tx->calcnt, &target_tx->calcnt);
+    __get_user(host_tx->errcnt, &target_tx->errcnt);
+    __get_user(host_tx->stbcnt, &target_tx->stbcnt);
+    unlock_user_struct(target_tx, target_tx_addr, 1);
+
+    return 0;
+}
+
+abi_long h2t_freebsd_ntptimeval(abi_ulong target_ntv_addr,
+        struct ntptimeval *ntv)
+{
+    struct target_freebsd_ntptimeval *target_ntv;
+
+    if (!lock_user_struct(VERIFY_WRITE, target_ntv, target_ntv_addr, 0)) {
+        return -TARGET_EFAULT;
+    }
+    __put_user(ntv->time.tv_sec, &target_ntv->time.tv_sec);
+    __put_user(ntv->time.tv_nsec, &target_ntv->time.tv_nsec);
+    __put_user(ntv->maxerror, &target_ntv->maxerror);
+    __put_user(ntv->esterror, &target_ntv->esterror);
+    __put_user(ntv->tai, &target_ntv->tai);
+    __put_user(ntv->time_state, &target_ntv->time_state);
+
+    return 0;
+}
+
+/*
+ * select(2) fdset copy functions
+ */
+abi_ulong copy_from_user_fdset(fd_set *fds, abi_ulong target_fds_addr, int n)
+{
+    int i, nw, j, k;
+    abi_ulong b, *target_fds;
+
+    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
+    target_fds = lock_user(VERIFY_READ, target_fds_addr,
+            sizeof(abi_ulong) * nw, 1);
+    if (target_fds == NULL) {
+        return -TARGET_EFAULT;
+    }
+    FD_ZERO(fds);
+    k = 0;
+    for (i = 0; i < nw; i++) {
+        /* grab the abi_ulong */
+        __get_user(b, &target_fds[i]);
+        for (j = 0; j < TARGET_ABI_BITS; j++) {
+            /* check the bit inside the abi_ulong */
+            if ((b >> j) & 1) {
+                FD_SET(k, fds);
+            }
+            k++;
+        }
+    }
+    unlock_user(target_fds, target_fds_addr, 0);
+
+    return 0;
+}
+
+abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
+        abi_ulong target_fds_addr, int n)
+{
+
+    if (target_fds_addr) {
+        if (copy_from_user_fdset(fds, target_fds_addr, n)) {
+            return -TARGET_EFAULT;
+        }
+        *fds_ptr = fds;
+    } else {
+        *fds_ptr = NULL;
+    }
+
+    return 0;
+}
+
+abi_long copy_to_user_fdset(abi_ulong target_fds_addr, const fd_set *fds, int 
n)
+{
+    int i, nw, j, k;
+    abi_long v;
+    abi_ulong *target_fds;
+
+    nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS;
+    target_fds = lock_user(VERIFY_WRITE, target_fds_addr,
+            sizeof(abi_ulong) * nw, 0);
+    if (target_fds == NULL) {
+        return -TARGET_EFAULT;
+    }
+    k = 0;
+    for (i = 0; i < nw; i++) {
+        v = 0;
+        for (j = 0; j < TARGET_ABI_BITS; j++) {
+            v |= ((FD_ISSET(k, fds) != 0) << j);
+            k++;
+        }
+        __put_user(v, &target_fds[i]);
+    }
+    unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw);
+
+    return 0;
+}
+
diff --git a/bsd-user/freebsd/os-time.h b/bsd-user/freebsd/os-time.h
new file mode 100644
index 0000000..c6b5b28
--- /dev/null
+++ b/bsd-user/freebsd/os-time.h
@@ -0,0 +1,643 @@
+/*
+ *  FreeBSD time related system call shims
+ *
+ *  Copyright (c) 2013 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
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef __FREEBSD_OS_TIME_H_
+#define __FREEBSD_OS_TIME_H_
+
+#include <sys/types.h>
+#include <sys/event.h>
+#include <sys/select.h>
+#include <sys/timex.h>
+#include <signal.h>
+#include <time.h>
+
+#include "qemu-os.h"
+
+/* nanosleep(2) */
+static inline abi_long do_freebsd_nanosleep(abi_long arg1, abi_long arg2)
+{
+    abi_long ret;
+    struct timespec req, rem;
+
+    ret = t2h_freebsd_timespec(&req, arg1);
+    if (!is_error(ret)) {
+        ret = get_errno(nanosleep(&req, &rem));
+        if (!is_error(ret) && arg2) {
+            h2t_freebsd_timespec(arg2, &rem);
+        }
+    }
+
+    return ret;
+}
+
+/* clock_gettime(2) */
+static inline abi_long do_freebsd_clock_gettime(abi_long arg1, abi_long arg2)
+{
+    abi_long ret;
+    struct timespec ts;
+
+    ret = get_errno(clock_gettime(arg1, &ts));
+    if (!is_error(ret)) {
+        if (h2t_freebsd_timespec(arg2, &ts)) {
+            return -TARGET_EFAULT;
+        }
+    }
+
+    return ret;
+}
+
+/* clock_settime(2) */
+static inline abi_long do_freebsd_clock_settime(abi_long arg1, abi_long arg2)
+{
+    struct timespec ts;
+
+    if (t2h_freebsd_timespec(&ts, arg2) != 0) {
+        return -TARGET_EFAULT;
+    }
+
+    return get_errno(clock_settime(arg1, &ts));
+}
+
+/* clock_getres(2) */
+static inline abi_long do_freebsd_clock_getres(abi_long arg1, abi_long arg2)
+{
+    abi_long ret;
+    struct timespec ts;
+
+    ret = get_errno(clock_getres(arg1, &ts));
+    if (!is_error(ret)) {
+        if (h2t_freebsd_timespec(arg2, &ts)) {
+            return -TARGET_EFAULT;
+        }
+    }
+
+    return ret;
+}
+
+/* gettimeofday(2) */
+static inline abi_long do_freebsd_gettimeofday(abi_ulong arg1, abi_ulong arg2)
+{
+    abi_long ret;
+    struct timeval tv;
+    struct timezone tz, *target_tz; /* XXX */
+
+    if (arg2 != 0) {
+        if (!lock_user_struct(VERIFY_READ, target_tz, arg2, 0)) {
+            return -TARGET_EFAULT;
+        }
+        __get_user(tz.tz_minuteswest, &target_tz->tz_minuteswest);
+        __get_user(tz.tz_dsttime, &target_tz->tz_dsttime);
+        unlock_user_struct(target_tz, arg2, 1);
+    }
+    ret = get_errno(gettimeofday(&tv, arg2 != 0 ? &tz : NULL));
+    if (!is_error(ret)) {
+        if (h2t_freebsd_timeval(&tv, arg1)) {
+            return -TARGET_EFAULT;
+        }
+    }
+
+    return ret;
+}
+
+/* settimeofday(2) */
+static inline abi_long do_freebsd_settimeofday(abi_long arg1, abi_long arg2)
+{
+    struct timeval tv;
+    struct timezone tz, *target_tz; /* XXX */
+
+    if (arg2 != 0) {
+        if (!lock_user_struct(VERIFY_READ, target_tz, arg2, 0)) {
+            return -TARGET_EFAULT;
+        }
+        __get_user(tz.tz_minuteswest, &target_tz->tz_minuteswest);
+        __get_user(tz.tz_dsttime, &target_tz->tz_dsttime);
+        unlock_user_struct(target_tz, arg2, 1);
+    }
+    if (t2h_freebsd_timeval(&tv, arg1)) {
+        return -TARGET_EFAULT;
+    }
+
+    return get_errno(settimeofday(&tv, arg2 != 0 ? &tz : NULL));
+}
+
+/* adjtime(2) */
+static inline abi_long do_freebsd_adjtime(abi_ulong target_delta_addr,
+        abi_ulong target_old_addr)
+{
+    abi_long ret;
+    struct timeval host_delta, host_old;
+
+    ret = t2h_freebsd_timeval(&host_delta, target_delta_addr);
+    if (is_error(ret)) {
+        return ret;
+    }
+
+    if (target_old_addr) {
+        ret = get_errno(adjtime(&host_delta, &host_old));
+        if (is_error(ret)) {
+            return ret;
+        }
+        ret = h2t_freebsd_timeval(&host_old, target_old_addr);
+    } else {
+        ret = get_errno(adjtime(&host_delta, NULL));
+    }
+
+    return ret;
+}
+
+/* ntp_adjtime(2) */
+static abi_long do_freebsd_ntp_adjtime(abi_ulong target_tx_addr)
+{
+    abi_long ret;
+    struct timex host_tx;
+
+    ret = t2h_freebsd_timex(&host_tx, target_tx_addr);
+    if (ret == 0) {
+        ret = get_errno(ntp_adjtime(&host_tx));
+    }
+
+    return ret;
+}
+
+/* ntp_gettime(2) */
+static abi_long do_freebsd_ntp_gettime(abi_ulong target_ntv_addr)
+{
+    abi_long ret;
+    struct ntptimeval host_ntv;
+
+    ret = get_errno(ntp_gettime(&host_ntv));
+    if (ret == 0) {
+        ret = h2t_freebsd_ntptimeval(target_ntv_addr, &host_ntv);
+    }
+
+    return ret;
+}
+
+
+/* utimes(2) */
+static inline abi_long do_freebsd_utimes(abi_long arg1, abi_long arg2)
+{
+    abi_long ret;
+    void *p;
+    struct timeval *tvp, tv[2];
+
+    if (arg2 != 0) {
+        if (t2h_freebsd_timeval(&tv[0], arg2) ||
+                t2h_freebsd_timeval(&tv[1], arg2 +
+                        sizeof(struct target_freebsd_timeval))) {
+            return -TARGET_EFAULT;
+        }
+        tvp = tv;
+    } else {
+        tvp = NULL;
+    }
+    p = lock_user_string(arg1);
+    if (p == NULL) {
+        return -TARGET_EFAULT;
+    }
+    ret = get_errno(utimes(p, tvp));
+    unlock_user(p, arg1, 0);
+
+    return ret;
+}
+
+/* lutimes(2) */
+static inline abi_long do_freebsd_lutimes(abi_long arg1, abi_long arg2)
+{
+    abi_long ret;
+    void *p;
+    struct timeval *tvp, tv[2];
+
+    if (arg2 != 0) {
+        if (t2h_freebsd_timeval(&tv[0], arg2) ||
+                t2h_freebsd_timeval(&tv[1], arg2 +
+                        sizeof(struct target_freebsd_timeval))) {
+            return -TARGET_EFAULT;
+        }
+        tvp = tv;
+    } else {
+        tvp = NULL;
+    }
+    p = lock_user_string(arg1);
+    if (p == NULL) {
+        return -TARGET_EFAULT;
+    }
+    ret = get_errno(lutimes(p, tvp));
+    unlock_user(p, arg1, 0);
+
+    return ret;
+}
+
+/* futimes(2) */
+static inline abi_long do_freebsd_futimes(abi_long arg1, abi_long arg2)
+{
+    struct timeval *tvp, tv[2];
+
+    if (arg2 != 0) {
+        if (t2h_freebsd_timeval(&tv[0], arg2) ||
+                t2h_freebsd_timeval(&tv[1], arg2 +
+                        sizeof(struct target_freebsd_timeval))) {
+            return -TARGET_EFAULT;
+        }
+        tvp = tv;
+    } else {
+        tvp = NULL;
+    }
+
+    return get_errno(futimes(arg1, tvp));
+}
+
+/* futimesat(2) */
+static inline abi_long do_freebsd_futimesat(abi_long arg1, abi_long arg2,
+        abi_long arg3)
+{
+    abi_long ret;
+    void *p;
+    struct timeval *tvp, tv[2];
+
+    if (arg3 != 0) {
+        if (t2h_freebsd_timeval(&tv[0], arg3) ||
+                t2h_freebsd_timeval(&tv[1], arg3 +
+                        sizeof(struct target_freebsd_timeval))) {
+            return -TARGET_EFAULT;
+        }
+        tvp = tv;
+    } else {
+        tvp = NULL;
+    }
+
+    p = lock_user_string(arg2);
+    if (p == NULL) {
+        return -TARGET_EFAULT;
+    }
+    ret = get_errno(futimesat(arg1, p, tvp));
+    unlock_user(p, arg2, 0);
+
+    return ret;
+}
+
+/*
+ * undocumented ktimer_create(clockid_t clock_id,  struct sigevent *evp,
+ * int *timerid) syscall
+ */
+static inline abi_long do_freebsd_ktimer_create(abi_long arg1, abi_long arg2,
+        abi_long arg3)
+{
+
+    qemu_log("qemu: Unsupported syscall ktimer_create()\n");
+    return -TARGET_ENOSYS;
+}
+
+/* undocumented ktimer_delete(int timerid) syscall */
+static inline abi_long do_freebsd_ktimer_delete(abi_long arg1)
+{
+
+    qemu_log("qemu: Unsupported syscall ktimer_delete()\n");
+    return -TARGET_ENOSYS;
+}
+
+/*
+ * undocumented ktimer_settime(int timerid, int flags,
+ * const struct itimerspec *value, struct itimerspec *ovalue) syscall
+ */
+static inline abi_long do_freebsd_ktimer_settime(abi_long arg1, abi_long arg2,
+        abi_long arg3, abi_long arg4)
+{
+
+    qemu_log("qemu: Unsupported syscall ktimer_settime()\n");
+    return -TARGET_ENOSYS;
+}
+
+/*
+ * undocumented ktimer_gettime(int timerid, struct itimerspec *value)
+ * syscall
+ */
+static inline abi_long do_freebsd_ktimer_gettime(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall ktimer_gettime()\n");
+    return -TARGET_ENOSYS;
+}
+
+/*
+ * undocumented ktimer_getoverrun(int timerid) syscall
+ */
+static inline abi_long do_freebsd_ktimer_getoverrun(abi_long arg1)
+{
+
+    qemu_log("qemu: Unsupported syscall ktimer_getoverrun()\n");
+    return -TARGET_ENOSYS;
+}
+
+/* select(2) */
+static inline abi_long do_freebsd_select(int n, abi_ulong rfd_addr,
+        abi_ulong wfd_addr, abi_ulong efd_addr, abi_ulong target_tv_addr)
+{
+    fd_set rfds, wfds, efds;
+    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
+    struct timeval tv, *tv_ptr;
+    abi_long ret, error;
+
+    ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
+    if (ret != 0) {
+        return ret;
+    }
+    ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
+    if (ret != 0) {
+        return ret;
+    }
+    ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
+    if (ret != 0) {
+        return ret;
+    }
+
+    if (target_tv_addr != 0) {
+        if (t2h_freebsd_timeval(&tv, target_tv_addr)) {
+            return -TARGET_EFAULT;
+        }
+        tv_ptr = &tv;
+    } else {
+        tv_ptr = NULL;
+    }
+
+    ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr));
+
+    if (!is_error(ret)) {
+        if (rfd_addr != 0) {
+            error = copy_to_user_fdset(rfd_addr, &rfds, n);
+            if (error != 0) {
+                return error;
+            }
+        }
+        if (wfd_addr != 0) {
+            error = copy_to_user_fdset(wfd_addr, &wfds, n);
+            if (error != 0) {
+                return error;
+            }
+        }
+        if (efd_addr != 0) {
+            error = copy_to_user_fdset(efd_addr, &efds, n);
+            if (error != 0) {
+                return error;
+            }
+        }
+        if (target_tv_addr != 0) {
+            error = h2t_freebsd_timeval(&tv, target_tv_addr);
+            if (is_error(error)) {
+                return error;
+            }
+        }
+    }
+    return ret;
+}
+
+/* pselect(2) */
+static inline abi_long do_freebsd_pselect(int n, abi_ulong rfd_addr,
+        abi_ulong wfd_addr, abi_ulong efd_addr, abi_ulong ts_addr,
+        abi_ulong set_addr)
+{
+    fd_set rfds, wfds, efds;
+    fd_set *rfds_ptr, *wfds_ptr, *efds_ptr;
+    sigset_t set, *set_ptr;
+    struct timespec ts, *ts_ptr;
+    void *p;
+    abi_long ret;
+
+    ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n);
+    if (is_error(ret)) {
+        return ret;
+    }
+    ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n);
+    if (is_error(ret)) {
+        return ret;
+    }
+    ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n);
+    if (is_error(ret)) {
+        return ret;
+    }
+
+    /* Unlike select(), pselect() uses struct timespec instead of timeval */
+    if (ts_addr) {
+        if (t2h_freebsd_timespec(&ts, ts_addr)) {
+            return -TARGET_EFAULT;
+        }
+        ts_ptr = &ts;
+    } else {
+        ts_ptr = NULL;
+    }
+
+    if (set_addr != 0) {
+        p = lock_user(VERIFY_READ, set_addr, sizeof(target_sigset_t), 1);
+        if (p == NULL) {
+            return -TARGET_EFAULT;
+        }
+        target_to_host_sigset(&set, p);
+        unlock_user(p, set_addr, 0);
+        set_ptr = &set;
+    } else {
+        set_ptr = NULL;
+    }
+
+    ret = get_errno(pselect(n, rfds_ptr, wfds_ptr, efds_ptr, ts_ptr, set_ptr));
+
+    if (!is_error(ret)) {
+        if (rfd_addr != 0) {
+            ret = copy_to_user_fdset(rfd_addr, &rfds, n);
+            if (is_error(ret)) {
+                return ret;
+            }
+        }
+        if (wfd_addr != 0) {
+            ret = copy_to_user_fdset(wfd_addr, &wfds, n);
+            if (is_error(ret)) {
+                return ret;
+            }
+        }
+        if (efd_addr != 0) {
+            ret = copy_to_user_fdset(efd_addr, &efds, n);
+            if (is_error(ret)) {
+                return ret;
+            }
+        }
+        if (ts_addr != 0) {
+            ret = h2t_freebsd_timespec(ts_addr, &ts);
+            if (is_error(ret)) {
+                return ret;
+            }
+        }
+    }
+    return ret;
+}
+
+/* kqueue(2) */
+static inline abi_long do_freebsd_kqueue(void)
+{
+
+    return get_errno(kqueue());
+}
+
+/* kevent(2) */
+static inline abi_long do_freebsd_kevent(abi_long arg1, abi_ulong arg2,
+        abi_long arg3, abi_ulong arg4, abi_long arg5, abi_long arg6)
+{
+    abi_long ret;
+    struct kevent *changelist = NULL, *eventlist = NULL;
+    struct target_freebsd_kevent *target_changelist, *target_eventlist;
+    struct timespec ts;
+    int i;
+
+    if (arg3 != 0) {
+        target_changelist = lock_user(VERIFY_READ, arg2,
+                sizeof(struct target_freebsd_kevent) * arg3, 1);
+        if (target_changelist == NULL) {
+            return -TARGET_EFAULT;
+        }
+
+        changelist = alloca(sizeof(struct kevent) * arg3);
+        for (i = 0; i < arg3; i++) {
+            __get_user(changelist[i].ident, &target_changelist[i].ident);
+            __get_user(changelist[i].filter, &target_changelist[i].filter);
+            __get_user(changelist[i].flags, &target_changelist[i].flags);
+            __get_user(changelist[i].fflags, &target_changelist[i].fflags);
+            __get_user(changelist[i].data, &target_changelist[i].data);
+            /* __get_user(changelist[i].udata, &target_changelist[i].udata); */
+#if TARGET_ABI_BITS == 32
+            changelist[i].udata = (void 
*)(uintptr_t)target_changelist[i].udata;
+            tswap32s((uint32_t *)&changelist[i].udata);
+#else
+            changelist[i].udata = (void 
*)(uintptr_t)target_changelist[i].udata;
+            tswap64s((uint64_t *)&changelist[i].udata);
+#endif
+        }
+        unlock_user(target_changelist, arg2, 0);
+    }
+
+    if (arg5 != 0) {
+        eventlist = alloca(sizeof(struct kevent) * arg5);
+    }
+    if (arg6 != 0) {
+        if (t2h_freebsd_timespec(&ts, arg6)) {
+            return -TARGET_EFAULT;
+        }
+    }
+    ret = get_errno(kevent(arg1, changelist, arg3, eventlist, arg5,
+                arg6 != 0 ? &ts : NULL));
+    if (!is_error(ret)) {
+        target_eventlist = lock_user(VERIFY_WRITE, arg4,
+                sizeof(struct target_freebsd_kevent) * arg5, 0);
+        if (target_eventlist == NULL) {
+                return -TARGET_EFAULT;
+        }
+        for (i = 0; i < arg5; i++) {
+            __put_user(eventlist[i].ident, &target_eventlist[i].ident);
+            __put_user(eventlist[i].filter, &target_eventlist[i].filter);
+            __put_user(eventlist[i].flags, &target_eventlist[i].flags);
+            __put_user(eventlist[i].fflags, &target_eventlist[i].fflags);
+            __put_user(eventlist[i].data, &target_eventlist[i].data);
+            /* __put_user(eventlist[i].udata, &target_eventlist[i].udata);*/
+#if TARGET_ABI_BITS == 32
+            tswap32s((uint32_t *)&eventlist[i].data);
+            target_eventlist[i].data = (uintptr_t)eventlist[i].data;
+#else
+            tswap64s((uint64_t *)&eventlist[i].data);
+            target_eventlist[i].data = (uintptr_t)eventlist[i].data;
+#endif
+        }
+        unlock_user(target_eventlist, arg4,
+                sizeof(struct target_freebsd_kevent) * arg5);
+    }
+    return ret;
+}
+
+/* sigtimedwait(2) */
+static inline abi_long do_freebsd_sigtimedwait(abi_ulong arg1, abi_ulong arg2,
+        abi_ulong arg3)
+{
+    abi_long ret;
+    void *p;
+    sigset_t set;
+    struct timespec uts, *puts;
+    siginfo_t uinfo;
+
+    p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1);
+    if (p == NULL) {
+        return -TARGET_EFAULT;
+    }
+    target_to_host_sigset(&set, p);
+    unlock_user(p, arg1, 0);
+    if (arg3) {
+        puts = &uts;
+        t2h_freebsd_timespec(puts, arg3);
+    } else {
+        puts = NULL;
+    }
+    ret = get_errno(sigtimedwait(&set, &uinfo, puts));
+    if (!is_error(ret) && arg2) {
+        p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0);
+        if (p == NULL) {
+            return -TARGET_EFAULT;
+        }
+        host_to_target_siginfo(p, &uinfo);
+        unlock_user(p, arg2, sizeof(target_siginfo_t));
+    }
+    return ret;
+}
+
+/* setitimer(2) */
+static inline abi_long do_freebsd_setitimer(int arg1, abi_ulong arg2, 
abi_ulong arg3)
+{
+   abi_long ret = 0;
+   struct itimerval value, ovalue, *pvalue;
+
+   if (arg2) {
+       pvalue = &value;
+       if (t2h_freebsd_timeval(&pvalue->it_interval, arg2) ||
+           t2h_freebsd_timeval(&pvalue->it_value, arg2 + sizeof(struct 
target_freebsd_timeval))) {
+             return -TARGET_EFAULT;
+       } 
+   } else {
+       pvalue = NULL;
+   }
+   ret = get_errno(setitimer(arg1, pvalue, &ovalue));
+   if (!is_error(ret) && arg3) {
+       if (h2t_freebsd_timeval(&ovalue.it_interval, arg3)
+          || h2t_freebsd_timeval(&ovalue.it_value, arg3 + sizeof(struct 
target_freebsd_timeval))) {
+             return -TARGET_EFAULT;
+       }
+   }
+   return ret;
+}
+
+/* getitimer(2) */
+static inline abi_long do_freebsd_getitimer(int arg1, abi_ulong arg2)
+{
+   abi_long ret = 0;
+   struct itimerval value;
+
+   ret = get_errno(getitimer(arg1, &value));
+   if (!is_error(ret) && arg2) {
+       if (h2t_freebsd_timeval(&value.it_interval, arg2) ||
+           h2t_freebsd_timeval(&value.it_value, arg2 + sizeof(struct 
target_freebsd_timeval))) {
+            return -TARGET_EFAULT;
+       }
+   }
+   return ret;
+}
+
+#endif /* __FREEBSD_OS_TIME_H_ */
diff --git a/bsd-user/freebsd/qemu-os.h b/bsd-user/freebsd/qemu-os.h
new file mode 100644
index 0000000..bde610e
--- /dev/null
+++ b/bsd-user/freebsd/qemu-os.h
@@ -0,0 +1,53 @@
+/*
+ *  FreeBSD conversion extern declarations
+ *
+ *  Copyright (c) 2013 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
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef _QEMU_OS_H_
+#define _QEMU_OS_H_
+
+#include <sys/types.h>
+#include <sys/acl.h>
+#include <sys/mount.h>
+#include <sys/timex.h>
+#include <sys/rtprio.h>
+#include <sys/select.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <netinet/in.h>
+
+#include <time.h>
+
+/* os-time.c */
+abi_long t2h_freebsd_timeval(struct timeval *tv, abi_ulong target_tv_addr);
+abi_long h2t_freebsd_timeval(struct timeval *tv, abi_ulong target_tv_addr);
+
+abi_long t2h_freebsd_timespec(struct timespec *ts, abi_ulong target_ts_addr);
+abi_long h2t_freebsd_timespec(abi_ulong target_ts_addr, struct timespec *ts);
+
+abi_long t2h_freebsd_timex(struct timex *host_tx, abi_ulong target_tx_addr);
+
+abi_long h2t_freebsd_ntptimeval(abi_ulong target_ntv_addr,
+        struct ntptimeval *ntv);
+
+abi_ulong copy_from_user_fdset(fd_set *fds, abi_ulong target_fds_addr, int n);
+abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr,
+        abi_ulong target_fds_addr, int n);
+abi_long copy_to_user_fdset(abi_ulong target_fds_addr, const fd_set *fds,
+        int n);
+
+#endif /* !_QEMU_OS_H_ */
diff --git a/bsd-user/netbsd/os-time.c b/bsd-user/netbsd/os-time.c
new file mode 100644
index 0000000..ee2c7a0
--- /dev/null
+++ b/bsd-user/netbsd/os-time.c
@@ -0,0 +1 @@
+/* XXX NetBSD time related helpers */
diff --git a/bsd-user/netbsd/os-time.h b/bsd-user/netbsd/os-time.h
new file mode 100644
index 0000000..6d0f1de
--- /dev/null
+++ b/bsd-user/netbsd/os-time.h
@@ -0,0 +1,179 @@
+#ifndef __NETBSD_OS_TIME_H_
+#define __NETBSD_OS_TIME_H_
+
+/*
+ * XXX To support FreeBSD binaries on NetBSD these syscalls will need to
+ * be emulated.
+ */
+static inline abi_long do_freebsd_nanosleep(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_clock_gettime(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_clock_settime(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_clock_getres(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_gettimeofday(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_settimeofday(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_adjtime(abi_ulong target_delta_addr,
+        abi_ulong target_old_addr)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static abi_long do_freebsd_ntp_adjtime(abi_ulong target_tx_addr)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static abi_long do_freebsd_ntp_gettime(abi_ulong target_ntv_addr)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_utimes(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_lutimes(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_futimes(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_futimesat(abi_long arg1, abi_long arg2,
+        abi_long arg3)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_ktimer_create(abi_long arg1, abi_long arg2,
+        abi_long arg3)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_ktimer_delete(abi_long arg1)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_ktimer_settime(abi_long arg1, abi_long arg2,
+        abi_long arg3, abi_long arg4)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_ktimer_gettime(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_ktimer_getoverrun(abi_long arg1)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_select(int n, abi_ulong rfd_addr,
+        abi_ulong wfd_addr, abi_ulong efd_addr, abi_ulong target_tv_addr)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+
+static inline abi_long do_freebsd_pselect(int n, abi_ulong rfd_addr,
+        abi_ulong wfd_addr, abi_ulong efd_addr, abi_ulong ts_addr,
+        abi_ulong set_addr)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_kqueue(void)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_kevent(abi_long arg1, abi_ulong arg2,
+        abi_long arg3, abi_ulong arg4, abi_long arg5, abi_long arg6)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_sigtimedwait(abi_ulong arg1, abi_ulong arg2,
+        abi_ulong arg3)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+#endif /* ! __NETBSD_OS_TIME_H_ */
diff --git a/bsd-user/netbsd/qemu-os.h b/bsd-user/netbsd/qemu-os.h
new file mode 100644
index 0000000..016618b
--- /dev/null
+++ b/bsd-user/netbsd/qemu-os.h
@@ -0,0 +1 @@
+/* NetBSD conversion extern declarations */
diff --git a/bsd-user/openbsd/os-time.c b/bsd-user/openbsd/os-time.c
new file mode 100644
index 0000000..accd886
--- /dev/null
+++ b/bsd-user/openbsd/os-time.c
@@ -0,0 +1 @@
+/* XXX OpenBSD time related helpers */
diff --git a/bsd-user/openbsd/os-time.h b/bsd-user/openbsd/os-time.h
new file mode 100644
index 0000000..fc444bb
--- /dev/null
+++ b/bsd-user/openbsd/os-time.h
@@ -0,0 +1,179 @@
+#ifndef __OPENBSD_OS_TIME_H_
+#define __OPENBSD_OS_TIME_H_
+
+/*
+ * XXX To support FreeBSD binaries on OpenBSD these syscalls will need to
+ * be emulated.
+ */
+static inline abi_long do_freebsd_nanosleep(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_clock_gettime(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_clock_settime(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_clock_getres(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_gettimeofday(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_settimeofday(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_adjtime(abi_ulong target_delta_addr,
+        abi_ulong target_old_addr)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static abi_long do_freebsd_ntp_adjtime(abi_ulong target_tx_addr)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static abi_long do_freebsd_ntp_gettime(abi_ulong target_ntv_addr)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_utimes(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_lutimes(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_futimes(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_futimesat(abi_long arg1, abi_long arg2,
+        abi_long arg3)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_ktimer_create(abi_long arg1, abi_long arg2,
+        abi_long arg3)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_ktimer_delete(abi_long arg1)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_ktimer_settime(abi_long arg1, abi_long arg2,
+        abi_long arg3, abi_long arg4)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_ktimer_gettime(abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_ktimer_getoverrun(abi_long arg1)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_select(int n, abi_ulong rfd_addr,
+        abi_ulong wfd_addr, abi_ulong efd_addr, abi_ulong target_tv_addr)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+
+static inline abi_long do_freebsd_pselect(int n, abi_ulong rfd_addr,
+        abi_ulong wfd_addr, abi_ulong efd_addr, abi_ulong ts_addr,
+        abi_ulong set_addr)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_kqueue(void)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_kevent(abi_long arg1, abi_ulong arg2,
+        abi_long arg3, abi_ulong arg4, abi_long arg5, abi_long arg6)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+static inline abi_long do_freebsd_sigtimedwait(abi_ulong arg1, abi_ulong arg2,
+        abi_ulong arg3)
+{
+
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+#endif /* ! __OPENBSD_OS_TIME_H_ */
diff --git a/bsd-user/openbsd/qemu-os.h b/bsd-user/openbsd/qemu-os.h
new file mode 100644
index 0000000..f4ad3be
--- /dev/null
+++ b/bsd-user/openbsd/qemu-os.h
@@ -0,0 +1 @@
+/* OpenBSD conversion extern declarations */
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index dbc212d..0996787 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -39,6 +39,9 @@
 
 #define target_to_host_bitmask(x, tbl) (x)
 
+/* *BSD dependent syscall shims */
+#include "os-time.h"
+
 /* #define DEBUG */
 
 static abi_ulong target_brk;
@@ -224,6 +227,105 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, 
abi_long arg1,
         break;
 
         /*
+         * time related system calls.
+         */
+    case TARGET_FREEBSD_NR_nanosleep: /* nanosleep(2) */
+        ret = do_freebsd_nanosleep(arg1, arg2);
+        break;
+
+    case TARGET_FREEBSD_NR_clock_gettime: /* clock_gettime(2) */
+        ret = do_freebsd_clock_gettime(arg1, arg2);
+        break;
+
+    case TARGET_FREEBSD_NR_clock_settime: /* clock_settime(2) */
+        ret = do_freebsd_clock_settime(arg1, arg2);
+        break;
+
+    case TARGET_FREEBSD_NR_clock_getres: /* clock_getres(2) */
+        ret = do_freebsd_clock_getres(arg1, arg2);
+        break;
+
+    case TARGET_FREEBSD_NR_gettimeofday: /* gettimeofday(2) */
+        ret = do_freebsd_gettimeofday(arg1, arg2);
+        break;
+
+    case TARGET_FREEBSD_NR_settimeofday: /* settimeofday(2) */
+        ret = do_freebsd_settimeofday(arg1, arg2);
+        break;
+
+    case TARGET_FREEBSD_NR_adjtime: /* adjtime(2) */
+        ret = do_freebsd_adjtime(arg1, arg2);
+        break;
+
+    case TARGET_FREEBSD_NR_ntp_adjtime: /* ntp_adjtime(2) */
+        ret = do_freebsd_ntp_adjtime(arg1);
+        break;
+
+    case TARGET_FREEBSD_NR_ntp_gettime: /* ntp_gettime(2) */
+        ret = do_freebsd_ntp_gettime(arg1);
+        break;
+
+    case TARGET_FREEBSD_NR_utimes: /* utimes(2) */
+        ret = do_freebsd_utimes(arg1, arg2);
+        break;
+
+    case TARGET_FREEBSD_NR_lutimes: /* lutimes(2) */
+        ret = do_freebsd_lutimes(arg1, arg2);
+        break;
+
+    case TARGET_FREEBSD_NR_futimes: /* futimes(2) */
+        ret = do_freebsd_futimes(arg1, arg2);
+        break;
+
+    case TARGET_FREEBSD_NR_futimesat: /* futimesat(2) */
+        ret = do_freebsd_futimesat(arg1, arg2, arg3);
+        break;
+
+    case TARGET_FREEBSD_NR_ktimer_create: /* undocumented */
+        ret = do_freebsd_ktimer_create(arg1, arg2, arg3);
+        break;
+
+    case TARGET_FREEBSD_NR_ktimer_delete: /* undocumented */
+        ret = do_freebsd_ktimer_delete(arg1);
+        break;
+
+    case TARGET_FREEBSD_NR_ktimer_settime: /* undocumented */
+        ret = do_freebsd_ktimer_settime(arg1, arg2, arg3, arg4);
+        break;
+
+    case TARGET_FREEBSD_NR_ktimer_gettime: /* undocumented */
+        ret = do_freebsd_ktimer_gettime(arg1, arg2);
+        break;
+
+    case TARGET_FREEBSD_NR_ktimer_getoverrun: /* undocumented */
+        ret = do_freebsd_ktimer_getoverrun(arg1);
+        break;
+
+    case TARGET_FREEBSD_NR_select: /* select(2) */
+        ret = do_freebsd_select(arg1, arg2, arg3, arg4, arg5);
+        break;
+
+    case TARGET_FREEBSD_NR_pselect: /* pselect(2) */
+        ret = do_freebsd_pselect(arg1, arg2, arg3, arg4, arg5, arg6);
+        break;
+
+    case TARGET_FREEBSD_NR_kqueue: /* kqueue(2) */
+        ret = do_freebsd_kqueue();
+        break;
+
+    case TARGET_FREEBSD_NR_kevent: /* kevent(2) */
+        ret = do_freebsd_kevent(arg1, arg2, arg3, arg4, arg5, arg6);
+        break;
+
+    case TARGET_FREEBSD_NR_setitimer: /* setitimer(2) */
+        ret = do_freebsd_setitimer(arg1, arg2, arg3);
+        break;
+
+    case TARGET_FREEBSD_NR_getitimer: /* getitimer(2) */
+        ret = do_freebsd_getitimer(arg1, arg2);
+        break;
+
+        /*
          * sys{ctl, arch, call}
          */
     case TARGET_FREEBSD_NR___sysctl: /* sysctl(3) */
diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h
index 207ddee..ad84d33 100644
--- a/bsd-user/syscall_defs.h
+++ b/bsd-user/syscall_defs.h
@@ -1,105 +1,5 @@
-/*      $OpenBSD: signal.h,v 1.19 2006/01/08 14:20:16 millert Exp $     */
-/*      $NetBSD: signal.h,v 1.21 1996/02/09 18:25:32 christos Exp $     */
-
-/*
- * Copyright (c) 1982, 1986, 1989, 1991, 1993
- *      The Regents of the University of California.  All rights reserved.
- * (c) UNIX System Laboratories, Inc.
- * All or some portions of this file are derived from material licensed
- * to the University of California by American Telephone and Telegraph
- * Co. or Unix System Laboratories, Inc. and are reproduced herein with
- * the permission of UNIX System Laboratories, Inc.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- *      @(#)signal.h    8.2 (Berkeley) 1/21/94
- */
-
-#define TARGET_NSIG     32              /* counting 0; could be 33 (mask is 
1-32) */
-
-#define TARGET_SIGHUP  1       /* hangup */
-#define TARGET_SIGINT  2       /* interrupt */
-#define TARGET_SIGQUIT 3       /* quit */
-#define TARGET_SIGILL  4       /* illegal instruction (not reset when caught) 
*/
-#define TARGET_SIGTRAP 5       /* trace trap (not reset when caught) */
-#define TARGET_SIGABRT 6       /* abort() */
-#define TARGET_SIGIOT  SIGABRT /* compatibility */
-#define TARGET_SIGEMT  7       /* EMT instruction */
-#define TARGET_SIGFPE  8       /* floating point exception */
-#define TARGET_SIGKILL 9       /* kill (cannot be caught or ignored) */
-#define TARGET_SIGBUS  10      /* bus error */
-#define TARGET_SIGSEGV 11      /* segmentation violation */
-#define TARGET_SIGSYS  12      /* bad argument to system call */
-#define TARGET_SIGPIPE 13      /* write on a pipe with no one to read it */
-#define TARGET_SIGALRM 14      /* alarm clock */
-#define TARGET_SIGTERM 15      /* software termination signal from kill */
-#define TARGET_SIGURG  16      /* urgent condition on IO channel */
-#define TARGET_SIGSTOP 17      /* sendable stop signal not from tty */
-#define TARGET_SIGTSTP 18      /* stop signal from tty */
-#define TARGET_SIGCONT 19      /* continue a stopped process */
-#define TARGET_SIGCHLD 20      /* to parent on child stop or exit */
-#define TARGET_SIGTTIN 21      /* to readers pgrp upon background tty read */
-#define TARGET_SIGTTOU 22      /* like TTIN for output if 
(tp->t_local&LTOSTOP) */
-#define TARGET_SIGIO   23      /* input/output possible signal */
-#define TARGET_SIGXCPU 24      /* exceeded CPU time limit */
-#define TARGET_SIGXFSZ 25      /* exceeded file size limit */
-#define TARGET_SIGVTALRM 26    /* virtual time alarm */
-#define TARGET_SIGPROF 27      /* profiling time alarm */
-#define TARGET_SIGWINCH 28      /* window size changes */
-#define TARGET_SIGINFO  29      /* information request */
-#define TARGET_SIGUSR1 30       /* user defined signal 1 */
-#define TARGET_SIGUSR2 31       /* user defined signal 2 */
-
-/*
- * Language spec says we must list exactly one parameter, even though we
- * actually supply three.  Ugh!
- */
-#define TARGET_SIG_DFL         (void (*)(int))0
-#define TARGET_SIG_IGN         (void (*)(int))1
-#define TARGET_SIG_ERR         (void (*)(int))-1
-
-#define TARGET_SA_ONSTACK       0x0001  /* take signal on signal stack */
-#define TARGET_SA_RESTART       0x0002  /* restart system on signal return */
-#define TARGET_SA_RESETHAND     0x0004  /* reset to SIG_DFL when taking signal 
*/
-#define TARGET_SA_NODEFER       0x0010  /* don't mask the signal we're 
delivering */
-#define TARGET_SA_NOCLDWAIT     0x0020  /* don't create zombies (assign to pid 
1) */
-#define TARGET_SA_USERTRAMP    0x0100  /* do not bounce off kernel's sigtramp 
*/
-#define TARGET_SA_NOCLDSTOP     0x0008  /* do not generate SIGCHLD on child 
stop */
-#define TARGET_SA_SIGINFO       0x0040  /* generate siginfo_t */
-
-/*
- * Flags for sigprocmask:
- */
-#define TARGET_SIG_BLOCK       1       /* block specified signal set */
-#define TARGET_SIG_UNBLOCK     2       /* unblock specified signal set */
-#define TARGET_SIG_SETMASK     3       /* set specified signal set */
-
-#define TARGET_BADSIG          SIG_ERR
-
-#define TARGET_SS_ONSTACK       0x0001  /* take signals on alternate stack */
-#define TARGET_SS_DISABLE       0x0004  /* disable taking signals on alternate 
stack */
+#ifndef _SYSCALL_DEFS_H_
+#define _SYSCALL_DEFS_H_
 
 #include "errno_defs.h"
 
@@ -112,3 +12,695 @@ struct target_iovec {
     abi_long iov_len;   /* Number of bytes */
 };
 
+/*
+ * sys/ipc.h
+ */
+struct target_ipc_perm {
+    uint32_t    cuid;       /* creator user id */
+    uint32_t    cgid;       /* creator group id */
+    uint32_t    uid;        /* user id */
+    uint32_t    gid;        /* group id */
+    uint16_t    mode;       /* r/w permission */
+    uint16_t    seq;        /* sequence # */
+    abi_long    key;        /* user specified msg/sem/shm key */
+};
+
+#define TARGET_IPC_RMID 0   /* remove identifier */
+#define TARGET_IPC_SET  1   /* set options */
+#define TARGET_IPC_STAT 2   /* get options */
+
+/*
+ * sys/sem.h
+ */
+#define TARGET_GETNCNT  3   /* Return the value of semncnt {READ} */
+#define TARGET_GETPID   4   /* Return the value of sempid {READ} */
+#define TARGET_GETVAL   5   /* Return the value of semval {READ} */
+#define TARGET_GETALL   6   /* Return semvals into arg.array {READ} */
+#define TARGET_GETZCNT  7   /* Return the value of semzcnt {READ} */
+#define TARGET_SETVAL   8   /* Set the value of semval to arg.val {ALTER} */
+#define TARGET_SETALL   9   /* Set semvals from arg.array {ALTER} */
+#define TARGET_SEM_STAT 10 /* Like IPC_STAT but treats semid as sema-index */
+#define TARGET_SEM_INFO 11 /* Like IPC_INFO but treats semid as sema-index */
+
+struct target_sembuf {
+    unsigned short  sem_num;    /* semaphore # */
+    short       sem_op;         /* semaphore operation */
+    short       sem_flg;        /* operation flags */
+};
+
+union target_semun {
+    int     val;        /* value for SETVAL */
+    abi_ulong   buf;        /* buffer for IPC_STAT & IPC_SET */
+    abi_ulong   array;      /* array for GETALL & SETALL */
+};
+
+struct target_semid_ds {
+    struct target_ipc_perm sem_perm; /* operation permission struct */
+    abi_ulong   sem_base;   /* pointer to first semaphore in set */
+    uint16_t    sem_nsems;  /* number of sems in set */
+    abi_ulong   sem_otime;  /* last operation time */
+    abi_ulong   sem_ctime;  /* times measured in secs */
+};
+
+/*
+ * sys/shm.h
+ */
+struct target_shmid_ds {
+    struct  target_ipc_perm shm_perm; /* peration permission structure */
+    abi_ulong   shm_segsz;  /* size of segment in bytes */
+    int32_t     shm_lpid;   /* process ID of last shared memory op */
+    int32_t     shm_cpid;   /* process ID of creator */
+    int32_t     shm_nattch; /* number of current attaches */
+    abi_ulong   shm_atime;  /* time of last shmat() */
+    abi_ulong   shm_dtime;  /* time of last shmdt() */
+    abi_ulong   shm_ctime;  /* time of last change by shmctl() */
+};
+
+#define N_BSD_SHM_REGIONS   32
+struct bsd_shm_regions {
+    abi_long start;
+    abi_long size;
+};
+
+/*
+ * sys/msg.h
+ */
+struct target_msqid_ds {
+    struct  target_ipc_perm msg_perm; /* msg queue permission bits */
+    abi_ulong   msg_first;  /* first message in the queue */
+    abi_ulong   msg_last;   /* last message in the queue */
+    abi_ulong   msg_cbytes; /* # of bytes in use on the queue */
+    abi_ulong   msg_qnum;   /* number of msgs in the queue */
+    abi_ulong   msg_qbytes; /* max # of bytes on the queue */
+    int32_t     msg_lspid;  /* pid of last msgsnd() */
+    int32_t     msg_lrpid;  /* pid of last msgrcv() */
+    abi_ulong   msg_stime;  /* time of last msgsnd() */
+    abi_ulong   msg_rtime;  /* time of last msgrcv() */
+    abi_ulong   msg_ctime;  /* time of last msgctl() */
+};
+
+struct target_msgbuf {
+    abi_long    mtype;      /* message type */
+    char        mtext[1];   /* body of message */
+};
+
+/*
+ * sched.h
+ */
+struct target_sched_param {
+        int32_t sched_priority;
+};
+
+/*
+ *  sys/mman.h
+ */
+#define TARGET_FREEBSD_MAP_RESERVED0080 0x0080  /* previously misimplemented
+                                                   MAP_INHERIT */
+#define TARGET_FREEBSD_MAP_RESERVED0100 0x0100  /* previously unimplemented
+                                                   MAP_NOEXTEND */
+#define TARGET_FREEBSD_MAP_STACK        0x0400  /* region grows down, like a
+                                                   stack */
+#define TARGET_FREEBSD_MAP_NOSYNC       0x0800  /* page to but do not sync
+                                                   underlying file */
+
+#define TARGET_FREEBSD_MAP_FLAGMASK     0x1ff7
+
+#define TARGET_NETBSD_MAP_INHERIT       0x0080  /* region is retained after
+                                                   exec */
+#define TARGET_NETBSD_MAP_TRYFIXED      0x0400 /* attempt hint address, even
+                                                  within break */
+#define TARGET_NETBSD_MAP_WIRED         0x0800  /* mlock() mapping when it is
+                                                   established */
+
+#define TARGET_NETBSD_MAP_STACK         0x2000  /* allocated from memory, swap
+                                                   space (stack) */
+
+#define TARGET_NETBSD_MAP_FLAGMASK      0x3ff7
+
+#define TARGET_OPENBSD_MAP_INHERIT      0x0080  /* region is retained after
+                                                   exec */
+#define TARGET_OPENBSD_MAP_NOEXTEND     0x0100  /* for MAP_FILE, don't change
+                                                   file size */
+#define TARGET_OPENBSD_MAP_TRYFIXED     0x0400  /* attempt hint address,
+                                                   even within heap */
+
+#define TARGET_OPENBSD_MAP_FLAGMASK     0x17f7
+
+/* XXX */
+#define TARGET_BSD_MAP_FLAGMASK         0x3ff7
+
+/*
+ * sys/time.h
+ * sys/timex.h
+ */
+
+/*
+ * time_t seems to be very inconsistly defined for the different *BSD's...
+ *
+ * FreeBSD/{arm, mips} uses a 64bits time_t, even in 32bits mode,
+ * so we have to add a special case here.
+ *
+ * On NetBSD time_t is always defined as an int64_t.  On OpenBSD time_t
+ * is always defined as an int.
+ *
+ */
+#if (defined(TARGET_ARM) || defined(TARGET_MIPS))
+typedef int64_t target_freebsd_time_t;
+#else
+typedef abi_long target_freebsd_time_t;
+#endif
+
+typedef abi_long target_freebsd_suseconds_t;
+
+/* compare to sys/timespec.h */
+struct target_freebsd_timespec {
+    target_freebsd_time_t   tv_sec;     /* seconds */
+    abi_long                tv_nsec;    /* and nanoseconds */
+#if (defined(TARGET_ARM) || defined(TARGET_MIPS)) && TARGET_ABI_BITS == 32
+    abi_long _pad;
+#endif
+} __packed;
+
+struct target_freebsd_timeval {
+    target_freebsd_time_t       tv_sec; /* seconds */
+    target_freebsd_suseconds_t  tv_usec;/* and microseconds */
+#if (defined(TARGET_ARM) || defined(TARGET_MIPS)) && TARGET_ABI_BITS == 32
+    abi_long _pad;
+#endif
+} __packed;
+
+/* compare to sys/timex.h */
+struct target_freebsd_ntptimeval {
+    struct target_freebsd_timespec  time;
+    abi_long    maxerror;
+    abi_long    esterror;
+    abi_long    tai;
+    int32_t     time_state;
+};
+
+struct target_freebsd_timex {
+    uint32_t    modes;
+    abi_long    offset;
+    abi_long    freq;
+    abi_long    maxerror;
+    abi_long    esterror;
+    int32_t     status;
+    abi_long    constant;
+    abi_long    precision;
+    abi_long    tolerance;
+
+    abi_long    ppsfreq;
+    abi_long    jitter;
+    int32_t     shift;
+    abi_long    stabil;
+    abi_long    jitcnt;
+    abi_long    calcnt;
+    abi_long    errcnt;
+    abi_long    stbcnt;
+};
+
+/*
+ * sys/event.h
+ */
+struct target_freebsd_kevent {
+    abi_ulong  ident;
+    int16_t    filter;
+    uint16_t   flags;
+    uint32_t   fflags;
+    abi_long   data;
+    abi_ulong  udata;
+} __packed;
+
+/*
+ *  sys/resource.h
+ */
+#if defined(__FreeBSD__) && defined(TARGET_ALPHA)
+#define TARGET_RLIM_INFINITY    0x7fffffffffffffffull
+#elif defined(__FreeBSD__) && (defined(TARGET_MIPS) || \
+        (defined(TARGET_SPARC) && TARGET_ABI_BITS == 32))
+#define TARGET_RLIM_INFINITY    0x7fffffffUL
+#else
+#define TARGET_RLIM_INFINITY    ((abi_ulong)-1)
+#endif
+
+#define TARGET_RLIMIT_CPU       0
+#define TARGET_RLIMIT_FSIZE     1
+#define TARGET_RLIMIT_DATA      2
+#define TARGET_RLIMIT_STACK     3
+#define TARGET_RLIMIT_CORE      4
+#define TARGET_RLIMIT_RSS       5
+#define TARGET_RLIMIT_MEMLOCK   6
+#define TARGET_RLIMIT_NPROC     7
+#define TARGET_RLIMIT_NOFILE    8
+#define TARGET_RLIMIT_SBSIZE    9
+#define TARGET_RLIMIT_AS        10
+#define TARGET_RLIMIT_NPTS      11
+#define TARGET_RLIMIT_SWAP      12
+
+struct target_rlimit {
+    uint64_t rlim_cur;
+    uint64_t rlim_max;
+};
+
+struct target_freebsd_rusage {
+    struct target_freebsd_timeval ru_utime; /* user time used */
+    struct target_freebsd_timeval ru_stime; /* system time used */
+    abi_long    ru_maxrss;      /* maximum resident set size */
+    abi_long    ru_ixrss;       /* integral shared memory size */
+    abi_long    ru_idrss;       /* integral unshared data size */
+    abi_long    ru_isrss;       /* integral unshared stack size */
+    abi_long    ru_minflt;      /* page reclaims */
+    abi_long    ru_majflt;      /* page faults */
+    abi_long    ru_nswap;       /* swaps */
+    abi_long    ru_inblock;     /* block input operations */
+    abi_long    ru_oublock;     /* block output operations */
+    abi_long    ru_msgsnd;      /* messages sent */
+    abi_long    ru_msgrcv;      /* messages received */
+    abi_long    ru_nsignals;    /* signals received */
+    abi_long    ru_nvcsw;       /* voluntary context switches */
+    abi_long    ru_nivcsw;      /* involuntary context switches */
+};
+
+/*
+ * sys/socket.h
+ */
+
+/*
+ * Types
+ */
+#define TARGET_SOCK_STREAM      1   /* stream socket */
+#define TARGET_SOCK_DGRAM       2   /* datagram socket */
+#define TARGET_SOCK_RAW         3   /* raw-protocol interface */
+#define TARGET_SOCK_RDM         4   /* reliably-delivered message */
+#define TARGET_SOCK_SEQPACKET   5   /* sequenced packet stream */
+
+
+/*
+ * Option flags per-socket.
+ */
+
+#define TARGET_SO_DEBUG         0x0001  /* turn on debugging info recording */
+#define TARGET_SO_ACCEPTCONN    0x0002  /* socket has had listen() */
+#define TARGET_SO_REUSEADDR     0x0004  /* allow local address reuse */
+#define TARGET_SO_KEEPALIVE     0x0008  /* keep connections alive */
+#define TARGET_SO_DONTROUTE     0x0010  /* just use interface addresses */
+#define TARGET_SO_BROADCAST     0x0020  /* permit sending of broadcast msgs */
+#define TARGET_SO_USELOOPBACK   0x0040  /* bypass hardware when possible */
+#define TARGET_SO_LINGER        0x0080  /* linger on close if data present */
+#define TARGET_SO_OOBINLINE     0x0100  /* leave received OOB data in line */
+#define TARGET_SO_REUSEPORT     0x0200  /* allow local address & port reuse */
+#define TARGET_SO_TIMESTAMP     0x0400  /* timestamp received dgram traffic */
+#define TARGET_SO_NOSIGPIPE     0x0800  /* no SIGPIPE from EPIPE */
+#define TARGET_SO_ACCEPTFILTER  0x1000  /* there is an accept filter */
+#define TARGET_SO_BINTIME       0x2000  /* timestamp received dgram traffic */
+#define TARGET_SO_NO_OFFLOAD    0x4000  /* socket cannot be offloaded */
+#define TARGET_SO_NO_DDP        0x8000  /* disable direct data placement */
+
+/*
+ * Additional options, not kept in so_options.
+ */
+#define TARGET_SO_SNDBUF        0x1001  /* send buffer size */
+#define TARGET_SO_RCVBUF        0x1002  /* receive buffer size */
+#define TARGET_SO_SNDLOWAT      0x1003  /* send low-water mark */
+#define TARGET_SO_RCVLOWAT      0x1004  /* receive low-water mark */
+#define TARGET_SO_SNDTIMEO      0x1005  /* send timeout */
+#define TARGET_SO_RCVTIMEO      0x1006  /* receive timeout */
+#define TARGET_SO_ERROR         0x1007  /* get error status and clear */
+#define TARGET_SO_TYPE          0x1008  /* get socket type */
+#define TARGET_SO_LABEL         0x1009  /* socket's MAC label */
+#define TARGET_SO_PEERLABEL     0x1010  /* socket's peer's MAC label */
+#define TARGET_SO_LISTENQLIMIT  0x1011  /* socket's backlog limit */
+#define TARGET_SO_LISTENQLEN    0x1012  /* socket's complete queue length */
+#define TARGET_SO_LISTENINCQLEN 0x1013  /* socket's incomplete queue length */
+#define TARGET_SO_SETFIB        0x1014  /* use this FIB to route */
+#define TARGET_SO_USER_COOKIE   0x1015  /* user cookie (dummynet etc.) */
+#define TARGET_SO_PROTOCOL      0x1016  /* get socket protocol (Linux name) */
+
+/* alias for SO_PROTOCOL (SunOS name) */
+#define TARGET_SO_PROTOTYPE     TARGET_SO_PROTOCOL
+
+/*
+ * Level number for (get/set)sockopt() to apply to socket itself.
+ */
+#define TARGET_SOL_SOCKET       0xffff  /* options for socket level */
+
+#ifndef CMSG_ALIGN
+#define CMSG_ALIGN(len) (((len)+sizeof(long)-1) & ~(sizeof(long)-1))
+#endif
+
+struct target_msghdr {
+    abi_long    msg_name;       /* So cket name */
+    int32_t     msg_namelen;    /* Length of name */
+    abi_long    msg_iov;        /* Data blocks */
+    abi_long    msg_iovlen;     /* Number of blocks */
+    abi_long    msg_control;    /* Per protocol magic
+                                   (eg BSD file descriptor passing) */
+    abi_long    msg_controllen; /* Length of cmsg list */
+    int32_t     msg_flags;      /* flags on received message */
+};
+
+struct target_sockaddr {
+    uint8_t sa_len;
+    uint8_t sa_family;
+    uint8_t sa_data[14];
+} QEMU_PACKED;
+
+struct target_in_addr {
+    uint32_t s_addr; /* big endian */
+};
+
+struct target_cmsghdr {
+    abi_long    cmsg_len;
+    int32_t     cmsg_level;
+    int32_t     cmsg_type;
+};
+
+#define TARGET_CMSG_DATA(cmsg)  \
+    ((unsigned char *)((struct target_cmsghdr *) (cmsg) + 1))
+#define TARGET_CMSG_NXTHDR(mhdr, cmsg) __target_cmsg_nxthdr(mhdr, cmsg)
+#define TARGET_CMSG_ALIGN(len) (((len) + sizeof(abi_long) - 1) \
+    & (size_t) ~(sizeof(abi_long) - 1))
+#define TARGET_CMSG_SPACE(len) (TARGET_CMSG_ALIGN(len) \
+    + TARGET_CMSG_ALIGN(sizeof(struct target_cmsghdr)))
+#define TARGET_CMSG_LEN(len)  \
+    (TARGET_CMSG_ALIGN(sizeof(struct target_cmsghdr)) + (len))
+
+static inline struct target_cmsghdr *__target_cmsg_nxthdr(
+        struct target_msghdr *__mhdr, struct target_cmsghdr *__cmsg)
+{
+    struct target_cmsghdr *__ptr;
+
+    __ptr = (struct target_cmsghdr *)((unsigned char *) __cmsg +
+        TARGET_CMSG_ALIGN(tswapal(__cmsg->cmsg_len)));
+    if ((unsigned long)((char *)(__ptr+1) -
+        (char *)(size_t)tswapal(__mhdr->msg_control)) >
+        tswapal(__mhdr->msg_controllen)) {
+        /* No more entries.  */
+        return (struct target_cmsghdr *)0;
+    }
+    return __cmsg;
+}
+
+/*
+ * netinet/in.h
+ */
+struct target_ip_mreq {
+    struct target_in_addr   imr_multiaddr;
+    struct target_in_addr   imr_interface;
+};
+
+struct target_ip_mreqn {
+    struct target_in_addr   imr_multiaddr;
+    struct target_in_addr   imr_address;
+    int32_t                 imr_ifindex;
+};
+
+/*
+ * sys/stat.h
+ */
+#if defined(__FreeBSD_version) && __FreeBSD_version < 900000
+#define st_atim st_atimespec
+#define st_ctim st_ctimespec
+#define st_mtim st_mtimespec
+#define st_birthtim st_birthtimespec
+#endif
+
+struct target_freebsd_stat {
+    uint32_t  st_dev;       /* inode's device */
+    uint32_t  st_ino;       /* inode's number */
+    int16_t   st_mode;      /* inode protection mode */
+    int16_t   st_nlink;     /* number of hard links */
+    uint32_t  st_uid;       /* user ID of the file's owner */
+    uint32_t  st_gid;       /* group ID of the file's group */
+    uint32_t  st_rdev;      /* device type */
+    struct  target_freebsd_timespec st_atim; /* time last accessed */
+    struct  target_freebsd_timespec st_mtim; /* time last data modification */
+    struct  target_freebsd_timespec st_ctim; /* time last file status change */
+    int64_t    st_size;     /* file size, in bytes */
+    int64_t    st_blocks;   /* blocks allocated for file */
+    uint32_t   st_blksize;  /* optimal blocksize for I/O */
+    uint32_t   st_flags;    /* user defined flags for file */
+    __uint32_t st_gen;      /* file generation number */
+    __int32_t  st_lspare;
+    struct target_freebsd_timespec st_birthtim; /* time of file creation */
+    /*
+     * Explicitly pad st_birthtim to 16 bytes so that the size of
+     * struct stat is backwards compatible.  We use bitfields instead
+     * of an array of chars so that this doesn't require a C99 compiler
+     * to compile if the size of the padding is 0.  We use 2 bitfields
+     * to cover up to 64 bits on 32-bit machines.  We assume that
+     * CHAR_BIT is 8...
+     */
+    unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec));
+    unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec));
+} __packed;
+
+/* struct nstat is the same as stat above but without the st_lspare field */
+struct target_freebsd_nstat {
+    uint32_t  st_dev;       /* inode's device */
+    uint32_t  st_ino;       /* inode's number */
+    int16_t   st_mode;      /* inode protection mode */
+    int16_t   st_nlink;     /* number of hard links */
+    uint32_t  st_uid;       /* user ID of the file's owner */
+    uint32_t  st_gid;       /* group ID of the file's group */
+    uint32_t  st_rdev;      /* device type */
+    struct  target_freebsd_timespec st_atim; /* time last accessed */
+    struct  target_freebsd_timespec st_mtim; /* time last data modification */
+    struct  target_freebsd_timespec st_ctim; /* time last file status change */
+    int64_t    st_size;     /* file size, in bytes */
+    int64_t    st_blocks;   /* blocks allocated for file */
+    uint32_t   st_blksize;  /* optimal blocksize for I/O */
+    uint32_t   st_flags;    /* user defined flags for file */
+    __uint32_t st_gen;      /* file generation number */
+    /* __int32_t  st_lspare; */
+    struct target_freebsd_timespec st_birthtim; /* time of file creation */
+    /*
+     * Explicitly pad st_birthtim to 16 bytes so that the size of
+     * struct stat is backwards compatible.  We use bitfields instead
+     * of an array of chars so that this doesn't require a C99 compiler
+     * to compile if the size of the padding is 0.  We use 2 bitfields
+     * to cover up to 64 bits on 32-bit machines.  We assume that
+     * CHAR_BIT is 8...
+     */
+    unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec));
+    unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec));
+} __packed;
+
+/*
+ * sys/mount.h
+ */
+
+/* filesystem id type */
+typedef struct target_freebsd_fsid { int32_t val[2]; } target_freebsd_fsid_t;
+
+/* filesystem statistics */
+#define TARGET_MFSNAMELEN   16  /* length of type name include null */
+#define TARGET_MNAMELEN     88  /* size of on/from name bufs */
+#define TARGET_STATFS_VERSION   0x20030518  /* current version number */
+struct target_freebsd_statfs {
+    uint32_t f_version; /* structure version number */
+    uint32_t f_type;    /* type of filesystem */
+    uint64_t f_flags;   /* copy of mount exported flags */
+    uint64_t f_bsize;   /* filesystem fragment size */
+    uint64_t f_iosize;  /* optimal transfer block size */
+    uint64_t f_blocks;  /* total data blocks in filesystem */
+    uint64_t f_bfree;   /* free blocks in filesystem */
+    int64_t  f_bavail;  /* free blocks avail to non-superuser */
+    uint64_t f_files;   /* total file nodes in filesystem */
+    int64_t  f_ffree;   /* free nodes avail to non-superuser */
+    uint64_t f_syncwrites;  /* count of sync writes since mount */
+    uint64_t f_asyncwrites; /* count of async writes since mount */
+    uint64_t f_syncreads;   /* count of sync reads since mount */
+    uint64_t f_asyncreads;  /* count of async reads since mount */
+    uint64_t f_spare[10];   /* unused spare */
+    uint32_t f_namemax; /* maximum filename length */
+    uint32_t f_owner;   /* user that mounted the filesystem */
+    target_freebsd_fsid_t   f_fsid; /* filesystem id */
+    char     f_charspare[80];           /* spare string space */
+    char     f_fstypename[TARGET_MFSNAMELEN];   /* filesys type name */
+    char     f_mntfromname[TARGET_MNAMELEN];    /* mount filesystem */
+    char     f_mntonname[TARGET_MNAMELEN];      /* dir on which mounted*/
+};
+
+/* File identifier. These are unique per filesystem on a single machine. */
+#define TARGET_MAXFIDSZ     16
+
+struct target_freebsd_fid {
+    u_short     fid_len;            /* len of data in bytes */
+    u_short     fid_data0;          /* force longword align */
+    char        fid_data[TARGET_MAXFIDSZ];  /* data (variable len) */
+};
+
+/* Generic file handle */
+struct target_freebsd_fhandle {
+    target_freebsd_fsid_t   fh_fsid;    /* Filesystem id of mount point */
+    struct target_freebsd_fid fh_fid;   /* Filesys specific id */
+};
+typedef struct target_freebsd_fhandle target_freebsd_fhandle_t;
+
+/*
+ * sys/fcntl.h
+ */
+#define TARGET_F_DUPFD              0
+#define TARGET_F_GETFD              1
+#define TARGET_F_SETFD              2
+#define TARGET_F_GETFL              3
+#define TARGET_F_SETFL              4
+#define TARGET_F_GETOWN             5
+#define TARGET_F_SETOWN             6
+#define TARGET_F_OGETLK             7
+#define TARGET_F_OSETLK             8
+#define TARGET_F_OSETLKW            9
+#define TARGET_F_DUP2FD             10
+#define TARGET_F_GETLK              11
+#define TARGET_F_SETLK              12
+#define TARGET_F_SETLKW             13
+#define TARGET_F_SETLK_REMOTE       14
+#define TARGET_F_READAHEAD          15
+#define TARGET_F_RDAHEAD            16
+#define TARGET_F_DUPFD_CLOEXEC     17
+#define TARGET_F_DUP2FD_CLOEXEC    18
+
+struct target_freebsd_flock {
+    int64_t l_start;
+    int64_t l_len;
+    int32_t l_pid;
+    int16_t l_type;
+    int16_t l_whence;
+    int32_t l_sysid;
+} QEMU_PACKED;
+
+/*
+ * FreeBSD thread and user mutex support.
+ */
+
+/* sys/thr.h */
+#define TARGET_THR_SUSPENDED    0x0001
+#define TARGET_THR_SYSTEM_SCOPE 0x0002
+
+struct target_freebsd_thr_param {
+    abi_ulong   start_func; /* thread entry function. */
+    abi_ulong   arg;        /* argument for entry function. */
+    abi_ulong   stack_base; /* stack base address. */
+    abi_ulong   stack_size; /* stack size. */
+    abi_ulong   tls_base;   /* tls base address. */
+    abi_ulong   tls_size;   /* tls size. */
+    abi_ulong   child_tid;  /* address to store new TID. */
+    abi_ulong   parent_tid; /* parent access the new TID here. */
+    int32_t     flags;      /* thread flags. */
+    abi_ulong   rtp;        /* Real-time scheduling priority. */
+    abi_ulong   spare[3];   /* spares. */
+};
+
+/* sys/rtprio.h */
+struct target_freebsd_rtprio {
+    uint16_t    type;
+    uint16_t    prio;
+};
+
+typedef struct {
+    CPUArchState *env;
+    long parent_tid;
+    pthread_mutex_t mutex;
+    pthread_cond_t cond;
+    pthread_t thread;
+    sigset_t sigmask;
+    struct target_freebsd_thr_param param;
+} new_freebsd_thread_info_t;
+
+/* sys/utmx.h */
+/* op code for _umtx_op */
+#define TARGET_UMTX_OP_LOCK                 0
+#define TARGET_UMTX_OP_UNLOCK               1
+#define TARGET_UMTX_OP_WAIT                 2
+#define TARGET_UMTX_OP_WAKE                 3
+#define TARGET_UMTX_OP_MUTEX_TRYLOCK        4
+#define TARGET_UMTX_OP_MUTEX_LOCK           5
+#define TARGET_UMTX_OP_MUTEX_UNLOCK         6
+#define TARGET_UMTX_OP_SET_CEILING          7
+#define TARGET_UMTX_OP_CV_WAIT              8
+#define TARGET_UMTX_OP_CV_SIGNAL            9
+#define TARGET_UMTX_OP_CV_BROADCAST         10
+#define TARGET_UMTX_OP_WAIT_UINT            11
+#define TARGET_UMTX_OP_RW_RDLOCK            12
+#define TARGET_UMTX_OP_RW_WRLOCK            13
+#define TARGET_UMTX_OP_RW_UNLOCK            14
+#define TARGET_UMTX_OP_WAIT_UINT_PRIVATE    15
+#define TARGET_UMTX_OP_WAKE_PRIVATE         16
+#define TARGET_UMTX_OP_MUTEX_WAIT           17
+#define TARGET_UMTX_OP_MUTEX_WAKE           18
+#define TARGET_UMTX_OP_SEM_WAIT             19
+#define TARGET_UMTX_OP_SEM_WAKE             20
+#define TARGET_UMTX_OP_NWAKE_PRIVATE        21
+#define TARGET_UMTX_OP_MUTEX_WAKE2          22
+#define TARGET_UMTX_OP_MAX                  23
+
+/* flags for UMTX_OP_CV_WAIT */
+#define TARGET_CVWAIT_CHECK_UNPARKING       0x01
+#define TARGET_CVWAIT_ABSTIME               0x02
+#define TARGET_CVWAIT_CLOCKID               0x04
+
+#define TARGET_UMTX_UNOWNED                 0x0
+#define TARGET_UMUTEX_UNOWNED               0x0
+#define TARGET_UMTX_CONTESTED               (abi_ulong)(-1)
+#define TARGET_UMUTEX_CONTESTED             0x80000000U
+
+/* flags for umutex */
+#define TARGET_UMUTEX_ERROR_CHECK   0x0002  /* Error-checking mutex */
+#define TARGET_UMUTEX_PRIO_INHERIT  0x0004  /* Priority inherited mutex */
+#define TARGET_UMUTEX_PRIO_PROTECT  0x0008  /* Priority protect mutex */
+
+#define TARGET_UMUTEX_TRY           1
+#define TARGET_UMUTEX_WAIT          2
+
+/* urwlock flags */
+#define TARGET_URWLOCK_PREFER_READER    0x0002
+#define TARGET_URWLOCK_WRITE_OWNER      0x80000000U
+#define TARGET_URWLOCK_WRITE_WAITERS    0x40000000U
+#define TARGET_URWLOCK_READ_WAITERS     0x20000000U
+#define TARGET_URWLOCK_MAX_READERS      0x1fffffffU
+#define TARGET_URWLOCK_READER_COUNT(c)  ((c) & TARGET_URWLOCK_MAX_READERS)
+
+/*
+ * sys/acl.h
+ */
+#define TARGET_FREEBSD_ACL_MAX_ENTRIES          254
+
+/* vaild acl_type_t arguments */
+#define TARGET_FREEBSD_ACL_TYPE_ACCESS_OLD      0x00000000
+#define TARGET_FREEBSD_ACL_TYPE_DEFAULT_OLD     0x00000001
+#define TARGET_FREEBSD_ACL_TYPE_ACCESS          0x00000002
+#define TARGET_FREEBSD_ACL_TYPE_DEFAULT         0x00000003
+#define TARGET_FREEBSD_ACL_TYPE_NFS4            0x00000004
+
+struct target_freebsd_acl_entry {
+    uint32_t    ae_tag;
+    uint32_t    ae_id;
+    uint32_t    ae_perm;
+    uint16_t    ae_entry_type;
+    uint16_t    ae_flags;
+};
+
+struct target_freebsd_acl {
+    uint32_t            acl_maxcnt;
+    uint32_t            acl_cnt;
+    int32_t             acl_spare[4];
+    struct target_freebsd_acl_entry  acl_entry[TARGET_FREEBSD_ACL_MAX_ENTRIES];
+};
+
+/*
+ *  sys/uuid.h
+ */
+
+#define TARGET_UUID_NODE_LEN    6
+
+struct target_uuid {
+    uint32_t    time_low;
+    uint16_t    time_mid;
+    uint16_t    time_hi_and_version;
+    uint8_t     clock_seq_hi_and_reserved;
+    uint8_t     clock_seq_low;
+    uint8_t     node[TARGET_UUID_NODE_LEN];
+};
+
+#endif /* ! _SYSCALL_DEFS_H_ */
-- 
1.7.8




reply via email to

[Prev in Thread] Current Thread [Next in Thread]