qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/4] bsd-user:  Update Queue
@ 2014-06-20  0:19 Sean Bruno
  2014-06-20  0:19 ` [Qemu-devel] [PATCH 1/4] bsd-user: Implement new syscall print_sysarch and add strace support Sean Bruno
                   ` (4 more replies)
  0 siblings, 5 replies; 11+ messages in thread
From: Sean Bruno @ 2014-06-20  0:19 UTC (permalink / raw)
  To: qemu-devel

This patchset brings us a couple of steps closer to the FreeBSD Development
tree, Stacey Son's bsd-user branch and qemu-devel port maintained out of tree.

These patches are designed to begin to break apart the architectures
in bsd-user for the upcoming new arch support patches.

Patch 1/4 of this set is a reset of Patch 5/10 from the last bsd-user
update push.  It addresses Peter Maydell's commentary about missing and
redundant code for print_sysarch and the build breakage for netbsd and
openbsd bsd-user programs.

Patch 4/4 of this set includes Patch 10/10 from the last bsd-user update
push.  It includes the code that uses the #define vaules as to avoid the
possibility of commiting dead code.

Sean Bruno (2):
  bsd-user: Implement new syscall print_sysarch and add strace support
  bsd-user:  Rename struct linux_binprm to struct bsd_binprm

Stacey Son (2):
  bsd-user: move arch/OS dependent code out of main.c
  bsd-user: move arch/OS dependent code out of syscall.c

 bsd-user/Makefile.objs                  |   2 +-
 bsd-user/bsdload.c                      | 170 ++++--
 bsd-user/elfload.c                      |  11 +-
 bsd-user/freebsd/host_os.h              |  46 ++
 bsd-user/freebsd/os-strace.h            |  29 +
 bsd-user/freebsd/os-sys.c               | 285 ++++++++++
 bsd-user/freebsd/strace.list            |   2 +-
 bsd-user/freebsd/target_os_stack.h      | 157 ++++++
 bsd-user/freebsd/target_os_vmparam.h    |  23 +
 bsd-user/i386/syscall.h                 |  23 +
 bsd-user/i386/target_arch.h             |  13 +
 bsd-user/i386/target_arch_cpu.c         |  79 +++
 bsd-user/i386/target_arch_cpu.h         | 300 +++++++++++
 bsd-user/i386/target_arch_sigtramp.h    |  11 +
 bsd-user/i386/target_arch_sysarch.h     |  78 +++
 bsd-user/i386/target_arch_vmparam.h     |  28 +
 bsd-user/i386/target_signal.h           |   6 -
 bsd-user/main.c                         | 927 +++++++-------------------------
 bsd-user/mmap.c                         |   2 +-
 bsd-user/netbsd/host_os.h               |  31 ++
 bsd-user/netbsd/os-strace.h             |  29 +
 bsd-user/netbsd/os-sys.c                |  46 ++
 bsd-user/netbsd/target_os_stack.h       |  33 ++
 bsd-user/netbsd/target_os_vmparam.h     |  23 +
 bsd-user/openbsd/host_os.h              |  31 ++
 bsd-user/openbsd/os-strace.h            |  29 +
 bsd-user/openbsd/os-sys.c               |  46 ++
 bsd-user/openbsd/target_os_stack.h      |  33 ++
 bsd-user/openbsd/target_os_vmparam.h    |  23 +
 bsd-user/qemu.h                         |  50 +-
 bsd-user/sparc/syscall.h                |  29 +-
 bsd-user/sparc/target_arch.h            |  11 +
 bsd-user/sparc/target_arch_cpu.c        | 113 ++++
 bsd-user/sparc/target_arch_cpu.h        | 158 ++++++
 bsd-user/sparc/target_arch_sigtramp.h   |  11 +
 bsd-user/sparc/target_arch_sysarch.h    |  52 ++
 bsd-user/sparc/target_arch_vmparam.h    |  37 ++
 bsd-user/sparc/target_signal.h          |   5 -
 bsd-user/sparc64/syscall.h              |  28 +-
 bsd-user/sparc64/target_arch.h          |  11 +
 bsd-user/sparc64/target_arch_cpu.c      | 118 ++++
 bsd-user/sparc64/target_arch_cpu.h      | 191 +++++++
 bsd-user/sparc64/target_arch_sigtramp.h |  11 +
 bsd-user/sparc64/target_arch_sysarch.h  |  52 ++
 bsd-user/sparc64/target_arch_vmparam.h  |  37 ++
 bsd-user/sparc64/target_signal.h        |   5 -
 bsd-user/strace.c                       |  10 +
 bsd-user/syscall.c                      | 210 +-------
 bsd-user/x86_64/syscall.h               |  26 +-
 bsd-user/x86_64/target_arch.h           |  13 +
 bsd-user/x86_64/target_arch_cpu.c       |  79 +++
 bsd-user/x86_64/target_arch_cpu.h       | 322 +++++++++++
 bsd-user/x86_64/target_arch_sigtramp.h  |  11 +
 bsd-user/x86_64/target_arch_sysarch.h   |  76 +++
 bsd-user/x86_64/target_arch_vmparam.h   |  28 +
 bsd-user/x86_64/target_signal.h         |   5 -
 56 files changed, 3207 insertions(+), 1008 deletions(-)
 create mode 100644 bsd-user/freebsd/host_os.h
 create mode 100644 bsd-user/freebsd/os-strace.h
 create mode 100644 bsd-user/freebsd/os-sys.c
 create mode 100644 bsd-user/freebsd/target_os_stack.h
 create mode 100644 bsd-user/freebsd/target_os_vmparam.h
 create mode 100644 bsd-user/i386/target_arch.h
 create mode 100644 bsd-user/i386/target_arch_cpu.c
 create mode 100644 bsd-user/i386/target_arch_cpu.h
 create mode 100644 bsd-user/i386/target_arch_sigtramp.h
 create mode 100644 bsd-user/i386/target_arch_sysarch.h
 create mode 100644 bsd-user/i386/target_arch_vmparam.h
 create mode 100644 bsd-user/netbsd/host_os.h
 create mode 100644 bsd-user/netbsd/os-strace.h
 create mode 100644 bsd-user/netbsd/os-sys.c
 create mode 100644 bsd-user/netbsd/target_os_stack.h
 create mode 100644 bsd-user/netbsd/target_os_vmparam.h
 create mode 100644 bsd-user/openbsd/host_os.h
 create mode 100644 bsd-user/openbsd/os-strace.h
 create mode 100644 bsd-user/openbsd/os-sys.c
 create mode 100644 bsd-user/openbsd/target_os_stack.h
 create mode 100644 bsd-user/openbsd/target_os_vmparam.h
 create mode 100644 bsd-user/sparc/target_arch.h
 create mode 100644 bsd-user/sparc/target_arch_cpu.c
 create mode 100644 bsd-user/sparc/target_arch_cpu.h
 create mode 100644 bsd-user/sparc/target_arch_sigtramp.h
 create mode 100644 bsd-user/sparc/target_arch_sysarch.h
 create mode 100644 bsd-user/sparc/target_arch_vmparam.h
 create mode 100644 bsd-user/sparc64/target_arch.h
 create mode 100644 bsd-user/sparc64/target_arch_cpu.c
 create mode 100644 bsd-user/sparc64/target_arch_cpu.h
 create mode 100644 bsd-user/sparc64/target_arch_sigtramp.h
 create mode 100644 bsd-user/sparc64/target_arch_sysarch.h
 create mode 100644 bsd-user/sparc64/target_arch_vmparam.h
 create mode 100644 bsd-user/x86_64/target_arch.h
 create mode 100644 bsd-user/x86_64/target_arch_cpu.c
 create mode 100644 bsd-user/x86_64/target_arch_cpu.h
 create mode 100644 bsd-user/x86_64/target_arch_sigtramp.h
 create mode 100644 bsd-user/x86_64/target_arch_sysarch.h
 create mode 100644 bsd-user/x86_64/target_arch_vmparam.h

-- 
2.0.0

^ permalink raw reply	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH 1/4] bsd-user: Implement new syscall print_sysarch and add strace support
  2014-06-20  0:19 [Qemu-devel] [PATCH 0/4] bsd-user: Update Queue Sean Bruno
@ 2014-06-20  0:19 ` Sean Bruno
  2014-07-03 13:19   ` Peter Maydell
  2014-06-20  0:19 ` [Qemu-devel] [PATCH 2/4] bsd-user: move arch/OS dependent code out of main.c Sean Bruno
                   ` (3 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Sean Bruno @ 2014-06-20  0:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sean Bruno

Signed-off-by: Sean Bruno <sbruno@freebsd.org>
Signed-off-by: Stacey Son <sson@freebsd.org>
---
 bsd-user/freebsd/os-strace.h           | 35 +++++++++++++++
 bsd-user/freebsd/strace.list           |  2 +-
 bsd-user/i386/syscall.h                | 21 +++++++++
 bsd-user/i386/target_arch_sysarch.h    | 78 ++++++++++++++++++++++++++++++++++
 bsd-user/netbsd/os-strace.h            | 37 ++++++++++++++++
 bsd-user/openbsd/os-strace.h           | 37 ++++++++++++++++
 bsd-user/qemu.h                        |  3 ++
 bsd-user/sparc/syscall.h               | 27 +++++++++++-
 bsd-user/sparc/target_arch_sysarch.h   | 52 +++++++++++++++++++++++
 bsd-user/sparc64/syscall.h             | 26 +++++++++++-
 bsd-user/sparc64/target_arch_sysarch.h | 52 +++++++++++++++++++++++
 bsd-user/strace.c                      | 10 +++++
 bsd-user/syscall.c                     | 63 +--------------------------
 bsd-user/x86_64/syscall.h              | 24 ++++++++++-
 bsd-user/x86_64/target_arch_sysarch.h  | 76 +++++++++++++++++++++++++++++++++
 15 files changed, 477 insertions(+), 66 deletions(-)
 create mode 100644 bsd-user/freebsd/os-strace.h
 create mode 100644 bsd-user/i386/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

diff --git a/bsd-user/freebsd/os-strace.h b/bsd-user/freebsd/os-strace.h
new file mode 100644
index 0000000..c856450
--- /dev/null
+++ b/bsd-user/freebsd/os-strace.h
@@ -0,0 +1,35 @@
+/*
+ *  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);
+}
+
+/* sysarch() is architecture dependent. */
+abi_long do_bsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2)
+{
+    return do_freebsd_arch_sysarch(cpu_env, arg1, arg2);
+}
diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list
index 2800a2d..55f5ff8 100644
--- a/bsd-user/freebsd/strace.list
+++ b/bsd-user/freebsd/strace.list
@@ -209,7 +209,7 @@
 { 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", "%s(%#x, %#x, %d)", NULL, NULL },
 { TARGET_FREEBSD_NR_thr_exit, "thr_exit", "%s(%#x)", NULL, NULL },
diff --git a/bsd-user/i386/syscall.h b/bsd-user/i386/syscall.h
index 9b34c61..8028fc8 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)
@@ -159,3 +179,4 @@ struct target_vm86plus_struct {
 
 #define UNAME_MACHINE "i386"
 
+#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/netbsd/os-strace.h b/bsd-user/netbsd/os-strace.h
new file mode 100644
index 0000000..20dfd4b
--- /dev/null
+++ b/bsd-user/netbsd/os-strace.h
@@ -0,0 +1,37 @@
+/*
+ *  NetBSD dependent strace print functions
+ *
+ *  Copyright (c) 2014 Sean Bruno <sbruno@freebsd.org>
+ *
+ *  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)
+{
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+/* sysarch() is architecture dependent. */
+abi_long do_bsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2)
+{
+    qemu_log("qemu: Unsupported syscall sysarch()\n");
+    return -TARGET_ENOSYS;
+}
+
diff --git a/bsd-user/openbsd/os-strace.h b/bsd-user/openbsd/os-strace.h
new file mode 100644
index 0000000..277b96c
--- /dev/null
+++ b/bsd-user/openbsd/os-strace.h
@@ -0,0 +1,37 @@
+/*
+ *  OpenBSD dependent strace print functions
+ *
+ *  Copyright (c) 2014 Sean Bruno <sbruno@freebsd.org>
+ *
+ *  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)
+{
+    qemu_log("qemu: Unsupported syscall %s\n", __func__);
+    return -TARGET_ENOSYS;
+}
+
+/* sysarch() is architecture dependent. */
+abi_long do_bsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall sysarch()\n");
+    return -TARGET_ENOSYS;
+}
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 5362297..658999b 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -225,6 +225,9 @@ void mmap_fork_end(int child);
 /* main.c */
 extern unsigned long x86_stack_size;
 
+/* os-strace.h */
+abi_long do_bsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2);
+
 /* user access */
 
 #define VERIFY_READ 0
diff --git a/bsd-user/sparc/syscall.h b/bsd-user/sparc/syscall.h
index 5a9bb7e..7ed2152 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,9 @@ struct target_pt_regs {
 	abi_ulong u_regs[16];
 };
 
-#define UNAME_MACHINE "sun4"
+#define UNAME_MACHINE           "sun4"
+
+#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..8571092 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,9 @@ struct target_pt_regs {
 	abi_ulong fprs;
 };
 
-#define UNAME_MACHINE "sun4u"
+#define UNAME_MACHINE           "sun4u"
+
+#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 e33dd4d..60aabc3 100644
--- a/bsd-user/strace.c
+++ b/bsd-user/strace.c
@@ -27,6 +27,8 @@
 
 #include "qemu.h"
 
+#include "os-strace.h"  /* OS dependent strace print functions */
+
 int do_strace;
 
 /*
@@ -108,6 +110,14 @@ static void print_ioctl(const struct syscallname *name,
             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
  */
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index a4d1583..b3efc3c 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -96,67 +96,6 @@ static abi_long do_obreak(abi_ulong new_brk)
     return 0;
 }
 
