diff mbox

[v3,03/19] bsd-user: move strace OS/arch dependent code to host/arch dirs

Message ID 1387281158-65744-4-git-send-email-sson@FreeBSD.org
State New
Headers show

Commit Message

Stacey Son Dec. 17, 2013, 11:52 a.m. UTC
This change moves host OS and arch dependent code for the sysarch
system call related to the -strace functionality into the
appropriate host OS and target arch directories.
---
 bsd-user/arm/syscall.h                 |   36 +++++++
 bsd-user/arm/target_arch_sysarch.h     |   78 ++++++++++++++
 bsd-user/freebsd/os-strace.h           |   29 +++++
 bsd-user/freebsd/strace.list           |   76 +++++++++++++--
 bsd-user/i386/syscall.h                |   23 ++++
 bsd-user/i386/target_arch_sysarch.h    |   78 ++++++++++++++
 bsd-user/mips/syscall.h                |   52 ++++++++++
 bsd-user/mips/target_arch_sysarch.h    |   69 +++++++++++++
 bsd-user/mips64/syscall.h              |   53 ++++++++++
 bsd-user/mips64/target_arch_sysarch.h  |   69 +++++++++++++
 bsd-user/netbsd/os-strace.h            |    1 +
 bsd-user/openbsd/os-strace.h           |    1 +
 bsd-user/qemu.h                        |   26 +++++
 bsd-user/sparc/syscall.h               |   29 +++++-
 bsd-user/sparc/target_arch_sysarch.h   |   52 ++++++++++
 bsd-user/sparc64/syscall.h             |   28 +++++-
 bsd-user/sparc64/target_arch_sysarch.h |   52 ++++++++++
 bsd-user/strace.c                      |  175 +++++++++++++++++++++----------
 bsd-user/x86_64/syscall.h              |   26 +++++-
 bsd-user/x86_64/target_arch_sysarch.h  |   76 ++++++++++++++
 20 files changed, 962 insertions(+), 67 deletions(-)
 create mode 100644 bsd-user/arm/syscall.h
 create mode 100644 bsd-user/arm/target_arch_sysarch.h
 create mode 100644 bsd-user/freebsd/os-strace.h
 create mode 100644 bsd-user/i386/target_arch_sysarch.h
 create mode 100644 bsd-user/mips/syscall.h
 create mode 100644 bsd-user/mips/target_arch_sysarch.h
 create mode 100644 bsd-user/mips64/syscall.h
 create mode 100644 bsd-user/mips64/target_arch_sysarch.h
 create mode 100644 bsd-user/netbsd/os-strace.h
 create mode 100644 bsd-user/openbsd/os-strace.h
 create mode 100644 bsd-user/sparc/target_arch_sysarch.h
 create mode 100644 bsd-user/sparc64/target_arch_sysarch.h
 create mode 100644 bsd-user/x86_64/target_arch_sysarch.h

Comments

Peter Maydell Jan. 27, 2014, 7:46 p.m. UTC | #1
On 17 December 2013 11:52, Stacey Son <sson@freebsd.org> wrote:
> This change moves host OS and arch dependent code for the sysarch
> system call related to the -strace functionality into the
> appropriate host OS and target arch directories.

This patch seems to be trying to do too much at once.

Before this patch is applied, bsd-user supports
just i386, x86_64, sparc, sparc64. You should have
a patch which refactors the code for those targets
to move them into the per-target/per-host-os
directories. Then once you've done that (and all
the other refactoring patches), have patches at
the very end of the series which simply add new arm
and mips support in the correct places.


> --- a/bsd-user/freebsd/strace.list
> +++ b/bsd-user/freebsd/strace.list
> @@ -1,7 +1,38 @@
> +/*
> + *  FreeBSD strace list
> + *
> + *
> + *  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/>.
> + */
> +
> +{ TARGET_FREEBSD_NR___acl_aclcheck_fd, "__acl_get_fd", "%s(%d, %d, %#x)", NULL, NULL },
> +{ TARGET_FREEBSD_NR___acl_aclcheck_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL },
> +{ TARGET_FREEBSD_NR___acl_aclcheck_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL },
> +{ TARGET_FREEBSD_NR___acl_delete_fd, "__acl_delete_fd", "%s(%d, %d)", NULL, NULL },
> +{ TARGET_FREEBSD_NR___acl_delete_file, "__acl_delete_file", "%s(\"%s\", %d)", NULL, NULL },
> +{ TARGET_FREEBSD_NR___acl_delete_link, "__acl_delete_link", "%s(\"%s\", %d)", NULL, NULL },
> +{ TARGET_FREEBSD_NR___acl_get_fd, "__acl_get_fd", "%s(\"%s\", %d, %#x)", NULL, NULL },
> +{ TARGET_FREEBSD_NR___acl_get_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL },
> +{ TARGET_FREEBSD_NR___acl_get_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL },
> +{ TARGET_FREEBSD_NR___acl_set_fd, "__acl_get_fd", "%s(\"%s\", %d, %#x)", NULL, NULL },
> +{ TARGET_FREEBSD_NR___acl_set_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL },
> +{ TARGET_FREEBSD_NR___acl_set_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL },
>  { TARGET_FREEBSD_NR___getcwd, "__getcwd", NULL, NULL, NULL },
>  { TARGET_FREEBSD_NR___semctl, "__semctl", NULL, NULL, NULL },
>  { TARGET_FREEBSD_NR___syscall, "__syscall", NULL, NULL, NULL },
> -{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, NULL, NULL },
> +{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, print_sysctl, NULL },
> +{ TARGET_FREEBSD_NR__umtx_op, "_umtx_op", "%s(%#x, %d, %d, %#x, %#x)", NULL, NULL },

This hunk seems to just be adding strace support for a
lot of new syscalls. It ought to be in its own patch,
not in this one.
> --- /dev/null
> +++ b/bsd-user/i386/target_arch_sysarch.h
> @@ -0,0 +1,78 @@
> +/*
> + *  i386 sysarch system call emulation
> + *
> + *  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 __ARCH_SYSARCH_H_
> +#define __ARCH_SYSARCH_H_
> +
> +#include "syscall.h"
> +
> +static inline abi_long do_freebsd_arch_sysarch(CPUX86State *env, int op,
> +        abi_ulong parms)
> +{
> +    abi_long ret = 0;
> +    abi_ulong val;
> +    int idx;
> +
> +    switch (op) {
> +    case TARGET_FREEBSD_I386_SET_GSBASE:
> +    case TARGET_FREEBSD_I386_SET_FSBASE:
> +        if (op == TARGET_FREEBSD_I386_SET_GSBASE) {
> +            idx = R_GS;
> +        } else {
> +            idx = R_FS;
> +        }
> +        if (get_user(val, parms, abi_ulong)) {
> +            return -TARGET_EFAULT;
> +        }
> +        cpu_x86_load_seg(env, idx, 0);
> +        env->segs[idx].base = val;
> +        break;
> +
> +    case TARGET_FREEBSD_I386_GET_GSBASE:
> +    case TARGET_FREEBSD_I386_GET_FSBASE:
> +        if (op == TARGET_FREEBSD_I386_GET_GSBASE) {
> +            idx = R_GS;
> +        } else {
> +            idx = R_FS;
> +        }
> +        val = env->segs[idx].base;
> +        if (put_user(val, parms, abi_ulong)) {
> +            return -TARGET_EFAULT;
> +        }
> +        break;
> +
> +    /* XXX handle the others... */
> +    default:
> +        ret = -TARGET_EINVAL;
> +        break;
> +    }
> +    return ret;
> +}

