[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<OSTOP) */
-#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
- [Qemu-devel] [PATCH v3 00/19] bsd-user: Add system call and mips/arm support., Stacey Son, 2013/12/17
- Message not available
- Message not available
- Message not available
- Message not available
- Message not available
- Message not available
- Message not available
- Message not available
- Message not available
- [Qemu-devel] [PATCH v3 06/19] bsd-user: add support for freebsd time related system calls,
Stacey Son <=
- Message not available
- Message not available
- Message not available
- Message not available
- Message not available
- Message not available
- Message not available
- Message not available
- Message not available
- Message not available