-#if defined(TARGET_I386)
-static abi_long do_freebsd_sysarch(CPUX86State *env, int op, abi_ulong parms)
-{
-    abi_long ret = 0;
-    abi_ulong val;
-    int idx;
-
-    switch(op) {
-#ifdef TARGET_ABI32
-    case TARGET_FREEBSD_I386_SET_GSBASE:
-    case TARGET_FREEBSD_I386_SET_FSBASE:
-        if (op == TARGET_FREEBSD_I386_SET_GSBASE)
-#else
-    case TARGET_FREEBSD_AMD64_SET_GSBASE:
-    case TARGET_FREEBSD_AMD64_SET_FSBASE:
-        if (op == TARGET_FREEBSD_AMD64_SET_GSBASE)
-#endif
-            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;
-#ifdef TARGET_ABI32
-    case TARGET_FREEBSD_I386_GET_GSBASE:
-    case TARGET_FREEBSD_I386_GET_FSBASE:
-        if (op == TARGET_FREEBSD_I386_GET_GSBASE)
-#else
-    case TARGET_FREEBSD_AMD64_GET_GSBASE:
-    case TARGET_FREEBSD_AMD64_GET_FSBASE:
-        if (op == TARGET_FREEBSD_AMD64_GET_GSBASE)
-#endif
-            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;
-}
-#endif
-
-#ifdef TARGET_SPARC
-static abi_long do_freebsd_sysarch(void *env, int op, abi_ulong parms)
-{
-    /* XXX handle
-     * TARGET_FREEBSD_SPARC_UTRAP_INSTALL,
-     * TARGET_FREEBSD_SPARC_SIGTRAMP_INSTALL
-     */
-    return -TARGET_EINVAL;
-}
-#endif
-
 #ifdef __FreeBSD__
 /*
  * XXX this uses the undocumented oidfmt interface to find the kind of
@@ -393,7 +332,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
         break;
 #endif
     case TARGET_FREEBSD_NR_sysarch:
-        ret = do_freebsd_sysarch(cpu_env, arg1, arg2);
+        ret = do_bsd_sysarch(cpu_env, arg1, arg2);
         break;
     case TARGET_FREEBSD_NR_syscall:
     case TARGET_FREEBSD_NR___syscall:
diff --git a/bsd-user/x86_64/syscall.h b/bsd-user/x86_64/syscall.h
index 630514a..4e77235 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,11 @@ struct target_msqid64_ds {
 #define TARGET_FREEBSD_AMD64_SET_GSBASE	131
 
 
-#define UNAME_MACHINE "x86_64"
+#define UNAME_MACHINE           "x86_64"
 
 #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_ */
-- 
2.0.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH 2/4] bsd-user: move arch/OS dependent code out of main.c
  2014-06-20  0:19 [Qemu-devel] [PATCH 0/4] bsd-user: Update Queue Sean Bruno
  2014-06-20  0:19 ` [Qemu-devel] [PATCH 1/4] bsd-user: Implement new syscall print_sysarch and add strace support Sean Bruno
@ 2014-06-20  0:19 ` Sean Bruno
  2014-07-03 13:45   ` Peter Maydell
  2014-06-20  0:19 ` [Qemu-devel] [PATCH 3/4] bsd-user: Rename linux_binprm to bsd_binprm Sean Bruno
                   ` (2 subsequent siblings)
  4 siblings, 1 reply; 11+ messages in thread
From: Sean Bruno @ 2014-06-20  0:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sean Bruno

From: Stacey Son <sson@FreeBSD.org>

This change moves the cpu initialization and main loop code from
main.c to the OS and arch dependent directories. This eliminates
many of the #ifdef's in main.c. The cpu initialization and loop
code is now located in the arch directory along with target arch
support code.

Signed-off-by: Sean Bruno <sbruno@freebsd.org>
---
 bsd-user/Makefile.objs                 |   2 +-
 bsd-user/elfload.c                     |   2 +-
 bsd-user/freebsd/host_os.h             |  46 ++
 bsd-user/freebsd/target_os_vmparam.h   |  23 +
 bsd-user/i386/target_arch.h            |  13 +
 bsd-user/i386/target_arch_cpu.c        |  79 +++
 bsd-user/i386/target_arch_cpu.h        | 300 +++++++++++
 bsd-user/i386/target_arch_vmparam.h    |  28 +
 bsd-user/i386/target_signal.h          |   6 -
 bsd-user/main.c                        | 927 +++++++--------------------------
 bsd-user/mmap.c                        |   2 +-
 bsd-user/netbsd/host_os.h              |  31 ++
 bsd-user/netbsd/os-strace.h            |   2 +-
 bsd-user/netbsd/target_os_vmparam.h    |  23 +
 bsd-user/openbsd/host_os.h             |  31 ++
 bsd-user/openbsd/os-strace.h           |   2 +-
 bsd-user/openbsd/target_os_vmparam.h   |  23 +
 bsd-user/qemu.h                        |  21 +-
 bsd-user/sparc/target_arch.h           |  11 +
 bsd-user/sparc/target_arch_cpu.c       | 113 ++++
 bsd-user/sparc/target_arch_cpu.h       | 158 ++++++
 bsd-user/sparc/target_arch_vmparam.h   |  37 ++
 bsd-user/sparc/target_signal.h         |   5 -
 bsd-user/sparc64/target_arch.h         |  11 +
 bsd-user/sparc64/target_arch_cpu.c     | 118 +++++
 bsd-user/sparc64/target_arch_cpu.h     | 191 +++++++
 bsd-user/sparc64/target_arch_vmparam.h |  37 ++
 bsd-user/sparc64/target_signal.h       |   5 -
 bsd-user/x86_64/target_arch.h          |  13 +
 bsd-user/x86_64/target_arch_cpu.c      |  79 +++
 bsd-user/x86_64/target_arch_cpu.h      | 322 ++++++++++++
 bsd-user/x86_64/target_arch_vmparam.h  |  28 +
 bsd-user/x86_64/target_signal.h        |   5 -
 33 files changed, 1930 insertions(+), 764 deletions(-)
 create mode 100644 bsd-user/freebsd/host_os.h
 create mode 100644 bsd-user/freebsd/target_os_vmparam.h
 create mode 100644 bsd-user/i386/target_arch.h
 create mode 100644 bsd-user/i386/target_arch_cpu.c
 create mode 100644 bsd-user/i386/target_arch_cpu.h
 create mode 100644 bsd-user/i386/target_arch_vmparam.h
 create mode 100644 bsd-user/netbsd/host_os.h
 create mode 100644 bsd-user/netbsd/target_os_vmparam.h
 create mode 100644 bsd-user/openbsd/host_os.h
 create mode 100644 bsd-user/openbsd/target_os_vmparam.h
 create mode 100644 bsd-user/sparc/target_arch.h
 create mode 100644 bsd-user/sparc/target_arch_cpu.c
 create mode 100644 bsd-user/sparc/target_arch_cpu.h
 create mode 100644 bsd-user/sparc/target_arch_vmparam.h
 create mode 100644 bsd-user/sparc64/target_arch.h
 create mode 100644 bsd-user/sparc64/target_arch_cpu.c
 create mode 100644 bsd-user/sparc64/target_arch_cpu.h
 create mode 100644 bsd-user/sparc64/target_arch_vmparam.h
 create mode 100644 bsd-user/x86_64/target_arch.h
 create mode 100644 bsd-user/x86_64/target_arch_cpu.c
 create mode 100644 bsd-user/x86_64/target_arch_cpu.h
 create mode 100644 bsd-user/x86_64/target_arch_vmparam.h

diff --git a/bsd-user/Makefile.objs b/bsd-user/Makefile.objs
index 5e77f57..41e8dce 100644
--- a/bsd-user/Makefile.objs
+++ b/bsd-user/Makefile.objs
@@ -1,2 +1,2 @@
 obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \
-	        uaccess.o
+	        uaccess.o $(TARGET_ABI_DIR)/target_arch_cpu.o
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index 93fd9e4..ccf72d1 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -674,7 +674,7 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
     /* Create enough stack to hold everything.  If we don't use
      * it for args, we'll use it for something else...
      */
-    size = x86_stack_size;
+    size = target_dflssiz;
     if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE)
         size = MAX_ARG_PAGES*TARGET_PAGE_SIZE;
     error = target_mmap(0,
diff --git a/bsd-user/freebsd/host_os.h b/bsd-user/freebsd/host_os.h
new file mode 100644
index 0000000..efe2351
--- /dev/null
+++ b/bsd-user/freebsd/host_os.h
@@ -0,0 +1,46 @@
+/*
+ *  FreeBSD host dependent code and definitions
+ *
+ *  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 __HOST_OS_H_
+#define __HOST_OS_H_
+
+#include <stdio.h>
+#include <sys/sysctl.h>
+
+#include "qemu.h"
+
+#define HOST_DEFAULT_BSD_TYPE target_freebsd
+
+static inline void save_proc_pathname(char *argv0)
+{
+    int mib[4];
+    size_t len;
+
+    mib[0] = CTL_KERN;
+    mib[1] = KERN_PROC;
+    mib[2] = KERN_PROC_PATHNAME;
+    mib[3] = -1;
+
+    len = PATH_MAX;
+    if (sysctl(mib, 4, qemu_proc_pathname, &len, NULL, 0)) {
+        perror("sysctl");
+    }
+}
+
+#endif /*!__HOST_OS_H_ */
diff --git a/bsd-user/freebsd/target_os_vmparam.h b/bsd-user/freebsd/target_os_vmparam.h
new file mode 100644
index 0000000..80ac6c8
--- /dev/null
+++ b/bsd-user/freebsd/target_os_vmparam.h
@@ -0,0 +1,23 @@
+#ifndef _TARGET_OS_VMPARAM_H_
+#define _TARGET_OS_VMPARAM_H_
+
+#include "target_arch_vmparam.h"
+
+#define TARGET_SPACE_USRSPACE   4096
+#define TARGET_ARG_MAX          262144
+
+/* Compare to sys/exec.h */
+struct target_ps_strings {
+    abi_ulong ps_argvstr;
+    uint32_t ps_nargvstr;
+    abi_ulong ps_envstr;
+    uint32_t ps_nenvstr;
+};
+
+extern abi_ulong target_stkbas;
+extern abi_ulong target_stksiz;
+
+#define TARGET_PS_STRINGS  ((target_stkbas + target_stksiz) - \
+		sizeof(struct target_ps_strings))
+
+#endif /* !TARGET_OS_VMPARAM_H_ */
diff --git a/bsd-user/i386/target_arch.h b/bsd-user/i386/target_arch.h
new file mode 100644
index 0000000..4cb398c
--- /dev/null
+++ b/bsd-user/i386/target_arch.h
@@ -0,0 +1,13 @@
+
+#ifndef _TARGET_ARCH_H_
+#define _TARGET_ARCH_H_
+
+/* target_arch_cpu.c */
+void bsd_i386_write_dt(void *ptr, unsigned long addr, unsigned long limit,
+                int flags);
+void bsd_i386_set_idt(int n, unsigned int dpl);
+void bsd_i386_set_idt_base(uint64_t base);
+
+#define target_cpu_set_tls(env, newtls)
+
+#endif /* ! _TARGET_ARCH_H_ */
diff --git a/bsd-user/i386/target_arch_cpu.c b/bsd-user/i386/target_arch_cpu.c
new file mode 100644
index 0000000..2e0eec0
--- /dev/null
+++ b/bsd-user/i386/target_arch_cpu.c
@@ -0,0 +1,79 @@
+/*
+ *  i386 cpu related code
+ *
+ *
+ *  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 <sys/types.h>
+
+#include "cpu.h"
+#include "qemu.h"
+#include "qemu/timer.h"
+
+#include "target_arch.h"
+
+static uint64_t *idt_table;
+
+/* CPUX86 core interface */
+void cpu_smm_update(CPUX86State *env)
+{
+}
+
+uint64_t cpu_get_tsc(CPUX86State *env)
+{
+    return cpu_get_real_ticks();
+}
+
+int cpu_get_pic_interrupt(CPUX86State *env)
+{
+    return -1;
+}
+
+void bsd_i386_write_dt(void *ptr, unsigned long addr, unsigned long limit,
+                     int flags)
+{
+    unsigned int e1, e2;
+    uint32_t *p;
+    e1 = (addr << 16) | (limit & 0xffff);
+    e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
+    e2 |= flags;
+    p = ptr;
+    p[0] = tswap32(e1);
+    p[1] = tswap32(e2);
+}
+
+
+static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
+                     uint32_t addr, unsigned int sel)
+{
+    uint32_t *p, e1, e2;
+    e1 = (addr & 0xffff) | (sel << 16);
+    e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
+    p = ptr;
+    p[0] = tswap32(e1);
+    p[1] = tswap32(e2);
+}
+
+/* only dpl matters as we do only user space emulation */
+void bsd_i386_set_idt(int n, unsigned int dpl)
+{
+    set_gate(idt_table + n, 0, dpl, 0, 0);
+}
+
+void bsd_i386_set_idt_base(uint64_t base)
+{
+    idt_table = g2h(base);
+}
+
diff --git a/bsd-user/i386/target_arch_cpu.h b/bsd-user/i386/target_arch_cpu.h
new file mode 100644
index 0000000..ab505c4
--- /dev/null
+++ b/bsd-user/i386/target_arch_cpu.h
@@ -0,0 +1,300 @@
+/*
+ *  i386 cpu init and loop
+ *
+ *
+ *  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 _TARGET_ARCH_CPU_H_
+#define _TARGET_ARCH_CPU_H_
+
+#include "target_arch.h"
+
+#define TARGET_DEFAULT_CPU_MODEL "qemu32"
+
+#define TARGET_CPU_RESET(env)
+
+static inline void target_cpu_init(CPUX86State *env,
+        struct target_pt_regs *regs)
+{
+    uint64_t *gdt_table;
+
+    env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
+    env->hflags |= HF_PE_MASK;
+    if (env->features[FEAT_1_EDX] & CPUID_SSE) {
+        env->cr[4] |= CR4_OSFXSR_MASK;
+        env->hflags |= HF_OSFXSR_MASK;
+    }
+
+    /* flags setup : we activate the IRQs by default as in user mode */
+    env->eflags |= IF_MASK;
+
+    /* register setup */
+    env->regs[R_EAX] = regs->eax;
+    env->regs[R_EBX] = regs->ebx;
+    env->regs[R_ECX] = regs->ecx;
+    env->regs[R_EDX] = regs->edx;
+    env->regs[R_ESI] = regs->esi;
+    env->regs[R_EDI] = regs->edi;
+    env->regs[R_EBP] = regs->ebp;
+    env->regs[R_ESP] = regs->esp;
+    env->eip = regs->eip;
+
+    /* interrupt setup */
+    env->idt.limit = 255;
+
+    env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
+        PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+    bsd_i386_set_idt_base(env->idt.base);
+    bsd_i386_set_idt(0, 0);
+    bsd_i386_set_idt(1, 0);
+    bsd_i386_set_idt(2, 0);
+    bsd_i386_set_idt(3, 3);
+    bsd_i386_set_idt(4, 3);
+    bsd_i386_set_idt(5, 0);
+    bsd_i386_set_idt(6, 0);
+    bsd_i386_set_idt(7, 0);
+    bsd_i386_set_idt(8, 0);
+    bsd_i386_set_idt(9, 0);
+    bsd_i386_set_idt(10, 0);
+    bsd_i386_set_idt(11, 0);
+    bsd_i386_set_idt(12, 0);
+    bsd_i386_set_idt(13, 0);
+    bsd_i386_set_idt(14, 0);
+    bsd_i386_set_idt(15, 0);
+    bsd_i386_set_idt(16, 0);
+    bsd_i386_set_idt(17, 0);
+    bsd_i386_set_idt(18, 0);
+    bsd_i386_set_idt(19, 0);
+    bsd_i386_set_idt(0x80, 3);
+
+    /* segment setup */
+    env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
+            PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+    env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
+    gdt_table = g2h(env->gdt.base);
+
+    bsd_i386_write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
+            DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
+            (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
+
+    bsd_i386_write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
+            DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
+            (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
+
+    cpu_x86_load_seg(env, R_CS, __USER_CS);
+    cpu_x86_load_seg(env, R_SS, __USER_DS);
+    cpu_x86_load_seg(env, R_DS, __USER_DS);
+    cpu_x86_load_seg(env, R_ES, __USER_DS);
+    cpu_x86_load_seg(env, R_FS, __USER_DS);
+    cpu_x86_load_seg(env, R_GS, __USER_DS);
+    /* This hack makes Wine work... */
+    env->segs[R_FS].selector = 0;
+}
+
+static inline void target_cpu_loop(CPUX86State *env)
+{
+    int trapnr;
+    abi_ulong pc;
+    /* target_siginfo_t info; */
+
+    for (;;) {
+        trapnr = cpu_x86_exec(env);
+        switch (trapnr) {
+        case 0x80:
+            /* syscall from int $0x80 */
+            if (bsd_type == target_freebsd) {
+                abi_ulong params = (abi_ulong) env->regs[R_ESP] +
+                    sizeof(int32_t);
+                int32_t syscall_nr = env->regs[R_EAX];
+                int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;
+
+                if (syscall_nr == TARGET_FREEBSD_NR_syscall) {
+                    get_user_s32(syscall_nr, params);
+                    params += sizeof(int32_t);
+                } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) {
+                    get_user_s32(syscall_nr, params);
+                    params += sizeof(int64_t);
+                }
+                get_user_s32(arg1, params);
+                params += sizeof(int32_t);
+                get_user_s32(arg2, params);
+                params += sizeof(int32_t);
+                get_user_s32(arg3, params);
+                params += sizeof(int32_t);
+                get_user_s32(arg4, params);
+                params += sizeof(int32_t);
+                get_user_s32(arg5, params);
+                params += sizeof(int32_t);
+                get_user_s32(arg6, params);
+                params += sizeof(int32_t);
+                get_user_s32(arg7, params);
+                params += sizeof(int32_t);
+                get_user_s32(arg8, params);
+                env->regs[R_EAX] = do_freebsd_syscall(env,
+                                                      syscall_nr,
+                                                      arg1,
+                                                      arg2,
+                                                      arg3,
+                                                      arg4,
+                                                      arg5,
+                                                      arg6,
+                                                      arg7,
+                                                      arg8);
+            } else { /* if (bsd_type == target_openbsd) */
+                env->regs[R_EAX] = do_openbsd_syscall(env,
+                                                      env->regs[R_EAX],
+                                                      env->regs[R_EBX],
+                                                      env->regs[R_ECX],
+                                                      env->regs[R_EDX],
+                                                      env->regs[R_ESI],
+                                                      env->regs[R_EDI],
+                                                      env->regs[R_EBP]);
+            }
+            if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
+                env->regs[R_EAX] = -env->regs[R_EAX];
+                env->eflags |= CC_C;
+            } else {
+                env->eflags &= ~CC_C;
+            }
+            break;
+
+#if 0
+        case EXCP0B_NOSEG:
+        case EXCP0C_STACK:
+            info.si_signo = SIGBUS;
+            info.si_errno = 0;
+            info.si_code = TARGET_SI_KERNEL;
+            info._sifields._sigfault._addr = 0;
+            queue_signal(env, info.si_signo, &info);
+            break;
+
+        case EXCP0D_GPF:
+            /* XXX: potential problem if ABI32 */
+            if (env->eflags & VM_MASK) {
+                handle_vm86_fault(env);
+            } else {
+                info.si_signo = SIGSEGV;
+                info.si_errno = 0;
+                info.si_code = TARGET_SI_KERNEL;
+                info._sifields._sigfault._addr = 0;
+                queue_signal(env, info.si_signo, &info);
+            }
+            break;
+
+        case EXCP0E_PAGE:
+            info.si_signo = SIGSEGV;
+            info.si_errno = 0;
+            if (!(env->error_code & 1)) {
+                info.si_code = TARGET_SEGV_MAPERR;
+            } else {
+                info.si_code = TARGET_SEGV_ACCERR;
+            }
+            info._sifields._sigfault._addr = env->cr[2];
+            queue_signal(env, info.si_signo, &info);
+            break;
+
+        case EXCP00_DIVZ:
+            if (env->eflags & VM_MASK) {
+                handle_vm86_trap(env, trapnr);
+            } else {
+                /* division by zero */
+                info.si_signo = SIGFPE;
+                info.si_errno = 0;
+                info.si_code = TARGET_FPE_INTDIV;
+                info._sifields._sigfault._addr = env->eip;
+                queue_signal(env, info.si_signo, &info);
+            }
+            break;
+
+        case EXCP01_DB:
+        case EXCP03_INT3:
+            if (env->eflags & VM_MASK) {
+                handle_vm86_trap(env, trapnr);
+            } else {
+                info.si_signo = SIGTRAP;
+                info.si_errno = 0;
+                if (trapnr == EXCP01_DB) {
+                    info.si_code = TARGET_TRAP_BRKPT;
+                    info._sifields._sigfault._addr = env->eip;
+                } else {
+                    info.si_code = TARGET_SI_KERNEL;
+                    info._sifields._sigfault._addr = 0;
+                }
+                queue_signal(env, info.si_signo, &info);
+            }
+            break;
+
+        case EXCP04_INTO:
+        case EXCP05_BOUND:
+            if (env->eflags & VM_MASK) {
+                handle_vm86_trap(env, trapnr);
+            } else {
+                info.si_signo = SIGSEGV;
+                info.si_errno = 0;
+                info.si_code = TARGET_SI_KERNEL;
+                info._sifields._sigfault._addr = 0;
+                queue_signal(env, info.si_signo, &info);
+            }
+            break;
+
+        case EXCP06_ILLOP:
+            info.si_signo = SIGILL;
+            info.si_errno = 0;
+            info.si_code = TARGET_ILL_ILLOPN;
+            info._sifields._sigfault._addr = env->eip;
+            queue_signal(env, info.si_signo, &info);
+            break;
+#endif
+        case EXCP_INTERRUPT:
+            /* just indicate that signals should be handled asap */
+            break;
+#if 0
+        case EXCP_DEBUG:
+            {
+                int sig;
+
+                sig = gdb_handlesig(env, TARGET_SIGTRAP);
+                if (sig) {
+                    info.si_signo = sig;
+                    info.si_errno = 0;
+                    info.si_code = TARGET_TRAP_BRKPT;
+                    queue_signal(env, info.si_signo, &info);
+                }
+            }
+            break;
+#endif
+        default:
+            pc = env->segs[R_CS].base + env->eip;
+            fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - "
+                    "aborting\n", (long)pc, trapnr);
+            abort();
+        }
+        process_pending_signals(env);
+    }
+}
+
+static inline void target_cpu_clone_regs(CPUX86State *env, target_ulong newsp)
+{
+    if (newsp)
+        env->regs[R_ESP] = newsp;
+    env->regs[R_EAX] = 0;
+}
+
+static inline void target_cpu_reset(CPUArchState *cpu)
+{
+    cpu_reset(ENV_GET_CPU(cpu));
+}
+
+#endif /* ! _TARGET_ARCH_CPU_H_ */
diff --git a/bsd-user/i386/target_arch_vmparam.h b/bsd-user/i386/target_arch_vmparam.h
new file mode 100644
index 0000000..f15af91
--- /dev/null
+++ b/bsd-user/i386/target_arch_vmparam.h
@@ -0,0 +1,28 @@
+#ifndef _TARGET_ARCH_VMPARAM_H_
+#define _TARGET_ARCH_VMPARAM_H_
+
+#include "cpu.h"
+
+/* compare to i386/include/vmparam.h */
+#define TARGET_MAXTSIZ  (128UL*1024*1024)   /* max text size */
+#define TARGET_DFLDSIZ  (128UL*1024*1024)   /* initial data size limit */
+#define TARGET_MAXDSIZ  (512UL*1024*1024)   /* max data size */
+#define TARGET_DFLSSIZ  (8UL*1024*1024)     /* initial stack size limit */
+#define TARGET_MAXSSIZ  (64UL*1024*1024)    /* max stack size */
+#define TARGET_SGROWSIZ (128UL*1024)        /* amount to grow stack */
+
+#define TARGET_RESERVED_VA 0xf7000000
+
+#define TARGET_USRSTACK (0xbfc00000)
+
+static inline abi_ulong get_sp_from_cpustate(CPUX86State *state)
+{
+    return state->regs[R_ESP];
+}
+
+static inline void set_second_rval(CPUX86State *state, abi_ulong retval2)
+{
+    state->regs[R_EDX] = retval2;
+}
+
+#endif /* !_TARGET_ARCH_VMPARAM_H_ */
diff --git a/bsd-user/i386/target_signal.h b/bsd-user/i386/target_signal.h
index 2ef36d1..5491687 100644
--- a/bsd-user/i386/target_signal.h
+++ b/bsd-user/i386/target_signal.h
@@ -11,10 +11,4 @@ typedef struct target_sigaltstack {
 	abi_ulong ss_size;
 } target_stack_t;
 
-
-static inline abi_ulong get_sp_from_cpustate(CPUX86State *state)
-{
-    return state->regs[R_ESP];
-}
-
 #endif /* TARGET_SIGNAL_H */
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 0e8c26c..9c5711d 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -1,7 +1,8 @@
 /*
- *  qemu user main
+ *  qemu bsd user main
  *
  *  Copyright (c) 2003-2008 Fabrice Bellard
+ *  Copyright (c) 2013 Stacey 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
@@ -23,652 +24,194 @@
 #include <errno.h>
 #include <unistd.h>
 #include <machine/trap.h>
+#include <sys/syscall.h>
 #include <sys/types.h>
 #include <sys/mman.h>
 
 #include "qemu.h"
 #include "qemu-common.h"
-/* For tb_lock */
 #include "cpu.h"
 #include "tcg.h"
 #include "qemu/timer.h"
 #include "qemu/envlist.h"
 
+#include "host_os.h"
+#include "target_arch_cpu.h"
+
 int singlestep;
-#if defined(CONFIG_USE_GUEST_BASE)
+static const char *cpu_model;
 unsigned long mmap_min_addr;
+#if defined(CONFIG_USE_GUEST_BASE)
 unsigned long guest_base;
 int have_guest_base;
+#if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
+/*
+ * When running 32-on-64 we should make sure we can fit all of the possible
+ * guest address space into a contiguous chunk of virtual host memory.
+ *
+ * This way we will never overlap with our own libraries or binaries or stack
+ * or anything else that QEMU maps.
+ */
+unsigned long reserved_va = TARGET_RESERVED_VA;
+#else
 unsigned long reserved_va;
 #endif
+#endif /* CONFIG_USE_GUEST_BASE */
 
 static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX;
 const char *qemu_uname_release;
 extern char **environ;
 enum BSDType bsd_type;
 
-/* XXX: on x86 MAP_GROWSDOWN only works if ESP <= address + 32, so
-   we allocate a bigger stack. Need a better solution, for example
-   by remapping the process stack directly at the right place */
-unsigned long x86_stack_size = 512 * 1024;
+unsigned long target_maxtsiz = TARGET_MAXTSIZ;   /* max text size */
+unsigned long target_dfldsiz = TARGET_DFLDSIZ;   /* initial data size limit */
+unsigned long target_maxdsiz = TARGET_MAXDSIZ;   /* max data size */
+unsigned long target_dflssiz = TARGET_DFLSSIZ;   /* initial data size limit */
+unsigned long target_maxssiz = TARGET_MAXSSIZ;   /* max stack size */
+unsigned long target_sgrowsiz = TARGET_SGROWSIZ; /* amount to grow stack */
 
-void gemu_log(const char *fmt, ...)
-{
-    va_list ap;
+char qemu_proc_pathname[PATH_MAX];  /* full path to exeutable */
 
-    va_start(ap, fmt);
-    vfprintf(stderr, fmt, ap);
-    va_end(ap);
-}
-
-#if defined(TARGET_I386)
-int cpu_get_pic_interrupt(CPUX86State *env)
-{
-    return -1;
-}
-#endif
-
-/* These are no-ops because we are not threadsafe.  */
-static inline void cpu_exec_start(CPUArchState *env)
-{
-}
-
-static inline void cpu_exec_end(CPUArchState *env)
-{
-}
-
-static inline void start_exclusive(void)
-{
-}
-
-static inline void end_exclusive(void)
-{
-}
+/* Helper routines for implementing atomic operations. */
 
+/*
+ * To implement exclusive operations we force all cpus to synchronize.
+ * We don't require a full sync, only that no cpus are executing guest code.
+ * The alternative is to map target atomic ops onto host eqivalents,
+ * which requires quite a lot of per host/target work.
+ */
+static pthread_mutex_t cpu_list_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t exclusive_lock = PTHREAD_MUTEX_INITIALIZER;
+static pthread_cond_t exclusive_cond = PTHREAD_COND_INITIALIZER;
+static pthread_cond_t exclusive_resume = PTHREAD_COND_INITIALIZER;
+static int pending_cpus;
+
+#if defined(CONFIG_USE_NPTL)
+/* Make sure everything is in a consistent state for calling fork(). */
 void fork_start(void)
 {
+    pthread_mutex_lock(&tcg_ctx.tb_ctx.tb_lock);
+    pthread_mutex_lock(&exclusive_lock);
+    mmap_fork_start();
 }
 
 void fork_end(int child)
 {
+    mmap_fork_end(child);
     if (child) {
+        CPUState *cpu, *next_cpu;
+        /*
+         * Child processes created by fork() only have a single thread.
+         * Discard information about the parent threads.
+         */
+        CPU_FOREACH_SAFE(cpu, next_cpu) {
+            if (cpu != thread_cpu) {
+                QTAILQ_REMOVE(&cpus, thread_cpu, node);
+            }
+        }
+        pending_cpus = 0;
+        pthread_mutex_init(&exclusive_lock, NULL);
+        pthread_mutex_init(&cpu_list_mutex, NULL);
+        pthread_cond_init(&exclusive_cond, NULL);
+        pthread_cond_init(&exclusive_resume, NULL);
+        pthread_mutex_init(&tcg_ctx.tb_ctx.tb_lock, NULL);
         gdbserver_fork((CPUArchState *)thread_cpu->env_ptr);
+    } else {
+        pthread_mutex_unlock(&exclusive_lock);
+        pthread_mutex_unlock(&tcg_ctx.tb_ctx.tb_lock);
     }
 }
-
-void cpu_list_lock(void)
-{
-}
-
-void cpu_list_unlock(void)
+#else
+void fork_start(void)
 {
 }
 
-#ifdef TARGET_I386
-/***********************************************************/
-/* CPUX86 core interface */
-
-void cpu_smm_update(CPUX86State *env)
+void fork_end(int child)
 {
-}
 
-uint64_t cpu_get_tsc(CPUX86State *env)
-{
-    return cpu_get_real_ticks();
 }
+#endif
 
-static void write_dt(void *ptr, unsigned long addr, unsigned long limit,
-                     int flags)
+/*
+ * Wait for pending exclusive operations to complete.  The exclusive lock
+ * must be held.
+ */
+static inline void exclusive_idle(void)
 {
-    unsigned int e1, e2;
-    uint32_t *p;
-    e1 = (addr << 16) | (limit & 0xffff);
-    e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
-    e2 |= flags;
-    p = ptr;
-    p[0] = tswap32(e1);
-    p[1] = tswap32(e2);
+    while (pending_cpus) {
+        pthread_cond_wait(&exclusive_resume, &exclusive_lock);
+    }
 }
 
-static uint64_t *idt_table;
-#ifdef TARGET_X86_64
-static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
-                       uint64_t addr, unsigned int sel)
-{
-    uint32_t *p, e1, e2;
-    e1 = (addr & 0xffff) | (sel << 16);
-    e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
-    p = ptr;
-    p[0] = tswap32(e1);
-    p[1] = tswap32(e2);
-    p[2] = tswap32(addr >> 32);
-    p[3] = 0;
-}
-/* only dpl matters as we do only user space emulation */
-static void set_idt(int n, unsigned int dpl)
+/* Start an exclusive operation.  Must only be called outside of cpu_exec. */
+void start_exclusive(void)
 {
-    set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
-}
-#else
-static void set_gate(void *ptr, unsigned int type, unsigned int dpl,
-                     uint32_t addr, unsigned int sel)
-{
-    uint32_t *p, e1, e2;
-    e1 = (addr & 0xffff) | (sel << 16);
-    e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
-    p = ptr;
-    p[0] = tswap32(e1);
-    p[1] = tswap32(e2);
-}
+    CPUState *other_cpu;
 
-/* only dpl matters as we do only user space emulation */
-static void set_idt(int n, unsigned int dpl)
-{
-    set_gate(idt_table + n, 0, dpl, 0, 0);
-}
-#endif
+    pthread_mutex_lock(&exclusive_lock);
+    exclusive_idle();
 
-void cpu_loop(CPUX86State *env)
-{
-    int trapnr;
-    abi_ulong pc;
-    //target_siginfo_t info;
-
-    for(;;) {
-        trapnr = cpu_x86_exec(env);
-        switch(trapnr) {
-        case 0x80:
-            /* syscall from int $0x80 */
-            if (bsd_type == target_freebsd) {
-                abi_ulong params = (abi_ulong) env->regs[R_ESP] +
-                    sizeof(int32_t);
-                int32_t syscall_nr = env->regs[R_EAX];
-                int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;
-
-                if (syscall_nr == TARGET_FREEBSD_NR_syscall) {
-                    get_user_s32(syscall_nr, params);
-                    params += sizeof(int32_t);
-                } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) {
-                    get_user_s32(syscall_nr, params);
-                    params += sizeof(int64_t);
-                }
-                get_user_s32(arg1, params);
-                params += sizeof(int32_t);
-                get_user_s32(arg2, params);
-                params += sizeof(int32_t);
-                get_user_s32(arg3, params);
-                params += sizeof(int32_t);
-                get_user_s32(arg4, params);
-                params += sizeof(int32_t);
-                get_user_s32(arg5, params);
-                params += sizeof(int32_t);
-                get_user_s32(arg6, params);
-                params += sizeof(int32_t);
-                get_user_s32(arg7, params);
-                params += sizeof(int32_t);
-                get_user_s32(arg8, params);
-                env->regs[R_EAX] = do_freebsd_syscall(env,
-                                                      syscall_nr,
-                                                      arg1,
-                                                      arg2,
-                                                      arg3,
-                                                      arg4,
-                                                      arg5,
-                                                      arg6,
-                                                      arg7,
-                                                      arg8);
-            } else { //if (bsd_type == target_openbsd)
-                env->regs[R_EAX] = do_openbsd_syscall(env,
-                                                      env->regs[R_EAX],
-                                                      env->regs[R_EBX],
-                                                      env->regs[R_ECX],
-                                                      env->regs[R_EDX],
-                                                      env->regs[R_ESI],
-                                                      env->regs[R_EDI],
-                                                      env->regs[R_EBP]);
-            }
-            if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
-                env->regs[R_EAX] = -env->regs[R_EAX];
-                env->eflags |= CC_C;
-            } else {
-                env->eflags &= ~CC_C;
-            }
-            break;
-#ifndef TARGET_ABI32
-        case EXCP_SYSCALL:
-            /* syscall from syscall instruction */
-            if (bsd_type == target_freebsd)
-                env->regs[R_EAX] = do_freebsd_syscall(env,
-                                                      env->regs[R_EAX],
-                                                      env->regs[R_EDI],
-                                                      env->regs[R_ESI],
-                                                      env->regs[R_EDX],
-                                                      env->regs[R_ECX],
-                                                      env->regs[8],
-                                                      env->regs[9], 0, 0);
-            else { //if (bsd_type == target_openbsd)
-                env->regs[R_EAX] = do_openbsd_syscall(env,
-                                                      env->regs[R_EAX],
-                                                      env->regs[R_EDI],
-                                                      env->regs[R_ESI],
-                                                      env->regs[R_EDX],
-                                                      env->regs[10],
-                                                      env->regs[8],
-                                                      env->regs[9]);
-            }
-            env->eip = env->exception_next_eip;
-            if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
-                env->regs[R_EAX] = -env->regs[R_EAX];
-                env->eflags |= CC_C;
-            } else {
-                env->eflags &= ~CC_C;
-            }
-            break;
-#endif
-#if 0
-        case EXCP0B_NOSEG:
-        case EXCP0C_STACK:
-            info.si_signo = SIGBUS;
-            info.si_errno = 0;
-            info.si_code = TARGET_SI_KERNEL;
-            info._sifields._sigfault._addr = 0;
-            queue_signal(env, info.si_signo, &info);
-            break;
-        case EXCP0D_GPF:
-            /* XXX: potential problem if ABI32 */
-#ifndef TARGET_X86_64
-            if (env->eflags & VM_MASK) {
-                handle_vm86_fault(env);
-            } else
-#endif
-            {
-                info.si_signo = SIGSEGV;
-                info.si_errno = 0;
-                info.si_code = TARGET_SI_KERNEL;
-                info._sifields._sigfault._addr = 0;
-                queue_signal(env, info.si_signo, &info);
-            }
-            break;
-        case EXCP0E_PAGE:
-            info.si_signo = SIGSEGV;
-            info.si_errno = 0;
-            if (!(env->error_code & 1))
-                info.si_code = TARGET_SEGV_MAPERR;
-            else
-                info.si_code = TARGET_SEGV_ACCERR;
-            info._sifields._sigfault._addr = env->cr[2];
-            queue_signal(env, info.si_signo, &info);
-            break;
-        case EXCP00_DIVZ:
-#ifndef TARGET_X86_64
-            if (env->eflags & VM_MASK) {
-                handle_vm86_trap(env, trapnr);
-            } else
-#endif
-            {
-                /* division by zero */
-                info.si_signo = SIGFPE;
-                info.si_errno = 0;
-                info.si_code = TARGET_FPE_INTDIV;
-                info._sifields._sigfault._addr = env->eip;
-                queue_signal(env, info.si_signo, &info);
-            }
-            break;
-        case EXCP01_DB:
-        case EXCP03_INT3:
-#ifndef TARGET_X86_64
-            if (env->eflags & VM_MASK) {
-                handle_vm86_trap(env, trapnr);
-            } else
-#endif
-            {
-                info.si_signo = SIGTRAP;
-                info.si_errno = 0;
-                if (trapnr == EXCP01_DB) {
-                    info.si_code = TARGET_TRAP_BRKPT;
-                    info._sifields._sigfault._addr = env->eip;
-                } else {
-                    info.si_code = TARGET_SI_KERNEL;
-                    info._sifields._sigfault._addr = 0;
-                }
-                queue_signal(env, info.si_signo, &info);
-            }
-            break;
-        case EXCP04_INTO:
-        case EXCP05_BOUND:
-#ifndef TARGET_X86_64
-            if (env->eflags & VM_MASK) {
-                handle_vm86_trap(env, trapnr);
-            } else
-#endif
-            {
-                info.si_signo = SIGSEGV;
-                info.si_errno = 0;
-                info.si_code = TARGET_SI_KERNEL;
-                info._sifields._sigfault._addr = 0;
-                queue_signal(env, info.si_signo, &info);
-            }
-            break;
-        case EXCP06_ILLOP:
-            info.si_signo = SIGILL;
-            info.si_errno = 0;
-            info.si_code = TARGET_ILL_ILLOPN;
-            info._sifields._sigfault._addr = env->eip;
-            queue_signal(env, info.si_signo, &info);
-            break;
-#endif
-        case EXCP_INTERRUPT:
-            /* just indicate that signals should be handled asap */
-            break;
-#if 0
-        case EXCP_DEBUG:
-            {
-                int sig;
-
-                sig = gdb_handlesig (env, TARGET_SIGTRAP);
-                if (sig)
-                  {
-                    info.si_signo = sig;
-                    info.si_errno = 0;
-                    info.si_code = TARGET_TRAP_BRKPT;
-                    queue_signal(env, info.si_signo, &info);
-                  }
-            }
-            break;
-#endif
-        default:
-            pc = env->segs[R_CS].base + env->eip;
-            fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - aborting\n",
-                    (long)pc, trapnr);
-            abort();
+    pending_cpus = 1;
+    /* Make all other cpus stop executing. */
+    CPU_FOREACH(other_cpu) {
+        if (other_cpu->running) {
+            pending_cpus++;
+            cpu_exit(other_cpu);
         }
-        process_pending_signals(env);
+    }
+    if (pending_cpus > 1) {
+        pthread_cond_wait(&exclusive_cond, &exclusive_lock);
     }
 }
-#endif
-
-#ifdef TARGET_SPARC
-#define SPARC64_STACK_BIAS 2047
 
-//#define DEBUG_WIN
-/* WARNING: dealing with register windows _is_ complicated. More info
-   can be found at http://www.sics.se/~psm/sparcstack.html */
-static inline int get_reg_index(CPUSPARCState *env, int cwp, int index)
+/* Finish an exclusive operation. */
+void end_exclusive(void)
 {
-    index = (index + cwp * 16) % (16 * env->nwindows);
-    /* wrap handling : if cwp is on the last window, then we use the
-       registers 'after' the end */
-    if (index < 8 && env->cwp == env->nwindows - 1)
-        index += 16 * env->nwindows;
-    return index;
+    pending_cpus = 0;
+    pthread_cond_broadcast(&exclusive_resume);
+    pthread_mutex_unlock(&exclusive_lock);
 }
 
-/* save the register window 'cwp1' */
-static inline void save_window_offset(CPUSPARCState *env, int cwp1)
+/* Wait for exclusive ops to finish, and begin cpu execution. */
+void cpu_exec_start(CPUState *cpu)
 {
-    unsigned int i;
-    abi_ulong sp_ptr;
-
-    sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
-#ifdef TARGET_SPARC64
-    if (sp_ptr & 3)
-        sp_ptr += SPARC64_STACK_BIAS;
-#endif
-#if defined(DEBUG_WIN)
-    printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
-           sp_ptr, cwp1);
-#endif
-    for(i = 0; i < 16; i++) {
-        /* FIXME - what to do if put_user() fails? */
-        put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
-        sp_ptr += sizeof(abi_ulong);
-    }
+    pthread_mutex_lock(&exclusive_lock);
+    exclusive_idle();
+    cpu->running = true;
+    pthread_mutex_unlock(&exclusive_lock);
 }
 
-static void save_window(CPUSPARCState *env)
+/* Mark cpu as not excuting, and release pending exclusive ops. */
+void cpu_exec_end(CPUState *cpu)
 {
-#ifndef TARGET_SPARC64
-    unsigned int new_wim;
-    new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
-        ((1LL << env->nwindows) - 1);
-    save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
-    env->wim = new_wim;
-#else
-    save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
-    env->cansave++;
-    env->canrestore--;
-#endif
+    pthread_mutex_lock(&exclusive_lock);
+    cpu->running = false;
+    if (pending_cpus > 1) {
+        pending_cpus--;
+        if (pending_cpus == 1) {
+            pthread_cond_signal(&exclusive_cond);
+        }
+    }
+    exclusive_idle();
+    pthread_mutex_unlock(&exclusive_lock);
 }
 
-static void restore_window(CPUSPARCState *env)
+void cpu_list_lock(void)
 {
-#ifndef TARGET_SPARC64
-    unsigned int new_wim;
-#endif
-    unsigned int i, cwp1;
-    abi_ulong sp_ptr;
-
-#ifndef TARGET_SPARC64
-    new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
-        ((1LL << env->nwindows) - 1);
-#endif
-
-    /* restore the invalid window */
-    cwp1 = cpu_cwp_inc(env, env->cwp + 1);
-    sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
-#ifdef TARGET_SPARC64
-    if (sp_ptr & 3)
-        sp_ptr += SPARC64_STACK_BIAS;
-#endif
-#if defined(DEBUG_WIN)
-    printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
-           sp_ptr, cwp1);
-#endif
-    for(i = 0; i < 16; i++) {
-        /* FIXME - what to do if get_user() fails? */
-        get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
-        sp_ptr += sizeof(abi_ulong);
-    }
-#ifdef TARGET_SPARC64
-    env->canrestore++;
-    if (env->cleanwin < env->nwindows - 1)
-        env->cleanwin++;
-    env->cansave--;
-#else
-    env->wim = new_wim;
-#endif
+    pthread_mutex_lock(&cpu_list_mutex);
 }
 
-static void flush_windows(CPUSPARCState *env)
+void cpu_list_unlock(void)
 {
-    int offset, cwp1;
-
-    offset = 1;
-    for(;;) {
-        /* if restore would invoke restore_window(), then we can stop */
-        cwp1 = cpu_cwp_inc(env, env->cwp + offset);
-#ifndef TARGET_SPARC64
-        if (env->wim & (1 << cwp1))
-            break;
-#else
-        if (env->canrestore == 0)
-            break;
-        env->cansave++;
-        env->canrestore--;
-#endif
-        save_window_offset(env, cwp1);
-        offset++;
-    }
-    cwp1 = cpu_cwp_inc(env, env->cwp + 1);
-#ifndef TARGET_SPARC64
-    /* set wim so that restore will reload the registers */
-    env->wim = 1 << cwp1;
-#endif
-#if defined(DEBUG_WIN)
-    printf("flush_windows: nb=%d\n", offset - 1);
-#endif
+    pthread_mutex_unlock(&cpu_list_mutex);
 }
 
-void cpu_loop(CPUSPARCState *env)
+void cpu_loop(CPUArchState *env)
 {
-    CPUState *cs = CPU(sparc_env_get_cpu(env));
-    int trapnr, ret, syscall_nr;
-    //target_siginfo_t info;
-
-    while (1) {
-        trapnr = cpu_sparc_exec (env);
 
-        switch (trapnr) {
-#ifndef TARGET_SPARC64
-        case 0x80:
-#else
-        /* FreeBSD uses 0x141 for syscalls too */
-        case 0x141:
-            if (bsd_type != target_freebsd)
-                goto badtrap;
-        case 0x100:
-#endif
-            syscall_nr = env->gregs[1];
-            if (bsd_type == target_freebsd)
-                ret = do_freebsd_syscall(env, syscall_nr,
-                                         env->regwptr[0], env->regwptr[1],
-                                         env->regwptr[2], env->regwptr[3],
-                                         env->regwptr[4], env->regwptr[5], 0, 0);
-            else if (bsd_type == target_netbsd)
-                ret = do_netbsd_syscall(env, syscall_nr,
-                                        env->regwptr[0], env->regwptr[1],
-                                        env->regwptr[2], env->regwptr[3],
-                                        env->regwptr[4], env->regwptr[5]);
-            else { //if (bsd_type == target_openbsd)
-#if defined(TARGET_SPARC64)
-                syscall_nr &= ~(TARGET_OPENBSD_SYSCALL_G7RFLAG |
-                                TARGET_OPENBSD_SYSCALL_G2RFLAG);
-#endif
-                ret = do_openbsd_syscall(env, syscall_nr,
-                                         env->regwptr[0], env->regwptr[1],
-                                         env->regwptr[2], env->regwptr[3],
-                                         env->regwptr[4], env->regwptr[5]);
-            }
-            if ((unsigned int)ret >= (unsigned int)(-515)) {
-                ret = -ret;
-#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
-                env->xcc |= PSR_CARRY;
-#else
-                env->psr |= PSR_CARRY;
-#endif
-            } else {
-#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
-                env->xcc &= ~PSR_CARRY;
-#else
-                env->psr &= ~PSR_CARRY;
-#endif
-            }
-            env->regwptr[0] = ret;
-            /* next instruction */
-#if defined(TARGET_SPARC64)
-            if (bsd_type == target_openbsd &&
-                env->gregs[1] & TARGET_OPENBSD_SYSCALL_G2RFLAG) {
-                env->pc = env->gregs[2];
-                env->npc = env->pc + 4;
-            } else if (bsd_type == target_openbsd &&
-                       env->gregs[1] & TARGET_OPENBSD_SYSCALL_G7RFLAG) {
-                env->pc = env->gregs[7];
-                env->npc = env->pc + 4;
-            } else {
-                env->pc = env->npc;
-                env->npc = env->npc + 4;
-            }
-#else
-            env->pc = env->npc;
-            env->npc = env->npc + 4;
-#endif
-            break;
-        case 0x83: /* flush windows */
-#ifdef TARGET_ABI32
-        case 0x103:
-#endif
-            flush_windows(env);
-            /* next instruction */
-            env->pc = env->npc;
-            env->npc = env->npc + 4;
-            break;
-#ifndef TARGET_SPARC64
-        case TT_WIN_OVF: /* window overflow */
-            save_window(env);
-            break;
-        case TT_WIN_UNF: /* window underflow */
-            restore_window(env);
-            break;
-        case TT_TFAULT:
-        case TT_DFAULT:
-#if 0
-            {
-                info.si_signo = SIGSEGV;
-                info.si_errno = 0;
-                /* XXX: check env->error_code */
-                info.si_code = TARGET_SEGV_MAPERR;
-                info._sifields._sigfault._addr = env->mmuregs[4];
-                queue_signal(env, info.si_signo, &info);
-            }
-#endif
-            break;
-#else
-        case TT_SPILL: /* window overflow */
-            save_window(env);
-            break;
-        case TT_FILL: /* window underflow */
-            restore_window(env);
-            break;
-        case TT_TFAULT:
-        case TT_DFAULT:
-#if 0
-            {
-                info.si_signo = SIGSEGV;
-                info.si_errno = 0;
-                /* XXX: check env->error_code */
-                info.si_code = TARGET_SEGV_MAPERR;
-                if (trapnr == TT_DFAULT)
-                    info._sifields._sigfault._addr = env->dmmuregs[4];
-                else
-                    info._sifields._sigfault._addr = env->tsptr->tpc;
-                //queue_signal(env, info.si_signo, &info);
-            }
-#endif
-            break;
-#endif
-        case EXCP_INTERRUPT:
-            /* just indicate that signals should be handled asap */
-            break;
-        case EXCP_DEBUG:
-            {
-                int sig;
-
-                sig = gdb_handlesig(cs, TARGET_SIGTRAP);
-#if 0
-                if (sig)
-                  {
-                    info.si_signo = sig;
-                    info.si_errno = 0;
-                    info.si_code = TARGET_TRAP_BRKPT;
-                    //queue_signal(env, info.si_signo, &info);
-                  }
-#endif
-            }
-            break;
-        default:
-#ifdef TARGET_SPARC64
-        badtrap:
-#endif
-            printf ("Unhandled trap: 0x%x\n", trapnr);
-            cpu_dump_state(cs, stderr, fprintf, 0);
-            exit (1);
-        }
-        process_pending_signals (env);
-    }
+    target_cpu_loop(env);
 }
 
-#endif
-
 static void usage(void)
 {
     printf("qemu-" TARGET_NAME " version " QEMU_VERSION ", Copyright (c) 2003-2008 Fabrice Bellard\n"
@@ -709,12 +252,21 @@ static void usage(void)
            ,
            TARGET_NAME,
            interp_prefix,
-           x86_stack_size);
+           target_dflssiz);
     exit(1);
 }
 
 THREAD CPUState *thread_cpu;
 
+void stop_all_tasks(void)
+{
+    /*
+     * We trust when using NPTL (pthreads) start_exclusive() handles thread
+     * stopping correctly.
+     */
+    start_exclusive();
+}
+
 /* Assumes contents are already zeroed.  */
 void init_task_state(TaskState *ts)
 {
@@ -728,14 +280,55 @@ void init_task_state(TaskState *ts)
     ts->sigqueue_table[i].next = NULL;
 }
 
+CPUArchState *cpu_copy(CPUArchState *env)
+{
+    CPUArchState *new_env = cpu_init(cpu_model);
+    CPUState *cpu = ENV_GET_CPU(env);
+#if defined(TARGET_HAS_ICE)
+    CPUBreakpoint *bp;
+    CPUWatchpoint *wp;
+#endif
+
+    /* Reset non arch specific state */
+    cpu_reset(ENV_GET_CPU(new_env));
+
+    memcpy(new_env, env, sizeof(CPUArchState));
+
+    /* Clone all break/watchpoints.
+       Note: Once we support ptrace with hw-debug register access, make sure
+       BP_CPU break/watchpoints are handled correctly on clone. */
+    QTAILQ_INIT(&cpu->breakpoints);
+    QTAILQ_INIT(&cpu->watchpoints);
+#if defined(TARGET_HAS_ICE)
+    QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) {
+        cpu_breakpoint_insert(cpu, bp->pc, bp->flags, NULL);
+    }
+    QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) {
+        cpu_watchpoint_insert(cpu, wp->vaddr, (~wp->len_mask) + 1,
+                              wp->flags, NULL);
+    }
+#endif
+
+    return new_env;
+}
+
+void gemu_log(const char *fmt, ...)
+{
+    va_list ap;
+
+    va_start(ap, fmt);
+    vfprintf(stderr, fmt, ap);
+    va_end(ap);
+}
+
 int main(int argc, char **argv)
 {
     const char *filename;
-    const char *cpu_model;
     const char *log_file = NULL;
     const char *log_mask = NULL;
     struct target_pt_regs regs1, *regs = &regs1;
     struct image_info info1, *info = &info1;
+    struct linux_binprm bprm;
     TaskState ts1, *ts = &ts1;
     CPUArchState *env;
     CPUState *cpu;
@@ -744,11 +337,13 @@ int main(int argc, char **argv)
     int gdbstub_port = 0;
     char **target_environ, **wrk;
     envlist_t *envlist = NULL;
-    bsd_type = target_openbsd;
+    bsd_type = HOST_DEFAULT_BSD_TYPE;
 
     if (argc <= 1)
         usage();
 
+    save_proc_pathname(argv[0]);
+
     module_call_init(MODULE_INIT_QOM);
 
     if ((envlist = envlist_create()) == NULL) {
@@ -767,7 +362,7 @@ int main(int argc, char **argv)
 #endif
 
     optind = 1;
-    for(;;) {
+    for (;;) {
         if (optind >= argc)
             break;
         r = argv[optind];
@@ -803,13 +398,18 @@ int main(int argc, char **argv)
                 usage();
         } else if (!strcmp(r, "s")) {
             r = argv[optind++];
-            x86_stack_size = strtol(r, (char **)&r, 0);
-            if (x86_stack_size <= 0)
+            target_dflssiz = strtol(r, (char **)&r, 0);
+            if (target_dflssiz <= 0) {
+                usage();
+            }
+            if (*r == 'M') {
+                target_dflssiz *= 1024 * 1024;
+            } else if (*r == 'k' || *r == 'K') {
+                target_dflssiz *= 1024;
+            }
+            if (target_dflssiz > target_maxssiz) {
                 usage();
-            if (*r == 'M')
-                x86_stack_size *= 1024 * 1024;
-            else if (*r == 'k' || *r == 'K')
-                x86_stack_size *= 1024;
+            }
         } else if (!strcmp(r, "L")) {
             interp_prefix = argv[optind++];
         } else if (!strcmp(r, "p")) {
@@ -881,6 +481,8 @@ int main(int argc, char **argv)
     /* Zero out regs */
     memset(regs, 0, sizeof(struct target_pt_regs));
 
+    memset(&bprm, 0, sizeof(bprm));
+
     /* Zero out image_info */
     memset(info, 0, sizeof(struct image_info));
 
@@ -888,21 +490,7 @@ int main(int argc, char **argv)
     init_paths(interp_prefix);
 
     if (cpu_model == NULL) {
-#if defined(TARGET_I386)
-#ifdef TARGET_X86_64
-        cpu_model = "qemu64";
-#else
-        cpu_model = "qemu32";
-#endif
-#elif defined(TARGET_SPARC)
-#ifdef TARGET_SPARC64
-        cpu_model = "TI UltraSparc II";
-#else
-        cpu_model = "Fujitsu MB86904";
-#endif
-#else
-        cpu_model = "any";
-#endif
+        cpu_model = TARGET_DEFAULT_CPU_MODEL;
     }
     tcg_exec_init(0);
     cpu_exec_init_all();
@@ -914,9 +502,7 @@ int main(int argc, char **argv)
         exit(1);
     }
     cpu = ENV_GET_CPU(env);
-#if defined(TARGET_SPARC) || defined(TARGET_PPC)
-    cpu_reset(cpu);
-#endif
+    TARGET_CPU_RESET(env);
     thread_cpu = cpu;
 
     if (getenv("QEMU_STRACE")) {
@@ -955,7 +541,7 @@ int main(int argc, char **argv)
     }
 #endif /* CONFIG_USE_GUEST_BASE */
 
-    if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) {
+    if (loader_exec(filename, argv+optind, target_environ, regs, info)) {
         printf("Error loading %s\n", filename);
         _exit(1);
     }
@@ -1000,137 +586,10 @@ int main(int argc, char **argv)
     memset(ts, 0, sizeof(TaskState));
     init_task_state(ts);
     ts->info = info;
+    ts->bprm = &bprm;
     cpu->opaque = ts;
 
-#if defined(TARGET_I386)
-    env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
-    env->hflags |= HF_PE_MASK | HF_CPL_MASK;
-    if (env->features[FEAT_1_EDX] & CPUID_SSE) {
-        env->cr[4] |= CR4_OSFXSR_MASK;
-        env->hflags |= HF_OSFXSR_MASK;
-    }
-#ifndef TARGET_ABI32
-    /* enable 64 bit mode if possible */
-    if (!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) {
-        fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
-        exit(1);
-    }
-    env->cr[4] |= CR4_PAE_MASK;
-    env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
-    env->hflags |= HF_LMA_MASK;
-#endif
-
-    /* flags setup : we activate the IRQs by default as in user mode */
-    env->eflags |= IF_MASK;
-
-    /* linux register setup */
-#ifndef TARGET_ABI32
-    env->regs[R_EAX] = regs->rax;
-    env->regs[R_EBX] = regs->rbx;
-    env->regs[R_ECX] = regs->rcx;
-    env->regs[R_EDX] = regs->rdx;
-    env->regs[R_ESI] = regs->rsi;
-    env->regs[R_EDI] = regs->rdi;
-    env->regs[R_EBP] = regs->rbp;
-    env->regs[R_ESP] = regs->rsp;
-    env->eip = regs->rip;
-#else
-    env->regs[R_EAX] = regs->eax;
-    env->regs[R_EBX] = regs->ebx;
-    env->regs[R_ECX] = regs->ecx;
-    env->regs[R_EDX] = regs->edx;
-    env->regs[R_ESI] = regs->esi;
-    env->regs[R_EDI] = regs->edi;
-    env->regs[R_EBP] = regs->ebp;
-    env->regs[R_ESP] = regs->esp;
-    env->eip = regs->eip;
-#endif
-
-    /* linux interrupt setup */
-#ifndef TARGET_ABI32
-    env->idt.limit = 511;
-#else
-    env->idt.limit = 255;
-#endif
-    env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
-                                PROT_READ|PROT_WRITE,
-                                MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
-    idt_table = g2h(env->idt.base);
-    set_idt(0, 0);
-    set_idt(1, 0);
-    set_idt(2, 0);
-    set_idt(3, 3);
-    set_idt(4, 3);
-    set_idt(5, 0);
-    set_idt(6, 0);
-    set_idt(7, 0);
-    set_idt(8, 0);
-    set_idt(9, 0);
-    set_idt(10, 0);
-    set_idt(11, 0);
-    set_idt(12, 0);
-    set_idt(13, 0);
-    set_idt(14, 0);
-    set_idt(15, 0);
-    set_idt(16, 0);
-    set_idt(17, 0);
-    set_idt(18, 0);
-    set_idt(19, 0);
-    set_idt(0x80, 3);
-
-    /* linux segment setup */
-    {
-        uint64_t *gdt_table;
-        env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
-                                    PROT_READ|PROT_WRITE,
-                                    MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
-        env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
-        gdt_table = g2h(env->gdt.base);
-#ifdef TARGET_ABI32
-        write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
-                 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
-                 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
-#else
-        /* 64 bit code segment */
-        write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
-                 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
-                 DESC_L_MASK |
-                 (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
-#endif
-        write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
-                 DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
-                 (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
-    }
-
-    cpu_x86_load_seg(env, R_CS, __USER_CS);
-    cpu_x86_load_seg(env, R_SS, __USER_DS);
-#ifdef TARGET_ABI32
-    cpu_x86_load_seg(env, R_DS, __USER_DS);
-    cpu_x86_load_seg(env, R_ES, __USER_DS);
-    cpu_x86_load_seg(env, R_FS, __USER_DS);
-    cpu_x86_load_seg(env, R_GS, __USER_DS);
-    /* This hack makes Wine work... */
-    env->segs[R_FS].selector = 0;
-#else
-    cpu_x86_load_seg(env, R_DS, 0);
-    cpu_x86_load_seg(env, R_ES, 0);
-    cpu_x86_load_seg(env, R_FS, 0);
-    cpu_x86_load_seg(env, R_GS, 0);
-#endif
-#elif defined(TARGET_SPARC)
-    {
-        int i;
-        env->pc = regs->pc;
-        env->npc = regs->npc;
-        env->y = regs->y;
-        for(i = 0; i < 8; i++)
-            env->gregs[i] = regs->u_regs[i];
-        for(i = 0; i < 8; i++)
-            env->regwptr[i] = regs->u_regs[i + 8];
-    }
-#else
-#error unsupported target CPU
-#endif
+    target_cpu_init(env, regs);
 
     if (gdbstub_port) {
         gdbserver_start (gdbstub_port);
diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index 092bf7f..121443a 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -30,7 +30,7 @@
 
 //#define DEBUG_MMAP
 
-#if defined(CONFIG_USE_NPTL)
+#ifdef __FreeBSD__
 pthread_mutex_t mmap_mutex;
 static int __thread mmap_lock_count;
 
diff --git a/bsd-user/netbsd/host_os.h b/bsd-user/netbsd/host_os.h
new file mode 100644
index 0000000..5c492e3
--- /dev/null
+++ b/bsd-user/netbsd/host_os.h
@@ -0,0 +1,31 @@
+/*
+ *  NetBSD host dependent code and 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 __HOST_OS_H_
+#define __HOST_OS_H_
+
+#include "qemu.h"
+
+#define HOST_DEFAULT_BSD_TYPE target_netbsd
+
+static inline void save_proc_pathname(char *argv0)
+{
+    /* XXX */
+}
+
+#endif /*!__HOST_OS_H_ */
diff --git a/bsd-user/netbsd/os-strace.h b/bsd-user/netbsd/os-strace.h
index 20dfd4b..ead15db 100644
--- a/bsd-user/netbsd/os-strace.h
+++ b/bsd-user/netbsd/os-strace.h
@@ -25,7 +25,7 @@ static inline void do_os_print_sysarch(const struct syscallname *name,
         abi_long arg5, abi_long arg6)
 {
     qemu_log("qemu: Unsupported syscall %s\n", __func__);
-    return -TARGET_ENOSYS;
+    return;
 }
 
 /* sysarch() is architecture dependent. */
diff --git a/bsd-user/netbsd/target_os_vmparam.h b/bsd-user/netbsd/target_os_vmparam.h
new file mode 100644
index 0000000..80ac6c8
--- /dev/null
+++ b/bsd-user/netbsd/target_os_vmparam.h
@@ -0,0 +1,23 @@
+#ifndef _TARGET_OS_VMPARAM_H_
+#define _TARGET_OS_VMPARAM_H_
+
+#include "target_arch_vmparam.h"
+
+#define TARGET_SPACE_USRSPACE   4096
+#define TARGET_ARG_MAX          262144
+
+/* Compare to sys/exec.h */
+struct target_ps_strings {
+    abi_ulong ps_argvstr;
+    uint32_t ps_nargvstr;
+    abi_ulong ps_envstr;
+    uint32_t ps_nenvstr;
+};
+
+extern abi_ulong target_stkbas;
+extern abi_ulong target_stksiz;
+
+#define TARGET_PS_STRINGS  ((target_stkbas + target_stksiz) - \
+		sizeof(struct target_ps_strings))
+
+#endif /* !TARGET_OS_VMPARAM_H_ */
diff --git a/bsd-user/openbsd/host_os.h b/bsd-user/openbsd/host_os.h
new file mode 100644
index 0000000..162ce58
--- /dev/null
+++ b/bsd-user/openbsd/host_os.h
@@ -0,0 +1,31 @@
+/*
+ *  OpenBSD host dependent code and 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 __HOST_OS_H_
+#define __HOST_OS_H_
+
+#include "qemu.h"
+
+#define HOST_DEFAULT_BSD_TYPE target_openbsd
+
+static inline void save_proc_pathname(char *argv0)
+{
+    /* XXX */
+}
+
+#endif /*!__HOST_OS_H_ */
diff --git a/bsd-user/openbsd/os-strace.h b/bsd-user/openbsd/os-strace.h
index 277b96c..88907b4 100644
--- a/bsd-user/openbsd/os-strace.h
+++ b/bsd-user/openbsd/os-strace.h
@@ -25,7 +25,7 @@ static inline void do_os_print_sysarch(const struct syscallname *name,
         abi_long arg5, abi_long arg6)
 {
     qemu_log("qemu: Unsupported syscall %s\n", __func__);
-    return -TARGET_ENOSYS;
+    return;
 }
 
 /* sysarch() is architecture dependent. */
diff --git a/bsd-user/openbsd/target_os_vmparam.h b/bsd-user/openbsd/target_os_vmparam.h
new file mode 100644
index 0000000..80ac6c8
--- /dev/null
+++ b/bsd-user/openbsd/target_os_vmparam.h
@@ -0,0 +1,23 @@
+#ifndef _TARGET_OS_VMPARAM_H_
+#define _TARGET_OS_VMPARAM_H_
+
+#include "target_arch_vmparam.h"
+
+#define TARGET_SPACE_USRSPACE   4096
+#define TARGET_ARG_MAX          262144
+
+/* Compare to sys/exec.h */
+struct target_ps_strings {
+    abi_ulong ps_argvstr;
+    uint32_t ps_nargvstr;
+    abi_ulong ps_envstr;
+    uint32_t ps_nenvstr;
+};
+
+extern abi_ulong target_stkbas;
+extern abi_ulong target_stksiz;
+
+#define TARGET_PS_STRINGS  ((target_stkbas + target_stksiz) - \
+		sizeof(struct target_ps_strings))
+
+#endif /* !TARGET_OS_VMPARAM_H_ */
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 658999b..7521ebe 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -39,10 +39,11 @@ extern enum BSDType bsd_type;
 
 #include "syscall_defs.h"
 #include "syscall.h"
+#include "target_os_vmparam.h"
 #include "target_signal.h"
 #include "exec/gdbstub.h"
 
-#if defined(CONFIG_USE_NPTL)
+#ifdef __FreeBSD__
 #define THREAD __thread
 #else
 #define THREAD
@@ -90,6 +91,7 @@ typedef struct TaskState {
     struct TaskState *next;
     int used; /* non zero if used */
     struct image_info *info;
+    struct linux_binprm *bprm;
 
     struct emulated_sigtable sigtab[TARGET_NSIG];
     struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
@@ -100,6 +102,7 @@ typedef struct TaskState {
 } __attribute__((aligned(16))) TaskState;
 
 void init_task_state(TaskState *ts);
+void stop_all_tasks(void);
 extern const char *qemu_uname_release;
 #if defined(CONFIG_USE_GUEST_BASE)
 extern unsigned long mmap_min_addr;
@@ -217,13 +220,23 @@ void mmap_lock(void);
 void mmap_unlock(void);
 void cpu_list_lock(void);
 void cpu_list_unlock(void);
-#if defined(CONFIG_USE_NPTL)
+#ifdef __FreeBSD__
 void mmap_fork_start(void);
 void mmap_fork_end(int child);
 #endif
 
 /* main.c */
-extern unsigned long x86_stack_size;
+extern unsigned long target_maxtsiz;
+extern unsigned long target_dfldsiz;
+extern unsigned long target_maxdsiz;
+extern unsigned long target_dflssiz;
+extern unsigned long target_maxssiz;
+extern unsigned long target_sgrowsiz;
+extern char qemu_proc_pathname[];
+void start_exclusive(void);
+void end_exclusive(void);
+void cpu_exec_start(CPUState *cpu);
+void cpu_exec_end(CPUState *cpu);
 
 /* os-strace.h */
 abi_long do_bsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2);
@@ -417,7 +430,7 @@ static inline void *lock_user_string(abi_ulong guest_addr)
 #define unlock_user_struct(host_ptr, guest_addr, copy)          \
     unlock_user(host_ptr, guest_addr, (copy) ? sizeof(*host_ptr) : 0)
 
-#if defined(CONFIG_USE_NPTL)
+#ifdef __FreeBSD__
 #include <pthread.h>
 #endif
 
diff --git a/bsd-user/sparc/target_arch.h b/bsd-user/sparc/target_arch.h
new file mode 100644
index 0000000..5ee479b
--- /dev/null
+++ b/bsd-user/sparc/target_arch.h
@@ -0,0 +1,11 @@
+
+#ifndef _TARGET_ARCH_H_
+#define _TARGET_ARCH_H_
+
+void bsd_sparc_save_window(CPUSPARCState *env);
+void bsd_sparc_restore_window(CPUSPARCState *env);
+void bsd_sparc_flush_windows(CPUSPARCState *env);
+
+#define target_cpu_set_tls(env, newtls)
+
+#endif /* ! _TARGET_ARCH_H_ */
diff --git a/bsd-user/sparc/target_arch_cpu.c b/bsd-user/sparc/target_arch_cpu.c
new file mode 100644
index 0000000..0af5c7e
--- /dev/null
+++ b/bsd-user/sparc/target_arch_cpu.c
@@ -0,0 +1,113 @@
+/*
+ *  sparc cpu related code
+ *
+ *
+ *  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 <sys/types.h>
+
+#include "cpu.h"
+#include "qemu.h"
+
+#include "target_arch.h"
+
+/* #define DEBUG_WIN */
+/* WARNING: dealing with register windows _is_ complicated. More info
+   can be found at http://www.sics.se/~psm/sparcstack.html */
+static int get_reg_index(CPUSPARCState *env, int cwp, int index)
+{
+    index = (index + cwp * 16) % (16 * env->nwindows);
+    /* wrap handling : if cwp is on the last window, then we use the
+       registers 'after' the end */
+    if (index < 8 && env->cwp == env->nwindows - 1) {
+        index += 16 * env->nwindows;
+    }
+    return index;
+}
+
+/* save the register window 'cwp1' */
+static void save_window_offset(CPUSPARCState *env, int cwp1)
+{
+    unsigned int i;
+    abi_ulong sp_ptr;
+
+    sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
+#if defined(DEBUG_WIN)
+    printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
+           sp_ptr, cwp1);
+#endif
+    for (i = 0; i < 16; i++) {
+        /* FIXME - what to do if put_user() fails? */
+        put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
+        sp_ptr += sizeof(abi_ulong);
+    }
+}
+
+void bsd_sparc_save_window(CPUSPARCState *env)
+{
+    unsigned int new_wim;
+
+    new_wim = ((env->wim >> 1) | (env->wim << (env->nwindows - 1))) &
+        ((1LL << env->nwindows) - 1);
+    save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
+    env->wim = new_wim;
+}
+
+void bsd_sparc_restore_window(CPUSPARCState *env)
+{
+    unsigned int new_wim;
+    unsigned int i, cwp1;
+    abi_ulong sp_ptr;
+
+    new_wim = ((env->wim << 1) | (env->wim >> (env->nwindows - 1))) &
+        ((1LL << env->nwindows) - 1);
+
+    /* restore the invalid window */
+    cwp1 = cpu_cwp_inc(env, env->cwp + 1);
+    sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
+#if defined(DEBUG_WIN)
+    printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
+           sp_ptr, cwp1);
+#endif
+    for (i = 0; i < 16; i++) {
+        /* FIXME - what to do if get_user() fails? */
+        get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
+        sp_ptr += sizeof(abi_ulong);
+    }
+    env->wim = new_wim;
+}
+
+void bsd_sparc_flush_windows(CPUSPARCState *env)
+{
+    int offset, cwp1;
+
+    offset = 1;
+    for (;;) {
+        /* if restore would invoke restore_window(), then we can stop */
+        cwp1 = cpu_cwp_inc(env, env->cwp + offset);
+        if (env->wim & (1 << cwp1)) {
+            break;
+        }
+        save_window_offset(env, cwp1);
+        offset++;
+    }
+    cwp1 = cpu_cwp_inc(env, env->cwp + 1);
+    /* set wim so that restore will reload the registers */
+    env->wim = 1 << cwp1;
+#if defined(DEBUG_WIN)
+    printf("bsd_sparc_flush_windows: nb=%d\n", offset - 1);
+#endif
+}
+
diff --git a/bsd-user/sparc/target_arch_cpu.h b/bsd-user/sparc/target_arch_cpu.h
new file mode 100644
index 0000000..f61884b
--- /dev/null
+++ b/bsd-user/sparc/target_arch_cpu.h
@@ -0,0 +1,158 @@
+/*
+ *  sparc cpu init and loop
+ *
+ *
+ *  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 _TARGET_ARCH_CPU_H_
+#define _TARGET_ARCH_CPU_H_
+
+#include "target_arch.h"
+
+#define TARGET_DEFAULT_CPU_MODEL "Fujitsu MB86904"
+
+#define TARGET_CPU_RESET(env) cpu_reset(ENV_GET_CPU(env))
+
+static inline void target_cpu_init(CPUSPARCState *env,
+        struct target_pt_regs *regs)
+{
+    int i;
+
+    env->pc = regs->pc;
+    env->npc = regs->npc;
+    env->y = regs->y;
+    for (i = 0; i < 8; i++) {
+        env->gregs[i] = regs->u_regs[i];
+    }
+    for (i = 0; i < 8; i++) {
+        env->regwptr[i] = regs->u_regs[i + 8];
+    }
+}
+
+static inline void target_cpu_loop(CPUSPARCState *env)
+{
+    CPUState *cs = CPU(sparc_env_get_cpu(env));
+    int trapnr, ret, syscall_nr;
+    /* target_siginfo_t info; */
+
+    while (1) {
+        trapnr = cpu_sparc_exec(env);
+
+        switch (trapnr) {
+        case 0x80:
+            syscall_nr = env->gregs[1];
+            if (bsd_type == target_freebsd) {
+                ret = do_freebsd_syscall(env, syscall_nr,
+                                        env->regwptr[0], env->regwptr[1],
+                                        env->regwptr[2], env->regwptr[3],
+                                        env->regwptr[4], env->regwptr[5], 0, 0);
+            } else if (bsd_type == target_netbsd) {
+                ret = do_netbsd_syscall(env, syscall_nr,
+                                        env->regwptr[0], env->regwptr[1],
+                                        env->regwptr[2], env->regwptr[3],
+                                        env->regwptr[4], env->regwptr[5]);
+            } else { /* if (bsd_type == target_openbsd) */
+                ret = do_openbsd_syscall(env, syscall_nr,
+                                         env->regwptr[0], env->regwptr[1],
+                                         env->regwptr[2], env->regwptr[3],
+                                         env->regwptr[4], env->regwptr[5]);
+            }
+            if ((unsigned int)ret >= (unsigned int)(-515)) {
+                ret = -ret;
+                env->psr |= PSR_CARRY;
+            } else {
+                env->psr &= ~PSR_CARRY;
+            }
+            env->regwptr[0] = ret;
+            /* next instruction */
+            env->pc = env->npc;
+            env->npc = env->npc + 4;
+            break;
+        case 0x83: /* flush windows */
+#ifdef TARGET_ABI32
+        case 0x103:
+#endif
+            bsd_sparc_flush_windows(env);
+            /* next instruction */
+            env->pc = env->npc;
+            env->npc = env->npc + 4;
+            break;
+
+        case TT_WIN_OVF: /* window overflow */
+            bsd_sparc_save_window(env);
+            break;
+
+        case TT_WIN_UNF: /* window underflow */
+            bsd_sparc_restore_window(env);
+            break;
+
+        case TT_TFAULT:
+        case TT_DFAULT:
+#if 0
+            {
+                info.si_signo = SIGSEGV;
+                info.si_errno = 0;
+                /* XXX: check env->error_code */
+                info.si_code = TARGET_SEGV_MAPERR;
+                info._sifields._sigfault._addr = env->mmuregs[4];
+                queue_signal(env, info.si_signo, &info);
+            }
+#endif
+            break;
+
+        case EXCP_INTERRUPT:
+            /* just indicate that signals should be handled asap */
+            break;
+
+        case EXCP_DEBUG:
+#if 0
+            {
+                int sig;
+
+                sig = gdb_handlesig(cs, TARGET_SIGTRAP);
+                if (sig) {
+                    info.si_signo = sig;
+                    info.si_errno = 0;
+                    info.si_code = TARGET_TRAP_BRKPT;
+                    /* queue_signal(env, info.si_signo, &info); */
+                }
+            }
+#endif
+            break;
+        default:
+            printf("Unhandled trap: 0x%x\n", trapnr);
+            cpu_dump_state(cs, stderr, fprintf, 0);
+            exit(1);
+        }
+        process_pending_signals(env);
+    }
+}
+
+static inline void target_cpu_clone_regs(CPUSPARCState *env, target_ulong newsp)
+{
+    if (newsp)
+        env->regwptr[22] = newsp;
+    env->regwptr[0] = 0;
+    /* FIXME: Do we also need to clear CF?  */
+    /* XXXXX */
+    printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
+}
+
+static inline void target_cpu_reset(CPUArchState *cpu)
+{
+    cpu_reset(ENV_GET_CPU(cpu));
+}
+
+#endif /* ! _TARGET_ARCH_CPU_H_ */
diff --git a/bsd-user/sparc/target_arch_vmparam.h b/bsd-user/sparc/target_arch_vmparam.h
new file mode 100644
index 0000000..5f28fcf
--- /dev/null
+++ b/bsd-user/sparc/target_arch_vmparam.h
@@ -0,0 +1,37 @@
+#ifndef _TARGET_ARCH_VMPARAM_H_
+#define _TARGET_ARCH_VMPARAM_H_
+
+#include "cpu.h"
+
+#define TARGET_MAXTSIZ  (1*1024*1024*1024)  /* max text size */
+#define TARGET_DFLDSIZ  (128*1024*1024)     /* initial data size limit */
+#define TARGET_MAXDSIZ  (1*1024*1024*1024)  /* max data size */
+#define TARGET_DFLSSIZ  (128*1024*1024)     /* initial stack size limit */
+#define TARGET_MAXSSIZ  (1*1024*1024*1024)  /* max stack size */
+#define TARGET_SGROWSIZ (128*1024)      /* amount to grow stack */
+
+#define TARGET_RESERVED_VA 0xf7000000
+
+/* XXX this may not be right */
+#define TARGET_VM_MAXUSER_ADDRESS   (0xc0000000 - (512 * 1024 * 1024))
+#define TARGET_USRSTACK (TARGET_VM_MAXUSER_ADDRESS - TARGET_PAGE_SIZE)
+
+#ifndef UREG_I6
+#define UREG_I6        6
+#endif
+#ifndef UREG_FP
+#define UREG_FP        UREG_I6
+#endif
+
+static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
+{
+    return state->regwptr[UREG_FP];
+}
+
+static inline void set_second_rval(CPUSPARCState *state, abi_ulong retval2)
+{
+    state->regwptr[1] = retval2;
+}
+
+#endif /* !_TARGET_ARCH_VMPARAM_H_ */
+
diff --git a/bsd-user/sparc/target_signal.h b/bsd-user/sparc/target_signal.h
index 5b2abba..181867a 100644
--- a/bsd-user/sparc/target_signal.h
+++ b/bsd-user/sparc/target_signal.h
@@ -19,9 +19,4 @@ typedef struct target_sigaltstack {
 #define UREG_FP        UREG_I6
 #endif
 
-static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
-{
-    return state->regwptr[UREG_FP];
-}
-
 #endif /* TARGET_SIGNAL_H */
diff --git a/bsd-user/sparc64/target_arch.h b/bsd-user/sparc64/target_arch.h
new file mode 100644
index 0000000..46bbcf8
--- /dev/null
+++ b/bsd-user/sparc64/target_arch.h
@@ -0,0 +1,11 @@
+
+#ifndef _TARGET_ARCH_H_
+#define _TARGET_ARCH_H_
+
+void bsd_sparc64_save_window(CPUSPARCState *env);
+void bsd_sparc64_restore_window(CPUSPARCState *env);
+void bsd_sparc64_flush_windows(CPUSPARCState *env);
+
+#define target_cpu_set_tls(env, newtls)
+
+#endif /* ! _TARGET_ARCH_H_ */
diff --git a/bsd-user/sparc64/target_arch_cpu.c b/bsd-user/sparc64/target_arch_cpu.c
new file mode 100644
index 0000000..e7bede8
--- /dev/null
+++ b/bsd-user/sparc64/target_arch_cpu.c
@@ -0,0 +1,118 @@
+/*
+ *  sparc64 cpu related code
+ *
+ *
+ *  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 <sys/types.h>
+
+#include "cpu.h"
+#include "qemu.h"
+
+#include "target_arch.h"
+
+#define SPARC64_STACK_BIAS 2047
+
+/* #define DEBUG_WIN */
+/* WARNING: dealing with register windows _is_ complicated. More info
+   can be found at http://www.sics.se/~psm/sparcstack.html */
+static int get_reg_index(CPUSPARCState *env, int cwp, int index)
+{
+    index = (index + cwp * 16) % (16 * env->nwindows);
+    /* wrap handling : if cwp is on the last window, then we use the
+       registers 'after' the end */
+    if (index < 8 && env->cwp == env->nwindows - 1) {
+        index += 16 * env->nwindows;
+    }
+    return index;
+}
+
+/* save the register window 'cwp1' */
+static void save_window_offset(CPUSPARCState *env, int cwp1)
+{
+    unsigned int i;
+    abi_ulong sp_ptr;
+
+    sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
+    if (sp_ptr & 3) {
+        sp_ptr += SPARC64_STACK_BIAS;
+    }
+#if defined(DEBUG_WIN)
+    printf("win_overflow: sp_ptr=0x" TARGET_ABI_FMT_lx " save_cwp=%d\n",
+           sp_ptr, cwp1);
+#endif
+    for (i = 0; i < 16; i++) {
+        /* FIXME - what to do if put_user() fails? */
+        put_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
+        sp_ptr += sizeof(abi_ulong);
+    }
+}
+
+void bsd_sparc64_save_window(CPUSPARCState *env)
+{
+    save_window_offset(env, cpu_cwp_dec(env, env->cwp - 2));
+    env->cansave++;
+    env->canrestore--;
+}
+
+void bsd_sparc64_restore_window(CPUSPARCState *env)
+{
+    unsigned int i, cwp1;
+    abi_ulong sp_ptr;
+
+    /* restore the invalid window */
+    cwp1 = cpu_cwp_inc(env, env->cwp + 1);
+    sp_ptr = env->regbase[get_reg_index(env, cwp1, 6)];
+    if (sp_ptr & 3) {
+        sp_ptr += SPARC64_STACK_BIAS;
+    }
+#if defined(DEBUG_WIN)
+    printf("win_underflow: sp_ptr=0x" TARGET_ABI_FMT_lx " load_cwp=%d\n",
+           sp_ptr, cwp1);
+#endif
+    for (i = 0; i < 16; i++) {
+        /* FIXME - what to do if get_user() fails? */
+        get_user_ual(env->regbase[get_reg_index(env, cwp1, 8 + i)], sp_ptr);
+        sp_ptr += sizeof(abi_ulong);
+    }
+    env->canrestore++;
+    if (env->cleanwin < env->nwindows - 1) {
+        env->cleanwin++;
+    }
+    env->cansave--;
+}
+
+void bsd_sparc64_flush_windows(CPUSPARCState *env)
+{
+    int offset, cwp1;
+
+    offset = 1;
+    for (;;) {
+        /* if restore would invoke restore_window(), then we can stop */
+        cwp1 = cpu_cwp_inc(env, env->cwp + offset);
+        if (env->canrestore == 0) {
+            break;
+        }
+        env->cansave++;
+        env->canrestore--;
+        save_window_offset(env, cwp1);
+        offset++;
+    }
+    cwp1 = cpu_cwp_inc(env, env->cwp + 1);
+#if defined(DEBUG_WIN)
+    printf("bsd_sparc64_flush_windows: nb=%d\n", offset - 1);
+#endif
+}
+
diff --git a/bsd-user/sparc64/target_arch_cpu.h b/bsd-user/sparc64/target_arch_cpu.h
new file mode 100644
index 0000000..e497711
--- /dev/null
+++ b/bsd-user/sparc64/target_arch_cpu.h
@@ -0,0 +1,191 @@
+/*
+ *  sparc64 cpu init and loop
+ *
+ *
+ *  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 _TARGET_ARCH_CPU_H_
+#define _TARGET_ARCH_CPU_H_
+
+#include "target_arch.h"
+
+#define TARGET_DEFAULT_CPU_MODEL "TI UltraSparc II"
+
+#define TARGET_CPU_RESET(env) cpu_reset(ENV_GET_CPU(env))
+
+static inline void target_cpu_init(CPUSPARCState *env,
+        struct target_pt_regs *regs)
+{
+    int i;
+
+    env->pc = regs->pc;
+    env->npc = regs->npc;
+    env->y = regs->y;
+    for (i = 0; i < 8; i++) {
+        env->gregs[i] = regs->u_regs[i];
+    }
+    for (i = 0; i < 8; i++) {
+        env->regwptr[i] = regs->u_regs[i + 8];
+    }
+}
+
+
+static inline void target_cpu_loop(CPUSPARCState *env)
+{
+    CPUState *cs = CPU(sparc_env_get_cpu(env));
+    int trapnr, ret, syscall_nr;
+    /* target_siginfo_t info; */
+
+    while (1) {
+        trapnr = cpu_sparc_exec(env);
+
+        switch (trapnr) {
+        /* FreeBSD uses 0x141 for syscalls too */
+        case 0x141:
+            if (bsd_type != target_freebsd) {
+                goto badtrap;
+            }
+        case 0x100:
+            syscall_nr = env->gregs[1];
+            if (bsd_type == target_freebsd) {
+                ret = do_freebsd_syscall(env, syscall_nr,
+                                        env->regwptr[0], env->regwptr[1],
+                                        env->regwptr[2], env->regwptr[3],
+                                        env->regwptr[4], env->regwptr[5], 0, 0);
+            } else if (bsd_type == target_netbsd) {
+                ret = do_netbsd_syscall(env, syscall_nr,
+                                        env->regwptr[0], env->regwptr[1],
+                                        env->regwptr[2], env->regwptr[3],
+                                        env->regwptr[4], env->regwptr[5]);
+            } else { /* if (bsd_type == target_openbsd) */
+                syscall_nr &= ~(TARGET_OPENBSD_SYSCALL_G7RFLAG |
+                                TARGET_OPENBSD_SYSCALL_G2RFLAG);
+                ret = do_openbsd_syscall(env, syscall_nr,
+                                         env->regwptr[0], env->regwptr[1],
+                                         env->regwptr[2], env->regwptr[3],
+                                         env->regwptr[4], env->regwptr[5]);
+            }
+            if ((unsigned int)ret >= (unsigned int)(-515)) {
+                ret = -ret;
+#if !defined(TARGET_ABI32)
+                env->xcc |= PSR_CARRY;
+#else
+                env->psr |= PSR_CARRY;
+#endif
+            } else {
+#if !defined(TARGET_ABI32)
+                env->xcc &= ~PSR_CARRY;
+#else
+                env->psr &= ~PSR_CARRY;
+#endif
+            }
+            env->regwptr[0] = ret;
+            /* next instruction */
+            if (bsd_type == target_openbsd &&
+                env->gregs[1] & TARGET_OPENBSD_SYSCALL_G2RFLAG) {
+                env->pc = env->gregs[2];
+                env->npc = env->pc + 4;
+            } else if (bsd_type == target_openbsd &&
+                       env->gregs[1] & TARGET_OPENBSD_SYSCALL_G7RFLAG) {
+                env->pc = env->gregs[7];
+                env->npc = env->pc + 4;
+            } else {
+                env->pc = env->npc;
+                env->npc = env->npc + 4;
+            }
+            break;
+
+        case 0x83: /* flush windows */
+#ifdef TARGET_ABI32
+        case 0x103:
+#endif
+            bsd_sparc64_flush_windows(env);
+            /* next instruction */
+            env->pc = env->npc;
+            env->npc = env->npc + 4;
+            break;
+
+        case TT_SPILL: /* window overflow */
+            bsd_sparc64_save_window(env);
+            break;
+
+        case TT_FILL: /* window underflow */
+            bsd_sparc64_restore_window(env);
+            break;
+
+        case TT_TFAULT:
+        case TT_DFAULT:
+#if 0
+            {
+                info.si_signo = SIGSEGV;
+                info.si_errno = 0;
+                /* XXX: check env->error_code */
+                info.si_code = TARGET_SEGV_MAPERR;
+                if (trapnr == TT_DFAULT) {
+                    info._sifields._sigfault._addr = env->dmmuregs[4];
+                } else {
+                    info._sifields._sigfault._addr = env->tsptr->tpc;
+                    /* queue_signal(env, info.si_signo, &info); */
+                }
+            }
+#endif
+            break;
+
+        case EXCP_INTERRUPT:
+            /* just indicate that signals should be handled asap */
+            break;
+
+        case EXCP_DEBUG:
+            {
+                int sig;
+
+                sig = gdb_handlesig(cs, TARGET_SIGTRAP);
+#if 0
+                if (sig) {
+                    info.si_signo = sig;
+                    info.si_errno = 0;
+                    info.si_code = TARGET_TRAP_BRKPT;
+                    /* queue_signal(env, info.si_signo, &info); */
+                }
+#endif
+            }
+            break;
+
+        default:
+badtrap:
+            printf("Unhandled trap: 0x%x\n", trapnr);
+            cpu_dump_state(cs, stderr, fprintf, 0);
+            exit(1);
+        }
+        process_pending_signals(env);
+    }
+}
+
+static inline void target_cpu_clone_regs(CPUSPARCState *env, target_ulong newsp)
+{
+    if (newsp)
+        env->regwptr[22] = newsp;
+    env->regwptr[0] = 0;
+    /* FIXME: Do we also need to clear CF?  */
+    /* XXXXX */
+    printf ("HELPME: %s:%d\n", __FILE__, __LINE__);
+}
+
+static inline void target_cpu_reset(CPUArchState *cpu)
+{
+    cpu_reset(ENV_GET_CPU(cpu));
+}
+
+#endif /* ! _TARGET_ARCH_CPU_H_ */
diff --git a/bsd-user/sparc64/target_arch_vmparam.h b/bsd-user/sparc64/target_arch_vmparam.h
new file mode 100644
index 0000000..2c2323b
--- /dev/null
+++ b/bsd-user/sparc64/target_arch_vmparam.h
@@ -0,0 +1,37 @@
+#ifndef _TARGET_ARCH_VMPARAM_H_
+#define _TARGET_ARCH_VMPARAM_H_
+
+#include "cpu.h"
+
+/* compare to amd64/include/vmparam.h */
+#define TARGET_MAXTSIZ  (1*1024*1024*1024)  /* max text size */
+#define TARGET_DFLDSIZ  (128*1024*1024)     /* initial data size limit */
+#define TARGET_MAXDSIZ  (1*1024*1024*1024)  /* max data size */
+#define TARGET_DFLSSIZ  (128*1024*1024)     /* initial stack size limit */
+#define TARGET_MAXSSIZ  (1*1024*1024*1024)  /* max stack size */
+#define TARGET_SGROWSIZ (128*1024)      /* amount to grow stack */
+
+/* XXX */
+#define TARGET_VM_MINUSER_ADDRESS   (0x0000000000000000UL)
+#define TARGET_VM_MAXUSER_ADDRESS   (0x000007fe00000000UL)
+#define TARGET_USRSTACK (TARGET_VM_MAXUSER_ADDRESS - TARGET_PAGE_SIZE)
+
+#ifndef UREG_I6
+#define UREG_I6        6
+#endif
+#ifndef UREG_FP
+#define UREG_FP        UREG_I6
+#endif
+
+static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
+{
+    return state->regwptr[UREG_FP];
+}
+
+static inline void set_second_rval(CPUSPARCState *state, abi_ulong retval2)
+{
+    state->regwptr[1] = retval2;
+}
+
+#endif /* !_TARGET_ARCH_VMPARAM_H_ */
+
diff --git a/bsd-user/sparc64/target_signal.h b/bsd-user/sparc64/target_signal.h
index 5b2abba..181867a 100644
--- a/bsd-user/sparc64/target_signal.h
+++ b/bsd-user/sparc64/target_signal.h
@@ -19,9 +19,4 @@ typedef struct target_sigaltstack {
 #define UREG_FP        UREG_I6
 #endif
 
-static inline abi_ulong get_sp_from_cpustate(CPUSPARCState *state)
-{
-    return state->regwptr[UREG_FP];
-}
-
 #endif /* TARGET_SIGNAL_H */
diff --git a/bsd-user/x86_64/target_arch.h b/bsd-user/x86_64/target_arch.h
new file mode 100644
index 0000000..7fe81dc
--- /dev/null
+++ b/bsd-user/x86_64/target_arch.h
@@ -0,0 +1,13 @@
+
+#ifndef _TARGET_ARCH_H_
+#define _TARGET_ARCH_H_
+
+/* target_arch_cpu.c */
+void bsd_x86_64_write_dt(void *ptr, unsigned long addr, unsigned long limit,
+                int flags);
+void bsd_x86_64_set_idt(int n, unsigned int dpl);
+void bsd_x86_64_set_idt_base(uint64_t base);
+
+#define target_cpu_set_tls(env, newtls)
+
+#endif /* !_TARGET_ARCH_H_ */
diff --git a/bsd-user/x86_64/target_arch_cpu.c b/bsd-user/x86_64/target_arch_cpu.c
new file mode 100644
index 0000000..5cfdfca
--- /dev/null
+++ b/bsd-user/x86_64/target_arch_cpu.c
@@ -0,0 +1,79 @@
+/*
+ *  x86_64 cpu related code
+ *
+ *
+ *  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 <sys/types.h>
+
+#include "cpu.h"
+#include "qemu.h"
+#include "qemu/timer.h"
+
+#include "target_arch.h"
+
+static uint64_t *idt_table;
+
+/* CPUX86 core interface */
+void cpu_smm_update(CPUX86State *env)
+{
+}
+
+uint64_t cpu_get_tsc(CPUX86State *env)
+{
+    return cpu_get_real_ticks();
+}
+
+int cpu_get_pic_interrupt(CPUX86State *env)
+{
+    return -1;
+}
+
+void bsd_x86_64_write_dt(void *ptr, unsigned long addr,
+        unsigned long limit, int flags)
+{
+    unsigned int e1, e2;
+    uint32_t *p;
+    e1 = (addr << 16) | (limit & 0xffff);
+    e2 = ((addr >> 16) & 0xff) | (addr & 0xff000000) | (limit & 0x000f0000);
+    e2 |= flags;
+    p = ptr;
+    p[0] = tswap32(e1);
+    p[1] = tswap32(e2);
+}
+
+static void set_gate64(void *ptr, unsigned int type, unsigned int dpl,
+        uint64_t addr, unsigned int sel)
+{
+    uint32_t *p, e1, e2;
+    e1 = (addr & 0xffff) | (sel << 16);
+    e2 = (addr & 0xffff0000) | 0x8000 | (dpl << 13) | (type << 8);
+    p = ptr;
+    p[0] = tswap32(e1);
+    p[1] = tswap32(e2);
+    p[2] = tswap32(addr >> 32);
+    p[3] = 0;
+}
+
+/* only dpl matters as we do only user space emulation */
+void bsd_x86_64_set_idt(int n, unsigned int dpl)
+{
+    set_gate64(idt_table + n * 2, 0, dpl, 0, 0);
+}
+
+void bsd_x86_64_set_idt_base(uint64_t base)
+{
+    idt_table = g2h(base);
+}
diff --git a/bsd-user/x86_64/target_arch_cpu.h b/bsd-user/x86_64/target_arch_cpu.h
new file mode 100644
index 0000000..dd0f128
--- /dev/null
+++ b/bsd-user/x86_64/target_arch_cpu.h
@@ -0,0 +1,322 @@
+/*
+ *  x86_64 cpu init and loop
+ *
+ *
+ *  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 _TARGET_ARCH_CPU_H_
+#define _TARGET_ARCH_CPU_H_
+
+#include "target_arch.h"
+
+#define TARGET_DEFAULT_CPU_MODEL "qemu64"
+
+#define TARGET_CPU_RESET(env)
+
+static inline void target_cpu_init(CPUX86State *env,
+        struct target_pt_regs *regs)
+{
+    uint64_t *gdt_table;
+
+    env->cr[0] = CR0_PG_MASK | CR0_WP_MASK | CR0_PE_MASK;
+    env->hflags |= HF_PE_MASK;
+    if (env->features[FEAT_1_EDX] & CPUID_SSE) {
+        env->cr[4] |= CR4_OSFXSR_MASK;
+        env->hflags |= HF_OSFXSR_MASK;
+    }
+
+    /* enable 64 bit mode if possible */
+    if (!(env->features[FEAT_8000_0001_EDX] & CPUID_EXT2_LM)) {
+        fprintf(stderr, "The selected x86 CPU does not support 64 bit mode\n");
+        exit(1);
+    }
+    env->cr[4] |= CR4_PAE_MASK;
+    env->efer |= MSR_EFER_LMA | MSR_EFER_LME;
+    env->hflags |= HF_LMA_MASK;
+
+    /* flags setup : we activate the IRQs by default as in user mode */
+    env->eflags |= IF_MASK;
+
+    /* register setup */
+    env->regs[R_EAX] = regs->rax;
+    env->regs[R_EBX] = regs->rbx;
+    env->regs[R_ECX] = regs->rcx;
+    env->regs[R_EDX] = regs->rdx;
+    env->regs[R_ESI] = regs->rsi;
+    env->regs[R_EDI] = regs->rdi;
+    env->regs[R_EBP] = regs->rbp;
+    env->regs[R_ESP] = regs->rsp;
+    env->eip = regs->rip;
+
+    /* interrupt setup */
+    env->idt.limit = 511;
+
+    env->idt.base = target_mmap(0, sizeof(uint64_t) * (env->idt.limit + 1),
+        PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+    bsd_x86_64_set_idt_base(env->idt.base);
+    bsd_x86_64_set_idt(0, 0);
+    bsd_x86_64_set_idt(1, 0);
+    bsd_x86_64_set_idt(2, 0);
+    bsd_x86_64_set_idt(3, 3);
+    bsd_x86_64_set_idt(4, 3);
+    bsd_x86_64_set_idt(5, 0);
+    bsd_x86_64_set_idt(6, 0);
+    bsd_x86_64_set_idt(7, 0);
+    bsd_x86_64_set_idt(8, 0);
+    bsd_x86_64_set_idt(9, 0);
+    bsd_x86_64_set_idt(10, 0);
+    bsd_x86_64_set_idt(11, 0);
+    bsd_x86_64_set_idt(12, 0);
+    bsd_x86_64_set_idt(13, 0);
+    bsd_x86_64_set_idt(14, 0);
+    bsd_x86_64_set_idt(15, 0);
+    bsd_x86_64_set_idt(16, 0);
+    bsd_x86_64_set_idt(17, 0);
+    bsd_x86_64_set_idt(18, 0);
+    bsd_x86_64_set_idt(19, 0);
+    bsd_x86_64_set_idt(0x80, 3);
+
+    /* segment setup */
+    env->gdt.base = target_mmap(0, sizeof(uint64_t) * TARGET_GDT_ENTRIES,
+            PROT_READ|PROT_WRITE, MAP_ANONYMOUS|MAP_PRIVATE, -1, 0);
+    env->gdt.limit = sizeof(uint64_t) * TARGET_GDT_ENTRIES - 1;
+    gdt_table = g2h(env->gdt.base);
+
+    /* 64 bit code segment */
+    bsd_x86_64_write_dt(&gdt_table[__USER_CS >> 3], 0, 0xfffff,
+            DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK | DESC_L_MASK
+            | (3 << DESC_DPL_SHIFT) | (0xa << DESC_TYPE_SHIFT));
+
+    bsd_x86_64_write_dt(&gdt_table[__USER_DS >> 3], 0, 0xfffff,
+            DESC_G_MASK | DESC_B_MASK | DESC_P_MASK | DESC_S_MASK |
+            (3 << DESC_DPL_SHIFT) | (0x2 << DESC_TYPE_SHIFT));
+
+    cpu_x86_load_seg(env, R_CS, __USER_CS);
+    cpu_x86_load_seg(env, R_SS, __USER_DS);
+    cpu_x86_load_seg(env, R_DS, 0);
+    cpu_x86_load_seg(env, R_ES, 0);
+    cpu_x86_load_seg(env, R_FS, 0);
+    cpu_x86_load_seg(env, R_GS, 0);
+}
+
+static inline void target_cpu_loop(CPUX86State *env)
+{
+    int trapnr;
+    abi_ulong pc;
+    /* target_siginfo_t info; */
+
+    for (;;) {
+        trapnr = cpu_x86_exec(env);
+        switch (trapnr) {
+        case 0x80:
+            /* syscall from int $0x80 */
+            if (bsd_type == target_freebsd) {
+                abi_ulong params = (abi_ulong) env->regs[R_ESP] +
+                    sizeof(int32_t);
+                int32_t syscall_nr = env->regs[R_EAX];
+                int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8;
+
+                if (syscall_nr == TARGET_FREEBSD_NR_syscall) {
+                    get_user_s32(syscall_nr, params);
+                    params += sizeof(int32_t);
+                } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) {
+                    get_user_s32(syscall_nr, params);
+                    params += sizeof(int64_t);
+                }
+                get_user_s32(arg1, params);
+                params += sizeof(int32_t);
+                get_user_s32(arg2, params);
+                params += sizeof(int32_t);
+                get_user_s32(arg3, params);
+                params += sizeof(int32_t);
+                get_user_s32(arg4, params);
+                params += sizeof(int32_t);
+                get_user_s32(arg5, params);
+                params += sizeof(int32_t);
+                get_user_s32(arg6, params);
+                params += sizeof(int32_t);
+                get_user_s32(arg7, params);
+                params += sizeof(int32_t);
+                get_user_s32(arg8, params);
+                env->regs[R_EAX] = do_freebsd_syscall(env,
+                                                      syscall_nr,
+                                                      arg1,
+                                                      arg2,
+                                                      arg3,
+                                                      arg4,
+                                                      arg5,
+                                                      arg6,
+                                                      arg7,
+                                                      arg8);
+            } else { /* if (bsd_type == target_openbsd) */
+                env->regs[R_EAX] = do_openbsd_syscall(env,
+                                                      env->regs[R_EAX],
+                                                      env->regs[R_EBX],
+                                                      env->regs[R_ECX],
+                                                      env->regs[R_EDX],
+                                                      env->regs[R_ESI],
+                                                      env->regs[R_EDI],
+                                                      env->regs[R_EBP]);
+            }
+            if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
+                env->regs[R_EAX] = -env->regs[R_EAX];
+                env->eflags |= CC_C;
+            } else {
+                env->eflags &= ~CC_C;
+            }
+            break;
+
+        case EXCP_SYSCALL:
+            /* syscall from syscall instruction */
+            if (bsd_type == target_freebsd) {
+                env->regs[R_EAX] = do_freebsd_syscall(env,
+                                                      env->regs[R_EAX],
+                                                      env->regs[R_EDI],
+                                                      env->regs[R_ESI],
+                                                      env->regs[R_EDX],
+                                                      env->regs[R_ECX],
+                                                      env->regs[8],
+                                                      env->regs[9], 0, 0);
+            } else { /* if (bsd_type == target_openbsd) */
+                env->regs[R_EAX] = do_openbsd_syscall(env,
+                                                      env->regs[R_EAX],
+                                                      env->regs[R_EDI],
+                                                      env->regs[R_ESI],
+                                                      env->regs[R_EDX],
+                                                      env->regs[10],
+                                                      env->regs[8],
+                                                      env->regs[9]);
+            }
+            env->eip = env->exception_next_eip;
+            if (((abi_ulong)env->regs[R_EAX]) >= (abi_ulong)(-515)) {
+                env->regs[R_EAX] = -env->regs[R_EAX];
+                env->eflags |= CC_C;
+            } else {
+                env->eflags &= ~CC_C;
+            }
+            break;
+
+#if 0
+        case EXCP0B_NOSEG:
+        case EXCP0C_STACK:
+            info.si_signo = SIGBUS;
+            info.si_errno = 0;
+            info.si_code = TARGET_SI_KERNEL;
+            info._sifields._sigfault._addr = 0;
+            queue_signal(env, info.si_signo, &info);
+            break;
+
+        case EXCP0D_GPF:
+            /* XXX: potential problem if ABI32 */
+            info.si_signo = SIGSEGV;
+            info.si_errno = 0;
+            info.si_code = TARGET_SI_KERNEL;
+            info._sifields._sigfault._addr = 0;
+            queue_signal(env, info.si_signo, &info);
+            break;
+
+        case EXCP0E_PAGE:
+            info.si_signo = SIGSEGV;
+            info.si_errno = 0;
+            if (!(env->error_code & 1)) {
+                info.si_code = TARGET_SEGV_MAPERR;
+            } else {
+                info.si_code = TARGET_SEGV_ACCERR;
+            }
+            info._sifields._sigfault._addr = env->cr[2];
+            queue_signal(env, info.si_signo, &info);
+            break;
+
+        case EXCP00_DIVZ:
+            /* division by zero */
+            info.si_signo = SIGFPE;
+            info.si_errno = 0;
+            info.si_code = TARGET_FPE_INTDIV;
+            info._sifields._sigfault._addr = env->eip;
+            queue_signal(env, info.si_signo, &info);
+            break;
+
+        case EXCP01_DB:
+        case EXCP03_INT3:
+            info.si_signo = SIGTRAP;
+            info.si_errno = 0;
+            if (trapnr == EXCP01_DB) {
+                info.si_code = TARGET_TRAP_BRKPT;
+                info._sifields._sigfault._addr = env->eip;
+            } else {
+                info.si_code = TARGET_SI_KERNEL;
+                info._sifields._sigfault._addr = 0;
+            }
+            queue_signal(env, info.si_signo, &info);
+            break;
+
+        case EXCP04_INTO:
+        case EXCP05_BOUND:
+            info.si_signo = SIGSEGV;
+            info.si_errno = 0;
+            info.si_code = TARGET_SI_KERNEL;
+            info._sifields._sigfault._addr = 0;
+            queue_signal(env, info.si_signo, &info);
+            break;
+
+        case EXCP06_ILLOP:
+            info.si_signo = SIGILL;
+            info.si_errno = 0;
+            info.si_code = TARGET_ILL_ILLOPN;
+            info._sifields._sigfault._addr = env->eip;
+            queue_signal(env, info.si_signo, &info);
+            break;
+#endif
+        case EXCP_INTERRUPT:
+            /* just indicate that signals should be handled asap */
+            break;
+#if 0
+        case EXCP_DEBUG:
+            {
+                int sig;
+
+                sig = gdb_handlesig(env, TARGET_SIGTRAP);
+                if (sig) {
+                    info.si_signo = sig;
+                    info.si_errno = 0;
+                    info.si_code = TARGET_TRAP_BRKPT;
+                    queue_signal(env, info.si_signo, &info);
+                }
+            }
+            break;
+#endif
+        default:
+            pc = env->segs[R_CS].base + env->eip;
+            fprintf(stderr, "qemu: 0x%08lx: unhandled CPU exception 0x%x - "
+                    "aborting\n", (long)pc, trapnr);
+            abort();
+        }
+        process_pending_signals(env);
+    }
+}
+
+static inline void target_cpu_clone_regs(CPUX86State *env, target_ulong newsp)
+{
+    if (newsp)
+        env->regs[R_ESP] = newsp;
+    env->regs[R_EAX] = 0;
+}
+
+static inline void target_cpu_reset(CPUArchState *cpu)
+{
+    cpu_reset(ENV_GET_CPU(cpu));
+}
+
+#endif /* ! _TARGET_ARCH_CPU_H_ */
diff --git a/bsd-user/x86_64/target_arch_vmparam.h b/bsd-user/x86_64/target_arch_vmparam.h
new file mode 100644
index 0000000..ceb8af5
--- /dev/null
+++ b/bsd-user/x86_64/target_arch_vmparam.h
@@ -0,0 +1,28 @@
+#ifndef _TARGET_ARCH_VMPARAM_H_
+#define _TARGET_ARCH_VMPARAM_H_
+
+#include "cpu.h"
+
+/* compare to amd64/include/vmparam.h */
+#define TARGET_MAXTSIZ  (128UL*1024*1024)   /* max text size */
+#define TARGET_DFLDSIZ  (32768UL*1024*1024) /* initial data size limit */
+#define TARGET_MAXDSIZ  (32768UL*1024*1024) /* max data size */
+#define TARGET_DFLSSIZ  (8UL*1024*1024)     /* initial stack size limit */
+#define TARGET_MAXSSIZ  (512UL*1024*1024)   /* max stack size */
+#define TARGET_SGROWSIZ (128UL*1024)        /* amount to grow stack */
+
+#define TARGET_VM_MAXUSER_ADDRESS   (0x00007fffff000000UL)
+
+#define TARGET_USRSTACK (TARGET_VM_MAXUSER_ADDRESS - TARGET_PAGE_SIZE)
+
+static inline abi_ulong get_sp_from_cpustate(CPUX86State *state)
+{
+    return state->regs[R_ESP];
+}
+
+static inline void set_second_rval(CPUX86State *state, abi_ulong retval2)
+{
+    state->regs[R_EDX] = retval2;
+}
+
+#endif /* !_TARGET_ARCH_VMPARAM_H_ */
diff --git a/bsd-user/x86_64/target_signal.h b/bsd-user/x86_64/target_signal.h
index 659cd40..5491687 100644
--- a/bsd-user/x86_64/target_signal.h
+++ b/bsd-user/x86_64/target_signal.h
@@ -11,9 +11,4 @@ typedef struct target_sigaltstack {
 	abi_ulong ss_size;
 } target_stack_t;
 
-static inline abi_ulong get_sp_from_cpustate(CPUX86State *state)
-{
-    return state->regs[R_ESP];
-}
-
 #endif /* TARGET_SIGNAL_H */
-- 
2.0.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH 3/4] bsd-user: Rename linux_binprm to bsd_binprm
  2014-06-20  0:19 [Qemu-devel] [PATCH 0/4] bsd-user: Update Queue Sean Bruno
  2014-06-20  0:19 ` [Qemu-devel] [PATCH 1/4] bsd-user: Implement new syscall print_sysarch and add strace support Sean Bruno
  2014-06-20  0:19 ` [Qemu-devel] [PATCH 2/4] bsd-user: move arch/OS dependent code out of main.c Sean Bruno
@ 2014-06-20  0:19 ` Sean Bruno
  2014-07-03 13:23   ` Peter Maydell
  2014-06-20  0:19 ` [Qemu-devel] [PATCH 4/4] bsd-user: move arch/OS dependent code out of syscall.c Sean Bruno
  2014-06-21 16:39 ` [Qemu-devel] [PATCH 0/4] bsd-user: Update Queue Sean Bruno
  4 siblings, 1 reply; 11+ messages in thread
From: Sean Bruno @ 2014-06-20  0:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sean Bruno

These too similar data structures will be diverging in future updates
from my trees.  Rename now.

Signed-off-by: Sean Bruno <sbruno@freebsd.org>
---
 bsd-user/bsdload.c | 4 ++--
 bsd-user/elfload.c | 4 ++--
 bsd-user/main.c    | 2 +-
 bsd-user/qemu.h    | 8 ++++----
 4 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index 2abc713..e59b03d 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -53,7 +53,7 @@ static int count(char ** vec)
     return(i);
 }
 
-static int prepare_binprm(struct linux_binprm *bprm)
+static int prepare_binprm(struct bsd_binprm *bprm)
 {
     struct stat         st;
     int mode;
@@ -157,7 +157,7 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
 int loader_exec(const char * filename, char ** argv, char ** envp,
              struct target_pt_regs * regs, struct image_info *infop)
 {
-    struct linux_binprm bprm;
+    struct bsd_binprm bprm;
     int retval;
     int i;
 
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index ccf72d1..c2e2daa 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -665,7 +665,7 @@ static abi_ulong copy_elf_strings(int argc,char ** argv, void **page,
     return p;
 }
 
-static abi_ulong setup_arg_pages(abi_ulong p, struct linux_binprm *bprm,
+static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm,
                                  struct image_info *info)
 {
     abi_ulong stack_base, size, error;
@@ -1147,7 +1147,7 @@ static void load_symbols(struct elfhdr *hdr, int fd)
     syminfos = s;
 }
 
-int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
+int load_elf_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs,
                     struct image_info * info)
 {
     struct elfhdr elf_ex;
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 9c5711d..0ba5955 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -328,7 +328,7 @@ int main(int argc, char **argv)
     const char *log_mask = NULL;
     struct target_pt_regs regs1, *regs = &regs1;
     struct image_info info1, *info = &info1;
-    struct linux_binprm bprm;
+    struct bsd_binprm bprm;
     TaskState ts1, *ts = &ts1;
     CPUArchState *env;
     CPUState *cpu;
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 7521ebe..c70602e 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -91,7 +91,7 @@ typedef struct TaskState {
     struct TaskState *next;
     int used; /* non zero if used */
     struct image_info *info;
-    struct linux_binprm *bprm;
+    struct bsd_binprm *bprm;
 
     struct emulated_sigtable sigtab[TARGET_NSIG];
     struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
@@ -120,7 +120,7 @@ extern unsigned long mmap_min_addr;
  * This structure is used to hold the arguments that are
  * used when loading binaries.
  */
-struct linux_binprm {
+struct bsd_binprm {
         char buf[128];
         void *page[MAX_ARG_PAGES];
         abi_ulong p;
@@ -138,9 +138,9 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
 int loader_exec(const char * filename, char ** argv, char ** envp,
              struct target_pt_regs * regs, struct image_info *infop);
 
-int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
+int load_elf_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs,
                     struct image_info * info);
-int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
+int load_flt_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs,
                     struct image_info * info);
 
 abi_long memcpy_to_target(abi_ulong dest, const void *src,
-- 
2.0.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* [Qemu-devel] [PATCH 4/4] bsd-user: move arch/OS dependent code out of syscall.c
  2014-06-20  0:19 [Qemu-devel] [PATCH 0/4] bsd-user: Update Queue Sean Bruno
                   ` (2 preceding siblings ...)
  2014-06-20  0:19 ` [Qemu-devel] [PATCH 3/4] bsd-user: Rename linux_binprm to bsd_binprm Sean Bruno
@ 2014-06-20  0:19 ` Sean Bruno
  2014-07-03 13:55   ` Peter Maydell
  2014-06-21 16:39 ` [Qemu-devel] [PATCH 0/4] bsd-user: Update Queue Sean Bruno
  4 siblings, 1 reply; 11+ messages in thread
