[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH 12/23] bsd-user: add shims for time related system c
From: |
Stacey Son |
Subject: |
[Qemu-devel] [PATCH 12/23] bsd-user: add shims for time related system calls. |
Date: |
Sun, 23 Jun 2013 21:03:44 -0500 |
This change adds support for time related system calls that are largely
FreeBSD dependent because time_t is inconsistly defined for the various *BSD's.
On FreeBSD time_t is mostly defined as a 64-bit value. On some architectures
like PPC32 it is defined as a 32-bit value, however. On NetBSD it is always
defined as an int64_t. On OpenBSD it is defined as an int. This change also
defines system call shim stubs for NetBSD/OpenBSD in case some whats to add
code to emulate FreeBSD binaries on one of the other *BSD's.
Signed-off-by: Stacey Son <address@hidden>
---
bsd-user/Makefile.objs | 2 +-
bsd-user/freebsd/os-time.c | 205 +++++++++++++++
bsd-user/freebsd/os-time.h | 602 ++++++++++++++++++++++++++++++++++++++++++++
bsd-user/freebsd/qemu-os.h | 41 +++
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 | 96 +++++++
bsd-user/syscall_defs.h | 76 ++++++
12 files changed, 1383 insertions(+), 1 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 d0cea36..4c6acb0 100644
--- a/bsd-user/Makefile.objs
+++ b/bsd-user/Makefile.objs
@@ -1,2 +1,2 @@
obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \
- uaccess.o bsd-mem.o
+ uaccess.o bsd-mem.o $(TARGET_OS)/os-time.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..a607e06
--- /dev/null
+++ b/bsd-user/freebsd/os-time.h
@@ -0,0 +1,602 @@
+/*
+ * 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_long arg1, abi_long 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;
+}
+
+#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..7a1ed9c
--- /dev/null
+++ b/bsd-user/freebsd/qemu-os.h
@@ -0,0 +1,41 @@
+/*
+ * 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_
+
+/* 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 2efa772..cbdd363 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -2,6 +2,7 @@
* BSD syscalls
*
* Copyright (c) 2003 - 2008 Fabrice Bellard
+ * 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
@@ -36,6 +37,8 @@
#include "bsd-file.h"
#include "bsd-mem.h"
+#include "os-time.h"
+
/* #define DEBUG */
#if defined(TARGET_I386)
@@ -682,6 +685,99 @@ 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_break:
ret = do_obreak(arg1);
break;
diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h
index dea94ef..7b85835 100644
--- a/bsd-user/syscall_defs.h
+++ b/bsd-user/syscall_defs.h
@@ -83,4 +83,80 @@ struct bsd_shm_regions {
/* 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 */
+} __packed;
+
+struct target_freebsd_timeval {
+ target_freebsd_time_t tv_sec; /* seconds */
+ target_freebsd_suseconds_t tv_usec;/* and microseconds */
+} __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;
+
#endif /* ! _SYSCALL_DEFS_H_ */
--
1.7.8
- [Qemu-devel] [PATCH 13/23] bsd-user: add shims for signal related system calls, (continued)
- [Qemu-devel] [PATCH 13/23] bsd-user: add shims for signal related system calls, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 08/23] bsd-user: initialize stack with signal trampolin code and canary, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 02/23] bsd-user: add initial support for mips/mips64, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 01/23] bsd-user: initial code clean up, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 11/23] bsd-user: add shims for file related system calls, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 10/23] bsd-user: add shims for memory management related syscalls, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 09/23] bsd-user: refresh FreeBSD's system call numbers, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 12/23] bsd-user: add shims for time related system calls.,
Stacey Son <=
- [Qemu-devel] [PATCH 03/23] bsd-user: additional seperation of OS and architecture dependent code, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 04/23] bsd-user: add bsd signal emulation, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 22/23] bsd-user: add more strace formating, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 20/23] bsd-user: add shims for extended attributes system calls, Stacey Son, 2013/06/24
- [Qemu-devel] [PATCH 18/23] bsd-user: add shim for the ioctl system call, Stacey Son, 2013/06/24