This patch adds this function, but the old version is
still in syscalls.c (it doesn't get deleted until patch 5).
This patch should be doing the refactoring, which means it
should add the code in the new correct location and also
delete it from the old.

(The patchstack should also compile and work at every
point along it, so git bisect works. If you haven't
tested that, you should do so.)

>  /*
>   * The public interface to this module.
>   */
> -void
> -print_freebsd_syscall(int num,
> -                      abi_long arg1, abi_long arg2, abi_long arg3,
> -                      abi_long arg4, abi_long arg5, abi_long arg6)
> +void print_freebsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3,
> +        abi_long arg4, abi_long arg5, abi_long arg6)
>  {
> -    print_syscall(num, freebsd_scnames, ARRAY_SIZE(freebsd_scnames),
> -                  arg1, arg2, arg3, arg4, arg5, arg6);
> +
> +    print_syscall(num, freebsd_scnames, ARRAY_SIZE(freebsd_scnames), arg1, arg2,
> +            arg3, arg4, arg5, arg6);

So this hunk (and some others) are doing nothing
but whitespace changes. QEMU general policy on this
sort of style fixup is:

(1) for lines of code your patch is touching because it's
making a functional change, it's recommended to fix those
lines to follow the coding style (where the metric of this is
"is scripts/checkpatch.pl happy with your patch?". checkpatch
is sometimes wrong, especially where preprocessor macros are
involved, so you need to exercise some judgement, but it will
spot all the nits like hardcoded tabs, missing braces, etc.
I noticed a lot of your patches are failing checkpatch.

(2) don't include in patches sections like this which
are *only* making whitespace or style changes: it makes
it harder to see what the patch is actually doing when
the functional changes are mixed up with whitespace changes

(3) mostly we prefer not to do "update whole file to
the coding style" patches, because they break git blame
and similar tools. However if you really want to do them
keep them in completely separate patches so those can
be reviewed as "should make no code changes".

thanks
-- PMM
diff mbox

Patch

diff --git a/bsd-user/arm/syscall.h b/bsd-user/arm/syscall.h
new file mode 100644
index 0000000..bc3d6e6
--- /dev/null
+++ b/bsd-user/arm/syscall.h
@@ -0,0 +1,36 @@ 
+#ifndef __ARCH_SYSCALL_H_
+#define __ARCH_SYSCALL_H_
+
+struct target_pt_regs {
+    abi_long uregs[17];
+};
+
+#define ARM_cpsr    uregs[16]
+#define ARM_pc      uregs[15]
+#define ARM_lr      uregs[14]
+#define ARM_sp      uregs[13]
+#define ARM_ip      uregs[12]
+#define ARM_fp      uregs[11]
+#define ARM_r10     uregs[10]
+#define ARM_r9      uregs[9]
+#define ARM_r8      uregs[8]
+#define ARM_r7      uregs[7]
+#define ARM_r6      uregs[6]
+#define ARM_r5      uregs[5]
+#define ARM_r4      uregs[4]
+#define ARM_r3      uregs[3]
+#define ARM_r2      uregs[2]
+#define ARM_r1      uregs[1]
+#define ARM_r0      uregs[0]
+
+#define ARM_SYSCALL_BASE    0 /* XXX: FreeBSD only */
+
+#define TARGET_FREEBSD_ARM_SYNC_ICACHE      0
+#define TARGET_FREEBSD_ARM_DRAIN_WRITEBUF   1
+#define TARGET_FREEBSD_ARM_SET_TP       2
+#define TARGET_FREEBSD_ARM_GET_TP       3
+
+#define TARGET_HW_MACHINE       "arm"
+#define TARGET_HW_MACHINE_ARCH  "armv6"
+
+#endif /* !__ARCH_SYSCALL_H_ */
diff --git a/bsd-user/arm/target_arch_sysarch.h b/bsd-user/arm/target_arch_sysarch.h
new file mode 100644
index 0000000..96d617a
--- /dev/null
+++ b/bsd-user/arm/target_arch_sysarch.h
@@ -0,0 +1,78 @@ 
+/*
+ *  arm sysarch() system call emulation
+ *
+ *  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 __ARCH_SYSARCH_H_
+#define __ARCH_SYSARCH_H_
+
+#include "syscall.h"
+#include "target_arch.h"
+
+static inline abi_long do_freebsd_arch_sysarch(CPUARMState *env, int op,
+        abi_ulong parms)
+{
+    int ret = 0;
+
+    switch (op) {
+    case TARGET_FREEBSD_ARM_SYNC_ICACHE:
+    case TARGET_FREEBSD_ARM_DRAIN_WRITEBUF:
+        break;
+
+    case TARGET_FREEBSD_ARM_SET_TP:
+        target_cpu_set_tls(env, parms);
+        break;
+
+    case TARGET_FREEBSD_ARM_GET_TP:
+        ret = target_cpu_get_tls(env);
+        break;
+
+    default:
+        ret = -TARGET_EINVAL;
+        break;
+    }
+    return ret;
+}
+
+static inline void do_freebsd_arch_print_sysarch(
+        const struct syscallname *name, abi_long arg1, abi_long arg2,
+        abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6)
+{
+
+    switch (arg1) {
+    case TARGET_FREEBSD_ARM_SYNC_ICACHE:
+        gemu_log("%s(ARM_SYNC_ICACHE, ...)", name->name);
+        break;
+
+    case TARGET_FREEBSD_ARM_DRAIN_WRITEBUF:
+        gemu_log("%s(ARM_DRAIN_WRITEBUF, ...)", name->name);
+        break;
+
+    case TARGET_FREEBSD_ARM_SET_TP:
+        gemu_log("%s(ARM_SET_TP, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2);
+        break;
+
+    case TARGET_FREEBSD_ARM_GET_TP:
+        gemu_log("%s(ARM_GET_TP, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2);
+        break;
+
+    default:
+        gemu_log("UNKNOWN OP: %d, " TARGET_ABI_FMT_lx ")", (int)arg1, arg2);
+    }
+}
+
+#endif /*!__ARCH_SYSARCH_H_ */
diff --git a/bsd-user/freebsd/os-strace.h b/bsd-user/freebsd/os-strace.h
new file mode 100644
index 0000000..a222f09
--- /dev/null
+++ b/bsd-user/freebsd/os-strace.h
@@ -0,0 +1,29 @@ 
+/*
+ *  FreeBSD dependent strace print functions
+ *
+ *  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 "target_arch_sysarch.h"    /* architecture dependent functions */
+
+
+static inline void do_os_print_sysarch(const struct syscallname *name,
+        abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4,
+        abi_long arg5, abi_long arg6)
+{
+    /* This is arch dependent */
+    do_freebsd_arch_print_sysarch(name, arg1, arg2, arg3, arg4, arg5, arg6);
+}
diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list
index 1edf412..ae2a4a3 100644
--- a/bsd-user/freebsd/strace.list
+++ b/bsd-user/freebsd/strace.list
@@ -1,7 +1,38 @@ 
+/*
+ *  FreeBSD strace list
+ *
+ *
+ *  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/>.
+ */
+
+{ TARGET_FREEBSD_NR___acl_aclcheck_fd, "__acl_get_fd", "%s(%d, %d, %#x)", NULL, NULL },
+{ TARGET_FREEBSD_NR___acl_aclcheck_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL },
+{ TARGET_FREEBSD_NR___acl_aclcheck_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL },
+{ TARGET_FREEBSD_NR___acl_delete_fd, "__acl_delete_fd", "%s(%d, %d)", NULL, NULL },
+{ TARGET_FREEBSD_NR___acl_delete_file, "__acl_delete_file", "%s(\"%s\", %d)", NULL, NULL },
+{ TARGET_FREEBSD_NR___acl_delete_link, "__acl_delete_link", "%s(\"%s\", %d)", NULL, NULL },
+{ TARGET_FREEBSD_NR___acl_get_fd, "__acl_get_fd", "%s(\"%s\", %d, %#x)", NULL, NULL },
+{ TARGET_FREEBSD_NR___acl_get_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL },
+{ TARGET_FREEBSD_NR___acl_get_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL },
+{ TARGET_FREEBSD_NR___acl_set_fd, "__acl_get_fd", "%s(\"%s\", %d, %#x)", NULL, NULL },
+{ TARGET_FREEBSD_NR___acl_set_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL },
+{ TARGET_FREEBSD_NR___acl_set_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL },
 { TARGET_FREEBSD_NR___getcwd, "__getcwd", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR___semctl, "__semctl", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR___syscall, "__syscall", NULL, NULL, NULL },
-{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, print_sysctl, NULL },
+{ TARGET_FREEBSD_NR__umtx_op, "_umtx_op", "%s(%#x, %d, %d, %#x, %#x)", NULL, NULL },
 { TARGET_FREEBSD_NR_accept, "accept", "%s(%d,%#x,%#x)", NULL, NULL },
 { TARGET_FREEBSD_NR_access, "access", "%s(\"%s\",%#o)", NULL, NULL },
 { TARGET_FREEBSD_NR_acct, "acct", NULL, NULL, NULL },
@@ -20,24 +51,41 @@ 
 { TARGET_FREEBSD_NR_connect, "connect", "%s(%d,%#x,%d)", NULL, NULL },
 { TARGET_FREEBSD_NR_dup, "dup", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_dup2, "dup2", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_eaccess, "eaccess", "%s(%s,%#x)", NULL, NULL },
 { TARGET_FREEBSD_NR_execve, "execve", NULL, print_execve, NULL },
 { TARGET_FREEBSD_NR_exit, "exit", "%s(%d)\n", NULL, NULL },
+{ TARGET_FREEBSD_NR_extattrctl, "extattrctl", "%s(\"%s\", %d, \"%s\", %d, \"%s\"", NULL, NULL },
+{ TARGET_FREEBSD_NR_extattr_delete_fd, "extattr_delete_fd", "%s(%d, %d, \"%s\")", NULL, NULL },
+{ TARGET_FREEBSD_NR_extattr_delete_file, "extattr_delete_file", "%s(\"%s\", %d, \"%s\")", NULL, NULL },
+{ TARGET_FREEBSD_NR_extattr_delete_link, "extattr_delete_link", "%s(\"%s\", %d, \"%s\")", NULL, NULL },
+{ TARGET_FREEBSD_NR_extattr_get_fd, "extattr_get_fd", "%s(%d, %d, \"%s\", %#x, %d)", NULL, NULL },
+{ TARGET_FREEBSD_NR_extattr_get_file, "extattr_get_file", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
+{ TARGET_FREEBSD_NR_extattr_get_file, "extattr_get_link", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
+{ TARGET_FREEBSD_NR_extattr_list_fd, "extattr_list_fd", "%s(%d, %d, %#x, %d)", NULL, NULL },
+{ TARGET_FREEBSD_NR_extattr_list_file, "extattr_list_file", "%s(\"%s\", %#x, %d)", NULL, NULL },
+{ TARGET_FREEBSD_NR_extattr_list_link, "extattr_list_link", "%s(\"%s\", %d, %#x, %d)", NULL, NULL },
+{ TARGET_FREEBSD_NR_extattr_set_fd, "extattr_set_fd", "%s(%d, %d, \"%s\", %#x, %d)", NULL, NULL },
+{ TARGET_FREEBSD_NR_extattr_set_file, "extattr_set_file", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
+{ TARGET_FREEBSD_NR_extattr_set_link, "extattr_set_link", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL },
 { TARGET_FREEBSD_NR_fchdir, "fchdir", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_fchflags, "fchflags", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_fchmod, "fchmod", "%s(%d,%#o)", NULL, NULL },
-{ TARGET_FREEBSD_NR_fchown, "fchown", "%s(\"%s\",%d,%d)", NULL, NULL },
+{ TARGET_FREEBSD_NR_fchown, "fchown", "%s(%d,%d,%d)", NULL, NULL },
 { TARGET_FREEBSD_NR_fcntl, "fcntl", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_fexecve, "fexecve", NULL, print_execve, NULL },
 { TARGET_FREEBSD_NR_fhopen, "fhopen", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_fhstat, "fhstat", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_fhstatfs, "fhstatfs", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_flock, "flock", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_fork, "fork", "%s()", NULL, NULL },
 { TARGET_FREEBSD_NR_fpathconf, "fpathconf", NULL, NULL, NULL },
-{ TARGET_FREEBSD_NR_fstat, "fstat", "%s(%d,%p)", NULL, NULL },
-{ TARGET_FREEBSD_NR_fstatfs, "fstatfs", "%s(%d,%p)", NULL, NULL },
+{ TARGET_FREEBSD_NR_fstat, "fstat", "%s(%d,%#x)", NULL, NULL },
+{ TARGET_FREEBSD_NR_fstatat, "fstatat", "%s(%d,\"%s\", %#x)", NULL, NULL },
+{ TARGET_FREEBSD_NR_fstatfs, "fstatfs", "%s(%d,%#x)", NULL, NULL },
 { TARGET_FREEBSD_NR_fsync, "fsync", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_ftruncate, "ftruncate", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_futimes, "futimes", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_getcontext, "getcontext", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_getdirentries, "getdirentries", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_freebsd6_mmap, "freebsd6_mmap", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_getegid, "getegid", "%s()", NULL, NULL },
@@ -63,7 +111,7 @@ 
 { TARGET_FREEBSD_NR_getsockopt, "getsockopt", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_gettimeofday, "gettimeofday", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_getuid, "getuid", "%s()", NULL, NULL },
-{ TARGET_FREEBSD_NR_ioctl, "ioctl", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_ioctl, "ioctl", NULL, print_ioctl, NULL },
 { TARGET_FREEBSD_NR_issetugid, "issetugid", "%s()", NULL, NULL },
 { TARGET_FREEBSD_NR_kevent, "kevent", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_kill, "kill", NULL, NULL, NULL },
@@ -72,6 +120,7 @@ 
 { TARGET_FREEBSD_NR_lchown, "lchown", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_link, "link", "%s(\"%s\",\"%s\")", NULL, NULL },
 { TARGET_FREEBSD_NR_listen, "listen", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_lpathconf, "lpathconf", "%s(\"%s\", %d)", NULL, NULL },
 { TARGET_FREEBSD_NR_lseek, "lseek", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_lstat, "lstat", "%s(\"%s\",%p)", NULL, NULL },
 { TARGET_FREEBSD_NR_madvise, "madvise", NULL, NULL, NULL },
@@ -96,7 +145,9 @@ 
 { TARGET_FREEBSD_NR_nanosleep, "nanosleep", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_nfssvc, "nfssvc", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_open, "open", "%s(\"%s\",%#x,%#o)", NULL, NULL },
+{ TARGET_FREEBSD_NR_openat, "openat", "%s(%d, \"%s\",%#x,%#o)", NULL, NULL },
 { TARGET_FREEBSD_NR_pathconf, "pathconf", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_pathconf, "pathconf", "%s(\"%s\", %d)", NULL, NULL },
 { TARGET_FREEBSD_NR_pipe, "pipe", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_poll, "poll", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_pread, "pread", NULL, NULL, NULL },
@@ -116,6 +167,7 @@ 
 { TARGET_FREEBSD_NR_revoke, "revoke", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_rfork, "rfork", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_rmdir, "rmdir", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_rtprio_thread, "rtprio_thread", "%s(%d, %d, %p)", NULL, NULL },
 { TARGET_FREEBSD_NR_sbrk, "sbrk", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_sched_yield, "sched_yield", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_select, "select", NULL, NULL, NULL },
@@ -123,6 +175,7 @@ 
 { TARGET_FREEBSD_NR_semop, "semop", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_sendmsg, "sendmsg", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_sendto, "sendto", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_setcontext, "setcontext", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_setegid, "setegid", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_seteuid, "seteuid", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_setgid, "setgid", NULL, NULL, NULL },
@@ -151,15 +204,24 @@ 
 { TARGET_FREEBSD_NR_sigprocmask, "sigprocmask", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_sigreturn, "sigreturn", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_sigsuspend, "sigsuspend", NULL, NULL, NULL },
-{ TARGET_FREEBSD_NR_socket, "socket", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_socket, "socket", "%s(%d,%d,%d)", NULL, NULL },
 { TARGET_FREEBSD_NR_socketpair, "socketpair", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_sstk, "sstk", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_stat, "stat", "%s(\"%s\",%p)", NULL, NULL },
 { TARGET_FREEBSD_NR_statfs, "statfs", "%s(\"%s\",%p)", NULL, NULL },
 { TARGET_FREEBSD_NR_symlink, "symlink", "%s(\"%s\",\"%s\")", NULL, NULL },
 { TARGET_FREEBSD_NR_sync, "sync", NULL, NULL, NULL },
-{ TARGET_FREEBSD_NR_sysarch, "sysarch", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_sysarch, "sysarch", NULL, print_sysarch, NULL },
 { TARGET_FREEBSD_NR_syscall, "syscall", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_thr_create, "thr_create", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_thr_exit, "thr_exit", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_thr_kill, "thr_kill", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_thr_kill2, "thr_kill2", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_thr_new, "thr_new", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_thr_self, "thr_self", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_thr_set_name, "thr_set_name", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_thr_suspend, "thr_suspend", NULL, NULL, NULL },
+{ TARGET_FREEBSD_NR_thr_wake, "thr_wake", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_truncate, "truncate", NULL, NULL, NULL },
 { TARGET_FREEBSD_NR_umask, "umask", "%s(%#o)", NULL, NULL },
 { TARGET_FREEBSD_NR_unlink, "unlink", "%s(\"%s\")", NULL, NULL },
diff --git a/bsd-user/i386/syscall.h b/bsd-user/i386/syscall.h
index 9b34c61..52de302 100644
--- a/bsd-user/i386/syscall.h
+++ b/bsd-user/i386/syscall.h
@@ -1,3 +1,23 @@ 
+/*
+ *  i386 system call definitions
+ *
+ *
+ *  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 _I386_SYSCALL_H_
+#define _I386_SYSCALL_H_
+
 /* default linux values for the selectors */
 #define __USER_CS	(0x23)
 #define __USER_DS	(0x2B)
@@ -158,4 +178,7 @@  struct target_vm86plus_struct {
 
 
 #define UNAME_MACHINE "i386"
+#define TARGET_HW_MACHINE UNAME_MACHINE
+#define TARGET_HW_MACHINE_ARCH UNAME_MACHINE
 
+#endif /* ! _I386_SYSCALL_H_ */
diff --git a/bsd-user/i386/target_arch_sysarch.h b/bsd-user/i386/target_arch_sysarch.h
new file mode 100644
index 0000000..4fa6698
--- /dev/null
+++ b/bsd-user/i386/target_arch_sysarch.h
@@ -0,0 +1,78 @@ 
+/*
+ *  i386 sysarch system call emulation
+ *
+ *  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 __ARCH_SYSARCH_H_
+#define __ARCH_SYSARCH_H_
+
+#include "syscall.h"
+
+static inline abi_long do_freebsd_arch_sysarch(CPUX86State *env, int op,
+        abi_ulong parms)
+{
+    abi_long ret = 0;
+    abi_ulong val;
+    int idx;
+
+    switch (op) {
+    case TARGET_FREEBSD_I386_SET_GSBASE:
+    case TARGET_FREEBSD_I386_SET_FSBASE:
+        if (op == TARGET_FREEBSD_I386_SET_GSBASE) {
+            idx = R_GS;
+        } else {
+            idx = R_FS;
+        }
+        if (get_user(val, parms, abi_ulong)) {
+            return -TARGET_EFAULT;
+        }
+        cpu_x86_load_seg(env, idx, 0);
+        env->segs[idx].base = val;
+        break;
+
+    case TARGET_FREEBSD_I386_GET_GSBASE:
+    case TARGET_FREEBSD_I386_GET_FSBASE:
+        if (op == TARGET_FREEBSD_I386_GET_GSBASE) {
+            idx = R_GS;
+        } else {
+            idx = R_FS;
+        }
+        val = env->segs[idx].base;
+        if (put_user(val, parms, abi_ulong)) {
+            return -TARGET_EFAULT;
+        }
+        break;
+
+    /* XXX handle the others... */
+    default:
+        ret = -TARGET_EINVAL;
+        break;
+    }
+    return ret;
+}
+
+static inline void do_freebsd_arch_print_sysarch(
+        const struct syscallname *name, abi_long arg1, abi_long arg2,
+        abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6)
+{
+
+    gemu_log("%s(%d, " TARGET_ABI_FMT_lx ", " TARGET_ABI_FMT_lx ", "
+        TARGET_ABI_FMT_lx ")", name->name, (int)arg1, arg2, arg3, arg4);
+}
+
+#endif /* !__ARCH_SYSARCH_H_ */
+
diff --git a/bsd-user/mips/syscall.h b/bsd-user/mips/syscall.h
new file mode 100644
index 0000000..aacc6dd
--- /dev/null
+++ b/bsd-user/mips/syscall.h
@@ -0,0 +1,52 @@ 
+/*
+ *  mips system call definitions
+ *
+ *
+ *  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 _MIPS_SYSCALL_H_
+#define _MIPS_SYSCALL_H_
+
+/*
+ * struct target_pt_regs defines the way the registers are stored on the stack
+ * during a system call.
+ */
+
+struct target_pt_regs {
+    /* Saved main processor registers. */
+    abi_ulong regs[32];
+
+    /* Saved special registers. */
+    abi_ulong cp0_status;
+    abi_ulong lo;
+    abi_ulong hi;
+    abi_ulong cp0_badvaddr;
+    abi_ulong cp0_cause;
+    abi_ulong cp0_epc;
+};
+
+#if defined(TARGET_WORDS_BIGENDIAN)
+#define UNAME_MACHINE "mips"
+#else
+#define UNAME_MACHINE "mipsel"
+#endif
+
+#define TARGET_HW_MACHINE       "mips"
+#define TARGET_HW_MACHINE_ARCH   UNAME_MACHINE
+
+/* sysarch() commands */
+#define TARGET_MIPS_SET_TLS     1
+#define TARGET_MIPS_GET_TLS     2
+
+#endif /* !_MIPS_SYSCALL_H_ */
diff --git a/bsd-user/mips/target_arch_sysarch.h b/bsd-user/mips/target_arch_sysarch.h
new file mode 100644
index 0000000..d333740
--- /dev/null
+++ b/bsd-user/mips/target_arch_sysarch.h
@@ -0,0 +1,69 @@ 
+/*
+ *  mips sysarch() system call emulation
+ *
+ *  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 __ARCH_SYSARCH_H_
+#define __ARCH_SYSARCH_H_
+
+#include "syscall.h"
+#include "target_arch.h"
+
+static inline abi_long do_freebsd_arch_sysarch(CPUMIPSState *env, int op,
+        abi_ulong parms)
+{
+    int ret = 0;
+
+    switch (op) {
+    case TARGET_MIPS_SET_TLS:
+        target_cpu_set_tls(env, parms);
+        break;
+
+    case TARGET_MIPS_GET_TLS:
+        if (put_user(target_cpu_get_tls(env), parms, abi_ulong)) {
+            ret = -TARGET_EFAULT;
+        }
+        break;
+
+    default:
+        ret = -TARGET_EINVAL;
+        break;
+    }
+
+    return ret;
+}
+
+static inline void do_freebsd_arch_print_sysarch(
+        const struct syscallname *name, abi_long arg1, abi_long arg2,
+        abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6)
+{
+
+    switch (arg1) {
+    case TARGET_MIPS_SET_TLS:
+        gemu_log("%s(SET_TLS, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2);
+        break;
+
+    case TARGET_MIPS_GET_TLS:
+        gemu_log("%s(GET_TLS, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2);
+        break;
+
+    default:
+        gemu_log("UNKNOWN OP: %d, " TARGET_ABI_FMT_lx ")", (int)arg1, arg2);
+    }
+}
+
+#endif /*!__ARCH_SYSARCH_H_ */
diff --git a/bsd-user/mips64/syscall.h b/bsd-user/mips64/syscall.h
new file mode 100644
index 0000000..bf4c598
--- /dev/null
+++ b/bsd-user/mips64/syscall.h
@@ -0,0 +1,53 @@ 
+/*
+ *  mips64 system call definitions
+ *
+ *
+ *  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 _MIPS64_SYSCALL_H_
+#define _MIPS64_SYSCALL_H_
+
+/*
+ * struct target_pt_regs defines the way the registers are stored on the stack
+ * during a system call.
+ */
+
+struct target_pt_regs {
+    /* Saved main processor registers. */
+    abi_ulong regs[32];
+
+    /* Saved special registers. */
+    abi_ulong cp0_status;
+    abi_ulong lo;
+    abi_ulong hi;
+    abi_ulong cp0_badvaddr;
+    abi_ulong cp0_cause;
+    abi_ulong cp0_epc;
+};
+
+
+#if defined(TARGET_WORDS_BIGENDIAN)
+#define UNAME_MACHINE "mips64"
+#else
+#define UNAME_MACHINE "mips64el"
+#endif
+
+#define TARGET_HW_MACHINE       "mips"
+#define TARGET_HW_MACHINE_ARCH  UNAME_MACHINE
+
+/* sysarch() commands */
+#define TARGET_MIPS_SET_TLS     1
+#define TARGET_MIPS_GET_TLS     2
+
+#endif /* !_MIPS64_SYSCALL_H_ */
diff --git a/bsd-user/mips64/target_arch_sysarch.h b/bsd-user/mips64/target_arch_sysarch.h
new file mode 100644
index 0000000..95b4e78
--- /dev/null
+++ b/bsd-user/mips64/target_arch_sysarch.h
@@ -0,0 +1,69 @@ 
+/*
+ *  mips64 sysarch() system call emulation
+ *
+ *  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 __ARCH_SYSARCH_H_
+#define __ARCH_SYSARCH_H_
+
+#include "syscall.h"
+#include "target_arch.h"
+
+static inline abi_long do_freebsd_arch_sysarch(CPUMIPSState *env, int op,
+        abi_ulong parms)
+{
+    int ret = 0;
+
+    switch (op) {
+    case TARGET_MIPS_SET_TLS:
+        target_cpu_set_tls(env, parms);
+        break;
+
+    case TARGET_MIPS_GET_TLS:
+        if (put_user(target_cpu_get_tls(env), parms, abi_ulong)) {
+            ret = -TARGET_EFAULT;
+        }
+        break;
+
+    default:
+        ret = -TARGET_EINVAL;
+        break;
+    }
+
+    return ret;
+}
+
+static inline void do_freebsd_arch_print_sysarch(
+        const struct syscallname *name, abi_long arg1, abi_long arg2,
+        abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6)
+{
+
+    switch (arg1) {
+    case TARGET_MIPS_SET_TLS:
+        gemu_log("%s(SET_TLS, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2);
+        break;
+
+    case TARGET_MIPS_GET_TLS:
+        gemu_log("%s(GET_TLS, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2);
+        break;
+
+    default:
+        gemu_log("UNKNOWN OP: %d, " TARGET_ABI_FMT_lx ")", (int)arg1, arg2);
+    }
+}
+
+#endif /*!__ARCH_SYSARCH_H_ */
diff --git a/bsd-user/netbsd/os-strace.h b/bsd-user/netbsd/os-strace.h
new file mode 100644
index 0000000..70cf51d
--- /dev/null
+++ b/bsd-user/netbsd/os-strace.h
@@ -0,0 +1 @@ 
+/* XXX NetBSD dependent strace print functions */
diff --git a/bsd-user/openbsd/os-strace.h b/bsd-user/openbsd/os-strace.h
new file mode 100644
index 0000000..9161390
--- /dev/null
+++ b/bsd-user/openbsd/os-strace.h
@@ -0,0 +1 @@ 
+/* XXX OpenBSD dependent strace print functions */
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index ddc74ed..b8a34c7 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -1,3 +1,19 @@ 
+/*
+ *  qemu bsd user mode definition
+ *
+ *  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_H
 #define QEMU_H
 
@@ -149,6 +165,16 @@  void fork_end(int child);
 #include "qemu/log.h"
 
 /* strace.c */
+struct syscallname {
+    int nr;
+    const char *name;
+    const char *format;
+    void (*call)(const struct syscallname *,
+                 abi_long, abi_long, abi_long,
+                 abi_long, abi_long, abi_long);
+    void (*result)(const struct syscallname *, abi_long);
+};
+
 void
 print_freebsd_syscall(int num,
                       abi_long arg1, abi_long arg2, abi_long arg3,
diff --git a/bsd-user/sparc/syscall.h b/bsd-user/sparc/syscall.h
index 5a9bb7e..3a5b1e2 100644
--- a/bsd-user/sparc/syscall.h
+++ b/bsd-user/sparc/syscall.h
@@ -1,3 +1,23 @@ 
+/*
+ *  sparc dependent system call definitions
+ *
+ *
+ *  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 _SPARC_SYSCALL_H_
+#define _SPARC_SYSCALL_H_
+
 struct target_pt_regs {
 	abi_ulong psr;
 	abi_ulong pc;
@@ -6,4 +26,11 @@  struct target_pt_regs {
 	abi_ulong u_regs[16];
 };
 
-#define UNAME_MACHINE "sun4"
+#define UNAME_MACHINE           "sun4"
+#define TARGET_HW_MACHINE       "sparc"
+#define TARGET_HW_MACHINE_ARCH  "sparc"
+
+#define TARGET_SPARC_UTRAP_INSTALL      1
+#define TARGET_SPARC_SIGTRAMP_INSTALL   2
+
+#endif /* ! _SPARC_SYSCALL_H_ */
diff --git a/bsd-user/sparc/target_arch_sysarch.h b/bsd-user/sparc/target_arch_sysarch.h
new file mode 100644
index 0000000..454c084
--- /dev/null
+++ b/bsd-user/sparc/target_arch_sysarch.h
@@ -0,0 +1,52 @@ 
+/*
+ *  SPARC sysarch() system call emulation
+ *
+ *  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 __ARCH_SYSARCH_H_
+#define __ARCH_SYSARCH_H_
+
+#include "syscall.h"
+
+static inline abi_long do_freebsd_arch_sysarch(void *env, int op,
+        abi_ulong parms)
+{
+    int ret = 0;
+
+    switch (op) {
+    case TARGET_SPARC_SIGTRAMP_INSTALL:
+        /* XXX not currently handled */
+    case TARGET_SPARC_UTRAP_INSTALL:
+        /* XXX not currently handled */
+    default:
+        ret = -TARGET_EINVAL;
+        break;
+    }
+
+    return ret;
+}
+
+static inline void do_freebsd_arch_print_sysarch(
+        const struct syscallname *name, abi_long arg1, abi_long arg2,
+        abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6)
+{
+
+    gemu_log("%s(%d, " TARGET_ABI_FMT_lx ", " TARGET_ABI_FMT_lx ", "
+        TARGET_ABI_FMT_lx ")", name->name, (int)arg1, arg2, arg3, arg4);
+}
+
+#endif /*!__ARCH_SYSARCH_H_ */
diff --git a/bsd-user/sparc64/syscall.h b/bsd-user/sparc64/syscall.h
index 81a816d..58cc38d 100644
--- a/bsd-user/sparc64/syscall.h
+++ b/bsd-user/sparc64/syscall.h
@@ -1,3 +1,22 @@ 
+/*
+ *  sparc64 dependent system call definitions
+ *
+ *
+ *  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 _SPARC64_SYSCALL_H_
+#define _SPARC64_SYSCALL_H_
 struct target_pt_regs {
 	abi_ulong u_regs[16];
 	abi_ulong tstate;
@@ -7,4 +26,11 @@  struct target_pt_regs {
 	abi_ulong fprs;
 };
 
-#define UNAME_MACHINE "sun4u"
+#define UNAME_MACHINE           "sun4u"
+#define TARGET_HW_MACHINE       "sparc"
+#define TARGET_HW_MACHINE_ARCH  "sparc64"
+
+#define TARGET_SPARC_UTRAP_INSTALL      1
+#define TARGET_SPARC_SIGTRAMP_INSTALL   2
+
+#endif /* !_SPARC64_SYSCALL_H_ */
diff --git a/bsd-user/sparc64/target_arch_sysarch.h b/bsd-user/sparc64/target_arch_sysarch.h
new file mode 100644
index 0000000..84e1339
--- /dev/null
+++ b/bsd-user/sparc64/target_arch_sysarch.h
@@ -0,0 +1,52 @@ 
+/*
+ *  SPARC64 sysarch() system call emulation
+ *
+ *  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 __ARCH_SYSARCH_H_
+#define __ARCH_SYSARCH_H_
+
+#include "syscall.h"
+
+static inline abi_long do_freebsd_arch_sysarch(void *env, int op,
+        abi_ulong parms)
+{
+    int ret = 0;
+
+    switch (op) {
+    case TARGET_SPARC_SIGTRAMP_INSTALL:
+        /* XXX not currently handled */
+    case TARGET_SPARC_UTRAP_INSTALL:
+        /* XXX not currently handled */
+    default:
+        ret = -TARGET_EINVAL;
+        break;
+    }
+
+    return ret;
+}
+
+static inline void do_freebsd_arch_print_sysarch(
+        const struct syscallname *name, abi_long arg1, abi_long arg2,
+        abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6)
+{
+
+    gemu_log("%s(%d, " TARGET_ABI_FMT_lx ", " TARGET_ABI_FMT_lx ", "
+        TARGET_ABI_FMT_lx ")", name->name, (int)arg1, arg2, arg3, arg4);
+}
+
+#endif /*!__ARCH_SYSARCH_H_ */
diff --git a/bsd-user/strace.c b/bsd-user/strace.c
index d73bbca..60aabc3 100644
--- a/bsd-user/strace.c
+++ b/bsd-user/strace.c
@@ -1,37 +1,73 @@ 
+/*
+ *  System call tracing and debugging
+ *
+ *
+ *  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 <stdio.h>
 #include <errno.h>
 #include <sys/select.h>
 #include <sys/types.h>
 #include <unistd.h>
 #include <sys/syscall.h>
+#include <sys/ioccom.h>
+#include <ctype.h>
+
 #include "qemu.h"
 
-int do_strace=0;
+#include "os-strace.h"  /* OS dependent strace print functions */
 
-struct syscallname {
-    int nr;
-    const char *name;
-    const char *format;
-    void (*call)(const struct syscallname *,
-                 abi_long, abi_long, abi_long,
-                 abi_long, abi_long, abi_long);
-    void (*result)(const struct syscallname *, abi_long);
-};
+int do_strace;
 
 /*
  * Utility functions
  */
 
-static void
-print_execve(const struct syscallname *name,
-             abi_long arg1, abi_long arg2, abi_long arg3,
-             abi_long arg4, abi_long arg5, abi_long arg6)
+static void print_sysctl(const struct syscallname *name, abi_long arg1,
+        abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5,
+        abi_long arg6)
+{
+    uint32_t i;
+    int32_t *namep;
+
+    gemu_log("%s({ ", name->name);
+    namep = lock_user(VERIFY_READ, arg1, sizeof(int32_t) * arg2, 1);
+    if (namep) {
+        int32_t *p = namep;
+
+        for (i = 0; i < (uint32_t)arg2; i++) {
+            gemu_log("%d ", tswap32(*p++));
+        }
+        unlock_user(namep, arg1, 0);
+    }
+    gemu_log("}, %u, 0x" TARGET_ABI_FMT_lx ", 0x" TARGET_ABI_FMT_lx ", 0x"
+        TARGET_ABI_FMT_lx ", 0x" TARGET_ABI_FMT_lx ")",
+        (uint32_t)arg2, arg3, arg4, arg5, arg6);
+}
+
+static void print_execve(const struct syscallname *name, abi_long arg1,
+        abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5,
+        abi_long arg6)
 {
     abi_ulong arg_ptr_addr;
     char *s;
 
-    if (!(s = lock_user_string(arg1)))
+    s = lock_user_string(arg1);
+    if (s == NULL) {
         return;
+    }
     gemu_log("%s(\"%s\",{", name->name, s);
     unlock_user(s, arg1, 0);
 
@@ -39,29 +75,56 @@  print_execve(const struct syscallname *name,
         abi_ulong *arg_ptr, arg_addr;
 
         arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1);
-        if (!arg_ptr)
+        if (!arg_ptr) {
             return;
+        }
         arg_addr = tswapl(*arg_ptr);
         unlock_user(arg_ptr, arg_ptr_addr, 0);
-        if (!arg_addr)
+        if (!arg_addr) {
             break;
+        }
         if ((s = lock_user_string(arg_addr))) {
             gemu_log("\"%s\",", s);
             unlock_user(s, arg_addr, 0);
         }
     }
-
     gemu_log("NULL})");
 }
 