From: Sean Bruno @ 2014-06-20  0:19 UTC (permalink / raw)
  To: qemu-devel; +Cc: Sean Bruno

From: Stacey Son <sson@FreeBSD.org>

This change moves the system call handler for sysctl(2) and
sysarch(2) from syscall.c to the OS and arch dependent directories.
This eliminates many of the #ifdef's in syscall.c.  These system
call handlers are now located in the host os and target arch
directories.

Signed-off-by: Sean Bruno <sbruno@freebsd.org>
Signed-off-by: Stacey Son <sson@freebsd.org>
---
 bsd-user/Makefile.objs                  |   2 +-
 bsd-user/bsdload.c                      | 168 +++++++++++++------
 bsd-user/elfload.c                      |   7 +-
 bsd-user/freebsd/os-strace.h            |   6 -
 bsd-user/freebsd/os-sys.c               | 285 ++++++++++++++++++++++++++++++++
 bsd-user/freebsd/target_os_stack.h      | 157 ++++++++++++++++++
 bsd-user/i386/syscall.h                 |   2 +
 bsd-user/i386/target_arch_sigtramp.h    |  11 ++
 bsd-user/main.c                         |   2 +-
 bsd-user/netbsd/os-strace.h             |   8 -
 bsd-user/netbsd/os-sys.c                |  46 ++++++
 bsd-user/netbsd/target_os_stack.h       |  33 ++++
 bsd-user/openbsd/os-strace.h            |   8 -
 bsd-user/openbsd/os-sys.c               |  46 ++++++
 bsd-user/openbsd/target_os_stack.h      |  33 ++++
 bsd-user/qemu.h                         |  28 +++-
 bsd-user/sparc/syscall.h                |   2 +
 bsd-user/sparc/target_arch_sigtramp.h   |  11 ++
 bsd-user/sparc64/syscall.h              |   2 +
 bsd-user/sparc64/target_arch_sigtramp.h |  11 ++
 bsd-user/syscall.c                      | 151 ++++-------------
 bsd-user/x86_64/syscall.h               |   2 +
 bsd-user/x86_64/target_arch_sigtramp.h  |  11 ++
 23 files changed, 827 insertions(+), 205 deletions(-)
 create mode 100644 bsd-user/freebsd/os-sys.c
 create mode 100644 bsd-user/freebsd/target_os_stack.h
 create mode 100644 bsd-user/i386/target_arch_sigtramp.h
 create mode 100644 bsd-user/netbsd/os-sys.c
 create mode 100644 bsd-user/netbsd/target_os_stack.h
 create mode 100644 bsd-user/openbsd/os-sys.c
 create mode 100644 bsd-user/openbsd/target_os_stack.h
 create mode 100644 bsd-user/sparc/target_arch_sigtramp.h
 create mode 100644 bsd-user/sparc64/target_arch_sigtramp.h
 create mode 100644 bsd-user/x86_64/target_arch_sigtramp.h