+static void print_ioctl(const struct syscallname *name,
+        abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4,
+        abi_long arg5, abi_long arg6)
+{
+    /* Decode the ioctl request */
+    gemu_log("%s(%d, 0x%0lx { IO%s%s GRP:0x%x('%c') CMD:%d LEN:%d }, 0x"
+            TARGET_ABI_FMT_lx ", ...)",
+            name->name,
+            (int)arg1,
+            (unsigned long)arg2,
+            arg2 & IOC_OUT ? "R" : "",
+            arg2 & IOC_IN ? "W" : "",
+            (unsigned)IOCGROUP(arg2),
+            isprint(IOCGROUP(arg2)) ? (char)IOCGROUP(arg2) : '?',
+            (int)arg2 & 0xFF,
+            (int)IOCPARM_LEN(arg2),
+            arg3);
+}
+
+static void print_sysarch(const struct syscallname *name, abi_long arg1,
+        abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5,
+        abi_long arg6)
+{
+    /* This is os dependent. */
+    do_os_print_sysarch(name, arg1, arg2, arg3, arg4, arg5, arg6);
+}
+
 /*
  * Variants for the return value output function
  */
 
-static void
-print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
+static void print_syscall_ret_addr(const struct syscallname *name, abi_long ret)
 {
-if( ret == -1 ) {
+    if (ret == -1) {
         gemu_log(" = -1 errno=%d (%s)\n", errno, strerror(errno));
     } else {
         gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret);
@@ -90,10 +153,9 @@  static const struct syscallname openbsd_scnames[] = {
 #include "openbsd/strace.list"
 };
 
-static void
-print_syscall(int num, const struct syscallname *scnames, unsigned int nscnames,
-              abi_long arg1, abi_long arg2, abi_long arg3,
-              abi_long arg4, abi_long arg5, abi_long arg6)
+static void print_syscall(int num, const struct syscallname *scnames,
+        unsigned int nscnames, abi_long arg1, abi_long arg2, abi_long arg3,
+        abi_long arg4, abi_long arg5, abi_long arg6)
 {
     unsigned int i;
     const char *format="%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld ","
@@ -102,36 +164,37 @@  print_syscall(int num, const struct syscallname *scnames, unsigned int nscnames,
 
     gemu_log("%d ", getpid() );
 
-    for (i = 0; i < nscnames; i++)
+    for (i = 0; i < nscnames; i++) {
         if (scnames[i].nr == num) {
             if (scnames[i].call != NULL) {
                 scnames[i].call(&scnames[i], arg1, arg2, arg3, arg4, arg5,
-                                arg6);
+                        arg6);
             } else {
                 /* XXX: this format system is broken because it uses
                    host types and host pointers for strings */
-                if (scnames[i].format != NULL)
+                if (scnames[i].format != NULL) {
                     format = scnames[i].format;
-                gemu_log(format, scnames[i].name, arg1, arg2, arg3, arg4,
-                         arg5, arg6);
+                }
+                gemu_log(format, scnames[i].name, arg1, arg2, arg3, arg4, arg5,
+                        arg6);
             }
             return;
         }
+    }
     gemu_log("Unknown syscall %d\n", num);
 }
 
-static void
-print_syscall_ret(int num, abi_long ret, const struct syscallname *scnames,
-                  unsigned int nscnames)
+static void print_syscall_ret(int num, abi_long ret,
+        const struct syscallname *scnames, unsigned int nscnames)
 {
     unsigned int i;
 
-    for (i = 0; i < nscnames; i++)
+    for (i = 0; i < nscnames; i++) {
         if (scnames[i].nr == num) {
             if (scnames[i].result != NULL) {
                 scnames[i].result(&scnames[i], ret);
             } else {
-                if( ret < 0 ) {
+                if (ret < 0) {
                     gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret,
                              strerror(-ret));
                 } else {
@@ -140,52 +203,50 @@  print_syscall_ret(int num, abi_long ret, const struct syscallname *scnames,
             }
             break;
         }
+    }
 }
 
 /*
  * The public interface to this module.
  */
-void
-print_freebsd_syscall(int num,
-                      abi_long arg1, abi_long arg2, abi_long arg3,
-                      abi_long arg4, abi_long arg5, abi_long arg6)
+void print_freebsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3,
+        abi_long arg4, abi_long arg5, abi_long arg6)
 {
-    print_syscall(num, freebsd_scnames, ARRAY_SIZE(freebsd_scnames),
-                  arg1, arg2, arg3, arg4, arg5, arg6);
+
+    print_syscall(num, freebsd_scnames, ARRAY_SIZE(freebsd_scnames), arg1, arg2,
+            arg3, arg4, arg5, arg6);
 }
 
-void
-print_freebsd_syscall_ret(int num, abi_long ret)
+void print_freebsd_syscall_ret(int num, abi_long ret)
 {
+
     print_syscall_ret(num, ret, freebsd_scnames, ARRAY_SIZE(freebsd_scnames));
 }
 
-void
-print_netbsd_syscall(int num,
-                      abi_long arg1, abi_long arg2, abi_long arg3,
-                      abi_long arg4, abi_long arg5, abi_long arg6)
+void print_netbsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3,
+        abi_long arg4, abi_long arg5, abi_long arg6)
 {
+
     print_syscall(num, netbsd_scnames, ARRAY_SIZE(netbsd_scnames),
                   arg1, arg2, arg3, arg4, arg5, arg6);
 }
 
-void
-print_netbsd_syscall_ret(int num, abi_long ret)
+void print_netbsd_syscall_ret(int num, abi_long ret)
 {
+
     print_syscall_ret(num, ret, netbsd_scnames, ARRAY_SIZE(netbsd_scnames));
 }
 
-void
-print_openbsd_syscall(int num,
-                      abi_long arg1, abi_long arg2, abi_long arg3,
-                      abi_long arg4, abi_long arg5, abi_long arg6)
+void print_openbsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3,
+        abi_long arg4, abi_long arg5, abi_long arg6)
 {
-    print_syscall(num, openbsd_scnames, ARRAY_SIZE(openbsd_scnames),
-                  arg1, arg2, arg3, arg4, arg5, arg6);
+
+    print_syscall(num, openbsd_scnames, ARRAY_SIZE(openbsd_scnames), arg1, arg2,
+            arg3, arg4, arg5, arg6);
 }
 
-void
-print_openbsd_syscall_ret(int num, abi_long ret)
+void print_openbsd_syscall_ret(int num, abi_long ret)
 {
+
     print_syscall_ret(num, ret, openbsd_scnames, ARRAY_SIZE(openbsd_scnames));
 }
diff --git a/bsd-user/x86_64/syscall.h b/bsd-user/x86_64/syscall.h
index 630514a..4fff6a5 100644
--- a/bsd-user/x86_64/syscall.h
+++ b/bsd-user/x86_64/syscall.h
@@ -1,3 +1,23 @@ 
+/*
+ *  x86_64 system call definitions
+ *
+ *
+ *  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 _X86_64_SYSCALL_H_
+#define _X86_64_SYSCALL_H_
+
 #define __USER_CS	(0x33)
 #define __USER_DS	(0x2B)
 
@@ -108,9 +128,13 @@  struct target_msqid64_ds {
 #define TARGET_FREEBSD_AMD64_SET_GSBASE	131
 
 
-#define UNAME_MACHINE "x86_64"
+#define UNAME_MACHINE           "x86_64"
+#define TARGET_HW_MACHINE       "amd64"
+#define TARGET_HW_MACHINE_ARCH  "amd64"
 
 #define TARGET_ARCH_SET_GS 0x1001
 #define TARGET_ARCH_SET_FS 0x1002
 #define TARGET_ARCH_GET_FS 0x1003
 #define TARGET_ARCH_GET_GS 0x1004
+
+#endif /* ! _X86_64_SYSCALL_H_ */
diff --git a/bsd-user/x86_64/target_arch_sysarch.h b/bsd-user/x86_64/target_arch_sysarch.h
new file mode 100644
index 0000000..6d09d50
--- /dev/null
+++ b/bsd-user/x86_64/target_arch_sysarch.h
@@ -0,0 +1,76 @@ 
+/*
+ *  x86_64 sysarch() syscall emulation
+ *
+ *
+ *  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 __ARCH_SYSARCH_H_
+#define __ARCH_SYSARCH_H_
+
+#include "syscall.h"
+
+static inline abi_long do_freebsd_arch_sysarch(CPUX86State *env, int op,
+        abi_ulong parms)
+{
+    abi_long ret = 0;
+    abi_ulong val;
+    int idx;
+
+    switch (op) {
+    case TARGET_FREEBSD_AMD64_SET_GSBASE:
+    case TARGET_FREEBSD_AMD64_SET_FSBASE:
+        if (op == TARGET_FREEBSD_AMD64_SET_GSBASE) {
+            idx = R_GS;
+        } else {
+            idx = R_FS;
+        }
+        if (get_user(val, parms, abi_ulong)) {
+            return -TARGET_EFAULT;
+        }
+        cpu_x86_load_seg(env, idx, 0);
+        env->segs[idx].base = val;
+        break;
+
+    case TARGET_FREEBSD_AMD64_GET_GSBASE:
+    case TARGET_FREEBSD_AMD64_GET_FSBASE:
+        if (op == TARGET_FREEBSD_AMD64_GET_GSBASE) {
+            idx = R_GS;
+        } else {
+            idx = R_FS;
+        }
+        val = env->segs[idx].base;
+        if (put_user(val, parms, abi_ulong)) {
+            return -TARGET_EFAULT;
+        }
+        break;
+
+    /* XXX handle the others... */
+    default:
+        ret = -TARGET_EINVAL;
+        break;
+    }
+    return ret;
+}
+
+static inline void do_freebsd_arch_print_sysarch(
+        const struct syscallname *name, abi_long arg1, abi_long arg2,
+        abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6)
+{
+
+    gemu_log("%s(%d, " TARGET_ABI_FMT_lx ", " TARGET_ABI_FMT_lx ", "
+        TARGET_ABI_FMT_lx ")", name->name, (int)arg1, arg2, arg3, arg4);
+}
+
+#endif /*! __ARCH_SYSARCH_H_ */