diff --git a/bsd-user/Makefile.objs b/bsd-user/Makefile.objs
index 41e8dce..a4dca8e 100644
--- a/bsd-user/Makefile.objs
+++ b/bsd-user/Makefile.objs
@@ -1,2 +1,2 @@
 obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \
-	        uaccess.o $(TARGET_ABI_DIR)/target_arch_cpu.o
+	        uaccess.o $(HOST_VARIANT_DIR)/os-sys.o $(TARGET_ABI_DIR)/target_arch_cpu.o
diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c
index e59b03d..45fdcf8 100644
--- a/bsd-user/bsdload.c
+++ b/bsd-user/bsdload.c
@@ -1,4 +1,19 @@
-/* Code for loading BSD executables.  Mostly linux kernel code.  */
+/*
+ *  Load BSD executables.
+ *
+ *  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 <sys/types.h>
 #include <sys/stat.h>
@@ -26,27 +41,11 @@ abi_long memcpy_to_target(abi_ulong dest, const void *src,
     return 0;
 }
 
-static int in_group_p(gid_t g)
-{
-    /* return TRUE if we're in the specified group, FALSE otherwise */
-    int         ngroup;
-    int         i;
-    gid_t       grouplist[TARGET_NGROUPS];
-
-    ngroup = getgroups(TARGET_NGROUPS, grouplist);
-    for(i = 0; i < ngroup; i++) {
-        if(grouplist[i] == g) {
-            return 1;
-        }
-    }
-    return 0;
-}
-
 static int count(char ** vec)
 {
     int         i;
 
-    for(i = 0; *vec; i++) {
+    for (i = 0; *vec; i++) {
         vec++;
     }
 
@@ -57,7 +56,7 @@ static int prepare_binprm(struct bsd_binprm *bprm)
 {
     struct stat         st;
     int mode;
-    int retval, id_change;
+    int retval;
 
     if(fstat(bprm->fd, &st) < 0) {
         return(-errno);
@@ -73,14 +72,10 @@ static int prepare_binprm(struct bsd_binprm *bprm)
 
     bprm->e_uid = geteuid();
     bprm->e_gid = getegid();
-    id_change = 0;
 
     /* Set-uid? */
     if(mode & S_ISUID) {
         bprm->e_uid = st.st_uid;
-        if(bprm->e_uid != geteuid()) {
-            id_change = 1;
-        }
     }
 
     /* Set-gid? */
@@ -91,9 +86,6 @@ static int prepare_binprm(struct bsd_binprm *bprm)
      */
     if ((mode & (S_ISGID | S_IXGRP)) == (S_ISGID | S_IXGRP)) {
         bprm->e_gid = st.st_gid;
-        if (!in_group_p(bprm->e_gid)) {
-                id_change = 1;
-        }
     }
 
     memset(bprm->buf, 0, sizeof(bprm->buf));
@@ -154,34 +146,116 @@ abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
     return sp;
 }
 
+static int is_there(const char *candidate)
+{
+    struct stat fin;
+
+    /* XXX work around access(2) false positives for superuser */
+    if (access(candidate, X_OK) == 0 && stat(candidate, &fin) == 0 &&
+            S_ISREG(fin.st_mode) && (getuid() != 0 ||
+                (fin.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0)) {
+        return 1;
+    }
+
+    return 0;
+}
+
+static int find_in_path(char *path, const char *filename, char *retpath,
+        size_t rpsize)
+{
+    const char *d;
+    int found;
+
+    if (strchr(filename, '/') != NULL) {
+        if (is_there(filename)) {
+                if (!realpath(filename, retpath)) {
+                    return -1;
+                }
+                return 0;
+        } else {
+            return -1;
+        }
+    }
+
+    found = 0;
+    while ((d = strsep(&path, ":")) != NULL) {
+        if (*d == '\0') {
+            d = ".";
+        }
+        if (snprintf(retpath, rpsize, "%s/%s", d, filename) >= (int)rpsize) {
+            continue;
+        }
+        if (is_there((const char *)retpath)) {
+            found = 1;
+            break;
+        }
+    }
+    return found;
+}
+
 int loader_exec(const char * filename, char ** argv, char ** envp,
-             struct target_pt_regs * regs, struct image_info *infop)
+             struct target_pt_regs *regs, struct image_info *infop,
+             struct bsd_binprm *bprm)
 {
-    struct bsd_binprm bprm;
-    int retval;
-    int i;
+    char *p, *path = NULL, fullpath[PATH_MAX];
+    const char *execname = NULL;
+    int retval, i, found;
 
-    bprm.p = TARGET_PAGE_SIZE*MAX_ARG_PAGES-sizeof(unsigned int);
+    bprm->p = TARGET_PAGE_SIZE * MAX_ARG_PAGES; /* -sizeof(unsigned int); */
     for (i=0 ; i<MAX_ARG_PAGES ; i++)       /* clear page-table */
-            bprm.page[i] = NULL;
-    retval = open(filename, O_RDONLY);
-    if (retval < 0)
+            bprm->page[i] = NULL;
+
+    /* Find target executable in path, if not already an absolute path. */
+    p = getenv("PATH");
+    if (p != NULL) {
+        path = g_strdup(p);
+        if (path == NULL) {
+            fprintf(stderr, "Out of memory\n");
+            return -1;
+        }
+        execname = realpath(filename, NULL);
+        if (execname == NULL) {
+            execname = g_strdup(filename);
+        }
+        found = find_in_path(path, execname, fullpath, sizeof(fullpath));
+        /* Absolute path specified but not found? */
+        if (found == -1) {
+            return -1;
+        }
+        if (found) {
+            retval = open(fullpath, O_RDONLY);
+            bprm->fullpath = g_strdup(fullpath);
+        } else {
+            retval = open(execname, O_RDONLY);
+            bprm->fullpath = NULL;
+        }
+        if (execname) {
+            g_free((void *)execname);
+        }
+        g_free(path);
+    } else {
+        retval = open(filename, O_RDONLY);
+        bprm->fullpath = NULL;
+    }
+    if (retval < 0) {
         return retval;
-    bprm.fd = retval;
-    bprm.filename = (char *)filename;
-    bprm.argc = count(argv);
-    bprm.argv = argv;
-    bprm.envc = count(envp);
-    bprm.envp = envp;
+    }
+
+    bprm->fd = retval;
+    bprm->filename = (char *)filename;
+    bprm->argc = count(argv);
+    bprm->argv = argv;
+    bprm->envc = count(envp);
+    bprm->envp = envp;
 
-    retval = prepare_binprm(&bprm);
+    retval = prepare_binprm(bprm);
 
     if(retval>=0) {
-        if (bprm.buf[0] == 0x7f
-                && bprm.buf[1] == 'E'
-                && bprm.buf[2] == 'L'
-                && bprm.buf[3] == 'F') {
-            retval = load_elf_binary(&bprm,regs,infop);
+        if (bprm->buf[0] == 0x7f
+                && bprm->buf[1] == 'E'
+                && bprm->buf[2] == 'L'
+                && bprm->buf[3] == 'F') {
+            retval = load_elf_binary(bprm, regs, infop);
         } else {
             fprintf(stderr, "Unknown binary format\n");
             return -1;
@@ -196,7 +270,7 @@ int loader_exec(const char * filename, char ** argv, char ** envp,
 
     /* Something went wrong, return the inode and free the argument pages*/
     for (i=0 ; i<MAX_ARG_PAGES ; i++) {
-        g_free(bprm.page[i]);
+        g_free(bprm->page[i]);
     }
     return(retval);
 }
diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c
index c2e2daa..68d0209 100644
--- a/bsd-user/elfload.c
+++ b/bsd-user/elfload.c
@@ -91,6 +91,9 @@ enum {
 #define ELIBBAD 80
 #endif
 
+abi_ulong target_stksiz;
+abi_ulong target_stkbas;
+
 #ifdef TARGET_I386
 
 #define ELF_PLATFORM get_elf_platform()
@@ -1147,8 +1150,8 @@ static void load_symbols(struct elfhdr *hdr, int fd)
     syminfos = s;
 }
 
-int load_elf_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs,
-                    struct image_info * info)
+int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
+                    struct image_info *info)
 {
     struct elfhdr elf_ex;
     struct elfhdr interp_elf_ex;
diff --git a/bsd-user/freebsd/os-strace.h b/bsd-user/freebsd/os-strace.h
index c856450..a222f09 100644
--- a/bsd-user/freebsd/os-strace.h
+++ b/bsd-user/freebsd/os-strace.h
@@ -27,9 +27,3 @@ static inline void do_os_print_sysarch(const struct syscallname *name,
     /* This is arch dependent */
     do_freebsd_arch_print_sysarch(name, arg1, arg2, arg3, arg4, arg5, arg6);
 }
-
-/* sysarch() is architecture dependent. */
-abi_long do_bsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2)
-{
-    return do_freebsd_arch_sysarch(cpu_env, arg1, arg2);
-}
diff --git a/bsd-user/freebsd/os-sys.c b/bsd-user/freebsd/os-sys.c
new file mode 100644
index 0000000..24de6b5
--- /dev/null
+++ b/bsd-user/freebsd/os-sys.c
@@ -0,0 +1,285 @@
+/*
+ *  FreeBSD sysctl() and 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/>.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <string.h>
+
+#include "qemu.h"
+
+#include "target_arch_sysarch.h"
+#include "target_os_vmparam.h"
+
+/*
+ * XXX this uses the undocumented oidfmt interface to find the kind of
+ * a requested sysctl, see /sys/kern/kern_sysctl.c:sysctl_sysctl_oidfmt()
+ * (compare to src/sbin/sysctl/sysctl.c)
+ */
+static int
+oidfmt(int *oid, int len, char *fmt, uint32_t *kind)
+{
+    int qoid[CTL_MAXNAME+2];
+    uint8_t buf[BUFSIZ];
+    int i;
+    size_t j;
+
+    qoid[0] = 0;
+    qoid[1] = 4;
+    memcpy(qoid + 2, oid, len * sizeof(int));
+
+    j = sizeof(buf);
+    i = sysctl(qoid, len + 2, buf, &j, 0, 0);
+    if (i) {
+        return i;
+    }
+
+    if (kind) {
+        *kind = *(uint32_t *)buf;
+    }
+
+    if (fmt) {
+        strcpy(fmt, (char *)(buf + sizeof(uint32_t)));
+    }
+    return 0;
+}
+
+/*
+ * try and convert sysctl return data for the target.
+ * XXX doesn't handle CTLTYPE_OPAQUE and CTLTYPE_STRUCT.
+ */
+static int sysctl_oldcvt(void *holdp, size_t holdlen, uint32_t kind)
+{
+    switch (kind & CTLTYPE) {
+    case CTLTYPE_INT:
+    case CTLTYPE_UINT:
+        *(uint32_t *)holdp = tswap32(*(uint32_t *)holdp);
+        break;
+
+#ifdef TARGET_ABI32
+    case CTLTYPE_LONG:
+    case CTLTYPE_ULONG:
+        *(uint32_t *)holdp = tswap32(*(long *)holdp);
+        break;
+#else
+    case CTLTYPE_LONG:
+        *(uint64_t *)holdp = tswap64(*(long *)holdp);
+    case CTLTYPE_ULONG:
+        *(uint64_t *)holdp = tswap64(*(unsigned long *)holdp);
+        break;
+#endif
+#if !defined(__FreeBSD_version) || __FreeBSD_version < 900031
+    case CTLTYPE_QUAD:
+#else
+    case CTLTYPE_U64:
+    case CTLTYPE_S64:
+#endif
+        *(uint64_t *)holdp = tswap64(*(uint64_t *)holdp);
+        break;
+
+    case CTLTYPE_STRING:
+        break;
+
+    default:
+        /* XXX unhandled */
+        return -1;
+    }
+    return 0;
+}
+
+/*
+ * Convert the undocmented name2oid sysctl data for the target.
+ */
+static inline void sysctl_name2oid(uint32_t *holdp, size_t holdlen)
+{
+    size_t i;
+
+    for (i = 0; i < holdlen; i++) {
+        holdp[i] = tswap32(holdp[i]);
+    }
+}
+
+static inline void sysctl_oidfmt(uint32_t *holdp)
+{
+    /* byte swap the kind */
+    holdp[0] = tswap32(holdp[0]);
+}
+
+abi_long do_freebsd_sysctl(CPUArchState *env, abi_ulong namep, int32_t namelen,
+        abi_ulong oldp, abi_ulong oldlenp, abi_ulong newp, abi_ulong newlen)
+{
+    abi_long ret;
+    void *hnamep, *holdp = NULL, *hnewp = NULL;
+    size_t holdlen;
+    abi_ulong oldlen = 0;
+    int32_t *snamep = g_malloc(sizeof(int32_t) * namelen), *p, *q, i;
+    uint32_t kind = 0;
+    CPUState *cpu = ENV_GET_CPU(env);
+    TaskState *ts = (TaskState *)cpu->opaque;
+
+    if (oldlenp) {
+        if (get_user_ual(oldlen, oldlenp)) {
+            return -TARGET_EFAULT;
+        }
+    }
+    hnamep = lock_user(VERIFY_READ, namep, namelen, 1);
+    if (hnamep == NULL) {
+        return -TARGET_EFAULT;
+    }
+    if (newp) {
+        hnewp = lock_user(VERIFY_READ, newp, newlen, 1);
+        if (hnewp == NULL) {
+            return -TARGET_EFAULT;
+        }
+    }
+    if (oldp) {
+        holdp = lock_user(VERIFY_WRITE, oldp, oldlen, 0);
+        if (holdp == NULL) {
+            return -TARGET_EFAULT;
+        }
+    }
+    holdlen = oldlen;
+    for (p = hnamep, q = snamep, i = 0; i < namelen; p++, i++) {
+        *q++ = tswap32(*p);
+    }
+    oidfmt(snamep, namelen, NULL, &kind);
+
+    /* Handle some arch/emulator dependent sysctl()'s here. */
+    switch (snamep[0]) {
+    case CTL_KERN:
+        switch (snamep[1]) {
+        case KERN_USRSTACK:
+#if TARGET_USRSTACK != 0
+            (*(abi_ulong *)holdp) = tswapal(TARGET_USRSTACK);
+            holdlen = sizeof(abi_ulong);
+            ret = 0;
+#else
+            ret = -TARGET_ENOENT;
+#endif
+            goto out;
+
+        case KERN_PS_STRINGS:
+#if defined(TARGET_PS_STRINGS)
+            (*(abi_ulong *)holdp) = tswapal(TARGET_PS_STRINGS);
+            holdlen = sizeof(abi_ulong);
+            ret = 0;
+#else
+            ret = -TARGET_ENOENT;
+#endif
+            goto out;
+
+        case KERN_PROC:
+            switch (snamep[2]) {
+            case KERN_PROC_PATHNAME:
+                holdlen = strlen(ts->bprm->fullpath) + 1;
+                if (holdp) {
+                    if (oldlen < holdlen) {
+                        ret = -TARGET_EINVAL;
+                        goto out;
+                    }
+                    strlcpy(holdp, ts->bprm->fullpath, oldlen);
+                }
+                ret = 0;
+                goto out;
+
+            default:
+                break;
+            }
+            break;
+
+        default:
+            break;
+        }
+        break;
+
+    case CTL_HW:
+        switch (snamep[1]) {
+        case HW_MACHINE:
+            strlcpy(holdp, TARGET_HW_MACHINE, oldlen);
+            ret = 0;
+            goto out;
+
+        case HW_MACHINE_ARCH:
+            strlcpy(holdp, TARGET_HW_MACHINE_ARCH, oldlen);
+            ret = 0;
+            goto out;
+
+        case 851: /* hw.availpages */
+            {
+                long lvalue;
+                size_t len = sizeof(lvalue);
+
+                if (sysctlbyname("hw.availpages", &lvalue, &len, NULL, 0)
+                        == -1) {
+                    ret = -1;
+                } else {
+                    (*(abi_ulong *)holdp) = tswapal((abi_ulong)lvalue);
+                    holdlen = sizeof(abi_ulong);
+                    ret = 0;
+                }
+            }
+            goto out;
+
+        default:
+            break;
+        }
+    default:
+        break;
+    }
+
+    ret = get_errno(sysctl(snamep, namelen, holdp, &holdlen, hnewp, newlen));
+    if (!ret && (holdp != 0 && holdlen != 0)) {
+        if (0 == snamep[0] && (3 == snamep[1] || 4 == snamep[1])) {
+            if (3 == snamep[1]) {
+                /* Handle the undocumented name2oid special case. */
+                sysctl_name2oid(holdp, holdlen);
+            } else {
+                /* Handle oidfmt */
+                sysctl_oidfmt(holdp);
+            }
+        } else {
+            sysctl_oldcvt(holdp, holdlen, kind);
+        }
+    }
+#ifdef DEBUG
+    else {
+        printf("sysctl(mib[0]=%d, mib[1]=%d, mib[3]=%d...) returned %d\n",
+        snamep[0], snamep[1], snamep[2], (int)ret);
+    }
+#endif
+
+out:
+    if (oldlenp) {
+        put_user_ual(holdlen, oldlenp);
+    }
+    unlock_user(hnamep, namep, 0);
+    unlock_user(holdp, oldp, holdlen);
+    if (hnewp) {
+        unlock_user(hnewp, newp, 0);
+    }
+    g_free(snamep);
+    return ret;
+}
+
+/* sysarch() is architecture dependent. */
+abi_long do_freebsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2)
+{
+
+    return do_freebsd_arch_sysarch(cpu_env, arg1, arg2);
+}
diff --git a/bsd-user/freebsd/target_os_stack.h b/bsd-user/freebsd/target_os_stack.h
new file mode 100644
index 0000000..c84b69e
--- /dev/null
+++ b/bsd-user/freebsd/target_os_stack.h
@@ -0,0 +1,157 @@
+#ifndef _TARGET_OS_STACK_H_
+#define _TARGET_OS_STACK_H_
+
+#include <sys/param.h>
+#include "target_arch_sigtramp.h"
+
+/*
+ * The inital FreeBSD stack is as follows:
+ * (see kern/kern_exec.c exec_copyout_strings() )
+ *
+ *  Hi Address -> char **ps_argvstr  (struct ps_strings for ps, w, etc.)
+ *                unsigned ps_nargvstr
+ *                char **ps_envstr
+ *  PS_STRINGS -> unsigned ps_nenvstr
+ *
+ *                machine dependent sigcode (sv_sigcode of size
+ *                                           sv_szsigcode)
+ *
+ *                execpath          (absolute image path for rtld)
+ *
+ *                SSP Canary        (sizeof(long) * 8)
+ *
+ *                page sizes array  (usually sizeof(u_long) )
+ *
+ *  "destp" ->    argv, env strings (up to 262144 bytes)
+ */
+static inline int setup_initial_stack(struct bsd_binprm *bprm,
+        abi_ulong *ret_addr)
+{
+    int i;
+    abi_ulong stack_hi_addr;
+    size_t execpath_len, stringspace;
+    abi_ulong destp, argvp, envp, p;
+    struct target_ps_strings ps_strs;
+    char canary[sizeof(abi_long) * 8];
+
+    stack_hi_addr = p = target_stkbas + target_stksiz;
+
+    /* Save some space for ps_strings. */
+    p -= sizeof(struct target_ps_strings);
+
+#ifdef TARGET_SZSIGCODE
+    /* Add machine depedent sigcode. */
+    p -= TARGET_SZSIGCODE;
+    if (setup_sigtramp(p, (unsigned)offsetof(struct target_sigframe, sf_uc),
+            TARGET_FREEBSD_NR_sigreturn)) {
+        errno = EFAULT;
+        return -1;
+    }
+#endif
+    if (bprm->fullpath) {
+        execpath_len = strlen(bprm->fullpath) + 1;
+        p -= roundup(execpath_len, sizeof(abi_ulong));
+        if (memcpy_to_target(p, bprm->fullpath, execpath_len)) {
+            errno = EFAULT;
+            return -1;
+        }
+    }
+    /* Add canary for SSP. */
+    arc4random_buf(canary, sizeof(canary));
+    p -= roundup(sizeof(canary), sizeof(abi_ulong));
+    if (memcpy_to_target(p, canary, sizeof(canary))) {
+        errno = EFAULT;
+        return -1;
+    }
+    /* Add page sizes array. */
+    /* p -= sizeof(int); */
+    p -= sizeof(abi_ulong);
+    /* if (put_user_u32(TARGET_PAGE_SIZE, p)) { */
+    if (put_user_ual(TARGET_PAGE_SIZE, p)) {
+        errno = EFAULT;
+        return -1;
+    }
+    /* Calculate the string space needed */
+    stringspace = 0;
+    for (i = 0; i < bprm->argc; ++i) {
+        stringspace += strlen(bprm->argv[i]) + 1;
+    }
+    for (i = 0; i < bprm->envc; ++i) {
+        stringspace += strlen(bprm->envp[i]) + 1;
+    }
+    if (stringspace > TARGET_ARG_MAX) {
+       errno = ENOMEM;
+       return -1;
+    }
+
+    /* Make room for the argv and envp strings */
+    /* p = destp = roundup(p - TARGET_SPACE_USRSPACE - (TARGET_ARG_MAX - stringspace), sizeof(abi_ulong)); */
+    argvp = p - TARGET_SPACE_USRSPACE;
+    p = destp = roundup(p - TARGET_SPACE_USRSPACE - TARGET_ARG_MAX, sizeof(abi_ulong));
+
+    /*
+     * Add argv strings.  Note that the argv[] vectors are added by
+     * loader_build_argptr()
+     */
+    /* XXX need to make room for auxargs */
+    /* argvp = destp - ((bprm->argc + bprm->envc + 2) * sizeof(abi_ulong)); */
+    /* envp = argvp + (bprm->argc + 2) * sizeof(abi_ulong); */
+    envp = argvp + (bprm->argc + 1) * sizeof(abi_ulong);
+    ps_strs.ps_argvstr = tswapl(argvp);
+    ps_strs.ps_nargvstr = tswap32(bprm->argc);
+    for (i = 0; i < bprm->argc; ++i) {
+        size_t len = strlen(bprm->argv[i]) + 1;
+
+        if (memcpy_to_target(destp, bprm->argv[i], len)) {
+            errno = EFAULT;
+            return -1;
+        }
+        if (put_user_ual(destp, argvp)) {
+            errno = EFAULT;
+            return -1;
+        }
+        argvp += sizeof(abi_ulong);
+        destp += len;
+    }
+    if (put_user_ual(0, argvp)) {
+        errno = EFAULT;
+        return -1;
+    }
+    /*
+     * Add env strings. Note that the envp[] vectors are added by
+     * loader_build_argptr().
+     */
+    ps_strs.ps_envstr = tswapl(envp);
+    ps_strs.ps_nenvstr = tswap32(bprm->envc);
+    for (i = 0; i < bprm->envc; ++i) {
+        size_t len = strlen(bprm->envp[i]) + 1;
+
+        if (memcpy_to_target(destp, bprm->envp[i], len)) {
+            errno = EFAULT;
+            return -1;
+        }
+        if (put_user_ual(destp, envp)) {
+            errno = EFAULT;
+            return -1;
+        }
+        envp += sizeof(abi_ulong);
+        destp += len;
+    }
+    if (put_user_ual(0, envp)) {
+        errno = EFAULT;
+        return -1;
+    }
+    if (memcpy_to_target(stack_hi_addr - sizeof(ps_strs), &ps_strs,
+                sizeof(ps_strs))) {
+        errno = EFAULT;
+        return -1;
+    }
+
+    if (ret_addr) {
+       *ret_addr = p;
+    }
+
+    return 0;
+ }
+
+#endif /* !_TARGET_OS_STACK_H_ */
diff --git a/bsd-user/i386/syscall.h b/bsd-user/i386/syscall.h
index 8028fc8..52de302 100644
--- a/bsd-user/i386/syscall.h
+++ b/bsd-user/i386/syscall.h
@@ -178,5 +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_sigtramp.h b/bsd-user/i386/target_arch_sigtramp.h
new file mode 100644
index 0000000..f0f36d1
--- /dev/null
+++ b/bsd-user/i386/target_arch_sigtramp.h
@@ -0,0 +1,11 @@
+
+#ifndef _TARGET_ARCH_SIGTRAMP_H_
+#define _TARGET_ARCH_SIGTRAMP_H_
+
+static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc,
+        unsigned sys_sigreturn)
+{
+
+    return -TARGET_EOPNOTSUPP;
+}
+#endif /* _TARGET_ARCH_SIGTRAMP_H_ */
diff --git a/bsd-user/main.c b/bsd-user/main.c
index 0ba5955..e11f524 100644
--- a/bsd-user/main.c
+++ b/bsd-user/main.c
@@ -541,7 +541,7 @@ int main(int argc, char **argv)
     }
 #endif /* CONFIG_USE_GUEST_BASE */
 
-    if (loader_exec(filename, argv+optind, target_environ, regs, info)) {
+    if (loader_exec(filename, argv+optind, target_environ, regs, info, &bprm)) {
         printf("Error loading %s\n", filename);
         _exit(1);
     }
diff --git a/bsd-user/netbsd/os-strace.h b/bsd-user/netbsd/os-strace.h
index ead15db..442af7f 100644
--- a/bsd-user/netbsd/os-strace.h
+++ b/bsd-user/netbsd/os-strace.h
@@ -27,11 +27,3 @@ static inline void do_os_print_sysarch(const struct syscallname *name,
     qemu_log("qemu: Unsupported syscall %s\n", __func__);
     return;
 }
-
-/* sysarch() is architecture dependent. */
-abi_long do_bsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2)
-{
-    qemu_log("qemu: Unsupported syscall sysarch()\n");
-    return -TARGET_ENOSYS;
-}
-
diff --git a/bsd-user/netbsd/os-sys.c b/bsd-user/netbsd/os-sys.c
new file mode 100644
index 0000000..68ea0e1
--- /dev/null
+++ b/bsd-user/netbsd/os-sys.c
@@ -0,0 +1,46 @@
+/*
+ *  NetBSD sysctl() and sysarch() system call 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/>.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <string.h>
+
+#include "qemu.h"
+
+#include "target_arch_sysarch.h"
+#include "target_os_vmparam.h"
+
+
+/* This must be emulated to support FreeBSD target binaries on NetBSD host. */
+
+abi_long do_freebsd_sysctl(CPUArchState *env, abi_ulong namep, int32_t namelen,
+        abi_ulong oldp, abi_ulong oldlenp, abi_ulong newp, abi_ulong newlen)
+{
+
+    qemu_log("qemu: Unsupported syscall __sysctl()\n");
+    return -TARGET_ENOSYS;
+}
+
+/* sysarch() is architecture dependent. */
+abi_long do_freebsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall sysarch()\n");
+    return -TARGET_ENOSYS;
+}
diff --git a/bsd-user/netbsd/target_os_stack.h b/bsd-user/netbsd/target_os_stack.h
new file mode 100644
index 0000000..1a26c3f
--- /dev/null
+++ b/bsd-user/netbsd/target_os_stack.h
@@ -0,0 +1,33 @@
+#ifndef _TARGET_OS_STACK_H_
+#define _TARGET_OS_STACK_H_
+
+#include "target_arch_sigtramp.h"
+
+static inline int setup_initial_stack(struct bsd_binprm *bprm, abi_ulong *p)
+{
+    int i;
+    abi_ulong stack_base;
+
+    stack_base = (target_stkbas + target_stksiz) -
+                  MAX_ARG_PAGES * TARGET_PAGE_SIZE;
+    if (p) {
+        *p = stack_base;
+    }
+
+    for (i = 0; i < MAX_ARG_PAGES; i++) {
+        if (bprm->page[i]) {
+            info->rss++;
+            if (!memcpy_to_target(stack_base, bprm->page[i],
+                        TARGET_PAGE_SIZE)) {
+                errno = EFAULT;
+                return -1;
+            }
+            g_free(bprm->page[i]);
+        }
+        stack_base += TARGET_PAGE_SIZE;
+    }
+
+    return 0;
+}
+
+#endif /* !_TARGET_OS_STACK_H_ */
diff --git a/bsd-user/openbsd/os-strace.h b/bsd-user/openbsd/os-strace.h
index 88907b4..d8dc83b 100644
--- a/bsd-user/openbsd/os-strace.h
+++ b/bsd-user/openbsd/os-strace.h
@@ -27,11 +27,3 @@ static inline void do_os_print_sysarch(const struct syscallname *name,
     qemu_log("qemu: Unsupported syscall %s\n", __func__);
     return;
 }
-
-/* sysarch() is architecture dependent. */
-abi_long do_bsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2)
-{
-
-    qemu_log("qemu: Unsupported syscall sysarch()\n");
-    return -TARGET_ENOSYS;
-}
diff --git a/bsd-user/openbsd/os-sys.c b/bsd-user/openbsd/os-sys.c
new file mode 100644
index 0000000..30df472
--- /dev/null
+++ b/bsd-user/openbsd/os-sys.c
@@ -0,0 +1,46 @@
+/*
+ *  OpenBSD sysctl() and sysarch() system call 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/>.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <string.h>
+
+#include "qemu.h"
+
+#include "target_arch_sysarch.h"
+#include "target_os_vmparam.h"
+
+
+/* This must be emulated to support FreeBSD target binaries on NetBSD host. */
+
+abi_long do_freebsd_sysctl(CPUArchState *env, abi_ulong namep, int32_t namelen,
+        abi_ulong oldp, abi_ulong oldlenp, abi_ulong newp, abi_ulong newlen)
+{
+
+    qemu_log("qemu: Unsupported syscall __sysctl()\n");
+    return -TARGET_ENOSYS;
+}
+
+/* sysarch() is architecture dependent. */
+abi_long do_freebsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2)
+{
+
+    qemu_log("qemu: Unsupported syscall sysarch()\n");
+    return -TARGET_ENOSYS;
+}
diff --git a/bsd-user/openbsd/target_os_stack.h b/bsd-user/openbsd/target_os_stack.h
new file mode 100644
index 0000000..1a26c3f
--- /dev/null
+++ b/bsd-user/openbsd/target_os_stack.h
@@ -0,0 +1,33 @@
+#ifndef _TARGET_OS_STACK_H_
+#define _TARGET_OS_STACK_H_
+
+#include "target_arch_sigtramp.h"
+
+static inline int setup_initial_stack(struct bsd_binprm *bprm, abi_ulong *p)
+{
+    int i;
+    abi_ulong stack_base;
+
+    stack_base = (target_stkbas + target_stksiz) -
+                  MAX_ARG_PAGES * TARGET_PAGE_SIZE;
+    if (p) {
+        *p = stack_base;
+    }
+
+    for (i = 0; i < MAX_ARG_PAGES; i++) {
+        if (bprm->page[i]) {
+            info->rss++;
+            if (!memcpy_to_target(stack_base, bprm->page[i],
+                        TARGET_PAGE_SIZE)) {
+                errno = EFAULT;
+                return -1;
+            }
+            g_free(bprm->page[i]);
+        }
+        stack_base += TARGET_PAGE_SIZE;
+    }
+
+    return 0;
+}
+
+#endif /* !_TARGET_OS_STACK_H_ */
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index c70602e..eda6f29 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -129,19 +129,23 @@ struct bsd_binprm {
         int argc, envc;
         char **argv;
         char **envp;
-        char * filename;        /* Name of binary */
+        char *filename;         /* (Given) Name of binary */
+        char *fullpath;         /* Full path of binary */
+        int (*core_dump)(int, const CPUArchState *);
 };
 
 void do_init_thread(struct target_pt_regs *regs, struct image_info *infop);
 abi_ulong loader_build_argptr(int envc, int argc, abi_ulong sp,
                               abi_ulong stringp, int push_ptr);
-int loader_exec(const char * filename, char ** argv, char ** envp,
-             struct target_pt_regs * regs, struct image_info *infop);
+int loader_exec(const char *filename, char **argv, char **envp,
+             struct target_pt_regs *regs, struct image_info *infop,
+             struct bsd_binprm *bprm);
 
-int load_elf_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs,
-                    struct image_info * info);
-int load_flt_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs,
-                    struct image_info * info);
+int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
+                    struct image_info *info);
+int load_flt_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs,
+                    struct image_info *info);
+int is_target_elf_binary(int fd);
 
 abi_long memcpy_to_target(abi_ulong dest, const void *src,
                           unsigned long len);
@@ -238,8 +242,14 @@ void end_exclusive(void);
 void cpu_exec_start(CPUState *cpu);
 void cpu_exec_end(CPUState *cpu);
 
-/* os-strace.h */
-abi_long do_bsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2);
+/* syscall.c */
+abi_long get_errno(abi_long ret);
+int is_error(abi_long ret);
+
+/* os-sys.c */
+abi_long do_freebsd_sysctl(CPUArchState *env, abi_ulong namep, int32_t namelen,
+        abi_ulong oldp, abi_ulong oldlenp, abi_ulong newp, abi_ulong newlen);
+abi_long do_freebsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2);
 
 /* user access */
 
diff --git a/bsd-user/sparc/syscall.h b/bsd-user/sparc/syscall.h
index 7ed2152..3a5b1e2 100644
--- a/bsd-user/sparc/syscall.h
+++ b/bsd-user/sparc/syscall.h
@@ -27,6 +27,8 @@ struct target_pt_regs {
 };
 
 #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
diff --git a/bsd-user/sparc/target_arch_sigtramp.h b/bsd-user/sparc/target_arch_sigtramp.h
new file mode 100644
index 0000000..f0f36d1
--- /dev/null
+++ b/bsd-user/sparc/target_arch_sigtramp.h
@@ -0,0 +1,11 @@
+
+#ifndef _TARGET_ARCH_SIGTRAMP_H_
+#define _TARGET_ARCH_SIGTRAMP_H_
+
+static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc,
+        unsigned sys_sigreturn)
+{
+
+    return -TARGET_EOPNOTSUPP;
+}
+#endif /* _TARGET_ARCH_SIGTRAMP_H_ */
diff --git a/bsd-user/sparc64/syscall.h b/bsd-user/sparc64/syscall.h
index 8571092..58cc38d 100644
--- a/bsd-user/sparc64/syscall.h
+++ b/bsd-user/sparc64/syscall.h
@@ -27,6 +27,8 @@ struct target_pt_regs {
 };
 
 #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
diff --git a/bsd-user/sparc64/target_arch_sigtramp.h b/bsd-user/sparc64/target_arch_sigtramp.h
new file mode 100644
index 0000000..f0f36d1
--- /dev/null
+++ b/bsd-user/sparc64/target_arch_sigtramp.h
@@ -0,0 +1,11 @@
+
+#ifndef _TARGET_ARCH_SIGTRAMP_H_
+#define _TARGET_ARCH_SIGTRAMP_H_
+
+static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc,
+        unsigned sys_sigreturn)
+{
+
+    return -TARGET_EOPNOTSUPP;
+}
+#endif /* _TARGET_ARCH_SIGTRAMP_H_ */
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index b3efc3c..dbc212d 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -2,6 +2,7 @@
  *  BSD syscalls
  *
  *  Copyright (c) 2003 - 2008 Fabrice Bellard
+ *  Copyright (c) 2013 Stacey D. Son
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -36,12 +37,17 @@
 #include "qemu.h"
 #include "qemu-common.h"
 
-//#define DEBUG
+#define target_to_host_bitmask(x, tbl) (x)
+
+/* #define DEBUG */
 
 static abi_ulong target_brk;
 static abi_ulong target_original_brk;
 
-static inline abi_long get_errno(abi_long ret)
+/*
+ * errno conversion.
+ */
+abi_long get_errno(abi_long ret)
 {
     if (ret == -1)
         /* XXX need to translate host -> target errnos here */
@@ -50,9 +56,7 @@ static inline abi_long get_errno(abi_long ret)
         return ret;
 }
 
-#define target_to_host_bitmask(x, tbl) (x)
-
-static inline int is_error(abi_long ret)
+int is_error(abi_long ret)
 {
     return (abi_ulong)ret >= (abi_ulong)(-4096);
 }
@@ -96,114 +100,6 @@ static abi_long do_obreak(abi_ulong new_brk)
     return 0;
 }
 
-#ifdef __FreeBSD__
-/*
- * XXX this uses the undocumented oidfmt interface to find the kind of
- * a requested sysctl, see /sys/kern/kern_sysctl.c:sysctl_sysctl_oidfmt()
- * (this is mostly copied from src/sbin/sysctl/sysctl.c)
- */
-static int
-oidfmt(int *oid, int len, char *fmt, uint32_t *kind)
-{
-    int qoid[CTL_MAXNAME+2];
-    uint8_t buf[BUFSIZ];
-    int i;
-    size_t j;
-
-    qoid[0] = 0;
-    qoid[1] = 4;
-    memcpy(qoid + 2, oid, len * sizeof(int));
-
-    j = sizeof(buf);
-    i = sysctl(qoid, len + 2, buf, &j, 0, 0);
-    if (i)
-        return i;
-
-    if (kind)
-        *kind = *(uint32_t *)buf;
-
-    if (fmt)
-        strcpy(fmt, (char *)(buf + sizeof(uint32_t)));
-    return (0);
-}
-
-/*
- * try and convert sysctl return data for the target.
- * XXX doesn't handle CTLTYPE_OPAQUE and CTLTYPE_STRUCT.
- */
-static int sysctl_oldcvt(void *holdp, size_t holdlen, uint32_t kind)
-{
-    switch (kind & CTLTYPE) {
-    case CTLTYPE_INT:
-    case CTLTYPE_UINT:
-        *(uint32_t *)holdp = tswap32(*(uint32_t *)holdp);
-        break;
-#ifdef TARGET_ABI32
-    case CTLTYPE_LONG:
-    case CTLTYPE_ULONG:
-        *(uint32_t *)holdp = tswap32(*(long *)holdp);
-        break;
-#else
-    case CTLTYPE_LONG:
-        *(uint64_t *)holdp = tswap64(*(long *)holdp);
-    case CTLTYPE_ULONG:
-        *(uint64_t *)holdp = tswap64(*(unsigned long *)holdp);
-        break;
-#endif
-#ifdef CTLTYPE_U64
-    case CTLTYPE_S64:
-    case CTLTYPE_U64:
-#else
-    case CTLTYPE_QUAD:
-#endif
-        *(uint64_t *)holdp = tswap64(*(uint64_t *)holdp);
-        break;
-    case CTLTYPE_STRING:
-        break;
-    default:
-        /* XXX unhandled */
-        return -1;
-    }
-    return 0;
-}
-
-/* XXX this needs to be emulated on non-FreeBSD hosts... */
-static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong oldp,
-                          abi_ulong oldlenp, abi_ulong newp, abi_ulong newlen)
-{
-    abi_long ret;
-    void *hnamep, *holdp, *hnewp = NULL;
-    size_t holdlen;
-    abi_ulong oldlen = 0;
-    int32_t *snamep = g_malloc(sizeof(int32_t) * namelen), *p, *q, i;
-    uint32_t kind = 0;
-
-    if (oldlenp)
-        get_user_ual(oldlen, oldlenp);
-    if (!(hnamep = lock_user(VERIFY_READ, namep, namelen, 1)))
-        return -TARGET_EFAULT;
-    if (newp && !(hnewp = lock_user(VERIFY_READ, newp, newlen, 1)))
-        return -TARGET_EFAULT;
-    if (!(holdp = lock_user(VERIFY_WRITE, oldp, oldlen, 0)))
-        return -TARGET_EFAULT;
-    holdlen = oldlen;
-    for (p = hnamep, q = snamep, i = 0; i < namelen; p++, i++)
-       *q++ = tswap32(*p);
-    oidfmt(snamep, namelen, NULL, &kind);
-    /* XXX swap hnewp */
-    ret = get_errno(sysctl(snamep, namelen, holdp, &holdlen, hnewp, newlen));
-    if (!ret)
-        sysctl_oldcvt(holdp, holdlen, kind);
-    put_user_ual(holdlen, oldlenp);
-    unlock_user(hnamep, namep, 0);
-    unlock_user(holdp, oldp, holdlen);
-    if (hnewp)
-        unlock_user(hnewp, newp, 0);
-    g_free(snamep);
-    return ret;
-}
-#endif
-
 /* FIXME
  * lock_iovec()/unlock_iovec() have a return code of 0 for success where
  * other lock functions have a return code of 0 for failure.
@@ -326,20 +222,27 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_FREEBSD_NR_break:
         ret = do_obreak(arg1);
         break;
-#ifdef __FreeBSD__
-    case TARGET_FREEBSD_NR___sysctl:
-        ret = do_freebsd_sysctl(arg1, arg2, arg3, arg4, arg5, arg6);
+
+        /*
+         * sys{ctl, arch, call}
+         */
+    case TARGET_FREEBSD_NR___sysctl: /* sysctl(3) */
+        ret = do_freebsd_sysctl(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6);
         break;
-#endif
-    case TARGET_FREEBSD_NR_sysarch:
-        ret = do_bsd_sysarch(cpu_env, arg1, arg2);
+
+    case TARGET_FREEBSD_NR_sysarch: /* sysarch(2) */
+        ret = do_freebsd_sysarch(cpu_env, arg1, arg2);
         break;
-    case TARGET_FREEBSD_NR_syscall:
-    case TARGET_FREEBSD_NR___syscall:
-        ret = do_freebsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,arg7,arg8,0);
+
+    case TARGET_FREEBSD_NR_syscall: /* syscall(2) */
+    case TARGET_FREEBSD_NR___syscall: /* __syscall(2) */
+        ret = do_freebsd_syscall(cpu_env, arg1 & 0xffff, arg2, arg3, arg4,
+                arg5, arg6, arg7, arg8, 0);
         break;
+
     default:
-        ret = get_errno(syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8));
+        ret = get_errno(syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7,
+                    arg8));
         break;
     }
  fail:
@@ -406,6 +309,7 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_NETBSD_NR_mprotect:
         ret = get_errno(target_mprotect(arg1, arg2, arg3));
         break;
+
     case TARGET_NETBSD_NR_syscall:
     case TARGET_NETBSD_NR___syscall:
         ret = do_netbsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
@@ -478,6 +382,7 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
     case TARGET_OPENBSD_NR_mprotect:
         ret = get_errno(target_mprotect(arg1, arg2, arg3));
         break;
+
     case TARGET_OPENBSD_NR_syscall:
     case TARGET_OPENBSD_NR___syscall:
         ret = do_openbsd_syscall(cpu_env,arg1 & 0xffff,arg2,arg3,arg4,arg5,arg6,0);
diff --git a/bsd-user/x86_64/syscall.h b/bsd-user/x86_64/syscall.h
index 4e77235..4fff6a5 100644
--- a/bsd-user/x86_64/syscall.h
+++ b/bsd-user/x86_64/syscall.h
@@ -129,6 +129,8 @@ struct target_msqid64_ds {
 
 
 #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
diff --git a/bsd-user/x86_64/target_arch_sigtramp.h b/bsd-user/x86_64/target_arch_sigtramp.h
new file mode 100644
index 0000000..f0f36d1
--- /dev/null
+++ b/bsd-user/x86_64/target_arch_sigtramp.h
@@ -0,0 +1,11 @@
+
+#ifndef _TARGET_ARCH_SIGTRAMP_H_
+#define _TARGET_ARCH_SIGTRAMP_H_
+
+static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc,
+        unsigned sys_sigreturn)
+{
+
+    return -TARGET_EOPNOTSUPP;
+}
+#endif /* _TARGET_ARCH_SIGTRAMP_H_ */
-- 
2.0.0

^ permalink raw reply related	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] bsd-user:  Update Queue
  2014-06-20  0:19 [Qemu-devel] [PATCH 0/4] bsd-user: Update Queue Sean Bruno
                   ` (3 preceding siblings ...)
  2014-06-20  0:19 ` [Qemu-devel] [PATCH 4/4] bsd-user: move arch/OS dependent code out of syscall.c Sean Bruno
@ 2014-06-21 16:39 ` Sean Bruno
  2014-06-23 14:20   ` Sean Bruno
  4 siblings, 1 reply; 11+ messages in thread
From: Sean Bruno @ 2014-06-21 16:39 UTC (permalink / raw)
  To: qemu-devel

On Thu, 2014-06-19 at 17:19 -0700, Sean Bruno wrote:
> This patchset brings us a couple of steps closer to the FreeBSD Development
> tree, Stacey Son's bsd-user branch and qemu-devel port maintained out of tree.
> 
> These patches are designed to begin to break apart the architectures
> in bsd-user for the upcoming new arch support patches.
> 
> Patch 1/4 of this set is a reset of Patch 5/10 from the last bsd-user
> update push.  It addresses Peter Maydell's commentary about missing and
> redundant code for print_sysarch and the build breakage for netbsd and
> openbsd bsd-user programs.
> 
> Patch 4/4 of this set includes Patch 10/10 from the last bsd-user update
> push.  It includes the code that uses the #define vaules as to avoid the
> possibility of commiting dead code.
> 
> Sean Bruno (2):
>   bsd-user: Implement new syscall print_sysarch and add strace support
>   bsd-user:  Rename struct linux_binprm to struct bsd_binprm
> 
> Stacey Son (2):
>   bsd-user: move arch/OS dependent code out of main.c
>   bsd-user: move arch/OS dependent code out of syscall.c
> 
>  bsd-user/Makefile.objs                  |   2 +-
>  bsd-user/bsdload.c                      | 170 ++++--
>  bsd-user/elfload.c                      |  11 +-
>  bsd-user/freebsd/host_os.h              |  46 ++
>  bsd-user/freebsd/os-strace.h            |  29 +
>  bsd-user/freebsd/os-sys.c               | 285 ++++++++++
>  bsd-user/freebsd/strace.list            |   2 +-
>  bsd-user/freebsd/target_os_stack.h      | 157 ++++++
>  bsd-user/freebsd/target_os_vmparam.h    |  23 +
>  bsd-user/i386/syscall.h                 |  23 +
>  bsd-user/i386/target_arch.h             |  13 +
>  bsd-user/i386/target_arch_cpu.c         |  79 +++
>  bsd-user/i386/target_arch_cpu.h         | 300 +++++++++++
>  bsd-user/i386/target_arch_sigtramp.h    |  11 +
>  bsd-user/i386/target_arch_sysarch.h     |  78 +++
>  bsd-user/i386/target_arch_vmparam.h     |  28 +
>  bsd-user/i386/target_signal.h           |   6 -
>  bsd-user/main.c                         | 927 +++++++-------------------------
>  bsd-user/mmap.c                         |   2 +-
>  bsd-user/netbsd/host_os.h               |  31 ++
>  bsd-user/netbsd/os-strace.h             |  29 +
>  bsd-user/netbsd/os-sys.c                |  46 ++
>  bsd-user/netbsd/target_os_stack.h       |  33 ++
>  bsd-user/netbsd/target_os_vmparam.h     |  23 +
>  bsd-user/openbsd/host_os.h              |  31 ++
>  bsd-user/openbsd/os-strace.h            |  29 +
>  bsd-user/openbsd/os-sys.c               |  46 ++
>  bsd-user/openbsd/target_os_stack.h      |  33 ++
>  bsd-user/openbsd/target_os_vmparam.h    |  23 +
>  bsd-user/qemu.h                         |  50 +-
>  bsd-user/sparc/syscall.h                |  29 +-
>  bsd-user/sparc/target_arch.h            |  11 +
>  bsd-user/sparc/target_arch_cpu.c        | 113 ++++
>  bsd-user/sparc/target_arch_cpu.h        | 158 ++++++
>  bsd-user/sparc/target_arch_sigtramp.h   |  11 +
>  bsd-user/sparc/target_arch_sysarch.h    |  52 ++
>  bsd-user/sparc/target_arch_vmparam.h    |  37 ++
>  bsd-user/sparc/target_signal.h          |   5 -
>  bsd-user/sparc64/syscall.h              |  28 +-
>  bsd-user/sparc64/target_arch.h          |  11 +
>  bsd-user/sparc64/target_arch_cpu.c      | 118 ++++
>  bsd-user/sparc64/target_arch_cpu.h      | 191 +++++++
>  bsd-user/sparc64/target_arch_sigtramp.h |  11 +
>  bsd-user/sparc64/target_arch_sysarch.h  |  52 ++
>  bsd-user/sparc64/target_arch_vmparam.h  |  37 ++
>  bsd-user/sparc64/target_signal.h        |   5 -
>  bsd-user/strace.c                       |  10 +
>  bsd-user/syscall.c                      | 210 +-------
>  bsd-user/x86_64/syscall.h               |  26 +-
>  bsd-user/x86_64/target_arch.h           |  13 +
>  bsd-user/x86_64/target_arch_cpu.c       |  79 +++
>  bsd-user/x86_64/target_arch_cpu.h       | 322 +++++++++++
>  bsd-user/x86_64/target_arch_sigtramp.h  |  11 +
>  bsd-user/x86_64/target_arch_sysarch.h   |  76 +++
>  bsd-user/x86_64/target_arch_vmparam.h   |  28 +
>  bsd-user/x86_64/target_signal.h         |   5 -
>  56 files changed, 3207 insertions(+), 1008 deletions(-)
>  create mode 100644 bsd-user/freebsd/host_os.h
>  create mode 100644 bsd-user/freebsd/os-strace.h
>  create mode 100644 bsd-user/freebsd/os-sys.c
>  create mode 100644 bsd-user/freebsd/target_os_stack.h
>  create mode 100644 bsd-user/freebsd/target_os_vmparam.h
>  create mode 100644 bsd-user/i386/target_arch.h
>  create mode 100644 bsd-user/i386/target_arch_cpu.c
>  create mode 100644 bsd-user/i386/target_arch_cpu.h
>  create mode 100644 bsd-user/i386/target_arch_sigtramp.h
>  create mode 100644 bsd-user/i386/target_arch_sysarch.h
>  create mode 100644 bsd-user/i386/target_arch_vmparam.h
>  create mode 100644 bsd-user/netbsd/host_os.h
>  create mode 100644 bsd-user/netbsd/os-strace.h
>  create mode 100644 bsd-user/netbsd/os-sys.c
>  create mode 100644 bsd-user/netbsd/target_os_stack.h
>  create mode 100644 bsd-user/netbsd/target_os_vmparam.h
>  create mode 100644 bsd-user/openbsd/host_os.h
>  create mode 100644 bsd-user/openbsd/os-strace.h
>  create mode 100644 bsd-user/openbsd/os-sys.c
>  create mode 100644 bsd-user/openbsd/target_os_stack.h
>  create mode 100644 bsd-user/openbsd/target_os_vmparam.h
>  create mode 100644 bsd-user/sparc/target_arch.h
>  create mode 100644 bsd-user/sparc/target_arch_cpu.c
>  create mode 100644 bsd-user/sparc/target_arch_cpu.h
>  create mode 100644 bsd-user/sparc/target_arch_sigtramp.h
>  create mode 100644 bsd-user/sparc/target_arch_sysarch.h
>  create mode 100644 bsd-user/sparc/target_arch_vmparam.h
>  create mode 100644 bsd-user/sparc64/target_arch.h
>  create mode 100644 bsd-user/sparc64/target_arch_cpu.c
>  create mode 100644 bsd-user/sparc64/target_arch_cpu.h
>  create mode 100644 bsd-user/sparc64/target_arch_sigtramp.h
>  create mode 100644 bsd-user/sparc64/target_arch_sysarch.h
>  create mode 100644 bsd-user/sparc64/target_arch_vmparam.h
>  create mode 100644 bsd-user/x86_64/target_arch.h
>  create mode 100644 bsd-user/x86_64/target_arch_cpu.c
>  create mode 100644 bsd-user/x86_64/target_arch_cpu.h
>  create mode 100644 bsd-user/x86_64/target_arch_sigtramp.h
>  create mode 100644 bsd-user/x86_64/target_arch_sysarch.h
>  create mode 100644 bsd-user/x86_64/target_arch_vmparam.h
> 

ping and happy weekend!

sean

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH 0/4] bsd-user:  Update Queue
  2014-06-21 16:39 ` [Qemu-devel] [PATCH 0/4] bsd-user: Update Queue Sean Bruno
@ 2014-06-23 14:20   ` Sean Bruno
  0 siblings, 0 replies; 11+ messages in thread
From: Sean Bruno @ 2014-06-23 14:20 UTC (permalink / raw)
  To: qemu-devel

On Sat, 2014-06-21 at 09:39 -0700, Sean Bruno wrote:
> On Thu, 2014-06-19 at 17:19 -0700, Sean Bruno wrote:
> > This patchset brings us a couple of steps closer to the FreeBSD Development
> > tree, Stacey Son's bsd-user branch and qemu-devel port maintained out of tree.
> > 
> > These patches are designed to begin to break apart the architectures
> > in bsd-user for the upcoming new arch support patches.
> > 
> > Patch 1/4 of this set is a reset of Patch 5/10 from the last bsd-user
> > update push.  It addresses Peter Maydell's commentary about missing and
> > redundant code for print_sysarch and the build breakage for netbsd and
> > openbsd bsd-user programs.
> > 
> > Patch 4/4 of this set includes Patch 10/10 from the last bsd-user update
> > push.  It includes the code that uses the #define vaules as to avoid the
> > possibility of commiting dead code.
> > 
> > Sean Bruno (2):
> >   bsd-user: Implement new syscall print_sysarch and add strace support
> >   bsd-user:  Rename struct linux_binprm to struct bsd_binprm
> > 
> > Stacey Son (2):
> >   bsd-user: move arch/OS dependent code out of main.c
> >   bsd-user: move arch/OS dependent code out of syscall.c
> > 
> >  bsd-user/Makefile.objs                  |   2 +-
> >  bsd-user/bsdload.c                      | 170 ++++--
> >  bsd-user/elfload.c                      |  11 +-
> >  bsd-user/freebsd/host_os.h              |  46 ++
> >  bsd-user/freebsd/os-strace.h            |  29 +
> >  bsd-user/freebsd/os-sys.c               | 285 ++++++++++
> >  bsd-user/freebsd/strace.list            |   2 +-
> >  bsd-user/freebsd/target_os_stack.h      | 157 ++++++
> >  bsd-user/freebsd/target_os_vmparam.h    |  23 +
> >  bsd-user/i386/syscall.h                 |  23 +
> >  bsd-user/i386/target_arch.h             |  13 +
> >  bsd-user/i386/target_arch_cpu.c         |  79 +++
> >  bsd-user/i386/target_arch_cpu.h         | 300 +++++++++++
> >  bsd-user/i386/target_arch_sigtramp.h    |  11 +
> >  bsd-user/i386/target_arch_sysarch.h     |  78 +++
> >  bsd-user/i386/target_arch_vmparam.h     |  28 +
> >  bsd-user/i386/target_signal.h           |   6 -
> >  bsd-user/main.c                         | 927 +++++++-------------------------
> >  bsd-user/mmap.c                         |   2 +-
> >  bsd-user/netbsd/host_os.h               |  31 ++
> >  bsd-user/netbsd/os-strace.h             |  29 +
> >  bsd-user/netbsd/os-sys.c                |  46 ++
> >  bsd-user/netbsd/target_os_stack.h       |  33 ++
> >  bsd-user/netbsd/target_os_vmparam.h     |  23 +
> >  bsd-user/openbsd/host_os.h              |  31 ++
> >  bsd-user/openbsd/os-strace.h            |  29 +
> >  bsd-user/openbsd/os-sys.c               |  46 ++
> >  bsd-user/openbsd/target_os_stack.h      |  33 ++
> >  bsd-user/openbsd/target_os_vmparam.h    |  23 +
> >  bsd-user/qemu.h                         |  50 +-
> >  bsd-user/sparc/syscall.h                |  29 +-
> >  bsd-user/sparc/target_arch.h            |  11 +
> >  bsd-user/sparc/target_arch_cpu.c        | 113 ++++
> >  bsd-user/sparc/target_arch_cpu.h        | 158 ++++++
> >  bsd-user/sparc/target_arch_sigtramp.h   |  11 +
> >  bsd-user/sparc/target_arch_sysarch.h    |  52 ++
> >  bsd-user/sparc/target_arch_vmparam.h    |  37 ++
> >  bsd-user/sparc/target_signal.h          |   5 -
> >  bsd-user/sparc64/syscall.h              |  28 +-
> >  bsd-user/sparc64/target_arch.h          |  11 +
> >  bsd-user/sparc64/target_arch_cpu.c      | 118 ++++
> >  bsd-user/sparc64/target_arch_cpu.h      | 191 +++++++
> >  bsd-user/sparc64/target_arch_sigtramp.h |  11 +
> >  bsd-user/sparc64/target_arch_sysarch.h  |  52 ++
> >  bsd-user/sparc64/target_arch_vmparam.h  |  37 ++
> >  bsd-user/sparc64/target_signal.h        |   5 -
> >  bsd-user/strace.c                       |  10 +
> >  bsd-user/syscall.c                      | 210 +-------
> >  bsd-user/x86_64/syscall.h               |  26 +-
> >  bsd-user/x86_64/target_arch.h           |  13 +
> >  bsd-user/x86_64/target_arch_cpu.c       |  79 +++
> >  bsd-user/x86_64/target_arch_cpu.h       | 322 +++++++++++
> >  bsd-user/x86_64/target_arch_sigtramp.h  |  11 +
> >  bsd-user/x86_64/target_arch_sysarch.h   |  76 +++
> >  bsd-user/x86_64/target_arch_vmparam.h   |  28 +
> >  bsd-user/x86_64/target_signal.h         |   5 -
> >  56 files changed, 3207 insertions(+), 1008 deletions(-)
> >  create mode 100644 bsd-user/freebsd/host_os.h
> >  create mode 100644 bsd-user/freebsd/os-strace.h
> >  create mode 100644 bsd-user/freebsd/os-sys.c
> >  create mode 100644 bsd-user/freebsd/target_os_stack.h
> >  create mode 100644 bsd-user/freebsd/target_os_vmparam.h
> >  create mode 100644 bsd-user/i386/target_arch.h
> >  create mode 100644 bsd-user/i386/target_arch_cpu.c
> >  create mode 100644 bsd-user/i386/target_arch_cpu.h
> >  create mode 100644 bsd-user/i386/target_arch_sigtramp.h
> >  create mode 100644 bsd-user/i386/target_arch_sysarch.h
> >  create mode 100644 bsd-user/i386/target_arch_vmparam.h
> >  create mode 100644 bsd-user/netbsd/host_os.h
> >  create mode 100644 bsd-user/netbsd/os-strace.h
> >  create mode 100644 bsd-user/netbsd/os-sys.c
> >  create mode 100644 bsd-user/netbsd/target_os_stack.h
> >  create mode 100644 bsd-user/netbsd/target_os_vmparam.h
> >  create mode 100644 bsd-user/openbsd/host_os.h
> >  create mode 100644 bsd-user/openbsd/os-strace.h
> >  create mode 100644 bsd-user/openbsd/os-sys.c
> >  create mode 100644 bsd-user/openbsd/target_os_stack.h
> >  create mode 100644 bsd-user/openbsd/target_os_vmparam.h
> >  create mode 100644 bsd-user/sparc/target_arch.h
> >  create mode 100644 bsd-user/sparc/target_arch_cpu.c
> >  create mode 100644 bsd-user/sparc/target_arch_cpu.h
> >  create mode 100644 bsd-user/sparc/target_arch_sigtramp.h
> >  create mode 100644 bsd-user/sparc/target_arch_sysarch.h
> >  create mode 100644 bsd-user/sparc/target_arch_vmparam.h
> >  create mode 100644 bsd-user/sparc64/target_arch.h
> >  create mode 100644 bsd-user/sparc64/target_arch_cpu.c
> >  create mode 100644 bsd-user/sparc64/target_arch_cpu.h
> >  create mode 100644 bsd-user/sparc64/target_arch_sigtramp.h
> >  create mode 100644 bsd-user/sparc64/target_arch_sysarch.h
> >  create mode 100644 bsd-user/sparc64/target_arch_vmparam.h
> >  create mode 100644 bsd-user/x86_64/target_arch.h
> >  create mode 100644 bsd-user/x86_64/target_arch_cpu.c
> >  create mode 100644 bsd-user/x86_64/target_arch_cpu.h
> >  create mode 100644 bsd-user/x86_64/target_arch_sigtramp.h
> >  create mode 100644 bsd-user/x86_64/target_arch_sysarch.h
> >  create mode 100644 bsd-user/x86_64/target_arch_vmparam.h
> > 
> 
> ping and happy weekend!
> 
> sean
> 
> 

ping x2, happy monday.

sean

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH 1/4] bsd-user: Implement new syscall print_sysarch and add strace support
  2014-06-20  0:19 ` [Qemu-devel] [PATCH 1/4] bsd-user: Implement new syscall print_sysarch and add strace support Sean Bruno
@ 2014-07-03 13:19   ` Peter Maydell
  0 siblings, 0 replies; 11+ messages in thread
From: Peter Maydell @ 2014-07-03 13:19 UTC (permalink / raw)
  To: Sean Bruno; +Cc: QEMU Developers

On 20 June 2014 01:19, Sean Bruno <sbruno@freebsd.org> wrote:
> Signed-off-by: Sean Bruno <sbruno@freebsd.org>
> Signed-off-by: Stacey Son <sson@freebsd.org>
> ---
>  bsd-user/freebsd/os-strace.h           | 35 +++++++++++++++
>  bsd-user/freebsd/strace.list           |  2 +-
>  bsd-user/i386/syscall.h                | 21 +++++++++
>  bsd-user/i386/target_arch_sysarch.h    | 78 ++++++++++++++++++++++++++++++++++
>  bsd-user/netbsd/os-strace.h            | 37 ++++++++++++++++
>  bsd-user/openbsd/os-strace.h           | 37 ++++++++++++++++
>  bsd-user/qemu.h                        |  3 ++
>  bsd-user/sparc/syscall.h               | 27 +++++++++++-
>  bsd-user/sparc/target_arch_sysarch.h   | 52 +++++++++++++++++++++++
>  bsd-user/sparc64/syscall.h             | 26 +++++++++++-
>  bsd-user/sparc64/target_arch_sysarch.h | 52 +++++++++++++++++++++++
>  bsd-user/strace.c                      | 10 +++++
>  bsd-user/syscall.c                     | 63 +--------------------------
>  bsd-user/x86_64/syscall.h              | 24 ++++++++++-
>  bsd-user/x86_64/target_arch_sysarch.h  | 76 +++++++++++++++++++++++++++++++++
>  15 files changed, 477 insertions(+), 66 deletions(-)
>  create mode 100644 bsd-user/freebsd/os-strace.h
>  create mode 100644 bsd-user/i386/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

I think this would be clearer if you split it in two:
 * code motion to split the syscall into per-OS/per-arch
   subdirectories
 * add support for strace for it

At the moment this is a big patch doing two distinct things,
which is usually a sign it should be split up.

Your commit message is also very brief and inaccurate
(the syscall is not called "print_sysarch" and we already
implemented it, this is just refactoring). Single-line
commit messages should be the exception, not the rule,
and generally only for very simple small patches.

Codewise there are just a few minor things:

> +++ b/bsd-user/netbsd/os-strace.h
> @@ -0,0 +1,37 @@
> +/*
> + *  NetBSD dependent strace print functions
> + *
> + *  Copyright (c) 2014 Sean Bruno <sbruno@freebsd.org>
> + *
> + *  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)
> +{
> +    qemu_log("qemu: Unsupported syscall %s\n", __func__);
> +    return -TARGET_ENOSYS;

Void function attempting to return a value... (the compiler
ought to warn about this I hope).

> +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)
> +{
> +    qemu_log("qemu: Unsupported syscall %s\n", __func__);
> +    return -TARGET_ENOSYS;
> +}

Ditto.

> +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 */

If you want to fall through to a following case you should
have a marker comment like this:
    /* fallthrough */

for the benefit of automatic static analysis tools.

> +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;
> +    }

Ditto.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH 3/4] bsd-user: Rename linux_binprm to bsd_binprm
  2014-06-20  0:19 ` [Qemu-devel] [PATCH 3/4] bsd-user: Rename linux_binprm to bsd_binprm Sean Bruno
@ 2014-07-03 13:23   ` Peter Maydell
  0 siblings, 0 replies; 11+ messages in thread
From: Peter Maydell @ 2014-07-03 13:23 UTC (permalink / raw)
  To: Sean Bruno; +Cc: QEMU Developers

On 20 June 2014 01:19, Sean Bruno <sbruno@freebsd.org> wrote:
> These too similar data structures will be diverging in future updates
> from my trees.  Rename now.
>
> Signed-off-by: Sean Bruno <sbruno@freebsd.org>

> -int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
> +int load_elf_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs,
>                      struct image_info * info)

> -int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
> +int load_elf_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs,
>                      struct image_info * info);
> -int load_flt_binary(struct linux_binprm * bprm, struct target_pt_regs * regs,
> +int load_flt_binary(struct bsd_binprm * bprm, struct target_pt_regs * regs,
>                      struct image_info * info);

If you run this patch through checkpatch.pl you'll find that
it complains about the space following the "*" in these
function prototypes. You might as well fix that here since
you touch those lines anyway.

Otherwise
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

thanks
-- PMM

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH 2/4] bsd-user: move arch/OS dependent code out of main.c
  2014-06-20  0:19 ` [Qemu-devel] [PATCH 2/4] bsd-user: move arch/OS dependent code out of main.c Sean Bruno
@ 2014-07-03 13:45   ` Peter Maydell
  0 siblings, 0 replies; 11+ messages in thread
From: Peter Maydell @ 2014-07-03 13:45 UTC (permalink / raw)
  To: Sean Bruno; +Cc: QEMU Developers

On 20 June 2014 01:19, Sean Bruno <sbruno@freebsd.org> wrote:
> From: Stacey Son <sson@FreeBSD.org>
>
> This change moves the cpu initialization and main loop code from
> main.c to the OS and arch dependent directories. This eliminates
> many of the #ifdef's in main.c. The cpu initialization and loop
> code is now located in the arch directory along with target arch
> support code.
>
> Signed-off-by: Sean Bruno <sbruno@freebsd.org>
> ---
>  bsd-user/Makefile.objs                 |   2 +-
>  bsd-user/elfload.c                     |   2 +-
>  bsd-user/freebsd/host_os.h             |  46 ++
>  bsd-user/freebsd/target_os_vmparam.h   |  23 +
>  bsd-user/i386/target_arch.h            |  13 +
>  bsd-user/i386/target_arch_cpu.c        |  79 +++
>  bsd-user/i386/target_arch_cpu.h        | 300 +++++++++++
>  bsd-user/i386/target_arch_vmparam.h    |  28 +
>  bsd-user/i386/target_signal.h          |   6 -
>  bsd-user/main.c                        | 927 +++++++--------------------------
>  bsd-user/mmap.c                        |   2 +-
>  bsd-user/netbsd/host_os.h              |  31 ++
>  bsd-user/netbsd/os-strace.h            |   2 +-
>  bsd-user/netbsd/target_os_vmparam.h    |  23 +
>  bsd-user/openbsd/host_os.h             |  31 ++
>  bsd-user/openbsd/os-strace.h           |   2 +-
>  bsd-user/openbsd/target_os_vmparam.h   |  23 +
>  bsd-user/qemu.h                        |  21 +-
>  bsd-user/sparc/target_arch.h           |  11 +
>  bsd-user/sparc/target_arch_cpu.c       | 113 ++++
>  bsd-user/sparc/target_arch_cpu.h       | 158 ++++++
>  bsd-user/sparc/target_arch_vmparam.h   |  37 ++
>  bsd-user/sparc/target_signal.h         |   5 -
>  bsd-user/sparc64/target_arch.h         |  11 +
>  bsd-user/sparc64/target_arch_cpu.c     | 118 +++++
>  bsd-user/sparc64/target_arch_cpu.h     | 191 +++++++
>  bsd-user/sparc64/target_arch_vmparam.h |  37 ++
>  bsd-user/sparc64/target_signal.h       |   5 -
>  bsd-user/x86_64/target_arch.h          |  13 +
>  bsd-user/x86_64/target_arch_cpu.c      |  79 +++
>  bsd-user/x86_64/target_arch_cpu.h      | 322 ++++++++++++
>  bsd-user/x86_64/target_arch_vmparam.h  |  28 +
>  bsd-user/x86_64/target_signal.h        |   5 -
>  33 files changed, 1930 insertions(+), 764 deletions(-)

Oof. I'm afraid this still needs to be separated out into
separate patches a bit more. This patch seems to have:
 * some things which are unrelated to the code-refactoring
   it claims to be doing (I've noted a few below)
 * movement of multiple different functions (most notably,
   this patch deals with both the main cpu loop and also
   the target-cpu-init) which could be done in separate patches
 * some minor style/whitespace changes

> +#if (TARGET_LONG_BITS == 32) && (HOST_LONG_BITS == 64)
> +/*
> + * When running 32-on-64 we should make sure we can fit all of the possible
> + * guest address space into a contiguous chunk of virtual host memory.
> + *
> + * This way we will never overlap with our own libraries or binaries or stack
> + * or anything else that QEMU maps.
> + */
> +unsigned long reserved_va = TARGET_RESERVED_VA;
> +#else
>  unsigned long reserved_va;
>  #endif
> +#endif /* CONFIG_USE_GUEST_BASE */

For instance, this is a separate change -- it's moving into
line with linux-user for the default reserved address, which
is good but not related to moving the arch/OS dependent code.

> +/* Helper routines for implementing atomic operations. */
>
> +/*
> + * To implement exclusive operations we force all cpus to synchronize.
> + * We don't require a full sync, only that no cpus are executing guest code.
> + * The alternative is to map target atomic ops onto host eqivalents,
> + * which requires quite a lot of per host/target work.
> + */
> +static pthread_mutex_t cpu_list_mutex = PTHREAD_MUTEX_INITIALIZER;
> +static pthread_mutex_t exclusive_lock = PTHREAD_MUTEX_INITIALIZER;
> +static pthread_cond_t exclusive_cond = PTHREAD_COND_INITIALIZER;
> +static pthread_cond_t exclusive_resume = PTHREAD_COND_INITIALIZER;
> +static int pending_cpus;

This atomic-operations stuff also looks like a new feature
that should go in its own patch.

> +
> +#if defined(CONFIG_USE_NPTL)

Anything using CONFIG_USE_NPTL needs fixing, because
configure no longer sets that at all: using NPTL became the
default once we converted all the Linux archs to it.

> +void gemu_log(const char *fmt, ...)
> +{
> +    va_list ap;
> +
> +    va_start(ap, fmt);
> +    vfprintf(stderr, fmt, ap);
> +    va_end(ap);
> +}

This function just randomly moved location; seems a bit
pointless, but if you want to do it don't stuff it into this patch.

> @@ -767,7 +362,7 @@ int main(int argc, char **argv)
>  #endif
>
>      optind = 1;
> -    for(;;) {
> +    for (;;) {

Stray style/whitespace only change, don't bother or put it in
its own patch.

> -    if (loader_exec(filename, argv+optind, target_environ, regs, info) != 0) {
> +    if (loader_exec(filename, argv+optind, target_environ, regs, info)) {

Another style-only change.

> @@ -25,7 +25,7 @@ static inline void do_os_print_sysarch(const struct syscallname *name,
>          abi_long arg5, abi_long arg6)
>  {
>      qemu_log("qemu: Unsupported syscall %s\n", __func__);
> -    return -TARGET_ENOSYS;
> +    return;
>  }

Oh look, here's the fix for a bug I pointed out in review of
patch 1/4 :-)

thanks
-- PMM

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: [Qemu-devel] [PATCH 4/4] bsd-user: move arch/OS dependent code out of syscall.c
  2014-06-20  0:19 ` [Qemu-devel] [PATCH 4/4] bsd-user: move arch/OS dependent code out of syscall.c Sean Bruno
@ 2014-07-03 13:55   ` Peter Maydell
  0 siblings, 0 replies; 11+ messages in thread
From: Peter Maydell @ 2014-07-03 13:55 UTC (permalink / raw)
  To: Sean Bruno; +Cc: QEMU Developers

On 20 June 2014 01:19, Sean Bruno <sbruno@freebsd.org> wrote:
> From: Stacey Son <sson@FreeBSD.org>
>
> This change moves the system call handler for sysctl(2) and
> sysarch(2) from syscall.c to the OS and arch dependent directories.
> This eliminates many of the #ifdef's in syscall.c.  These system
> call handlers are now located in the host os and target arch
> directories.
>
> Signed-off-by: Sean Bruno <sbruno@freebsd.org>
> Signed-off-by: Stacey Son <sson@freebsd.org>
> ---
>  bsd-user/Makefile.objs                  |   2 +-
>  bsd-user/bsdload.c                      | 168 +++++++++++++------

Why are we making lots of changes to bsdload.c then? This
doesn't match up with the commit message...

>  bsd-user/elfload.c                      |   7 +-
>  bsd-user/freebsd/os-strace.h            |   6 -
>  bsd-user/freebsd/os-sys.c               | 285 ++++++++++++++++++++++++++++++++
>  bsd-user/freebsd/target_os_stack.h      | 157 ++++++++++++++++++
>  bsd-user/i386/syscall.h                 |   2 +
>  bsd-user/i386/target_arch_sigtramp.h    |  11 ++
>  bsd-user/main.c                         |   2 +-
>  bsd-user/netbsd/os-strace.h             |   8 -
>  bsd-user/netbsd/os-sys.c                |  46 ++++++
>  bsd-user/netbsd/target_os_stack.h       |  33 ++++
>  bsd-user/openbsd/os-strace.h            |   8 -
>  bsd-user/openbsd/os-sys.c               |  46 ++++++
>  bsd-user/openbsd/target_os_stack.h      |  33 ++++
>  bsd-user/qemu.h                         |  28 +++-
>  bsd-user/sparc/syscall.h                |   2 +
>  bsd-user/sparc/target_arch_sigtramp.h   |  11 ++
>  bsd-user/sparc64/syscall.h              |   2 +
>  bsd-user/sparc64/target_arch_sigtramp.h |  11 ++
>  bsd-user/syscall.c                      | 151 ++++-------------
>  bsd-user/x86_64/syscall.h               |   2 +
>  bsd-user/x86_64/target_arch_sigtramp.h  |  11 ++
>  23 files changed, 827 insertions(+), 205 deletions(-)
>  create mode 100644 bsd-user/freebsd/os-sys.c
>  create mode 100644 bsd-user/freebsd/target_os_stack.h
>  create mode 100644 bsd-user/i386/target_arch_sigtramp.h
>  create mode 100644 bsd-user/netbsd/os-sys.c
>  create mode 100644 bsd-user/netbsd/target_os_stack.h
>  create mode 100644 bsd-user/openbsd/os-sys.c
>  create mode 100644 bsd-user/openbsd/target_os_stack.h
>  create mode 100644 bsd-user/sparc/target_arch_sigtramp.h
>  create mode 100644 bsd-user/sparc64/target_arch_sigtramp.h
>  create mode 100644 bsd-user/x86_64/target_arch_sigtramp.h

Again, this patch is doing too much at once. I would
suggest you could split it out into at least:
 * 1 patch for sigtramp related code
 * 1 patch for os_stack related code
 * 1 or more patches for the loader changes
 * 1 patch for sysctl changes (making sure you keep
   "add new functionality" separate from "just moving
   code around"; I'm pretty sure you're adding support for
   new sysctls here, like the HW_MACHINE stuff)
 * either drop whitespace/format changes or put them in
   their own patch, your choice

> diff --git a/bsd-user/freebsd/os-strace.h b/bsd-user/freebsd/os-strace.h
> index c856450..a222f09 100644
> --- a/bsd-user/freebsd/os-strace.h
> +++ b/bsd-user/freebsd/os-strace.h
> @@ -27,9 +27,3 @@ static inline void do_os_print_sysarch(const struct syscallname *name,
>      /* This is arch dependent */
>      do_freebsd_arch_print_sysarch(name, arg1, arg2, arg3, arg4, arg5, arg6);
>  }
> -
> -/* sysarch() is architecture dependent. */
> -abi_long do_bsd_sysarch(void *cpu_env, abi_long arg1, abi_long arg2)
> -{
> -    return do_freebsd_arch_sysarch(cpu_env, arg1, arg2);
> -}

We just added this function in patch 1, why are we removing it again?
Either patch 1 or this one is wrong... There are other bits of
code in this patch touching the sysarch code which should be
in patch 1 as well.

thanks
-- PMM

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2014-07-03 13:55 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-06-20  0:19 [Qemu-devel] [PATCH 0/4] bsd-user: Update Queue Sean Bruno
2014-06-20  0:19 ` [Qemu-devel] [PATCH 1/4] bsd-user: Implement new syscall print_sysarch and add strace support Sean Bruno
2014-07-03 13:19   ` Peter Maydell
2014-06-20  0:19 ` [Qemu-devel] [PATCH 2/4] bsd-user: move arch/OS dependent code out of main.c Sean Bruno
2014-07-03 13:45   ` Peter Maydell
2014-06-20  0:19 ` [Qemu-devel] [PATCH 3/4] bsd-user: Rename linux_binprm to bsd_binprm Sean Bruno
2014-07-03 13:23   ` Peter Maydell
2014-06-20  0:19 ` [Qemu-devel] [PATCH 4/4] bsd-user: move arch/OS dependent code out of syscall.c Sean Bruno
2014-07-03 13:55   ` Peter Maydell
2014-06-21 16:39 ` [Qemu-devel] [PATCH 0/4] bsd-user: Update Queue Sean Bruno
2014-06-23 14:20   ` Sean Bruno

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).