diff options
author | Juergen Lock <nox@FreeBSD.org> | 2015-01-06 19:47:28 +0000 |
---|---|---|
committer | Juergen Lock <nox@FreeBSD.org> | 2015-01-06 19:47:28 +0000 |
commit | dbc8d4a8be751066be977999cb8e6bd9d56cd6e6 (patch) | |
tree | 98ea2e3e5e43b906f6267887acd9ac55a87c2af4 /emulators | |
parent | Update to GNU Chess 6.2.1 (diff) |
- Update emulators/qemu-sbruno to latest github snapshot, fixing
the bsd-user targets on 8 and 9.
- Switch emulators/qemu-user-static to be slave of emulators/qemu-sbruno.
- Update emulators/qemu-devel to latest upstream release 2.2.0, now
w/o bsd-user patches and knob again. (Or at least until the
patches are merged upstream...) [1]
- Add appropriate CONFLICTS to emulators/qemu too and bump its
PORTREVISION.
Suggested by: andrew [1] (for the benefit of testing aarch64 guests)
Notes
Notes:
svn path=/head/; revision=376437
Diffstat (limited to 'emulators')
73 files changed, 74 insertions, 35271 deletions
diff --git a/emulators/qemu-devel/Makefile b/emulators/qemu-devel/Makefile index 339ebc2dec9b..e6dfc9701601 100644 --- a/emulators/qemu-devel/Makefile +++ b/emulators/qemu-devel/Makefile @@ -2,8 +2,7 @@ # $FreeBSD$ PORTNAME= qemu -PORTVERSION= 2.0.2 -PORTREVISION= 12 +PORTVERSION= 2.2.0 CATEGORIES= emulators MASTER_SITES= http://wiki.qemu.org/download/:release \ LOCAL/nox:snapshot @@ -24,7 +23,7 @@ MAKE_ENV+= BSD_MAKE="${MAKE}" ONLY_FOR_ARCHS= amd64 i386 powerpc powerpc64 # XXX someone wants to debug sparc64 hosts? OPTIONS_DEFINE= SAMBA X11 GTK2 OPENGL GNUTLS SASL JPEG PNG CURL \ - CDROM_DMA PCAP USBREDIR GNS3 X86_TARGETS BSD_USER \ + CDROM_DMA PCAP USBREDIR GNS3 X86_TARGETS \ STATIC_LINK DOCS SAMBA_DESC= samba dependency (for -smb) GNUTLS_DESC= gnutls dependency (vnc encryption) @@ -41,73 +40,11 @@ STATIC_LINK_DESC= Statically link the executables OPTIONS_DEFAULT=X11 GTK2 OPENGL GNUTLS SASL JPEG PNG CDROM_DMA CURL PCAP .if !defined(QEMU_USER_STATIC) -CONFLICTS_INSTALL= qemu-[0-9]* +CONFLICTS_INSTALL= qemu-[0-9]* qemu-sbruno-[0-9]* .endif .include <bsd.port.options.mk> -.if ${PORT_OPTIONS:MBSD_USER} -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-790d0ef625d22ff3f1a895d266a48e2bacd63776 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-3d175d6ed5b809976662135369c639f53780ca5c -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-a3129eea10f188bfd39ce83b18b25dcefbc5bffc -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-fd7ec8e06cd1876ef478975f052ff64134d19c6c -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-9ac2c49c734a49025fe1647ce84728d3988ea5d2 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-38f8d5aaebdb4b1624bae86b374b5265c9f01b54 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-c13_tls2 -# -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-freebsd-os-proc.c -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-05ee8495804599b52a88eb36b13ea9c06b3207cd -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-mips-target_arch_vmparam.h -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-inherit-interp_prefix -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-d62553b108aa27c0c020dbb771d29f8673807a3b -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-6201cb17ad905dffee1b2eb76f58fb032e99b2a1 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-syscall.c -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-sysctl-hw-availpages -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-sysctl-0oldlen -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-mmap.c -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-sysctl-hw-pagesizes -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-x86_64-target_arch_vmparam.h -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-target_siginfo -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-arm-signal -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-getvfsbyname -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-kernproc -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-freebsd-target_os_stack.h -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-arm-target_arch_thread.h -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-sparc64-target_arch_cpu.h -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-trapsig -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-21927cffcc7bcacbb953155f778200846df9f60e -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-freebsd-os-sys.c -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-sysctl-hw-physmem -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-max-arg-pages -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-ad92220df37d1ab3120316fcc436071c78817561 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-2478a4e4a33d0523cc436eabb4a27b258b4358b8 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-ac9f83019a2059d4bfe5cedfae35ba4151d5ac88 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-d9388715135ed1f36e12e6cdbcc1be09d1657916 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-c9c55ac786f09ce575b5f67b35241ce9452896c9 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-5f81caf45c0d0eb2b4b852f8580a1938fb3d12c6 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-f32d585446698e1faa319c95df6b4d00c16f866c -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-a6402a4b7077af85733a1c98d63ab09f02d980ec -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-30c8ccb41e2c9e1ddda7e3f8a8ac1eb5dab8b408 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-22b23eb877a8a5ec251b4ae0e71e3c7ce5397721 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-1ebbb5b56e890741f1461662fae9728da0c76e27 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-93cf90cb04fee057a710be43614b033e6b2e86d1 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-ad225b8412847303d48d8e7852589456325e8f9b -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-3ed485b9b4ef8d8ba916760aec0cdf9dbce8ca27 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-72f0a64c7dd7be796dc2d8f2b0dab340309800e2 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-9ed0e07e2e07791858339874eb4d20daca858c8a -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-a8dc4de7f73bc6f8363c0fc81c4c6e53733c444b -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-bsd-user-freebsd-os-socket.h -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-cab0d36ffd4e70b1879dc2cf860c975a7965afc3 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-8267ad2cb92b106bb16e91234f04abc49ab32036 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-290a6e398b9d132a673e1f95954fc7d9a86c3baa -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-26a50e8a9d8723d406e5ef3d1449911cfa2d3454 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-22aae36fc2227aa772ebbc701f45319464ecae4d -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-a72c668c8ab84c24372ff664d9b853c2a42d37b1 -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-d5c3fb7b75b4ea80e09bf3cb7ff6dd1061968d6e -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-f4319eb1a3a8393930570f061bdac6abe007b2bb -EXTRA_PATCHES+= ${FILESDIR}/extra-patch-f254372f13ab5cd8f25bd1ca8641ce6d67bff3fe -.endif - CONFIGURE_ARGS+= --localstatedir=/var CONFIGURE_ARGS+= --extra-ldflags=-L${LOCALBASE}/lib CONFIGURE_ARGS+= --disable-smartcard-nss --disable-libssh2 @@ -286,6 +223,7 @@ CONFIGURE_ARGS+= --sparc_cpu=v9 .if ${OSVERSION} < 900033 BUILD_DEPENDS+= ${LOCALBASE}/bin/as:${PORTSDIR}/devel/binutils +CONFIGURE_ENV+= AS=${LOCALBASE}/bin/as CONFIGURE_ENV+= LD=${LOCALBASE}/bin/ld CONFIGURE_ENV+= COMPILER_PATH=${LOCALBASE}/bin MAKE_ENV+= COMPILER_PATH=${LOCALBASE}/bin @@ -338,8 +276,8 @@ post-install: .if ${PORT_OPTIONS:MDOCS} @(cd ${WRKSRC} && ${COPYTREE_SHARE} docs ${STAGEDIR}${DOCSDIR}/) .endif - @${INSTALL_SCRIPT} ${FILESDIR}/qemu-ifup.sample ${STAGEDIR}${PREFIX}/etc - @${INSTALL_SCRIPT} ${FILESDIR}/qemu-ifdown.sample ${STAGEDIR}${PREFIX}/etc + ${INSTALL_SCRIPT} ${FILESDIR}/qemu-ifup.sample ${STAGEDIR}${PREFIX}/etc + ${INSTALL_SCRIPT} ${FILESDIR}/qemu-ifdown.sample ${STAGEDIR}${PREFIX}/etc @(cd ${STAGEDIR}${PREFIX}/etc/qemu && \ ${MV} -i target-x86_64.conf target-x86_64.conf.sample) @${STRIP_CMD} ${STAGEDIR}${PREFIX}/bin/qemu-* diff --git a/emulators/qemu-devel/distinfo b/emulators/qemu-devel/distinfo index d2aff4a18e54..a048e4fa9f24 100644 --- a/emulators/qemu-devel/distinfo +++ b/emulators/qemu-devel/distinfo @@ -1,2 +1,2 @@ -SHA256 (qemu/2.0.2/qemu-2.0.2.tar.bz2) = 20b207238015b773a8b8752801397bac2bb284b157a4999fb7a1039625d282cc -SIZE (qemu/2.0.2/qemu-2.0.2.tar.bz2) = 12841893 +SHA256 (qemu/2.2.0/qemu-2.2.0.tar.bz2) = b68c9b6c7c694f5489b5a6bffe993cd976ffbb78e7d178eb3bc016caf460039c +SIZE (qemu/2.2.0/qemu-2.2.0.tar.bz2) = 24316697 diff --git a/emulators/qemu-devel/files/extra-patch-05ee8495804599b52a88eb36b13ea9c06b3207cd b/emulators/qemu-devel/files/extra-patch-05ee8495804599b52a88eb36b13ea9c06b3207cd deleted file mode 100644 index 1bc661386a9f..000000000000 --- a/emulators/qemu-devel/files/extra-patch-05ee8495804599b52a88eb36b13ea9c06b3207cd +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h -index fc279a8..5d8a347 100644 ---- a/bsd-user/bsd-file.h -+++ b/bsd-user/bsd-file.h -@@ -996,9 +996,15 @@ static abi_long do_bsd_lseek(void *cpu_env, abi_long arg1, abi_long arg2, - } - if (res == -1) { - ret = get_errno(res); -+ set_second_rval(cpu_env, 0xFFFFFFFF); - } else { -- ret = res & 0xFFFFFFFF; -+#ifdef TARGET_WORDS_BIGENDIAN -+ ret = ((res >> 32) & 0xFFFFFFFF); -+ set_second_rval(cpu_env, res & 0xFFFFFFFF); -+#else -+ ret = res & 0xFFFFFFFF; - set_second_rval(cpu_env, (res >> 32) & 0xFFFFFFFF); -+#endif - } - #else - ret = get_errno(lseek(arg1, arg2, arg3)); diff --git a/emulators/qemu-devel/files/extra-patch-1ebbb5b56e890741f1461662fae9728da0c76e27 b/emulators/qemu-devel/files/extra-patch-1ebbb5b56e890741f1461662fae9728da0c76e27 deleted file mode 100644 index 2ce53dcf5d9a..000000000000 --- a/emulators/qemu-devel/files/extra-patch-1ebbb5b56e890741f1461662fae9728da0c76e27 +++ /dev/null @@ -1,72 +0,0 @@ -From 1ebbb5b56e890741f1461662fae9728da0c76e27 Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Thu, 6 Nov 2014 22:35:01 +0000 -Subject: [PATCH] Add JHB's ioctl decoding to unknown ioctl message. - ---- - bsd-user/bsd-ioctl.c | 31 ++++++++++++++++++++++++++++--- - 1 file changed, 28 insertions(+), 3 deletions(-) - -diff --git a/bsd-user/bsd-ioctl.c b/bsd-user/bsd-ioctl.c -index 95505a4..10e8e54 100644 ---- a/bsd-user/bsd-ioctl.c -+++ b/bsd-user/bsd-ioctl.c -@@ -19,6 +19,7 @@ - - #include <sys/types.h> - #include <sys/param.h> -+#include <sys/ioccom.h> - #include <sys/ioctl.h> - #if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - #include <sys/_termios.h> -@@ -307,6 +308,29 @@ static IOCTLEntry ioctl_entries[] = { - { 0, 0 }, - }; - -+static void log_unsupported_ioctl(unsigned long cmd) -+{ -+ gemu_log("cmd=0x%08lx dir=", cmd); -+ switch (cmd & IOC_DIRMASK) { -+ case IOC_VOID: -+ gemu_log("VOID "); -+ break; -+ case IOC_OUT: -+ gemu_log("OUT "); -+ break; -+ case IOC_IN: -+ gemu_log("IN "); -+ break; -+ case IOC_INOUT: -+ gemu_log("INOUT"); -+ break; -+ default: -+ gemu_log("%01lx ???", (cmd & IOC_DIRMASK) >> 29); -+ break; -+ } -+ gemu_log(" '%c' %3d %lu\n", (char)IOCGROUP(cmd), (int)(cmd & 0xff), IOCPARM_LEN(cmd)); -+} -+ - abi_long do_bsd_ioctl(int fd, abi_long cmd, abi_long arg) - { - const IOCTLEntry *ie; -@@ -319,7 +343,8 @@ abi_long do_bsd_ioctl(int fd, abi_long cmd, abi_long arg) - ie = ioctl_entries; - for (;;) { - if (ie->target_cmd == 0) { -- gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd); -+ gemu_log("Qemu unsupported ioctl: "); -+ log_unsupported_ioctl(cmd); - return -TARGET_ENOSYS; - } - if (ie->target_cmd == cmd) { -@@ -398,8 +423,8 @@ abi_long do_bsd_ioctl(int fd, abi_long cmd, abi_long arg) - break; - - default: -- gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", -- (long)cmd, arg_type[0]); -+ gemu_log("Qemu unknown ioctl: type=%d ", arg_type[0]); -+ log_unsupported_ioctl(cmd); - ret = -TARGET_ENOSYS; - break; - } diff --git a/emulators/qemu-devel/files/extra-patch-21927cffcc7bcacbb953155f778200846df9f60e b/emulators/qemu-devel/files/extra-patch-21927cffcc7bcacbb953155f778200846df9f60e deleted file mode 100644 index 3c370fc2507a..000000000000 --- a/emulators/qemu-devel/files/extra-patch-21927cffcc7bcacbb953155f778200846df9f60e +++ /dev/null @@ -1,274 +0,0 @@ -From 96cc385829084403d39ad71d4ee366993900e632 Mon Sep 17 00:00:00 2001 -From: Alexander Kabaev <kan@FreeBSD.ORG> -Date: Fri, 27 Jun 2014 16:42:16 -0400 -Subject: [PATCH] Follow exec_copyout_strings more closely when setting up - guest stack. - -Remove mysterious TARGET_SPACE_USRSPACE define that limited the -compined size of argvp and envp vectors to just 4k and use the same -calculation that FreeBSD kernel uses to allocate the space for -strings and vectors sans aux vector, which we do not support just -yet. Remove assumption that argv and env strings end up at the top -of the stack and pass the pointer around instead. - -This allows one to run programs with more than 4096/sizeof(abi_long) -env and args strings on command line. ---- - bsd-user/elfload.c | 11 +++++------ - bsd-user/freebsd/target_os_elf.h | 3 ++- - bsd-user/freebsd/target_os_stack.h | 25 ++++++++++++++++--------- - bsd-user/freebsd/target_os_vmparam.h | 1 - - bsd-user/netbsd/target_os_elf.h | 3 ++- - bsd-user/netbsd/target_os_stack.h | 6 +++++- - bsd-user/openbsd/target_os_elf.h | 3 ++- - bsd-user/openbsd/target_os_stack.h | 6 +++++- - bsd-user/qemu.h | 1 + - 9 files changed, 38 insertions(+), 21 deletions(-) - -diff --git a/bsd-user/elfload.c b/bsd-user/elfload.c -index 945e2a0..406d1c2 100644 ---- a/bsd-user/elfload.c -+++ b/bsd-user/elfload.c -@@ -166,8 +166,8 @@ static abi_ulong copy_elf_strings(int argc,char ** argv, void **page, - return p; - } - --static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm, -- struct image_info *info) -+static void setup_arg_pages(struct bsd_binprm *bprm, struct image_info *info, -+ abi_ulong *stackp, abi_ulong *stringp) - { - abi_ulong stack_base, size; - abi_long addr; -@@ -189,12 +189,10 @@ static abi_ulong setup_arg_pages(abi_ulong p, struct bsd_binprm *bprm, - target_stksiz = size; - target_stkbas = addr; - -- if (setup_initial_stack(bprm, &p) != 0) { -+ if (setup_initial_stack(bprm, stackp, stringp) != 0) { - perror("stk setup"); - exit(-1); - } -- -- return p; - } - - static void set_brk(abi_ulong start, abi_ulong end) -@@ -819,7 +817,7 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs, - /* Do this so that we can load the interpreter, if need be. We will - change some of these later */ - info->rss = 0; -- bprm->p = setup_arg_pages(bprm->p, bprm, info); -+ setup_arg_pages(bprm, info, &bprm->p, &bprm->stringp); - info->start_stack = bprm->p; - - /* Now we do a little grungy work by mmaping the ELF image into -@@ -945,6 +943,7 @@ int load_elf_binary(struct bsd_binprm *bprm, struct target_pt_regs *regs, - bprm->p = target_create_elf_tables(bprm->p, - bprm->argc, - bprm->envc, -+ bprm->stringp, - &elf_ex, - load_addr, load_bias, - interp_load_addr, -diff --git a/bsd-user/freebsd/target_os_elf.h b/bsd-user/freebsd/target_os_elf.h -index 5bc689a..592a1c2 100644 ---- a/bsd-user/freebsd/target_os_elf.h -+++ b/bsd-user/freebsd/target_os_elf.h -@@ -85,6 +85,7 @@ struct exec - #define DLINFO_ITEMS 12 - - static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc, -+ abi_ulong stringp, - struct elfhdr * exec, - abi_ulong load_addr, - abi_ulong load_bias, -@@ -140,7 +141,7 @@ static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc, - #endif - #undef NEW_AUX_ENT - -- sp = loader_build_argptr(envc, argc, sp, p, !ibcs); -+ sp = loader_build_argptr(envc, argc, sp, stringp, !ibcs); - return sp; - } - -diff --git a/bsd-user/freebsd/target_os_stack.h b/bsd-user/freebsd/target_os_stack.h -index 73aea8f..410b282 100644 ---- a/bsd-user/freebsd/target_os_stack.h -+++ b/bsd-user/freebsd/target_os_stack.h -@@ -44,7 +44,7 @@ - * "destp" -> argv, env strings (up to 262144 bytes) - */ - static inline int setup_initial_stack(struct bsd_binprm *bprm, -- abi_ulong *ret_addr) -+ abi_ulong *ret_addr, abi_ulong *stringp) - { - int i; - abi_ulong stack_hi_addr; -@@ -88,6 +88,15 @@ static inline int setup_initial_stack(struct bsd_binprm *bprm, - errno = EFAULT; - return -1; - } -+ /* -+ * Deviate from FreeBSD stack layout: force stack to new page here -+ * so that signal trampoline is not sharing the page with user stack -+ * frames. This is actively harmful in qemu as it marks pages with -+ * code it translated as read-only, which is somewhat problematic -+ * for user trying to use the stack as intended. -+ */ -+ p = rounddown(p, TARGET_PAGE_SIZE); -+ - /* Calculate the string space needed */ - stringspace = 0; - for (i = 0; i < bprm->argc; ++i) { -@@ -100,20 +109,17 @@ static inline int setup_initial_stack(struct bsd_binprm *bprm, - errno = ENOMEM; - return -1; - } -- - /* Make room for the argv and envp strings */ -- argvp = roundup(p - TARGET_SPACE_USRSPACE - (TARGET_ARG_MAX - stringspace), -- sizeof(abi_ulong)); -- p = destp = p - TARGET_SPACE_USRSPACE - TARGET_ARG_MAX; -- -+ destp = rounddown(p - stringspace, sizeof(abi_ulong)); -+ p = argvp = destp - (bprm->argc + bprm->envc + 2) * sizeof(abi_ulong); -+ /* Remember the strings pointer */ -+ if (stringp) -+ *stringp = destp; - /* - * 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) { -@@ -138,6 +144,7 @@ static inline int setup_initial_stack(struct bsd_binprm *bprm, - * Add env strings. Note that the envp[] vectors are added by - * loader_build_argptr(). - */ -+ envp = argvp + sizeof(abi_ulong); - ps_strs.ps_envstr = tswapl(envp); - ps_strs.ps_nenvstr = tswap32(bprm->envc); - for (i = 0; i < bprm->envc; ++i) { -diff --git a/bsd-user/freebsd/target_os_vmparam.h b/bsd-user/freebsd/target_os_vmparam.h -index 80ac6c8..7415809 100644 ---- a/bsd-user/freebsd/target_os_vmparam.h -+++ b/bsd-user/freebsd/target_os_vmparam.h -@@ -3,7 +3,6 @@ - - #include "target_arch_vmparam.h" - --#define TARGET_SPACE_USRSPACE 4096 - #define TARGET_ARG_MAX 262144 - - /* Compare to sys/exec.h */ -diff --git a/bsd-user/netbsd/target_os_elf.h b/bsd-user/netbsd/target_os_elf.h -index bf663d2..1f6421c 100644 ---- a/bsd-user/netbsd/target_os_elf.h -+++ b/bsd-user/netbsd/target_os_elf.h -@@ -146,6 +146,7 @@ struct exec - #define DLINFO_ITEMS 12 - - static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc, -+ abi_ulong stringp, - struct elfhdr * exec, - abi_ulong load_addr, - abi_ulong load_bias, -@@ -219,7 +220,7 @@ static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc, - #endif - #undef NEW_AUX_ENT - -- sp = loader_build_argptr(envc, argc, sp, p, !ibcs); -+ sp = loader_build_argptr(envc, argc, sp, stringp, !ibcs); - return sp; - } - -diff --git a/bsd-user/netbsd/target_os_stack.h b/bsd-user/netbsd/target_os_stack.h -index 1a26c3f..912207c 100644 ---- a/bsd-user/netbsd/target_os_stack.h -+++ b/bsd-user/netbsd/target_os_stack.h -@@ -3,7 +3,8 @@ - - #include "target_arch_sigtramp.h" - --static inline int setup_initial_stack(struct bsd_binprm *bprm, abi_ulong *p) -+static inline int setup_initial_stack(struct bsd_binprm *bprm, abi_ulong *p, -+ abi_ulong *stringp) - { - int i; - abi_ulong stack_base; -@@ -13,6 +14,9 @@ static inline int setup_initial_stack(struct bsd_binprm *bprm, abi_ulong *p) - if (p) { - *p = stack_base; - } -+ if (stringp) { -+ *stringp = stack_base; -+ } - - for (i = 0; i < MAX_ARG_PAGES; i++) { - if (bprm->page[i]) { -diff --git a/bsd-user/openbsd/target_os_elf.h b/bsd-user/openbsd/target_os_elf.h -index 978d944..b991e02 100644 ---- a/bsd-user/openbsd/target_os_elf.h -+++ b/bsd-user/openbsd/target_os_elf.h -@@ -146,6 +146,7 @@ struct exec - #define DLINFO_ITEMS 12 - - static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc, -+ abi_ulong stringp, - struct elfhdr * exec, - abi_ulong load_addr, - abi_ulong load_bias, -@@ -219,7 +220,7 @@ static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc, - #endif - #undef NEW_AUX_ENT - -- sp = loader_build_argptr(envc, argc, sp, p, !ibcs); -+ sp = loader_build_argptr(envc, argc, sp, stringp, !ibcs); - return sp; - } - -diff --git a/bsd-user/openbsd/target_os_stack.h b/bsd-user/openbsd/target_os_stack.h -index 1a26c3f..42959fd 100644 ---- a/bsd-user/openbsd/target_os_stack.h -+++ b/bsd-user/openbsd/target_os_stack.h -@@ -3,7 +3,8 @@ - - #include "target_arch_sigtramp.h" - --static inline int setup_initial_stack(struct bsd_binprm *bprm, abi_ulong *p) -+static inline int setup_initial_stack(struct bsd_binprm *bprm, abi_ulong *p, -+ abi_ulong *stringp) - { - int i; - abi_ulong stack_base; -@@ -13,6 +14,9 @@ static inline int setup_initial_stack(struct bsd_binprm *bprm, abi_ulong *p) - if (p) { - *p = stack_base; - } -+ if (stringp) { -+ *stringp = stack_base; -+ } - - for (i = 0; i < MAX_ARG_PAGES; i++) { - if (bprm->page[i]) { -diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h -index 5791037..09af1b4 100644 ---- a/bsd-user/qemu.h -+++ b/bsd-user/qemu.h -@@ -134,6 +134,7 @@ struct bsd_binprm { - char buf[128]; - void *page[MAX_ARG_PAGES]; - abi_ulong p; -+ abi_ulong stringp; - int fd; - int e_uid, e_gid; - int argc, envc; --- -1.9.3 - diff --git a/emulators/qemu-devel/files/extra-patch-22aae36fc2227aa772ebbc701f45319464ecae4d b/emulators/qemu-devel/files/extra-patch-22aae36fc2227aa772ebbc701f45319464ecae4d deleted file mode 100644 index dc8c1e695d26..000000000000 --- a/emulators/qemu-devel/files/extra-patch-22aae36fc2227aa772ebbc701f45319464ecae4d +++ /dev/null @@ -1,23 +0,0 @@ -From 22aae36fc2227aa772ebbc701f45319464ecae4d Mon Sep 17 00:00:00 2001 -From: Sean Bruno <sbruno@crack.ysv.freebsd.org> -Date: Sat, 29 Nov 2014 23:02:36 +0000 -Subject: [PATCH] Change UX/AWRAP to allow compile. Probably, this is part of - the problem - ---- - bsd-user/mips64/target_arch_cpu.h | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/bsd-user/mips64/target_arch_cpu.h b/bsd-user/mips64/target_arch_cpu.h -index f4e212f..0619f5b 100644 ---- a/bsd-user/mips64/target_arch_cpu.h -+++ b/bsd-user/mips64/target_arch_cpu.h -@@ -42,7 +42,7 @@ static inline void target_cpu_init(CPUMIPSState *env, - if (regs->cp0_epc & 1) { - env->hflags |= MIPS_HFLAG_M16; - } -- env->hflags |= MIPS_HFLAG_UX | MIPS_HFLAG_64; -+ env->hflags |= MIPS_HFLAG_AWRAP | MIPS_HFLAG_64; - } - - static int do_store_exclusive(CPUMIPSState *env) diff --git a/emulators/qemu-devel/files/extra-patch-22b23eb877a8a5ec251b4ae0e71e3c7ce5397721 b/emulators/qemu-devel/files/extra-patch-22b23eb877a8a5ec251b4ae0e71e3c7ce5397721 deleted file mode 100644 index 59d262be4fcc..000000000000 --- a/emulators/qemu-devel/files/extra-patch-22b23eb877a8a5ec251b4ae0e71e3c7ce5397721 +++ /dev/null @@ -1,1051 +0,0 @@ -From 22b23eb877a8a5ec251b4ae0e71e3c7ce5397721 Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Thu, 6 Nov 2014 20:16:28 +0000 -Subject: [PATCH] Add bsd-user/freebsd/make_syscall_nr_h.sh to generate - syscall_nr.h. - -make_syscall_nr.h.sh is added so syscall_nr.h can be generated from -<sys/syscall.h>. Maybe this should be configure or one of the -makefiles. Also report "qemu: unsupported syscall: #" via gemu_log -when we try to emulate an unsupported system call. ---- - bsd-user/freebsd/make_syscall_nr_h.sh | 26 + - bsd-user/freebsd/strace.list | 2 - - bsd-user/freebsd/syscall_nr.h | 918 +++++++++++++++++----------------- - bsd-user/syscall.c | 7 + - 4 files changed, 495 insertions(+), 458 deletions(-) - create mode 100644 bsd-user/freebsd/make_syscall_nr_h.sh - -diff --git a/bsd-user/freebsd/make_syscall_nr_h.sh b/bsd-user/freebsd/make_syscall_nr_h.sh -new file mode 100644 -index 0000000..cc180df ---- /dev/null -+++ b/bsd-user/freebsd/make_syscall_nr_h.sh -@@ -0,0 +1,26 @@ -+#! /bin/sh - -+ -+# -+# Usage: 'sh ./make_syscall_nr_h.sh [full path to syscall.h] [syscall_nr.h]' -+# -+ -+#default input file: -+syshdr="/usr/include/sys/syscall.h" -+ -+#default output file: -+sysnr="./syscall_nr.h" -+ -+if [ -n "$1" ]; then -+ syshdr=$1 -+fi -+ -+if [ -n "$2" ]; then -+ sysnr=$2 -+fi -+ -+echo "/*" > $sysnr -+echo " * This file was generated from $syshdr" >> $sysnr -+echo " */" >> $sysnr -+echo "" >> $sysnr -+ -+/usr/bin/sed -e 's:SYS_:TARGET_FREEBSD_NR_:' < $syshdr >> $sysnr -diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list -index cba4afe..e09048f 100644 ---- a/bsd-user/freebsd/strace.list -+++ b/bsd-user/freebsd/strace.list -@@ -45,10 +45,8 @@ - { TARGET_FREEBSD_NR_cap_fcntls_get, "cap_fcntls_get", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_cap_fcntls_limit, "cap_fcntls_limit", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_cap_getmode, "cap_getmode", NULL, NULL, NULL }, --{ TARGET_FREEBSD_NR_cap_getrights, "cap_getrights", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_cap_ioctls_get, "cap_ioctls_get", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_cap_ioctls_limit, "cap_ioctls_limit", NULL, NULL, NULL }, --{ TARGET_FREEBSD_NR_cap_new, "cap_new", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_cap_rights_limit, "cap_rights_limit", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_chdir, "chdir", "%s(\"%s\")", NULL, NULL }, - { TARGET_FREEBSD_NR_chflags, "chflags", NULL, NULL, NULL }, -diff --git a/bsd-user/freebsd/syscall_nr.h b/bsd-user/freebsd/syscall_nr.h -index 7d6bef8..74c3135 100644 ---- a/bsd-user/freebsd/syscall_nr.h -+++ b/bsd-user/freebsd/syscall_nr.h -@@ -1,463 +1,469 @@ - /* -+ * This file was generated from /usr/include/sys/syscall.h -+ */ -+ -+/* - * System call numbers. - * -- * created from FreeBSD: releng/9.1/sys/kern/syscalls.master 229723 -- * 2012-01-06 19:29:16Z jhb -+ * DO NOT EDIT-- this file is automatically generated. -+ * $FreeBSD$ -+ * created from FreeBSD: head/sys/kern/syscalls.master 272823 2014-10-09 15:16:52Z marcel - */ - --#define TARGET_FREEBSD_NR_syscall 0 --#define TARGET_FREEBSD_NR_exit 1 --#define TARGET_FREEBSD_NR_fork 2 --#define TARGET_FREEBSD_NR_read 3 --#define TARGET_FREEBSD_NR_write 4 --#define TARGET_FREEBSD_NR_open 5 --#define TARGET_FREEBSD_NR_close 6 --#define TARGET_FREEBSD_NR_wait4 7 -- /* 8 is old creat */ --#define TARGET_FREEBSD_NR_link 9 --#define TARGET_FREEBSD_NR_unlink 10 -- /* 11 is obsolete execv */ --#define TARGET_FREEBSD_NR_chdir 12 --#define TARGET_FREEBSD_NR_fchdir 13 --#define TARGET_FREEBSD_NR_mknod 14 --#define TARGET_FREEBSD_NR_chmod 15 --#define TARGET_FREEBSD_NR_chown 16 --#define TARGET_FREEBSD_NR_break 17 --#define TARGET_FREEBSD_NR_freebsd4_getfsstat 18 -- /* 19 is old lseek */ --#define TARGET_FREEBSD_NR_getpid 20 --#define TARGET_FREEBSD_NR_mount 21 --#define TARGET_FREEBSD_NR_unmount 22 --#define TARGET_FREEBSD_NR_setuid 23 --#define TARGET_FREEBSD_NR_getuid 24 --#define TARGET_FREEBSD_NR_geteuid 25 --#define TARGET_FREEBSD_NR_ptrace 26 --#define TARGET_FREEBSD_NR_recvmsg 27 --#define TARGET_FREEBSD_NR_sendmsg 28 --#define TARGET_FREEBSD_NR_recvfrom 29 --#define TARGET_FREEBSD_NR_accept 30 --#define TARGET_FREEBSD_NR_getpeername 31 --#define TARGET_FREEBSD_NR_getsockname 32 --#define TARGET_FREEBSD_NR_access 33 --#define TARGET_FREEBSD_NR_chflags 34 --#define TARGET_FREEBSD_NR_fchflags 35 --#define TARGET_FREEBSD_NR_sync 36 --#define TARGET_FREEBSD_NR_kill 37 -- /* 38 is old stat */ --#define TARGET_FREEBSD_NR_getppid 39 -- /* 40 is old lstat */ --#define TARGET_FREEBSD_NR_dup 41 --#define TARGET_FREEBSD_NR_pipe 42 --#define TARGET_FREEBSD_NR_getegid 43 --#define TARGET_FREEBSD_NR_profil 44 --#define TARGET_FREEBSD_NR_ktrace 45 -- /* 46 is old sigaction */ --#define TARGET_FREEBSD_NR_getgid 47 -- /* 48 is old sigprocmask */ --#define TARGET_FREEBSD_NR_getlogin 49 --#define TARGET_FREEBSD_NR_setlogin 50 --#define TARGET_FREEBSD_NR_acct 51 -- /* 52 is old sigpending */ --#define TARGET_FREEBSD_NR_sigaltstack 53 --#define TARGET_FREEBSD_NR_ioctl 54 --#define TARGET_FREEBSD_NR_reboot 55 --#define TARGET_FREEBSD_NR_revoke 56 --#define TARGET_FREEBSD_NR_symlink 57 --#define TARGET_FREEBSD_NR_readlink 58 --#define TARGET_FREEBSD_NR_execve 59 --#define TARGET_FREEBSD_NR_umask 60 --#define TARGET_FREEBSD_NR_chroot 61 -- /* 62 is old fstat */ -- /* 63 is old getkerninfo */ -- /* 64 is old getpagesize */ --#define TARGET_FREEBSD_NR_msync 65 --#define TARGET_FREEBSD_NR_vfork 66 -- /* 67 is obsolete vread */ -- /* 68 is obsolete vwrite */ --#define TARGET_FREEBSD_NR_sbrk 69 --#define TARGET_FREEBSD_NR_sstk 70 -- /* 71 is old mmap */ --#define TARGET_FREEBSD_NR_vadvise 72 --#define TARGET_FREEBSD_NR_munmap 73 --#define TARGET_FREEBSD_NR_mprotect 74 --#define TARGET_FREEBSD_NR_madvise 75 -- /* 76 is obsolete vhangup */ -- /* 77 is obsolete vlimit */ --#define TARGET_FREEBSD_NR_mincore 78 --#define TARGET_FREEBSD_NR_getgroups 79 --#define TARGET_FREEBSD_NR_setgroups 80 --#define TARGET_FREEBSD_NR_getpgrp 81 --#define TARGET_FREEBSD_NR_setpgid 82 --#define TARGET_FREEBSD_NR_setitimer 83 -- /* 84 is old wait */ --#define TARGET_FREEBSD_NR_swapon 85 --#define TARGET_FREEBSD_NR_getitimer 86 -- /* 87 is old gethostname */ -- /* 88 is old sethostname */ --#define TARGET_FREEBSD_NR_getdtablesize 89 --#define TARGET_FREEBSD_NR_dup2 90 --#define TARGET_FREEBSD_NR_fcntl 92 --#define TARGET_FREEBSD_NR_select 93 --#define TARGET_FREEBSD_NR_fsync 95 --#define TARGET_FREEBSD_NR_setpriority 96 --#define TARGET_FREEBSD_NR_socket 97 --#define TARGET_FREEBSD_NR_connect 98 -- /* 99 is old accept */ --#define TARGET_FREEBSD_NR_getpriority 100 -- /* 101 is old send */ -- /* 102 is old recv */ -- /* 103 is old sigreturn */ --#define TARGET_FREEBSD_NR_bind 104 --#define TARGET_FREEBSD_NR_setsockopt 105 --#define TARGET_FREEBSD_NR_listen 106 -- /* 107 is obsolete vtimes */ -- /* 108 is old sigvec */ -- /* 109 is old sigblock */ -- /* 110 is old sigsetmask */ -- /* 111 is old sigsuspend */ -- /* 112 is old sigstack */ -- /* 113 is old recvmsg */ -- /* 114 is old sendmsg */ -- /* 115 is obsolete vtrace */ --#define TARGET_FREEBSD_NR_gettimeofday 116 --#define TARGET_FREEBSD_NR_getrusage 117 --#define TARGET_FREEBSD_NR_getsockopt 118 --#define TARGET_FREEBSD_NR_readv 120 --#define TARGET_FREEBSD_NR_writev 121 --#define TARGET_FREEBSD_NR_settimeofday 122 --#define TARGET_FREEBSD_NR_fchown 123 --#define TARGET_FREEBSD_NR_fchmod 124 -- /* 125 is old recvfrom */ --#define TARGET_FREEBSD_NR_setreuid 126 --#define TARGET_FREEBSD_NR_setregid 127 --#define TARGET_FREEBSD_NR_rename 128 -- /* 129 is old truncate */ -- /* 130 is old ftruncate */ --#define TARGET_FREEBSD_NR_flock 131 --#define TARGET_FREEBSD_NR_mkfifo 132 --#define TARGET_FREEBSD_NR_sendto 133 --#define TARGET_FREEBSD_NR_shutdown 134 --#define TARGET_FREEBSD_NR_socketpair 135 --#define TARGET_FREEBSD_NR_mkdir 136 --#define TARGET_FREEBSD_NR_rmdir 137 --#define TARGET_FREEBSD_NR_utimes 138 -- /* 139 is obsolete 4.2 sigreturn */ --#define TARGET_FREEBSD_NR_adjtime 140 -- /* 141 is old getpeername */ -- /* 142 is old gethostid */ -- /* 143 is old sethostid */ -- /* 144 is old getrlimit */ -- /* 145 is old setrlimit */ -- /* 146 is old killpg */ --#define TARGET_FREEBSD_NR_killpg 146 /* COMPAT */ --#define TARGET_FREEBSD_NR_setsid 147 --#define TARGET_FREEBSD_NR_quotactl 148 -- /* 149 is old quota */ -- /* 150 is old getsockname */ --#define TARGET_FREEBSD_NR_nlm_syscall 154 --#define TARGET_FREEBSD_NR_nfssvc 155 -- /* 156 is old getdirentries */ --#define TARGET_FREEBSD_NR_freebsd4_statfs 157 --#define TARGET_FREEBSD_NR_freebsd4_fstatfs 158 --#define TARGET_FREEBSD_NR_lgetfh 160 --#define TARGET_FREEBSD_NR_getfh 161 --#define TARGET_FREEBSD_NR_freebsd4_getdomainname 162 --#define TARGET_FREEBSD_NR_freebsd4_setdomainname 163 --#define TARGET_FREEBSD_NR_freebsd4_uname 164 --#define TARGET_FREEBSD_NR_sysarch 165 --#define TARGET_FREEBSD_NR_rtprio 166 --#define TARGET_FREEBSD_NR_semsys 169 --#define TARGET_FREEBSD_NR_msgsys 170 --#define TARGET_FREEBSD_NR_shmsys 171 --#define TARGET_FREEBSD_NR_freebsd6_pread 173 --#define TARGET_FREEBSD_NR_freebsd6_pwrite 174 --#define TARGET_FREEBSD_NR_setfib 175 --#define TARGET_FREEBSD_NR_ntp_adjtime 176 --#define TARGET_FREEBSD_NR_setgid 181 --#define TARGET_FREEBSD_NR_setegid 182 --#define TARGET_FREEBSD_NR_seteuid 183 --#define TARGET_FREEBSD_NR_stat 188 --#define TARGET_FREEBSD_NR_fstat 189 --#define TARGET_FREEBSD_NR_lstat 190 --#define TARGET_FREEBSD_NR_pathconf 191 --#define TARGET_FREEBSD_NR_fpathconf 192 --#define TARGET_FREEBSD_NR_getrlimit 194 --#define TARGET_FREEBSD_NR_setrlimit 195 --#define TARGET_FREEBSD_NR_getdirentries 196 --#define TARGET_FREEBSD_NR_freebsd6_mmap 197 --#define TARGET_FREEBSD_NR___syscall 198 --#define TARGET_FREEBSD_NR_freebsd6_lseek 199 --#define TARGET_FREEBSD_NR_freebsd6_truncate 200 --#define TARGET_FREEBSD_NR_freebsd6_ftruncate 201 --#define TARGET_FREEBSD_NR___sysctl 202 --#define TARGET_FREEBSD_NR_mlock 203 --#define TARGET_FREEBSD_NR_munlock 204 --#define TARGET_FREEBSD_NR_undelete 205 --#define TARGET_FREEBSD_NR_futimes 206 --#define TARGET_FREEBSD_NR_getpgid 207 --#define TARGET_FREEBSD_NR_poll 209 --#define TARGET_FREEBSD_NR_freebsd7___semctl 220 --#define TARGET_FREEBSD_NR_semget 221 --#define TARGET_FREEBSD_NR_semop 222 --#define TARGET_FREEBSD_NR_freebsd7_msgctl 224 --#define TARGET_FREEBSD_NR_msgget 225 --#define TARGET_FREEBSD_NR_msgsnd 226 --#define TARGET_FREEBSD_NR_msgrcv 227 --#define TARGET_FREEBSD_NR_shmat 228 --#define TARGET_FREEBSD_NR_freebsd7_shmctl 229 --#define TARGET_FREEBSD_NR_shmdt 230 --#define TARGET_FREEBSD_NR_shmget 231 --#define TARGET_FREEBSD_NR_clock_gettime 232 --#define TARGET_FREEBSD_NR_clock_settime 233 --#define TARGET_FREEBSD_NR_clock_getres 234 --#define TARGET_FREEBSD_NR_ktimer_create 235 --#define TARGET_FREEBSD_NR_ktimer_delete 236 --#define TARGET_FREEBSD_NR_ktimer_settime 237 --#define TARGET_FREEBSD_NR_ktimer_gettime 238 --#define TARGET_FREEBSD_NR_ktimer_getoverrun 239 --#define TARGET_FREEBSD_NR_nanosleep 240 --#define TARGET_FREEBSD_NR_ntp_gettime 248 --#define TARGET_FREEBSD_NR_minherit 250 --#define TARGET_FREEBSD_NR_rfork 251 --#define TARGET_FREEBSD_NR_openbsd_poll 252 --#define TARGET_FREEBSD_NR_issetugid 253 --#define TARGET_FREEBSD_NR_lchown 254 --#define TARGET_FREEBSD_NR_aio_read 255 --#define TARGET_FREEBSD_NR_aio_write 256 --#define TARGET_FREEBSD_NR_lio_listio 257 --#define TARGET_FREEBSD_NR_getdents 272 --#define TARGET_FREEBSD_NR_lchmod 274 --#define TARGET_FREEBSD_NR_netbsd_lchown 275 --#define TARGET_FREEBSD_NR_lutimes 276 --#define TARGET_FREEBSD_NR_netbsd_msync 277 --#define TARGET_FREEBSD_NR_nstat 278 --#define TARGET_FREEBSD_NR_nfstat 279 --#define TARGET_FREEBSD_NR_nlstat 280 --#define TARGET_FREEBSD_NR_preadv 289 --#define TARGET_FREEBSD_NR_pwritev 290 --#define TARGET_FREEBSD_NR_freebsd4_fhstatfs 297 --#define TARGET_FREEBSD_NR_fhopen 298 --#define TARGET_FREEBSD_NR_fhstat 299 --#define TARGET_FREEBSD_NR_modnext 300 --#define TARGET_FREEBSD_NR_modstat 301 --#define TARGET_FREEBSD_NR_modfnext 302 --#define TARGET_FREEBSD_NR_modfind 303 --#define TARGET_FREEBSD_NR_kldload 304 --#define TARGET_FREEBSD_NR_kldunload 305 --#define TARGET_FREEBSD_NR_kldfind 306 --#define TARGET_FREEBSD_NR_kldnext 307 --#define TARGET_FREEBSD_NR_kldstat 308 --#define TARGET_FREEBSD_NR_kldfirstmod 309 --#define TARGET_FREEBSD_NR_getsid 310 --#define TARGET_FREEBSD_NR_setresuid 311 --#define TARGET_FREEBSD_NR_setresgid 312 -- /* 313 is obsolete signanosleep */ --#define TARGET_FREEBSD_NR_aio_return 314 --#define TARGET_FREEBSD_NR_aio_suspend 315 --#define TARGET_FREEBSD_NR_aio_cancel 316 --#define TARGET_FREEBSD_NR_aio_error 317 --#define TARGET_FREEBSD_NR_oaio_read 318 --#define TARGET_FREEBSD_NR_oaio_write 319 --#define TARGET_FREEBSD_NR_olio_listio 320 --#define TARGET_FREEBSD_NR_yield 321 -- /* 322 is obsolete thr_sleep */ -- /* 323 is obsolete thr_wakeup */ --#define TARGET_FREEBSD_NR_mlockall 324 --#define TARGET_FREEBSD_NR_munlockall 325 --#define TARGET_FREEBSD_NR___getcwd 326 --#define TARGET_FREEBSD_NR_sched_setparam 327 --#define TARGET_FREEBSD_NR_sched_getparam 328 --#define TARGET_FREEBSD_NR_sched_setscheduler 329 --#define TARGET_FREEBSD_NR_sched_getscheduler 330 --#define TARGET_FREEBSD_NR_sched_yield 331 --#define TARGET_FREEBSD_NR_sched_get_priority_max 332 --#define TARGET_FREEBSD_NR_sched_get_priority_min 333 --#define TARGET_FREEBSD_NR_sched_rr_get_interval 334 --#define TARGET_FREEBSD_NR_utrace 335 --#define TARGET_FREEBSD_NR_freebsd4_sendfile 336 --#define TARGET_FREEBSD_NR_kldsym 337 --#define TARGET_FREEBSD_NR_jail 338 --#define TARGET_FREEBSD_NR_nnpfs_syscall 339 --#define TARGET_FREEBSD_NR_sigprocmask 340 --#define TARGET_FREEBSD_NR_sigsuspend 341 --#define TARGET_FREEBSD_NR_freebsd4_sigaction 342 --#define TARGET_FREEBSD_NR_sigpending 343 --#define TARGET_FREEBSD_NR_freebsd4_sigreturn 344 --#define TARGET_FREEBSD_NR_sigtimedwait 345 --#define TARGET_FREEBSD_NR_sigwaitinfo 346 --#define TARGET_FREEBSD_NR___acl_get_file 347 --#define TARGET_FREEBSD_NR___acl_set_file 348 --#define TARGET_FREEBSD_NR___acl_get_fd 349 --#define TARGET_FREEBSD_NR___acl_set_fd 350 --#define TARGET_FREEBSD_NR___acl_delete_file 351 --#define TARGET_FREEBSD_NR___acl_delete_fd 352 --#define TARGET_FREEBSD_NR___acl_aclcheck_file 353 --#define TARGET_FREEBSD_NR___acl_aclcheck_fd 354 --#define TARGET_FREEBSD_NR_extattrctl 355 --#define TARGET_FREEBSD_NR_extattr_set_file 356 --#define TARGET_FREEBSD_NR_extattr_get_file 357 --#define TARGET_FREEBSD_NR_extattr_delete_file 358 --#define TARGET_FREEBSD_NR_aio_waitcomplete 359 --#define TARGET_FREEBSD_NR_getresuid 360 --#define TARGET_FREEBSD_NR_getresgid 361 --#define TARGET_FREEBSD_NR_kqueue 362 --#define TARGET_FREEBSD_NR_kevent 363 --#define TARGET_FREEBSD_NR_extattr_set_fd 371 --#define TARGET_FREEBSD_NR_extattr_get_fd 372 --#define TARGET_FREEBSD_NR_extattr_delete_fd 373 --#define TARGET_FREEBSD_NR___setugid 374 --#define TARGET_FREEBSD_NR_eaccess 376 --#define TARGET_FREEBSD_NR_afs3_syscall 377 --#define TARGET_FREEBSD_NR_nmount 378 --#define TARGET_FREEBSD_NR___mac_get_proc 384 --#define TARGET_FREEBSD_NR___mac_set_proc 385 --#define TARGET_FREEBSD_NR___mac_get_fd 386 --#define TARGET_FREEBSD_NR___mac_get_file 387 --#define TARGET_FREEBSD_NR___mac_set_fd 388 --#define TARGET_FREEBSD_NR___mac_set_file 389 --#define TARGET_FREEBSD_NR_kenv 390 --#define TARGET_FREEBSD_NR_lchflags 391 --#define TARGET_FREEBSD_NR_uuidgen 392 --#define TARGET_FREEBSD_NR_sendfile 393 --#define TARGET_FREEBSD_NR_mac_syscall 394 --#define TARGET_FREEBSD_NR_getfsstat 395 --#define TARGET_FREEBSD_NR_statfs 396 --#define TARGET_FREEBSD_NR_fstatfs 397 --#define TARGET_FREEBSD_NR_fhstatfs 398 --#define TARGET_FREEBSD_NR_ksem_close 400 --#define TARGET_FREEBSD_NR_ksem_post 401 --#define TARGET_FREEBSD_NR_ksem_wait 402 --#define TARGET_FREEBSD_NR_ksem_trywait 403 --#define TARGET_FREEBSD_NR_ksem_init 404 --#define TARGET_FREEBSD_NR_ksem_open 405 --#define TARGET_FREEBSD_NR_ksem_unlink 406 --#define TARGET_FREEBSD_NR_ksem_getvalue 407 --#define TARGET_FREEBSD_NR_ksem_destroy 408 --#define TARGET_FREEBSD_NR___mac_get_pid 409 --#define TARGET_FREEBSD_NR___mac_get_link 410 --#define TARGET_FREEBSD_NR___mac_set_link 411 --#define TARGET_FREEBSD_NR_extattr_set_link 412 --#define TARGET_FREEBSD_NR_extattr_get_link 413 --#define TARGET_FREEBSD_NR_extattr_delete_link 414 --#define TARGET_FREEBSD_NR___mac_execve 415 --#define TARGET_FREEBSD_NR_sigaction 416 --#define TARGET_FREEBSD_NR_sigreturn 417 --#define TARGET_FREEBSD_NR_getcontext 421 --#define TARGET_FREEBSD_NR_setcontext 422 --#define TARGET_FREEBSD_NR_swapcontext 423 --#define TARGET_FREEBSD_NR_swapoff 424 --#define TARGET_FREEBSD_NR___acl_get_link 425 --#define TARGET_FREEBSD_NR___acl_set_link 426 --#define TARGET_FREEBSD_NR___acl_delete_link 427 --#define TARGET_FREEBSD_NR___acl_aclcheck_link 428 --#define TARGET_FREEBSD_NR_sigwait 429 --#define TARGET_FREEBSD_NR_thr_create 430 --#define TARGET_FREEBSD_NR_thr_exit 431 --#define TARGET_FREEBSD_NR_thr_self 432 --#define TARGET_FREEBSD_NR_thr_kill 433 --#define TARGET_FREEBSD_NR__umtx_lock 434 --#define TARGET_FREEBSD_NR__umtx_unlock 435 --#define TARGET_FREEBSD_NR_jail_attach 436 --#define TARGET_FREEBSD_NR_extattr_list_fd 437 --#define TARGET_FREEBSD_NR_extattr_list_file 438 --#define TARGET_FREEBSD_NR_extattr_list_link 439 --#define TARGET_FREEBSD_NR_ksem_timedwait 441 --#define TARGET_FREEBSD_NR_thr_suspend 442 --#define TARGET_FREEBSD_NR_thr_wake 443 --#define TARGET_FREEBSD_NR_kldunloadf 444 --#define TARGET_FREEBSD_NR_audit 445 --#define TARGET_FREEBSD_NR_auditon 446 --#define TARGET_FREEBSD_NR_getauid 447 --#define TARGET_FREEBSD_NR_setauid 448 --#define TARGET_FREEBSD_NR_getaudit 449 --#define TARGET_FREEBSD_NR_setaudit 450 --#define TARGET_FREEBSD_NR_getaudit_addr 451 --#define TARGET_FREEBSD_NR_setaudit_addr 452 --#define TARGET_FREEBSD_NR_auditctl 453 --#define TARGET_FREEBSD_NR__umtx_op 454 --#define TARGET_FREEBSD_NR_thr_new 455 --#define TARGET_FREEBSD_NR_sigqueue 456 --#define TARGET_FREEBSD_NR_kmq_open 457 --#define TARGET_FREEBSD_NR_kmq_setattr 458 --#define TARGET_FREEBSD_NR_kmq_timedreceive 459 --#define TARGET_FREEBSD_NR_kmq_timedsend 460 --#define TARGET_FREEBSD_NR_kmq_notify 461 --#define TARGET_FREEBSD_NR_kmq_unlink 462 --#define TARGET_FREEBSD_NR_abort2 463 --#define TARGET_FREEBSD_NR_thr_set_name 464 --#define TARGET_FREEBSD_NR_aio_fsync 465 --#define TARGET_FREEBSD_NR_rtprio_thread 466 --#define TARGET_FREEBSD_NR_sctp_peeloff 471 --#define TARGET_FREEBSD_NR_sctp_generic_sendmsg 472 --#define TARGET_FREEBSD_NR_sctp_generic_sendmsg_iov 473 --#define TARGET_FREEBSD_NR_sctp_generic_recvmsg 474 --#define TARGET_FREEBSD_NR_pread 475 --#define TARGET_FREEBSD_NR_pwrite 476 --#define TARGET_FREEBSD_NR_mmap 477 --#define TARGET_FREEBSD_NR_lseek 478 --#define TARGET_FREEBSD_NR_truncate 479 --#define TARGET_FREEBSD_NR_ftruncate 480 --#define TARGET_FREEBSD_NR_thr_kill2 481 --#define TARGET_FREEBSD_NR_shm_open 482 --#define TARGET_FREEBSD_NR_shm_unlink 483 --#define TARGET_FREEBSD_NR_cpuset 484 --#define TARGET_FREEBSD_NR_cpuset_setid 485 --#define TARGET_FREEBSD_NR_cpuset_getid 486 --#define TARGET_FREEBSD_NR_cpuset_getaffinity 487 --#define TARGET_FREEBSD_NR_cpuset_setaffinity 488 --#define TARGET_FREEBSD_NR_faccessat 489 --#define TARGET_FREEBSD_NR_fchmodat 490 --#define TARGET_FREEBSD_NR_fchownat 491 --#define TARGET_FREEBSD_NR_fexecve 492 --#define TARGET_FREEBSD_NR_fstatat 493 --#define TARGET_FREEBSD_NR_futimesat 494 --#define TARGET_FREEBSD_NR_linkat 495 --#define TARGET_FREEBSD_NR_mkdirat 496 --#define TARGET_FREEBSD_NR_mkfifoat 497 --#define TARGET_FREEBSD_NR_mknodat 498 --#define TARGET_FREEBSD_NR_openat 499 --#define TARGET_FREEBSD_NR_readlinkat 500 --#define TARGET_FREEBSD_NR_renameat 501 --#define TARGET_FREEBSD_NR_symlinkat 502 --#define TARGET_FREEBSD_NR_unlinkat 503 --#define TARGET_FREEBSD_NR_posix_openpt 504 --#define TARGET_FREEBSD_NR_gssd_syscall 505 --#define TARGET_FREEBSD_NR_jail_get 506 --#define TARGET_FREEBSD_NR_jail_set 507 --#define TARGET_FREEBSD_NR_jail_remove 508 --#define TARGET_FREEBSD_NR_closefrom 509 --#define TARGET_FREEBSD_NR___semctl 510 --#define TARGET_FREEBSD_NR_msgctl 511 --#define TARGET_FREEBSD_NR_shmctl 512 --#define TARGET_FREEBSD_NR_lpathconf 513 --#define TARGET_FREEBSD_NR_cap_new 514 --#define TARGET_FREEBSD_NR_cap_getrights 515 --#define TARGET_FREEBSD_NR_cap_enter 516 --#define TARGET_FREEBSD_NR_cap_getmode 517 --#define TARGET_FREEBSD_NR_pdfork 518 --#define TARGET_FREEBSD_NR_pdkill 519 --#define TARGET_FREEBSD_NR_pdgetpid 520 --#define TARGET_FREEBSD_NR_pselect 522 --#define TARGET_FREEBSD_NR_getloginclass 523 --#define TARGET_FREEBSD_NR_setloginclass 524 --#define TARGET_FREEBSD_NR_rctl_get_racct 525 --#define TARGET_FREEBSD_NR_rctl_get_rules 526 --#define TARGET_FREEBSD_NR_rctl_get_limits 527 --#define TARGET_FREEBSD_NR_rctl_add_rule 528 --#define TARGET_FREEBSD_NR_rctl_remove_rule 529 --#define TARGET_FREEBSD_NR_posix_fallocate 530 --#define TARGET_FREEBSD_NR_posix_fadvise 531 --#define TARGET_FREEBSD_NR_wait6 532 --#define TARGET_FREEBSD_NR_cap_rights_limit 533 --#define TARGET_FREEBSD_NR_cap_ioctls_limit 534 --#define TARGET_FREEBSD_NR_cap_ioctls_get 535 --#define TARGET_FREEBSD_NR_cap_fcntls_limit 536 --#define TARGET_FREEBSD_NR_cap_fcntls_get 537 --#define TARGET_FREEBSD_NR_bindat 538 --#define TARGET_FREEBSD_NR_connectat 539 --#define TARGET_FREEBSD_NR_chflagsat 540 --#define TARGET_FREEBSD_NR_accept4 541 --#define TARGET_FREEBSD_NR_pipe2 542 -+#define TARGET_FREEBSD_NR_syscall 0 -+#define TARGET_FREEBSD_NR_exit 1 -+#define TARGET_FREEBSD_NR_fork 2 -+#define TARGET_FREEBSD_NR_read 3 -+#define TARGET_FREEBSD_NR_write 4 -+#define TARGET_FREEBSD_NR_open 5 -+#define TARGET_FREEBSD_NR_close 6 -+#define TARGET_FREEBSD_NR_wait4 7 -+ /* 8 is old creat */ -+#define TARGET_FREEBSD_NR_link 9 -+#define TARGET_FREEBSD_NR_unlink 10 -+ /* 11 is obsolete execv */ -+#define TARGET_FREEBSD_NR_chdir 12 -+#define TARGET_FREEBSD_NR_fchdir 13 -+#define TARGET_FREEBSD_NR_mknod 14 -+#define TARGET_FREEBSD_NR_chmod 15 -+#define TARGET_FREEBSD_NR_chown 16 -+#define TARGET_FREEBSD_NR_break 17 -+#define TARGET_FREEBSD_NR_freebsd4_getfsstat 18 -+ /* 19 is old lseek */ -+#define TARGET_FREEBSD_NR_getpid 20 -+#define TARGET_FREEBSD_NR_mount 21 -+#define TARGET_FREEBSD_NR_unmount 22 -+#define TARGET_FREEBSD_NR_setuid 23 -+#define TARGET_FREEBSD_NR_getuid 24 -+#define TARGET_FREEBSD_NR_geteuid 25 -+#define TARGET_FREEBSD_NR_ptrace 26 -+#define TARGET_FREEBSD_NR_recvmsg 27 -+#define TARGET_FREEBSD_NR_sendmsg 28 -+#define TARGET_FREEBSD_NR_recvfrom 29 -+#define TARGET_FREEBSD_NR_accept 30 -+#define TARGET_FREEBSD_NR_getpeername 31 -+#define TARGET_FREEBSD_NR_getsockname 32 -+#define TARGET_FREEBSD_NR_access 33 -+#define TARGET_FREEBSD_NR_chflags 34 -+#define TARGET_FREEBSD_NR_fchflags 35 -+#define TARGET_FREEBSD_NR_sync 36 -+#define TARGET_FREEBSD_NR_kill 37 -+ /* 38 is old stat */ -+#define TARGET_FREEBSD_NR_getppid 39 -+ /* 40 is old lstat */ -+#define TARGET_FREEBSD_NR_dup 41 -+#define TARGET_FREEBSD_NR_pipe 42 -+#define TARGET_FREEBSD_NR_getegid 43 -+#define TARGET_FREEBSD_NR_profil 44 -+#define TARGET_FREEBSD_NR_ktrace 45 -+ /* 46 is old sigaction */ -+#define TARGET_FREEBSD_NR_getgid 47 -+ /* 48 is old sigprocmask */ -+#define TARGET_FREEBSD_NR_getlogin 49 -+#define TARGET_FREEBSD_NR_setlogin 50 -+#define TARGET_FREEBSD_NR_acct 51 -+ /* 52 is old sigpending */ -+#define TARGET_FREEBSD_NR_sigaltstack 53 -+#define TARGET_FREEBSD_NR_ioctl 54 -+#define TARGET_FREEBSD_NR_reboot 55 -+#define TARGET_FREEBSD_NR_revoke 56 -+#define TARGET_FREEBSD_NR_symlink 57 -+#define TARGET_FREEBSD_NR_readlink 58 -+#define TARGET_FREEBSD_NR_execve 59 -+#define TARGET_FREEBSD_NR_umask 60 -+#define TARGET_FREEBSD_NR_chroot 61 -+ /* 62 is old fstat */ -+ /* 63 is old getkerninfo */ -+ /* 64 is old getpagesize */ -+#define TARGET_FREEBSD_NR_msync 65 -+#define TARGET_FREEBSD_NR_vfork 66 -+ /* 67 is obsolete vread */ -+ /* 68 is obsolete vwrite */ -+#define TARGET_FREEBSD_NR_sbrk 69 -+#define TARGET_FREEBSD_NR_sstk 70 -+ /* 71 is old mmap */ -+#define TARGET_FREEBSD_NR_vadvise 72 -+#define TARGET_FREEBSD_NR_munmap 73 -+#define TARGET_FREEBSD_NR_mprotect 74 -+#define TARGET_FREEBSD_NR_madvise 75 -+ /* 76 is obsolete vhangup */ -+ /* 77 is obsolete vlimit */ -+#define TARGET_FREEBSD_NR_mincore 78 -+#define TARGET_FREEBSD_NR_getgroups 79 -+#define TARGET_FREEBSD_NR_setgroups 80 -+#define TARGET_FREEBSD_NR_getpgrp 81 -+#define TARGET_FREEBSD_NR_setpgid 82 -+#define TARGET_FREEBSD_NR_setitimer 83 -+ /* 84 is old wait */ -+#define TARGET_FREEBSD_NR_swapon 85 -+#define TARGET_FREEBSD_NR_getitimer 86 -+ /* 87 is old gethostname */ -+ /* 88 is old sethostname */ -+#define TARGET_FREEBSD_NR_getdtablesize 89 -+#define TARGET_FREEBSD_NR_dup2 90 -+#define TARGET_FREEBSD_NR_fcntl 92 -+#define TARGET_FREEBSD_NR_select 93 -+#define TARGET_FREEBSD_NR_fsync 95 -+#define TARGET_FREEBSD_NR_setpriority 96 -+#define TARGET_FREEBSD_NR_socket 97 -+#define TARGET_FREEBSD_NR_connect 98 -+ /* 99 is old accept */ -+#define TARGET_FREEBSD_NR_getpriority 100 -+ /* 101 is old send */ -+ /* 102 is old recv */ -+ /* 103 is old sigreturn */ -+#define TARGET_FREEBSD_NR_bind 104 -+#define TARGET_FREEBSD_NR_setsockopt 105 -+#define TARGET_FREEBSD_NR_listen 106 -+ /* 107 is obsolete vtimes */ -+ /* 108 is old sigvec */ -+ /* 109 is old sigblock */ -+ /* 110 is old sigsetmask */ -+ /* 111 is old sigsuspend */ -+ /* 112 is old sigstack */ -+ /* 113 is old recvmsg */ -+ /* 114 is old sendmsg */ -+ /* 115 is obsolete vtrace */ -+#define TARGET_FREEBSD_NR_gettimeofday 116 -+#define TARGET_FREEBSD_NR_getrusage 117 -+#define TARGET_FREEBSD_NR_getsockopt 118 -+#define TARGET_FREEBSD_NR_readv 120 -+#define TARGET_FREEBSD_NR_writev 121 -+#define TARGET_FREEBSD_NR_settimeofday 122 -+#define TARGET_FREEBSD_NR_fchown 123 -+#define TARGET_FREEBSD_NR_fchmod 124 -+ /* 125 is old recvfrom */ -+#define TARGET_FREEBSD_NR_setreuid 126 -+#define TARGET_FREEBSD_NR_setregid 127 -+#define TARGET_FREEBSD_NR_rename 128 -+ /* 129 is old truncate */ -+ /* 130 is old ftruncate */ -+#define TARGET_FREEBSD_NR_flock 131 -+#define TARGET_FREEBSD_NR_mkfifo 132 -+#define TARGET_FREEBSD_NR_sendto 133 -+#define TARGET_FREEBSD_NR_shutdown 134 -+#define TARGET_FREEBSD_NR_socketpair 135 -+#define TARGET_FREEBSD_NR_mkdir 136 -+#define TARGET_FREEBSD_NR_rmdir 137 -+#define TARGET_FREEBSD_NR_utimes 138 -+ /* 139 is obsolete 4.2 sigreturn */ -+#define TARGET_FREEBSD_NR_adjtime 140 -+ /* 141 is old getpeername */ -+ /* 142 is old gethostid */ -+ /* 143 is old sethostid */ -+ /* 144 is old getrlimit */ -+ /* 145 is old setrlimit */ -+ /* 146 is old killpg */ -+#define TARGET_FREEBSD_NR_setsid 147 -+#define TARGET_FREEBSD_NR_quotactl 148 -+ /* 149 is old quota */ -+ /* 150 is old getsockname */ -+#define TARGET_FREEBSD_NR_nlm_syscall 154 -+#define TARGET_FREEBSD_NR_nfssvc 155 -+ /* 156 is old getdirentries */ -+#define TARGET_FREEBSD_NR_freebsd4_statfs 157 -+#define TARGET_FREEBSD_NR_freebsd4_fstatfs 158 -+#define TARGET_FREEBSD_NR_lgetfh 160 -+#define TARGET_FREEBSD_NR_getfh 161 -+#define TARGET_FREEBSD_NR_freebsd4_getdomainname 162 -+#define TARGET_FREEBSD_NR_freebsd4_setdomainname 163 -+#define TARGET_FREEBSD_NR_freebsd4_uname 164 -+#define TARGET_FREEBSD_NR_sysarch 165 -+#define TARGET_FREEBSD_NR_rtprio 166 -+#define TARGET_FREEBSD_NR_semsys 169 -+#define TARGET_FREEBSD_NR_msgsys 170 -+#define TARGET_FREEBSD_NR_shmsys 171 -+#define TARGET_FREEBSD_NR_freebsd6_pread 173 -+#define TARGET_FREEBSD_NR_freebsd6_pwrite 174 -+#define TARGET_FREEBSD_NR_setfib 175 -+#define TARGET_FREEBSD_NR_ntp_adjtime 176 -+#define TARGET_FREEBSD_NR_setgid 181 -+#define TARGET_FREEBSD_NR_setegid 182 -+#define TARGET_FREEBSD_NR_seteuid 183 -+#define TARGET_FREEBSD_NR_stat 188 -+#define TARGET_FREEBSD_NR_fstat 189 -+#define TARGET_FREEBSD_NR_lstat 190 -+#define TARGET_FREEBSD_NR_pathconf 191 -+#define TARGET_FREEBSD_NR_fpathconf 192 -+#define TARGET_FREEBSD_NR_getrlimit 194 -+#define TARGET_FREEBSD_NR_setrlimit 195 -+#define TARGET_FREEBSD_NR_getdirentries 196 -+#define TARGET_FREEBSD_NR_freebsd6_mmap 197 -+#define TARGET_FREEBSD_NR___syscall 198 -+#define TARGET_FREEBSD_NR_freebsd6_lseek 199 -+#define TARGET_FREEBSD_NR_freebsd6_truncate 200 -+#define TARGET_FREEBSD_NR_freebsd6_ftruncate 201 -+#define TARGET_FREEBSD_NR___sysctl 202 -+#define TARGET_FREEBSD_NR_mlock 203 -+#define TARGET_FREEBSD_NR_munlock 204 -+#define TARGET_FREEBSD_NR_undelete 205 -+#define TARGET_FREEBSD_NR_futimes 206 -+#define TARGET_FREEBSD_NR_getpgid 207 -+#define TARGET_FREEBSD_NR_poll 209 -+#define TARGET_FREEBSD_NR_freebsd7___semctl 220 -+#define TARGET_FREEBSD_NR_semget 221 -+#define TARGET_FREEBSD_NR_semop 222 -+#define TARGET_FREEBSD_NR_freebsd7_msgctl 224 -+#define TARGET_FREEBSD_NR_msgget 225 -+#define TARGET_FREEBSD_NR_msgsnd 226 -+#define TARGET_FREEBSD_NR_msgrcv 227 -+#define TARGET_FREEBSD_NR_shmat 228 -+#define TARGET_FREEBSD_NR_freebsd7_shmctl 229 -+#define TARGET_FREEBSD_NR_shmdt 230 -+#define TARGET_FREEBSD_NR_shmget 231 -+#define TARGET_FREEBSD_NR_clock_gettime 232 -+#define TARGET_FREEBSD_NR_clock_settime 233 -+#define TARGET_FREEBSD_NR_clock_getres 234 -+#define TARGET_FREEBSD_NR_ktimer_create 235 -+#define TARGET_FREEBSD_NR_ktimer_delete 236 -+#define TARGET_FREEBSD_NR_ktimer_settime 237 -+#define TARGET_FREEBSD_NR_ktimer_gettime 238 -+#define TARGET_FREEBSD_NR_ktimer_getoverrun 239 -+#define TARGET_FREEBSD_NR_nanosleep 240 -+#define TARGET_FREEBSD_NR_ffclock_getcounter 241 -+#define TARGET_FREEBSD_NR_ffclock_setestimate 242 -+#define TARGET_FREEBSD_NR_ffclock_getestimate 243 -+#define TARGET_FREEBSD_NR_clock_getcpuclockid2 247 -+#define TARGET_FREEBSD_NR_ntp_gettime 248 -+#define TARGET_FREEBSD_NR_minherit 250 -+#define TARGET_FREEBSD_NR_rfork 251 -+#define TARGET_FREEBSD_NR_openbsd_poll 252 -+#define TARGET_FREEBSD_NR_issetugid 253 -+#define TARGET_FREEBSD_NR_lchown 254 -+#define TARGET_FREEBSD_NR_aio_read 255 -+#define TARGET_FREEBSD_NR_aio_write 256 -+#define TARGET_FREEBSD_NR_lio_listio 257 -+#define TARGET_FREEBSD_NR_getdents 272 -+#define TARGET_FREEBSD_NR_lchmod 274 -+#define TARGET_FREEBSD_NR_netbsd_lchown 275 -+#define TARGET_FREEBSD_NR_lutimes 276 -+#define TARGET_FREEBSD_NR_netbsd_msync 277 -+#define TARGET_FREEBSD_NR_nstat 278 -+#define TARGET_FREEBSD_NR_nfstat 279 -+#define TARGET_FREEBSD_NR_nlstat 280 -+#define TARGET_FREEBSD_NR_preadv 289 -+#define TARGET_FREEBSD_NR_pwritev 290 -+#define TARGET_FREEBSD_NR_freebsd4_fhstatfs 297 -+#define TARGET_FREEBSD_NR_fhopen 298 -+#define TARGET_FREEBSD_NR_fhstat 299 -+#define TARGET_FREEBSD_NR_modnext 300 -+#define TARGET_FREEBSD_NR_modstat 301 -+#define TARGET_FREEBSD_NR_modfnext 302 -+#define TARGET_FREEBSD_NR_modfind 303 -+#define TARGET_FREEBSD_NR_kldload 304 -+#define TARGET_FREEBSD_NR_kldunload 305 -+#define TARGET_FREEBSD_NR_kldfind 306 -+#define TARGET_FREEBSD_NR_kldnext 307 -+#define TARGET_FREEBSD_NR_kldstat 308 -+#define TARGET_FREEBSD_NR_kldfirstmod 309 -+#define TARGET_FREEBSD_NR_getsid 310 -+#define TARGET_FREEBSD_NR_setresuid 311 -+#define TARGET_FREEBSD_NR_setresgid 312 -+ /* 313 is obsolete signanosleep */ -+#define TARGET_FREEBSD_NR_aio_return 314 -+#define TARGET_FREEBSD_NR_aio_suspend 315 -+#define TARGET_FREEBSD_NR_aio_cancel 316 -+#define TARGET_FREEBSD_NR_aio_error 317 -+#define TARGET_FREEBSD_NR_oaio_read 318 -+#define TARGET_FREEBSD_NR_oaio_write 319 -+#define TARGET_FREEBSD_NR_olio_listio 320 -+#define TARGET_FREEBSD_NR_yield 321 -+ /* 322 is obsolete thr_sleep */ -+ /* 323 is obsolete thr_wakeup */ -+#define TARGET_FREEBSD_NR_mlockall 324 -+#define TARGET_FREEBSD_NR_munlockall 325 -+#define TARGET_FREEBSD_NR___getcwd 326 -+#define TARGET_FREEBSD_NR_sched_setparam 327 -+#define TARGET_FREEBSD_NR_sched_getparam 328 -+#define TARGET_FREEBSD_NR_sched_setscheduler 329 -+#define TARGET_FREEBSD_NR_sched_getscheduler 330 -+#define TARGET_FREEBSD_NR_sched_yield 331 -+#define TARGET_FREEBSD_NR_sched_get_priority_max 332 -+#define TARGET_FREEBSD_NR_sched_get_priority_min 333 -+#define TARGET_FREEBSD_NR_sched_rr_get_interval 334 -+#define TARGET_FREEBSD_NR_utrace 335 -+#define TARGET_FREEBSD_NR_freebsd4_sendfile 336 -+#define TARGET_FREEBSD_NR_kldsym 337 -+#define TARGET_FREEBSD_NR_jail 338 -+#define TARGET_FREEBSD_NR_nnpfs_syscall 339 -+#define TARGET_FREEBSD_NR_sigprocmask 340 -+#define TARGET_FREEBSD_NR_sigsuspend 341 -+#define TARGET_FREEBSD_NR_freebsd4_sigaction 342 -+#define TARGET_FREEBSD_NR_sigpending 343 -+#define TARGET_FREEBSD_NR_freebsd4_sigreturn 344 -+#define TARGET_FREEBSD_NR_sigtimedwait 345 -+#define TARGET_FREEBSD_NR_sigwaitinfo 346 -+#define TARGET_FREEBSD_NR___acl_get_file 347 -+#define TARGET_FREEBSD_NR___acl_set_file 348 -+#define TARGET_FREEBSD_NR___acl_get_fd 349 -+#define TARGET_FREEBSD_NR___acl_set_fd 350 -+#define TARGET_FREEBSD_NR___acl_delete_file 351 -+#define TARGET_FREEBSD_NR___acl_delete_fd 352 -+#define TARGET_FREEBSD_NR___acl_aclcheck_file 353 -+#define TARGET_FREEBSD_NR___acl_aclcheck_fd 354 -+#define TARGET_FREEBSD_NR_extattrctl 355 -+#define TARGET_FREEBSD_NR_extattr_set_file 356 -+#define TARGET_FREEBSD_NR_extattr_get_file 357 -+#define TARGET_FREEBSD_NR_extattr_delete_file 358 -+#define TARGET_FREEBSD_NR_aio_waitcomplete 359 -+#define TARGET_FREEBSD_NR_getresuid 360 -+#define TARGET_FREEBSD_NR_getresgid 361 -+#define TARGET_FREEBSD_NR_kqueue 362 -+#define TARGET_FREEBSD_NR_kevent 363 -+#define TARGET_FREEBSD_NR_extattr_set_fd 371 -+#define TARGET_FREEBSD_NR_extattr_get_fd 372 -+#define TARGET_FREEBSD_NR_extattr_delete_fd 373 -+#define TARGET_FREEBSD_NR___setugid 374 -+#define TARGET_FREEBSD_NR_eaccess 376 -+#define TARGET_FREEBSD_NR_afs3_syscall 377 -+#define TARGET_FREEBSD_NR_nmount 378 -+#define TARGET_FREEBSD_NR___mac_get_proc 384 -+#define TARGET_FREEBSD_NR___mac_set_proc 385 -+#define TARGET_FREEBSD_NR___mac_get_fd 386 -+#define TARGET_FREEBSD_NR___mac_get_file 387 -+#define TARGET_FREEBSD_NR___mac_set_fd 388 -+#define TARGET_FREEBSD_NR___mac_set_file 389 -+#define TARGET_FREEBSD_NR_kenv 390 -+#define TARGET_FREEBSD_NR_lchflags 391 -+#define TARGET_FREEBSD_NR_uuidgen 392 -+#define TARGET_FREEBSD_NR_sendfile 393 -+#define TARGET_FREEBSD_NR_mac_syscall 394 -+#define TARGET_FREEBSD_NR_getfsstat 395 -+#define TARGET_FREEBSD_NR_statfs 396 -+#define TARGET_FREEBSD_NR_fstatfs 397 -+#define TARGET_FREEBSD_NR_fhstatfs 398 -+#define TARGET_FREEBSD_NR_ksem_close 400 -+#define TARGET_FREEBSD_NR_ksem_post 401 -+#define TARGET_FREEBSD_NR_ksem_wait 402 -+#define TARGET_FREEBSD_NR_ksem_trywait 403 -+#define TARGET_FREEBSD_NR_ksem_init 404 -+#define TARGET_FREEBSD_NR_ksem_open 405 -+#define TARGET_FREEBSD_NR_ksem_unlink 406 -+#define TARGET_FREEBSD_NR_ksem_getvalue 407 -+#define TARGET_FREEBSD_NR_ksem_destroy 408 -+#define TARGET_FREEBSD_NR___mac_get_pid 409 -+#define TARGET_FREEBSD_NR___mac_get_link 410 -+#define TARGET_FREEBSD_NR___mac_set_link 411 -+#define TARGET_FREEBSD_NR_extattr_set_link 412 -+#define TARGET_FREEBSD_NR_extattr_get_link 413 -+#define TARGET_FREEBSD_NR_extattr_delete_link 414 -+#define TARGET_FREEBSD_NR___mac_execve 415 -+#define TARGET_FREEBSD_NR_sigaction 416 -+#define TARGET_FREEBSD_NR_sigreturn 417 -+#define TARGET_FREEBSD_NR_getcontext 421 -+#define TARGET_FREEBSD_NR_setcontext 422 -+#define TARGET_FREEBSD_NR_swapcontext 423 -+#define TARGET_FREEBSD_NR_swapoff 424 -+#define TARGET_FREEBSD_NR___acl_get_link 425 -+#define TARGET_FREEBSD_NR___acl_set_link 426 -+#define TARGET_FREEBSD_NR___acl_delete_link 427 -+#define TARGET_FREEBSD_NR___acl_aclcheck_link 428 -+#define TARGET_FREEBSD_NR_sigwait 429 -+#define TARGET_FREEBSD_NR_thr_create 430 -+#define TARGET_FREEBSD_NR_thr_exit 431 -+#define TARGET_FREEBSD_NR_thr_self 432 -+#define TARGET_FREEBSD_NR_thr_kill 433 -+#define TARGET_FREEBSD_NR_jail_attach 436 -+#define TARGET_FREEBSD_NR_extattr_list_fd 437 -+#define TARGET_FREEBSD_NR_extattr_list_file 438 -+#define TARGET_FREEBSD_NR_extattr_list_link 439 -+#define TARGET_FREEBSD_NR_ksem_timedwait 441 -+#define TARGET_FREEBSD_NR_thr_suspend 442 -+#define TARGET_FREEBSD_NR_thr_wake 443 -+#define TARGET_FREEBSD_NR_kldunloadf 444 -+#define TARGET_FREEBSD_NR_audit 445 -+#define TARGET_FREEBSD_NR_auditon 446 -+#define TARGET_FREEBSD_NR_getauid 447 -+#define TARGET_FREEBSD_NR_setauid 448 -+#define TARGET_FREEBSD_NR_getaudit 449 -+#define TARGET_FREEBSD_NR_setaudit 450 -+#define TARGET_FREEBSD_NR_getaudit_addr 451 -+#define TARGET_FREEBSD_NR_setaudit_addr 452 -+#define TARGET_FREEBSD_NR_auditctl 453 -+#define TARGET_FREEBSD_NR__umtx_op 454 -+#define TARGET_FREEBSD_NR_thr_new 455 -+#define TARGET_FREEBSD_NR_sigqueue 456 -+#define TARGET_FREEBSD_NR_kmq_open 457 -+#define TARGET_FREEBSD_NR_kmq_setattr 458 -+#define TARGET_FREEBSD_NR_kmq_timedreceive 459 -+#define TARGET_FREEBSD_NR_kmq_timedsend 460 -+#define TARGET_FREEBSD_NR_kmq_notify 461 -+#define TARGET_FREEBSD_NR_kmq_unlink 462 -+#define TARGET_FREEBSD_NR_abort2 463 -+#define TARGET_FREEBSD_NR_thr_set_name 464 -+#define TARGET_FREEBSD_NR_aio_fsync 465 -+#define TARGET_FREEBSD_NR_rtprio_thread 466 -+#define TARGET_FREEBSD_NR_sctp_peeloff 471 -+#define TARGET_FREEBSD_NR_sctp_generic_sendmsg 472 -+#define TARGET_FREEBSD_NR_sctp_generic_sendmsg_iov 473 -+#define TARGET_FREEBSD_NR_sctp_generic_recvmsg 474 -+#define TARGET_FREEBSD_NR_pread 475 -+#define TARGET_FREEBSD_NR_pwrite 476 -+#define TARGET_FREEBSD_NR_mmap 477 -+#define TARGET_FREEBSD_NR_lseek 478 -+#define TARGET_FREEBSD_NR_truncate 479 -+#define TARGET_FREEBSD_NR_ftruncate 480 -+#define TARGET_FREEBSD_NR_thr_kill2 481 -+#define TARGET_FREEBSD_NR_shm_open 482 -+#define TARGET_FREEBSD_NR_shm_unlink 483 -+#define TARGET_FREEBSD_NR_cpuset 484 -+#define TARGET_FREEBSD_NR_cpuset_setid 485 -+#define TARGET_FREEBSD_NR_cpuset_getid 486 -+#define TARGET_FREEBSD_NR_cpuset_getaffinity 487 -+#define TARGET_FREEBSD_NR_cpuset_setaffinity 488 -+#define TARGET_FREEBSD_NR_faccessat 489 -+#define TARGET_FREEBSD_NR_fchmodat 490 -+#define TARGET_FREEBSD_NR_fchownat 491 -+#define TARGET_FREEBSD_NR_fexecve 492 -+#define TARGET_FREEBSD_NR_fstatat 493 -+#define TARGET_FREEBSD_NR_futimesat 494 -+#define TARGET_FREEBSD_NR_linkat 495 -+#define TARGET_FREEBSD_NR_mkdirat 496 -+#define TARGET_FREEBSD_NR_mkfifoat 497 -+#define TARGET_FREEBSD_NR_mknodat 498 -+#define TARGET_FREEBSD_NR_openat 499 -+#define TARGET_FREEBSD_NR_readlinkat 500 -+#define TARGET_FREEBSD_NR_renameat 501 -+#define TARGET_FREEBSD_NR_symlinkat 502 -+#define TARGET_FREEBSD_NR_unlinkat 503 -+#define TARGET_FREEBSD_NR_posix_openpt 504 -+#define TARGET_FREEBSD_NR_gssd_syscall 505 -+#define TARGET_FREEBSD_NR_jail_get 506 -+#define TARGET_FREEBSD_NR_jail_set 507 -+#define TARGET_FREEBSD_NR_jail_remove 508 -+#define TARGET_FREEBSD_NR_closefrom 509 -+#define TARGET_FREEBSD_NR___semctl 510 -+#define TARGET_FREEBSD_NR_msgctl 511 -+#define TARGET_FREEBSD_NR_shmctl 512 -+#define TARGET_FREEBSD_NR_lpathconf 513 -+ /* 514 is obsolete cap_new */ -+#define TARGET_FREEBSD_NR___cap_rights_get 515 -+#define TARGET_FREEBSD_NR_cap_enter 516 -+#define TARGET_FREEBSD_NR_cap_getmode 517 -+#define TARGET_FREEBSD_NR_pdfork 518 -+#define TARGET_FREEBSD_NR_pdkill 519 -+#define TARGET_FREEBSD_NR_pdgetpid 520 -+#define TARGET_FREEBSD_NR_pselect 522 -+#define TARGET_FREEBSD_NR_getloginclass 523 -+#define TARGET_FREEBSD_NR_setloginclass 524 -+#define TARGET_FREEBSD_NR_rctl_get_racct 525 -+#define TARGET_FREEBSD_NR_rctl_get_rules 526 -+#define TARGET_FREEBSD_NR_rctl_get_limits 527 -+#define TARGET_FREEBSD_NR_rctl_add_rule 528 -+#define TARGET_FREEBSD_NR_rctl_remove_rule 529 -+#define TARGET_FREEBSD_NR_posix_fallocate 530 -+#define TARGET_FREEBSD_NR_posix_fadvise 531 -+#define TARGET_FREEBSD_NR_wait6 532 -+#define TARGET_FREEBSD_NR_cap_rights_limit 533 -+#define TARGET_FREEBSD_NR_cap_ioctls_limit 534 -+#define TARGET_FREEBSD_NR_cap_ioctls_get 535 -+#define TARGET_FREEBSD_NR_cap_fcntls_limit 536 -+#define TARGET_FREEBSD_NR_cap_fcntls_get 537 -+#define TARGET_FREEBSD_NR_bindat 538 -+#define TARGET_FREEBSD_NR_connectat 539 -+#define TARGET_FREEBSD_NR_chflagsat 540 -+#define TARGET_FREEBSD_NR_accept4 541 -+#define TARGET_FREEBSD_NR_pipe2 542 - #define TARGET_FREEBSD_NR_aio_mlock 543 - #define TARGET_FREEBSD_NR_procctl 544 --#define TARGET_FREEBSD_NR_MAXSYSCALL 545 -+#define TARGET_FREEBSD_NR_MAXSYSCALL 545 -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 2ad63e5..4a743e8 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -356,6 +356,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - ret = do_freebsd_cap_enter(); - break; - -+#if defined(__FreeBSD_version) && __FreeBSD_version < 1000000 - case TARGET_FREEBSD_NR_cap_new: /* cap_new(2) */ - ret = do_freebsd_cap_new(arg1, arg2); - break; -@@ -363,6 +364,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - case TARGET_FREEBSD_NR_cap_getrights: /* cap_getrights(2) */ - ret = do_freebsd_cap_getrights(arg1, arg2); - break; -+#endif /* __FreeBSD_version < 1000000 */ - - case TARGET_FREEBSD_NR_cap_getmode: /* cap_getmode(2) */ - ret = do_freebsd_cap_getmode(arg1); -@@ -1052,9 +1054,11 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - ret = do_bsd_kill(arg1, arg2); - break; - -+#if defined(__FreeBSD_version) && __FreeBSD_version < 1000000 - case TARGET_FREEBSD_NR_killpg: /* killpg(2) */ - ret = do_bsd_killpg(arg1, arg2); - break; -+#endif - - case TARGET_FREEBSD_NR_pdkill: /* pdkill(2) */ - ret = do_freebsd_pdkill(arg1, arg2); -@@ -1218,6 +1222,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - ret = do_freebsd_swapcontext(cpu_env, arg1, arg2); - break; - -+#if defined(__FreeBSD_version) && __FreeBSD_version < 1000000 - case TARGET_FREEBSD_NR__umtx_lock: /* undocumented */ - ret = do_freebsd__umtx_lock(arg1); - break; -@@ -1225,6 +1230,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - case TARGET_FREEBSD_NR__umtx_unlock: /* undocumented */ - ret = do_freebsd__umtx_unlock(arg1); - break; -+#endif - - case TARGET_FREEBSD_NR__umtx_op: /* undocumented */ - ret = do_freebsd__umtx_op(arg1, arg2, arg3, arg4, arg5); -@@ -1628,6 +1634,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - break; - - default: -+ gemu_log("qemu: unsupported syscall: %d (calling anyway)\n", num); - ret = get_errno(syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, - arg8)); - break; diff --git a/emulators/qemu-devel/files/extra-patch-2478a4e4a33d0523cc436eabb4a27b258b4358b8 b/emulators/qemu-devel/files/extra-patch-2478a4e4a33d0523cc436eabb4a27b258b4358b8 deleted file mode 100644 index 60acfebd6da6..000000000000 --- a/emulators/qemu-devel/files/extra-patch-2478a4e4a33d0523cc436eabb4a27b258b4358b8 +++ /dev/null @@ -1,80 +0,0 @@ -From 2478a4e4a33d0523cc436eabb4a27b258b4358b8 Mon Sep 17 00:00:00 2001 -From: Sean Bruno <sbruno@freebsd.org> -Date: Sun, 2 Nov 2014 15:05:40 -0800 -Subject: [PATCH] Deal with new sem_wait2 and sem_wake2 syscalls in head. - ---- - bsd-user/freebsd/os-thread.c | 19 +++++++++++++++++++ - bsd-user/freebsd/os-thread.h | 6 ++++++ - bsd-user/syscall_defs.h | 4 +++- - 3 files changed, 28 insertions(+), 1 deletion(-) - -diff --git a/bsd-user/freebsd/os-thread.c b/bsd-user/freebsd/os-thread.c -index 91a42ac..cca46cf 100644 ---- a/bsd-user/freebsd/os-thread.c -+++ b/bsd-user/freebsd/os-thread.c -@@ -225,6 +225,25 @@ abi_long freebsd_umtx_mutex_wake2(abi_ulong target_addr, - } - #endif /* UMTX_OP_MUTEX_WAKE2 */ - -+#if defined(__FreeBSD_version) && __FreeBSD_version > 1100000 -+abi_long freebsd_umtx_sem_wait(abi_ulong obj, struct timespec *timeout) -+{ -+ -+ /* XXX Assumes struct _usem is opauque to the user */ -+ if (!access_ok(VERIFY_WRITE, obj, sizeof(struct target__usem))) { -+ return -TARGET_EFAULT; -+ } -+ return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM2_WAIT, 0, NULL, timeout)); -+} -+ -+abi_long freebsd_umtx_sem_wake(abi_ulong obj, uint32_t val) -+{ -+ -+ return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM2_WAKE, val, NULL, NULL)); -+} -+#endif -+ -+#else - abi_long freebsd_umtx_sem_wait(abi_ulong obj, struct timespec *timeout) - { - -diff --git a/bsd-user/freebsd/os-thread.h b/bsd-user/freebsd/os-thread.h -index 28f737f..8157e85 100644 ---- a/bsd-user/freebsd/os-thread.h -+++ b/bsd-user/freebsd/os-thread.h -@@ -486,6 +486,9 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, - break; - #endif /* UMTX_OP_NWAKE_PRIVATE */ - -+#if defined(__FreeBSD_version) && __FreeBSD_version > 1100000 -+ case TARGET_UMTX_OP_SEM2_WAIT: -+#endif - case TARGET_UMTX_OP_SEM_WAIT: - if (target_ts != 0) { - if (t2h_freebsd_timespec(&ts, target_ts)) { -@@ -497,6 +500,9 @@ static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, - } - break; - -+#if defined(__FreeBSD_version) && __FreeBSD_version > 1100000 -+ case TARGET_UMTX_OP_SEM2_WAKE: -+#endif - case TARGET_UMTX_OP_SEM_WAKE: - /* Don't need to do access_ok(). */ - ret = freebsd_umtx_sem_wake(obj, val); -diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h -index 13678d4..d02476c 100644 ---- a/bsd-user/syscall_defs.h -+++ b/bsd-user/syscall_defs.h -@@ -633,7 +633,9 @@ typedef struct { - #define TARGET_UMTX_OP_SEM_WAKE 20 - #define TARGET_UMTX_OP_NWAKE_PRIVATE 21 - #define TARGET_UMTX_OP_MUTEX_WAKE2 22 --#define TARGET_UMTX_OP_MAX 23 -+#define TARGET_UMTX_OP_SEM2_WAIT 23 -+#define TARGET_UMTX_OP_SEM2_WAKE 24 -+#define TARGET_UMTX_OP_MAX 25 - - /* flags for UMTX_OP_CV_WAIT */ - #define TARGET_CVWAIT_CHECK_UNPARKING 0x01 diff --git a/emulators/qemu-devel/files/extra-patch-26a50e8a9d8723d406e5ef3d1449911cfa2d3454 b/emulators/qemu-devel/files/extra-patch-26a50e8a9d8723d406e5ef3d1449911cfa2d3454 deleted file mode 100644 index 44194816d201..000000000000 --- a/emulators/qemu-devel/files/extra-patch-26a50e8a9d8723d406e5ef3d1449911cfa2d3454 +++ /dev/null @@ -1,62 +0,0 @@ -From 26a50e8a9d8723d406e5ef3d1449911cfa2d3454 Mon Sep 17 00:00:00 2001 -From: Leon Alrae <leon.alrae@imgtec.com> -Date: Fri, 27 Jun 2014 08:49:00 +0100 -Subject: [PATCH] target-mips: define ISA_MIPS64R6 - -Signed-off-by: Leon Alrae <leon.alrae@imgtec.com> -Reviewed-by: Aurelien Jarno <aurelien@aurel32.net> ---- - target-mips/mips-defs.h | 28 +++++++++++++++++++--------- - 1 file changed, 19 insertions(+), 9 deletions(-) - -diff --git a/target-mips/mips-defs.h b/target-mips/mips-defs.h -index 9dfa516..6cb62b2 100644 ---- a/target-mips/mips-defs.h -+++ b/target-mips/mips-defs.h -@@ -30,17 +30,21 @@ - #define ISA_MIPS64 0x00000080 - #define ISA_MIPS64R2 0x00000100 - #define ISA_MIPS32R3 0x00000200 --#define ISA_MIPS32R5 0x00000400 -+#define ISA_MIPS64R3 0x00000400 -+#define ISA_MIPS32R5 0x00000800 -+#define ISA_MIPS64R5 0x00001000 -+#define ISA_MIPS32R6 0x00002000 -+#define ISA_MIPS64R6 0x00004000 - - /* MIPS ASEs. */ --#define ASE_MIPS16 0x00001000 --#define ASE_MIPS3D 0x00002000 --#define ASE_MDMX 0x00004000 --#define ASE_DSP 0x00008000 --#define ASE_DSPR2 0x00010000 --#define ASE_MT 0x00020000 --#define ASE_SMARTMIPS 0x00040000 --#define ASE_MICROMIPS 0x00080000 -+#define ASE_MIPS16 0x00010000 -+#define ASE_MIPS3D 0x00020000 -+#define ASE_MDMX 0x00040000 -+#define ASE_DSP 0x00080000 -+#define ASE_DSPR2 0x00100000 -+#define ASE_MT 0x00200000 -+#define ASE_SMARTMIPS 0x00400000 -+#define ASE_MICROMIPS 0x00800000 - - /* Chip specific instructions. */ - #define INSN_LOONGSON2E 0x20000000 -@@ -68,9 +72,15 @@ - - /* MIPS Technologies "Release 3" */ - #define CPU_MIPS32R3 (CPU_MIPS32R2 | ISA_MIPS32R3) -+#define CPU_MIPS64R3 (CPU_MIPS64R2 | CPU_MIPS32R3 | ISA_MIPS64R3) - - /* MIPS Technologies "Release 5" */ - #define CPU_MIPS32R5 (CPU_MIPS32R3 | ISA_MIPS32R5) -+#define CPU_MIPS64R5 (CPU_MIPS64R3 | CPU_MIPS32R5 | ISA_MIPS64R5) -+ -+/* MIPS Technologies "Release 6" */ -+#define CPU_MIPS32R6 (CPU_MIPS32R5 | ISA_MIPS32R6) -+#define CPU_MIPS64R6 (CPU_MIPS64R5 | CPU_MIPS32R6 | ISA_MIPS64R6) - - /* Strictly follow the architecture standard: - - Disallow "special" instruction handling for PMON/SPIM. diff --git a/emulators/qemu-devel/files/extra-patch-290a6e398b9d132a673e1f95954fc7d9a86c3baa b/emulators/qemu-devel/files/extra-patch-290a6e398b9d132a673e1f95954fc7d9a86c3baa deleted file mode 100644 index 8d9ef66fb484..000000000000 --- a/emulators/qemu-devel/files/extra-patch-290a6e398b9d132a673e1f95954fc7d9a86c3baa +++ /dev/null @@ -1,76 +0,0 @@ -From 290a6e398b9d132a673e1f95954fc7d9a86c3baa Mon Sep 17 00:00:00 2001 -From: Leon Alrae <leon.alrae@imgtec.com> -Date: Fri, 27 Jun 2014 08:49:04 +0100 -Subject: [PATCH] target-mips: Status.UX/SX/KX enable 32-bit address wrapping - -In R6 the special behaviour for data references is also specified for Kernel -and Supervisor mode. Therefore MIPS_HFLAG_UX is replaced by generic -MIPS_HFLAG_AWRAP indicating enabled 32-bit address wrapping. - -Signed-off-by: Leon Alrae <leon.alrae@imgtec.com> -Reviewed-by: Aurelien Jarno <aurelien@aurel32.net> ---- - target-mips/cpu.h | 18 ++++++++++++++---- - target-mips/translate.c | 6 +----- - 2 files changed, 15 insertions(+), 9 deletions(-) - -diff --git a/target-mips/cpu.h b/target-mips/cpu.h -index 8b9a92e..51a8331 100644 ---- a/target-mips/cpu.h -+++ b/target-mips/cpu.h -@@ -450,7 +450,7 @@ struct CPUMIPSState { - and RSQRT.D. */ - #define MIPS_HFLAG_COP1X 0x00080 /* COP1X instructions enabled */ - #define MIPS_HFLAG_RE 0x00100 /* Reversed endianness */ --#define MIPS_HFLAG_UX 0x00200 /* 64-bit user mode */ -+#define MIPS_HFLAG_AWRAP 0x00200 /* 32-bit compatibility address wrapping */ - #define MIPS_HFLAG_M16 0x00400 /* MIPS16 mode flag */ - #define MIPS_HFLAG_M16_SHIFT 10 - /* If translation is interrupted between the branch instruction and -@@ -725,7 +725,7 @@ static inline void compute_hflags(CPUMIPSState *env) - { - env->hflags &= ~(MIPS_HFLAG_COP1X | MIPS_HFLAG_64 | MIPS_HFLAG_CP0 | - MIPS_HFLAG_F64 | MIPS_HFLAG_FPU | MIPS_HFLAG_KSU | -- MIPS_HFLAG_UX | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2); -+ MIPS_HFLAG_AWRAP | MIPS_HFLAG_DSP | MIPS_HFLAG_DSPR2); - if (!(env->CP0_Status & (1 << CP0St_EXL)) && - !(env->CP0_Status & (1 << CP0St_ERL)) && - !(env->hflags & MIPS_HFLAG_DM)) { -@@ -737,8 +737,18 @@ static inline void compute_hflags(CPUMIPSState *env) - (env->CP0_Status & (1 << CP0St_UX))) { - env->hflags |= MIPS_HFLAG_64; - } -- if (env->CP0_Status & (1 << CP0St_UX)) { -- env->hflags |= MIPS_HFLAG_UX; -+ -+ if (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) && -+ !(env->CP0_Status & (1 << CP0St_UX))) { -+ env->hflags |= MIPS_HFLAG_AWRAP; -+ } else if (env->insn_flags & ISA_MIPS32R6) { -+ /* Address wrapping for Supervisor and Kernel is specified in R6 */ -+ if ((((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_SM) && -+ !(env->CP0_Status & (1 << CP0St_SX))) || -+ (((env->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_KM) && -+ !(env->CP0_Status & (1 << CP0St_KX)))) { -+ env->hflags |= MIPS_HFLAG_AWRAP; -+ } - } - #endif - if ((env->CP0_Status & (1 << CP0St_CU0)) || -diff --git a/target-mips/translate.c b/target-mips/translate.c -index 06db150..05044b0 100644 ---- a/target-mips/translate.c -+++ b/target-mips/translate.c -@@ -1343,11 +1343,7 @@ static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv - tcg_gen_add_tl(ret, arg0, arg1); - - #if defined(TARGET_MIPS64) -- /* For compatibility with 32-bit code, data reference in user mode -- with Status_UX = 0 should be casted to 32-bit and sign extended. -- See the MIPS64 PRA manual, section 4.10. */ -- if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) && -- !(ctx->hflags & MIPS_HFLAG_UX)) { -+ if (ctx->hflags & MIPS_HFLAG_AWRAP) { - tcg_gen_ext32s_i64(ret, ret); - } - #endif diff --git a/emulators/qemu-devel/files/extra-patch-30c8ccb41e2c9e1ddda7e3f8a8ac1eb5dab8b408 b/emulators/qemu-devel/files/extra-patch-30c8ccb41e2c9e1ddda7e3f8a8ac1eb5dab8b408 deleted file mode 100644 index 1228f51a067f..000000000000 --- a/emulators/qemu-devel/files/extra-patch-30c8ccb41e2c9e1ddda7e3f8a8ac1eb5dab8b408 +++ /dev/null @@ -1,51 +0,0 @@ -From 30c8ccb41e2c9e1ddda7e3f8a8ac1eb5dab8b408 Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Wed, 5 Nov 2014 22:52:17 +0000 -Subject: [PATCH] Add stub for the new procctl(2) system call. - ---- - bsd-user/freebsd/os-proc.h | 10 ++++++++++ - bsd-user/syscall.c | 4 +++- - 2 files changed, 13 insertions(+), 1 deletion(-) - -diff --git a/bsd-user/freebsd/os-proc.h b/bsd-user/freebsd/os-proc.h -index 612a5fd..193e1fc 100644 ---- a/bsd-user/freebsd/os-proc.h -+++ b/bsd-user/freebsd/os-proc.h -@@ -21,6 +21,7 @@ - #define __FREEBSD_PROC_H_ - - #if defined(__FreeBSD_version) && __FreeBSD_version >= 1000000 -+#include <sys/procctl.h> - #include <sys/signal.h> - #endif - #include <sys/types.h> -@@ -520,4 +521,13 @@ static inline abi_long do_freebsd_auditctl(abi_ulong arg1) - return -TARGET_ENOSYS; - } - -+/* procctl(2) */ -+static inline abi_long do_freebsd_procctl(__unused int idtype, __unused int id, -+ __unused int cmd, __unused abi_ulong arg) -+{ -+ -+ qemu_log("qemu: Unsupported syscall procctl()\n"); -+ return -TARGET_ENOSYS; -+} -+ - #endif /* ! __FREEBSD_PROC_H_ */ -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 30dc2f3..2ad63e5 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -432,7 +432,9 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - ret = do_bsd_setpriority(arg1, arg2, arg3); - break; - -- -+ case TARGET_FREEBSD_NR_procctl: /* procctl(2) */ -+ ret = do_freebsd_procctl(arg1, arg2, arg3, arg4); -+ break; - - /* - * File system calls. diff --git a/emulators/qemu-devel/files/extra-patch-38f8d5aaebdb4b1624bae86b374b5265c9f01b54 b/emulators/qemu-devel/files/extra-patch-38f8d5aaebdb4b1624bae86b374b5265c9f01b54 deleted file mode 100644 index 3de6319ed4f6..000000000000 --- a/emulators/qemu-devel/files/extra-patch-38f8d5aaebdb4b1624bae86b374b5265c9f01b54 +++ /dev/null @@ -1,29 +0,0 @@ -diff --git a/bsd-user/freebsd/os-thread.c b/bsd-user/freebsd/os-thread.c -index 6bf2a9f..bcd2445 100644 ---- a/bsd-user/freebsd/os-thread.c -+++ b/bsd-user/freebsd/os-thread.c -@@ -899,11 +899,13 @@ abi_long do_freebsd_thr_new(CPUArchState *env, - pthread_attr_t attr; - TaskState *ts; - CPUArchState *new_env; -+ CPUState *new_cpu; - struct target_freebsd_thr_param *target_param; - abi_ulong target_rtp_addr; - struct target_freebsd_rtprio *target_rtp; - struct rtprio *rtp_ptr, rtp; -- TaskState *parent_ts = (TaskState *)env->opaque; -+ CPUState *parent_cpu = ENV_GET_CPU(env); -+ TaskState *parent_ts = parent_cpu->opaque; - sigset_t sigmask; - struct sched_param sched_param; - int sched_policy; -@@ -948,7 +950,8 @@ abi_long do_freebsd_thr_new(CPUArchState *env, - - /* init regs that differ from the parent thread. */ - target_cpu_clone_regs(new_env, info.param.stack_base); -- new_env->opaque = ts; -+ new_cpu = ENV_GET_CPU(new_env); -+ new_cpu->opaque = ts; - ts->bprm = parent_ts->bprm; - ts->info = parent_ts->info; - diff --git a/emulators/qemu-devel/files/extra-patch-3d175d6ed5b809976662135369c639f53780ca5c b/emulators/qemu-devel/files/extra-patch-3d175d6ed5b809976662135369c639f53780ca5c deleted file mode 100644 index 9272f46aa42f..000000000000 --- a/emulators/qemu-devel/files/extra-patch-3d175d6ed5b809976662135369c639f53780ca5c +++ /dev/null @@ -1,38 +0,0 @@ -diff --git a/bsd-user/main.c b/bsd-user/main.c -index f27fcbc..16a0590 100644 ---- a/bsd-user/main.c -+++ b/bsd-user/main.c -@@ -272,6 +272,7 @@ void init_task_state(TaskState *ts) - CPUArchState *cpu_copy(CPUArchState *env) - { - CPUArchState *new_env = cpu_init(cpu_model); -+ CPUState *cpu; - #if defined(TARGET_HAS_ICE) - CPUBreakpoint *bp; - CPUWatchpoint *wp; -@@ -281,18 +282,19 @@ CPUArchState *cpu_copy(CPUArchState *env) - cpu_reset(ENV_GET_CPU(new_env)); - - memcpy(new_env, env, sizeof(CPUArchState)); -+ cpu = ENV_GET_CPU(env); - - /* 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(&env->breakpoints); -- QTAILQ_INIT(&env->watchpoints); -+ QTAILQ_INIT(&cpu->breakpoints); -+ QTAILQ_INIT(&cpu->watchpoints); - #if defined(TARGET_HAS_ICE) -- QTAILQ_FOREACH(bp, &env->breakpoints, entry) { -- cpu_breakpoint_insert(new_env, bp->pc, bp->flags, NULL); -+ QTAILQ_FOREACH(bp, &cpu->breakpoints, entry) { -+ cpu_breakpoint_insert(cpu, bp->pc, bp->flags, NULL); - } -- QTAILQ_FOREACH(wp, &env->watchpoints, entry) { -- cpu_watchpoint_insert(new_env, wp->vaddr, (~wp->len_mask) + 1, -+ QTAILQ_FOREACH(wp, &cpu->watchpoints, entry) { -+ cpu_watchpoint_insert(cpu, wp->vaddr, (~wp->len_mask) + 1, - wp->flags, NULL); - } - #endif diff --git a/emulators/qemu-devel/files/extra-patch-3ed485b9b4ef8d8ba916760aec0cdf9dbce8ca27 b/emulators/qemu-devel/files/extra-patch-3ed485b9b4ef8d8ba916760aec0cdf9dbce8ca27 deleted file mode 100644 index aa0cca202ecf..000000000000 --- a/emulators/qemu-devel/files/extra-patch-3ed485b9b4ef8d8ba916760aec0cdf9dbce8ca27 +++ /dev/null @@ -1,63 +0,0 @@ -From 3ed485b9b4ef8d8ba916760aec0cdf9dbce8ca27 Mon Sep 17 00:00:00 2001 -From: Sean Bruno <sbruno@crack.ysv.freebsd.org> -Date: Fri, 7 Nov 2014 19:19:38 +0000 -Subject: [PATCH] Now that the kernel image activators can be run - independantly, there's no need for qemu itself to do this. This allows - /bin/sh to be used as a static amd64 binary on my poudriere jails. - ---- - bsd-user/freebsd/os-proc.c | 6 ++++++ - 1 file changed, 6 insertions(+) - -diff --git a/bsd-user/freebsd/os-proc.c b/bsd-user/freebsd/os-proc.c -index 24b8d27..b185439 100644 ---- a/bsd-user/freebsd/os-proc.c -+++ b/bsd-user/freebsd/os-proc.c -@@ -82,6 +82,7 @@ get_filename_from_fd(pid_t pid, int fd, char *filename, size_t len) - return ret; - } - -+#if defined(__FreeBSD_version) && __FreeBSD_version < 1100000 - static int - is_target_shell_script(int fd, char *interp, size_t size, char **interp_args) - { -@@ -143,6 +144,7 @@ is_target_shell_script(int fd, char *interp, size_t size, char **interp_args) - - return 0; - } -+#endif - - /* - * execve/fexecve -@@ -257,6 +259,7 @@ abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, - ret = -TARGET_EBADF; - goto execve_end; - } -+#if defined(__FreeBSD_version) && __FreeBSD_version < 1100000 - } else if (is_target_shell_script((int)path_or_fd, execpath, - sizeof(execpath), &scriptargs) != 0) { - char scriptpath[PATH_MAX]; -@@ -282,6 +285,7 @@ abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, - ret = -TARGET_EBADF; - goto execve_end; - } -+#endif - } else { - ret = get_errno(fexecve((int)path_or_fd, argp, envp)); - } -@@ -310,6 +314,7 @@ abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, - *qarg1++ = (char *)interp_prefix; - #endif - ret = get_errno(execve(qemu_proc_pathname, qargp, envp)); -+#if defined(__FreeBSD_version) && __FreeBSD_version < 1100000 - } else if (is_target_shell_script(fd, execpath, - sizeof(execpath), &scriptargs) != 0) { - close(fd); -@@ -328,6 +333,7 @@ abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, - *qarg1 = scriptargs; - } - ret = get_errno(execve(qemu_proc_pathname, qarg0, envp)); -+#endif - } else { - close(fd); - /* Execve() as a host native binary. */ diff --git a/emulators/qemu-devel/files/extra-patch-5f81caf45c0d0eb2b4b852f8580a1938fb3d12c6 b/emulators/qemu-devel/files/extra-patch-5f81caf45c0d0eb2b4b852f8580a1938fb3d12c6 deleted file mode 100644 index 193a6e4e8751..000000000000 --- a/emulators/qemu-devel/files/extra-patch-5f81caf45c0d0eb2b4b852f8580a1938fb3d12c6 +++ /dev/null @@ -1,201 +0,0 @@ -From 5f81caf45c0d0eb2b4b852f8580a1938fb3d12c6 Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Wed, 5 Nov 2014 20:28:13 +0000 -Subject: [PATCH] Add support for pipe2(2) and chflagsat(2) system calls. - -This change adds support for newly added pipe2(2) and chflagsat(2) -system calls. It also fixes what obviously looks like a bug with the -pipe(2) call emulation. The pipe descriptors were not written back. ---- - bsd-user/bsd-file.h | 8 +++- - bsd-user/freebsd/os-file.h | 86 +++++++++++++++++++++++++++++++++++++++++++ - bsd-user/freebsd/strace.list | 2 + - bsd-user/freebsd/syscall_nr.h | 3 +- - bsd-user/syscall.c | 9 +++++ - 5 files changed, 105 insertions(+), 3 deletions(-) - create mode 100644 bsd-user/freebsd/os-file.h - -diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h -index 5d8a347..f697eac 100644 ---- a/bsd-user/bsd-file.h -+++ b/bsd-user/bsd-file.h -@@ -1013,7 +1013,7 @@ static abi_long do_bsd_lseek(void *cpu_env, abi_long arg1, abi_long arg2, - } - - /* pipe(2) */ --static abi_long do_bsd_pipe(void *cpu_env, abi_long arg1) -+static abi_long do_bsd_pipe(void *cpu_env, abi_ulong pipedes) - { - abi_long ret; - int host_pipe[2]; -@@ -1022,8 +1022,12 @@ static abi_long do_bsd_pipe(void *cpu_env, abi_long arg1) - if (host_ret != -1) { - set_second_rval(cpu_env, host_pipe[1]); - ret = host_pipe[0]; -+ if (put_user_s32(host_pipe[0], pipedes) || -+ put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0]))) { -+ return -TARGET_EFAULT; -+ } - } else { -- ret = get_errno(host_ret); -+ ret = get_errno(host_ret); - } - return ret; - } -diff --git a/bsd-user/freebsd/os-file.h b/bsd-user/freebsd/os-file.h -new file mode 100644 -index 0000000..2c6bc24 ---- /dev/null -+++ b/bsd-user/freebsd/os-file.h -@@ -0,0 +1,86 @@ -+/* -+ * FreeBSD file related system call shims and definitions -+ * -+ * Copyright (c) 2014 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef __FREEBSD_OS_FILE_H_ -+#define __FREEBSD_OS_FILE_H_ -+ -+#include <sys/stat.h> -+#include <unistd.h> -+ -+#include "qemu-os.h" -+ -+ -+#if defined(__FreeBSD_version) && __FreeBSD_version >= 1000000 -+/* pipe2(2) */ -+static abi_long do_bsd_pipe2(void *cpu_env, abi_ulong pipedes, int flags) -+{ -+ abi_long ret; -+ int host_pipe[2]; -+ int host_ret = pipe2(host_pipe, flags); -+ -+ if (is_error(host_ret)) { -+ return get_errno(host_ret); -+ } -+ if (host_ret != -1) { -+ set_second_rval(cpu_env, host_pipe[1]); -+ ret = host_pipe[0]; -+ if (put_user_s32(host_pipe[0], pipedes) || -+ put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0]))) { -+ return -TARGET_EFAULT; -+ } -+ } else { -+ ret = get_errno(host_ret); -+ } -+ return ret; -+} -+ -+/* chflagsat(2) */ -+static inline abi_long do_bsd_chflagsat(int fd, abi_ulong path, -+ abi_ulong flags, int atflags) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, path); -+ ret = get_errno(chflagsat(fd, p, flags, atflags)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, path); -+ -+ return ret; -+} -+ -+#else /* ! __FreeBSD_version > 1000000 */ -+ -+static abi_long do_bsd_pipe2(__unused void *cpu_env, __unused abi_long arg1, -+ __unused int flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall pipe2()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_bsd_chflagsat(__unused int fd, -+ __unused abi_ulong path, __unused abi_ulong flags, int atflags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall chflagsat()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* ! __FreeBSD_version >= 1000000 */ -+#endif /* __FREEBSD_OS_FILE_H_ */ -diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list -index 991cbe2..cba4afe 100644 ---- a/bsd-user/freebsd/strace.list -+++ b/bsd-user/freebsd/strace.list -@@ -52,6 +52,7 @@ - { TARGET_FREEBSD_NR_cap_rights_limit, "cap_rights_limit", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_chdir, "chdir", "%s(\"%s\")", NULL, NULL }, - { TARGET_FREEBSD_NR_chflags, "chflags", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_chflagsat, "chflagsat", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_chmod, "chmod", "%s(\"%s\",%#o)", NULL, NULL }, - { TARGET_FREEBSD_NR_chown, "chown", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_chroot, "chroot", NULL, NULL, NULL }, -@@ -160,6 +161,7 @@ - { TARGET_FREEBSD_NR_openat, "openat", "%s(%d, \"%s\",%#x,%#o)", NULL, NULL }, - { TARGET_FREEBSD_NR_pathconf, "pathconf", "%s(\"%s\", %d)", NULL, NULL }, - { TARGET_FREEBSD_NR_pipe, "pipe", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_pipe2, "pipe2", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_poll, "poll", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_pread, "pread", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_preadv, "preadv", NULL, NULL, NULL }, -diff --git a/bsd-user/freebsd/syscall_nr.h b/bsd-user/freebsd/syscall_nr.h -index 260fd82..b44545b 100644 ---- a/bsd-user/freebsd/syscall_nr.h -+++ b/bsd-user/freebsd/syscall_nr.h -@@ -457,4 +457,5 @@ - #define TARGET_FREEBSD_NR_connectat 539 - #define TARGET_FREEBSD_NR_chflagsat 540 - #define TARGET_FREEBSD_NR_accept4 541 --#define TARGET_FREEBSD_NR_MAXSYSCALL 542 -+#define TARGET_FREEBSD_NR_pipe2 542 -+#define TARGET_FREEBSD_NR_MAXSYSCALL 543 -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index e043396..0a2ab88 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -44,6 +44,7 @@ - - /* *BSD dependent syscall shims */ - #include "os-extattr.h" -+#include "os-file.h" - #include "os-time.h" - #include "os-misc.h" - #include "os-proc.h" -@@ -646,6 +647,10 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - ret = do_bsd_chflags(arg1, arg2); - break; - -+ case TARGET_FREEBSD_NR_chflagsat: /* chflagsat(2) */ -+ ret = do_bsd_chflagsat(arg1, arg2, arg3, arg4); -+ break; -+ - case TARGET_FREEBSD_NR_lchflags: /* lchflags(2) */ - ret = do_bsd_lchflags(arg1, arg2); - break; -@@ -702,6 +707,10 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - ret = do_bsd_pipe(cpu_env, arg1); - break; - -+ case TARGET_FREEBSD_NR_pipe2: /* pipe2(2) */ -+ ret = do_bsd_pipe2(cpu_env, arg1, arg2); -+ break; -+ - case TARGET_FREEBSD_NR_swapon: /* swapon(2) */ - ret = do_bsd_swapon(arg1); - break; diff --git a/emulators/qemu-devel/files/extra-patch-6201cb17ad905dffee1b2eb76f58fb032e99b2a1 b/emulators/qemu-devel/files/extra-patch-6201cb17ad905dffee1b2eb76f58fb032e99b2a1 deleted file mode 100644 index 93fe4f62bbe5..000000000000 --- a/emulators/qemu-devel/files/extra-patch-6201cb17ad905dffee1b2eb76f58fb032e99b2a1 +++ /dev/null @@ -1,11 +0,0 @@ ---- a/bsd-user/mips/target_arch_sigtramp.h -+++ b/bsd-user/mips/target_arch_sigtramp.h -@@ -8,7 +8,7 @@ static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc, - { - int i; - uint32_t sigtramp_code[TARGET_SZSIGCODE/TARGET_INSN_SIZE] = { -- /* 1 */ 0x27A40000 + sigf_uc, /* daddu $a0, $sp, (sigf_uc) */ -+ /* 1 */ 0x27A40000 + sigf_uc, /* addu $a0, $sp, (sigf_uc) */ - /* 2 */ 0x24020000 + sys_sigreturn, /* li $v0, (sys_sigreturn) */ - /* 3 */ 0x0000000C, /* syscall */ - /* 4 */ 0x0000000D /* break */ diff --git a/emulators/qemu-devel/files/extra-patch-72f0a64c7dd7be796dc2d8f2b0dab340309800e2 b/emulators/qemu-devel/files/extra-patch-72f0a64c7dd7be796dc2d8f2b0dab340309800e2 deleted file mode 100644 index 57c54b994595..000000000000 --- a/emulators/qemu-devel/files/extra-patch-72f0a64c7dd7be796dc2d8f2b0dab340309800e2 +++ /dev/null @@ -1,45 +0,0 @@ -From 72f0a64c7dd7be796dc2d8f2b0dab340309800e2 Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Fri, 7 Nov 2014 20:48:56 +0000 -Subject: [PATCH] struct __wrusage is not available until FreeBSD 10.0. - ---- - bsd-user/bsd-proc.c | 2 ++ - bsd-user/qemu-bsd.h | 2 ++ - 2 files changed, 4 insertions(+) - -diff --git a/bsd-user/bsd-proc.c b/bsd-user/bsd-proc.c -index 7f0b21c..503e928 100644 ---- a/bsd-user/bsd-proc.c -+++ b/bsd-user/bsd-proc.c -@@ -147,6 +147,7 @@ abi_long host_to_target_rusage(abi_ulong target_addr, - return 0; - } - -+:#if defined(__FreeBSD_version) && __FreeBSD_version >= 1000000 - abi_long host_to_target_wrusage(abi_ulong target_addr, - const struct __wrusage *wrusage) - { -@@ -161,6 +162,7 @@ abi_long host_to_target_wrusage(abi_ulong target_addr, - - return 0; - } -+#endif /* ! __FreeBSD_version >= 1000000 */ - - /* - * wait status conversion. -diff --git a/bsd-user/qemu-bsd.h b/bsd-user/qemu-bsd.h -index e58fdd7..0c0d1e3 100644 ---- a/bsd-user/qemu-bsd.h -+++ b/bsd-user/qemu-bsd.h -@@ -48,8 +48,10 @@ rlim_t target_to_host_rlim(abi_ulong target_rlim); - abi_ulong host_to_target_rlim(rlim_t rlim); - abi_long host_to_target_rusage(abi_ulong target_addr, - const struct rusage *rusage); -+#if defined(__FreeBSD_version) && __FreeBSD_version >= 1000000 - abi_long host_to_target_wrusage(abi_ulong target_addr, - const struct __wrusage *wrusage); -+#endif /* __FreeBSD_version >= 1000000 */ - int host_to_target_waitstatus(int status); - - /* bsd-socket.c */ diff --git a/emulators/qemu-devel/files/extra-patch-790d0ef625d22ff3f1a895d266a48e2bacd63776 b/emulators/qemu-devel/files/extra-patch-790d0ef625d22ff3f1a895d266a48e2bacd63776 deleted file mode 100644 index dfd3d87acb5d..000000000000 --- a/emulators/qemu-devel/files/extra-patch-790d0ef625d22ff3f1a895d266a48e2bacd63776 +++ /dev/null @@ -1,30297 +0,0 @@ -diff --git a/Makefile.target b/Makefile.target -index ba12340..9e9a913 100644 ---- a/Makefile.target -+++ b/Makefile.target -@@ -99,10 +99,11 @@ endif #CONFIG_LINUX_USER - - ifdef CONFIG_BSD_USER - --QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ABI_DIR) -+QEMU_CFLAGS+=-I$(SRC_PATH)/bsd-user -I$(SRC_PATH)/bsd-user/$(TARGET_ABI_DIR) \ -+ -I$(SRC_PATH)/bsd-user/$(HOST_VARIANT_DIR) - - obj-y += bsd-user/ --obj-y += gdbstub.o user-exec.o -+obj-y += gdbstub.o thunk.o user-exec.o - - endif #CONFIG_BSD_USER - -diff --git a/bsd-user/Makefile.objs b/bsd-user/Makefile.objs -index 5e77f57..ab025a4 100644 ---- a/bsd-user/Makefile.objs -+++ b/bsd-user/Makefile.objs -@@ -1,2 +1,6 @@ - obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \ -- uaccess.o -+ uaccess.o bsd-ioctl.o bsd-mem.o bsd-misc.o bsd-proc.o bsd-socket.o \ -+ $(HOST_VARIANT_DIR)/os-extattr.o $(HOST_VARIANT_DIR)/os-proc.o \ -+ $(HOST_VARIANT_DIR)/os-socket.o $(HOST_VARIANT_DIR)/os-stat.o \ -+ $(HOST_VARIANT_DIR)/os-sys.o $(HOST_VARIANT_DIR)/os-thread.o \ -+ $(HOST_VARIANT_DIR)/os-time.o $(TARGET_ABI_DIR)/target_arch_cpu.o -diff --git a/bsd-user/arm/syscall.h b/bsd-user/arm/syscall.h -new file mode 100644 -index 0000000..bc3d6e6 ---- /dev/null -+++ b/bsd-user/arm/syscall.h -@@ -0,0 +1,36 @@ -+#ifndef __ARCH_SYSCALL_H_ -+#define __ARCH_SYSCALL_H_ -+ -+struct target_pt_regs { -+ abi_long uregs[17]; -+}; -+ -+#define ARM_cpsr uregs[16] -+#define ARM_pc uregs[15] -+#define ARM_lr uregs[14] -+#define ARM_sp uregs[13] -+#define ARM_ip uregs[12] -+#define ARM_fp uregs[11] -+#define ARM_r10 uregs[10] -+#define ARM_r9 uregs[9] -+#define ARM_r8 uregs[8] -+#define ARM_r7 uregs[7] -+#define ARM_r6 uregs[6] -+#define ARM_r5 uregs[5] -+#define ARM_r4 uregs[4] -+#define ARM_r3 uregs[3] -+#define ARM_r2 uregs[2] -+#define ARM_r1 uregs[1] -+#define ARM_r0 uregs[0] -+ -+#define ARM_SYSCALL_BASE 0 /* XXX: FreeBSD only */ -+ -+#define TARGET_FREEBSD_ARM_SYNC_ICACHE 0 -+#define TARGET_FREEBSD_ARM_DRAIN_WRITEBUF 1 -+#define TARGET_FREEBSD_ARM_SET_TP 2 -+#define TARGET_FREEBSD_ARM_GET_TP 3 -+ -+#define TARGET_HW_MACHINE "arm" -+#define TARGET_HW_MACHINE_ARCH "armv6" -+ -+#endif /* !__ARCH_SYSCALL_H_ */ -diff --git a/bsd-user/arm/target_arch.h b/bsd-user/arm/target_arch.h -new file mode 100644 -index 0000000..b5c5ddb ---- /dev/null -+++ b/bsd-user/arm/target_arch.h -@@ -0,0 +1,10 @@ -+ -+#ifndef _TARGET_ARCH_H_ -+#define _TARGET_ARCH_H_ -+ -+#include "qemu.h" -+ -+void target_cpu_set_tls(CPUARMState *env, target_ulong newtls); -+target_ulong target_cpu_get_tls(CPUARMState *env); -+ -+#endif /* !_TARGET_ARCH_H_ */ -diff --git a/bsd-user/arm/target_arch_cpu.c b/bsd-user/arm/target_arch_cpu.c -new file mode 100644 -index 0000000..d94a32a ---- /dev/null -+++ b/bsd-user/arm/target_arch_cpu.c -@@ -0,0 +1,27 @@ -+/* -+ * arm 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 "target_arch.h" -+ -+void target_cpu_set_tls(CPUARMState *env, target_ulong newtls) -+{ -+ env->cp15.c13_tls2 = newtls; -+} -+ -+target_ulong target_cpu_get_tls(CPUARMState *env) -+{ -+ return (env->cp15.c13_tls2); -+} -diff --git a/bsd-user/arm/target_arch_cpu.h b/bsd-user/arm/target_arch_cpu.h -new file mode 100644 -index 0000000..3eeb34a ---- /dev/null -+++ b/bsd-user/arm/target_arch_cpu.h -@@ -0,0 +1,375 @@ -+/* -+ * arm cpu init and loop -+ * -+ * Olivier Houchard -+ * -+ * 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 DEBUG_PRINTF(...) fprintf(stderr, __VA_ARGS__) -+#define DEBUG_PRINTF(...) -+ -+#define TARGET_DEFAULT_CPU_MODEL "any" -+ -+#define TARGET_CPU_RESET(env) -+ -+static inline void target_cpu_init(CPUARMState *env, -+ struct target_pt_regs *regs) -+{ -+ int i; -+ -+ cpsr_write(env, regs->uregs[16], 0xffffffff); -+ for (i = 0; i < 16; i++) { -+ env->regs[i] = regs->uregs[i]; -+ } -+} -+ -+static inline int do_strex(CPUARMState *env) -+{ -+ uint32_t val; -+ int size; -+ int rc = 1; -+ int segv = 0; -+ uint32_t addr; -+ start_exclusive(); -+ addr = env->exclusive_addr; -+ if (addr != env->exclusive_test) { -+ goto fail; -+ } -+ size = env->exclusive_info & 0xf; -+ switch (size) { -+ case 0: -+ segv = get_user_u8(val, addr); -+ break; -+ case 1: -+ segv = get_user_u16(val, addr); -+ break; -+ case 2: -+ case 3: -+ segv = get_user_u32(val, addr); -+ break; -+ default: -+ abort(); -+ } -+ if (segv) { -+ env->cp15.c6_data = addr; -+ goto done; -+ } -+ if (val != env->exclusive_val) { -+ goto fail; -+ } -+ if (size == 3) { -+ segv = get_user_u32(val, addr + 4); -+ if (segv) { -+ env->cp15.c6_data = addr + 4; -+ goto done; -+ } -+ if (val != env->exclusive_high) { -+ goto fail; -+ } -+ } -+ val = env->regs[(env->exclusive_info >> 8) & 0xf]; -+ switch (size) { -+ case 0: -+ segv = put_user_u8(val, addr); -+ break; -+ case 1: -+ segv = put_user_u16(val, addr); -+ break; -+ case 2: -+ case 3: -+ segv = put_user_u32(val, addr); -+ break; -+ } -+ if (segv) { -+ env->cp15.c6_data = addr; -+ goto done; -+ } -+ if (size == 3) { -+ val = env->regs[(env->exclusive_info >> 12) & 0xf]; -+ segv = put_user_u32(val, addr + 4); -+ if (segv) { -+ env->cp15.c6_data = addr + 4; -+ goto done; -+ } -+ } -+ rc = 0; -+fail: -+ env->regs[15] += 4; -+ env->regs[(env->exclusive_info >> 4) & 0xf] = rc; -+done: -+ end_exclusive(); -+ return segv; -+} -+ -+static inline void target_cpu_loop(CPUARMState *env) -+{ -+ int trapnr; -+ target_siginfo_t info; -+ unsigned int n; -+ uint32_t addr; -+ CPUState *cs = CPU(arm_env_get_cpu(env)); -+ -+ for (;;) { -+ DEBUG_PRINTF("CPU_LOOPING\n"); -+ cpu_exec_start(cs); -+ DEBUG_PRINTF("EXECUTING...\n"); -+ trapnr = cpu_arm_exec(env); -+ DEBUG_PRINTF("trapnr %d\n", trapnr); -+ cpu_exec_end(cs); -+ switch (trapnr) { -+ case EXCP_UDEF: -+ { -+ /* See arm/arm/undefined.c undefinedinstruction(); */ -+ info.si_addr = env->regs[15]; -+ -+ /* -+ * Make sure the PC is correctly aligned. (It should -+ * be.) -+ */ -+ if ((info.si_addr & 3) != 0) { -+ info.si_signo = SIGILL; -+ info.si_errno = 0; -+ info.si_code = TARGET_ILL_ILLADR; -+ queue_signal(env, info.si_signo, &info); -+ } else { -+ int rc = 0; -+#ifdef NOT_YET -+ uint32_t opcode; -+ -+ /* -+ * Get the opcode. -+ * -+ * FIXME - what to do if get_user() fails? -+ */ -+ get_user_u32(opcode, env->regs[15]); -+ -+ /* Check the opcode with CP handlers we may have. */ -+ rc = EmulateAll(opcode, &ts-fpa, env); -+#endif /* NOT_YET */ -+ if (rc == 0) { -+ /* illegal instruction */ -+ info.si_signo = SIGILL; -+ info.si_errno = 0; -+ info.si_code = TARGET_ILL_ILLOPC; -+ queue_signal(env, info.si_signo, &info); -+ } -+ } -+ } -+ break; -+ case EXCP_SWI: -+ case EXCP_BKPT: -+ { -+ unsigned int insn; -+#ifdef FREEBSD_ARM_OABI -+ env->eabi = 0; -+#else -+ env->eabi = 1; -+#endif -+ /* -+ * system call -+ * See arm/arm/trap.c cpu_fetch_syscall_args() -+ */ -+ if (trapnr == EXCP_BKPT) { -+ if (env->thumb) { -+ if (env->eabi) { -+ n = env->regs[7]; -+ } else { -+ /* FIXME - what to do if get_user() fails? */ -+ get_user_u16(insn, env->regs[15]); -+ n = insn & 0xff; -+ } -+ env->regs[15] += 2; -+ } else { -+ if (env->eabi) { -+ n = env->regs[7]; -+ } else { -+ /* FIXME - what to do if get_user() fails? */ -+ get_user_u32(insn, env->regs[15]); -+ n = (insn & 0xf) | ((insn >> 4) & 0xff0); -+ } -+ env->regs[15] += 4; -+ } -+ } else { /* trapnr != EXCP_BKPT */ -+ if (env->thumb) { -+ if (env->eabi) { -+ n = env->regs[7]; -+ } else { -+ /* FIXME - what to do if get_user() fails? */ -+ get_user_u16(insn, env->regs[15] - 2); -+ n = insn & 0xff; -+ } -+ } else { -+ if (env->eabi) { -+ n = env->regs[7]; -+ } else { -+ /* FIXME - what to do if get_user() fails? */ -+ get_user_u32(insn, env->regs[15] - 4); -+ n = insn & 0xffffff; -+ } -+ } -+ } -+ DEBUG_PRINTF("AVANT CALL %d\n", n); -+ if (bsd_type == target_freebsd) { -+ int ret; -+ abi_ulong params = get_sp_from_cpustate(env); -+ int32_t syscall_nr = n; -+ int32_t arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8; -+ -+ /* See arm/arm/trap.c cpu_fetch_syscall_args() */ -+ if (syscall_nr == TARGET_FREEBSD_NR_syscall) { -+ syscall_nr = env->regs[0]; -+ arg1 = env->regs[1]; -+ arg2 = env->regs[2]; -+ arg3 = env->regs[3]; -+ 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); -+ arg8 = 0; -+ } else if (syscall_nr == TARGET_FREEBSD_NR___syscall) { -+#ifdef TARGET_WORDS_BIGENDIAN -+ syscall_nr = env->regs[1]; -+#else -+ syscall_nr = env->regs[0]; -+#endif -+ arg1 = env->regs[2]; -+ arg2 = env->regs[3]; -+ 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); -+ arg7 = 0; -+ arg8 = 0; -+ } else { -+ arg1 = env->regs[0]; -+ arg2 = env->regs[1]; -+ arg3 = env->regs[2]; -+ arg4 = env->regs[3]; -+ 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); -+ } -+ ret = do_freebsd_syscall(env, syscall_nr, arg1, arg2, arg3, -+ arg4, arg5, arg6, arg7, arg8); -+ /* -+ * Compare to arm/arm/vm_machdep.c -+ * cpu_set_syscall_retval() -+ */ -+ /* XXX armeb may need some extra magic here */ -+ if (-TARGET_EJUSTRETURN == ret) { -+ /* -+ * Returning from a successful sigreturn syscall. -+ * Avoid clobbering register state. -+ */ -+ break; -+ } -+ /* -+ * XXX Need to handle ERESTART. Backup the PC by -+ * 1 instruction. -+ */ -+ if ((unsigned int)ret >= (unsigned int)(-515)) { -+ ret = -ret; -+ cpsr_write(env, CPSR_C, CPSR_C); -+ env->regs[0] = ret; -+ } else { -+ cpsr_write(env, 0, CPSR_C); -+ env->regs[0] = ret; /* XXX need to handle lseek()? */ -+ /* env->regs[1] = 0; */ -+ } -+ } /* else if (bsd_type == target_openbsd)... */ -+ else { -+ fprintf(stderr, "qemu: bsd_type (= %d) syscall " -+ "not supported\n", bsd_type); -+ } -+ DEBUG_PRINTF("APRES CALL\n"); -+ } -+ break; -+ case EXCP_INTERRUPT: -+ /* just indicate that signals should be handled asap */ -+ break; -+ case EXCP_PREFETCH_ABORT: -+ /* See arm/arm/trap.c prefetch_abort_handler() */ -+ addr = env->cp15.c6_insn; -+ goto do_segv; -+ case EXCP_DATA_ABORT: -+ /* See arm/arm/trap.c data_abort_handler() */ -+ addr = env->cp15.c6_data; -+ do_segv: -+ { -+ info.si_signo = SIGSEGV; -+ info.si_errno = 0; -+ /* XXX: check env->error_code */ -+ info.si_code = 0; -+ info.si_addr = addr; -+ queue_signal(env, info.si_signo, &info); -+ } -+ break; -+ case EXCP_DEBUG: -+ { -+ 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); -+ } -+ } -+ break; -+ /* XXX case EXCP_KERNEL_TRAP: */ -+ case EXCP_STREX: -+ if (do_strex(env)) { -+ addr = env->cp15.c6_data; -+ goto do_segv; -+ } -+ break; -+ default: -+ fprintf(stderr, "qemu: unhandled CPU exception 0x%x - aborting\n", -+ trapnr); -+ cpu_dump_state(cs, stderr, fprintf, 0); -+ abort(); -+ } /* switch() */ -+ process_pending_signals(env); -+ } /* for (;;) */ -+} -+ -+static inline void target_cpu_clone_regs(CPUARMState *env, target_ulong newsp) -+{ -+ if (newsp) -+ env->regs[13] = newsp; -+ env->regs[0] = 0; -+} -+ -+static inline void target_cpu_reset(CPUArchState *cpu) -+{ -+} -+ -+#endif /* !_TARGET_ARCH_CPU_H */ -diff --git a/bsd-user/arm/target_arch_elf.h b/bsd-user/arm/target_arch_elf.h -new file mode 100644 -index 0000000..c408cea ---- /dev/null -+++ b/bsd-user/arm/target_arch_elf.h -@@ -0,0 +1,54 @@ -+/* -+ * arm ELF 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 _TARGET_ARCH_ELF_H_ -+#define _TARGET_ARCH_ELF_H_ -+ -+#define ELF_START_MMAP 0x80000000 -+ -+#define elf_check_arch(x) ( (x) == EM_ARM ) -+ -+#define ELF_CLASS ELFCLASS32 -+#ifdef TARGET_WORDS_BIGENDIAN -+#define ELF_DATA ELFDATA2MSB -+#else -+#define ELF_DATA ELFDATA2LSB -+#endif -+#define ELF_ARCH EM_ARM -+ -+#define USE_ELF_CORE_DUMP -+#define ELF_EXEC_PAGESIZE 4096 -+ -+enum -+{ -+ ARM_HWCAP_ARM_SWP = 1 << 0, -+ ARM_HWCAP_ARM_HALF = 1 << 1, -+ ARM_HWCAP_ARM_THUMB = 1 << 2, -+ ARM_HWCAP_ARM_26BIT = 1 << 3, -+ ARM_HWCAP_ARM_FAST_MULT = 1 << 4, -+ ARM_HWCAP_ARM_FPA = 1 << 5, -+ ARM_HWCAP_ARM_VFP = 1 << 6, -+ ARM_HWCAP_ARM_EDSP = 1 << 7, -+}; -+ -+#define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF \ -+ | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT \ -+ | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP) -+ -+ -+#endif /* _TARGET_ARCH_ELF_H_ */ -diff --git a/bsd-user/arm/target_arch_signal.h b/bsd-user/arm/target_arch_signal.h -new file mode 100644 -index 0000000..048bd4f ---- /dev/null -+++ b/bsd-user/arm/target_arch_signal.h -@@ -0,0 +1,257 @@ -+/* -+ * arm signal 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 _TARGET_ARCH_SIGNAL_H_ -+#define _TARGET_ARCH_SIGNAL_H_ -+ -+#include "cpu.h" -+ -+#define TARGET_REG_R0 0 -+#define TARGET_REG_R1 1 -+#define TARGET_REG_R2 2 -+#define TARGET_REG_R3 3 -+#define TARGET_REG_R4 4 -+#define TARGET_REG_R5 5 -+#define TARGET_REG_R6 6 -+#define TARGET_REG_R7 7 -+#define TARGET_REG_R8 8 -+#define TARGET_REG_R9 9 -+#define TARGET_REG_R10 10 -+#define TARGET_REG_R11 11 -+#define TARGET_REG_R12 12 -+#define TARGET_REG_R13 13 -+#define TARGET_REG_R14 14 -+#define TARGET_REG_R15 15 -+#define TARGET_REG_CPSR 16 -+#define TARGET__NGREG 17 -+/* Convenience synonyms */ -+#define TARGET_REG_FP TARGET_REG_R11 -+#define TARGET_REG_SP TARGET_REG_R13 -+#define TARGET_REG_LR TARGET_REG_R14 -+#define TARGET_REG_PC TARGET_REG_R15 -+ -+#define TARGET_INSN_SIZE 4 /* arm instruction size */ -+ -+/* Size of the signal trampolin code. See _sigtramp(). */ -+#define TARGET_SZSIGCODE ((abi_ulong)(8 * TARGET_INSN_SIZE)) -+ -+/* compare to arm/include/_limits.h */ -+#define TARGET_MINSIGSTKSZ (1024 * 4) /* min sig stack size */ -+#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) /* recommended size */ -+ -+/* arm/arm/machdep.c */ -+#define TARGET_MC_GET_CLEAR_RET 0x0001 -+#define TARGET_MC_ADD_MAGIC 0x0002 -+#define TARGET_MC_SET_ONSTACK 0x0004 -+ -+struct target_sigcontext { -+ target_sigset_t sc_mask; /* signal mask to retstore */ -+ int32_t sc_onstack; /* sigstack state to restore */ -+ abi_long sc_pc; /* pc at time of signal */ -+ abi_long sc_reg[32]; /* processor regs 0 to 31 */ -+ abi_long mullo, mulhi; /* mullo and mulhi registers */ -+ int32_t sc_fpused; /* fp has been used */ -+ abi_long sc_fpregs[33]; /* fp regs 0 to 31 & csr */ -+ abi_long sc_fpc_eir; /* fp exception instr reg */ -+ /* int32_t reserved[8]; */ -+}; -+ -+typedef struct { -+ uint32_t __fp_fpsr; -+ struct { -+ uint32_t __fp_exponent; -+ uint32_t __fp_mantissa_hi; -+ uint32_t __fp_mantissa_lo; -+ } __fp_fr[8]; -+} target__fpregset_t; -+ -+typedef struct { -+ uint32_t __vfp_fpscr; -+ uint32_t __vfp_fstmx[33]; -+ uint32_t __vfp_fpsid; -+} target__vfpregset_t; -+ -+typedef struct target_mcontext { -+ uint32_t __gregs[TARGET__NGREG]; -+ union { -+ target__fpregset_t __fpregs; -+ target__vfpregset_t __vfpregs; -+ } __fpu; -+} target_mcontext_t; -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ abi_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __spare__[4]; -+} target_ucontext_t; -+ -+struct target_sigframe { -+ target_siginfo_t sf_si; /* saved siginfo */ -+ target_ucontext_t sf_uc; /* saved ucontext */ -+}; -+ -+ -+/* compare to sys/arm/include/frame.h */ -+struct target_trapframe { -+ abi_ulong tf_spsr; /* Zero on arm26 */ -+ abi_ulong tf_r0; -+ abi_ulong tf_r1; -+ abi_ulong tf_r2; -+ abi_ulong tf_r3; -+ abi_ulong tf_r4; -+ abi_ulong tf_r5; -+ abi_ulong tf_r6; -+ abi_ulong tf_r7; -+ abi_ulong tf_r8; -+ abi_ulong tf_r9; -+ abi_ulong tf_r10; -+ abi_ulong tf_r11; -+ abi_ulong tf_r12; -+ abi_ulong tf_usr_sp; -+ abi_ulong tf_usr_lr; -+ abi_ulong tf_svc_sp; /* Not used on arm26 */ -+ abi_ulong tf_svc_lr; /* Not used on arm26 */ -+ abi_ulong tf_pc; -+}; -+ -+/* -+ * Compare to arm/arm/machdep.c sendsig() -+ * Assumes that target stack frame memory is locked. -+ */ -+static inline abi_long -+set_sigtramp_args(CPUARMState *regs, int sig, struct target_sigframe *frame, -+ abi_ulong frame_addr, struct target_sigaction *ka) -+{ -+ /* -+ * Arguments to signal handler: -+ * r0 = signal number -+ * r1 = siginfo pointer -+ * r2 = ucontext pointer -+ * r5 = ucontext pointer -+ * pc = signal handler pointer -+ * sp = sigframe struct pointer -+ * lr = sigtramp at base of user stack -+ */ -+ -+ regs->regs[0] = sig; -+ regs->regs[1] = frame_addr + -+ offsetof(struct target_sigframe, sf_si); -+ regs->regs[2] = frame_addr + -+ offsetof(struct target_sigframe, sf_uc); -+ -+ /* the trampoline uses r5 as the uc address */ -+ regs->regs[5] = frame_addr + -+ offsetof(struct target_sigframe, sf_uc); -+ regs->regs[TARGET_REG_PC] = ka->_sa_handler; -+ regs->regs[TARGET_REG_SP] = frame_addr; -+ regs->regs[TARGET_REG_LR] = TARGET_PS_STRINGS - TARGET_SZSIGCODE; -+ -+ return 0; -+} -+ -+/* -+ * Compare to arm/arm/machdep.c get_mcontext() -+ * Assumes that the memory is locked if mcp points to user memory. -+ */ -+static inline abi_long get_mcontext(CPUARMState *regs, target_mcontext_t *mcp, -+ int flags) -+{ -+ int err = 0; -+ uint32_t *gr = mcp->__gregs; -+ -+ -+ if (flags & TARGET_MC_GET_CLEAR_RET) { -+ gr[TARGET_REG_R0] = 0; -+ } else { -+ gr[TARGET_REG_R0] = tswap32(regs->regs[0]); -+ } -+ -+ gr[TARGET_REG_R1] = tswap32(regs->regs[1]); -+ gr[TARGET_REG_R2] = tswap32(regs->regs[2]); -+ gr[TARGET_REG_R3] = tswap32(regs->regs[3]); -+ gr[TARGET_REG_R4] = tswap32(regs->regs[4]); -+ gr[TARGET_REG_R5] = tswap32(regs->regs[5]); -+ gr[TARGET_REG_R6] = tswap32(regs->regs[6]); -+ gr[TARGET_REG_R7] = tswap32(regs->regs[7]); -+ gr[TARGET_REG_R8] = tswap32(regs->regs[8]); -+ gr[TARGET_REG_R9] = tswap32(regs->regs[9]); -+ gr[TARGET_REG_R10] = tswap32(regs->regs[10]); -+ gr[TARGET_REG_R11] = tswap32(regs->regs[11]); -+ gr[TARGET_REG_R12] = tswap32(regs->regs[12]); -+ -+ gr[TARGET_REG_SP] = tswap32(regs->regs[13]); -+ gr[TARGET_REG_LR] = tswap32(regs->regs[14]); -+ gr[TARGET_REG_PC] = tswap32(regs->regs[15]); -+ gr[TARGET_REG_CPSR] = tswap32(cpsr_read(regs)); -+ -+ return err; -+} -+ -+/* Compare to arm/arm/machdep.c set_mcontext() */ -+static inline abi_long set_mcontext(CPUARMState *regs, target_mcontext_t *mcp, -+ int srflag) -+{ -+ int err = 0; -+ const uint32_t *gr = mcp->__gregs; -+ uint32_t cpsr; -+ -+ regs->regs[0] = tswap32(gr[TARGET_REG_R0]); -+ regs->regs[1] = tswap32(gr[TARGET_REG_R1]); -+ regs->regs[2] = tswap32(gr[TARGET_REG_R2]); -+ regs->regs[3] = tswap32(gr[TARGET_REG_R3]); -+ regs->regs[4] = tswap32(gr[TARGET_REG_R4]); -+ regs->regs[5] = tswap32(gr[TARGET_REG_R5]); -+ regs->regs[6] = tswap32(gr[TARGET_REG_R6]); -+ regs->regs[7] = tswap32(gr[TARGET_REG_R7]); -+ regs->regs[8] = tswap32(gr[TARGET_REG_R8]); -+ regs->regs[9] = tswap32(gr[TARGET_REG_R9]); -+ regs->regs[10] = tswap32(gr[TARGET_REG_R10]); -+ regs->regs[11] = tswap32(gr[TARGET_REG_R11]); -+ regs->regs[12] = tswap32(gr[TARGET_REG_R12]); -+ -+ regs->regs[13] = tswap32(gr[TARGET_REG_SP]); -+ regs->regs[14] = tswap32(gr[TARGET_REG_LR]); -+ regs->regs[15] = tswap32(gr[TARGET_REG_PC]); -+ cpsr = tswap32(gr[TARGET_REG_CPSR]); -+ cpsr_write(regs, cpsr, CPSR_USER | CPSR_EXEC); -+ -+ return err; -+} -+ -+/* Compare to arm/arm/machdep.c sys_sigreturn() */ -+static inline abi_long get_ucontext_sigreturn(CPUARMState *regs, -+ abi_ulong target_sf, abi_ulong *target_uc) -+{ -+ uint32_t cpsr = cpsr_read(regs); -+ -+ *target_uc = 0; -+ -+ if ((cpsr & CPSR_M) != ARM_CPU_MODE_USR || -+ (cpsr & (CPSR_I | CPSR_F)) != 0) { -+ return -TARGET_EINVAL; -+ } -+ -+ *target_uc = target_sf + offsetof(struct target_sigframe, sf_uc); -+ -+ return 0; -+} -+ -+ -+#endif /* !_TARGET_ARCH_SIGNAL_H_ */ -diff --git a/bsd-user/arm/target_arch_sigtramp.h b/bsd-user/arm/target_arch_sigtramp.h -new file mode 100644 -index 0000000..98dc313 ---- /dev/null -+++ b/bsd-user/arm/target_arch_sigtramp.h -@@ -0,0 +1,33 @@ -+ -+#ifndef _TARGET_ARCH_SIGTRAMP_H_ -+#define _TARGET_ARCH_SIGTRAMP_H_ -+ -+/* Compare to arm/arm/locore.S ENTRY_NP(sigcode) */ -+static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc, -+ unsigned sys_sigreturn) -+{ -+ int i; -+ uint32_t sys_exit = TARGET_FREEBSD_NR_exit; -+ /* -+ * The code has to load r7 manually rather than using -+ * "ldr r7, =SYS_return to make sure the size of the -+ * code is correct. -+ */ -+ uint32_t sigtramp_code[] = { -+ /* 1 */ 0xE1A0000D, /* mov r0, sp */ -+ /* 2 */ 0xE59F700C, /* ldr r7, [pc, #12] */ -+ /* 3 */ 0xEF000000 + sys_sigreturn, /* swi (SYS_sigreturn) */ -+ /* 4 */ 0xE59F7008, /* ldr r7, [pc, #8] */ -+ /* 5 */ 0xEF000000 + sys_exit, /* swi (SYS_exit)*/ -+ /* 6 */ 0xEAFFFFFA, /* b . -16 */ -+ /* 7 */ sys_sigreturn, -+ /* 8 */ sys_exit -+ }; -+ -+ for (i = 0; i < 8; i++) { -+ tswap32s(&sigtramp_code[i]); -+ } -+ -+ return memcpy_to_target(offset, sigtramp_code, TARGET_SZSIGCODE); -+} -+#endif /* _TARGET_ARCH_SIGTRAMP_H_ */ -diff --git a/bsd-user/arm/target_arch_sysarch.h b/bsd-user/arm/target_arch_sysarch.h -new file mode 100644 -index 0000000..96d617a ---- /dev/null -+++ b/bsd-user/arm/target_arch_sysarch.h -@@ -0,0 +1,78 @@ -+/* -+ * arm sysarch() system call emulation -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef __ARCH_SYSARCH_H_ -+#define __ARCH_SYSARCH_H_ -+ -+#include "syscall.h" -+#include "target_arch.h" -+ -+static inline abi_long do_freebsd_arch_sysarch(CPUARMState *env, int op, -+ abi_ulong parms) -+{ -+ int ret = 0; -+ -+ switch (op) { -+ case TARGET_FREEBSD_ARM_SYNC_ICACHE: -+ case TARGET_FREEBSD_ARM_DRAIN_WRITEBUF: -+ break; -+ -+ case TARGET_FREEBSD_ARM_SET_TP: -+ target_cpu_set_tls(env, parms); -+ break; -+ -+ case TARGET_FREEBSD_ARM_GET_TP: -+ ret = target_cpu_get_tls(env); -+ break; -+ -+ default: -+ ret = -TARGET_EINVAL; -+ break; -+ } -+ return ret; -+} -+ -+static inline void do_freebsd_arch_print_sysarch( -+ const struct syscallname *name, abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6) -+{ -+ -+ switch (arg1) { -+ case TARGET_FREEBSD_ARM_SYNC_ICACHE: -+ gemu_log("%s(ARM_SYNC_ICACHE, ...)", name->name); -+ break; -+ -+ case TARGET_FREEBSD_ARM_DRAIN_WRITEBUF: -+ gemu_log("%s(ARM_DRAIN_WRITEBUF, ...)", name->name); -+ break; -+ -+ case TARGET_FREEBSD_ARM_SET_TP: -+ gemu_log("%s(ARM_SET_TP, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2); -+ break; -+ -+ case TARGET_FREEBSD_ARM_GET_TP: -+ gemu_log("%s(ARM_GET_TP, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2); -+ break; -+ -+ default: -+ gemu_log("UNKNOWN OP: %d, " TARGET_ABI_FMT_lx ")", (int)arg1, arg2); -+ } -+} -+ -+#endif /*!__ARCH_SYSARCH_H_ */ -diff --git a/bsd-user/arm/target_arch_thread.h b/bsd-user/arm/target_arch_thread.h -new file mode 100644 -index 0000000..e69f612d ---- /dev/null -+++ b/bsd-user/arm/target_arch_thread.h -@@ -0,0 +1,67 @@ -+/* -+ * arm thread support -+ * -+ * 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 _TARGET_ARCH_THREAD_H_ -+#define _TARGET_ARCH_THREAD_H_ -+ -+/* Compare to arm/arm/vm_machdep.c cpu_set_upcall_kse() */ -+static inline void target_thread_set_upcall(CPUARMState *regs, abi_ulong entry, -+ abi_ulong arg, abi_ulong stack_base, abi_ulong stack_size) -+{ -+ abi_ulong sp; -+ -+ /* -+ * Make sure the stack is properly aligned. -+ * arm/include/param.h (STACKLIGN() macro) -+ */ -+ sp = ((u_int)(stack_base + stack_size) & ~(8-1)) - -+ sizeof(struct target_trapframe); -+ -+ /* sp = stack base */ -+ regs->regs[13] = sp; -+ /* pc = start function entry */ -+ regs->regs[15] = entry & 0xfffffffe; -+ /* r0 = arg */ -+ regs->regs[0] = arg; -+ regs->spsr = ARM_CPU_MODE_USR; -+} -+ -+static inline void target_thread_init(struct target_pt_regs *regs, -+ struct image_info *infop) -+{ -+ abi_long stack = infop->start_stack; -+ memset(regs, 0, sizeof(*regs)); -+ regs->ARM_cpsr = 0x10; -+ if (infop->entry & 1) -+ regs->ARM_cpsr |= CPSR_T; -+ regs->ARM_pc = infop->entry & 0xfffffffe; -+ regs->ARM_sp = infop->start_stack; -+ if (bsd_type == target_freebsd) { -+ regs->ARM_lr = infop->entry & 0xfffffffe; -+ } -+ /* FIXME - what to for failure of get_user()? */ -+ get_user_ual(regs->ARM_r2, stack + 8); /* envp */ -+ get_user_ual(regs->ARM_r1, stack + 4); /* envp */ -+ /* XXX: it seems that r0 is zeroed after ! */ -+ regs->ARM_r0 = 0; -+ /* For uClinux PIC binaries. */ -+ /* XXX: Linux does this only on ARM with no MMU (do we care ?) */ -+ regs->ARM_r10 = infop->start_data; -+} -+ -+#endif /* !_TARGET_ARCH_THREAD_H_ */ -diff --git a/bsd-user/arm/target_arch_vmparam.h b/bsd-user/arm/target_arch_vmparam.h -new file mode 100644 -index 0000000..014fc66 ---- /dev/null -+++ b/bsd-user/arm/target_arch_vmparam.h -@@ -0,0 +1,48 @@ -+/* -+ * arm VM parameters 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 _TARGET_ARCH_VMPARAM_H_ -+#define _TARGET_ARCH_VMPARAM_H_ -+ -+#include "cpu.h" -+ -+/* compare to sys/arm/include/vmparam.h */ -+#define TARGET_MAXTSIZ (64UL*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 (2UL*1024*1024) /* initial stack size limit */ -+#define TARGET_MAXSSIZ (8UL*1024*1024) /* max stack size */ -+#define TARGET_SGROWSIZ (128UL*1024) /* amount to grow stack */ -+ -+#define TARGET_RESERVED_VA 0xf7000000 -+ -+ /* KERNBASE - 512 MB */ -+#define TARGET_VM_MAXUSER_ADDRESS (0xc0000000 - (512 * 1024 * 1024)) -+#define TARGET_USRSTACK TARGET_VM_MAXUSER_ADDRESS -+ -+static inline abi_ulong get_sp_from_cpustate(CPUARMState *state) -+{ -+ return state->regs[13]; /* sp */ -+} -+ -+static inline void set_second_rval(CPUARMState *state, abi_ulong retval2) -+{ -+ state->regs[1] = retval2; -+} -+ -+#endif /* ! _TARGET_ARCH_VMPARAM_H_ */ -diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h -new file mode 100644 -index 0000000..fc279a8 ---- /dev/null -+++ b/bsd-user/bsd-file.h -@@ -0,0 +1,1111 @@ -+/* -+ * file related system call shims 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 __BSD_FILE_H_ -+#define __BSD_FILE_H_ -+ -+#include <sys/types.h> -+#include <sys/mount.h> -+#include <sys/uio.h> -+#include <fcntl.h> -+#include <poll.h> -+#include <stdio.h> -+#include <stdlib.h> -+#include <unistd.h> -+ -+#define target_to_host_bitmask(x, tbl) (x) -+ -+#define LOCK_PATH(p, arg) do { \ -+ (p) = lock_user_string(arg); \ -+ if ((p) == NULL) { \ -+ return -TARGET_EFAULT; \ -+ } \ -+} while (0) -+ -+#define UNLOCK_PATH(p, arg) unlock_user((p), (arg), 0) -+ -+struct target_pollfd { -+ int32_t fd; /* file descriptor */ -+ int16_t events; /* requested events */ -+ int16_t revents; /* returned events */ -+}; -+ -+static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr, -+ int count, int copy); -+static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr, -+ int count, int copy); -+extern int __getcwd(char *path, size_t len); -+ -+/* read(2) */ -+static inline abi_long do_bsd_read(abi_long arg1, abi_long arg2, abi_long arg3) -+{ -+ abi_long ret; -+ void *p; -+ -+ p = lock_user(VERIFY_WRITE, arg2, arg3, 0); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(read(arg1, p, arg3)); -+ unlock_user(p, arg2, ret); -+ -+ return ret; -+} -+ -+/* pread(2) */ -+static inline abi_long do_bsd_pread(void *cpu_env, abi_long arg1, -+ abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6) -+{ -+ abi_long ret; -+ void *p; -+ -+ p = lock_user(VERIFY_WRITE, arg2, arg3, 0); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ if (regpairs_aligned(cpu_env) != 0) { -+ arg4 = arg5; -+ arg5 = arg6; -+ } -+ ret = get_errno(pread(arg1, p, arg3, target_offset64(arg4, arg5))); -+ unlock_user(p, arg2, ret); -+ -+ return ret; -+} -+ -+/* readv(2) */ -+static inline abi_long do_bsd_readv(abi_long arg1, abi_long arg2, abi_long arg3) -+{ -+ abi_long ret; -+ int count = arg3; -+ struct iovec *vec; -+ -+ vec = alloca(count * sizeof(struct iovec)); -+ if (vec == NULL) { -+ return -TARGET_ENOMEM; -+ } -+ if (lock_iovec(VERIFY_WRITE, vec, arg2, count, 0) < 0) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(readv(arg1, vec, count)); -+ unlock_iovec(vec, arg2, count, 1); -+ -+ return ret; -+} -+ -+/* write(2) */ -+static inline abi_long do_bsd_write(abi_long arg1, abi_long arg2, abi_long arg3) -+{ -+ abi_long ret; -+ void *p; -+ -+ p = lock_user(VERIFY_READ, arg2, arg3, 1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(write(arg1, p, arg3)); -+ unlock_user(p, arg2, 0); -+ -+ return ret; -+} -+ -+/* pwrite(2) */ -+static inline abi_long do_bsd_pwrite(void *cpu_env, abi_long arg1, -+ abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6) -+{ -+ abi_long ret; -+ void *p; -+ -+ p = lock_user(VERIFY_READ, arg2, arg3, 1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ if (regpairs_aligned(cpu_env) != 0) { -+ arg4 = arg5; -+ arg5 = arg6; -+ } -+ ret = get_errno(pwrite(arg1, p, arg3, target_offset64(arg4, arg5))); -+ unlock_user(p, arg2, 0); -+ -+ return ret; -+} -+ -+/* writev(2) */ -+static inline abi_long do_bsd_writev(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ abi_long ret; -+ int count = arg3; -+ struct iovec *vec; -+ -+ vec = alloca(count * sizeof(struct iovec)); -+ if (vec == NULL) { -+ return -TARGET_ENOMEM; -+ } -+ if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(writev(arg1, vec, count)); -+ unlock_iovec(vec, arg2, count, 0); -+ -+ return ret; -+} -+ -+/* pwritev(2) */ -+static inline abi_long do_bsd_pwritev(void *cpu_env, abi_long arg1, -+ abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6) -+{ -+ abi_long ret; -+ int count = arg3; -+ struct iovec *vec; -+ -+ vec = alloca(count * sizeof(struct iovec)); -+ if (vec == NULL) { -+ return -TARGET_ENOMEM; -+ } -+ if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) { -+ return -TARGET_EFAULT; -+ } -+ if (regpairs_aligned(cpu_env) != 0) { -+ arg4 = arg5; -+ arg5 = arg6; -+ } -+ ret = get_errno(pwritev(arg1, vec, count, target_offset64(arg4, arg5))); -+ unlock_iovec(vec, arg2, count, 0); -+ -+ return ret; -+} -+ -+/* open(2) */ -+static inline abi_long do_bsd_open(abi_long arg1, abi_long arg2, abi_long arg3) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(open(path(p), target_to_host_bitmask(arg2, fcntl_flags_tbl), -+ arg3)); -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* openat(2) */ -+static inline abi_long do_bsd_openat(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg2); -+ ret = get_errno(openat(arg1, path(p), -+ target_to_host_bitmask(arg3, fcntl_flags_tbl), arg4)); -+ UNLOCK_PATH(p, arg2); -+ -+ return ret; -+} -+ -+/* close(2) */ -+static inline abi_long do_bsd_close(abi_long arg1) -+{ -+ -+ return get_errno(close(arg1)); -+} -+ -+/* closefrom(2) */ -+static inline abi_long do_bsd_closefrom(abi_long arg1) -+{ -+ -+ closefrom(arg1); /* returns void */ -+ return get_errno(0); -+} -+ -+/* revoke(2) */ -+static inline abi_long do_bsd_revoke(abi_long arg1) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(revoke(p)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* creat(2) (obsolete) */ -+static inline abi_long do_bsd_creat(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(open(path(p), O_CREAT | O_TRUNC | O_WRONLY, arg2)); -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+ -+/* access(2) */ -+static inline abi_long do_bsd_access(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(access(path(p), arg2)); -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* eaccess(2) */ -+static inline abi_long do_bsd_eaccess(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(eaccess(path(p), arg2)); -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* faccessat(2) */ -+static inline abi_long do_bsd_faccessat(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg2); -+ ret = get_errno(faccessat(arg1, p, arg3, arg4)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg2); -+ -+ return ret; -+} -+ -+/* chdir(2) */ -+static inline abi_long do_bsd_chdir(abi_long arg1) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(chdir(p)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* fchdir(2) */ -+static inline abi_long do_bsd_fchdir(abi_long arg1) -+{ -+ -+ return get_errno(fchdir(arg1)); -+} -+ -+/* rename(2) */ -+static inline abi_long do_bsd_rename(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p1, *p2; -+ -+ LOCK_PATH(p1, arg1); -+ LOCK_PATH(p2, arg2); -+ if (!p1 || !p2) { -+ ret = -TARGET_EFAULT; -+ } else { -+ ret = get_errno(rename(p1, p2)); /* XXX path(p1), path(p2) */ -+ } -+ UNLOCK_PATH(p2, arg2); -+ UNLOCK_PATH(p1, arg1); -+ -+ return ret; -+} -+ -+/* renameat(2) */ -+static inline abi_long do_bsd_renameat(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4) -+{ -+ abi_long ret; -+ void *p1, *p2; -+ -+ LOCK_PATH(p1, arg1); -+ LOCK_PATH(p2, arg2); -+ if (!p1 || !p2) { -+ ret = -TARGET_EFAULT; -+ } else { -+ ret = get_errno(renameat(arg1, p1, arg3, p2)); -+ } -+ UNLOCK_PATH(p2, arg2); -+ UNLOCK_PATH(p1, arg1); -+ -+ return ret; -+} -+ -+/* link(2) */ -+static inline abi_long do_bsd_link(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p1, *p2; -+ -+ LOCK_PATH(p1, arg1); -+ LOCK_PATH(p2, arg2); -+ if (!p1 || !p2) { -+ ret = -TARGET_EFAULT; -+ } else { -+ ret = get_errno(link(p1, p2)); /* XXX path(p1), path(p2) */ -+ } -+ UNLOCK_PATH(p2, arg2); -+ UNLOCK_PATH(p1, arg1); -+ -+ return ret; -+} -+ -+/* linkat(2) */ -+static inline abi_long do_bsd_linkat(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4, abi_long arg5) -+{ -+ abi_long ret; -+ void *p1, *p2; -+ -+ LOCK_PATH(p1, arg2); -+ LOCK_PATH(p2, arg4); -+ if (!p1 || !p2) { -+ ret = -TARGET_EFAULT; -+ } else { -+ ret = get_errno(linkat(arg1, p1, arg3, p2, arg5)); -+ } -+ UNLOCK_PATH(p2, arg4); -+ UNLOCK_PATH(p1, arg2); -+ -+ return ret; -+} -+ -+/* unlink(2) */ -+static inline abi_long do_bsd_unlink(abi_long arg1) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(unlink(p)); /* XXX path(p) */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* unlinkat(2) */ -+static inline abi_long do_bsd_unlinkat(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg2); -+ ret = get_errno(unlinkat(arg1, p, arg3)); /* XXX path(p) */ -+ UNLOCK_PATH(p, arg2); -+ -+ return ret; -+} -+ -+/* mkdir(2) */ -+static inline abi_long do_bsd_mkdir(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(mkdir(p, arg2)); /* XXX path(p) */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+ -+/* mkdirat(2) */ -+static inline abi_long do_bsd_mkdirat(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg2); -+ ret = get_errno(mkdirat(arg1, p, arg3)); -+ UNLOCK_PATH(p, arg2); -+ -+ return ret; -+} -+ -+ -+/* rmdir(2) */ -+static inline abi_long do_bsd_rmdir(abi_long arg1) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(rmdir(p)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* undocumented __getcwd(char *buf, size_t len) system call */ -+static inline abi_long do_bsd___getcwd(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ -+ p = lock_user(VERIFY_WRITE, arg1, arg2, 0); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(__getcwd(p, arg2)); -+ unlock_user(p, arg1, ret); -+ -+ return ret; -+} -+ -+/* dup(2) */ -+static inline abi_long do_bsd_dup(abi_long arg1) -+{ -+ -+ return get_errno(dup(arg1)); -+} -+ -+/* dup2(2) */ -+static inline abi_long do_bsd_dup2(abi_long arg1, abi_long arg2) -+{ -+ -+ return get_errno(dup2(arg1, arg2)); -+} -+ -+/* truncate(2) */ -+static inline abi_long do_bsd_truncate(void *cpu_env, abi_long arg1, -+ abi_long arg2, abi_long arg3, abi_long arg4) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ if (regpairs_aligned(cpu_env) != 0) { -+ arg2 = arg3; -+ arg3 = arg4; -+ } -+ ret = get_errno(truncate(p, target_offset64(arg2, arg3))); -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* ftruncate(2) */ -+static inline abi_long do_bsd_ftruncate(void *cpu_env, abi_long arg1, -+ abi_long arg2, abi_long arg3, abi_long arg4) -+{ -+ -+ if (regpairs_aligned(cpu_env) != 0) { -+ arg2 = arg3; -+ arg3 = arg4; -+ } -+ return get_errno(ftruncate(arg1, target_offset64(arg2, arg3))); -+} -+ -+/* acct(2) */ -+static inline abi_long do_bsd_acct(abi_long arg1) -+{ -+ abi_long ret; -+ void *p; -+ -+ if (arg1 == 0) { -+ ret = get_errno(acct(NULL)); -+ } else { -+ LOCK_PATH(p, arg1); -+ ret = get_errno(acct(path(p))); -+ UNLOCK_PATH(p, arg1); -+ } -+ return ret; -+} -+ -+/* sync(2) */ -+static inline abi_long do_bsd_sync(void) -+{ -+ -+ sync(); -+ return 0; -+} -+ -+/* mount(2) */ -+static inline abi_long do_bsd_mount(abi_long arg1, abi_long arg2, abi_long arg3, -+ abi_long arg4) -+{ -+ abi_long ret; -+ void *p1, *p2; -+ -+ LOCK_PATH(p1, arg1); -+ LOCK_PATH(p2, arg2); -+ if (!p1 || !p2) { -+ ret = -TARGET_EFAULT; -+ } else { -+ /* -+ * XXX arg4 should be locked, but it isn't clear how to do that -+ * since it's it may be not be a NULL-terminated string. -+ */ -+ if (arg4 == 0) { -+ ret = get_errno(mount(p1, p2, arg3, NULL)); /* XXX path(p2)? */ -+ } else { -+ ret = get_errno(mount(p1, p2, arg3, g2h(arg4))); /* XXX path(p2)? */ -+ } -+ } -+ UNLOCK_PATH(p2, arg2); -+ UNLOCK_PATH(p1, arg1); -+ -+ return ret; -+} -+ -+/* unmount(2) */ -+static inline abi_long do_bsd_unmount(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(unmount(p, arg2)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* nmount(2) */ -+static inline abi_long do_bsd_nmount(abi_long arg1, abi_long count, -+ abi_long flags) -+{ -+ abi_long ret; -+ struct iovec *vec; -+ -+ vec = alloca(count * sizeof(struct iovec)); -+ if (lock_iovec(VERIFY_READ, vec, arg1, count, 1) < 0) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(nmount(vec, count, flags)); -+ unlock_iovec(vec, arg1, count, 0); -+ -+ return ret; -+} -+ -+/* symlink(2) */ -+static inline abi_long do_bsd_symlink(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p1, *p2; -+ -+ LOCK_PATH(p1, arg1); -+ LOCK_PATH(p2, arg2); -+ if (!p1 || !p2) { -+ ret = -TARGET_EFAULT; -+ } else { -+ ret = get_errno(symlink(p1, p2)); /* XXX path(p1), path(p2) */ -+ } -+ UNLOCK_PATH(p2, arg2); -+ UNLOCK_PATH(p1, arg1); -+ -+ return ret; -+} -+ -+/* symlinkat(2) */ -+static inline abi_long do_bsd_symlinkat(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ abi_long ret; -+ void *p1, *p2; -+ -+ LOCK_PATH(p1, arg1); -+ LOCK_PATH(p2, arg3); -+ if (!p1 || !p2) { -+ ret = -TARGET_EFAULT; -+ } else { -+ ret = get_errno(symlinkat(p1, arg2, p2)); /* XXX path(p1), path(p2) */ -+ } -+ UNLOCK_PATH(p2, arg3); -+ UNLOCK_PATH(p1, arg1); -+ -+ return ret; -+} -+ -+/* readlink(2) */ -+static inline abi_long do_bsd_readlink(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ abi_long ret; -+ void *p1, *p2; -+ -+ LOCK_PATH(p1, arg1); -+ p2 = lock_user(VERIFY_WRITE, arg2, arg3, 0); -+ if (!p1 || !p2) { -+ ret = -TARGET_EFAULT; -+ } else { -+ ret = get_errno(readlink(path(p1), p2, arg3)); -+ } -+ unlock_user(p2, arg2, ret); -+ UNLOCK_PATH(p1, arg1); -+ -+ return ret; -+} -+ -+/* readlinkat(2) */ -+static inline abi_long do_bsd_readlinkat(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4) -+{ -+ abi_long ret; -+ void *p1, *p2; -+ -+ LOCK_PATH(p1, arg2); -+ p2 = lock_user(VERIFY_WRITE, arg3, arg4, 0); -+ if (!p1 || !p2) { -+ ret = -TARGET_EFAULT; -+ } else { -+ ret = get_errno(readlinkat(arg1, p1, p2, arg4)); -+ } -+ unlock_user(p2, arg3, ret); -+ UNLOCK_PATH(p1, arg2); -+ -+ return ret; -+} -+ -+/* chmod(2) */ -+static inline abi_long do_bsd_chmod(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(chmod(p, arg2)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* fchmod(2) */ -+static inline abi_long do_bsd_fchmod(abi_long arg1, abi_long arg2) -+{ -+ -+ return get_errno(fchmod(arg1, arg2)); -+} -+ -+/* lchmod(2) */ -+static inline abi_long do_bsd_lchmod(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(lchmod(p, arg2)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* fchmodat(2) */ -+static inline abi_long do_bsd_fchmodat(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg2); -+ ret = get_errno(fchmodat(arg1, p, arg3, arg4)); -+ UNLOCK_PATH(p, arg2); -+ -+ return ret; -+} -+ -+/* mknod(2) */ -+static inline abi_long do_bsd_mknod(abi_long arg1, abi_long arg2, abi_long arg3) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(mknod(p, arg2, arg3)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* mknodat(2) */ -+static inline abi_long do_bsd_mknodat(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg2); -+ ret = get_errno(mknodat(arg1, p, arg3, arg4)); -+ UNLOCK_PATH(p, arg2); -+ -+ return ret; -+} -+ -+/* chown(2) */ -+static inline abi_long do_bsd_chown(abi_long arg1, abi_long arg2, abi_long arg3) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(chown(p, arg2, arg3)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* fchown(2) */ -+static inline abi_long do_bsd_fchown(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ return get_errno(fchown(arg1, arg2, arg3)); -+} -+ -+/* lchown(2) */ -+static inline abi_long do_bsd_lchown(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(lchown(p, arg2, arg3)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* fchownat(2) */ -+static inline abi_long do_bsd_fchownat(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4, abi_long arg5) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg2); -+ ret = get_errno(fchownat(arg1, p, arg3, arg4, arg5)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg2); -+ -+ return ret; -+} -+ -+/* chflags(2) */ -+static inline abi_long do_bsd_chflags(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(chflags(p, arg2)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* lchflags(2) */ -+static inline abi_long do_bsd_lchflags(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(lchflags(p, arg2)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* fchflags(2) */ -+static inline abi_long do_bsd_fchflags(abi_long arg1, abi_long arg2) -+{ -+ -+ return get_errno(fchflags(arg1, arg2)); -+} -+ -+/* chroot(2) */ -+static inline abi_long do_bsd_chroot(abi_long arg1) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(chroot(p)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* flock(2) */ -+static abi_long do_bsd_flock(abi_long arg1, abi_long arg2) -+{ -+ -+ return get_errno(flock(arg1, arg2)); -+} -+ -+/* mkfifo(2) */ -+static inline abi_long do_bsd_mkfifo(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(mkfifo(p, arg2)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* mkfifoat(2) */ -+static inline abi_long do_bsd_mkfifoat(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg2); -+ ret = get_errno(mkfifoat(arg1, p, arg3)); -+ UNLOCK_PATH(p, arg2); -+ -+ return ret; -+} -+ -+/* pathconf(2) */ -+static inline abi_long do_bsd_pathconf(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(pathconf(p, arg2)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* lpathconf(2) */ -+static inline abi_long do_bsd_lpathconf(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(lpathconf(p, arg2)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* fpathconf(2) */ -+static inline abi_long do_bsd_fpathconf(abi_long arg1, abi_long arg2) -+{ -+ -+ return get_errno(fpathconf(arg1, arg2)); -+} -+ -+/* undelete(2) */ -+static inline abi_long do_bsd_undelete(abi_long arg1) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(undelete(p)); /* XXX path(p)? */ -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* poll(2) */ -+static abi_long do_bsd_poll(abi_long arg1, abi_long arg2, abi_long arg3) -+{ -+ abi_long ret; -+ nfds_t i, nfds = arg2; -+ int timeout = arg3; -+ struct pollfd *pfd; -+ struct target_pollfd *target_pfd; -+ -+ target_pfd = lock_user(VERIFY_WRITE, arg1, -+ sizeof(struct target_pollfd) * nfds, 1); -+ if (!target_pfd) { -+ return -TARGET_EFAULT; -+ } -+ pfd = alloca(sizeof(struct pollfd) * nfds); -+ for (i = 0; i < nfds; i++) { -+ pfd[i].fd = tswap32(target_pfd[i].fd); -+ pfd[i].events = tswap16(target_pfd[i].events); -+ } ret = get_errno(poll(pfd, nfds, timeout)); -+ if (!is_error(ret)) { -+ for (i = 0; i < nfds; i++) { -+ target_pfd[i].revents = tswap16(pfd[i].revents); -+ } -+ } -+ unlock_user(target_pfd, arg1, sizeof(struct target_pollfd) * nfds); -+ -+ return ret; -+} -+ -+/* -+ * undocumented openbsd_poll(struct pollfd *fds, u_int nfds, int -+ * timeout) system call. -+ */ -+static abi_long do_bsd_openbsd_poll(abi_long arg1, abi_long arg2, abi_long arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall openbsd_poll()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* lseek(2) */ -+static abi_long do_bsd_lseek(void *cpu_env, abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4, abi_long arg5) -+{ -+ abi_long ret; -+#if TARGET_ABI_BITS == 32 -+ int64_t res; -+ -+ /* 32-bit arch's use two 32 registers for 64 bit return value */ -+ if (regpairs_aligned(cpu_env) != 0) { -+ res = lseek(arg1, target_offset64(arg3, arg4), arg5); -+ } else { -+ res = lseek(arg1, target_offset64(arg2, arg3), arg4); -+ } -+ if (res == -1) { -+ ret = get_errno(res); -+ } else { -+ ret = res & 0xFFFFFFFF; -+ set_second_rval(cpu_env, (res >> 32) & 0xFFFFFFFF); -+ } -+#else -+ ret = get_errno(lseek(arg1, arg2, arg3)); -+#endif -+ return ret; -+} -+ -+/* pipe(2) */ -+static abi_long do_bsd_pipe(void *cpu_env, abi_long arg1) -+{ -+ abi_long ret; -+ int host_pipe[2]; -+ int host_ret = pipe(host_pipe); -+ -+ if (host_ret != -1) { -+ set_second_rval(cpu_env, host_pipe[1]); -+ ret = host_pipe[0]; -+ } else { -+ ret = get_errno(host_ret); -+ } -+ return ret; -+} -+ -+/* swapon(2) */ -+static abi_long do_bsd_swapon(abi_long arg1) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(swapon(path(p))); -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* swapoff(2) */ -+static abi_long do_bsd_swapoff(abi_long arg1) -+{ -+ abi_long ret; -+ void *p; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(swapoff(path(p))); -+ UNLOCK_PATH(p, arg1); -+ -+ return ret; -+} -+ -+/* -+ * undocumented freebsd6_pread(int fd, void *buf, size_t nbyte, int pad, -+ * off_t offset) system call. -+ */ -+static abi_long do_bsd_freebsd6_pread(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4, abi_long arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall freebsd6_pread()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * undocumented freebsd6_pwrite(int fd, void *buf, size_t nbyte, int pad, -+ * off_t offset) system call. -+ */ -+static abi_long do_bsd_freebsd6_pwrite(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4, abi_long arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall freebsd6_pwrite()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * undocumented freebsd6_lseek(int fd, int pad, off_t offset, int whence) -+ * system call. -+ */ -+static abi_long do_bsd_freebsd6_lseek(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4) -+{ -+ -+ qemu_log("qemu: Unsupported syscall freebsd6_lseek()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * undocumented freebsd6_truncate(char *path, int pad, off_t offset) system -+ * call. -+ */ -+static abi_long do_bsd_freebsd6_truncate(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall freebsd6_truncate()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * undocumented freebsd6_ftruncate(int fd, int pad, off_t offset) system -+ * call. -+ */ -+static abi_long do_bsd_freebsd6_ftruncate(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall freebsd6_ftruncate()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* !__BSD_FILE_H_ */ -diff --git a/bsd-user/bsd-ioctl.c b/bsd-user/bsd-ioctl.c -new file mode 100644 -index 0000000..95505a4 ---- /dev/null -+++ b/bsd-user/bsd-ioctl.c -@@ -0,0 +1,448 @@ -+/* -+ * BSD ioctl(2) 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/ioctl.h> -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 -+#include <sys/_termios.h> -+#else -+#include <sys/termios.h> -+#endif -+#include <sys/ttycom.h> -+#include <sys/filio.h> -+ -+#include "qemu.h" -+#include "qemu-common.h" -+ -+#include "bsd-ioctl.h" -+#include "os-ioctl-filio.h" -+#include "os-ioctl-ttycom.h" -+ -+static const bitmask_transtbl iflag_tbl[] = { -+ { TARGET_IGNBRK, TARGET_IGNBRK, IGNBRK, IGNBRK }, -+ { TARGET_BRKINT, TARGET_BRKINT, BRKINT, BRKINT }, -+ { TARGET_IGNPAR, TARGET_IGNPAR, IGNPAR, IGNPAR }, -+ { TARGET_PARMRK, TARGET_PARMRK, PARMRK, PARMRK }, -+ { TARGET_INPCK, TARGET_INPCK, INPCK, INPCK }, -+ { TARGET_ISTRIP, TARGET_ISTRIP, ISTRIP, ISTRIP }, -+ { TARGET_INLCR, TARGET_INLCR, INLCR, INLCR }, -+ { TARGET_IGNCR, TARGET_IGNCR, IGNCR, IGNCR }, -+ { TARGET_ICRNL, TARGET_ICRNL, ICRNL, ICRNL }, -+ { TARGET_IXON, TARGET_IXON, IXON, IXON }, -+ { TARGET_IXOFF, TARGET_IXOFF, IXOFF, IXOFF }, -+#ifdef IXANY -+ { TARGET_IXANY, TARGET_IXANY, IXANY, IXANY }, -+#endif -+#ifdef IMAXBEL -+ { TARGET_IMAXBEL, TARGET_IMAXBEL, IMAXBEL, IMAXBEL }, -+#endif -+ { 0, 0, 0, 0 } -+}; -+ -+static const bitmask_transtbl oflag_tbl[] = { -+ { TARGET_OPOST, TARGET_OPOST, OPOST, OPOST }, -+#ifdef ONLCR -+ { TARGET_ONLCR, TARGET_ONLCR, ONLCR, ONLCR }, -+#endif -+#ifdef TABDLY -+ { TARGET_TABDLY, TARGET_TAB0, TABDLY, TAB0 }, -+ { TARGET_TABDLY, TARGET_TAB3, TABDLY, TAB3 }, -+#endif -+#ifdef ONOEOT -+ { TARGET_ONOEOT, TARGET_ONOEOT, ONOEOT, ONOEOT }, -+#endif -+#ifdef OCRNL -+ { TARGET_OCRNL, TARGET_OCRNL, OCRNL, OCRNL }, -+#endif -+#ifdef ONOCR -+ { TARGET_ONOCR, TARGET_ONOCR, ONOCR, ONOCR }, -+#endif -+#ifdef ONLRET -+ { TARGET_ONLRET, TARGET_ONLRET, ONLRET, ONLRET }, -+#endif -+ { 0, 0, 0, 0 } -+}; -+ -+static const bitmask_transtbl cflag_tbl[] = { -+#ifdef CIGNORE -+ { TARGET_CIGNORE, TARGET_CIGNORE, CIGNORE, CIGNORE }, -+#endif -+ { TARGET_CSIZE, TARGET_CS5, CSIZE, CS5 }, -+ { TARGET_CSIZE, TARGET_CS6, CSIZE, CS6 }, -+ { TARGET_CSIZE, TARGET_CS7, CSIZE, CS7 }, -+ { TARGET_CSIZE, TARGET_CS8, CSIZE, CS8 }, -+ { TARGET_CSTOPB, TARGET_CSTOPB, CSTOPB, CSTOPB }, -+ { TARGET_CREAD, TARGET_CREAD, CREAD, CREAD }, -+ { TARGET_PARENB, TARGET_PARENB, PARENB, PARENB }, -+ { TARGET_PARODD, TARGET_PARODD, PARODD, PARODD }, -+ { TARGET_HUPCL, TARGET_HUPCL, HUPCL, HUPCL }, -+ { TARGET_CLOCAL, TARGET_CLOCAL, CLOCAL, CLOCAL }, -+#ifdef CCTS_OFLOW -+ { TARGET_CCTS_OFLOW, TARGET_CCTS_OFLOW, CCTS_OFLOW, CCTS_OFLOW }, -+#endif -+#ifdef CRTSCTS -+ { TARGET_CRTSCTS, TARGET_CRTSCTS, CRTSCTS, CRTSCTS }, -+#endif -+#ifdef CRTS_IFLOW -+ { TARGET_CRTS_IFLOW, TARGET_CRTS_IFLOW, CRTS_IFLOW, CRTS_IFLOW }, -+#endif -+#ifdef CDTS_IFLOW -+ { TARGET_CDTR_IFLOW, TARGET_CDTR_IFLOW, CDTR_IFLOW, CDTR_IFLOW }, -+#endif -+#ifdef CDSR_OFLOW -+ { TARGET_CDSR_OFLOW, TARGET_CDSR_OFLOW, CDSR_OFLOW, CDSR_OFLOW }, -+#endif -+#ifdef CCAR_OFLOW -+ { TARGET_CCAR_OFLOW, TARGET_CCAR_OFLOW, CCAR_OFLOW, CCAR_OFLOW }, -+#endif -+ { 0, 0, 0, 0 } -+}; -+ -+static const bitmask_transtbl lflag_tbl[] = { -+#ifdef ECHOKE -+ { TARGET_ECHOKE, TARGET_ECHOKE, ECHOKE, ECHOKE }, -+#endif -+ { TARGET_ECHOE, TARGET_ECHOE, ECHOE, ECHOE }, -+ { TARGET_ECHOK, TARGET_ECHOK, ECHOK, ECHOK }, -+ { TARGET_ECHO, TARGET_ECHO, ECHO, ECHO }, -+ { TARGET_ECHONL, TARGET_ECHONL, ECHONL, ECHONL }, -+#ifdef ECHOPRT -+ { TARGET_ECHOPRT, TARGET_ECHOPRT, ECHOPRT, ECHOPRT }, -+#endif -+#ifdef ECHOCTL -+ { TARGET_ECHOCTL, TARGET_ECHOCTL, ECHOCTL, ECHOCTL }, -+#endif -+ { TARGET_ISIG, TARGET_ISIG, ISIG, ISIG }, -+ { TARGET_ICANON, TARGET_ICANON, ICANON, ICANON }, -+#ifdef ALTWERASE -+ { TARGET_ALTWERASE, TARGET_ALTWERASE, ALTWERASE, ALTWERASE }, -+#endif -+ { TARGET_IEXTEN, TARGET_IEXTEN, IEXTEN, IEXTEN }, -+ { TARGET_EXTPROC, TARGET_EXTPROC, EXTPROC, EXTPROC }, -+ { TARGET_TOSTOP, TARGET_TOSTOP, TOSTOP, TOSTOP }, -+#ifdef FLUSHO -+ { TARGET_FLUSHO, TARGET_FLUSHO, FLUSHO, FLUSHO }, -+#endif -+#ifdef NOKERNINFO -+ { TARGET_NOKERNINFO, TARGET_NOKERNINFO, NOKERNINFO, NOKERNINFO }, -+#endif -+#ifdef PENDIN -+ { TARGET_PENDIN, TARGET_PENDIN, PENDIN, PENDIN }, -+#endif -+ { TARGET_NOFLSH, TARGET_NOFLSH, NOFLSH, NOFLSH }, -+ { 0, 0, 0, 0 } -+}; -+ -+static void target_to_host_termios(void *dst, const void *src) -+{ -+ struct termios *host = dst; -+ const struct target_termios *target = src; -+ -+ host->c_iflag = target_to_host_bitmask(tswap32(target->c_iflag), iflag_tbl); -+ host->c_oflag = target_to_host_bitmask(tswap32(target->c_oflag), oflag_tbl); -+ host->c_cflag = target_to_host_bitmask(tswap32(target->c_cflag), cflag_tbl); -+ host->c_lflag = target_to_host_bitmask(tswap32(target->c_lflag), lflag_tbl); -+ -+ memset(host->c_cc, 0, sizeof(host->c_cc)); -+ host->c_cc[VEOF] = target->c_cc[TARGET_VEOF]; -+ host->c_cc[VEOL] = target->c_cc[TARGET_VEOL]; -+#ifdef VEOL2 -+ host->c_cc[VEOL2] = target->c_cc[TARGET_VEOL2]; -+#endif -+ host->c_cc[VERASE] = target->c_cc[TARGET_VERASE]; -+#ifdef VWERASE -+ host->c_cc[VWERASE] = target->c_cc[TARGET_VWERASE]; -+#endif -+ host->c_cc[VKILL] = target->c_cc[TARGET_VKILL]; -+#ifdef VREPRINT -+ host->c_cc[VREPRINT] = target->c_cc[TARGET_VREPRINT]; -+#endif -+#ifdef VERASE2 -+ host->c_cc[VERASE2] = target->c_cc[TARGET_VERASE2]; -+#endif -+ host->c_cc[VINTR] = target->c_cc[TARGET_VINTR]; -+ host->c_cc[VQUIT] = target->c_cc[TARGET_VQUIT]; -+ host->c_cc[VSUSP] = target->c_cc[TARGET_VSUSP]; -+#ifdef VDSUSP -+ host->c_cc[VDSUSP] = target->c_cc[TARGET_VDSUSP]; -+#endif -+ host->c_cc[VSTART] = target->c_cc[TARGET_VSTART]; -+ host->c_cc[VSTOP] = target->c_cc[TARGET_VSTOP]; -+#ifdef VLNEXT -+ host->c_cc[VLNEXT] = target->c_cc[TARGET_VLNEXT]; -+#endif -+#ifdef VDISCARD -+ host->c_cc[VDISCARD] = target->c_cc[TARGET_VDISCARD]; -+#endif -+ host->c_cc[VMIN] = target->c_cc[TARGET_VMIN]; -+ host->c_cc[VTIME] = target->c_cc[TARGET_VTIME]; -+#ifdef VSTATUS -+ host->c_cc[VSTATUS] = target->c_cc[TARGET_VSTATUS]; -+#endif -+ -+ host->c_ispeed = tswap32(target->c_ispeed); -+ host->c_ospeed = tswap32(target->c_ospeed); -+} -+ -+static void host_to_target_termios(void *dst, const void *src) -+{ -+ struct target_termios *target = dst; -+ const struct termios *host = src; -+ -+ target->c_iflag = tswap32(host_to_target_bitmask(host->c_iflag, iflag_tbl)); -+ target->c_oflag = tswap32(host_to_target_bitmask(host->c_oflag, oflag_tbl)); -+ target->c_cflag = tswap32(host_to_target_bitmask(host->c_cflag, cflag_tbl)); -+ target->c_lflag = tswap32(host_to_target_bitmask(host->c_lflag, lflag_tbl)); -+ -+ memset(target->c_cc, 0, sizeof(target->c_cc)); -+ target->c_cc[TARGET_VEOF] = host->c_cc[VEOF]; -+ target->c_cc[TARGET_VEOL] = host->c_cc[VEOL]; -+#ifdef VEOL2 -+ target->c_cc[TARGET_VEOL2] = host->c_cc[VEOL2]; -+#endif -+ target->c_cc[TARGET_VERASE] = host->c_cc[VERASE]; -+#ifdef VWERASE -+ target->c_cc[TARGET_VWERASE] = host->c_cc[VWERASE]; -+#endif -+ target->c_cc[TARGET_VKILL] = host->c_cc[VKILL]; -+#ifdef VREPRINT -+ target->c_cc[TARGET_VREPRINT] = host->c_cc[VREPRINT]; -+#endif -+#ifdef VERASE2 -+ target->c_cc[TARGET_VERASE2] = host->c_cc[VERASE2]; -+#endif -+ target->c_cc[TARGET_VINTR] = host->c_cc[VINTR]; -+ target->c_cc[TARGET_VQUIT] = host->c_cc[VQUIT]; -+ target->c_cc[TARGET_VSUSP] = host->c_cc[VSUSP]; -+#ifdef VDSUSP -+ target->c_cc[TARGET_VDSUSP] = host->c_cc[VDSUSP]; -+#endif -+ target->c_cc[TARGET_VSTART] = host->c_cc[VSTART]; -+ target->c_cc[TARGET_VSTOP] = host->c_cc[VSTOP]; -+#ifdef VLNEXT -+ target->c_cc[TARGET_VLNEXT] = host->c_cc[VLNEXT]; -+#endif -+#ifdef VDISCARD -+ target->c_cc[TARGET_VDISCARD] = host->c_cc[VDISCARD]; -+#endif -+ target->c_cc[TARGET_VMIN] = host->c_cc[VMIN]; -+ target->c_cc[TARGET_VTIME] = host->c_cc[VTIME]; -+#ifdef VSTATUS -+ target->c_cc[TARGET_VSTATUS] = host->c_cc[VSTATUS]; -+#endif -+ -+ target->c_ispeed = tswap32(host->c_ispeed); -+ target->c_ospeed = tswap32(host->c_ospeed); -+} -+ -+static const StructEntry struct_termios_def = { -+ .convert = { host_to_target_termios, target_to_host_termios }, -+ .size = { sizeof(struct target_termios), sizeof(struct termios) }, -+ .align = { __alignof__(struct target_termios), -+ __alignof__(struct termios) }, -+}; -+ -+ -+/* ioctl structure type definitions */ -+#define STRUCT(name, ...) STRUCT_ ## name, -+#define STRUCT_SPECIAL(name) STRUCT_ ## name, -+enum { -+#include "os-ioctl-types.h" -+}; -+#undef STRUCT -+#undef STRUCT_SPECIAL -+ -+#define STRUCT(name, ...) \ -+ static const argtype struct_ ## name ## _def[] = { __VA_ARGS__, TYPE_NULL }; -+#define STRUCT_SPECIAL(name) -+#include "os-ioctl-types.h" -+#undef STRUCT -+#undef STRUCT_SPECIAL -+ -+ -+struct IOCTLEntry; -+ -+typedef abi_long do_ioctl_fn(const struct IOCTLEntry *ie, uint8_t *buf_temp, -+ int fd, abi_long cmd, abi_long arg); -+ -+struct IOCTLEntry { -+ unsigned int target_cmd; -+ unsigned int host_cmd; -+ const char *name; -+ int access; -+ do_ioctl_fn *do_ioctl; -+ const argtype arg_type[5]; -+}; -+typedef struct IOCTLEntry IOCTLEntry; -+ -+#define MAX_STRUCT_SIZE 4096 -+ -+static IOCTLEntry ioctl_entries[] = { -+#define IOC_ 0x0000 -+#define IOC_R 0x0001 -+#define IOC_W 0x0002 -+#define IOC_RW (IOC_R | IOC_W) -+#define IOCTL(cmd, access, ...) \ -+ { TARGET_ ## cmd, cmd, #cmd, access, 0, { __VA_ARGS__ } }, -+#define IOCTL_SPECIAL(cmd, access, dofn, ...) \ -+ { TARGET_ ## cmd, cmd, #cmd, access, dofn, { __VA_ARGS__ } }, -+#include "os-ioctl-cmds.h" -+ { 0, 0 }, -+}; -+ -+abi_long do_bsd_ioctl(int fd, abi_long cmd, abi_long arg) -+{ -+ const IOCTLEntry *ie; -+ const argtype *arg_type; -+ abi_long ret; -+ uint8_t buf_temp[MAX_STRUCT_SIZE]; -+ int target_size; -+ void *argptr; -+ -+ ie = ioctl_entries; -+ for (;;) { -+ if (ie->target_cmd == 0) { -+ gemu_log("Unsupported ioctl: cmd=0x%04lx\n", (long)cmd); -+ return -TARGET_ENOSYS; -+ } -+ if (ie->target_cmd == cmd) { -+ break; -+ } -+ ie++; -+ } -+ arg_type = ie->arg_type; -+#if defined(DEBUG) -+ gemu_log("ioctl: cmd=0x%04lx (%s)\n", (long)cmd, ie->name); -+#endif -+ if (ie->do_ioctl) { -+ return ie->do_ioctl(ie, buf_temp, fd, cmd, arg); -+ } -+ -+ switch (arg_type[0]) { -+ case TYPE_NULL: -+ /* no argument */ -+ ret = get_errno(ioctl(fd, ie->host_cmd)); -+ break; -+ -+ case TYPE_PTRVOID: -+ case TYPE_INT: -+ /* int argument */ -+ ret = get_errno(ioctl(fd, ie->host_cmd, arg)); -+ break; -+ -+ case TYPE_PTR: -+ arg_type++; -+ target_size = thunk_type_size(arg_type, 0); -+ switch (ie->access) { -+ case IOC_R: -+ ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); -+ if (!is_error(ret)) { -+ argptr = lock_user(VERIFY_WRITE, arg, -+ target_size, 0); -+ if (!argptr) { -+ return -TARGET_EFAULT; -+ } -+ thunk_convert(argptr, buf_temp, arg_type, -+ THUNK_TARGET); -+ unlock_user(argptr, arg, target_size); -+ } -+ break; -+ -+ case IOC_W: -+ argptr = lock_user(VERIFY_READ, arg, target_size, 1); -+ if (!argptr) { -+ return -TARGET_EFAULT; -+ } -+ thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); -+ unlock_user(argptr, arg, 0); -+ ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); -+ break; -+ -+ case IOC_RW: -+ /* fallthrough */ -+ default: -+ argptr = lock_user(VERIFY_READ, arg, target_size, 1); -+ if (!argptr) { -+ return -TARGET_EFAULT; -+ } -+ thunk_convert(buf_temp, argptr, arg_type, THUNK_HOST); -+ unlock_user(argptr, arg, 0); -+ ret = get_errno(ioctl(fd, ie->host_cmd, buf_temp)); -+ if (!is_error(ret)) { -+ argptr = lock_user(VERIFY_WRITE, arg, target_size, 0); -+ if (!argptr) { -+ return -TARGET_EFAULT; -+ } -+ thunk_convert(argptr, buf_temp, arg_type, THUNK_TARGET); -+ unlock_user(argptr, arg, target_size); -+ } -+ break; -+ } -+ break; -+ -+ default: -+ gemu_log("Unsupported ioctl type: cmd=0x%04lx type=%d\n", -+ (long)cmd, arg_type[0]); -+ ret = -TARGET_ENOSYS; -+ break; -+ } -+ return ret; -+} -+ -+void init_bsd_ioctl(void) -+{ -+ IOCTLEntry *ie; -+ const argtype *arg_type; -+ int size; -+ -+#define STRUCT(name, ...) \ -+ thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def); -+#define STRUCT_SPECIAL(name) \ -+ thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def); -+#include "os-ioctl-types.h" -+#undef STRUCT -+#undef STRUCT_SPECIAL -+ -+ /* -+ * Patch the ioctl size if necessary using the fact that no -+ * ioctl has all the bits at '1' in the size field -+ * (IOCPARM_MAX - 1). -+ */ -+ ie = ioctl_entries; -+ while (ie->target_cmd != 0) { -+ if (((ie->target_cmd >> TARGET_IOCPARM_SHIFT) & -+ TARGET_IOCPARM_MASK) == TARGET_IOCPARM_MASK) { -+ arg_type = ie->arg_type; -+ if (arg_type[0] != TYPE_PTR) { -+ fprintf(stderr, "cannot patch size for ioctl 0x%x\n", -+ ie->target_cmd); -+ exit(1); -+ } -+ arg_type++; -+ size = thunk_type_size(arg_type, 0); -+ ie->target_cmd = (ie->target_cmd & -+ ~(TARGET_IOCPARM_MASK << TARGET_IOCPARM_SHIFT)) | -+ (size << TARGET_IOCPARM_SHIFT); -+ } -+ ie++; -+ } -+ -+} -+ -diff --git a/bsd-user/bsd-ioctl.h b/bsd-user/bsd-ioctl.h -new file mode 100644 -index 0000000..b593c88 ---- /dev/null -+++ b/bsd-user/bsd-ioctl.h -@@ -0,0 +1,27 @@ -+/* -+ * ioctl system call 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 __BSD_IOCTL_H_ -+#define __BSD_IOCTL_H_ -+ -+abi_long do_bsd_ioctl(int fd, abi_long cmd, abi_long arg); -+void init_bsd_ioctl(void); -+ -+#endif /* !__BSD_IOCTL_H_ */ -+ -diff --git a/bsd-user/bsd-mem.c b/bsd-user/bsd-mem.c -new file mode 100644 -index 0000000..bfe03aa ---- /dev/null -+++ b/bsd-user/bsd-mem.c -@@ -0,0 +1,122 @@ -+/* -+ * memory management system conversion routines -+ * -+ * 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/ipc.h> -+#include <sys/shm.h> -+ -+#include "qemu.h" -+#include "qemu-bsd.h" -+ -+struct bsd_shm_regions bsd_shm_regions[N_BSD_SHM_REGIONS]; -+ -+abi_ulong bsd_target_brk; -+abi_ulong bsd_target_original_brk; -+ -+void target_set_brk(abi_ulong new_brk) -+{ -+ -+ bsd_target_original_brk = bsd_target_brk = HOST_PAGE_ALIGN(new_brk); -+} -+ -+abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip, -+ abi_ulong target_addr) -+{ -+ struct target_ipc_perm *target_ip; -+ -+ if (!lock_user_struct(VERIFY_READ, target_ip, target_addr, 1)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(host_ip->cuid, &target_ip->cuid); -+ __get_user(host_ip->cgid, &target_ip->cgid); -+ __get_user(host_ip->uid, &target_ip->uid); -+ __get_user(host_ip->gid, &target_ip->gid); -+ __get_user(host_ip->mode, &target_ip->mode); -+ __get_user(host_ip->seq, &target_ip->seq); -+ __get_user(host_ip->key, &target_ip->key); -+ unlock_user_struct(target_ip, target_addr, 0); -+ -+ return 0; -+} -+ -+abi_long host_to_target_ipc_perm(abi_ulong target_addr, -+ struct ipc_perm *host_ip) -+{ -+ struct target_ipc_perm *target_ip; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_ip, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __put_user(host_ip->cuid, &target_ip->cuid); -+ __put_user(host_ip->cgid, &target_ip->cgid); -+ __put_user(host_ip->uid, &target_ip->uid); -+ __put_user(host_ip->gid, &target_ip->gid); -+ __put_user(host_ip->mode, &target_ip->mode); -+ __put_user(host_ip->seq, &target_ip->seq); -+ __put_user(host_ip->key, &target_ip->key); -+ unlock_user_struct(target_ip, target_addr, 1); -+ -+ return 0; -+} -+ -+abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd, -+ abi_ulong target_addr) -+{ -+ struct target_shmid_ds *target_sd; -+ -+ if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) { -+ return -TARGET_EFAULT; -+ } -+ if (target_to_host_ipc_perm(&(host_sd->shm_perm), target_addr)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(host_sd->shm_segsz, &target_sd->shm_segsz); -+ __get_user(host_sd->shm_lpid, &target_sd->shm_lpid); -+ __get_user(host_sd->shm_cpid, &target_sd->shm_cpid); -+ __get_user(host_sd->shm_nattch, &target_sd->shm_nattch); -+ __get_user(host_sd->shm_atime, &target_sd->shm_atime); -+ __get_user(host_sd->shm_dtime, &target_sd->shm_dtime); -+ __get_user(host_sd->shm_ctime, &target_sd->shm_ctime); -+ unlock_user_struct(target_sd, target_addr, 0); -+ -+ return 0; -+} -+ -+abi_long host_to_target_shmid_ds(abi_ulong target_addr, -+ struct shmid_ds *host_sd) -+{ -+ struct target_shmid_ds *target_sd; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ if (host_to_target_ipc_perm(target_addr, &(host_sd->shm_perm))) { -+ return -TARGET_EFAULT; -+ } -+ __put_user(host_sd->shm_segsz, &target_sd->shm_segsz); -+ __put_user(host_sd->shm_lpid, &target_sd->shm_lpid); -+ __put_user(host_sd->shm_cpid, &target_sd->shm_cpid); -+ __put_user(host_sd->shm_nattch, &target_sd->shm_nattch); -+ __put_user(host_sd->shm_atime, &target_sd->shm_atime); -+ __put_user(host_sd->shm_dtime, &target_sd->shm_dtime); -+ __put_user(host_sd->shm_ctime, &target_sd->shm_ctime); -+ unlock_user_struct(target_sd, target_addr, 1); -+ -+ return 0; -+} -+ -diff --git a/bsd-user/bsd-mem.h b/bsd-user/bsd-mem.h -new file mode 100644 -index 0000000..88c01ec ---- /dev/null -+++ b/bsd-user/bsd-mem.h -@@ -0,0 +1,393 @@ -+/* -+ * memory management system call shims 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/>. -+ */ -+ -+/*-- -+ * Copyright (c) 1982, 1986, 1993 -+ * The Regents of the University of California. All rights reserved. -+ * -+ * Redistribution and use in source and binary forms, with or without -+ * modification, are permitted provided that the following conditions -+ * are met: -+ * 1. Redistributions of source code must retain the above copyright -+ * notice, this list of conditions and the following disclaimer. -+ * 2. Redistributions in binary form must reproduce the above copyright -+ * notice, this list of conditions and the following disclaimer in the -+ * documentation and/or other materials provided with the distribution. -+ * 4. Neither the name of the University nor the names of its contributors -+ * may be used to endorse or promote products derived from this software -+ * without specific prior written permission. -+ * -+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -+ * SUCH DAMAGE. -+ */ -+ -+#ifndef _BSD_MMAN_H_ -+#define _BSD_MMAN_H_ -+ -+#include <sys/types.h> -+#include <sys/ipc.h> -+#include <sys/mman.h> -+#include <sys/shm.h> -+#include <fcntl.h> -+ -+#include "qemu-bsd.h" -+ -+extern struct bsd_shm_regions bsd_shm_regions[]; -+extern abi_ulong bsd_target_brk; -+extern abi_ulong bsd_target_original_brk; -+ -+/* mmap(2) */ -+static inline abi_long do_bsd_mmap(void *cpu_env, abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6, abi_long arg7, -+ abi_long arg8) -+{ -+ -+ if (regpairs_aligned(cpu_env) != 0) { -+ arg6 = arg7; -+ arg7 = arg8; -+ } -+ return get_errno(target_mmap(arg1, arg2, arg3, -+ target_to_host_bitmask(arg4, mmap_flags_tbl), arg5, -+ target_offset64(arg6, arg7))); -+} -+ -+/* munmap(2) */ -+static inline abi_long do_bsd_munmap(abi_long arg1, abi_long arg2) -+{ -+ -+ return get_errno(target_munmap(arg1, arg2)); -+} -+ -+/* mprotect(2) */ -+static inline abi_long do_bsd_mprotect(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ return get_errno(target_mprotect(arg1, arg2, arg3)); -+} -+ -+/* msync(2) */ -+static inline abi_long do_bsd_msync(abi_long arg1, abi_long arg2, abi_long arg3) -+{ -+ -+ return get_errno(msync(g2h(arg1), arg2, arg3)); -+} -+ -+/* mlock(2) */ -+static inline abi_long do_bsd_mlock(abi_long arg1, abi_long arg2) -+{ -+ -+ return get_errno(mlock(g2h(arg1), arg2)); -+} -+ -+/* munlock(2) */ -+static inline abi_long do_bsd_munlock(abi_long arg1, abi_long arg2) -+{ -+ -+ return get_errno(munlock(g2h(arg1), arg2)); -+} -+ -+/* mlockall(2) */ -+static inline abi_long do_bsd_mlockall(abi_long arg1) -+{ -+ -+ return get_errno(mlockall(arg1)); -+} -+ -+/* munlockall(2) */ -+static inline abi_long do_bsd_munlockall(void) -+{ -+ -+ return get_errno(munlockall()); -+} -+ -+/* madvise(2) */ -+static inline abi_long do_bsd_madvise(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ /* -+ * A straight passthrough may not be safe because qemu sometimes -+ * turns private file-backed mapping into anonymous mappings. This -+ * will break MADV_DONTNEED. This is a hint, so ignoring and returing -+ * success is ok. -+ */ -+ return get_errno(0); -+} -+ -+/* minherit(2) */ -+static inline abi_long do_bsd_minherit(abi_long addr, abi_long len, -+ abi_long inherit) -+{ -+ -+ return get_errno(minherit(g2h(addr), len, inherit)); -+} -+ -+/* mincore(2) */ -+static inline abi_long do_bsd_mincore(abi_ulong target_addr, abi_ulong len, -+ abi_ulong target_vec) -+{ -+ abi_long ret; -+ void *p, *a; -+ -+ a = lock_user(VERIFY_WRITE, target_addr, len, 0); -+ if (a == NULL) { -+ return -TARGET_EFAULT; -+ } -+ p = lock_user_string(target_vec); -+ if (p == NULL) { -+ unlock_user(a, target_addr, 0); -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(mincore(a, len, p)); -+ unlock_user(p, target_vec, ret); -+ unlock_user(a, target_addr, 0); -+ -+ return ret; -+} -+ -+/* break() XXX this needs some more work. */ -+static inline abi_long do_obreak(abi_ulong new_brk) -+{ -+ abi_ulong brk_page; -+ abi_long mapped_addr; -+ int new_alloc_size; -+ -+ return -TARGET_EINVAL; -+ -+ if (!new_brk) { -+ return 0; -+ } -+ if (new_brk < bsd_target_original_brk) { -+ return -TARGET_EINVAL; -+ } -+ -+ brk_page = HOST_PAGE_ALIGN(bsd_target_brk); -+ -+ /* If the new brk is less than this, set it and we're done... */ -+ if (new_brk < brk_page) { -+ bsd_target_brk = new_brk; -+ return 0; -+ } -+ -+ /* We need to allocate more memory after the brk... */ -+ new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1); -+ mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, -+ PROT_READ|PROT_WRITE, MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0)); -+ -+ if (!is_error(mapped_addr)) { -+ bsd_target_brk = new_brk; -+ } else { -+ return mapped_addr; -+ } -+ -+ return 0; -+} -+ -+/* shm_open(2) */ -+static inline abi_long do_bsd_shm_open(abi_ulong arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ int ret; -+ void *p; -+ -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(shm_open(path(p), -+ target_to_host_bitmask(arg2, fcntl_flags_tbl), arg3)); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* shm_unlink(2) */ -+static inline abi_long do_bsd_shm_unlink(abi_ulong arg1) -+{ -+ int ret; -+ void *p; -+ -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(shm_unlink(p)); /* XXX path(p)? */ -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* shmget(2) */ -+static inline abi_long do_bsd_shmget(abi_long arg1, abi_ulong arg2, -+ abi_long arg3) -+{ -+ -+ return get_errno(shmget(arg1, arg2, arg3)); -+} -+ -+/* shmctl(2) */ -+static inline abi_long do_bsd_shmctl(abi_long shmid, abi_long cmd, -+ abi_ulong buff) -+{ -+ struct shmid_ds dsarg; -+ abi_long ret = -TARGET_EINVAL; -+ -+ cmd &= 0xff; -+ -+ switch (cmd) { -+ case IPC_STAT: -+ case IPC_SET: -+ if (target_to_host_shmid_ds(&dsarg, buff)) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(shmctl(shmid, cmd, &dsarg)); -+ if (host_to_target_shmid_ds(buff, &dsarg)) { -+ return -TARGET_EFAULT; -+ } -+ break; -+ -+ case IPC_RMID: -+ ret = get_errno(shmctl(shmid, cmd, NULL)); -+ break; -+ -+ default: -+ ret = -TARGET_EINVAL; -+ break; -+ } -+ -+ return ret; -+} -+ -+/* shmat(2) */ -+static inline abi_long do_bsd_shmat(int shmid, abi_ulong shmaddr, int shmflg) -+{ -+ abi_ulong raddr; -+ abi_long ret; -+ void *host_raddr; -+ struct shmid_ds shm_info; -+ int i; -+ -+ /* Find out the length of the shared memory segment. */ -+ ret = get_errno(shmctl(shmid, IPC_STAT, &shm_info)); -+ if (is_error(ret)) { -+ /* Can't get the length */ -+ return ret; -+ } -+ -+ mmap_lock(); -+ -+ if (shmaddr) { -+ host_raddr = shmat(shmid, (void *)g2h(shmaddr), shmflg); -+ } else { -+ abi_ulong mmap_start; -+ -+ mmap_start = mmap_find_vma(0, shm_info.shm_segsz); -+ -+ if (mmap_start == -1) { -+ errno = ENOMEM; -+ host_raddr = (void *)-1; -+ } else { -+ host_raddr = shmat(shmid, g2h(mmap_start), -+ shmflg /* | SHM_REMAP */); -+ } -+ } -+ -+ if (host_raddr == (void *)-1) { -+ mmap_unlock(); -+ return get_errno((long)host_raddr); -+ } -+ raddr = h2g((unsigned long)host_raddr); -+ -+ page_set_flags(raddr, raddr + shm_info.shm_segsz, -+ PAGE_VALID | PAGE_READ | ((shmflg & SHM_RDONLY) ? 0 : PAGE_WRITE)); -+ -+ for (i = 0; i < N_BSD_SHM_REGIONS; i++) { -+ if (bsd_shm_regions[i].start == 0) { -+ bsd_shm_regions[i].start = raddr; -+ bsd_shm_regions[i].size = shm_info.shm_segsz; -+ break; -+ } -+ } -+ -+ mmap_unlock(); -+ return raddr; -+} -+ -+/* shmdt(2) */ -+static inline abi_long do_bsd_shmdt(abi_ulong shmaddr) -+{ -+ int i; -+ -+ for (i = 0; i < N_BSD_SHM_REGIONS; ++i) { -+ if (bsd_shm_regions[i].start == shmaddr) { -+ bsd_shm_regions[i].start = 0; -+ page_set_flags(shmaddr, -+ shmaddr + bsd_shm_regions[i].size, 0); -+ break; -+ } -+ } -+ -+ return get_errno(shmdt(g2h(shmaddr))); -+} -+ -+ -+static inline abi_long do_bsd_vadvise(void) -+{ -+ /* See sys_ovadvise() in vm_unix.c */ -+ qemu_log("qemu: Unsupported syscall vadvise()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_bsd_sbrk(void) -+{ -+ /* see sys_sbrk() in vm_mmap.c */ -+ qemu_log("qemu: Unsupported syscall sbrk()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_bsd_sstk(void) -+{ -+ /* see sys_sstk() in vm_mmap.c */ -+ qemu_log("qemu: Unsupported syscall sstk()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * undocumented freebsd6_mmap(caddr_t addr, size_t len, int prot, int -+ * flags, int fd, int pad, off_t pos) system call. -+ */ -+static inline abi_long do_bsd_freebsd6_mmap(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6, -+ abi_long arg7) -+{ -+ -+ qemu_log("qemu: Unsupported syscall freebsd6_mmap()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* !_BSD_MMAN_H_ */ -diff --git a/bsd-user/bsd-misc.c b/bsd-user/bsd-misc.c -new file mode 100644 -index 0000000..bc85473 ---- /dev/null -+++ b/bsd-user/bsd-misc.c -@@ -0,0 +1,209 @@ -+/* -+ * BSD misc system call conversions routines -+ * -+ * 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/ipc.h> -+#include <sys/msg.h> -+#include <sys/sem.h> -+#include <sys/uuid.h> -+ -+#include "qemu.h" -+#include "qemu-bsd.h" -+ -+/* -+ * BSD uuidgen(2) struct uuid conversion -+ */ -+abi_long host_to_target_uuid(abi_ulong target_addr, struct uuid *host_uuid) -+{ -+ struct target_uuid *target_uuid; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_uuid, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __put_user(host_uuid->time_low, &target_uuid->time_low); -+ __put_user(host_uuid->time_mid, &target_uuid->time_mid); -+ __put_user(host_uuid->time_hi_and_version, -+ &target_uuid->time_hi_and_version); -+ host_uuid->clock_seq_hi_and_reserved = -+ target_uuid->clock_seq_hi_and_reserved; -+ host_uuid->clock_seq_low = target_uuid->clock_seq_low; -+ memcpy(host_uuid->node, target_uuid->node, TARGET_UUID_NODE_LEN); -+ unlock_user_struct(target_uuid, target_addr, 1); -+ return 0; -+} -+ -+abi_long target_to_host_semarray(int semid, unsigned short **host_array, -+ abi_ulong target_addr) -+{ -+ abi_long ret; -+ int nsems, i; -+ unsigned short *array; -+ union semun semun; -+ struct semid_ds semid_ds; -+ -+ semun.buf = &semid_ds; -+ ret = semctl(semid, 0, IPC_STAT, semun); -+ if (ret == -1) { -+ return get_errno(ret); -+ } -+ nsems = semid_ds.sem_nsems; -+ *host_array = (unsigned short *)malloc(nsems * sizeof(unsigned short)); -+ array = lock_user(VERIFY_READ, target_addr, -+ nsems*sizeof(unsigned short), 1); -+ if (array == NULL) { -+ free(*host_array); -+ return -TARGET_EFAULT; -+ } -+ for (i = 0; i < nsems; i++) { -+ (*host_array)[i] = array[i]; -+ } -+ unlock_user(array, target_addr, 0); -+ -+ return 0; -+} -+ -+abi_long host_to_target_semarray(int semid, abi_ulong target_addr, -+ unsigned short **host_array) -+{ -+ abi_long ret; -+ int nsems, i; -+ unsigned short *array; -+ union semun semun; -+ struct semid_ds semid_ds; -+ -+ semun.buf = &semid_ds; -+ -+ ret = semctl(semid, 0, IPC_STAT, semun); -+ if (ret == -1) { -+ free(*host_array); -+ return get_errno(ret); -+ } -+ -+ nsems = semid_ds.sem_nsems; -+ array = (unsigned short *)lock_user(VERIFY_WRITE, target_addr, -+ nsems*sizeof(unsigned short), 0); -+ if (array == NULL) { -+ free(*host_array); -+ return -TARGET_EFAULT; -+ } -+ for (i = 0; i < nsems; i++) { -+ array[i] = (*host_array)[i]; -+ } -+ free(*host_array); -+ unlock_user(array, target_addr, 1); -+ return 0; -+} -+ -+abi_long target_to_host_semid_ds(struct semid_ds *host_sd, -+ abi_ulong target_addr) -+{ -+ struct target_semid_ds *target_sd; -+ -+ if (!lock_user_struct(VERIFY_READ, target_sd, target_addr, 1)) { -+ return -TARGET_EFAULT; -+ } -+ if (target_to_host_ipc_perm(&(host_sd->sem_perm), (target_addr + -+ offsetof(struct target_semid_ds, sem_perm)))) { -+ return -TARGET_EFAULT; -+ } -+ /* sem_base is not used by kernel for IPC_STAT/IPC_SET */ -+ /* host_sd->sem_base = g2h(target_sd->sem_base); */ -+ host_sd->sem_nsems = tswap16(target_sd->sem_nsems); -+ host_sd->sem_otime = tswapal(target_sd->sem_otime); -+ host_sd->sem_ctime = tswapal(target_sd->sem_ctime); -+ unlock_user_struct(target_sd, target_addr, 0); -+ return 0; -+} -+ -+abi_long host_to_target_semid_ds(abi_ulong target_addr, -+ struct semid_ds *host_sd) -+{ -+ struct target_semid_ds *target_sd; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_sd, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ if (host_to_target_ipc_perm((target_addr + -+ offsetof(struct target_semid_ds, sem_perm)), -+ &(host_sd->sem_perm))) { -+ return -TARGET_EFAULT; -+ } -+ /* sem_base is not used by kernel for IPC_STAT/IPC_SET */ -+ /* target_sd->sem_base = h2g((void *)host_sd->sem_base); */ -+ target_sd->sem_nsems = tswap16(host_sd->sem_nsems); -+ target_sd->sem_otime = tswapal(host_sd->sem_otime); -+ target_sd->sem_ctime = tswapal(host_sd->sem_ctime); -+ unlock_user_struct(target_sd, target_addr, 1); -+ -+ return 0; -+} -+ -+abi_long target_to_host_msqid_ds(struct msqid_ds *host_md, -+ abi_ulong target_addr) -+{ -+ struct target_msqid_ds *target_md; -+ -+ if (!lock_user_struct(VERIFY_READ, target_md, target_addr, 1)) { -+ return -TARGET_EFAULT; -+ } -+ if (target_to_host_ipc_perm(&(host_md->msg_perm), target_addr)) { -+ return -TARGET_EFAULT; -+ } -+ -+ /* msg_first and msg_last are not used by IPC_SET/IPC_STAT in kernel. */ -+ host_md->msg_first = host_md->msg_last = NULL; -+ host_md->msg_cbytes = tswapal(target_md->msg_cbytes); -+ host_md->msg_qnum = tswapal(target_md->msg_qnum); -+ host_md->msg_qbytes = tswapal(target_md->msg_qbytes); -+ host_md->msg_lspid = tswapal(target_md->msg_lspid); -+ host_md->msg_lrpid = tswapal(target_md->msg_lrpid); -+ host_md->msg_stime = tswapal(target_md->msg_stime); -+ host_md->msg_rtime = tswapal(target_md->msg_rtime); -+ host_md->msg_ctime = tswapal(target_md->msg_ctime); -+ unlock_user_struct(target_md, target_addr, 0); -+ -+ return 0; -+} -+ -+abi_long host_to_target_msqid_ds(abi_ulong target_addr, -+ struct msqid_ds *host_md) -+{ -+ struct target_msqid_ds *target_md; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_md, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ if (host_to_target_ipc_perm(target_addr, &(host_md->msg_perm))) { -+ return -TARGET_EFAULT; -+ } -+ -+ /* msg_first and msg_last are not used by IPC_SET/IPC_STAT in kernel. */ -+ target_md->msg_cbytes = tswapal(host_md->msg_cbytes); -+ target_md->msg_qnum = tswapal(host_md->msg_qnum); -+ target_md->msg_qbytes = tswapal(host_md->msg_qbytes); -+ target_md->msg_lspid = tswapal(host_md->msg_lspid); -+ target_md->msg_lrpid = tswapal(host_md->msg_lrpid); -+ target_md->msg_stime = tswapal(host_md->msg_stime); -+ target_md->msg_rtime = tswapal(host_md->msg_rtime); -+ target_md->msg_ctime = tswapal(host_md->msg_ctime); -+ unlock_user_struct(target_md, target_addr, 1); -+ -+ return 0; -+} -+ -diff --git a/bsd-user/bsd-misc.h b/bsd-user/bsd-misc.h -new file mode 100644 -index 0000000..0c34089 ---- /dev/null -+++ b/bsd-user/bsd-misc.h -@@ -0,0 +1,339 @@ -+/* -+ * miscellaneous BSD system call shims -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef __BSD_MISC_H_ -+#define __BSD_MISC_H_ -+ -+#include <sys/types.h> -+#include <sys/ipc.h> -+#include <sys/msg.h> -+#include <sys/sem.h> -+#include <sys/uuid.h> -+ -+#include "qemu-bsd.h" -+ -+/* quotactl(2) */ -+static inline abi_long do_bsd_quotactl(abi_ulong path, abi_long cmd, -+ abi_ulong target_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall quotactl()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* reboot(2) */ -+static inline abi_long do_bsd_reboot(abi_long how) -+{ -+ -+ qemu_log("qemu: Unsupported syscall reboot()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* uuidgen(2) */ -+static inline abi_long do_bsd_uuidgen(abi_ulong target_addr, int count) -+{ -+ int i; -+ abi_long ret; -+ struct uuid *host_uuid; -+ -+ if (count < 1 || count > 2048) { -+ return -TARGET_EINVAL; -+ } -+ -+ host_uuid = (struct uuid *)g_malloc(count * sizeof(struct uuid)); -+ -+ if (host_uuid == NULL) { -+ return -TARGET_ENOMEM; -+ } -+ -+ ret = get_errno(uuidgen(host_uuid, count)); -+ if (is_error(ret)) { -+ goto out; -+ } -+ for (i = 0; i < count; i++) { -+ ret = host_to_target_uuid(target_addr + -+ (abi_ulong)(sizeof(struct target_uuid) * i), &host_uuid[i]); -+ if (is_error(ret)) { -+ goto out; -+ } -+ } -+ -+out: -+ g_free(host_uuid); -+ return ret; -+} -+ -+ -+/* -+ * System V Semaphores -+ */ -+ -+/* semget(2) */ -+static inline abi_long do_bsd_semget(abi_long key, int nsems, -+ int target_flags) -+{ -+ -+ return get_errno(semget(key, nsems, -+ target_to_host_bitmask(target_flags, ipc_flags_tbl))); -+} -+ -+/* semop(2) */ -+static inline abi_long do_bsd_semop(int semid, abi_long ptr, unsigned nsops) -+{ -+ struct sembuf sops[nsops]; -+ struct target_sembuf *target_sembuf; -+ int i; -+ -+ target_sembuf = lock_user(VERIFY_READ, ptr, -+ nsops * sizeof(struct target_sembuf), 1); -+ if (target_sembuf == NULL) { -+ return -TARGET_EFAULT; -+ } -+ for (i = 0; i < nsops; i++) { -+ __get_user(sops[i].sem_num, &target_sembuf[i].sem_num); -+ __get_user(sops[i].sem_op, &target_sembuf[i].sem_op); -+ __get_user(sops[i].sem_flg, &target_sembuf[i].sem_flg); -+ } -+ unlock_user(target_sembuf, ptr, 0); -+ -+ return semop(semid, sops, nsops); -+} -+ -+/* __semctl(2) */ -+static inline abi_long do_bsd___semctl(int semid, int semnum, int target_cmd, -+ union target_semun target_su) -+{ -+ union semun arg; -+ struct semid_ds dsarg; -+ unsigned short *array = NULL; -+ int host_cmd; -+ abi_long ret = 0; -+ abi_long err; -+ abi_ulong target_addr; -+ -+ switch (target_cmd) { -+ case TARGET_GETVAL: -+ host_cmd = GETVAL; -+ break; -+ -+ case TARGET_SETVAL: -+ host_cmd = SETVAL; -+ break; -+ -+ case TARGET_GETALL: -+ host_cmd = GETALL; -+ break; -+ -+ case TARGET_SETALL: -+ host_cmd = SETALL; -+ break; -+ -+ case TARGET_IPC_STAT: -+ host_cmd = IPC_STAT; -+ break; -+ -+ case TARGET_IPC_SET: -+ host_cmd = IPC_SET; -+ break; -+ -+ case TARGET_IPC_RMID: -+ host_cmd = IPC_RMID; -+ break; -+ -+ case TARGET_GETPID: -+ host_cmd = GETPID; -+ break; -+ -+ case TARGET_GETNCNT: -+ host_cmd = GETNCNT; -+ break; -+ -+ case TARGET_GETZCNT: -+ host_cmd = GETZCNT; -+ break; -+ -+ default: -+ return -TARGET_EINVAL; -+ } -+ -+ switch (host_cmd) { -+ case GETVAL: -+ case SETVAL: -+ arg.val = tswap32(target_su.val); -+ ret = get_errno(semctl(semid, semnum, host_cmd, arg)); -+ target_su.val = tswap32(arg.val); -+ break; -+ -+ case GETALL: -+ case SETALL: -+ if (get_user_ual(target_addr, (abi_ulong)target_su.array)) { -+ return -TARGET_EFAULT; -+ } -+ err = target_to_host_semarray(semid, &array, target_addr); -+ if (is_error(err)) { -+ return err; -+ } -+ arg.array = array; -+ ret = get_errno(semctl(semid, semnum, host_cmd, arg)); -+ err = host_to_target_semarray(semid, target_addr, &array); -+ if (is_error(err)) { -+ return err; -+ } -+ break; -+ -+ case IPC_STAT: -+ case IPC_SET: -+ if (get_user_ual(target_addr, (abi_ulong)target_su.buf)) { -+ return -TARGET_EFAULT; -+ } -+ err = target_to_host_semid_ds(&dsarg, target_addr); -+ if (is_error(err)) { -+ return err; -+ } -+ arg.buf = &dsarg; -+ ret = get_errno(semctl(semid, semnum, host_cmd, arg)); -+ err = host_to_target_semid_ds(target_addr, &dsarg); -+ if (is_error(err)) { -+ return err; -+ } -+ break; -+ -+ case IPC_RMID: -+ case GETPID: -+ case GETNCNT: -+ case GETZCNT: -+ ret = get_errno(semctl(semid, semnum, host_cmd, NULL)); -+ break; -+ -+ default: -+ ret = -TARGET_EINVAL; -+ break; -+ } -+ return ret; -+} -+ -+/* msgctl(2) */ -+static inline abi_long do_bsd_msgctl(int msgid, int target_cmd, abi_long ptr) -+{ -+ struct msqid_ds dsarg; -+ abi_long ret = -TARGET_EINVAL; -+ int host_cmd; -+ -+ switch (target_cmd) { -+ case TARGET_IPC_STAT: -+ host_cmd = IPC_STAT; -+ break; -+ -+ case TARGET_IPC_SET: -+ host_cmd = IPC_SET; -+ break; -+ -+ case TARGET_IPC_RMID: -+ host_cmd = IPC_RMID; -+ break; -+ -+ default: -+ return -TARGET_EINVAL; -+ } -+ -+ switch (host_cmd) { -+ case IPC_STAT: -+ case IPC_SET: -+ if (target_to_host_msqid_ds(&dsarg, ptr)) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(msgctl(msgid, host_cmd, &dsarg)); -+ if (host_to_target_msqid_ds(ptr, &dsarg)) { -+ return -TARGET_EFAULT; -+ } -+ break; -+ -+ case IPC_RMID: -+ ret = get_errno(msgctl(msgid, host_cmd, NULL)); -+ break; -+ -+ default: -+ ret = -TARGET_EINVAL; -+ break; -+ } -+ return ret; -+} -+ -+/* msgsnd(2) */ -+static inline abi_long do_bsd_msgsnd(int msqid, abi_long msgp, -+ unsigned int msgsz, int msgflg) -+{ -+ struct target_msgbuf *target_mb; -+ struct mymsg *host_mb; -+ abi_long ret; -+ -+ if (!lock_user_struct(VERIFY_READ, target_mb, msgp, 0)) { -+ return -TARGET_EFAULT; -+ } -+ host_mb = g_malloc(msgsz+sizeof(long)); -+ host_mb->mtype = (abi_long) tswapal(target_mb->mtype); -+ memcpy(host_mb->mtext, target_mb->mtext, msgsz); -+ ret = get_errno(msgsnd(msqid, host_mb, msgsz, msgflg)); -+ g_free(host_mb); -+ unlock_user_struct(target_mb, msgp, 0); -+ -+ return ret; -+} -+ -+/* msgrcv(2) */ -+static inline abi_long do_bsd_msgrcv(int msqid, abi_long msgp, -+ unsigned int msgsz, abi_long msgtyp, int msgflg) -+{ -+ struct target_msgbuf *target_mb = NULL; -+ char *target_mtext; -+ struct mymsg *host_mb; -+ abi_long ret = 0; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_mb, msgp, 0)) { -+ return -TARGET_EFAULT; -+ } -+ host_mb = g_malloc(msgsz+sizeof(long)); -+ ret = get_errno(msgrcv(msqid, host_mb, msgsz, tswapal(msgtyp), msgflg)); -+ if (ret > 0) { -+ abi_ulong target_mtext_addr = msgp + sizeof(abi_ulong); -+ target_mtext = lock_user(VERIFY_WRITE, target_mtext_addr, ret, 0); -+ if (target_mtext == NULL) { -+ ret = -TARGET_EFAULT; -+ goto end; -+ } -+ memcpy(target_mb->mtext, host_mb->mtext, ret); -+ unlock_user(target_mtext, target_mtext_addr, ret); -+ } -+ target_mb->mtype = tswapal(host_mb->mtype); -+end: -+ if (target_mb != NULL) { -+ unlock_user_struct(target_mb, msgp, 1); -+ } -+ g_free(host_mb); -+ return ret; -+} -+ -+/* getdtablesize(2) */ -+static inline abi_long do_bsd_getdtablesize(void) -+{ -+ -+ return get_errno(getdtablesize()); -+} -+ -+#endif /* ! __BSD_MISC_H_ */ -diff --git a/bsd-user/bsd-proc.c b/bsd-user/bsd-proc.c -new file mode 100644 -index 0000000..a4bcdc8 ---- /dev/null -+++ b/bsd-user/bsd-proc.c -@@ -0,0 +1,160 @@ -+/* -+ * BSD process related system call helpers -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#include <sys/types.h> -+#include <sys/resource.h> -+#include <sys/wait.h> -+ -+#include "qemu.h" -+#include "qemu-bsd.h" -+ -+/* -+ * resource/rusage conversion -+ */ -+int target_to_host_resource(int code) -+{ -+ -+ switch (code) { -+ case TARGET_RLIMIT_AS: -+ return RLIMIT_AS; -+ -+ case TARGET_RLIMIT_CORE: -+ return RLIMIT_CORE; -+ -+ case TARGET_RLIMIT_CPU: -+ return RLIMIT_CPU; -+ -+ case TARGET_RLIMIT_DATA: -+ return RLIMIT_DATA; -+ -+ case TARGET_RLIMIT_FSIZE: -+ return RLIMIT_FSIZE; -+ -+ case TARGET_RLIMIT_MEMLOCK: -+ return RLIMIT_MEMLOCK; -+ -+ case TARGET_RLIMIT_NOFILE: -+ return RLIMIT_NOFILE; -+ -+ case TARGET_RLIMIT_NPROC: -+ return RLIMIT_NPROC; -+ -+ case TARGET_RLIMIT_RSS: -+ return RLIMIT_RSS; -+ -+ case TARGET_RLIMIT_SBSIZE: -+ return RLIMIT_SBSIZE; -+ -+ case TARGET_RLIMIT_STACK: -+ return RLIMIT_STACK; -+ -+ case TARGET_RLIMIT_SWAP: -+ return RLIMIT_SWAP; -+ -+ case TARGET_RLIMIT_NPTS: -+ return RLIMIT_NPTS; -+ -+ default: -+ return code; -+ } -+} -+ -+rlim_t target_to_host_rlim(abi_ulong target_rlim) -+{ -+ abi_ulong target_rlim_swap; -+ rlim_t result; -+ -+ target_rlim_swap = tswapal(target_rlim); -+ if (target_rlim_swap == TARGET_RLIM_INFINITY) { -+ return RLIM_INFINITY; -+ } -+ -+ result = target_rlim_swap; -+ if (target_rlim_swap != (rlim_t)result) { -+ return RLIM_INFINITY; -+ } -+ -+ return result; -+} -+ -+abi_ulong host_to_target_rlim(rlim_t rlim) -+{ -+ abi_ulong target_rlim_swap; -+ abi_ulong result; -+ -+ if (rlim == RLIM_INFINITY || rlim != (abi_long)rlim) { -+ target_rlim_swap = TARGET_RLIM_INFINITY; -+ } else { -+ target_rlim_swap = rlim; -+ } -+ result = tswapal(target_rlim_swap); -+ -+ return result; -+} -+ -+abi_long host_to_target_rusage(abi_ulong target_addr, -+ const struct rusage *rusage) -+{ -+ struct target_freebsd_rusage *target_rusage; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __put_user(rusage->ru_utime.tv_sec, &target_rusage->ru_utime.tv_sec); -+ __put_user(rusage->ru_utime.tv_usec, &target_rusage->ru_utime.tv_usec); -+ -+ __put_user(rusage->ru_stime.tv_sec, &target_rusage->ru_stime.tv_sec); -+ __put_user(rusage->ru_stime.tv_usec, &target_rusage->ru_stime.tv_usec); -+ -+ __put_user(rusage->ru_maxrss, &target_rusage->ru_maxrss); -+ __put_user(rusage->ru_idrss, &target_rusage->ru_idrss); -+ __put_user(rusage->ru_idrss, &target_rusage->ru_idrss); -+ __put_user(rusage->ru_isrss, &target_rusage->ru_isrss); -+ __put_user(rusage->ru_minflt, &target_rusage->ru_minflt); -+ __put_user(rusage->ru_majflt, &target_rusage->ru_majflt); -+ __put_user(rusage->ru_nswap, &target_rusage->ru_nswap); -+ __put_user(rusage->ru_inblock, &target_rusage->ru_inblock); -+ __put_user(rusage->ru_oublock, &target_rusage->ru_oublock); -+ __put_user(rusage->ru_msgsnd, &target_rusage->ru_msgsnd); -+ __put_user(rusage->ru_msgrcv, &target_rusage->ru_msgrcv); -+ __put_user(rusage->ru_nsignals, &target_rusage->ru_nsignals); -+ __put_user(rusage->ru_nvcsw, &target_rusage->ru_nvcsw); -+ __put_user(rusage->ru_nivcsw, &target_rusage->ru_nivcsw); -+ unlock_user_struct(target_rusage, target_addr, 1); -+ -+ return 0; -+} -+ -+/* -+ * wait status conversion. -+ * -+ * Map host to target signal numbers for the wait family of syscalls. -+ * Assume all other status bits are the same. -+ */ -+int host_to_target_waitstatus(int status) -+{ -+ if (WIFSIGNALED(status)) { -+ return host_to_target_signal(WTERMSIG(status)) | (status & ~0x7f); -+ } -+ if (WIFSTOPPED(status)) { -+ return (host_to_target_signal(WSTOPSIG(status)) << 8) | (status & 0xff); -+ } -+ return status; -+} -+ -diff --git a/bsd-user/bsd-proc.h b/bsd-user/bsd-proc.h -new file mode 100644 -index 0000000..d1c732a ---- /dev/null -+++ b/bsd-user/bsd-proc.h -@@ -0,0 +1,434 @@ -+/* -+ * process related system call shims 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 __BSD_PROC_H_ -+#define __BSD_PROC_H_ -+ -+#include <sys/types.h> -+#include <sys/stat.h> -+#include <sys/time.h> -+#include <sys/resource.h> -+#include <unistd.h> -+ -+#include "qemu-bsd.h" -+ -+extern int _getlogin(char*, int); -+ -+/* exit(2) */ -+static inline abi_long do_bsd_exit(void *cpu_env, abi_long arg1) -+{ -+#ifdef TARGET_GPROF -+ _mcleanup(); -+#endif -+ gdb_exit(cpu_env, arg1); -+ /* XXX: should free thread stack and CPU env here */ -+ _exit(arg1); -+ -+ return 0; -+} -+ -+/* getgroups(2) */ -+static inline abi_long do_bsd_getgroups(abi_long gidsetsize, abi_long arg2) -+{ -+ abi_long ret; -+ uint32_t *target_grouplist; -+ gid_t *grouplist; -+ int i; -+ -+ grouplist = alloca(gidsetsize * sizeof(gid_t)); -+ ret = get_errno(getgroups(gidsetsize, grouplist)); -+ if (gidsetsize != 0) { -+ if (!is_error(ret)) { -+ target_grouplist = lock_user(VERIFY_WRITE, arg2, gidsetsize * 2, 0); -+ if (!target_grouplist) { -+ return -TARGET_EFAULT; -+ } -+ for (i = 0; i < ret; i++) { -+ target_grouplist[i] = tswap32(grouplist[i]); -+ } -+ unlock_user(target_grouplist, arg2, gidsetsize * 2); -+ } -+ } -+ return ret; -+} -+ -+/* setgroups(2) */ -+static inline abi_long do_bsd_setgroups(abi_long gidsetsize, abi_long arg2) -+{ -+ uint32_t *target_grouplist; -+ gid_t *grouplist; -+ int i; -+ -+ grouplist = alloca(gidsetsize * sizeof(gid_t)); -+ target_grouplist = lock_user(VERIFY_READ, arg2, gidsetsize * 2, 1); -+ if (!target_grouplist) { -+ return -TARGET_EFAULT; -+ } -+ for (i = 0; i < gidsetsize; i++) { -+ grouplist[i] = tswap32(target_grouplist[i]); -+ } -+ unlock_user(target_grouplist, arg2, 0); -+ return get_errno(setgroups(gidsetsize, grouplist)); -+} -+ -+/* umask(2) */ -+static inline abi_long do_bsd_umask(abi_long arg1) -+{ -+ -+ return get_errno(umask(arg1)); -+} -+ -+/* setlogin(2) */ -+static inline abi_long do_bsd_setlogin(abi_long arg1) -+{ -+ abi_long ret; -+ void *p; -+ -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(setlogin(p)); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* getlogin(2) */ -+static inline abi_long do_bsd_getlogin(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(_getlogin(p, arg2)); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* getrusage(2) */ -+static inline abi_long do_bsd_getrusage(abi_long who, abi_ulong target_addr) -+{ -+ abi_long ret; -+ struct rusage rusage; -+ -+ ret = get_errno(getrusage(who, &rusage)); -+ if (!is_error(ret)) { -+ host_to_target_rusage(target_addr, &rusage); -+ } -+ return ret; -+} -+ -+/* getrlimit(2) */ -+static inline abi_long do_bsd_getrlimit(abi_long arg1, abi_ulong arg2) -+{ -+ abi_long ret; -+ int resource = target_to_host_resource(arg1); -+ struct target_rlimit *target_rlim; -+ struct rlimit rlim; -+ -+ switch (resource) { -+ case RLIMIT_STACK: -+ rlim.rlim_cur = target_dflssiz; -+ rlim.rlim_max = target_maxssiz; -+ ret = 0; -+ break; -+ -+ case RLIMIT_DATA: -+ rlim.rlim_cur = target_dfldsiz; -+ rlim.rlim_max = target_maxdsiz; -+ ret = 0; -+ break; -+ -+ default: -+ ret = get_errno(getrlimit(resource, &rlim)); -+ break; -+ } -+ if (!is_error(ret)) { -+ if (!lock_user_struct(VERIFY_WRITE, target_rlim, arg2, 0)) { -+ return -TARGET_EFAULT; -+ } -+ target_rlim->rlim_cur = host_to_target_rlim(rlim.rlim_cur); -+ target_rlim->rlim_max = host_to_target_rlim(rlim.rlim_max); -+ unlock_user_struct(target_rlim, arg2, 1); -+ } -+ return ret; -+} -+ -+/* setrlimit(2) */ -+static inline abi_long do_bsd_setrlimit(abi_long arg1, abi_ulong arg2) -+{ -+ abi_long ret; -+ int resource = target_to_host_resource(arg1); -+ struct target_rlimit *target_rlim; -+ struct rlimit rlim; -+ -+ if (RLIMIT_STACK == resource) { -+ /* XXX We should, maybe, allow the stack size to shrink */ -+ ret = -TARGET_EPERM; -+ } else { -+ if (!lock_user_struct(VERIFY_READ, target_rlim, arg2, 1)) { -+ return -TARGET_EFAULT; -+ } -+ rlim.rlim_cur = target_to_host_rlim(target_rlim->rlim_cur); -+ rlim.rlim_max = target_to_host_rlim(target_rlim->rlim_max); -+ unlock_user_struct(target_rlim, arg2, 0); -+ ret = get_errno(setrlimit(resource, &rlim)); -+ } -+ return ret; -+} -+ -+/* getpid(2) */ -+static inline abi_long do_bsd_getpid(void) -+{ -+ -+ return get_errno(getpid()); -+} -+ -+/* getppid(2) */ -+static inline abi_long do_bsd_getppid(void) -+{ -+ -+ return get_errno(getppid()); -+} -+ -+/* getuid(2) */ -+static inline abi_long do_bsd_getuid(void) -+{ -+ -+ return get_errno(getuid()); -+} -+ -+/* geteuid(2) */ -+static inline abi_long do_bsd_geteuid(void) -+{ -+ -+ return get_errno(geteuid()); -+} -+ -+/* getgid(2) */ -+static inline abi_long do_bsd_getgid(void) -+{ -+ -+ return get_errno(getgid()); -+} -+ -+/* getegid(2) */ -+static inline abi_long do_bsd_getegid(void) -+{ -+ -+ return get_errno(getegid()); -+} -+ -+/* setuid(2) */ -+static inline abi_long do_bsd_setuid(abi_long arg1) -+{ -+ -+ return get_errno(setuid(arg1)); -+} -+ -+/* seteuid(2) */ -+static inline abi_long do_bsd_seteuid(abi_long arg1) -+{ -+ -+ return get_errno(seteuid(arg1)); -+} -+ -+/* setgid(2) */ -+static inline abi_long do_bsd_setgid(abi_long arg1) -+{ -+ -+ return get_errno(setgid(arg1)); -+} -+ -+/* setegid(2) */ -+static inline abi_long do_bsd_setegid(abi_long arg1) -+{ -+ -+ return get_errno(setegid(arg1)); -+} -+ -+/* getpgrp(2) */ -+static inline abi_long do_bsd_getpgrp(void) -+{ -+ -+ return get_errno(getpgrp()); -+} -+ -+/* setreuid(2) */ -+static inline abi_long do_bsd_setreuid(abi_long arg1, abi_long arg2) -+{ -+ -+ return get_errno(setreuid(arg1, arg2)); -+} -+ -+/* setregid(2) */ -+static inline abi_long do_bsd_setregid(abi_long arg1, abi_long arg2) -+{ -+ -+ return get_errno(setregid(arg1, arg2)); -+} -+ -+/* setresuid(2) */ -+static inline abi_long do_bsd_setresuid(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ return get_errno(setresuid(arg1, arg2, arg3)); -+} -+ -+/* getresuid(2) */ -+static inline abi_long do_bsd_getresuid(abi_ulong arg1, abi_ulong arg2, -+ abi_ulong arg3) -+{ -+ abi_long ret; -+ uid_t ruid, euid, suid; -+ -+ ret = get_errno(getresuid(&ruid, &euid, &suid)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ if (put_user_s32(ruid, arg1)) { -+ return -TARGET_EFAULT; -+ } -+ if (put_user_s32(euid, arg2)) { -+ return -TARGET_EFAULT; -+ } -+ if (put_user_s32(suid, arg3)) { -+ return -TARGET_EFAULT; -+ } -+ return ret; -+} -+ -+/* getresgid(2) */ -+static inline abi_long do_bsd_getresgid(abi_ulong arg1, abi_ulong arg2, -+ abi_ulong arg3) -+{ -+ abi_long ret; -+ uid_t ruid, euid, suid; -+ -+ ret = get_errno(getresgid(&ruid, &euid, &suid)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ if (put_user_s32(ruid, arg1)) { -+ return -TARGET_EFAULT; -+ } -+ if (put_user_s32(euid, arg2)) { -+ return -TARGET_EFAULT; -+ } -+ if (put_user_s32(suid, arg3)) { -+ return -TARGET_EFAULT; -+ } -+ return ret; -+} -+ -+/* getsid(2) */ -+static inline abi_long do_bsd_getsid(abi_long arg1) -+{ -+ -+ return get_errno(getsid(arg1)); -+} -+ -+/* setsid(2) */ -+static inline abi_long do_bsd_setsid(void) -+{ -+ -+ return get_errno(setsid()); -+} -+ -+/* issetugid(2) */ -+static inline abi_long do_bsd_issetugid(void) -+{ -+ -+ return get_errno(issetugid()); -+} -+ -+/* profil(2) */ -+static inline abi_long do_bsd_profil(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4) -+{ -+ -+ qemu_log("qemu: Unsupported syscall profil()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* ktrace(2) */ -+static inline abi_long do_bsd_ktrace(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4) -+{ -+ -+ qemu_log("qemu: Unsupported syscall ktrace()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* utrace(2) */ -+static inline abi_long do_bsd_utrace(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall ptrace()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* ptrace(2) */ -+static inline abi_long do_bsd_ptrace(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4) -+{ -+ -+ qemu_log("qemu: Unsupported syscall ptrace()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getpriority(2) */ -+static inline abi_long do_bsd_getpriority(abi_long which, abi_long who) -+{ -+ abi_long ret; -+ /* -+ * Note that negative values are valid for getpriority, so we must -+ * differentiate based on errno settings. -+ */ -+ errno = 0; -+ ret = getpriority(which, who); -+ if (ret == -1 && errno != 0) { -+ ret = -host_to_target_errno(errno); -+ return ret; -+ } -+ /* Return value is a biased priority to avoid negative numbers. */ -+ ret = 20 - ret; -+ -+ return ret; -+} -+ -+/* setpriority(2) */ -+static inline abi_long do_bsd_setpriority(abi_long which, abi_long who, -+ abi_long prio) -+{ -+ -+ return get_errno(setpriority(which, who, prio)); -+} -+ -+ -+#endif /* !__BSD_PROC_H_ */ -+ -diff --git a/bsd-user/bsd-signal.h b/bsd-user/bsd-signal.h -new file mode 100644 -index 0000000..48a8b56 ---- /dev/null -+++ b/bsd-user/bsd-signal.h -@@ -0,0 +1,232 @@ -+/* -+ * signal related system call shims -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef __BSD_SIGNAL_H_ -+#define __BSD_SIGNAL_H_ -+ -+/* sigaction(2) */ -+static inline abi_long do_bsd_sigaction(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ abi_long ret; -+ struct target_sigaction *old_act, act, oact, *pact; -+ -+ if (arg2) { -+ if (!lock_user_struct(VERIFY_READ, old_act, arg2, 1)) { -+ return -TARGET_EFAULT; -+ } -+ act._sa_handler = old_act->_sa_handler; -+ act.sa_flags = old_act->sa_flags; -+ memcpy(&act.sa_mask, &old_act->sa_mask, sizeof(target_sigset_t)); -+ unlock_user_struct(old_act, arg2, 0); -+ pact = &act; -+ } else { -+ pact = NULL; -+ } -+ ret = get_errno(do_sigaction(arg1, pact, &oact)); -+ if (!is_error(ret) && arg3) { -+ if (!lock_user_struct(VERIFY_WRITE, old_act, arg3, 0)) { -+ return -TARGET_EFAULT; -+ } -+ old_act->_sa_handler = oact._sa_handler; -+ old_act->sa_flags = oact.sa_flags; -+ memcpy(&old_act->sa_mask, &oact.sa_mask, sizeof(target_sigset_t)); -+ unlock_user_struct(old_act, arg3, 1); -+ } -+ return ret; -+} -+ -+ -+/* sigprocmask(2) */ -+static inline abi_long do_bsd_sigprocmask(abi_long arg1, abi_ulong arg2, -+ abi_ulong arg3) -+{ -+ abi_long ret; -+ void *p; -+ sigset_t set, oldset, *set_ptr; -+ int how; -+ -+ if (arg2) { -+ switch (arg1) { -+ case TARGET_SIG_BLOCK: -+ how = SIG_BLOCK; -+ break; -+ -+ case TARGET_SIG_UNBLOCK: -+ how = SIG_UNBLOCK; -+ break; -+ -+ case TARGET_SIG_SETMASK: -+ how = SIG_SETMASK; -+ break; -+ -+ default: -+ return -TARGET_EFAULT; -+ } -+ p = lock_user(VERIFY_READ, arg2, sizeof(target_sigset_t), 1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ target_to_host_sigset(&set, p); -+ unlock_user(p, arg2, 0); -+ set_ptr = &set; -+ } else { -+ how = 0; -+ set_ptr = NULL; -+ } -+ ret = get_errno(sigprocmask(how, set_ptr, &oldset)); -+ if (!is_error(ret) && arg3) { -+ p = lock_user(VERIFY_WRITE, arg3, sizeof(target_sigset_t), 0); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ host_to_target_sigset(p, &oldset); -+ unlock_user(p, arg3, sizeof(target_sigset_t)); -+ } -+ return ret; -+} -+ -+/* sigpending(2) */ -+static inline abi_long do_bsd_sigpending(abi_long arg1) -+{ -+ abi_long ret; -+ void *p; -+ sigset_t set; -+ -+ ret = get_errno(sigpending(&set)); -+ if (!is_error(ret)) { -+ p = lock_user(VERIFY_WRITE, arg1, sizeof(target_sigset_t), 0); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ host_to_target_sigset(p, &set); -+ unlock_user(p, arg1, sizeof(target_sigset_t)); -+ } -+ return ret; -+} -+ -+/* sigsuspend(2) */ -+static inline abi_long do_bsd_sigsuspend(abi_long arg1, abi_long arg2) -+{ -+ void *p; -+ sigset_t set; -+ -+ p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ target_to_host_sigset(&set, p); -+ unlock_user(p, arg1, 0); -+ -+ return get_errno(sigsuspend(&set)); -+} -+ -+/* sigreturn(2) */ -+static inline abi_long do_bsd_sigreturn(void *cpu_env, abi_long arg1) -+{ -+ -+ return do_sigreturn(cpu_env, arg1); -+} -+ -+/* sigvec(2) - not defined */ -+/* sigblock(2) - not defined */ -+/* sigsetmask(2) - not defined */ -+/* sigstack(2) - not defined */ -+ -+/* sigwait(2) */ -+static inline abi_long do_bsd_sigwait(abi_ulong arg1, abi_ulong arg2, -+ abi_long arg3) -+{ -+ abi_long ret; -+ void *p; -+ sigset_t set; -+ int sig; -+ -+ p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ target_to_host_sigset(&set, p); -+ unlock_user(p, arg1, 0); -+ ret = get_errno(sigwait(&set, &sig)); -+ if (!is_error(ret) && arg2) { -+ ret = put_user_s32(sig, arg2); -+ } -+ return ret; -+} -+ -+/* sigwaitinfo(2) */ -+static inline abi_long do_bsd_sigwaitinfo(abi_ulong arg1, abi_ulong arg2) -+{ -+ abi_long ret; -+ void *p; -+ sigset_t set; -+ siginfo_t uinfo; -+ -+ p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ target_to_host_sigset(&set, p); -+ unlock_user(p, arg1, 0); -+ ret = get_errno(sigwaitinfo(&set, &uinfo)); -+ if (!is_error(ret) && arg2) { -+ p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ host_to_target_siginfo(p, &uinfo); -+ unlock_user(p, arg2, sizeof(target_siginfo_t)); -+ } -+ return ret; -+} -+ -+/* sigqueue(2) */ -+static inline abi_long do_bsd_sigqueue(abi_long arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ union sigval value; -+ -+ value.sival_ptr = (void *)(uintptr_t)arg3; -+ return get_errno(sigqueue(arg1, target_to_host_signal(arg2), value)); -+} -+ -+/* sigaltstck(2) */ -+static inline abi_long do_bsd_sigaltstack(void *cpu_env, abi_ulong arg1, -+ abi_ulong arg2) -+{ -+ -+ return do_sigaltstack(arg1, arg2, get_sp_from_cpustate(cpu_env)); -+} -+ -+/* kill(2) */ -+static inline abi_long do_bsd_kill(abi_long pid, abi_long sig) -+{ -+ -+ return get_errno(kill(pid, target_to_host_signal(sig))); -+} -+ -+/* killpg(2) */ -+static inline abi_long do_bsd_killpg(abi_long pg, abi_long sig) -+{ -+ -+ return get_errno(killpg(pg, target_to_host_signal(sig))); -+} -+ -+#endif /* ! __BSD_SIGNAL_H_ */ -diff --git a/bsd-user/bsd-socket.c b/bsd-user/bsd-socket.c -new file mode 100644 -index 0000000..c1a3b49 ---- /dev/null -+++ b/bsd-user/bsd-socket.c -@@ -0,0 +1,108 @@ -+/* -+ * BSD socket system call related helpers -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#include <sys/types.h> -+#include <sys/socket.h> -+#include <sys/un.h> -+#include <netinet/in.h> -+ -+#include "qemu.h" -+#include "qemu-bsd.h" -+ -+/* -+ * socket conversion -+ */ -+abi_long target_to_host_sockaddr(struct sockaddr *addr, abi_ulong target_addr, -+ socklen_t len) -+{ -+ const socklen_t unix_maxlen = sizeof(struct sockaddr_un); -+ sa_family_t sa_family; -+ struct target_sockaddr *target_saddr; -+ -+ target_saddr = lock_user(VERIFY_READ, target_addr, len, 1); -+ if (target_saddr == 0) { -+ return -TARGET_EFAULT; -+ } -+ -+ sa_family = target_saddr->sa_family; -+ -+ /* -+ * Oops. The caller might send a incomplete sun_path; sun_path -+ * must be terminated by \0 (see the manual page), but unfortunately -+ * it is quite common to specify sockaddr_un length as -+ * "strlen(x->sun_path)" while it should be "strlen(...) + 1". We will -+ * fix that here if needed. -+ */ -+ if (target_saddr->sa_family == AF_UNIX) { -+ if (len < unix_maxlen && len > 0) { -+ char *cp = (char *)target_saddr; -+ -+ if (cp[len-1] && !cp[len]) { -+ len++; -+ } -+ } -+ if (len > unix_maxlen) { -+ len = unix_maxlen; -+ } -+ } -+ -+ memcpy(addr, target_saddr, len); -+ addr->sa_family = sa_family; /* type uint8_t */ -+ addr->sa_len = target_saddr->sa_len; /* type uint8_t */ -+ unlock_user(target_saddr, target_addr, 0); -+ -+ return 0; -+} -+ -+abi_long host_to_target_sockaddr(abi_ulong target_addr, struct sockaddr *addr, -+ socklen_t len) -+{ -+ struct target_sockaddr *target_saddr; -+ -+ target_saddr = lock_user(VERIFY_WRITE, target_addr, len, 0); -+ if (target_saddr == 0) { -+ return -TARGET_EFAULT; -+ } -+ memcpy(target_saddr, addr, len); -+ target_saddr->sa_family = addr->sa_family; /* type uint8_t */ -+ target_saddr->sa_len = addr->sa_len; /* type uint8_t */ -+ unlock_user(target_saddr, target_addr, len); -+ -+ return 0; -+} -+ -+abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn, abi_ulong target_addr, -+ socklen_t len) -+{ -+ struct target_ip_mreqn *target_smreqn; -+ -+ target_smreqn = lock_user(VERIFY_READ, target_addr, len, 1); -+ if (target_smreqn == 0) { -+ return -TARGET_EFAULT; -+ } -+ mreqn->imr_multiaddr.s_addr = target_smreqn->imr_multiaddr.s_addr; -+ mreqn->imr_address.s_addr = target_smreqn->imr_address.s_addr; -+ if (len == sizeof(struct target_ip_mreqn)) { -+ mreqn->imr_ifindex = tswapal(target_smreqn->imr_ifindex); -+ } -+ unlock_user(target_smreqn, target_addr, 0); -+ -+ return 0; -+} -+ -diff --git a/bsd-user/bsd-socket.h b/bsd-user/bsd-socket.h -new file mode 100644 -index 0000000..f5d1ac8 ---- /dev/null -+++ b/bsd-user/bsd-socket.h -@@ -0,0 +1,266 @@ -+/* -+ * socket related system call shims -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+#ifndef __BSD_SOCKET_H_ -+#define __BSD_SOCKET_H_ -+ -+#include <sys/types.h> -+#include <sys/socket.h> -+#include <sys/un.h> -+#include <netinet/in.h> -+ -+#include "qemu-bsd.h" -+ -+/* bind(2) */ -+static inline abi_long do_bsd_bind(int sockfd, abi_ulong target_addr, -+ socklen_t addrlen) -+{ -+ abi_long ret; -+ void *addr; -+ -+ if ((int)addrlen < 0) { -+ return -TARGET_EINVAL; -+ } -+ -+ addr = alloca(addrlen + 1); -+ ret = target_to_host_sockaddr(addr, target_addr, addrlen); -+ if (is_error(ret)) { -+ return ret; -+ } -+ -+ return get_errno(bind(sockfd, addr, addrlen)); -+} -+ -+/* connect(2) */ -+static inline abi_long do_bsd_connect(int sockfd, abi_ulong target_addr, -+ socklen_t addrlen) -+{ -+ abi_long ret; -+ void *addr; -+ -+ if ((int)addrlen < 0) { -+ return -TARGET_EINVAL; -+ } -+ addr = alloca(addrlen); -+ -+ ret = target_to_host_sockaddr(addr, target_addr, addrlen); -+ -+ if (is_error(ret)) { -+ return ret; -+ } -+ -+ return get_errno(connect(sockfd, addr, addrlen)); -+} -+ -+/* accept(2) */ -+static inline abi_long do_bsd_accept(int fd, abi_ulong target_addr, -+ abi_ulong target_addrlen_addr) -+{ -+ socklen_t addrlen; -+ void *addr; -+ abi_long ret; -+ -+ if (target_addr == 0) { -+ return get_errno(accept(fd, NULL, NULL)); -+ } -+ /* return EINVAL if addrlen pointer is invalid */ -+ if (get_user_u32(addrlen, target_addrlen_addr)) { -+ return -TARGET_EINVAL; -+ } -+ if ((int)addrlen < 0) { -+ return -TARGET_EINVAL; -+ } -+ if (!access_ok(VERIFY_WRITE, target_addr, addrlen)) { -+ return -TARGET_EINVAL; -+ } -+ addr = alloca(addrlen); -+ -+ ret = get_errno(accept(fd, addr, &addrlen)); -+ if (!is_error(ret)) { -+ host_to_target_sockaddr(target_addr, addr, addrlen); -+ if (put_user_u32(addrlen, target_addrlen_addr)) { -+ ret = -TARGET_EFAULT; -+ } -+ } -+ return ret; -+} -+ -+/* getpeername(2) */ -+static inline abi_long do_bsd_getpeername(int fd, abi_ulong target_addr, -+ abi_ulong target_addrlen_addr) -+{ -+ socklen_t addrlen; -+ void *addr; -+ abi_long ret; -+ -+ if (get_user_u32(addrlen, target_addrlen_addr)) { -+ return -TARGET_EFAULT; -+ } -+ if ((int)addrlen < 0) { -+ return -TARGET_EINVAL; -+ } -+ if (!access_ok(VERIFY_WRITE, target_addr, addrlen)) { -+ return -TARGET_EFAULT; -+ } -+ addr = alloca(addrlen); -+ ret = get_errno(getpeername(fd, addr, &addrlen)); -+ if (!is_error(ret)) { -+ host_to_target_sockaddr(target_addr, addr, addrlen); -+ if (put_user_u32(addrlen, target_addrlen_addr)) { -+ ret = -TARGET_EFAULT; -+ } -+ } -+ return ret; -+} -+ -+/* getsockname(2) */ -+static inline abi_long do_bsd_getsockname(int fd, abi_ulong target_addr, -+ abi_ulong target_addrlen_addr) -+{ -+ socklen_t addrlen; -+ void *addr; -+ abi_long ret; -+ -+ if (get_user_u32(addrlen, target_addrlen_addr)) { -+ return -TARGET_EFAULT; -+ } -+ if ((int)addrlen < 0) { -+ return -TARGET_EINVAL; -+ } -+ if (!access_ok(VERIFY_WRITE, target_addr, addrlen)) { -+ return -TARGET_EFAULT; -+ } -+ addr = alloca(addrlen); -+ -+ ret = get_errno(getsockname(fd, addr, &addrlen)); -+ if (!is_error(ret)) { -+ host_to_target_sockaddr(target_addr, addr, addrlen); -+ if (put_user_u32(addrlen, target_addrlen_addr)) { -+ ret = -TARGET_EFAULT; -+ } -+ } -+ return ret; -+} -+ -+/* socketpair(2) */ -+static inline abi_long do_bsd_socketpair(int domain, int type, int protocol, -+ abi_ulong target_tab_addr) -+{ -+ int tab[2]; -+ abi_long ret; -+ -+ ret = get_errno(socketpair(domain, type, protocol, tab)); -+ if (!is_error(ret)) { -+ if (put_user_s32(tab[0], target_tab_addr) || -+ put_user_s32(tab[1], target_tab_addr + sizeof(tab[0]))) { -+ ret = -TARGET_EFAULT; -+ } -+ } -+ return ret; -+} -+ -+/* sendto(2) */ -+static inline abi_long do_bsd_sendto(int fd, abi_ulong msg, size_t len, -+ int flags, abi_ulong target_addr, socklen_t addrlen) -+{ -+ struct sockaddr *saddr; -+ void *host_msg; -+ abi_long ret; -+ -+ if ((int)addrlen < 0) { -+ return -TARGET_EINVAL; -+ } -+ host_msg = lock_user(VERIFY_READ, msg, len, 1); -+ if (!host_msg) { -+ return -TARGET_EFAULT; -+ } -+ if (target_addr) { -+ saddr = alloca(addrlen); -+ ret = target_to_host_sockaddr(saddr, target_addr, addrlen); -+ if (is_error(ret)) { -+ unlock_user(host_msg, msg, 0); -+ return ret; -+ } -+ ret = get_errno(sendto(fd, host_msg, len, flags, saddr, addrlen)); -+ } else { -+ ret = get_errno(send(fd, host_msg, len, flags)); -+ } -+ unlock_user(host_msg, msg, 0); -+ return ret; -+} -+ -+/* recvfrom(2) */ -+static inline abi_long do_bsd_recvfrom(int fd, abi_ulong msg, size_t len, -+ int flags, abi_ulong target_addr, abi_ulong target_addrlen) -+{ -+ socklen_t addrlen; -+ struct sockaddr *saddr; -+ void *host_msg; -+ abi_long ret; -+ -+ host_msg = lock_user(VERIFY_WRITE, msg, len, 0); -+ if (!host_msg) { -+ return -TARGET_EFAULT; -+ } -+ if (target_addr) { -+ if (get_user_u32(addrlen, target_addrlen)) { -+ ret = -TARGET_EFAULT; -+ goto fail; -+ } -+ if ((int)addrlen < 0) { -+ ret = -TARGET_EINVAL; -+ goto fail; -+ } -+ saddr = alloca(addrlen); -+ ret = get_errno(recvfrom(fd, host_msg, len, flags, saddr, &addrlen)); -+ } else { -+ saddr = NULL; /* To keep compiler quiet. */ -+ ret = get_errno(qemu_recv(fd, host_msg, len, flags)); -+ } -+ if (!is_error(ret)) { -+ if (target_addr) { -+ host_to_target_sockaddr(target_addr, saddr, addrlen); -+ if (put_user_u32(addrlen, target_addrlen)) { -+ ret = -TARGET_EFAULT; -+ goto fail; -+ } -+ } -+ unlock_user(host_msg, msg, len); -+ } else { -+fail: -+ unlock_user(host_msg, msg, 0); -+ } -+ return ret; -+} -+ -+/* socket(2) */ -+static inline abi_long do_bsd_socket(abi_long domain, abi_long type, -+ abi_long protocol) -+{ -+ -+ return get_errno(socket(domain, type, protocol)); -+} -+ -+/* shutdown(2) */ -+static inline abi_long do_bsd_shutdown(abi_long s, abi_long how) -+{ -+ -+ return get_errno(shutdown(s, how)); -+} -+ -+#endif /* !__BSD_SOCKET_H_ */ -diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c -index 2abc713..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,38 +41,22 @@ 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++; - } - - return(i); - } - --static int prepare_binprm(struct linux_binprm *bprm) -+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 linux_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 linux_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 linux_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 93fd9e4..ef96b8c 100644 ---- a/bsd-user/elfload.c -+++ b/bsd-user/elfload.c -@@ -1,4 +1,20 @@ --/* This is the Linux kernel elf-loading code, ported into user space */ -+/* -+ * ELF loading 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 <stdio.h> - #include <sys/types.h> -@@ -11,544 +27,12 @@ - - #include "qemu.h" - #include "disas/disas.h" -+#include "target_os_elf.h" -+#include "target_os_stack.h" -+#include "target_os_thread.h" - --#ifdef _ARCH_PPC64 --#undef ARCH_DLINFO --#undef ELF_PLATFORM --#undef ELF_HWCAP --#undef ELF_CLASS --#undef ELF_DATA --#undef ELF_ARCH --#endif -- --/* from personality.h */ -- --/* -- * Flags for bug emulation. -- * -- * These occupy the top three bytes. -- */ --enum { -- ADDR_NO_RANDOMIZE = 0x0040000, /* disable randomization of VA space */ -- FDPIC_FUNCPTRS = 0x0080000, /* userspace function ptrs point to descriptors -- * (signal handling) -- */ -- MMAP_PAGE_ZERO = 0x0100000, -- ADDR_COMPAT_LAYOUT = 0x0200000, -- READ_IMPLIES_EXEC = 0x0400000, -- ADDR_LIMIT_32BIT = 0x0800000, -- SHORT_INODE = 0x1000000, -- WHOLE_SECONDS = 0x2000000, -- STICKY_TIMEOUTS = 0x4000000, -- ADDR_LIMIT_3GB = 0x8000000, --}; -- --/* -- * Personality types. -- * -- * These go in the low byte. Avoid using the top bit, it will -- * conflict with error returns. -- */ --enum { -- PER_LINUX = 0x0000, -- PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT, -- PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS, -- PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, -- PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE, -- PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS | -- WHOLE_SECONDS | SHORT_INODE, -- PER_OSR5 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS, -- PER_WYSEV386 = 0x0004 | STICKY_TIMEOUTS | SHORT_INODE, -- PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS, -- PER_BSD = 0x0006, -- PER_SUNOS = 0x0006 | STICKY_TIMEOUTS, -- PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE, -- PER_LINUX32 = 0x0008, -- PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB, -- PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */ -- PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */ -- PER_IRIX64 = 0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */ -- PER_RISCOS = 0x000c, -- PER_SOLARIS = 0x000d | STICKY_TIMEOUTS, -- PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, -- PER_OSF4 = 0x000f, /* OSF/1 v4 */ -- PER_HPUX = 0x0010, -- PER_MASK = 0x00ff, --}; -- --/* -- * Return the base personality without flags. -- */ --#define personality(pers) (pers & PER_MASK) -- --/* this flag is uneffective under linux too, should be deleted */ --#ifndef MAP_DENYWRITE --#define MAP_DENYWRITE 0 --#endif -- --/* should probably go in elf.h */ --#ifndef ELIBBAD --#define ELIBBAD 80 --#endif -- --#ifdef TARGET_I386 -- --#define ELF_PLATFORM get_elf_platform() -- --static const char *get_elf_platform(void) --{ -- static char elf_platform[] = "i386"; -- int family = object_property_get_int(OBJECT(thread_cpu), "family", NULL); -- if (family > 6) -- family = 6; -- if (family >= 3) -- elf_platform[1] = '0' + family; -- return elf_platform; --} -- --#define ELF_HWCAP get_elf_hwcap() -- --static uint32_t get_elf_hwcap(void) --{ -- X86CPU *cpu = X86_CPU(thread_cpu); -- -- return cpu->env.features[FEAT_1_EDX]; --} -- --#ifdef TARGET_X86_64 --#define ELF_START_MMAP 0x2aaaaab000ULL --#define elf_check_arch(x) ( ((x) == ELF_ARCH) ) -- --#define ELF_CLASS ELFCLASS64 --#define ELF_DATA ELFDATA2LSB --#define ELF_ARCH EM_X86_64 -- --static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) --{ -- regs->rax = 0; -- regs->rsp = infop->start_stack; -- regs->rip = infop->entry; -- if (bsd_type == target_freebsd) { -- regs->rdi = infop->start_stack; -- } --} -- --#else -- --#define ELF_START_MMAP 0x80000000 -- --/* -- * This is used to ensure we don't load something for the wrong architecture. -- */ --#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) ) -- --/* -- * These are used to set parameters in the core dumps. -- */ --#define ELF_CLASS ELFCLASS32 --#define ELF_DATA ELFDATA2LSB --#define ELF_ARCH EM_386 -- --static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) --{ -- regs->esp = infop->start_stack; -- regs->eip = infop->entry; -- -- /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program -- starts %edx contains a pointer to a function which might be -- registered using `atexit'. This provides a mean for the -- dynamic linker to call DT_FINI functions for shared libraries -- that have been loaded before the code runs. -- -- A value of 0 tells we have no such handler. */ -- regs->edx = 0; --} --#endif -- --#define USE_ELF_CORE_DUMP --#define ELF_EXEC_PAGESIZE 4096 -- --#endif -- --#ifdef TARGET_ARM -- --#define ELF_START_MMAP 0x80000000 -- --#define elf_check_arch(x) ( (x) == EM_ARM ) -- --#define ELF_CLASS ELFCLASS32 --#ifdef TARGET_WORDS_BIGENDIAN --#define ELF_DATA ELFDATA2MSB --#else --#define ELF_DATA ELFDATA2LSB --#endif --#define ELF_ARCH EM_ARM -- --static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) --{ -- abi_long stack = infop->start_stack; -- memset(regs, 0, sizeof(*regs)); -- regs->ARM_cpsr = 0x10; -- if (infop->entry & 1) -- regs->ARM_cpsr |= CPSR_T; -- regs->ARM_pc = infop->entry & 0xfffffffe; -- regs->ARM_sp = infop->start_stack; -- /* FIXME - what to for failure of get_user()? */ -- get_user_ual(regs->ARM_r2, stack + 8); /* envp */ -- get_user_ual(regs->ARM_r1, stack + 4); /* envp */ -- /* XXX: it seems that r0 is zeroed after ! */ -- regs->ARM_r0 = 0; -- /* For uClinux PIC binaries. */ -- /* XXX: Linux does this only on ARM with no MMU (do we care ?) */ -- regs->ARM_r10 = infop->start_data; --} -- --#define USE_ELF_CORE_DUMP --#define ELF_EXEC_PAGESIZE 4096 -- --enum --{ -- ARM_HWCAP_ARM_SWP = 1 << 0, -- ARM_HWCAP_ARM_HALF = 1 << 1, -- ARM_HWCAP_ARM_THUMB = 1 << 2, -- ARM_HWCAP_ARM_26BIT = 1 << 3, -- ARM_HWCAP_ARM_FAST_MULT = 1 << 4, -- ARM_HWCAP_ARM_FPA = 1 << 5, -- ARM_HWCAP_ARM_VFP = 1 << 6, -- ARM_HWCAP_ARM_EDSP = 1 << 7, --}; -- --#define ELF_HWCAP (ARM_HWCAP_ARM_SWP | ARM_HWCAP_ARM_HALF \ -- | ARM_HWCAP_ARM_THUMB | ARM_HWCAP_ARM_FAST_MULT \ -- | ARM_HWCAP_ARM_FPA | ARM_HWCAP_ARM_VFP) -- --#endif -- --#ifdef TARGET_SPARC --#ifdef TARGET_SPARC64 -- --#define ELF_START_MMAP 0x80000000 -- --#ifndef TARGET_ABI32 --#define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS ) --#else --#define elf_check_arch(x) ( (x) == EM_SPARC32PLUS || (x) == EM_SPARC ) --#endif -- --#define ELF_CLASS ELFCLASS64 --#define ELF_DATA ELFDATA2MSB --#define ELF_ARCH EM_SPARCV9 -- --#define STACK_BIAS 2047 -- --static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) --{ --#ifndef TARGET_ABI32 -- regs->tstate = 0; --#endif -- regs->pc = infop->entry; -- regs->npc = regs->pc + 4; -- regs->y = 0; --#ifdef TARGET_ABI32 -- regs->u_regs[14] = infop->start_stack - 16 * 4; --#else -- if (personality(infop->personality) == PER_LINUX32) -- regs->u_regs[14] = infop->start_stack - 16 * 4; -- else { -- regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS; -- if (bsd_type == target_freebsd) { -- regs->u_regs[8] = infop->start_stack; -- regs->u_regs[11] = infop->start_stack; -- } -- } --#endif --} -- --#else --#define ELF_START_MMAP 0x80000000 -- --#define elf_check_arch(x) ( (x) == EM_SPARC ) -- --#define ELF_CLASS ELFCLASS32 --#define ELF_DATA ELFDATA2MSB --#define ELF_ARCH EM_SPARC -- --static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) --{ -- regs->psr = 0; -- regs->pc = infop->entry; -- regs->npc = regs->pc + 4; -- regs->y = 0; -- regs->u_regs[14] = infop->start_stack - 16 * 4; --} -- --#endif --#endif -- --#ifdef TARGET_PPC -- --#define ELF_START_MMAP 0x80000000 -- --#if defined(TARGET_PPC64) && !defined(TARGET_ABI32) -- --#define elf_check_arch(x) ( (x) == EM_PPC64 ) -- --#define ELF_CLASS ELFCLASS64 -- --#else -- --#define elf_check_arch(x) ( (x) == EM_PPC ) -- --#define ELF_CLASS ELFCLASS32 -- --#endif -- --#ifdef TARGET_WORDS_BIGENDIAN --#define ELF_DATA ELFDATA2MSB --#else --#define ELF_DATA ELFDATA2LSB --#endif --#define ELF_ARCH EM_PPC -- --/* -- * We need to put in some extra aux table entries to tell glibc what -- * the cache block size is, so it can use the dcbz instruction safely. -- */ --#define AT_DCACHEBSIZE 19 --#define AT_ICACHEBSIZE 20 --#define AT_UCACHEBSIZE 21 --/* A special ignored type value for PPC, for glibc compatibility. */ --#define AT_IGNOREPPC 22 --/* -- * The requirements here are: -- * - keep the final alignment of sp (sp & 0xf) -- * - make sure the 32-bit value at the first 16 byte aligned position of -- * AUXV is greater than 16 for glibc compatibility. -- * AT_IGNOREPPC is used for that. -- * - for compatibility with glibc ARCH_DLINFO must always be defined on PPC, -- * even if DLINFO_ARCH_ITEMS goes to zero or is undefined. -- */ --#define DLINFO_ARCH_ITEMS 5 --#define ARCH_DLINFO \ --do { \ -- NEW_AUX_ENT(AT_DCACHEBSIZE, 0x20); \ -- NEW_AUX_ENT(AT_ICACHEBSIZE, 0x20); \ -- NEW_AUX_ENT(AT_UCACHEBSIZE, 0); \ -- /* \ -- * Now handle glibc compatibility. \ -- */ \ -- NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \ -- NEW_AUX_ENT(AT_IGNOREPPC, AT_IGNOREPPC); \ -- } while (0) -- --static inline void init_thread(struct target_pt_regs *_regs, struct image_info *infop) --{ -- abi_ulong pos = infop->start_stack; -- abi_ulong tmp; --#if defined(TARGET_PPC64) && !defined(TARGET_ABI32) -- abi_ulong entry, toc; --#endif -- -- _regs->gpr[1] = infop->start_stack; --#if defined(TARGET_PPC64) && !defined(TARGET_ABI32) -- entry = ldq_raw(infop->entry) + infop->load_addr; -- toc = ldq_raw(infop->entry + 8) + infop->load_addr; -- _regs->gpr[2] = toc; -- infop->entry = entry; --#endif -- _regs->nip = infop->entry; -- /* Note that isn't exactly what regular kernel does -- * but this is what the ABI wants and is needed to allow -- * execution of PPC BSD programs. -- */ -- /* FIXME - what to for failure of get_user()? */ -- get_user_ual(_regs->gpr[3], pos); -- pos += sizeof(abi_ulong); -- _regs->gpr[4] = pos; -- for (tmp = 1; tmp != 0; pos += sizeof(abi_ulong)) -- tmp = ldl(pos); -- _regs->gpr[5] = pos; --} -- --#define USE_ELF_CORE_DUMP --#define ELF_EXEC_PAGESIZE 4096 -- --#endif -- --#ifdef TARGET_MIPS -- --#define ELF_START_MMAP 0x80000000 -- --#define elf_check_arch(x) ( (x) == EM_MIPS ) -- --#ifdef TARGET_MIPS64 --#define ELF_CLASS ELFCLASS64 --#else --#define ELF_CLASS ELFCLASS32 --#endif --#ifdef TARGET_WORDS_BIGENDIAN --#define ELF_DATA ELFDATA2MSB --#else --#define ELF_DATA ELFDATA2LSB --#endif --#define ELF_ARCH EM_MIPS -- --static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) --{ -- regs->cp0_status = 2 << CP0St_KSU; -- regs->cp0_epc = infop->entry; -- regs->regs[29] = infop->start_stack; --} -- --#define USE_ELF_CORE_DUMP --#define ELF_EXEC_PAGESIZE 4096 -- --#endif /* TARGET_MIPS */ -- --#ifdef TARGET_SH4 -- --#define ELF_START_MMAP 0x80000000 -- --#define elf_check_arch(x) ( (x) == EM_SH ) -- --#define ELF_CLASS ELFCLASS32 --#define ELF_DATA ELFDATA2LSB --#define ELF_ARCH EM_SH -- --static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) --{ -- /* Check other registers XXXXX */ -- regs->pc = infop->entry; -- regs->regs[15] = infop->start_stack; --} -- --#define USE_ELF_CORE_DUMP --#define ELF_EXEC_PAGESIZE 4096 -- --#endif -- --#ifdef TARGET_CRIS -- --#define ELF_START_MMAP 0x80000000 -- --#define elf_check_arch(x) ( (x) == EM_CRIS ) -- --#define ELF_CLASS ELFCLASS32 --#define ELF_DATA ELFDATA2LSB --#define ELF_ARCH EM_CRIS -- --static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) --{ -- regs->erp = infop->entry; --} -- --#define USE_ELF_CORE_DUMP --#define ELF_EXEC_PAGESIZE 8192 -- --#endif -- --#ifdef TARGET_M68K -- --#define ELF_START_MMAP 0x80000000 -- --#define elf_check_arch(x) ( (x) == EM_68K ) -- --#define ELF_CLASS ELFCLASS32 --#define ELF_DATA ELFDATA2MSB --#define ELF_ARCH EM_68K -- --/* ??? Does this need to do anything? --#define ELF_PLAT_INIT(_r) */ -- --static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) --{ -- regs->usp = infop->start_stack; -- regs->sr = 0; -- regs->pc = infop->entry; --} -- --#define USE_ELF_CORE_DUMP --#define ELF_EXEC_PAGESIZE 8192 -- --#endif -- --#ifdef TARGET_ALPHA -- --#define ELF_START_MMAP (0x30000000000ULL) -- --#define elf_check_arch(x) ( (x) == ELF_ARCH ) -- --#define ELF_CLASS ELFCLASS64 --#define ELF_DATA ELFDATA2MSB --#define ELF_ARCH EM_ALPHA -- --static inline void init_thread(struct target_pt_regs *regs, struct image_info *infop) --{ -- regs->pc = infop->entry; -- regs->ps = 8; -- regs->usp = infop->start_stack; -- regs->unique = infop->start_data; /* ? */ -- printf("Set unique value to " TARGET_FMT_lx " (" TARGET_FMT_lx ")\n", -- regs->unique, infop->start_data); --} -- --#define USE_ELF_CORE_DUMP --#define ELF_EXEC_PAGESIZE 8192 -- --#endif /* TARGET_ALPHA */ -- --#ifndef ELF_PLATFORM --#define ELF_PLATFORM (NULL) --#endif -- --#ifndef ELF_HWCAP --#define ELF_HWCAP 0 --#endif -- --#ifdef TARGET_ABI32 --#undef ELF_CLASS --#define ELF_CLASS ELFCLASS32 --#undef bswaptls --#define bswaptls(ptr) bswap32s(ptr) --#endif -- --#include "elf.h" -- --struct exec --{ -- unsigned int a_info; /* Use macros N_MAGIC, etc for access */ -- unsigned int a_text; /* length of text, in bytes */ -- unsigned int a_data; /* length of data, in bytes */ -- unsigned int a_bss; /* length of uninitialized data area, in bytes */ -- unsigned int a_syms; /* length of symbol table data in file, in bytes */ -- unsigned int a_entry; /* start address */ -- unsigned int a_trsize; /* length of relocation info for text, in bytes */ -- unsigned int a_drsize; /* length of relocation info for data, in bytes */ --}; -- -- --#define N_MAGIC(exec) ((exec).a_info & 0xffff) --#define OMAGIC 0407 --#define NMAGIC 0410 --#define ZMAGIC 0413 --#define QMAGIC 0314 -- --/* max code+data+bss space allocated to elf interpreter */ --#define INTERP_MAP_SIZE (32 * 1024 * 1024) -- --/* max code+data+bss+brk space allocated to ET_DYN executables */ --#define ET_DYN_MAP_SIZE (128 * 1024 * 1024) -- --/* Necessary parameters */ --#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE --#define TARGET_ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1)) --#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1)) -- --#define INTERPRETER_NONE 0 --#define INTERPRETER_AOUT 1 --#define INTERPRETER_ELF 2 -- --#define DLINFO_ITEMS 12 -+abi_ulong target_stksiz; -+abi_ulong target_stkbas; - - static inline void memcpy_fromfs(void * to, const void * from, unsigned long n) - { -@@ -560,7 +44,7 @@ static int load_aout_interp(void * exptr, int interp_fd); - #ifdef BSWAP_NEEDED - static void bswap_ehdr(struct elfhdr *ehdr) - { -- bswap16s(&ehdr->e_type); /* Object file type */ -+ bswap16s(&ehdr->e_type); /* Object file type */ - bswap16s(&ehdr->e_machine); /* Architecture */ - bswap32s(&ehdr->e_version); /* Object file version */ - bswaptls(&ehdr->e_entry); /* Entry point virtual address */ -@@ -568,37 +52,45 @@ static void bswap_ehdr(struct elfhdr *ehdr) - bswaptls(&ehdr->e_shoff); /* Section header table file offset */ - bswap32s(&ehdr->e_flags); /* Processor-specific flags */ - bswap16s(&ehdr->e_ehsize); /* ELF header size in bytes */ -- bswap16s(&ehdr->e_phentsize); /* Program header table entry size */ -+ bswap16s(&ehdr->e_phentsize); /* Program header table entry size */ - bswap16s(&ehdr->e_phnum); /* Program header table entry count */ -- bswap16s(&ehdr->e_shentsize); /* Section header table entry size */ -+ bswap16s(&ehdr->e_shentsize); /* Section header table entry size */ - bswap16s(&ehdr->e_shnum); /* Section header table entry count */ -- bswap16s(&ehdr->e_shstrndx); /* Section header string table index */ -+ bswap16s(&ehdr->e_shstrndx); /* Section header string table index */ - } - --static void bswap_phdr(struct elf_phdr *phdr) -+static void bswap_phdr(struct elf_phdr *phdr, int phnum) - { -- bswap32s(&phdr->p_type); /* Segment type */ -- bswaptls(&phdr->p_offset); /* Segment file offset */ -- bswaptls(&phdr->p_vaddr); /* Segment virtual address */ -- bswaptls(&phdr->p_paddr); /* Segment physical address */ -- bswaptls(&phdr->p_filesz); /* Segment size in file */ -- bswaptls(&phdr->p_memsz); /* Segment size in memory */ -- bswap32s(&phdr->p_flags); /* Segment flags */ -- bswaptls(&phdr->p_align); /* Segment alignment */ -+ int i; -+ -+ for (i = 0; i < phnum; i++, phdr++) { -+ bswap32s(&phdr->p_type); /* Segment type */ -+ bswaptls(&phdr->p_offset); /* Segment file offset */ -+ bswaptls(&phdr->p_vaddr); /* Segment virtual address */ -+ bswaptls(&phdr->p_paddr); /* Segment physical address */ -+ bswaptls(&phdr->p_filesz); /* Segment size in file */ -+ bswaptls(&phdr->p_memsz); /* Segment size in memory */ -+ bswap32s(&phdr->p_flags); /* Segment flags */ -+ bswaptls(&phdr->p_align); /* Segment alignment */ -+ } - } - --static void bswap_shdr(struct elf_shdr *shdr) -+static void bswap_shdr(struct elf_shdr *shdr, int shnum) - { -- bswap32s(&shdr->sh_name); -- bswap32s(&shdr->sh_type); -- bswaptls(&shdr->sh_flags); -- bswaptls(&shdr->sh_addr); -- bswaptls(&shdr->sh_offset); -- bswaptls(&shdr->sh_size); -- bswap32s(&shdr->sh_link); -- bswap32s(&shdr->sh_info); -- bswaptls(&shdr->sh_addralign); -- bswaptls(&shdr->sh_entsize); -+ int i; -+ -+ for (i = 0; i < shnum; i++, shdr++) { -+ bswap32s(&shdr->sh_name); -+ bswap32s(&shdr->sh_type); -+ bswaptls(&shdr->sh_flags); -+ bswaptls(&shdr->sh_addr); -+ bswaptls(&shdr->sh_offset); -+ bswaptls(&shdr->sh_size); -+ bswap32s(&shdr->sh_link); -+ bswap32s(&shdr->sh_info); -+ bswaptls(&shdr->sh_addralign); -+ bswaptls(&shdr->sh_entsize); -+ } - } - - static void bswap_sym(struct elf_sym *sym) -@@ -608,7 +100,15 @@ static void bswap_sym(struct elf_sym *sym) - bswaptls(&sym->st_size); - bswap16s(&sym->st_shndx); - } --#endif -+ -+#else /* ! BSWAP_NEEDED */ -+ -+static void bswap_ehdr(struct elfhdr *ehdr) { } -+static void bswap_phdr(struct elf_phdr *phdr, int phnum) { } -+static void bswap_shdr(struct elf_shdr *shdr, int shnum) { } -+static void bswap_sym(struct elf_sym *sym) { } -+ -+#endif /* ! BSWAP_NEEDED */ - - /* - * 'copy_elf_strings()' copies argument/envelope strings from user -@@ -665,42 +165,34 @@ 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; -- int i; -+ abi_ulong stack_base, size; -+ abi_long addr; - - /* 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; -- if (size < MAX_ARG_PAGES*TARGET_PAGE_SIZE) -- size = MAX_ARG_PAGES*TARGET_PAGE_SIZE; -- error = target_mmap(0, -- size + qemu_host_page_size, -- PROT_READ | PROT_WRITE, -- MAP_PRIVATE | MAP_ANON, -- -1, 0); -- if (error == -1) { -+ size = target_dflssiz; -+ stack_base = TARGET_USRSTACK - size; -+ addr = target_mmap(stack_base , size + qemu_host_page_size, -+ PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); -+ if (addr == -1) { - perror("stk mmap"); - exit(-1); - } - /* we reserve one extra page at the top of the stack as guard */ -- target_mprotect(error + size, qemu_host_page_size, PROT_NONE); -+ target_mprotect(addr + size, qemu_host_page_size, PROT_NONE); - -- stack_base = error + size - MAX_ARG_PAGES*TARGET_PAGE_SIZE; -- p += stack_base; -+ target_stksiz = size; -+ target_stkbas = addr; - -- for (i = 0 ; i < MAX_ARG_PAGES ; i++) { -- if (bprm->page[i]) { -- info->rss++; -- /* FIXME - check return value of memcpy_to_target() for failure */ -- memcpy_to_target(stack_base, bprm->page[i], TARGET_PAGE_SIZE); -- g_free(bprm->page[i]); -- } -- stack_base += TARGET_PAGE_SIZE; -+ if (setup_initial_stack(bprm, &p) != 0) { -+ perror("stk setup"); -+ exit(-1); - } -+ - return p; - } - -@@ -758,86 +250,6 @@ static void padzero(abi_ulong elf_bss, abi_ulong last_bss) - } - } - -- --static abi_ulong create_elf_tables(abi_ulong p, int argc, int envc, -- struct elfhdr * exec, -- abi_ulong load_addr, -- abi_ulong load_bias, -- abi_ulong interp_load_addr, int ibcs, -- struct image_info *info) --{ -- abi_ulong sp; -- int size; -- abi_ulong u_platform; -- const char *k_platform; -- const int n = sizeof(elf_addr_t); -- -- sp = p; -- u_platform = 0; -- k_platform = ELF_PLATFORM; -- if (k_platform) { -- size_t len = strlen(k_platform) + 1; -- sp -= (len + n - 1) & ~(n - 1); -- u_platform = sp; -- /* FIXME - check return value of memcpy_to_target() for failure */ -- memcpy_to_target(sp, k_platform, len); -- } -- /* -- * Force 16 byte _final_ alignment here for generality. -- */ -- sp = sp &~ (abi_ulong)15; -- size = (DLINFO_ITEMS + 1) * 2; -- if (k_platform) -- size += 2; --#ifdef DLINFO_ARCH_ITEMS -- size += DLINFO_ARCH_ITEMS * 2; --#endif -- size += envc + argc + 2; -- size += (!ibcs ? 3 : 1); /* argc itself */ -- size *= n; -- if (size & 15) -- sp -= 16 - (size & 15); -- -- /* This is correct because Linux defines -- * elf_addr_t as Elf32_Off / Elf64_Off -- */ --#define NEW_AUX_ENT(id, val) do { \ -- sp -= n; put_user_ual(val, sp); \ -- sp -= n; put_user_ual(id, sp); \ -- } while(0) -- -- NEW_AUX_ENT (AT_NULL, 0); -- -- /* There must be exactly DLINFO_ITEMS entries here. */ -- NEW_AUX_ENT(AT_PHDR, (abi_ulong)(load_addr + exec->e_phoff)); -- NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr))); -- NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum)); -- NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(TARGET_PAGE_SIZE)); -- NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_load_addr)); -- NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0); -- NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry); -- NEW_AUX_ENT(AT_UID, (abi_ulong) getuid()); -- NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid()); -- NEW_AUX_ENT(AT_GID, (abi_ulong) getgid()); -- NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid()); -- NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP); -- NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK)); -- if (k_platform) -- NEW_AUX_ENT(AT_PLATFORM, u_platform); --#ifdef ARCH_DLINFO -- /* -- * ARCH_DLINFO must come last so platform specific code can enforce -- * special alignment requirements on the AUXV if necessary (eg. PPC). -- */ -- ARCH_DLINFO; --#endif --#undef NEW_AUX_ENT -- -- sp = loader_build_argptr(envc, argc, sp, p, !ibcs); -- return sp; --} -- -- - static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex, - int interpreter_fd, - abi_ulong *interp_load_addr) -@@ -855,9 +267,7 @@ static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex, - last_bss = 0; - error = 0; - --#ifdef BSWAP_NEEDED - bswap_ehdr(interp_elf_ex); --#endif - /* First of all, some simple consistency checks */ - if ((interp_elf_ex->e_type != ET_EXEC && - interp_elf_ex->e_type != ET_DYN) || -@@ -898,12 +308,7 @@ static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex, - free (elf_phdata); - return retval; - } --#ifdef BSWAP_NEEDED -- eppnt = elf_phdata; -- for (i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) { -- bswap_phdr(eppnt); -- } --#endif -+ bswap_phdr(elf_phdata, interp_elf_ex->e_phnum); - - if (interp_elf_ex->e_type == ET_DYN) { - /* in order to avoid hardcoding the interpreter load -@@ -920,54 +325,57 @@ static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex, - } - - eppnt = elf_phdata; -- for(i=0; i<interp_elf_ex->e_phnum; i++, eppnt++) -- if (eppnt->p_type == PT_LOAD) { -- int elf_type = MAP_PRIVATE | MAP_DENYWRITE; -- int elf_prot = 0; -- abi_ulong vaddr = 0; -- abi_ulong k; -- -- if (eppnt->p_flags & PF_R) elf_prot = PROT_READ; -- if (eppnt->p_flags & PF_W) elf_prot |= PROT_WRITE; -- if (eppnt->p_flags & PF_X) elf_prot |= PROT_EXEC; -- if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) { -- elf_type |= MAP_FIXED; -- vaddr = eppnt->p_vaddr; -- } -- error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr), -- eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr), -- elf_prot, -- elf_type, -- interpreter_fd, -- eppnt->p_offset - TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr)); -- -- if (error == -1) { -- /* Real error */ -- close(interpreter_fd); -- free(elf_phdata); -- return ~((abi_ulong)0UL); -- } -- -- if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) { -- load_addr = error; -- load_addr_set = 1; -+ for (i = 0; i < interp_elf_ex->e_phnum; i++, eppnt++) -+ if (eppnt->p_type == PT_LOAD) { -+ int elf_type = MAP_PRIVATE | MAP_DENYWRITE; -+ int elf_prot = 0; -+ abi_ulong vaddr = 0; -+ abi_ulong k; -+ -+ if (eppnt->p_flags & PF_R) { -+ elf_prot = PROT_READ; -+ } -+ if (eppnt->p_flags & PF_W) { -+ elf_prot |= PROT_WRITE; -+ } -+ if (eppnt->p_flags & PF_X) { -+ elf_prot |= PROT_EXEC; -+ } -+ if (interp_elf_ex->e_type == ET_EXEC || load_addr_set) { -+ elf_type |= MAP_FIXED; -+ vaddr = eppnt->p_vaddr; -+ } -+ error = target_mmap(load_addr+TARGET_ELF_PAGESTART(vaddr), -+ eppnt->p_filesz + TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr), -+ elf_prot, elf_type, interpreter_fd, eppnt->p_offset - -+ TARGET_ELF_PAGEOFFSET(eppnt->p_vaddr)); -+ if (error == -1) { -+ /* Real error */ -+ close(interpreter_fd); -+ free(elf_phdata); -+ return ~((abi_ulong)0UL); -+ } -+ if (!load_addr_set && interp_elf_ex->e_type == ET_DYN) { -+ load_addr = error; -+ load_addr_set = 1; -+ } -+ /* -+ * Find the end of the file mapping for this phdr, and keep -+ * track of the largest address we see for this. -+ */ -+ k = load_addr + eppnt->p_vaddr + eppnt->p_filesz; -+ if (k > elf_bss) { -+ elf_bss = k; -+ } -+ /* -+ * Do the same thing for the memory mapping - between -+ * elf_bss and last_bss is the bss section. -+ */ -+ k = load_addr + eppnt->p_memsz + eppnt->p_vaddr; -+ if (k > last_bss) { -+ last_bss = k; -+ } - } -- -- /* -- * Find the end of the file mapping for this phdr, and keep -- * track of the largest address we see for this. -- */ -- k = load_addr + eppnt->p_vaddr + eppnt->p_filesz; -- if (k > elf_bss) elf_bss = k; -- -- /* -- * Do the same thing for the memory mapping - between -- * elf_bss and last_bss is the bss section. -- */ -- k = load_addr + eppnt->p_memsz + eppnt->p_vaddr; -- if (k > last_bss) last_bss = k; -- } -- - /* Now use mmap to map the library into memory. */ - - close(interpreter_fd); -@@ -979,7 +387,8 @@ static abi_ulong load_elf_interp(struct elfhdr * interp_elf_ex, - * bss page. - */ - padzero(elf_bss, last_bss); -- elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); /* What we have mapped so far */ -+ /* What we have mapped so far */ -+ elf_bss = TARGET_ELF_PAGESTART(elf_bss + qemu_host_page_size - 1); - - /* Map the last of the bss segment */ - if (last_bss > elf_bss) { -@@ -1048,9 +457,7 @@ static void load_symbols(struct elfhdr *hdr, int fd) - for (i = 0; i < hdr->e_shnum; i++) { - if (read(fd, &sechdr, sizeof(sechdr)) != sizeof(sechdr)) - return; --#ifdef BSWAP_NEEDED -- bswap_shdr(&sechdr); --#endif -+ bswap_shdr(&sechdr, 1); - if (sechdr.sh_type == SHT_SYMTAB) { - symtab = sechdr; - lseek(fd, hdr->e_shoff -@@ -1058,9 +465,7 @@ static void load_symbols(struct elfhdr *hdr, int fd) - if (read(fd, &strtab, sizeof(strtab)) - != sizeof(strtab)) - return; --#ifdef BSWAP_NEEDED -- bswap_shdr(&strtab); --#endif -+ bswap_shdr(&strtab, 1); - goto found; - } - } -@@ -1093,9 +498,7 @@ static void load_symbols(struct elfhdr *hdr, int fd) - - i = 0; - while (i < nsyms) { --#ifdef BSWAP_NEEDED - bswap_sym(syms + i); --#endif - // Throw away entries which we do not need. - if (syms[i].st_shndx == SHN_UNDEF || - syms[i].st_shndx >= SHN_LORESERVE || -@@ -1147,8 +550,32 @@ static void load_symbols(struct elfhdr *hdr, int fd) - syminfos = s; - } - --int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, -- struct image_info * info) -+/* Check the elf header and see if this a target elf binary. */ -+int is_target_elf_binary(int fd) -+{ -+ uint8_t buf[128]; -+ struct elfhdr elf_ex; -+ -+ if (lseek(fd, 0L, SEEK_SET) < 0) { -+ return 0; -+ } -+ if (read(fd, buf, sizeof(buf)) < 0) { -+ return 0; -+ } -+ -+ elf_ex = *((struct elfhdr *)buf); -+ bswap_ehdr(&elf_ex); -+ -+ if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) || -+ (!elf_check_arch(elf_ex.e_machine))) { -+ return 0; -+ } else { -+ return 1; -+ } -+} -+ -+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; -@@ -1166,20 +593,18 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - int retval; - char * elf_interpreter; - abi_ulong elf_entry, interp_load_addr = 0; -- int status; - abi_ulong start_code, end_code, start_data, end_data; - abi_ulong reloc_func_desc = 0; -+#ifdef LOW_ELF_STACK - abi_ulong elf_stack; -+#endif - char passed_fileno[6]; - - ibcs2_interpreter = 0; -- status = 0; - load_addr = 0; - load_bias = 0; - elf_ex = *((struct elfhdr *) bprm->buf); /* exec-header */ --#ifdef BSWAP_NEEDED - bswap_ehdr(&elf_ex); --#endif - - /* First of all, some simple consistency checks */ - if ((elf_ex.e_type != ET_EXEC && elf_ex.e_type != ET_DYN) || -@@ -1187,12 +612,14 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - return -ENOEXEC; - } - -+#ifndef __FreeBSD__ - bprm->p = copy_elf_strings(1, &bprm->filename, bprm->page, bprm->p); - bprm->p = copy_elf_strings(bprm->envc,bprm->envp,bprm->page,bprm->p); - bprm->p = copy_elf_strings(bprm->argc,bprm->argv,bprm->page,bprm->p); - if (!bprm->p) { - retval = -E2BIG; - } -+#endif /* ! __FreeBSD__ */ - - /* Now read in all of the header information */ - elf_phdata = (struct elf_phdr *)malloc(elf_ex.e_phentsize*elf_ex.e_phnum); -@@ -1213,19 +640,16 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - return -errno; - } - --#ifdef BSWAP_NEEDED -- elf_ppnt = elf_phdata; -- for (i=0; i<elf_ex.e_phnum; i++, elf_ppnt++) { -- bswap_phdr(elf_ppnt); -- } --#endif -+ bswap_phdr(elf_phdata, elf_ex.e_phnum); - elf_ppnt = elf_phdata; - - elf_bss = 0; - elf_brk = 0; - - -+#ifdef LOW_ELF_STACK - elf_stack = ~((abi_ulong)0UL); -+#endif - elf_interpreter = NULL; - start_code = ~((abi_ulong)0UL); - end_code = 0; -@@ -1233,7 +657,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - end_data = 0; - interp_ex.a_info = 0; - -- for(i=0;i < elf_ex.e_phnum; i++) { -+ for (i = 0; i < elf_ex.e_phnum; i++) { - if (elf_ppnt->p_type == PT_INTERP) { - if ( elf_interpreter != NULL ) - { -@@ -1271,9 +695,9 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - - /* JRP - Need to add X86 lib dir stuff here... */ - -- if (strcmp(elf_interpreter,"/usr/lib/libc.so.1") == 0 || -- strcmp(elf_interpreter,"/usr/lib/ld.so.1") == 0) { -- ibcs2_interpreter = 1; -+ if (strcmp(elf_interpreter, "/usr/lib/libc.so.1") == 0 || -+ strcmp(elf_interpreter, "/usr/lib/ld-elf.so.1") == 0) { -+ ibcs2_interpreter = 1; - } - - #if 0 -@@ -1403,7 +827,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - * address. - */ - -- for(i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) { -+ for (i = 0, elf_ppnt = elf_phdata; i < elf_ex.e_phnum; i++, elf_ppnt++) { - int elf_prot = 0; - int elf_flags = 0; - abi_ulong error; -@@ -1420,7 +844,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - } else if (elf_ex.e_type == ET_DYN) { - /* Try and get dynamic programs out of the way of the default mmap - base, as well as whatever program they might try to exec. This -- is because the brk will follow the loader, and is not movable. */ -+ is because the brk will follow the loader, and is not movable. */ - /* NOTE: for qemu, we do a big mmap to get enough space - without hardcoding any address */ - error = target_mmap(0, ET_DYN_MAP_SIZE, -@@ -1517,7 +941,7 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - #ifdef LOW_ELF_STACK - info->start_stack = bprm->p = elf_stack - 4; - #endif -- bprm->p = create_elf_tables(bprm->p, -+ bprm->p = target_create_elf_tables(bprm->p, - bprm->argc, - bprm->envc, - &elf_ex, -@@ -1533,19 +957,22 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - info->end_data = end_data; - info->start_stack = bprm->p; - -- /* Calling set_brk effectively mmaps the pages that we need for the bss and break -- sections */ -+ /* -+ * Calling set_brk effectively mmaps the pages that we need for the bss -+ * and break sections. -+ */ - set_brk(elf_bss, elf_brk); - - padzero(elf_bss, elf_brk); - - #if 0 -- printf("(start_brk) %x\n" , info->start_brk); -- printf("(end_code) %x\n" , info->end_code); -- printf("(start_code) %x\n" , info->start_code); -- printf("(end_data) %x\n" , info->end_data); -- printf("(start_stack) %x\n" , info->start_stack); -- printf("(brk) %x\n" , info->brk); -+ printf("(start_brk) 0x" TARGET_FMT_lx "\n" , info->start_brk); -+ printf("(end_code) 0x" TARGET_FMT_lx "\n" , info->end_code); -+ printf("(start_code) 0x" TARGET_FMT_lx "\n" , info->start_code); -+ printf("(start_data) 0x" TARGET_FMT_lx "\n" , info->start_data); -+ printf("(end_data) 0x" TARGET_FMT_lx "\n" , info->end_data); -+ printf("(start_stack) 0x" TARGET_FMT_lx "\n" , info->start_stack); -+ printf("(brk) 0x" TARGET_FMT_lx "\n" , info->brk); - #endif - - if ( info->personality == PER_SVR4 ) -@@ -1554,12 +981,21 @@ int load_elf_binary(struct linux_binprm * bprm, struct target_pt_regs * regs, - and some applications "depend" upon this behavior. - Since we do not have the power to recompile these, we - emulate the SVr4 behavior. Sigh. */ -- mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ | PROT_EXEC, -- MAP_FIXED | MAP_PRIVATE, -1, 0); -+ mapped_addr = target_mmap(0, qemu_host_page_size, PROT_READ | -+ PROT_EXEC, MAP_FIXED | MAP_PRIVATE, -1, 0); -+ if (mapped_addr == -1) { -+ return -1; -+ } - } - - info->entry = elf_entry; - -+#ifdef USE_ELF_CORE_DUMP -+ /* not yet */ -+ /* bprm->core_dump = &elf_core_dump; */ -+ bprm->core_dump = NULL; -+#endif -+ - return 0; - } - -@@ -1571,5 +1007,5 @@ static int load_aout_interp(void * exptr, int interp_fd) - - void do_init_thread(struct target_pt_regs *regs, struct image_info *infop) - { -- init_thread(regs, infop); -+ target_thread_init(regs, infop); - } -diff --git a/bsd-user/errno_defs.h b/bsd-user/errno_defs.h -index 1efa502..f01181d 100644 ---- a/bsd-user/errno_defs.h -+++ b/bsd-user/errno_defs.h -@@ -1,6 +1,3 @@ --/* $OpenBSD: errno.h,v 1.20 2007/09/03 14:37:52 millert Exp $ */ --/* $NetBSD: errno.h,v 1.10 1996/01/20 01:33:53 jtc Exp $ */ -- - /* - * Copyright (c) 1982, 1986, 1989, 1993 - * The Regents of the University of California. All rights reserved. -@@ -37,6 +34,9 @@ - * @(#)errno.h 8.5 (Berkeley) 1/21/94 - */ - -+#ifndef _ERRNO_DEFS_H_ -+#define _ERRNO_DEFS_H_ -+ - #define TARGET_EPERM 1 /* Operation not permitted */ - #define TARGET_ENOENT 2 /* No such file or directory */ - #define TARGET_ESRCH 3 /* No such process */ -@@ -147,3 +147,10 @@ - #define TARGET_EIDRM 89 /* Identifier removed */ - #define TARGET_ENOMSG 90 /* No message of desired type */ - #define TARGET_ELAST 90 /* Must be equal largest errno */ -+ -+/* Internal errors: */ -+#define TARGET_EJUSTRETURN 254 /* Just return without -+ modifing regs */ -+#define TARGET_ERESTART 255 /* Restart syscall */ -+ -+#endif /* ! _ERRNO_DEFS_H_ */ -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/os-extattr.c b/bsd-user/freebsd/os-extattr.c -new file mode 100644 -index 0000000..95e7b24 ---- /dev/null -+++ b/bsd-user/freebsd/os-extattr.c -@@ -0,0 +1,118 @@ -+/* -+ * FreeBSD extend attributes and ACL conversions -+ * -+ * 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> -+#ifndef _ACL_PRIVATE -+#define _ACL_PRIVATE -+#endif -+#include <sys/acl.h> -+ -+#include "qemu.h" -+#include "qemu-os.h" -+ -+/* -+ * FreeBSD ACL conversion. -+ */ -+abi_long t2h_freebsd_acl(struct acl *host_acl, abi_ulong target_addr) -+{ -+ uint32_t i; -+ struct target_freebsd_acl *target_acl; -+ -+ if (!lock_user_struct(VERIFY_READ, target_acl, target_addr, 1)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(host_acl->acl_maxcnt, &target_acl->acl_maxcnt); -+ __get_user(host_acl->acl_cnt, &target_acl->acl_cnt); -+ -+ for (i = 0; i < host_acl->acl_maxcnt; i++) { -+ __get_user(host_acl->acl_entry[i].ae_tag, -+ &target_acl->acl_entry[i].ae_tag); -+ __get_user(host_acl->acl_entry[i].ae_id, -+ &target_acl->acl_entry[i].ae_id); -+ __get_user(host_acl->acl_entry[i].ae_perm, -+ &target_acl->acl_entry[i].ae_perm); -+ __get_user(host_acl->acl_entry[i].ae_entry_type, -+ &target_acl->acl_entry[i].ae_entry_type); -+ __get_user(host_acl->acl_entry[i].ae_flags, -+ &target_acl->acl_entry[i].ae_flags); -+ } -+ -+ unlock_user_struct(target_acl, target_addr, 0); -+ return 0; -+} -+ -+abi_long h2t_freebsd_acl(abi_ulong target_addr, struct acl *host_acl) -+{ -+ uint32_t i; -+ struct target_freebsd_acl *target_acl; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_acl, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ -+ __put_user(host_acl->acl_maxcnt, &target_acl->acl_maxcnt); -+ __put_user(host_acl->acl_cnt, &target_acl->acl_cnt); -+ -+ for (i = 0; i < host_acl->acl_maxcnt; i++) { -+ __put_user(host_acl->acl_entry[i].ae_tag, -+ &target_acl->acl_entry[i].ae_tag); -+ __put_user(host_acl->acl_entry[i].ae_id, -+ &target_acl->acl_entry[i].ae_id); -+ __put_user(host_acl->acl_entry[i].ae_perm, -+ &target_acl->acl_entry[i].ae_perm); -+ __put_user(host_acl->acl_entry[i].ae_entry_type, -+ &target_acl->acl_entry[i].ae_entry_type); -+ __put_user(host_acl->acl_entry[i].ae_flags, -+ &target_acl->acl_entry[i].ae_flags); -+ } -+ -+ unlock_user_struct(target_acl, target_addr, 1); -+ return 0; -+} -+ -+abi_long t2h_freebsd_acl_type(acl_type_t *host_type, abi_long target_type) -+{ -+ -+ switch (target_type) { -+ case TARGET_FREEBSD_ACL_TYPE_ACCESS_OLD: -+ *host_type = ACL_TYPE_ACCESS_OLD; -+ break; -+ -+ case TARGET_FREEBSD_ACL_TYPE_DEFAULT_OLD: -+ *host_type = ACL_TYPE_DEFAULT_OLD; -+ break; -+ -+ case TARGET_FREEBSD_ACL_TYPE_ACCESS: -+ *host_type = ACL_TYPE_ACCESS; -+ break; -+ -+ case TARGET_FREEBSD_ACL_TYPE_DEFAULT: -+ *host_type = ACL_TYPE_ACCESS; -+ break; -+ -+ case TARGET_FREEBSD_ACL_TYPE_NFS4: -+ *host_type = ACL_TYPE_NFS4; -+ break; -+ -+ default: -+ return -TARGET_EINVAL; -+ } -+ return 0; -+} -+ -diff --git a/bsd-user/freebsd/os-extattr.h b/bsd-user/freebsd/os-extattr.h -new file mode 100644 -index 0000000..2e45f42 ---- /dev/null -+++ b/bsd-user/freebsd/os-extattr.h -@@ -0,0 +1,654 @@ -+/* -+ * FreeBSD extended attributes and ACL system call support -+ * -+ * 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/extattr.h> -+#ifndef _ACL_PRIVATE -+#define _ACL_PRIVATE -+#endif -+#include <sys/acl.h> -+ -+#include "qemu-os.h" -+ -+/* extattrctl() */ -+static inline abi_long do_freebsd_extattrctl(abi_ulong arg1, abi_ulong arg2, -+ abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ abi_long ret; -+ void *p, *a, *f; -+ -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ f = lock_user_string(arg3); -+ if (f == NULL) { -+ unlock_user(p, arg1, 0); -+ return -TARGET_EFAULT; -+ } -+ a = lock_user_string(arg5); -+ if (a == NULL) { -+ unlock_user(f, arg3, 0); -+ unlock_user(p, arg1, 0); -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(extattrctl(path(p), arg2, f, arg4, a)); -+ unlock_user(a, arg5, 0); -+ unlock_user(f, arg3, 0); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* extattr_set_file(2) */ -+static inline abi_long do_freebsd_extattr_set_file(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ abi_long ret; -+ void *p, *a, *d; -+ -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ a = lock_user_string(arg3); -+ if (a == NULL) { -+ unlock_user(p, arg1, 0); -+ return -TARGET_EFAULT; -+ } -+ d = lock_user(VERIFY_READ, arg4, arg5, 1); -+ if (d == NULL) { -+ unlock_user(a, arg3, 0); -+ unlock_user(p, arg1, 0); -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(extattr_set_file(path(p), arg2, a, d, arg5)); -+ unlock_user(d, arg4, arg5); -+ unlock_user(a, arg3, 0); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* extattr_get_file(2) */ -+static inline abi_long do_freebsd_extattr_get_file(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ abi_long ret; -+ void *p, *a, *d; -+ -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ a = lock_user_string(arg3); -+ if (a == NULL) { -+ unlock_user(p, arg1, 0); -+ return -TARGET_EFAULT; -+ } -+ if (arg4 && arg5 > 0) { -+ d = lock_user(VERIFY_WRITE, arg4, arg5, 0); -+ if (d == NULL) { -+ unlock_user(a, arg3, 0); -+ unlock_user(p, arg1, 0); -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(extattr_get_file(path(p), arg2, a, d, arg5)); -+ unlock_user(d, arg4, arg5); -+ } else { -+ ret = get_errno(extattr_get_file(path(p), arg2, a, NULL, arg5)); -+ } -+ unlock_user(a, arg3, 0); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* extattr_delete_file(2) */ -+static inline abi_long do_freebsd_extattr_delete_file(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3) -+{ -+ abi_long ret; -+ void *p, *a; -+ -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ a = lock_user_string(arg3); -+ if (a == NULL) { -+ unlock_user(p, arg1, 0); -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(extattr_delete_file(path(p), arg2, a)); -+ unlock_user(a, arg3, 0); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* extattr_set_fd(2) */ -+static inline abi_long do_freebsd_extattr_set_fd(abi_long arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ abi_long ret; -+ void *a, *d; -+ -+ a = lock_user_string(arg3); -+ if (a == NULL) { -+ return -TARGET_EFAULT; -+ } -+ d = lock_user(VERIFY_READ, arg4, arg5, 1); -+ if (d == NULL) { -+ unlock_user(a, arg3, 0); -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(extattr_set_fd(arg1, arg2, a, d, arg5)); -+ unlock_user(d, arg4, arg5); -+ unlock_user(a, arg3, 0); -+ -+ return ret; -+} -+ -+/* extattr_get_fd(2) */ -+static inline abi_long do_freebsd_extattr_get_fd(abi_long arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ abi_long ret; -+ void *a, *d; -+ -+ a = lock_user_string(arg3); -+ if (a == NULL) { -+ return -TARGET_EFAULT; -+ } -+ -+ if (arg4 && arg5 > 0) { -+ d = lock_user(VERIFY_WRITE, arg4, arg5, 0); -+ if (d == NULL) { -+ unlock_user(a, arg3, 0); -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(extattr_get_fd(arg1, arg2, a, d, arg5)); -+ unlock_user(d, arg4, arg5); -+ } else { -+ ret = get_errno(extattr_get_fd(arg1, arg2, a, NULL, arg5)); -+ } -+ unlock_user(a, arg3, 0); -+ -+ return ret; -+} -+ -+/* extattr_delete_fd(2) */ -+static inline abi_long do_freebsd_extattr_delete_fd(abi_long arg1, -+ abi_long arg2, abi_ulong arg3) -+{ -+ abi_long ret; -+ void *a; -+ -+ a = lock_user_string(arg3); -+ if (a == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(extattr_delete_fd(arg1, arg2, a)); -+ unlock_user(a, arg3, 0); -+ -+ return ret; -+} -+ -+/* extattr_get_link(2) */ -+static inline abi_long do_freebsd_extattr_get_link(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ abi_long ret; -+ void *p, *a, *d; -+ -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ a = lock_user_string(arg3); -+ if (a == NULL) { -+ unlock_user(p, arg1, 0); -+ return -TARGET_EFAULT; -+ } -+ if (arg4 && arg5 > 0) { -+ d = lock_user(VERIFY_WRITE, arg4, arg5, 0); -+ if (d == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(extattr_get_link(path(p), arg2, a, d, arg5)); -+ unlock_user(d, arg4, arg5); -+ } else { -+ ret = get_errno(extattr_get_link(path(p), arg2, a, NULL, arg5)); -+ } -+ unlock_user(a, arg3, 0); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* extattr_set_link(2) */ -+static inline abi_long do_freebsd_extattr_set_link(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ abi_long ret; -+ void *p, *a, *d; -+ -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ a = lock_user_string(arg3); -+ if (a == NULL) { -+ unlock_user(p, arg1, 0); -+ return -TARGET_EFAULT; -+ } -+ d = lock_user(VERIFY_READ, arg4, arg5, 1); -+ if (d == NULL) { -+ unlock_user(a, arg3, 0); -+ unlock_user(p, arg1, 0); -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(extattr_set_link(path(p), arg2, a, d, arg5)); -+ unlock_user(d, arg4, arg5); -+ unlock_user(a, arg3, 0); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* extattr_delete_link(2) */ -+static inline abi_long do_freebsd_extattr_delete_link(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3) -+{ -+ abi_long ret; -+ void *p, *a; -+ -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ a = lock_user_string(arg3); -+ if (a == NULL) { -+ unlock_user(p, arg1, 0); -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(extattr_delete_link(path(p), arg2, a)); -+ unlock_user(a, arg3, 0); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* extattr_list_fd(2) */ -+static inline abi_long do_freebsd_extattr_list_fd(abi_long arg1, abi_long arg2, -+ abi_ulong arg3, abi_ulong arg4) -+{ -+ abi_long ret; -+ void *d; -+ -+ if (arg3 && arg4 > 0) { -+ d = lock_user(VERIFY_WRITE, arg3, arg4, 0); -+ if (d == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(extattr_list_fd(arg1, arg2, d, arg4)); -+ unlock_user(d, arg3, arg4); -+ } else { -+ ret = get_errno(extattr_list_fd(arg1, arg2, NULL, arg4)); -+ } -+ return ret; -+} -+ -+/* extattr_list_file(2) */ -+static inline abi_long do_freebsd_extattr_list_file(abi_long arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4) -+{ -+ abi_long ret; -+ void *p, *d; -+ -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ if (arg3 && arg4 > 0) { -+ d = lock_user(VERIFY_WRITE, arg3, arg4, 0); -+ if (d == NULL) { -+ unlock_user(p, arg1, 0); -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(extattr_list_file(path(p), arg2, d, arg4)); -+ unlock_user(d, arg3, arg4); -+ } else { -+ ret = get_errno(extattr_list_file(path(p), arg2, NULL, arg4)); -+ } -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* extattr_list_link(2) */ -+static inline abi_long do_freebsd_extattr_list_link(abi_long arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4) -+{ -+ abi_long ret; -+ void *p, *d; -+ -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ if (arg3 && arg4 > 0) { -+ d = lock_user(VERIFY_WRITE, arg3, arg4, 0); -+ if (d == NULL) { -+ unlock_user(p, arg1, 0); -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(extattr_list_link(path(p), arg2, d, arg4)); -+ unlock_user(d, arg3, arg4); -+ } else { -+ ret = get_errno(extattr_list_link(path(p), arg2, NULL, arg4)); -+ } -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* -+ * Access Control Lists -+ */ -+ -+/* __acl_aclcheck_fd(int filedes, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_aclcheck_fd(abi_long arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ abi_long ret; -+ struct acl host_acl; -+ acl_type_t type; -+ -+ ret = t2h_freebsd_acl_type(&type, arg2); -+ if (is_error(ret)) { -+ return ret; -+ } -+ ret = t2h_freebsd_acl(&host_acl, arg3); -+ if (!is_error(ret)) { -+ ret = get_errno(__acl_aclcheck_fd(arg1, type, &host_acl)); -+ } -+ -+ return ret; -+} -+ -+/* __acl_aclcheck_file(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_aclcheck_file(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3) -+{ -+ abi_long ret; -+ void *p; -+ struct acl host_acl; -+ acl_type_t type; -+ -+ ret = t2h_freebsd_acl_type(&type, arg2); -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = t2h_freebsd_acl(&host_acl, arg3); -+ if (!is_error(ret)) { -+ ret = get_errno(__acl_aclcheck_file(path(p) , arg2, &host_acl)); -+ } -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* __acl_aclcheck_link(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_aclcheck_link(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3) -+{ -+ abi_long ret; -+ void *p; -+ struct acl host_acl; -+ acl_type_t type; -+ -+ ret = t2h_freebsd_acl_type(&type, arg2); -+ if (is_error(ret)) { -+ return ret; -+ } -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = t2h_freebsd_acl(&host_acl, arg3); -+ if (!is_error(ret)) { -+ ret = get_errno(__acl_aclcheck_link(path(p), type, &host_acl)); -+ } -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* int __acl_delete_fd(int filedes, acl_type_t type); */ -+static inline abi_long do_freebsd__acl_delete_fd(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ acl_type_t type; -+ -+ ret = t2h_freebsd_acl_type(&type, arg2); -+ if (is_error(ret)) { -+ return ret; -+ } -+ return get_errno(__acl_delete_fd(arg1, type)); -+} -+ -+/* int __acl_delete_file(const char *path, acl_type_t type); */ -+static inline abi_long do_freebsd__acl_delete_file(abi_ulong arg1, -+ abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ acl_type_t type; -+ -+ ret = t2h_freebsd_acl_type(&type, arg2); -+ if (is_error(ret)) { -+ return ret; -+ } -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(__acl_delete_file(path(p), type)); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* int __acl_delete_link(const char *path, acl_type_t type); */ -+static inline abi_long do_freebsd__acl_delete_link(abi_ulong arg1, -+ abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ acl_type_t type; -+ -+ ret = t2h_freebsd_acl_type(&type, arg2); -+ if (is_error(ret)) { -+ return ret; -+ } -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(__acl_delete_link(path(p), type)); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* int __acl_get_fd(int filedes, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_get_fd(abi_long arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ abi_long ret; -+ acl_type_t type; -+ struct acl host_acl; -+ -+ bzero(&host_acl, sizeof(struct acl)); -+ host_acl.acl_maxcnt = ACL_MAX_ENTRIES; -+ -+ ret = t2h_freebsd_acl_type(&type, arg2); -+ if (is_error(ret)) { -+ return ret; -+ } -+ ret = get_errno(__acl_get_fd(arg1, type, &host_acl)); -+ if (!is_error(ret)) { -+ ret = h2t_freebsd_acl(arg3, &host_acl); -+ } -+ -+ return ret; -+} -+ -+/* __acl_get_file(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_get_file(abi_ulong arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ abi_long ret; -+ void *p; -+ acl_type_t type; -+ struct acl host_acl; -+ -+ bzero(&host_acl, sizeof(struct acl)); -+ host_acl.acl_maxcnt = ACL_MAX_ENTRIES; -+ -+ ret = t2h_freebsd_acl_type(&type, arg2); -+ if (is_error(ret)) { -+ return ret; -+ } -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(__acl_get_file(path(p), type, &host_acl)); -+ if (!is_error(ret)) { -+ ret = h2t_freebsd_acl(arg3, &host_acl); -+ } -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* int __acl_get_link(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_get_link(abi_ulong arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ abi_long ret; -+ void *p; -+ acl_type_t type; -+ struct acl host_acl; -+ -+ bzero(&host_acl, sizeof(struct acl)); -+ host_acl.acl_maxcnt = ACL_MAX_ENTRIES; -+ -+ ret = t2h_freebsd_acl_type(&type, arg2); -+ if (is_error(ret)) { -+ return ret; -+ } -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(__acl_get_link(path(p), type, &host_acl)); -+ if (!is_error(ret)) { -+ ret = h2t_freebsd_acl(arg3, &host_acl); -+ } -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* int __acl_set_fd(int filedes, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_set_fd(abi_long arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ abi_long ret; -+ acl_type_t type; -+ struct acl host_acl; -+ -+ ret = t2h_freebsd_acl_type(&type, arg2); -+ if (is_error(ret)) { -+ return ret; -+ } -+ ret = t2h_freebsd_acl(&host_acl, arg3); -+ if (!is_error(ret)) { -+ ret = get_errno(__acl_set_fd(arg1, type, &host_acl)); -+ } -+ -+ return ret; -+} -+ -+/* int __acl_set_file(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_set_file(abi_ulong arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ abi_long ret; -+ void *p; -+ acl_type_t type; -+ struct acl host_acl; -+ -+ ret = t2h_freebsd_acl_type(&type, arg2); -+ if (is_error(ret)) { -+ return ret; -+ } -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = t2h_freebsd_acl(&host_acl, arg3); -+ if (!is_error(ret)) { -+ ret = get_errno(__acl_set_file(path(p), type, &host_acl)); -+ } -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* int __acl_set_link(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_set_link(abi_ulong arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ abi_long ret; -+ void *p; -+ acl_type_t type; -+ struct acl host_acl; -+ -+ ret = t2h_freebsd_acl_type(&type, arg2); -+ if (is_error(ret)) { -+ return ret; -+ } -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = t2h_freebsd_acl(&host_acl, arg3); -+ if (!is_error(ret)) { -+ ret = get_errno(__acl_set_link(path(p), type, &host_acl)); -+ } -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -diff --git a/bsd-user/freebsd/os-ioctl-cmds.h b/bsd-user/freebsd/os-ioctl-cmds.h -new file mode 100644 -index 0000000..85d3c41 ---- /dev/null -+++ b/bsd-user/freebsd/os-ioctl-cmds.h -@@ -0,0 +1,49 @@ -+ -+/* sys/ttycom.h tty(4) */ -+IOCTL(TIOCSETD, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGETD, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSBRK, IOC_, TYPE_NULL) -+IOCTL(TIOCCBRK, IOC_, TYPE_NULL) -+IOCTL(TIOCSDTR, IOC_, TYPE_NULL) -+IOCTL(TIOCCDTR, IOC_, TYPE_NULL) -+IOCTL(TIOCGPGRP, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSPGRP, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGETA, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCSETA, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCSETAW, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCSETAF, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCPTMASTER, IOC_, TYPE_NULL) -+IOCTL(TIOCOUTQ, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSTI, IOC_W, MK_PTR(TYPE_CHAR)) -+IOCTL(TIOCNOTTY, IOC_, TYPE_NULL) -+IOCTL(TIOCSTOP, IOC_, TYPE_NULL) -+IOCTL(TIOCSTART, IOC_, TYPE_NULL) -+IOCTL(TIOCPKT, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSCTTY, IOC_, TYPE_NULL) -+IOCTL(TIOCDRAIN, IOC_, TYPE_NULL) -+IOCTL(TIOCEXCL, IOC_, TYPE_NULL) -+IOCTL(TIOCNXCL, IOC_, TYPE_NULL) -+IOCTL(TIOCFLUSH, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGWINSZ, IOC_R, MK_PTR(MK_STRUCT(STRUCT_winsize))) -+IOCTL(TIOCSWINSZ, IOC_W, MK_PTR(MK_STRUCT(STRUCT_winsize))) -+IOCTL(TIOCCONS, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMSET, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMGET, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMBIS, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMBIC, IOC_W, MK_PTR(TYPE_INT)) -+ -+/* sys/filio.h */ -+IOCTL(FIOCLEX, IOC_, TYPE_NULL) -+IOCTL(FIONCLEX, IOC_, TYPE_NULL) -+IOCTL(FIONREAD, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIONBIO, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(FIOASYNC, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(FIOSETOWN, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(FIOGETOWN, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIODTYPE, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIOGETLBA, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIODGNAME, IOC_W, MK_PTR(MK_STRUCT(STRUCT_fiodgname_arg))) -+IOCTL(FIONWRITE, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIONSPACE, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIOSEEKDATA, IOC_RW, MK_PTR(TYPE_ULONG)) -+IOCTL(FIOSEEKHOLE, IOC_RW, MK_PTR(TYPE_ULONG)) -diff --git a/bsd-user/freebsd/os-ioctl-filio.h b/bsd-user/freebsd/os-ioctl-filio.h -new file mode 100644 -index 0000000..7e1aae9 ---- /dev/null -+++ b/bsd-user/freebsd/os-ioctl-filio.h -@@ -0,0 +1,45 @@ -+/* -+ * FreeBSD filio definitions for ioctl(2) 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 _IOCTL_FILIO_H_ -+#define _IOCTL_FILIO_H_ -+ -+/* see sys/filio.h */ -+#define TARGET_FIOCLEX TARGET_IO('f', 1) -+#define TARGET_FIONCLEX TARGET_IO('f', 2) -+#define TARGET_FIONREAD TARGET_IOR('f', 127, int) -+#define TARGET_FIONBIO TARGET_IOW('f', 126, int) -+#define TARGET_FIOASYNC TARGET_IOW('f', 125, int) -+#define TARGET_FIOSETOWN TARGET_IOW('f', 124, int) -+#define TARGET_FIOGETOWN TARGET_IOR('f', 123, int) -+#define TARGET_FIODTYPE TARGET_IOR('f', 122, int) -+#define TARGET_FIOGETLBA TARGET_IOR('f', 121, int) -+ -+struct target_fiodgname_arg { -+ int32_t len; -+ abi_ulong buf; -+}; -+ -+#define TARGET_FIODGNAME TARGET_IOW('f', 120, \ -+ struct target_fiodgname_arg) -+#define TARGET_FIONWRITE TARGET_IOR('f', 119, int) -+#define TARGET_FIONSPACE TARGET_IOR('f', 118, int) -+#define TARGET_FIOSEEKDATA TARGET_IOWR('f', 97, off_t) -+#define TARGET_FIOSEEKHOLE TARGET_IOWR('f', 98, off_t) -+ -+#endif /* !_IOCTL_FILIO_H_ */ -diff --git a/bsd-user/freebsd/os-ioctl-ioccom.h b/bsd-user/freebsd/os-ioctl-ioccom.h -new file mode 100644 -index 0000000..fb9456f ---- /dev/null -+++ b/bsd-user/freebsd/os-ioctl-ioccom.h -@@ -0,0 +1,54 @@ -+/* -+ * FreeBSD ioccom definitions for ioctl(2) 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 _IOCTL_IOCCOM_H_ -+#define _IOCTL_IOCCOM_H_ -+/* -+ * Ioctl's have the command encoded in the lower word, and the size of -+ * any in or out parameters in the upper word. The high 3 bits of the -+ * upper word are used to encode the in/out status of the parameter. -+ */ -+/* number of bits for ioctl size */ -+#define TARGET_IOCPARM_SHIFT 13 -+ -+/* parameter length mask */ -+#define TARGET_IOCPARM_MASK ((1 << TARGET_IOCPARM_SHIFT) - 1) -+ -+#define TARGET_IOCPARM_LEN(x) (((x) >> 16) & TARGET_IOCPARM_MASK) -+#define TARGET_IOCBASECMD(x) ((x) & ~(TARGET_IOCPARM_MASK << 16)) -+#define TARGET_IOCGROUP(x) (((x) >> 8) & 0xff) -+ -+#define TARGET_IOCPARM_MAX (1 << TARGET_IOCPARM_SHIFT) /* max size of ioctl */ -+#define TARGET_IOC_VOID 0x20000000 /* no parameters */ -+#define TARGET_IOC_OUT 0x40000000 /* copy out parameters */ -+#define TARGET_IOC_IN 0x80000000 /* copy in parameters */ -+#define TARGET_IOC_INOUT (TARGET_IOC_IN|TARGET_IOC_OUT) -+#define TARGET_IOC_DIRMASK (TARGET_IOC_VOID|TARGET_IOC_OUT|TARGET_IOC_IN) -+ -+#define TARGET_IOC(inout, group, num, len) ((abi_ulong) \ -+ ((inout) | (((len) & TARGET_IOCPARM_MASK) << 16) | ((group) << 8) \ -+ | (num))) -+#define TARGET_IO(g, n) TARGET_IOC(IOC_VOID, (g), (n), 0) -+#define TARGET_IOWINT(g, n) TARGET_IOC(IOC_VOID, (g), (n), sizeof(int)) -+#define TARGET_IOR(g, n, t) TARGET_IOC(IOC_OUT, (g), (n), sizeof(t)) -+#define TARGET_IOW(g, n, t) TARGET_IOC(IOC_IN, (g), (n), sizeof(t)) -+/* this should be _IORW, but stdio got there first */ -+#define TARGET_IOWR(g, n, t) TARGET_IOC(IOC_INOUT, (g), (n), sizeof(t)) -+ -+#endif /* !_IOCTL_IOCCOM_H_ */ -diff --git a/bsd-user/freebsd/os-ioctl-ttycom.h b/bsd-user/freebsd/os-ioctl-ttycom.h -new file mode 100644 -index 0000000..b60db25 ---- /dev/null -+++ b/bsd-user/freebsd/os-ioctl-ttycom.h -@@ -0,0 +1,257 @@ -+/* -+ * FreeBSD ttycom definitions for ioctl(2) 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 _IOCTL_TTYCOM_H_ -+#define _IOCTL_TTYCOM_H_ -+ -+#include "os-ioctl-ioccom.h" -+ -+/* From sys/ttycom.h and sys/_termios.h */ -+ -+#define TARGET_VEOF 0 /* ICANON */ -+#define TARGET_VEOL 1 /* ICANON */ -+#define TARGET_VEOL2 2 /* ICANON together with IEXTEN */ -+#define TARGET_VERASE 3 /* ICANON */ -+#define TARGET_VWERASE 4 /* ICANON together with IEXTEN */ -+#define TARGET_VKILL 5 /* ICANON */ -+#define TARGET_VREPRINT 6 /* ICANON together with IEXTEN */ -+#define TARGET_VERASE2 7 /* ICANON */ -+#define TARGET_VINTR 8 /* ISIG */ -+#define TARGET_VQUIT 9 /* ISIG */ -+#define TARGET_VSUSP 10 /* ISIG */ -+#define TARGET_VDSUSP 11 /* ISIG together with IEXTEN */ -+#define TARGET_VSTART 12 /* IXON, IXOFF */ -+#define TARGET_VSTOP 13 /* IXON, IXOFF */ -+#define TARGET_VLNEXT 14 /* IEXTEN */ -+#define TARGET_VDISCARD 15 /* IEXTEN */ -+#define TARGET_VMIN 16 /* !ICANON */ -+#define TARGET_VTIME 17 /* !ICANON */ -+#define TARGET_VSTATUS 18 /* ICANON together with IEXTEN */ -+/* 19 spare 2 */ -+#define TARGET_NCCS 20 -+ -+/* -+ * Input flags - software input processing -+ */ -+#define TARGET_IGNBRK 0x00000001 /* ignore BREAK condition */ -+#define TARGET_BRKINT 0x00000002 /* map BREAK to SIGINTR */ -+#define TARGET_IGNPAR 0x00000004 /* ignore (discard) parity errors */ -+#define TARGET_PARMRK 0x00000008 /* mark parity and framing errors */ -+#define TARGET_INPCK 0x00000010 /* enable checking of parity errors */ -+#define TARGET_ISTRIP 0x00000020 /* strip 8th bit off chars */ -+#define TARGET_INLCR 0x00000040 /* map NL into CR */ -+#define TARGET_IGNCR 0x00000080 /* ignore CR */ -+#define TARGET_ICRNL 0x00000100 /* map CR to NL (ala CRMOD) */ -+#define TARGET_IXON 0x00000200 /* enable output flow control */ -+#define TARGET_IXOFF 0x00000400 /* enable input flow control */ -+#define TARGET_IXANY 0x00000800 /* any char will restart after stop */ -+#define TARGET_IMAXBEL 0x00002000 /* ring bell on input queue full */ -+ -+/* -+ * Output flags - software output processing -+ */ -+#define TARGET_OPOST 0x00000001 /* enable following output processing */ -+#define TARGET_ONLCR 0x00000002 /* map NL to CR-NL (ala CRMOD) */ -+#define TARGET_TABDLY 0x00000004 /* tab delay mask */ -+#define TARGET_TAB0 0x00000000 /* no tab delay and expansion */ -+#define TARGET_TAB3 0x00000004 /* expand tabs to spaces */ -+#define TARGET_ONOEOT 0x00000008 /* discard EOT's (^D) on output) */ -+#define TARGET_OCRNL 0x00000010 /* map CR to NL on output */ -+#define TARGET_ONOCR 0x00000020 /* no CR output at column 0 */ -+#define TARGET_ONLRET 0x00000040 /* NL performs CR function */ -+ -+/* -+ * Control flags - hardware control of terminal -+ */ -+#define TARGET_CIGNORE 0x00000001 /* ignore control flags */ -+#define TARGET_CSIZE 0x00000300 /* character size mask */ -+#define TARGET_CS5 0x00000000 /* 5 bits (pseudo) */ -+#define TARGET_CS6 0x00000100 /* 6 bits */ -+#define TARGET_CS7 0x00000200 /* 7 bits */ -+#define TARGET_CS8 0x00000300 /* 8 bits */ -+#define TARGET_CSTOPB 0x00000400 /* send 2 stop bits */ -+#define TARGET_CREAD 0x00000800 /* enable receiver */ -+#define TARGET_PARENB 0x00001000 /* parity enable */ -+#define TARGET_PARODD 0x00002000 /* odd parity, else even */ -+#define TARGET_HUPCL 0x00004000 /* hang up on last close */ -+#define TARGET_CLOCAL 0x00008000 /* ignore modem status lines */ -+#define TARGET_CCTS_OFLOW 0x00010000 /* CTS flow control of output */ -+#define TARGET_CRTSCTS (TARGET_CCTS_OFLOW | TARGET_CRTS_IFLOW) -+#define TARGET_CRTS_IFLOW 0x00020000 /* RTS flow control of input */ -+#define TARGET_CDTR_IFLOW 0x00040000 /* DTR flow control of input */ -+#define TARGET_CDSR_OFLOW 0x00080000 /* DSR flow control of output */ -+#define TARGET_CCAR_OFLOW 0x00100000 /* DCD flow control of output */ -+ -+/* -+ * "Local" flags - dumping ground for other state -+ */ -+#define TARGET_ECHOKE 0x00000001 /* visual erase for line kill */ -+#define TARGET_ECHOE 0x00000002 /* visually erase chars */ -+#define TARGET_ECHOK 0x00000004 /* echo NL after line kill */ -+#define TARGET_ECHO 0x00000008 /* enable echoing */ -+#define TARGET_ECHONL 0x00000010 /* echo NL even if ECHO is off */ -+#define TARGET_ECHOPRT 0x00000020 /* visual erase mode for hardcopy */ -+#define TARGET_ECHOCTL 0x00000040 /* echo control chars as ^(Char) */ -+#define TARGET_ISIG 0x00000080 /* enable signals INTR, QUIT, [D]SUSP */ -+#define TARGET_ICANON 0x00000100 /* canonicalize input lines */ -+#define TARGET_ALTWERASE 0x00000200 /* use alternate WERASE algorithm */ -+#define TARGET_IEXTEN 0x00000400 /* enable DISCARD and LNEXT */ -+#define TARGET_EXTPROC 0x00000800 /* external processing */ -+#define TARGET_TOSTOP 0x00400000 /* stop background jobs from output */ -+#define TARGET_FLUSHO 0x00800000 /* output being flushed (state) */ -+#define TARGET_NOKERNINFO 0x02000000 /* no kernel output from VSTATUS */ -+#define TARGET_PENDIN 0x20000000 /* XXX retype pending input (state) */ -+#define TARGET_NOFLSH 0x80000000 /* don't flush after interrupt */ -+ -+struct target_termios { -+ uint32_t c_iflag; /* input flags */ -+ uint32_t c_oflag; /* output flags */ -+ uint32_t c_cflag; /* control flags */ -+ uint32_t c_lflag; /* local flags */ -+ uint8_t c_cc[TARGET_NCCS]; /* control chars */ -+ uint32_t c_ispeed; /* input speed */ -+ uint32_t c_ospeed; /* output speed */ -+}; -+ -+ -+struct target_winsize { -+ uint16_t ws_row; /* rows, in characters */ -+ uint16_t ws_col; /* columns, in characters */ -+ uint16_t ws_xpixel; /* horizontal size, pixels */ -+ uint16_t ws_ypixel; /* vertical size, pixels */ -+}; -+ -+ /* 0-2 compat */ -+ /* 3-7 unused */ -+ /* 8-10 compat */ -+ /* 11-12 unused */ -+#define TARGET_TIOCEXCL TARGET_IO('t', 13) /* set exclusive use of tty */ -+#define TARGET_TIOCNXCL TARGET_IO('t', 14) /* reset exclusive use of tty */ -+#define TARGET_TIOCGPTN TARGET_IOR('t', 15, int) /* Get pts number. */ -+#define TARGET_TIOCFLUSH TARGET_IOW('t', 16, int) /* flush buffers */ -+ /* 17-18 compat */ -+/* get termios struct */ -+#define TARGET_TIOCGETA TARGET_IOR('t', 19, struct target_termios) -+/* set termios struct */ -+#define TARGET_TIOCSETA TARGET_IOW('t', 20, struct target_termios) -+/* drain output, set */ -+#define TARGET_TIOCSETAW TARGET_IOW('t', 21, struct target_termios) -+/* drn out, fls in, set */ -+#define TARGET_TIOCSETAF TARGET_IOW('t', 22, struct target_termios) -+ /* 23-25 unused */ -+#define TARGET_TIOCGETD TARGET_IOR('t', 26, int) /* get line discipline */ -+#define TARGET_TIOCSETD TARGET_IOW('t', 27, int) /* set line discipline */ -+#define TARGET_TIOCPTMASTER TARGET_IO('t', 28) /* pts master validation */ -+ /* 29-85 unused */ -+/* get ttywait timeout */ -+#define TARGET_TIOCGDRAINWAIT TARGET_IOR('t', 86, int) -+/* set ttywait timeout */ -+#define TARGET_TIOCSDRAINWAIT TARGET_IOW('t', 87, int) -+ /* 88 unused */ -+ /* 89-91 conflicts: tun and tap */ -+/* enable/get timestamp of last input event */ -+#define TARGET_TIOCTIMESTAMP TARGET_IOR('t', 89, struct target_timeval) -+/* modem: get wait on close */ -+#define TARGET_TIOCMGDTRWAIT TARGET_IOR('t', 90, int) -+/* modem: set wait on close */ -+#define TARGET_TIOCMSDTRWAIT TARGET_IOW('t', 91, int) -+ /* 92-93 tun and tap */ -+ /* 94-97 conflicts: tun and tap */ -+/* wait till output drained */ -+#define TARGET_TIOCDRAIN TARGET_IO('t', 94) -+ /* pty: generate signal */ -+#define TARGET_TIOCSIG TARGET_IOWINT('t', 95) -+/* pty: external processing */ -+#define TARGET_TIOCEXT TARGET_IOW('t', 96, int) -+/* become controlling tty */ -+#define TARGET_TIOCSCTTY TARGET_IO('t', 97) -+/* become virtual console */ -+#define TARGET_TIOCCONS TARGET_IOW('t', 98, int) -+/* get session id */ -+#define TARGET_TIOCGSID TARGET_IOR('t', 99, int) -+ /* 100 unused */ -+/* simulate ^T status message */ -+#define TARGET_TIOCSTAT TARGET_IO('t', 101) -+ /* pty: set/clr usr cntl mode */ -+#define TARGET_TIOCUCNTL TARGET_IOW('t', 102, int) -+/* usr cntl op "n" */ -+#define TARGET_TIOCCMD(n) TARGET_IO('u', n) -+/* set window size */ -+#define TARGET_TIOCSWINSZ TARGET_IOW('t', 103, struct target_winsize) -+/* get window size */ -+#define TARGET_TIOCGWINSZ TARGET_IOR('t', 104, struct target_winsize) -+ /* 105 unused */ -+/* get all modem bits */ -+#define TARGET_TIOCMGET TARGET_IOR('t', 106, int) -+#define TARGET_TIOCM_LE 0001 /* line enable */ -+#define TARGET_TIOCM_DTR 0002 /* data terminal ready */ -+#define TARGET_TIOCM_RTS 0004 /* request to send */ -+#define TARGET_TIOCM_ST 0010 /* secondary transmit */ -+#define TARGET_TIOCM_SR 0020 /* secondary receive */ -+#define TARGET_TIOCM_CTS 0040 /* clear to send */ -+#define TARGET_TIOCM_DCD 0100 /* data carrier detect */ -+#define TARGET_TIOCM_RI 0200 /* ring indicate */ -+#define TARGET_TIOCM_DSR 0400 /* data set ready */ -+#define TARGET_TIOCM_CD TARGET_TIOCM_DCD -+#define TARGET_TIOCM_CAR TARGET_TIOCM_DCD -+#define TARGET_TIOCM_RNG TARGET_TIOCM_RI -+#define TARGET_TIOCMBIC TARGET_IOW('t', 107, int) /* bic modem bits */ -+#define TARGET_TIOCMBIS TARGET_IOW('t', 108, int) /* bis modem bits */ -+#define TARGET_TIOCMSET TARGET_IOW('t', 109, int) /* set all modem bits */ -+/* start output, like ^Q */ -+#define TARGET_TIOCSTART TARGET_IO('t', 110) -+/* stop output, like ^S */ -+#define TARGET_TIOCSTOP TARGET_IO('t', 111) -+/* pty: set/clear packet mode */ -+#define TARGET_TIOCPKT TARGET_IOW('t', 112, int) -+#define TARGET_TIOCPKT_DATA 0x00 /* data packet */ -+#define TARGET_TIOCPKT_FLUSHREAD 0x01 /* flush packet */ -+#define TARGET_TIOCPKT_FLUSHWRITE 0x02 /* flush packet */ -+#define TARGET_TIOCPKT_STOP 0x04 /* stop output */ -+#define TARGET_TIOCPKT_START 0x08 /* start output */ -+#define TARGET_TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */ -+#define TARGET_TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */ -+#define TARGET_TIOCPKT_IOCTL 0x40 /* state change of pty -+ driver */ -+#define TARGET_TIOCNOTTY TARGET_IO('t', 113) /* void tty -+ association */ -+#define TARGET_TIOCSTI TARGET_IOW('t', 114, char) /* simulate -+ terminal input */ -+#define TARGET_TIOCOUTQ TARGET_IOR('t', 115, int) /* output queue size */ -+ /* 116-117 compat */ -+#define TARGET_TIOCSPGRP TARGET_IOW('t', 118, int) /* set pgrp of tty */ -+#define TARGET_TIOCGPGRP TARGET_IOR('t', 119, int) /* get pgrp of tty */ -+#define TARGET_TIOCCDTR TARGET_IO('t', 120) /* clear data terminal -+ ready */ -+#define TARGET_TIOCSDTR TARGET_IO('t', 121) /* set data terminal -+ ready */ -+#define TARGET_TIOCCBRK TARGET_IO('t', 122) /* clear break bit */ -+#define TARGET_TIOCSBRK TARGET_IO('t', 123) /* set break bit */ -+ /* 124-127 compat */ -+ -+#define TARGET_TTYDISC 0 /* termios tty line -+ discipline */ -+#define TARGET_SLIPDISC 4 /* serial IP discipline */ -+#define TARGET_PPPDISC 5 /* PPP discipline */ -+#define TARGET_NETGRAPHDISC 6 /* Netgraph tty node -+ discipline */ -+#define TARGET_H4DISC 7 /* Netgraph Bluetooth H4 -+ discipline */ -+ -+#endif /*! _IOCTL_TTYCOM_H_ */ -diff --git a/bsd-user/freebsd/os-ioctl-types.h b/bsd-user/freebsd/os-ioctl-types.h -new file mode 100644 -index 0000000..60b9288 ---- /dev/null -+++ b/bsd-user/freebsd/os-ioctl-types.h -@@ -0,0 +1,7 @@ -+ -+STRUCT_SPECIAL(termios) -+ -+STRUCT(winsize, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT) -+ -+STRUCT(fiodgname_arg, TYPE_INT, TYPE_PTRVOID) -+ -diff --git a/bsd-user/freebsd/os-misc.h b/bsd-user/freebsd/os-misc.h -new file mode 100644 -index 0000000..07e60fe ---- /dev/null -+++ b/bsd-user/freebsd/os-misc.h -@@ -0,0 +1,441 @@ -+/* -+ * miscellaneous FreeBSD system call shims -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+#ifndef __OS_MISC_H_ -+#define __OS_MISC_H_ -+ -+#include <sys/cpuset.h> -+#include <sched.h> -+ -+/* sched_setparam(2) */ -+static inline abi_long do_freebsd_sched_setparam(pid_t pid, -+ abi_ulong target_sp_addr) -+{ -+ abi_long ret; -+ struct sched_param host_sp; -+ -+ ret = get_user_s32(host_sp.sched_priority, target_sp_addr); -+ if (!is_error(ret)) { -+ ret = get_errno(sched_setparam(pid, &host_sp)); -+ } -+ return ret; -+} -+ -+/* sched_get_param(2) */ -+static inline abi_long do_freebsd_sched_getparam(pid_t pid, -+ abi_ulong target_sp_addr) -+{ -+ abi_long ret; -+ struct sched_param host_sp; -+ -+ ret = get_errno(sched_getparam(pid, &host_sp)); -+ if (!is_error(ret)) { -+ ret = put_user_s32(host_sp.sched_priority, target_sp_addr); -+ } -+ return ret; -+} -+ -+/* sched_setscheduler(2) */ -+static inline abi_long do_freebsd_sched_setscheduler(pid_t pid, int policy, -+ abi_ulong target_sp_addr) -+{ -+ abi_long ret; -+ struct sched_param host_sp; -+ -+ ret = get_user_s32(host_sp.sched_priority, target_sp_addr); -+ if (!is_error(ret)) { -+ ret = get_errno(sched_setscheduler(pid, policy, &host_sp)); -+ } -+ return ret; -+} -+ -+/* sched_getscheduler(2) */ -+static inline abi_long do_freebsd_sched_getscheduler(pid_t pid) -+{ -+ -+ return get_errno(sched_getscheduler(pid)); -+} -+ -+/* sched_getscheduler(2) */ -+static inline abi_long do_freebsd_sched_rr_get_interval(pid_t pid, -+ abi_ulong target_ts_addr) -+{ -+ abi_long ret; -+ struct timespec host_ts; -+ -+ ret = get_errno(sched_rr_get_interval(pid, &host_ts)); -+ if (!is_error(ret)) { -+ ret = h2t_freebsd_timespec(target_ts_addr, &host_ts); -+ } -+ return ret; -+} -+ -+/* cpuset(2) */ -+static inline abi_long do_freebsd_cpuset(abi_ulong target_cpuid) -+{ -+ abi_long ret; -+ cpusetid_t setid; -+ -+ ret = get_errno(cpuset(&setid)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ return put_user_s32(setid, target_cpuid); -+} -+ -+#define target_to_host_cpuset_which(hp, t) { \ -+ (*hp) = t; \ -+} while (0) -+ -+#define target_to_host_cpuset_level(hp, t) { \ -+ (*hp) = t; \ -+} while (0) -+ -+/* cpuset_setid(2) */ -+static inline abi_long do_freebsd_cpuset_setid(void *cpu_env, abi_long arg1, -+ abi_ulong arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ id_t id; /* 64-bit value */ -+ cpusetid_t setid; -+ cpuwhich_t which; -+ -+ target_to_host_cpuset_which(&which, arg1); -+#if TARGET_ABI_BITS == 32 -+ /* See if we need to align the register pairs */ -+ if (regpairs_aligned(cpu_env)) { -+ id = target_offset64(arg3, arg4); -+ setid = arg5; -+ } else { -+ id = target_offset64(arg2, arg3); -+ setid = arg4; -+ } -+#else -+ id = arg2; -+ setid = arg3; -+#endif -+ return get_errno(cpuset_setid(which, id, setid)); -+} -+ -+/* cpuset_getid(2) */ -+static inline abi_long do_freebsd_cpuset_getid(abi_long arg1, abi_ulong arg2, -+ abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ abi_long ret; -+ id_t id; /* 64-bit value */ -+ cpusetid_t setid; -+ cpuwhich_t which; -+ cpulevel_t level; -+ abi_ulong target_setid; -+ -+ target_to_host_cpuset_which(&which, arg1); -+ target_to_host_cpuset_level(&level, arg2); -+#if TARGET_ABI_BITS == 32 -+ id = target_offset64(arg3, arg4); -+ target_setid = arg5; -+#else -+ id = arg3; -+ target_setid = arg4; -+#endif -+ ret = get_errno(cpuset_getid(level, which, id, &setid)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ return put_user_s32(setid, target_setid); -+} -+ -+/* cpuset_getaffinity(2) */ -+static inline abi_long do_freebsd_cpuset_getaffinity(abi_long arg1, -+ abi_ulong arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5, -+ abi_ulong arg6) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cpuset_getaffinity()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cpuset_setaffinity(2) */ -+static inline abi_long do_freebsd_cpuset_setaffinity(abi_long arg1, -+ abi_ulong arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5, -+ abi_ulong arg6) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cpuset_setaffinity()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* modfnext(2) */ -+static inline abi_long do_freebsd_modfnext(abi_long modid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall modfnext()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* modfind(2) */ -+static inline abi_long do_freebsd_modfind(abi_ulong target_name) -+{ -+ -+ qemu_log("qemu: Unsupported syscall modfind()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldload(2) */ -+static inline abi_long do_freebsd_kldload(abi_ulong target_name) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldload()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldunload(2) */ -+static inline abi_long do_freebsd_kldunload(abi_long fileid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldunload()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldunloadf(2) */ -+static inline abi_long do_freebsd_kldunloadf(abi_long fileid, abi_long flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldunloadf()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldfind(2) */ -+static inline abi_long do_freebsd_kldfind(abi_ulong target_name) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldfind()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldnext(2) */ -+static inline abi_long do_freebsd_kldnext(abi_long fileid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldnext()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* kldstat(2) */ -+static inline abi_long do_freebsd_kldstat(abi_long fileid, -+ abi_ulong target_stat) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldstat()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldfirstmod(2) */ -+static inline abi_long do_freebsd_kldfirstmod(abi_long fileid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldfirstmod()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldsym(2) */ -+static inline abi_long do_freebsd_kldsym(abi_long fileid, abi_long cmd, -+ abi_ulong target_data) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldsym()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * Resource limits (undocumented except for rctl(8) and rctl.conf(5) ) -+ */ -+/* rctl_get_racct() */ -+static inline abi_long do_freebsd_rctl_get_racct(abi_ulong target_inbufp, -+ abi_ulong inbuflen, abi_ulong target_outbufp, abi_ulong outbuflen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rctl_get_racct()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* rctl_get_rules() */ -+static inline abi_long do_freebsd_rctl_get_rules(abi_ulong target_inbufp, -+ abi_ulong inbuflen, abi_ulong target_outbufp, abi_ulong outbuflen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rctl_get_rules()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* rctl_add_rule() */ -+static inline abi_long do_freebsd_rctl_add_rule(abi_ulong target_inbufp, -+ abi_ulong inbuflen, abi_ulong target_outbufp, abi_ulong outbuflen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rctl_add_rule()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* rctl_remove_rule() */ -+static inline abi_long do_freebsd_rctl_remove_rule(abi_ulong target_inbufp, -+ abi_ulong inbuflen, abi_ulong target_outbufp, abi_ulong outbuflen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rctl_remove_rule()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* rctl_get_limits() */ -+static inline abi_long do_freebsd_rctl_get_limits(abi_ulong target_inbufp, -+ abi_ulong inbuflen, abi_ulong target_outbufp, abi_ulong outbuflen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rctl_get_limits()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * Kernel environment -+ */ -+ -+/* kenv(2) */ -+static inline abi_long do_freebsd_kenv(abi_long what, abi_ulong target_name, -+ abi_ulong target_value, abi_long len) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kenv()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* -+ * Mandatory Access Control -+ */ -+ -+/* __mac_get_proc */ -+static inline abi_long do_freebsd___mac_get_proc(abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_get_proc()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_set_proc */ -+static inline abi_long do_freebsd___mac_set_proc(abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_set_proc()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* __mac_get_fd */ -+static inline abi_long do_freebsd___mac_get_fd(abi_long fd, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_get_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_set_fd */ -+static inline abi_long do_freebsd___mac_set_fd(abi_long fd, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_set_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_get_file */ -+static inline abi_long do_freebsd___mac_get_file(abi_ulong target_path, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_get_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_set_file */ -+static inline abi_long do_freebsd___mac_set_file(abi_ulong target_path, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_set_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_get_link */ -+static inline abi_long do_freebsd___mac_get_link(abi_ulong target_path, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_get_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_set_link */ -+static inline abi_long do_freebsd___mac_set_link(abi_ulong target_path, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_set_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* mac_syscall */ -+static inline abi_long do_freebsd_mac_syscall(abi_ulong target_policy, -+ abi_long call, abi_ulong target_arg) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_syscall()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* -+ * New posix calls -+ */ -+/* posix_fallocate(2) */ -+static inline abi_long do_freebsd_posix_fallocate(abi_long fd, abi_ulong offset, -+ abi_ulong len) -+{ -+ -+ qemu_log("qemu: Unsupported syscall posix_fallocate()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* posix_openpt(2) */ -+static inline abi_long do_freebsd_posix_openpt(abi_long flags) -+{ -+ -+ return get_errno(posix_openpt(flags)); -+} -+ -+/* posix_fadvise(2) */ -+static inline abi_long do_freebsd_posix_fadvise(abi_long fd, abi_ulong offset, -+ abi_ulong len, abi_long advise) -+{ -+ -+ qemu_log("qemu: Unsupported syscall posix_fadvise()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+#endif /* ! __OS_MISC_H_ */ -diff --git a/bsd-user/freebsd/os-proc.c b/bsd-user/freebsd/os-proc.c -new file mode 100644 -index 0000000..05df37f ---- /dev/null -+++ b/bsd-user/freebsd/os-proc.c -@@ -0,0 +1,309 @@ -+/* -+ * FreeBSD process related emulation code -+ * -+ * 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/queue.h> -+#include <sys/sysctl.h> -+#include <sys/unistd.h> -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 -+#include <libprocstat.h> -+#endif -+#include <string.h> -+ -+#include "qemu.h" -+ -+/* -+ * Get the filename for the given file descriptor. -+ * Note that this may return NULL (fail) if no longer cached in the kernel. -+ */ -+static char * -+get_filename_from_fd(pid_t pid, int fd, char *filename, size_t len) -+{ -+ char *ret = NULL; -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 -+ unsigned int cnt; -+ struct procstat *procstat = NULL; -+ struct kinfo_proc *kipp = NULL; -+ struct filestat_list *head = NULL; -+ struct filestat *fst; -+ -+ procstat = procstat_open_sysctl(); -+ if (NULL == procstat) { -+ goto out; -+ } -+ -+ kipp = procstat_getprocs(procstat, KERN_PROC_PID, pid, &cnt); -+ if (NULL == kipp) { -+ goto out; -+ } -+ -+ head = procstat_getfiles(procstat, kipp, 0); -+ if (NULL == head) { -+ goto out; -+ } -+ -+ STAILQ_FOREACH(fst, head, next) { -+ if (fd == fst->fs_fd) { -+ if (fst->fs_path != NULL) { -+ (void)strlcpy(filename, fst->fs_path, len); -+ ret = filename; -+ } -+ break; -+ } -+ } -+ -+out: -+ if (head != NULL) { -+ procstat_freefiles(procstat, head); -+ } -+ if (kipp != NULL) { -+ procstat_freeprocs(procstat, kipp); -+ } -+ if (procstat != NULL) { -+ procstat_close(procstat); -+ } -+#endif -+ return ret; -+} -+ -+static int -+is_target_shell_script(int fd, char *interp, size_t size) -+{ -+ char buf[2], *p, *b; -+ ssize_t n; -+ -+ if (fd < 0) { -+ return 0; -+ } -+ (void)lseek(fd, 0L, SEEK_SET); -+ if (read(fd, buf, 2) != 2) { -+ return 0; -+ } -+ if (buf[0] != '#' && buf[1] != '!') { -+ return 0; -+ } -+ if (size == 0) { -+ return 0; -+ } -+ b = interp; -+ /* Remove the trailing whitespace after "#!", if any. */ -+ while (size != 0) { -+ n = read(fd, b, 1); -+ if (n < 0 || n == 0) { -+ return 0; -+ } -+ if ((*b != ' ') && (*b != '\t')) { -+ b++; -+ size--; -+ break; -+ } -+ } -+ while (size != 0) { -+ n = read(fd, b, size); -+ if (n < 0 || n == 0) { -+ return 0; -+ } -+ if ((p = memchr(b, '\n', size)) != NULL) { -+ *p = 0; -+ return 1; -+ } -+ b += n; -+ size -= n; -+ } -+ -+ return 0; -+} -+ -+/* -+ * execve/fexecve -+ */ -+abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, -+ abi_ulong guest_envp, int do_fexec) -+{ -+ char **argp, **envp, **qargp, **qarg1, **qarg0; -+ int argc, envc; -+ abi_ulong gp; -+ abi_ulong addr; -+ char **q; -+ int total_size = 0; -+ void *p; -+ abi_long ret; -+ -+ argc = 0; -+ for (gp = guest_argp; gp; gp += sizeof(abi_ulong)) { -+ if (get_user_ual(addr, gp)) { -+ return -TARGET_EFAULT; -+ } -+ if (!addr) { -+ break; -+ } -+ argc++; -+ } -+ envc = 0; -+ for (gp = guest_envp; gp; gp += sizeof(abi_ulong)) { -+ if (get_user_ual(addr, gp)) { -+ return -TARGET_EFAULT; -+ } -+ if (!addr) { -+ break; -+ } -+ envc++; -+ } -+ -+ qarg0 = argp = alloca((argc + 4) * sizeof(void *)); -+ /* save the first agrument for the emulator */ -+ *argp++ = (char *)getprogname(); -+ qargp = argp; -+ *argp++ = (char *)getprogname(); -+ qarg1 = argp; -+ envp = alloca((envc + 1) * sizeof(void *)); -+ for (gp = guest_argp, q = argp; gp; gp += sizeof(abi_ulong), q++) { -+ if (get_user_ual(addr, gp)) { -+ ret = -TARGET_EFAULT; -+ goto execve_end; -+ } -+ if (!addr) { -+ break; -+ } -+ *q = lock_user_string(addr); -+ if (*q == NULL) { -+ ret = -TARGET_EFAULT; -+ goto execve_end; -+ } -+ total_size += strlen(*q) + 1; -+ } -+ *q = NULL; -+ -+ for (gp = guest_envp, q = envp; gp; gp += sizeof(abi_ulong), q++) { -+ if (get_user_ual(addr, gp)) { -+ ret = -TARGET_EFAULT; -+ goto execve_end; -+ } -+ if (!addr) { -+ break; -+ } -+ *q = lock_user_string(addr); -+ if (*q == NULL) { -+ ret = -TARGET_EFAULT; -+ goto execve_end; -+ } -+ total_size += strlen(*q) + 1; -+ } -+ *q = NULL; -+ -+ /* -+ * This case will not be caught by the host's execve() if its -+ * page size is bigger than the target's. -+ */ -+ if (total_size > MAX_ARG_PAGES * TARGET_PAGE_SIZE) { -+ ret = -TARGET_E2BIG; -+ goto execve_end; -+ } -+ -+ if (do_fexec) { -+ char execpath[PATH_MAX]; -+ -+ if (((int)path_or_fd > 0 && -+ is_target_elf_binary((int)path_or_fd)) == 1) { -+ char execpath[PATH_MAX]; -+ -+ /* -+ * The executable is an elf binary for the target -+ * arch. execve() it using the emulator if we can -+ * determine the filename path from the fd. -+ */ -+ if (get_filename_from_fd(getpid(), (int)path_or_fd, execpath, -+ sizeof(execpath)) != NULL) { -+ *qarg1 = execpath; -+ ret = get_errno(execve(qemu_proc_pathname, qargp, envp)); -+ } else { -+ /* Getting the filename path failed. */ -+ ret = -TARGET_EBADF; -+ goto execve_end; -+ } -+ } else if (is_target_shell_script((int)path_or_fd, execpath, -+ sizeof(execpath)) != 0) { -+ char scriptpath[PATH_MAX]; -+ -+ /* execve() as a target script using emulator. */ -+ if (get_filename_from_fd(getpid(), (int)path_or_fd, scriptpath, -+ sizeof(scriptpath)) != NULL) { -+ *qargp = execpath; -+ *qarg1 = scriptpath; -+ ret = get_errno(execve(qemu_proc_pathname, qarg0, envp)); -+ } else { -+ ret = -TARGET_EBADF; -+ goto execve_end; -+ } -+ } else { -+ ret = get_errno(fexecve((int)path_or_fd, argp, envp)); -+ } -+ } else { -+ int fd; -+ char execpath[PATH_MAX]; -+ -+ p = lock_user_string(path_or_fd); -+ if (p == NULL) { -+ ret = -TARGET_EFAULT; -+ goto execve_end; -+ } -+ -+ /* -+ * Check the header and see if it a target elf binary. If so -+ * then execute using qemu user mode emulator. -+ */ -+ fd = open(p, O_RDONLY | O_CLOEXEC); -+ if (fd > 0 && is_target_elf_binary(fd) == 1) { -+ close(fd); -+ /* execve() as a target binary using emulator. */ -+ *qarg1 = (char *)p; -+ ret = get_errno(execve(qemu_proc_pathname, qargp, envp)); -+ } else if (is_target_shell_script(fd, execpath, -+ sizeof(execpath)) != 0) { -+ close(fd); -+ /* execve() as a target script using emulator. */ -+ *qargp = execpath; -+ *qarg1 = (char *)p; -+ ret = get_errno(execve(qemu_proc_pathname, qarg0, envp)); -+ } else { -+ close(fd); -+ /* Execve() as a host native binary. */ -+ ret = get_errno(execve(p, argp, envp)); -+ } -+ unlock_user(p, path_or_fd, 0); -+ } -+ -+execve_end: -+ for (gp = guest_argp, q = argp; *q; gp += sizeof(abi_ulong), q++) { -+ if (get_user_ual(addr, gp) || !addr) { -+ break; -+ } -+ unlock_user(*q, addr, 0); -+ } -+ -+ for (gp = guest_envp, q = envp; *q; gp += sizeof(abi_ulong), q++) { -+ if (get_user_ual(addr, gp) || !addr) { -+ break; -+ } -+ unlock_user(*q, addr, 0); -+ } -+ return ret; -+} -+ -+ -diff --git a/bsd-user/freebsd/os-proc.h b/bsd-user/freebsd/os-proc.h -new file mode 100644 -index 0000000..b31f7c4 ---- /dev/null -+++ b/bsd-user/freebsd/os-proc.h -@@ -0,0 +1,428 @@ -+/* -+ * process related system call shims 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 __FREEBSD_PROC_H_ -+#define __FREEBSD_PROC_H_ -+ -+#include <sys/types.h> -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 -+#include <sys/procdesc.h> -+#endif -+#include <sys/wait.h> -+#include <unistd.h> -+ -+#include "target_arch_cpu.h" -+ -+extern int __setugid(int flag); -+extern int pdwait4(int fd, int *status, int options, struct rusage *rusage); -+ -+/* execve(2) */ -+static inline abi_long do_freebsd_execve(abi_ulong path_or_fd, abi_ulong argp, -+ abi_ulong envp) -+{ -+ -+ return freebsd_exec_common(path_or_fd, argp, envp, 0); -+} -+ -+/* fexecve(2) */ -+static inline abi_long do_freebsd_fexecve(abi_ulong path_or_fd, abi_ulong argp, -+ abi_ulong envp) -+{ -+ -+ return freebsd_exec_common(path_or_fd, argp, envp, 1); -+} -+ -+/* wait4(2) */ -+static inline abi_long do_freebsd_wait4(abi_long arg1, abi_ulong target_status, -+ abi_long arg3, abi_ulong target_rusage) -+{ -+ abi_long ret; -+ int status; -+ struct rusage rusage, *rusage_ptr = NULL; -+ -+ if (target_rusage) { -+ rusage_ptr = &rusage; -+ } -+ ret = get_errno(wait4(arg1, &status, arg3, rusage_ptr)); -+ if (!is_error(ret)) { -+ status = host_to_target_waitstatus(status); -+ if (put_user_s32(status, target_status) != 0) { -+ return -TARGET_EFAULT; -+ } -+ if (target_rusage != 0) { -+ host_to_target_rusage(target_rusage, &rusage); -+ } -+ } -+ return ret; -+} -+ -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 -+/* setloginclass(2) */ -+static inline abi_long do_freebsd_setloginclass(abi_ulong arg1) -+{ -+ abi_long ret; -+ void *p; -+ -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(setloginclass(p)); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* getloginclass(2) */ -+static inline abi_long do_freebsd_getloginclass(abi_ulong arg1, abi_ulong arg2) -+{ -+ abi_long ret; -+ void *p; -+ -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(getloginclass(p, arg2)); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* pdwait4(2) */ -+static inline abi_long do_freebsd_pdwait4(abi_long arg1, -+ abi_ulong target_status, abi_long arg3, abi_ulong target_rusage) -+{ -+ abi_long ret; -+ int status; -+ struct rusage rusage, *rusage_ptr = NULL; -+ -+ if (target_rusage) { -+ rusage_ptr = &rusage; -+ } -+ ret = get_errno(pdwait4(arg1, &status, arg3, rusage_ptr)); -+ if (!is_error(ret)) { -+ status = host_to_target_waitstatus(status); -+ if (put_user_s32(status, target_status) != 0) { -+ return -TARGET_EFAULT; -+ } -+ if (target_rusage != 0) { -+ host_to_target_rusage(target_rusage, &rusage); -+ } -+ } -+ return ret; -+} -+ -+/* pdgetpid(2) */ -+static inline abi_long do_freebsd_pdgetpid(abi_long fd, abi_ulong target_pidp) -+{ -+ abi_long ret; -+ pid_t pid; -+ -+ ret = get_errno(pdgetpid(fd, &pid)); -+ if (!is_error(ret)) { -+ if (put_user_u32(pid, target_pidp)) { -+ return -TARGET_EFAULT; -+ } -+ } -+ return ret; -+} -+ -+#else -+ -+/* setloginclass(2) */ -+static inline abi_long do_freebsd_setloginclass(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall setloginclass()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getloginclass(2) */ -+static inline abi_long do_freebsd_getloginclass(abi_ulong arg1, abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getloginclass()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* pdwait4(2) */ -+static inline abi_long do_freebsd_pdwait4(abi_long arg1, -+ abi_ulong target_status, abi_long arg3, abi_ulong target_rusage) -+{ -+ -+ qemu_log("qemu: Unsupported syscall pdwait4()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* pdgetpid(2) */ -+static inline abi_long do_freebsd_pdgetpid(abi_long fd, abi_ulong target_pidp) -+{ -+ -+ qemu_log("qemu: Unsupported syscall pdgetpid()\n"); -+ return -TARGET_ENOSYS; -+} -+#endif /* ! __FreeBSD_version > 900000 */ -+ -+/* undocumented __setugid */ -+static inline abi_long do_freebsd___setugid(abi_long arg1) -+{ -+ -+ return get_errno(__setugid(arg1)); -+} -+ -+/* fork(2) */ -+static inline abi_long do_freebsd_fork(void *cpu_env) -+{ -+ abi_long ret; -+ abi_ulong child_flag = 0; -+ -+ fork_start(); -+ ret = fork(); -+ if (ret == 0) { -+ /* child */ -+ child_flag = 1; -+ target_cpu_clone_regs(cpu_env, 0); -+ } else { -+ /* parent */ -+ fork_end(0); -+ } -+ -+ /* -+ * The fork system call sets a child flag in the second return -+ * value: 0 for parent process, 1 for child process. -+ */ -+ set_second_rval(cpu_env, child_flag); -+ -+ return ret; -+} -+ -+/* vfork(2) */ -+static inline abi_long do_freebsd_vfork(void *cpu_env) -+{ -+ -+ return do_freebsd_fork(cpu_env); -+} -+ -+/* rfork(2) */ -+static inline abi_long do_freebsd_rfork(void *cpu_env, abi_long flags) -+{ -+ abi_long ret; -+ abi_ulong child_flag = 0; -+ -+ fork_start(); -+ ret = rfork(flags); -+ if (ret == 0) { -+ /* child */ -+ child_flag = 1; -+ target_cpu_clone_regs(cpu_env, 0); -+ } else { -+ /* parent */ -+ fork_end(0); -+ } -+ -+ /* -+ * The fork system call sets a child flag in the second return -+ * value: 0 for parent process, 1 for child process. -+ */ -+ set_second_rval(cpu_env, child_flag); -+ -+ return ret; -+ -+} -+ -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 -+/* pdfork(2) */ -+static inline abi_long do_freebsd_pdfork(void *cpu_env, abi_ulong target_fdp, -+ abi_long flags) -+{ -+ abi_long ret; -+ abi_ulong child_flag = 0; -+ int fd; -+ -+ fork_start(); -+ ret = pdfork(&fd, flags); -+ if (ret == 0) { -+ /* child */ -+ child_flag = 1; -+ target_cpu_clone_regs(cpu_env, 0); -+ } else { -+ /* parent */ -+ fork_end(0); -+ } -+ if (put_user_s32(fd, target_fdp)) { -+ return -TARGET_EFAULT; -+ } -+ -+ /* -+ * The fork system call sets a child flag in the second return -+ * value: 0 for parent process, 1 for child process. -+ */ -+ set_second_rval(cpu_env, child_flag); -+ -+ return ret; -+} -+ -+#else -+ -+/* pdfork(2) */ -+static inline abi_long do_freebsd_pdfork(void *cpu_env, abi_ulong arg1, -+ abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall pdfork()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* __FreeBSD_version > 900000 */ -+ -+/* jail(2) */ -+static inline abi_long do_freebsd_jail(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall jail()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* jail_attach(2) */ -+static inline abi_long do_freebsd_jail_attach(abi_long arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall jail_attach()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* jail_remove(2) */ -+static inline abi_long do_freebsd_jail_remove(abi_long arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall jail_remove()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* jail_get(2) */ -+static inline abi_long do_freebsd_jail_get(abi_ulong arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall jail_get()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* jail_set(2) */ -+static inline abi_long do_freebsd_jail_set(abi_ulong arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall jail_set()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_enter(2) */ -+static inline abi_long do_freebsd_cap_enter(void) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_enter()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_new(2) */ -+static inline abi_long do_freebsd_cap_new(abi_long arg1, abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_new()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_getrights(2) */ -+static inline abi_long do_freebsd_cap_getrights(abi_long arg1, abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_getrights()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_getmode(2) */ -+static inline abi_long do_freebsd_cap_getmode(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_getmode()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* audit(2) */ -+static inline abi_long do_freebsd_audit(abi_ulong arg1, abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall audit()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* auditon(2) */ -+static inline abi_long do_freebsd_auditon(abi_long arg1, abi_ulong arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall auditon()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getaudit(2) */ -+static inline abi_long do_freebsd_getaudit(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getaudit()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* setaudit(2) */ -+static inline abi_long do_freebsd_setaudit(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall setaudit()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getaudit_addr(2) */ -+static inline abi_long do_freebsd_getaudit_addr(abi_ulong arg1, -+ abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getaudit_addr()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* setaudit_addr(2) */ -+static inline abi_long do_freebsd_setaudit_addr(abi_ulong arg1, -+ abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall setaudit_addr()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* auditctl(2) */ -+static inline abi_long do_freebsd_auditctl(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall auditctl()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* ! __FREEBSD_PROC_H_ */ -diff --git a/bsd-user/freebsd/os-signal.h b/bsd-user/freebsd/os-signal.h -new file mode 100644 -index 0000000..d4a26da ---- /dev/null -+++ b/bsd-user/freebsd/os-signal.h -@@ -0,0 +1,43 @@ -+/* -+ * FreeBSD signal system call shims -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef __FREEBSD_OS_SIGNAL_H_ -+#define __FREEBSD_OS_SIGNAL_H_ -+ -+#include <sys/procdesc.h> -+ -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 -+/* pdkill(2) */ -+static inline abi_long do_freebsd_pdkill(abi_long arg1, abi_long arg2) -+{ -+ -+ return get_errno(pdkill(arg1, arg2)); -+} -+ -+#else -+ -+static inline abi_long do_freebsd_pdkill(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall pdkill()\n"); -+ return -TARGET_ENOSYS; -+} -+#endif /* ! __FreeBSD_version > 900000 */ -+ -+#endif /* ! __FREEBSD_OS_SIGNAL_H_ */ -diff --git a/bsd-user/freebsd/os-socket.c b/bsd-user/freebsd/os-socket.c -new file mode 100644 -index 0000000..949af28 ---- /dev/null -+++ b/bsd-user/freebsd/os-socket.c -@@ -0,0 +1,149 @@ -+/* -+ * FreeBSD socket related system call helpers -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#include <sys/types.h> -+#include <sys/socket.h> -+#include <netinet/in.h> -+ -+#include "qemu.h" -+#include "qemu-os.h" -+ -+abi_long t2h_freebsd_cmsg(struct msghdr *msgh, -+ struct target_msghdr *target_msgh) -+{ -+ struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh); -+ abi_long msg_controllen; -+ abi_ulong target_cmsg_addr; -+ struct target_cmsghdr *target_cmsg; -+ socklen_t space = 0; -+ -+ -+ msg_controllen = tswapal(target_msgh->msg_controllen); -+ if (msg_controllen < sizeof(struct target_cmsghdr)) { -+ goto the_end; -+ } -+ target_cmsg_addr = tswapal(target_msgh->msg_control); -+ target_cmsg = lock_user(VERIFY_READ, target_cmsg_addr, msg_controllen, 1); -+ if (target_cmsg == 0) { -+ return -TARGET_EFAULT; -+ } -+ while (cmsg && target_cmsg) { -+ void *data = CMSG_DATA(cmsg); -+ void *target_data = TARGET_CMSG_DATA(target_cmsg); -+ int len = tswapal(target_cmsg->cmsg_len) - -+ TARGET_CMSG_ALIGN(sizeof(struct target_cmsghdr)); -+ space += CMSG_SPACE(len); -+ if (space > msgh->msg_controllen) { -+ space -= CMSG_SPACE(len); -+ gemu_log("Host cmsg overflow\n"); -+ break; -+ } -+ cmsg->cmsg_level = tswap32(target_cmsg->cmsg_level); -+ cmsg->cmsg_type = tswap32(target_cmsg->cmsg_type); -+ cmsg->cmsg_len = CMSG_LEN(len); -+ -+ if (cmsg->cmsg_level != TARGET_SOL_SOCKET || -+ cmsg->cmsg_type != SCM_RIGHTS) { -+ gemu_log("Unsupported ancillary data: %d/%d\n", -+ cmsg->cmsg_level, cmsg->cmsg_type); -+ memcpy(data, target_data, len); -+ } else { -+ int *fd = (int *)data; -+ int *target_fd = (int *)target_data; -+ int i, numfds = len / sizeof(int); -+ -+ for (i = 0; i < numfds; i++) { -+ fd[i] = tswap32(target_fd[i]); -+ } -+ } -+ cmsg = CMSG_NXTHDR(msgh, cmsg); -+ target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg); -+ } -+ unlock_user(target_cmsg, target_cmsg_addr, 0); -+ -+the_end: -+ msgh->msg_controllen = space; -+ return 0; -+} -+ -+abi_long h2t_freebsd_cmsg(struct target_msghdr *target_msgh, -+ struct msghdr *msgh) -+{ -+ struct cmsghdr *cmsg = CMSG_FIRSTHDR(msgh); -+ abi_long msg_controllen; -+ abi_ulong target_cmsg_addr; -+ struct target_cmsghdr *target_cmsg; -+ socklen_t space = 0; -+ -+ msg_controllen = tswapal(target_msgh->msg_controllen); -+ if (msg_controllen < sizeof(struct target_cmsghdr)) { -+ goto the_end; -+ } -+ target_cmsg_addr = tswapal(target_msgh->msg_control); -+ target_cmsg = lock_user(VERIFY_WRITE, target_cmsg_addr, -+ msg_controllen, 0); -+ if (target_cmsg == 0) { -+ return -TARGET_EFAULT; -+ } -+ while (cmsg && target_cmsg) { -+ void *data = CMSG_DATA(cmsg); -+ void *target_data = TARGET_CMSG_DATA(target_cmsg); -+ int len = cmsg->cmsg_len - CMSG_ALIGN(sizeof(struct cmsghdr)); -+ -+ space += TARGET_CMSG_SPACE(len); -+ if (space > msg_controllen) { -+ space -= TARGET_CMSG_SPACE(len); -+ gemu_log("Target cmsg overflow\n"); -+ break; -+ } -+ target_cmsg->cmsg_level = tswap32(cmsg->cmsg_level); -+ target_cmsg->cmsg_type = tswap32(cmsg->cmsg_type); -+ target_cmsg->cmsg_len = tswapal(TARGET_CMSG_LEN(len)); -+ if ((cmsg->cmsg_level == TARGET_SOL_SOCKET) && -+ (cmsg->cmsg_type == SCM_RIGHTS)) { -+ int *fd = (int *)data; -+ int *target_fd = (int *)target_data; -+ int i, numfds = len / sizeof(int); -+ for (i = 0; i < numfds; i++) { -+ target_fd[i] = tswap32(fd[i]); -+ } -+ } else if ((cmsg->cmsg_level == TARGET_SOL_SOCKET) && -+ (cmsg->cmsg_type == SO_TIMESTAMP) && -+ (len == sizeof(struct timeval))) { -+ /* copy struct timeval to target */ -+ struct timeval *tv = (struct timeval *)data; -+ struct target_freebsd_timeval *target_tv = -+ (struct target_freebsd_timeval *)target_data; -+ __put_user(tv->tv_sec, &target_tv->tv_sec); -+ __put_user(tv->tv_usec, &target_tv->tv_usec); -+ } else { -+ gemu_log("Unsupported ancillary data: %d/%d\n", -+ cmsg->cmsg_level, cmsg->cmsg_type); -+ memcpy(target_data, data, len); -+ } -+ cmsg = CMSG_NXTHDR(msgh, cmsg); -+ target_cmsg = TARGET_CMSG_NXTHDR(target_msgh, target_cmsg); -+ } -+ unlock_user(target_cmsg, target_cmsg_addr, space); -+ -+the_end: -+ target_msgh->msg_controllen = tswapal(space); -+ return 0; -+} -+ -diff --git a/bsd-user/freebsd/os-socket.h b/bsd-user/freebsd/os-socket.h -new file mode 100644 -index 0000000..9339ffb ---- /dev/null -+++ b/bsd-user/freebsd/os-socket.h -@@ -0,0 +1,548 @@ -+/* -+ * FreeBSD socket related system call shims -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+#ifndef __FREEBSD_SOCKET_H_ -+#define __FREEBSD_SOCKET_H_ -+ -+#include <sys/types.h> -+#include <sys/socket.h> -+#include <sys/un.h> -+#include <netinet/in.h> -+ -+#include "qemu-os.h" -+ -+/* sendmsg(2) */ -+static inline abi_long do_freebsd_sendmsg(int fd, abi_ulong target_msg, -+ int flags) -+{ -+ abi_long ret; -+ struct target_msghdr *msgp; -+ struct msghdr msg; -+ int count; -+ struct iovec *vec; -+ abi_ulong target_vec; -+ -+ if (!lock_user_struct(VERIFY_READ, msgp, target_msg, 1)) { -+ return -TARGET_EFAULT; -+ } -+ if (msgp->msg_name) { -+ msg.msg_namelen = tswap32(msgp->msg_namelen); -+ msg.msg_name = alloca(msg.msg_namelen); -+ ret = target_to_host_sockaddr(msg.msg_name, -+ tswapal(msgp->msg_name), msg.msg_namelen); -+ -+ if (is_error(ret)) { -+ unlock_user_struct(msgp, target_msg, 0); -+ return ret; -+ } -+ } else { -+ msg.msg_name = NULL; -+ msg.msg_namelen = 0; -+ } -+ msg.msg_controllen = 2 * tswapal(msgp->msg_controllen); -+ msg.msg_control = alloca(msg.msg_controllen); -+ msg.msg_flags = tswap32(msgp->msg_flags); -+ -+ count = tswapal(msgp->msg_iovlen); -+ vec = alloca(count * sizeof(struct iovec)); -+ target_vec = tswapal(msgp->msg_iov); -+ lock_iovec(VERIFY_READ, vec, target_vec, count, 1); -+ msg.msg_iovlen = count; -+ msg.msg_iov = vec; -+ -+ ret = t2h_freebsd_cmsg(&msg, msgp); -+ if (!is_error(ret)) { -+ ret = get_errno(sendmsg(fd, &msg, flags)); -+ } -+ unlock_iovec(vec, target_vec, count, 0); -+ unlock_user_struct(msgp, target_msg, 0); -+ return ret; -+} -+ -+/* recvmsg(2) */ -+static inline abi_long do_freebsd_recvmsg(int fd, abi_ulong target_msg, -+ int flags) -+{ -+ abi_long ret, len; -+ struct target_msghdr *msgp; -+ struct msghdr msg; -+ int count; -+ struct iovec *vec; -+ abi_ulong target_vec; -+ -+ if (!lock_user_struct(VERIFY_WRITE, msgp, target_msg, 0)) { -+ return -TARGET_EFAULT; -+ } -+ if (msgp->msg_name) { -+ msg.msg_namelen = tswap32(msgp->msg_namelen); -+ msg.msg_name = alloca(msg.msg_namelen); -+ ret = target_to_host_sockaddr(msg.msg_name, -+ tswapal(msgp->msg_name), msg.msg_namelen); -+ -+ if (is_error(ret)) { -+ unlock_user_struct(msgp, target_msg, 1); -+ return ret; -+ } -+ } else { -+ msg.msg_name = NULL; -+ msg.msg_namelen = 0; -+ } -+ msg.msg_controllen = 2 * tswapal(msgp->msg_controllen); -+ msg.msg_control = alloca(msg.msg_controllen); -+ msg.msg_flags = tswap32(msgp->msg_flags); -+ -+ count = tswapal(msgp->msg_iovlen); -+ vec = alloca(count * sizeof(struct iovec)); -+ target_vec = tswapal(msgp->msg_iov); -+ lock_iovec(VERIFY_WRITE, vec, target_vec, count, 0); -+ msg.msg_iovlen = count; -+ msg.msg_iov = vec; -+ -+ ret = get_errno(recvmsg(fd, &msg, flags)); -+ if (!is_error(ret)) { -+ len = ret; -+ ret = h2t_freebsd_cmsg(msgp, &msg); -+ if (!is_error(ret)) { -+ msgp->msg_namelen = tswap32(msg.msg_namelen); -+ if (msg.msg_name != NULL) { -+ ret = host_to_target_sockaddr(tswapal(msgp->msg_name), -+ msg.msg_name, msg.msg_namelen); -+ if (is_error(ret)) { -+ goto out; -+ } -+ } -+ } -+ ret = len; -+ } -+out: -+ unlock_iovec(vec, target_vec, count, 1); -+ unlock_user_struct(msgp, target_msg, 1); -+ return ret; -+} -+ -+/* setsockopt(2) */ -+static inline abi_long do_bsd_setsockopt(int sockfd, int level, int optname, -+ abi_ulong optval_addr, socklen_t optlen) -+{ -+ abi_long ret; -+ int val; -+ struct ip_mreqn *ip_mreq; -+ -+ switch (level) { -+ case IPPROTO_TCP: -+ /* TCP options all take an 'int' value. */ -+ if (optlen < sizeof(uint32_t)) { -+ return -TARGET_EINVAL; -+ } -+ if (get_user_u32(val, optval_addr)) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(setsockopt(sockfd, level, optname, &val, sizeof(val))); -+ break; -+ -+ case IPPROTO_IP: -+ switch (optname) { -+ case IP_HDRINCL:/* int; header is included with data */ -+ case IP_TOS: /* int; IP type of service and preced. */ -+ case IP_TTL: /* int; IP time to live */ -+ case IP_RECVOPTS: /* bool; receive all IP opts w/dgram */ -+ case IP_RECVRETOPTS: /* bool; receive IP opts for response */ -+ case IP_RECVDSTADDR: /* bool; receive IP dst addr w/dgram */ -+ case IP_MULTICAST_IF:/* u_char; set/get IP multicast i/f */ -+ case IP_MULTICAST_TTL:/* u_char; set/get IP multicast ttl */ -+ case IP_MULTICAST_LOOP:/*u_char;set/get IP multicast loopback */ -+ case IP_PORTRANGE: /* int; range to choose for unspec port */ -+ case IP_RECVIF: /* bool; receive reception if w/dgram */ -+ case IP_IPSEC_POLICY: /* int; set/get security policy */ -+ case IP_FAITH: /* bool; accept FAITH'ed connections */ -+ case IP_RECVTTL: /* bool; receive reception TTL w/dgram */ -+ val = 0; -+ if (optlen >= sizeof(uint32_t)) { -+ if (get_user_u32(val, optval_addr)) { -+ return -TARGET_EFAULT; -+ } -+ } else if (optlen >= 1) { -+ if (get_user_u8(val, optval_addr)) { -+ return -TARGET_EFAULT; -+ } -+ } -+ ret = get_errno(setsockopt(sockfd, level, optname, &val, -+ sizeof(val))); -+ break; -+ -+ case IP_ADD_MEMBERSHIP: /*ip_mreq; add an IP group membership */ -+ case IP_DROP_MEMBERSHIP:/*ip_mreq; drop an IP group membership*/ -+ if (optlen < sizeof(struct target_ip_mreq) || -+ optlen > sizeof(struct target_ip_mreqn)) { -+ return -TARGET_EINVAL; -+ } -+ ip_mreq = (struct ip_mreqn *) alloca(optlen); -+ target_to_host_ip_mreq(ip_mreq, optval_addr, optlen); -+ ret = get_errno(setsockopt(sockfd, level, optname, ip_mreq, -+ optlen)); -+ break; -+ -+ default: -+ goto unimplemented; -+ } -+ break; -+ -+ case TARGET_SOL_SOCKET: -+ switch (optname) { -+ /* Options with 'int' argument. */ -+ case TARGET_SO_DEBUG: -+ optname = SO_DEBUG; -+ break; -+ -+ case TARGET_SO_REUSEADDR: -+ optname = SO_REUSEADDR; -+ break; -+ -+ case TARGET_SO_REUSEPORT: -+ optname = SO_REUSEADDR; -+ break; -+ -+ case TARGET_SO_KEEPALIVE: -+ optname = SO_KEEPALIVE; -+ break; -+ -+ case TARGET_SO_DONTROUTE: -+ optname = SO_DONTROUTE; -+ break; -+ -+ case TARGET_SO_LINGER: -+ optname = SO_LINGER; -+ break; -+ -+ case TARGET_SO_BROADCAST: -+ optname = SO_BROADCAST; -+ break; -+ -+ case TARGET_SO_OOBINLINE: -+ optname = SO_OOBINLINE; -+ break; -+ -+ case TARGET_SO_SNDBUF: -+ optname = SO_SNDBUF; -+ break; -+ -+ case TARGET_SO_RCVBUF: -+ optname = SO_RCVBUF; -+ break; -+ -+ case TARGET_SO_SNDLOWAT: -+ optname = SO_RCVLOWAT; -+ break; -+ -+ case TARGET_SO_RCVLOWAT: -+ optname = SO_RCVLOWAT; -+ break; -+ -+ case TARGET_SO_SNDTIMEO: -+ optname = SO_SNDTIMEO; -+ break; -+ -+ case TARGET_SO_RCVTIMEO: -+ optname = SO_RCVTIMEO; -+ break; -+ -+ case TARGET_SO_ACCEPTFILTER: -+ goto unimplemented; -+ -+ case TARGET_SO_NOSIGPIPE: -+ optname = SO_NOSIGPIPE; -+ break; -+ -+ case TARGET_SO_TIMESTAMP: -+ optname = SO_TIMESTAMP; -+ break; -+ -+ case TARGET_SO_BINTIME: -+ optname = SO_BINTIME; -+ break; -+ -+ case TARGET_SO_ERROR: -+ optname = SO_ERROR; -+ break; -+ -+ case TARGET_SO_SETFIB: -+ optname = SO_ERROR; -+ break; -+ -+#ifdef SO_USER_COOKIE -+ case TARGET_SO_USER_COOKIE: -+ optname = SO_USER_COOKIE; -+ break; -+#endif -+ default: -+ goto unimplemented; -+ } -+ if (optlen < sizeof(uint32_t)) { -+ return -TARGET_EINVAL; -+ } -+ if (get_user_u32(val, optval_addr)) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(setsockopt(sockfd, SOL_SOCKET, optname, &val, -+ sizeof(val))); -+ break; -+ default: -+unimplemented: -+ gemu_log("Unsupported setsockopt level=%d optname=%d\n", -+ level, optname); -+ ret = -TARGET_ENOPROTOOPT; -+ } -+ -+ return ret; -+} -+ -+/* getsockopt(2) */ -+static inline abi_long do_bsd_getsockopt(int sockfd, int level, int optname, -+ abi_ulong optval_addr, abi_ulong optlen) -+{ -+ abi_long ret; -+ int len, val; -+ socklen_t lv; -+ -+ switch (level) { -+ case TARGET_SOL_SOCKET: -+ level = SOL_SOCKET; -+ switch (optname) { -+ -+ /* These don't just return a single integer */ -+ case TARGET_SO_LINGER: -+ case TARGET_SO_RCVTIMEO: -+ case TARGET_SO_SNDTIMEO: -+ case TARGET_SO_ACCEPTFILTER: -+ goto unimplemented; -+ -+ /* Options with 'int' argument. */ -+ case TARGET_SO_DEBUG: -+ optname = SO_DEBUG; -+ goto int_case; -+ -+ case TARGET_SO_REUSEADDR: -+ optname = SO_REUSEADDR; -+ goto int_case; -+ -+ case TARGET_SO_REUSEPORT: -+ optname = SO_REUSEPORT; -+ goto int_case; -+ -+ case TARGET_SO_TYPE: -+ optname = SO_TYPE; -+ goto int_case; -+ -+ case TARGET_SO_ERROR: -+ optname = SO_ERROR; -+ goto int_case; -+ -+ case TARGET_SO_DONTROUTE: -+ optname = SO_DONTROUTE; -+ goto int_case; -+ -+ case TARGET_SO_BROADCAST: -+ optname = SO_BROADCAST; -+ goto int_case; -+ -+ case TARGET_SO_SNDBUF: -+ optname = SO_SNDBUF; -+ goto int_case; -+ -+ case TARGET_SO_RCVBUF: -+ optname = SO_RCVBUF; -+ goto int_case; -+ -+ case TARGET_SO_KEEPALIVE: -+ optname = SO_KEEPALIVE; -+ goto int_case; -+ -+ case TARGET_SO_OOBINLINE: -+ optname = SO_OOBINLINE; -+ goto int_case; -+ -+ case TARGET_SO_TIMESTAMP: -+ optname = SO_TIMESTAMP; -+ goto int_case; -+ -+ case TARGET_SO_RCVLOWAT: -+ optname = SO_RCVLOWAT; -+ goto int_case; -+ -+ case TARGET_SO_LISTENINCQLEN: -+ optname = SO_LISTENINCQLEN; -+ goto int_case; -+ -+ default: -+int_case: -+ if (get_user_u32(len, optlen)) { -+ return -TARGET_EFAULT; -+ } -+ if (len < 0) { -+ return -TARGET_EINVAL; -+ } -+ lv = sizeof(lv); -+ ret = get_errno(getsockopt(sockfd, level, optname, &val, &lv)); -+ if (ret < 0) { -+ return ret; -+ } -+ if (len > lv) { -+ len = lv; -+ } -+ if (len == 4) { -+ if (put_user_u32(val, optval_addr)) { -+ return -TARGET_EFAULT; -+ } -+ } else { -+ if (put_user_u8(val, optval_addr)) { -+ return -TARGET_EFAULT; -+ } -+ } -+ if (put_user_u32(len, optlen)) { -+ return -TARGET_EFAULT; -+ } -+ break; -+ -+ } -+ break; -+ -+ case IPPROTO_TCP: -+ /* TCP options all take an 'int' value. */ -+ goto int_case; -+ -+ case IPPROTO_IP: -+ switch (optname) { -+ case IP_HDRINCL: -+ case IP_TOS: -+ case IP_TTL: -+ case IP_RECVOPTS: -+ case IP_RECVRETOPTS: -+ case IP_RECVDSTADDR: -+ -+ case IP_RETOPTS: -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 && defined(IP_RECVTOS) -+ case IP_RECVTOS: -+#endif -+ case IP_MULTICAST_TTL: -+ case IP_MULTICAST_LOOP: -+ case IP_PORTRANGE: -+ case IP_IPSEC_POLICY: -+ case IP_FAITH: -+ case IP_ONESBCAST: -+ case IP_BINDANY: -+ if (get_user_u32(len, optlen)) { -+ return -TARGET_EFAULT; -+ } -+ if (len < 0) { -+ return -TARGET_EINVAL; -+ } -+ lv = sizeof(lv); -+ ret = get_errno(getsockopt(sockfd, level, optname, -+ &val, &lv)); -+ if (ret < 0) { -+ return ret; -+ } -+ if (len < sizeof(int) && len > 0 && val >= 0 && -+ val < 255) { -+ len = 1; -+ if (put_user_u32(len, optlen) || -+ put_user_u8(val, optval_addr)) { -+ return -TARGET_EFAULT; -+ } -+ } else { -+ if (len > sizeof(int)) { -+ len = sizeof(int); -+ } -+ if (put_user_u32(len, optlen) || -+ put_user_u32(val, optval_addr)) { -+ return -TARGET_EFAULT; -+ } -+ } -+ break; -+ -+ default: -+ goto unimplemented; -+ } -+ break; -+ -+ default: -+unimplemented: -+ gemu_log("getsockopt level=%d optname=%d not yet supported\n", -+ level, optname); -+ ret = -TARGET_EOPNOTSUPP; -+ break; -+ } -+ return ret; -+} -+ -+/* setfib(2) */ -+static inline abi_long do_freebsd_setfib(abi_long fib) -+{ -+ -+ return get_errno(setfib(fib)); -+} -+ -+/* sctp_peeloff(2) */ -+static inline abi_long do_freebsd_sctp_peeloff(abi_long s, abi_ulong id) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sctp_peeloff()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sctp_generic_sendmsg(2) */ -+static inline abi_long do_freebsd_sctp_generic_sendmsg(abi_long s, -+ abi_ulong target_msg, abi_long msglen, abi_ulong target_to, -+ abi_ulong len, abi_ulong target_sinfo, abi_long flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sctp_generic_sendmsg()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sctp_generic_recvmsg(2) */ -+static inline abi_long do_freebsd_sctp_generic_recvmsg(abi_long s, -+ abi_ulong target_iov, abi_long iovlen, abi_ulong target_from, -+ abi_ulong fromlen, abi_ulong target_sinfo, abi_ulong target_msgflags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sctp_generic_recvmsg()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* freebsd4_sendfile(2) */ -+static inline abi_long do_freebsd_freebsd4_sendfile(abi_long fd, abi_long s, -+ abi_ulong arg3, abi_ulong arg4, abi_ulong nbytes, abi_ulong target_hdtr, -+ abi_ulong target_sbytes, abi_long flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall freebsd4_sendfile()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sendfile(2) */ -+static inline abi_long do_freebsd_sendfile(abi_long fd, abi_long s, -+ abi_ulong arg3, abi_ulong arg4, abi_ulong nbytes, abi_ulong target_hdtr, -+ abi_ulong target_sbytes, abi_long flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sendfile()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* !__FREEBSD_SOCKET_H_ */ -diff --git a/bsd-user/freebsd/os-stat.c b/bsd-user/freebsd/os-stat.c -new file mode 100644 -index 0000000..50885d1 ---- /dev/null -+++ b/bsd-user/freebsd/os-stat.c -@@ -0,0 +1,234 @@ -+/* -+ * FreeBSD stat related conversion routines -+ * -+ * 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/stat.h> -+#include <sys/mount.h> -+ -+#include "qemu.h" -+#include "qemu-os.h" -+ -+/* -+ * stat conversion -+ */ -+abi_long h2t_freebsd_stat(abi_ulong target_addr, struct stat *host_st) -+{ -+ struct target_freebsd_stat *target_st; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ memset(target_st, 0, sizeof(*target_st)); -+ __put_user(host_st->st_dev, &target_st->st_dev); -+ __put_user(host_st->st_ino, &target_st->st_ino); -+ __put_user(host_st->st_mode, &target_st->st_mode); -+ __put_user(host_st->st_nlink, &target_st->st_nlink); -+ __put_user(host_st->st_uid, &target_st->st_uid); -+ __put_user(host_st->st_gid, &target_st->st_gid); -+ __put_user(host_st->st_rdev, &target_st->st_rdev); -+ __put_user(host_st->st_atim.tv_sec, &target_st->st_atim.tv_sec); -+ __put_user(host_st->st_atim.tv_nsec, &target_st->st_atim.tv_nsec); -+ __put_user(host_st->st_mtim.tv_sec, &target_st->st_mtim.tv_sec); -+ __put_user(host_st->st_mtim.tv_nsec, &target_st->st_mtim.tv_nsec); -+ __put_user(host_st->st_ctim.tv_sec, &target_st->st_ctim.tv_sec); -+ __put_user(host_st->st_ctim.tv_nsec, &target_st->st_ctim.tv_nsec); -+ __put_user(host_st->st_size, &target_st->st_size); -+ __put_user(host_st->st_blocks, &target_st->st_blocks); -+ __put_user(host_st->st_blksize, &target_st->st_blksize); -+ __put_user(host_st->st_flags, &target_st->st_flags); -+ __put_user(host_st->st_gen, &target_st->st_gen); -+ /* st_lspare not used */ -+ __put_user(host_st->st_birthtim.tv_sec, &target_st->st_birthtim.tv_sec); -+ __put_user(host_st->st_birthtim.tv_nsec, &target_st->st_birthtim.tv_nsec); -+ unlock_user_struct(target_st, target_addr, 1); -+ -+ return 0; -+} -+ -+abi_long h2t_freebsd_nstat(abi_ulong target_addr, struct stat *host_st) -+{ -+ struct target_freebsd_nstat *target_st; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_st, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ memset(target_st, 0, sizeof(*target_st)); -+ __put_user(host_st->st_dev, &target_st->st_dev); -+ __put_user(host_st->st_ino, &target_st->st_ino); -+ __put_user(host_st->st_mode, &target_st->st_mode); -+ __put_user(host_st->st_nlink, &target_st->st_nlink); -+ __put_user(host_st->st_uid, &target_st->st_uid); -+ __put_user(host_st->st_gid, &target_st->st_gid); -+ __put_user(host_st->st_rdev, &target_st->st_rdev); -+ __put_user(host_st->st_atim.tv_sec, &target_st->st_atim.tv_sec); -+ __put_user(host_st->st_atim.tv_nsec, &target_st->st_atim.tv_nsec); -+ __put_user(host_st->st_mtim.tv_sec, &target_st->st_mtim.tv_sec); -+ __put_user(host_st->st_mtim.tv_nsec, &target_st->st_mtim.tv_nsec); -+ __put_user(host_st->st_ctim.tv_sec, &target_st->st_ctim.tv_sec); -+ __put_user(host_st->st_ctim.tv_nsec, &target_st->st_ctim.tv_nsec); -+ __put_user(host_st->st_size, &target_st->st_size); -+ __put_user(host_st->st_blocks, &target_st->st_blocks); -+ __put_user(host_st->st_blksize, &target_st->st_blksize); -+ __put_user(host_st->st_flags, &target_st->st_flags); -+ __put_user(host_st->st_gen, &target_st->st_gen); -+ __put_user(host_st->st_birthtim.tv_sec, &target_st->st_birthtim.tv_sec); -+ __put_user(host_st->st_birthtim.tv_nsec, &target_st->st_birthtim.tv_nsec); -+ unlock_user_struct(target_st, target_addr, 1); -+ -+ return 0; -+} -+ -+/* -+ * file handle conversion -+ */ -+abi_long t2h_freebsd_fhandle(fhandle_t *host_fh, abi_ulong target_addr) -+{ -+ target_freebsd_fhandle_t *target_fh; -+ -+ if (!lock_user_struct(VERIFY_READ, target_fh, target_addr, 1)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(host_fh->fh_fsid.val[0], &target_fh->fh_fsid.val[0]); -+ __get_user(host_fh->fh_fsid.val[1], &target_fh->fh_fsid.val[0]); -+ __get_user(host_fh->fh_fid.fid_len, &target_fh->fh_fid.fid_len); -+ /* u_short fid_data0; */ -+ memcpy(host_fh->fh_fid.fid_data, target_fh->fh_fid.fid_data, -+ TARGET_MAXFIDSZ); -+ unlock_user_struct(target_fh, target_addr, 0); -+ return 0; -+} -+ -+abi_long h2t_freebsd_fhandle(abi_ulong target_addr, fhandle_t *host_fh) -+{ -+ target_freebsd_fhandle_t *target_fh; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_fh, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __put_user(host_fh->fh_fsid.val[0], &target_fh->fh_fsid.val[0]); -+ __put_user(host_fh->fh_fsid.val[1], &target_fh->fh_fsid.val[0]); -+ __put_user(host_fh->fh_fid.fid_len, &target_fh->fh_fid.fid_len); -+ /* u_short fid_data0; */ -+ memcpy(target_fh->fh_fid.fid_data, host_fh->fh_fid.fid_data, -+ TARGET_MAXFIDSZ); -+ unlock_user_struct(target_fh, target_addr, 1); -+ return 0; -+} -+ -+/* -+ * file system stat -+ */ -+abi_long h2t_freebsd_statfs(abi_ulong target_addr, struct statfs *host_statfs) -+{ -+ struct target_freebsd_statfs *target_statfs; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_statfs, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __put_user(host_statfs->f_version, &target_statfs->f_version); -+ __put_user(host_statfs->f_type, &target_statfs->f_type); -+ __put_user(host_statfs->f_flags, &target_statfs->f_flags); -+ __put_user(host_statfs->f_bsize, &target_statfs->f_bsize); -+ __put_user(host_statfs->f_iosize, &target_statfs->f_iosize); -+ __put_user(host_statfs->f_blocks, &target_statfs->f_blocks); -+ __put_user(host_statfs->f_bfree, &target_statfs->f_bfree); -+ __put_user(host_statfs->f_bavail, &target_statfs->f_bavail); -+ __put_user(host_statfs->f_files, &target_statfs->f_files); -+ __put_user(host_statfs->f_ffree, &target_statfs->f_ffree); -+ __put_user(host_statfs->f_syncwrites, &target_statfs->f_syncwrites); -+ __put_user(host_statfs->f_asyncwrites, &target_statfs->f_asyncwrites); -+ __put_user(host_statfs->f_syncreads, &target_statfs->f_syncreads); -+ __put_user(host_statfs->f_asyncreads, &target_statfs->f_asyncreads); -+ /* uint64_t f_spare[10]; */ -+ __put_user(host_statfs->f_namemax, &target_statfs->f_namemax); -+ __put_user(host_statfs->f_owner, &target_statfs->f_owner); -+ __put_user(host_statfs->f_fsid.val[0], &target_statfs->f_fsid.val[0]); -+ __put_user(host_statfs->f_fsid.val[1], &target_statfs->f_fsid.val[1]); -+ /* char f_charspace[80]; */ -+ strncpy(&target_statfs->f_fstypename[0], host_statfs->f_fstypename, -+ TARGET_MFSNAMELEN); -+ strncpy(&target_statfs->f_mntfromname[0], host_statfs->f_mntfromname, -+ TARGET_MNAMELEN); -+ strncpy(&target_statfs->f_mntonname[0], host_statfs->f_mntonname, -+ TARGET_MNAMELEN); -+ unlock_user_struct(target_statfs, target_addr, 1); -+ return 0; -+} -+ -+/* -+ * fcntl cmd conversion -+ */ -+abi_long target_to_host_fcntl_cmd(int cmd) -+{ -+ -+ switch (cmd) { -+ case TARGET_F_DUPFD: -+ return F_DUPFD; -+ -+ case TARGET_F_DUP2FD: -+ return F_DUP2FD; -+ -+ case TARGET_F_GETFD: -+ return F_GETFD; -+ -+ case TARGET_F_SETFD: -+ return F_SETFD; -+ -+ case TARGET_F_GETFL: -+ return F_GETFL; -+ -+ case TARGET_F_SETFL: -+ return F_SETFL; -+ -+ case TARGET_F_GETOWN: -+ return F_GETOWN; -+ -+ case TARGET_F_SETOWN: -+ return F_SETOWN; -+ -+ case TARGET_F_GETLK: -+ return F_GETLK; -+ -+ case TARGET_F_SETLK: -+ return F_SETLK; -+ -+ case TARGET_F_SETLKW: -+ return F_SETLKW; -+ -+ case TARGET_F_READAHEAD: -+ return F_READAHEAD; -+ -+ case TARGET_F_RDAHEAD: -+ return F_RDAHEAD; -+ -+#ifdef F_DUPFD_CLOEXEC -+ case TARGET_F_DUPFD_CLOEXEC: -+ return F_DUPFD_CLOEXEC; -+#endif -+ -+#ifdef F_DUP2FD_CLOEXEC -+ case TARGET_F_DUP2FD_CLOEXEC: -+ return F_DUP2FD_CLOEXEC; -+#endif -+ -+ default: -+ return -TARGET_EINVAL; -+ } -+} -+ -diff --git a/bsd-user/freebsd/os-stat.h b/bsd-user/freebsd/os-stat.h -new file mode 100644 -index 0000000..ed6bcab ---- /dev/null -+++ b/bsd-user/freebsd/os-stat.h -@@ -0,0 +1,437 @@ -+/* -+ * stat related system call shims 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 __FREEBSD_STAT_H_ -+#define __FREEBSD_STAT_H_ -+ -+#include <sys/types.h> -+#include <sys/ucred.h> -+#include <sys/mount.h> -+#include <sys/stat.h> -+#include <dirent.h> -+ -+#include "qemu-os.h" -+ -+/* undocumented nstat system calls */ -+int nstat(const char *path, struct stat *sb); -+int nlstat(const char *path, struct stat *sb); -+int nfstat(int fd, struct stat *sb); -+ -+/* stat(2) */ -+static inline abi_long do_freebsd_stat(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ struct stat st; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(stat(path(p), &st)); -+ UNLOCK_PATH(p, arg1); -+ if (!is_error(ret)) { -+ ret = h2t_freebsd_stat(arg2, &st); -+ } -+ return ret; -+} -+ -+/* lstat(2) */ -+static inline abi_long do_freebsd_lstat(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ struct stat st; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(lstat(path(p), &st)); -+ UNLOCK_PATH(p, arg1); -+ if (!is_error(ret)) { -+ ret = h2t_freebsd_stat(arg2, &st); -+ } -+ return ret; -+} -+ -+/* fstat(2) */ -+static inline abi_long do_freebsd_fstat(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ struct stat st; -+ -+ ret = get_errno(fstat(arg1, &st)); -+ if (!is_error(ret)) { -+ ret = h2t_freebsd_stat(arg2, &st); -+ } -+ return ret; -+} -+ -+/* fstatat(2) */ -+static inline abi_long do_freebsd_fstatat(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4) -+{ -+ abi_long ret; -+ void *p; -+ struct stat st; -+ -+ LOCK_PATH(p, arg2); -+ ret = get_errno(fstatat(arg1, p, &st, arg4)); -+ UNLOCK_PATH(p, arg2); -+ if (!is_error(ret) && arg3) { -+ ret = h2t_freebsd_stat(arg3, &st); -+ } -+ return ret; -+} -+ -+/* undocummented nstat(char *path, struct nstat *ub) syscall */ -+static abi_long do_freebsd_nstat(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ struct stat st; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(nstat(path(p), &st)); -+ UNLOCK_PATH(p, arg1); -+ if (!is_error(ret)) { -+ ret = h2t_freebsd_nstat(arg2, &st); -+ } -+ return ret; -+} -+ -+/* undocummented nfstat(int fd, struct nstat *sb) syscall */ -+static abi_long do_freebsd_nfstat(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ struct stat st; -+ -+ ret = get_errno(nfstat(arg1, &st)); -+ if (!is_error(ret)) { -+ ret = h2t_freebsd_nstat(arg2, &st); -+ } -+ return ret; -+} -+ -+/* undocummented nlstat(char *path, struct nstat *ub) syscall */ -+static abi_long do_freebsd_nlstat(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ struct stat st; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(nlstat(path(p), &st)); -+ UNLOCK_PATH(p, arg1); -+ if (!is_error(ret)) { -+ ret = h2t_freebsd_nstat(arg2, &st); -+ } -+ return ret; -+} -+ -+/* getfh(2) */ -+static abi_long do_freebsd_getfh(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ fhandle_t host_fh; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(getfh(path(p), &host_fh)); -+ UNLOCK_PATH(p, arg1); -+ if (is_error(ret)) { -+ return ret; -+ } -+ return h2t_freebsd_fhandle(arg2, &host_fh); -+} -+ -+/* lgetfh(2) */ -+static inline abi_long do_freebsd_lgetfh(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ fhandle_t host_fh; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(lgetfh(path(p), &host_fh)); -+ UNLOCK_PATH(p, arg1); -+ if (is_error(ret)) { -+ return ret; -+ } -+ return h2t_freebsd_fhandle(arg2, &host_fh); -+} -+ -+/* fhopen(2) */ -+static inline abi_long do_freebsd_fhopen(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ fhandle_t host_fh; -+ -+ ret = t2h_freebsd_fhandle(&host_fh, arg1); -+ if (is_error(ret)) { -+ return ret; -+ } -+ -+ return get_errno(fhopen(&host_fh, arg2)); -+} -+ -+/* fhstat(2) */ -+static inline abi_long do_freebsd_fhstat(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ fhandle_t host_fh; -+ struct stat host_sb; -+ -+ ret = t2h_freebsd_fhandle(&host_fh, arg1); -+ if (is_error(ret)) { -+ return ret; -+ } -+ ret = get_errno(fhstat(&host_fh, &host_sb)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ return h2t_freebsd_stat(arg2, &host_sb); -+} -+ -+/* fhstatfs(2) */ -+static inline abi_long do_freebsd_fhstatfs(abi_ulong target_fhp_addr, -+ abi_ulong target_stfs_addr) -+{ -+ abi_long ret; -+ fhandle_t host_fh; -+ struct statfs host_stfs; -+ -+ ret = t2h_freebsd_fhandle(&host_fh, target_fhp_addr); -+ if (is_error(ret)) { -+ return ret; -+ } -+ ret = get_errno(fhstatfs(&host_fh, &host_stfs)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ return h2t_freebsd_statfs(target_stfs_addr, &host_stfs); -+} -+ -+/* statfs(2) */ -+static inline abi_long do_freebsd_statfs(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ struct statfs host_stfs; -+ -+ LOCK_PATH(p, arg1); -+ ret = get_errno(statfs(path(p), &host_stfs)); -+ UNLOCK_PATH(p, arg1); -+ if (is_error(ret)) { -+ return ret; -+ } -+ -+ return h2t_freebsd_statfs(arg2, &host_stfs); -+} -+ -+/* fstatfs(2) */ -+static inline abi_long do_freebsd_fstatfs(abi_long fd, abi_ulong target_addr) -+{ -+ abi_long ret; -+ struct statfs host_stfs; -+ -+ ret = get_errno(fstatfs(fd, &host_stfs)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ -+ return h2t_freebsd_statfs(target_addr, &host_stfs); -+} -+ -+/* getfsstat(2) */ -+static inline abi_long do_freebsd_getfsstat(abi_ulong target_addr, -+ abi_long bufsize, abi_long flags) -+{ -+ abi_long ret; -+ struct statfs *host_stfs; -+ int count; -+ long host_bufsize; -+ -+ count = bufsize / sizeof(struct target_freebsd_statfs); -+ -+ /* if user buffer is NULL then return number of mounted FS's */ -+ if (target_addr == 0 || count == 0) { -+ return get_errno(getfsstat(NULL, 0, flags)); -+ } -+ -+ /* XXX check count to be reasonable */ -+ host_bufsize = sizeof(struct statfs) * count; -+ host_stfs = alloca(host_bufsize); -+ if (!host_stfs) { -+ return -TARGET_EINVAL; -+ } -+ -+ ret = count = get_errno(getfsstat(host_stfs, host_bufsize, flags)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ -+ while (count--) { -+ if (h2t_freebsd_statfs((target_addr + -+ (count * sizeof(struct target_freebsd_statfs))), -+ &host_stfs[count])) { -+ return -TARGET_EFAULT; -+ } -+ } -+ return ret; -+} -+ -+/* getdents(2) */ -+static inline abi_long do_freebsd_getdents(abi_long arg1, abi_ulong arg2, -+ abi_long nbytes) -+{ -+ abi_long ret; -+ struct dirent *dirp; -+ -+ dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0); -+ if (dirp == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(getdents(arg1, (char *)dirp, nbytes)); -+ if (!is_error(ret)) { -+ struct dirent *de; -+ int len = ret; -+ int reclen; -+ -+ de = dirp; -+ while (len > 0) { -+ reclen = de->d_reclen; -+ if (reclen > len) { -+ return -TARGET_EFAULT; -+ } -+ de->d_reclen = tswap16(reclen); -+ de->d_fileno = tswap32(de->d_fileno); -+ len -= reclen; -+ } -+ } -+ return ret; -+} -+ -+/* getdirecentries(2) */ -+static inline abi_long do_freebsd_getdirentries(abi_long arg1, abi_ulong arg2, -+ abi_long nbytes, abi_ulong arg4) -+{ -+ abi_long ret; -+ struct dirent *dirp; -+ long basep; -+ -+ dirp = lock_user(VERIFY_WRITE, arg2, nbytes, 0); -+ if (dirp == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(getdirentries(arg1, (char *)dirp, nbytes, &basep)); -+ if (!is_error(ret)) { -+ struct dirent *de; -+ int len = ret; -+ int reclen; -+ -+ de = dirp; -+ while (len > 0) { -+ reclen = de->d_reclen; -+ if (reclen > len) { -+ return -TARGET_EFAULT; -+ } -+ de->d_reclen = tswap16(reclen); -+ de->d_fileno = tswap32(de->d_fileno); -+ len -= reclen; -+ de = (struct dirent *)((void *)de + reclen); -+ } -+ } -+ unlock_user(dirp, arg2, ret); -+ if (arg4) { -+ if (put_user(basep, arg4, abi_ulong)) { -+ return -TARGET_EFAULT; -+ } -+ } -+ return ret; -+} -+ -+/* fcntl(2) */ -+static inline abi_long do_freebsd_fcntl(abi_long arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ abi_long ret; -+ int host_cmd; -+ struct flock fl; -+ struct target_freebsd_flock *target_fl; -+ -+ host_cmd = target_to_host_fcntl_cmd(arg2); -+ if (host_cmd < 0) { -+ return host_cmd; -+ } -+ switch (arg2) { -+ case TARGET_F_GETLK: -+ if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(fl.l_type, &target_fl->l_type); -+ __get_user(fl.l_whence, &target_fl->l_whence); -+ __get_user(fl.l_start, &target_fl->l_start); -+ __get_user(fl.l_len, &target_fl->l_len); -+ __get_user(fl.l_pid, &target_fl->l_pid); -+ __get_user(fl.l_sysid, &target_fl->l_sysid); -+ unlock_user_struct(target_fl, arg3, 0); -+ ret = get_errno(fcntl(arg1, host_cmd, &fl)); -+ if (!is_error(ret)) { -+ if (!lock_user_struct(VERIFY_WRITE, target_fl, arg3, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __put_user(fl.l_type, &target_fl->l_type); -+ __put_user(fl.l_whence, &target_fl->l_whence); -+ __put_user(fl.l_start, &target_fl->l_start); -+ __put_user(fl.l_len, &target_fl->l_len); -+ __put_user(fl.l_pid, &target_fl->l_pid); -+ __put_user(fl.l_sysid, &target_fl->l_sysid); -+ unlock_user_struct(target_fl, arg3, 1); -+ } -+ break; -+ -+ case TARGET_F_SETLK: -+ case TARGET_F_SETLKW: -+ if (!lock_user_struct(VERIFY_READ, target_fl, arg3, 1)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(fl.l_type, &target_fl->l_type); -+ __get_user(fl.l_whence, &target_fl->l_whence); -+ __get_user(fl.l_start, &target_fl->l_start); -+ __get_user(fl.l_len, &target_fl->l_len); -+ __get_user(fl.l_pid, &target_fl->l_pid); -+ __get_user(fl.l_sysid, &target_fl->l_sysid); -+ unlock_user_struct(target_fl, arg3, 0); -+ ret = get_errno(fcntl(arg1, host_cmd, &fl)); -+ break; -+ -+ case TARGET_F_DUPFD: -+ case TARGET_F_DUP2FD: -+ case TARGET_F_GETOWN: -+ case TARGET_F_SETOWN: -+ case TARGET_F_GETFD: -+ case TARGET_F_SETFD: -+ case TARGET_F_GETFL: -+ case TARGET_F_SETFL: -+ case TARGET_F_READAHEAD: -+ case TARGET_F_RDAHEAD: -+ default: -+ ret = get_errno(fcntl(arg1, host_cmd, arg3)); -+ break; -+ } -+ return ret; -+} -+ -+#endif /* ! __FREEBSD_STAT_H_ */ -diff --git a/bsd-user/freebsd/os-strace.h b/bsd-user/freebsd/os-strace.h -new file mode 100644 -index 0000000..a222f09 ---- /dev/null -+++ b/bsd-user/freebsd/os-strace.h -@@ -0,0 +1,29 @@ -+/* -+ * FreeBSD dependent strace print functions -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#include "target_arch_sysarch.h" /* architecture dependent functions */ -+ -+ -+static inline void do_os_print_sysarch(const struct syscallname *name, -+ abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, -+ abi_long arg5, abi_long arg6) -+{ -+ /* This is arch dependent */ -+ do_freebsd_arch_print_sysarch(name, arg1, arg2, arg3, arg4, arg5, arg6); -+} -diff --git a/bsd-user/freebsd/os-sys.c b/bsd-user/freebsd/os-sys.c -new file mode 100644 -index 0000000..c8f999f ---- /dev/null -+++ b/bsd-user/freebsd/os-sys.c -@@ -0,0 +1,284 @@ -+/* -+ * 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; -+ TaskState *ts = (TaskState *)env->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/os-thread.c b/bsd-user/freebsd/os-thread.c -new file mode 100644 -index 0000000..6bf2a9f ---- /dev/null -+++ b/bsd-user/freebsd/os-thread.c -@@ -0,0 +1,1001 @@ -+/* -+ * FreeBSD thr emulation support code -+ * -+ * 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/param.h> -+#include <sys/types.h> -+#include <sys/errno.h> -+#include <sys/mman.h> -+#include <sys/thr.h> -+#include <sys/umtx.h> -+#include <sys/rtprio.h> -+ -+#include <machine/atomic.h> -+ -+#include <time.h> -+ -+#include "qemu.h" -+#include "qemu-os.h" -+#include "target_arch_cpu.h" -+#include "target_arch_thread.h" -+ -+// #define DEBUG_UMTX(...) fprintf(stderr, __VA_ARGS__) -+#define DEBUG_UMTX(...) -+ -+#define NEW_STACK_SIZE 0x40000 -+ -+/* sys/_umtx.h */ -+struct target_umtx { -+ abi_ulong u_owner; /* Owner of the mutex. */ -+}; -+ -+struct target_umutex { -+ uint32_t m_owner; /* Owner of the mutex */ -+ uint32_t m_flags; /* Flags of the mutex */ -+ uint32_t m_ceiling[2]; /* Priority protect ceiling */ -+ uint32_t m_spare[4]; -+}; -+ -+struct target_ucond { -+ uint32_t c_has_waiters; /* Has waiters in kernel */ -+ uint32_t c_flags; /* Flags of the condition variable */ -+ uint32_t c_clockid; /* Clock id */ -+ uint32_t c_spare[1]; -+}; -+ -+struct target_urwlock { -+ uint32_t rw_state; -+ uint32_t rw_flags; -+ uint32_t rw_blocked_readers; -+ uint32_t rw_blocked_writers; -+ uint32_t rw_spare[4]; -+}; -+ -+struct target__usem { -+ uint32_t _has_waiters; -+ uint32_t _count; -+ uint32_t _flags; -+}; -+ -+static pthread_mutex_t new_thread_lock = PTHREAD_MUTEX_INITIALIZER; -+pthread_mutex_t *new_freebsd_thread_lock_ptr = &new_thread_lock; -+ -+static pthread_mutex_t umtx_wait_lck = PTHREAD_MUTEX_INITIALIZER; -+static pthread_cond_t umtx_wait_cv = PTHREAD_COND_INITIALIZER; -+static abi_ulong umtx_wait_addr; -+ -+static void rtp_to_schedparam(const struct rtprio *rtp, int *policy, -+ struct sched_param *param) -+{ -+ -+ switch (rtp->type) { -+ case RTP_PRIO_REALTIME: -+ *policy = SCHED_RR; -+ param->sched_priority = RTP_PRIO_MAX - rtp->prio; -+ break; -+ -+ case RTP_PRIO_FIFO: -+ *policy = SCHED_FIFO; -+ param->sched_priority = RTP_PRIO_MAX - rtp->prio; -+ break; -+ -+ default: -+ *policy = SCHED_OTHER; -+ param->sched_priority = 0; -+ break; -+ } -+} -+ -+void *new_freebsd_thread_start(void *arg) -+{ -+ new_freebsd_thread_info_t *info = arg; -+ CPUArchState *env; -+ CPUState *cpu; -+ // TaskState *ts; -+ long tid; -+ -+ env = info->env; -+ cpu = ENV_GET_CPU(env); -+ thread_cpu = cpu; -+ -+ // ts = (TaskState *)env->opaque; -+ (void)thr_self(&tid); -+ cpu->host_tid = tid; -+ // ts->ts_tid = tid; -+ -+ /* copy out the TID info */ -+ if (info->param.child_tid) { -+ put_user(tid, info->param.child_tid, abi_long); -+ } -+ if (info->param.parent_tid) { -+ put_user(info->parent_tid, info->param.parent_tid, abi_long); -+ } -+ -+ /* Set arch dependent registers to start thread. */ -+ target_thread_set_upcall(env, info->param.start_func, info->param.arg, -+ info->param.stack_base, info->param.stack_size); -+ -+ /* Enable signals */ -+ sigprocmask(SIG_SETMASK, &info->sigmask, NULL); -+ /* Signal to the parent that we're ready. */ -+ pthread_mutex_lock(&info->mutex); -+ pthread_cond_broadcast(&info->cond); -+ pthread_mutex_unlock(&info->mutex); -+ /* Wait until the parent has finished initializing the TLS state. */ -+ pthread_mutex_lock(new_freebsd_thread_lock_ptr); -+ pthread_mutex_unlock(new_freebsd_thread_lock_ptr); -+ -+ cpu_loop(env); -+ /* never exits */ -+ -+ return NULL; -+} -+ -+/* -+ * FreeBSD user mutex (_umtx) emulation -+ */ -+static int tcmpset_al(abi_ulong *addr, abi_ulong a, abi_ulong b) -+{ -+ abi_ulong current = tswapal(a); -+ abi_ulong new = tswapal(b); -+ -+#ifdef TARGET_ABI32 -+ return atomic_cmpset_acq_32(addr, current, new); -+#else -+ return atomic_cmpset_acq_64(addr, current, new); -+#endif -+} -+ -+static int tcmpset_32(uint32_t *addr, uint32_t a, uint32_t b) -+{ -+ uint32_t current = tswap32(a); -+ uint32_t new = tswap32(b); -+ -+ return atomic_cmpset_acq_32(addr, current, new); -+} -+ -+abi_long freebsd_umtx_wait_uint(abi_ulong obj, uint32_t val, -+ struct timespec *timeout) -+{ -+ -+ DEBUG_UMTX("<WAIT> %s: _umtx_op(%p, %d, 0x%x, NULL, %p)\n", -+ __func__, g2h(obj), UMTX_OP_WAIT_UINT, val, timeout); -+ return get_errno(_umtx_op(g2h(obj), UMTX_OP_WAIT_UINT, val, NULL, timeout)); -+} -+ -+abi_long freebsd_umtx_wait_uint_private(abi_ulong obj, uint32_t val, -+ struct timespec *timeout) -+{ -+ -+ DEBUG_UMTX("<WAIT> %s: _umtx_op(%p, %d, 0x%x, NULL, %p)\n", -+ __func__, g2h(obj), UMTX_OP_WAIT_UINT_PRIVATE, val, timeout); -+ return get_errno(_umtx_op(g2h(obj), UMTX_OP_WAIT_UINT_PRIVATE, val, NULL, -+ timeout)); -+} -+ -+abi_long freebsd_umtx_wake_private(abi_ulong obj, uint32_t val) -+{ -+ -+ DEBUG_UMTX("<WAKE> %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", -+ __func__, g2h(obj), UMTX_OP_WAKE_PRIVATE, val); -+ return get_errno(_umtx_op(g2h(obj), UMTX_OP_WAKE_PRIVATE, val, NULL, NULL)); -+} -+ -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 -+#if defined(UMTX_OP_NWAKE_PRIVATE) -+abi_long freebsd_umtx_nwake_private(abi_ulong obj, uint32_t val) -+{ -+ -+ DEBUG_UMTX("<NWAKE> %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", -+ __func__, g2h(obj), UMTX_OP_NWAKE_PRIVATE, val); -+ return get_errno(_umtx_op(g2h(obj), UMTX_OP_NWAKE_PRIVATE, val, NULL, -+ NULL)); -+} -+#endif /* UMTX_OP_NWAKE_PRIVATE */ -+ -+#if defined(UMTX_OP_MUTEX_WAKE2) -+abi_long freebsd_umtx_mutex_wake2(abi_ulong target_addr, -+ __unused uint32_t flags) -+{ -+ abi_long ret = 0; -+ -+ pthread_mutex_lock(&umtx_wait_lck); -+ DEBUG_UMTX("<WAKE2 CV> %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", -+ __func__, g2h(target_addr), UMTX_OP_MUTEX_WAKE2, flags); -+ umtx_wait_addr = target_addr; -+ ret = get_errno(pthread_cond_broadcast(&umtx_wait_cv)); -+ pthread_mutex_unlock(&umtx_wait_lck); -+ -+ return ret; -+} -+#endif /* UMTX_OP_MUTEX_WAKE2 */ -+ -+abi_long freebsd_umtx_sem_wait(abi_ulong obj, struct timespec *timeout) -+{ -+ -+ /* XXX Assumes struct _usem is opauque to the user */ -+ if (!access_ok(VERIFY_WRITE, obj, sizeof(struct target__usem))) { -+ return -TARGET_EFAULT; -+ } -+ return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM_WAIT, 0, NULL, timeout)); -+} -+ -+abi_long freebsd_umtx_sem_wake(abi_ulong obj, uint32_t val) -+{ -+ -+ return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM_WAKE, val, NULL, NULL)); -+} -+#endif -+ -+abi_long t2h_freebsd_rtprio(struct rtprio *host_rtp, abi_ulong target_addr) -+{ -+ struct target_freebsd_rtprio *target_rtp; -+ -+ if (!lock_user_struct(VERIFY_READ, target_rtp, target_addr, 1)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(host_rtp->type, &target_rtp->type); -+ __get_user(host_rtp->prio, &target_rtp->prio); -+ unlock_user_struct(target_rtp, target_addr, 0); -+ return 0; -+} -+ -+abi_long h2t_freebsd_rtprio(abi_ulong target_addr, struct rtprio *host_rtp) -+{ -+ struct target_freebsd_rtprio *target_rtp; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_rtp, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __put_user(host_rtp->type, &target_rtp->type); -+ __put_user(host_rtp->prio, &target_rtp->prio); -+ unlock_user_struct(target_rtp, target_addr, 1); -+ return 0; -+} -+ -+abi_long freebsd_lock_umtx(abi_ulong target_addr, abi_long id, -+ struct timespec *timeout) -+{ -+ abi_long ret; -+ abi_long owner; -+ -+ /* -+ * XXX Note that memory at umtx_addr can change and so we need to be -+ * careful and check for faults. -+ */ -+ for (;;) { -+ struct target_umtx *target_umtx; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_umtx, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ /* Check the simple uncontested case. */ -+ if (tcmpset_al(&target_umtx->u_owner, -+ TARGET_UMTX_UNOWNED, id)) { -+ unlock_user_struct(target_umtx, target_addr, 1); -+ return 0; -+ } -+ /* Check to see if the lock is contested but free. */ -+ __get_user(owner, &target_umtx->u_owner); -+ -+ if (TARGET_UMTX_CONTESTED == owner) { -+ if (tcmpset_al(&target_umtx->u_owner, TARGET_UMTX_CONTESTED, -+ id | TARGET_UMTX_CONTESTED)) { -+ unlock_user_struct(target_umtx, target_addr, 1); -+ return 0; -+ } -+ /* We failed because it changed on us, restart. */ -+ unlock_user_struct(target_umtx, target_addr, 1); -+ continue; -+ } -+ -+ /* Set the contested bit and sleep. */ -+ do { -+ __get_user(owner, &target_umtx->u_owner); -+ if (owner & TARGET_UMTX_CONTESTED) { -+ break; -+ } -+ } while (!tcmpset_al(&target_umtx->u_owner, owner, -+ owner | TARGET_UMTX_CONTESTED)); -+ -+ __get_user(owner, &target_umtx->u_owner); -+ unlock_user_struct(target_umtx, target_addr, 1); -+ -+ /* Byte swap, if needed, to match what is stored in user mem. */ -+ owner = tswapal(owner); -+ DEBUG_UMTX("<WAIT> %s: _umtx_op(%p, %d, 0x%llx, NULL, NULL)\n", -+ __func__, g2h(target_addr), UMTX_OP_WAIT, (long long)owner); -+#ifdef TARGET_ABI32 -+ ret = get_errno(_umtx_op(g2h(target_addr), UMTX_OP_WAIT_UINT, owner, -+ NULL, timeout)); -+#else -+ ret = get_errno(_umtx_op(g2h(target_addr), UMTX_OP_WAIT, owner, -+ NULL, timeout)); -+#endif -+ if (is_error(ret)) { -+ return ret; -+ } -+ } -+} -+ -+abi_long freebsd_unlock_umtx(abi_ulong target_addr, abi_long id) -+{ -+ abi_ulong owner; -+ struct target_umtx *target_umtx; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_umtx, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(owner, &target_umtx->u_owner); -+ if ((owner & ~TARGET_UMTX_CONTESTED) != id) { -+ unlock_user_struct(target_umtx, target_addr, 1); -+ return -TARGET_EPERM; -+ } -+ /* Check the simple uncontested case. */ -+ if ((owner & ~TARGET_UMTX_CONTESTED) == 0) { -+ if (tcmpset_al(&target_umtx->u_owner, owner, -+ TARGET_UMTX_UNOWNED)) { -+ unlock_user_struct(target_umtx, target_addr, 1); -+ return 0; -+ } -+ } -+ /* This is a contested lock. Unlock it. */ -+ __put_user(TARGET_UMTX_UNOWNED, &target_umtx->u_owner); -+ unlock_user_struct(target_umtx, target_addr, 1); -+ -+ /* Wake up all those contesting it. */ -+ DEBUG_UMTX("<WAKE> %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", -+ __func__, g2h(target_addr), UMTX_OP_WAKE, 0); -+ _umtx_op(g2h(target_addr), UMTX_OP_WAKE, 0, 0, 0); -+ -+ return 0; -+} -+ -+abi_long freebsd_umtx_wait(abi_ulong targ_addr, abi_ulong id, -+ struct timespec *ts) -+{ -+ -+ /* We want to check the user memory but not lock it. We might sleep. */ -+ if (!access_ok(VERIFY_READ, targ_addr, sizeof(abi_ulong))) { -+ return -TARGET_EFAULT; -+ } -+ -+ DEBUG_UMTX("<WAIT> %s: _umtx_op(%p, %d, 0x%llx, NULL, NULL)\n", -+ __func__, g2h(targ_addr), UMTX_OP_WAIT, (long long)id); -+#ifdef TARGET_ABI32 -+ return get_errno(_umtx_op(g2h(targ_addr), UMTX_OP_WAIT_UINT, id, NULL, ts)); -+#else -+ return get_errno(_umtx_op(g2h(targ_addr), UMTX_OP_WAIT, id, NULL, ts)); -+#endif -+} -+ -+abi_long freebsd_umtx_wake(abi_ulong target_addr, uint32_t n_wake) -+{ -+ -+ DEBUG_UMTX("<WAKE> %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", -+ __func__, g2h(target_addr), UMTX_OP_WAKE, n_wake); -+ return get_errno(_umtx_op(g2h(target_addr), UMTX_OP_WAKE, n_wake, NULL, 0)); -+} -+ -+abi_long freebsd_umtx_mutex_wake(abi_ulong obj, abi_long val) -+{ -+ -+ DEBUG_UMTX("<WAKE> %s: _umtx_op(%p, %d, 0x%llx, NULL, NULL)\n", -+ __func__, g2h(obj), UMTX_OP_WAKE, (long long)val); -+ return get_errno(_umtx_op(g2h(obj), UMTX_OP_MUTEX_WAKE, val, NULL, NULL)); -+} -+ -+abi_long freebsd_lock_umutex(abi_ulong target_addr, uint32_t id, -+ struct timespec *ts, int mode) -+{ -+ uint32_t owner, flags; -+ int ret = 0; -+ -+ for (;;) { -+ struct target_umutex *target_umutex; -+ -+ pthread_mutex_lock(&umtx_wait_lck); -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_umutex, target_addr, 0)) { -+ pthread_mutex_unlock(&umtx_wait_lck); -+ return -TARGET_EFAULT; -+ } -+ -+ __get_user(owner, &target_umutex->m_owner); -+ -+ if (TARGET_UMUTEX_WAIT == mode) { -+ if (TARGET_UMUTEX_UNOWNED == owner || -+ TARGET_UMUTEX_CONTESTED == owner) { -+ unlock_user_struct(target_umutex, target_addr, 1); -+ pthread_mutex_unlock(&umtx_wait_lck); -+ return 0; -+ } -+ } else { -+ if (tcmpset_32(&target_umutex->m_owner, TARGET_UMUTEX_UNOWNED, -+ id)) { -+ /* The acquired succeeded. */ -+ unlock_user_struct(target_umutex, target_addr, 1); -+ pthread_mutex_unlock(&umtx_wait_lck); -+ return 0; -+ } -+ -+ /* If no one owns it but it is contested try to acquire it. */ -+ if (TARGET_UMUTEX_CONTESTED == owner) { -+ if (tcmpset_32(&target_umutex->m_owner, TARGET_UMUTEX_CONTESTED, -+ id | TARGET_UMUTEX_CONTESTED)) { -+ unlock_user_struct(target_umutex, target_addr, 1); -+ pthread_mutex_unlock(&umtx_wait_lck); -+ return 0; -+ } -+ /* The lock changed so restart. */ -+ unlock_user_struct(target_umutex, target_addr, 1); -+ pthread_mutex_unlock(&umtx_wait_lck); -+ continue; -+ } -+ } -+ -+ __get_user(flags, &target_umutex->m_flags); -+ if ((flags & TARGET_UMUTEX_ERROR_CHECK) != 0 && -+ (owner & ~TARGET_UMUTEX_CONTESTED) == id) { -+ unlock_user_struct(target_umutex, target_addr, 1); -+ pthread_mutex_unlock(&umtx_wait_lck); -+ return -TARGET_EDEADLK; -+ } -+ -+ if (TARGET_UMUTEX_TRY == mode) { -+ unlock_user_struct(target_umutex, target_addr, 1); -+ pthread_mutex_unlock(&umtx_wait_lck); -+ return -TARGET_EBUSY; -+ } -+ -+ /* -+ * If we caught a signal, we have retried and now -+ * exit immediately. -+ */ -+ if (is_error(ret)) { -+ unlock_user_struct(target_umutex, target_addr, 1); -+ pthread_mutex_unlock(&umtx_wait_lck); -+ return ret; -+ } -+ -+ /* Set the contested bit and sleep. */ -+ if (!tcmpset_32(&target_umutex->m_owner, owner, -+ owner | TARGET_UMUTEX_CONTESTED)) { -+ unlock_user_struct(target_umutex, target_addr, 1); -+ pthread_mutex_unlock(&umtx_wait_lck); -+ continue; -+ } -+ -+ DEBUG_UMTX("<WAIT CV> %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", -+ __func__, g2h(target_addr), UMTX_OP_WAIT_UINT, -+ tswap32(target_umutex->m_owner)); -+ unlock_user_struct(target_umutex, target_addr, 1); -+ -+again: -+ if (ts == NULL) { -+ ret = get_errno(pthread_cond_wait(&umtx_wait_cv, -+ &umtx_wait_lck)); -+ } else { -+ ret = get_errno(pthread_cond_timedwait(&umtx_wait_cv, -+ &umtx_wait_lck, ts)); -+ } -+ if (ret != 0) { -+ pthread_mutex_unlock(&umtx_wait_lck); -+ break; -+ } -+ if (target_addr != umtx_wait_addr) { -+ goto again; -+ } -+ pthread_mutex_unlock(&umtx_wait_lck); -+ } -+ -+ return ret; -+} -+ -+abi_long freebsd_unlock_umutex(abi_ulong target_addr, uint32_t id) -+{ -+ struct target_umutex *target_umutex; -+ uint32_t owner; -+ -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_umutex, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ /* Make sure we own this mutex. */ -+ __get_user(owner, &target_umutex->m_owner); -+ if ((owner & ~TARGET_UMUTEX_CONTESTED) != id) { -+ unlock_user_struct(target_umutex, target_addr, 1); -+ return -TARGET_EPERM; -+ } -+ if ((owner & TARGET_UMUTEX_CONTESTED) == 0) { -+ if (tcmpset_32(&target_umutex->m_owner, owner, TARGET_UMTX_UNOWNED)) { -+ unlock_user_struct(target_umutex, target_addr, 1); -+ return 0; -+ } -+ } -+ /* This is a contested lock. Unlock it. */ -+ __put_user(TARGET_UMUTEX_UNOWNED, &target_umutex->m_owner); -+ unlock_user_struct(target_umutex, target_addr, 1); -+ -+ /* And wake up all those contesting it. */ -+ DEBUG_UMTX("<WAKE> %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", -+ __func__, g2h(target_addr), UMTX_OP_WAKE, 0); -+ return get_errno(_umtx_op(g2h(target_addr), UMTX_OP_WAKE, 0, 0, 0)); -+} -+ -+/* -+ * _cv_mutex is keeps other threads from doing a signal or broadcast until -+ * the thread is actually asleep and ready. This is a global mutex for all -+ * condition vars so I am sure performance may be a problem if there are lots -+ * of CVs. -+ */ -+static struct umutex _cv_mutex = { 0, 0, { 0, 0 }, { 0, 0, 0, 0 } }; -+ -+ -+/* -+ * wflags CVWAIT_CHECK_UNPARKING, CVWAIT_ABSTIME, CVWAIT_CLOCKID -+ */ -+abi_long freebsd_cv_wait(abi_ulong target_ucond_addr, -+ abi_ulong target_umtx_addr, struct timespec *ts, int wflags) -+{ -+ abi_long ret; -+ long tid; -+ -+ if (!access_ok(VERIFY_WRITE, target_ucond_addr, -+ sizeof(struct target_ucond))) { -+ return -TARGET_EFAULT; -+ } -+ -+ /* Check the clock ID if needed. */ -+ if ((wflags & TARGET_CVWAIT_CLOCKID) != 0) { -+ struct target_ucond *target_ucond; -+ uint32_t clockid; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_ucond, target_ucond_addr, -+ 0)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(clockid, &target_ucond->c_clockid); -+ unlock_user_struct(target_ucond, target_ucond_addr, 1); -+ if (clockid >= CLOCK_THREAD_CPUTIME_ID) { -+ /* Only HW clock id will work. */ -+ return -TARGET_EINVAL; -+ } -+ } -+ -+ thr_self(&tid); -+ -+ /* Lock the _cv_mutex so we can safely unlock the user mutex */ -+ _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_LOCK, 0, NULL, NULL); -+ -+ /* unlock the user mutex */ -+ ret = freebsd_unlock_umutex(target_umtx_addr, tid); -+ if (is_error(ret)) { -+ _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_UNLOCK, 0, NULL, NULL); -+ return ret; -+ } -+ -+ /* UMTX_OP_CV_WAIT unlocks _cv_mutex */ -+ DEBUG_UMTX("<WAIT> %s: _umtx_op(%p, %d, 0x%x, %p, NULL)\n", -+ __func__, g2h(target_ucond_addr), UMTX_OP_CV_WAIT, wflags, -+ &_cv_mutex); -+ ret = get_errno(_umtx_op(g2h(target_ucond_addr), UMTX_OP_CV_WAIT, wflags, -+ &_cv_mutex, ts)); -+ -+ return ret; -+} -+ -+abi_long freebsd_cv_signal(abi_ulong target_ucond_addr) -+{ -+ abi_long ret; -+ -+ if (!access_ok(VERIFY_WRITE, target_ucond_addr, -+ sizeof(struct target_ucond))) { -+ return -TARGET_EFAULT; -+ } -+ -+ /* Lock the _cv_mutex to prevent a race in do_cv_wait(). */ -+ _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_LOCK, 0, NULL, NULL); -+ DEBUG_UMTX("<WAKE> %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", -+ __func__, g2h(target_ucond_addr), UMTX_OP_CV_SIGNAL, 0); -+ ret = get_errno(_umtx_op(g2h(target_ucond_addr), UMTX_OP_CV_SIGNAL, 0, -+ NULL, NULL)); -+ _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_UNLOCK, 0, NULL, NULL); -+ -+ return ret; -+} -+ -+abi_long freebsd_cv_broadcast(abi_ulong target_ucond_addr) -+{ -+ int ret; -+ -+ if (!access_ok(VERIFY_WRITE, target_ucond_addr, -+ sizeof(struct target_ucond))) { -+ return -TARGET_EFAULT; -+ } -+ -+ /* Lock the _cv_mutex to prevent a race in do_cv_wait(). */ -+ _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_LOCK, 0, NULL, NULL); -+ DEBUG_UMTX("<WAKE> %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", -+ __func__, g2h(target_ucond_addr), UMTX_OP_CV_BROADCAST, 0); -+ ret = get_errno(_umtx_op(g2h(target_ucond_addr), UMTX_OP_CV_BROADCAST, 0, -+ NULL, NULL)); -+ _umtx_op(&_cv_mutex, UMTX_OP_MUTEX_UNLOCK, 0, NULL, NULL); -+ -+ return ret; -+} -+ -+abi_long freebsd_rw_rdlock(abi_ulong target_addr, long fflag, -+ struct timespec *ts) -+{ -+ struct target_urwlock *target_urwlock; -+ uint32_t flags, wrflags; -+ uint32_t state; -+ uint32_t blocked_readers; -+ abi_long ret; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_urwlock, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ -+ __get_user(flags, &target_urwlock->rw_flags); -+ wrflags = TARGET_URWLOCK_WRITE_OWNER; -+ if (!(fflag & TARGET_URWLOCK_PREFER_READER) && -+ !(flags & TARGET_URWLOCK_PREFER_READER)) { -+ wrflags |= TARGET_URWLOCK_WRITE_WAITERS; -+ } -+ for (;;) { -+ __get_user(state, &target_urwlock->rw_state); -+ /* try to lock it */ -+ while (!(state & wrflags)) { -+ if (TARGET_URWLOCK_READER_COUNT(state) == -+ TARGET_URWLOCK_MAX_READERS) { -+ unlock_user_struct(target_urwlock, -+ target_addr, 1); -+ return -TARGET_EAGAIN; -+ } -+ if (tcmpset_32(&target_urwlock->rw_state, state, -+ (state + 1))) { -+ /* The acquired succeeded. */ -+ unlock_user_struct(target_urwlock, -+ target_addr, 1); -+ return 0; -+ } -+ __get_user(state, &target_urwlock->rw_state); -+ } -+ /* set read contention bit */ -+ if (!tcmpset_32(&target_urwlock->rw_state, state, -+ state | TARGET_URWLOCK_READ_WAITERS)) { -+ /* The state has changed. Start over. */ -+ continue; -+ } -+ -+ /* contention bit is set, increase read waiter count */ -+ __get_user(blocked_readers, &target_urwlock->rw_blocked_readers); -+ while (!tcmpset_32(&target_urwlock->rw_blocked_readers, -+ blocked_readers, blocked_readers + 1)) { -+ __get_user(blocked_readers, &target_urwlock->rw_blocked_readers); -+ } -+ -+ while (state & wrflags) { -+ /* sleep/wait */ -+ unlock_user_struct(target_urwlock, target_addr, 1); -+ DEBUG_UMTX("<WAIT> %s: _umtx_op(%p, %d, 0x%x (0x%x), NULL, NULL)\n", -+ __func__, &target_urwlock->rw_state, -+ UMTX_OP_WAIT_UINT, tswap32(state), -+ target_urwlock->rw_state); -+ ret = get_errno(_umtx_op(&target_urwlock->rw_state, -+ UMTX_OP_WAIT_UINT, tswap32(state), NULL, ts)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ if (!lock_user_struct(VERIFY_WRITE, target_urwlock, -+ target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(state, &target_urwlock->rw_state); -+ } -+ -+ /* decrease read waiter count */ -+ __get_user(blocked_readers, &target_urwlock->rw_blocked_readers); -+ while (!tcmpset_32(&target_urwlock->rw_blocked_readers, -+ blocked_readers, (blocked_readers - 1))) { -+ __get_user(blocked_readers, &target_urwlock->rw_blocked_readers); -+ } -+ if (blocked_readers == 1) { -+ /* clear read contention bit */ -+ __get_user(state, &target_urwlock->rw_state); -+ while (!tcmpset_32(&target_urwlock->rw_state, state, -+ state & ~TARGET_URWLOCK_READ_WAITERS)) { -+ __get_user(state, &target_urwlock->rw_state); -+ } -+ } -+ } -+} -+ -+abi_long freebsd_rw_wrlock(abi_ulong target_addr, long fflag, -+ struct timespec *ts) -+{ -+ struct target_urwlock *target_urwlock; -+ uint32_t blocked_readers, blocked_writers; -+ uint32_t state; -+ abi_long ret; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_urwlock, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ blocked_readers = 0; -+ for (;;) { -+ __get_user(state, &target_urwlock->rw_state); -+ while (!(state & TARGET_URWLOCK_WRITE_OWNER) && -+ TARGET_URWLOCK_READER_COUNT(state) == 0) { -+ if (tcmpset_32(&target_urwlock->rw_state, state, -+ state | TARGET_URWLOCK_WRITE_OWNER)) { -+ unlock_user_struct(target_urwlock, target_addr, 1); -+ return 0; -+ } -+ __get_user(state, &target_urwlock->rw_state); -+ } -+ -+ if (!(state & (TARGET_URWLOCK_WRITE_OWNER | -+ TARGET_URWLOCK_WRITE_WAITERS)) && -+ blocked_readers != 0) { -+ DEBUG_UMTX("<WAKE> %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", -+ __func__, &target_urwlock->rw_state, UMTX_OP_WAKE, -+ tswap32(state)); -+ ret = get_errno(_umtx_op(&target_urwlock->rw_state, -+ UMTX_OP_WAKE, INT_MAX, NULL, NULL)); -+ return ret; -+ } -+ /* re-read the state */ -+ __get_user(state, &target_urwlock->rw_state); -+ -+ /* and set TARGET_URWLOCK_WRITE_WAITERS */ -+ while (((state & TARGET_URWLOCK_WRITE_OWNER) || -+ TARGET_URWLOCK_READER_COUNT(state) != 0) && -+ (state & TARGET_URWLOCK_WRITE_WAITERS) == 0) { -+ if (tcmpset_32(&target_urwlock->rw_state, state, -+ state | TARGET_URWLOCK_WRITE_WAITERS)) { -+ break; -+ } -+ __get_user(state, &target_urwlock->rw_state); -+ } -+ -+ /* contention bit is set, increase write waiter count */ -+ __get_user(blocked_writers, &target_urwlock->rw_blocked_writers); -+ while (!tcmpset_32(&target_urwlock->rw_blocked_writers, -+ blocked_writers, blocked_writers + 1)) { -+ __get_user(blocked_writers, &target_urwlock->rw_blocked_writers); -+ } -+ -+ /* sleep */ -+ while ((state & TARGET_URWLOCK_WRITE_OWNER) || -+ (TARGET_URWLOCK_READER_COUNT(state) != 0)) { -+ unlock_user_struct(target_urwlock, target_addr, 1); -+ DEBUG_UMTX("<WAIT> %s: _umtx_op(%p, %d, 0x%x(0x%x), NULL, NULL)\n", -+ __func__, &target_urwlock->rw_blocked_writers, -+ UMTX_OP_WAIT_UINT, tswap32(state), -+ target_urwlock->rw_state); -+ ret = get_errno(_umtx_op(&target_urwlock->rw_state, -+ UMTX_OP_WAIT_UINT, tswap32(state), NULL, ts)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ if (!lock_user_struct(VERIFY_WRITE, target_urwlock, target_addr, -+ 0)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(state, &target_urwlock->rw_state); -+ } -+ -+ /* decrease the write waiter count */ -+ __get_user(blocked_writers, &target_urwlock->rw_blocked_writers); -+ while (!tcmpset_32(&target_urwlock->rw_blocked_writers, -+ blocked_writers, (blocked_writers - 1))) { -+ __get_user(blocked_writers, &target_urwlock->rw_blocked_writers); -+ } -+ if (blocked_writers == 1) { -+ /* clear write contention bit */ -+ __get_user(state, &target_urwlock->rw_state); -+ while (!tcmpset_32(&target_urwlock->rw_state, state, -+ state & ~TARGET_URWLOCK_WRITE_WAITERS)) { -+ __get_user(state, &target_urwlock->rw_state); -+ } -+ __get_user(blocked_readers, &target_urwlock->rw_blocked_readers); -+ } else { -+ blocked_readers = 0; -+ } -+ } -+} -+ -+abi_long freebsd_rw_unlock(abi_ulong target_addr) -+{ -+ struct target_urwlock *target_urwlock; -+ uint32_t flags, state, count = 0; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_urwlock, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ -+ __get_user(flags, &target_urwlock->rw_flags); -+ __get_user(state, &target_urwlock->rw_state); -+ -+ if (state & TARGET_URWLOCK_WRITE_OWNER) { -+ for (;;) { -+ if (!tcmpset_32(&target_urwlock->rw_state, state, -+ state & ~TARGET_URWLOCK_WRITE_OWNER)) { -+ __get_user(state, &target_urwlock->rw_state); -+ if (!(state & TARGET_URWLOCK_WRITE_OWNER)) { -+ unlock_user_struct(target_urwlock, -+ target_addr, 1); -+ return -TARGET_EPERM; -+ } -+ } else { -+ break; -+ } -+ } -+ } else if (TARGET_URWLOCK_READER_COUNT(state) != 0) { -+ /* decrement reader count */ -+ for (;;) { -+ if (!tcmpset_32(&target_urwlock->rw_state, state, (state - 1))) { -+ if (TARGET_URWLOCK_READER_COUNT(state) == 0) { -+ unlock_user_struct(target_urwlock, -+ target_addr, 1); -+ return -TARGET_EPERM; -+ } -+ } else { -+ break; -+ } -+ } -+ } else { -+ unlock_user_struct(target_urwlock, target_addr, 1); -+ return -TARGET_EPERM; -+ } -+ -+ if (!(flags & TARGET_URWLOCK_PREFER_READER)) { -+ if (state & TARGET_URWLOCK_WRITE_WAITERS) { -+ count = 1; -+ } else if (state & TARGET_URWLOCK_READ_WAITERS) { -+ count = INT_MAX; -+ } -+ } else { -+ if (state & TARGET_URWLOCK_READ_WAITERS) { -+ count = INT_MAX; -+ } else if (state & TARGET_URWLOCK_WRITE_WAITERS) { -+ count = 1; -+ } -+ } -+ -+ unlock_user_struct(target_urwlock, target_addr, 1); -+ if (count != 0) { -+ DEBUG_UMTX("<WAKE> %s: _umtx_op(%p, %d, 0x%x, NULL, NULL)\n", -+ __func__, &target_urwlock->rw_state, UMTX_OP_WAKE, count); -+ return get_errno(_umtx_op(&target_urwlock->rw_state, UMTX_OP_WAKE, -+ count, NULL, NULL)); -+ } else { -+ return 0; -+ } -+} -+ -+abi_long do_freebsd_thr_new(CPUArchState *env, -+ abi_ulong target_param_addr, int32_t param_size) -+{ -+ new_freebsd_thread_info_t info; -+ pthread_attr_t attr; -+ TaskState *ts; -+ CPUArchState *new_env; -+ struct target_freebsd_thr_param *target_param; -+ abi_ulong target_rtp_addr; -+ struct target_freebsd_rtprio *target_rtp; -+ struct rtprio *rtp_ptr, rtp; -+ TaskState *parent_ts = (TaskState *)env->opaque; -+ sigset_t sigmask; -+ struct sched_param sched_param; -+ int sched_policy; -+ int ret = 0; -+ -+ memset(&info, 0, sizeof(info)); -+ -+ if (!lock_user_struct(VERIFY_READ, target_param, target_param_addr, 1)) { -+ return -TARGET_EFAULT; -+ } -+ info.param.start_func = tswapal(target_param->start_func); -+ info.param.arg = tswapal(target_param->arg); -+ info.param.stack_base = tswapal(target_param->stack_base); -+ info.param.stack_size = tswapal(target_param->stack_size); -+ info.param.tls_base = tswapal(target_param->tls_base); -+ info.param.tls_size = tswapal(target_param->tls_size); -+ info.param.child_tid = tswapal(target_param->child_tid); -+ info.param.parent_tid = tswapal(target_param->parent_tid); -+ info.param.flags = tswap32(target_param->flags); -+ target_rtp_addr = info.param.rtp = tswapal(target_param->rtp); -+ unlock_user(target_param, target_param_addr, 0); -+ -+ thr_self(&info.parent_tid); -+ -+ if (target_rtp_addr) { -+ if (!lock_user_struct(VERIFY_READ, target_rtp, target_rtp_addr, 1)) { -+ return -TARGET_EFAULT; -+ } -+ rtp.type = tswap16(target_rtp->type); -+ rtp.prio = tswap16(target_rtp->prio); -+ unlock_user(target_rtp, target_rtp_addr, 0); -+ rtp_ptr = &rtp; -+ } else { -+ rtp_ptr = NULL; -+ } -+ -+ /* Create a new CPU instance. */ -+ ts = g_malloc0(sizeof(TaskState)); -+ init_task_state(ts); -+ new_env = cpu_copy(env); -+ //target_cpu_reset(new_env); /* XXX called in cpu_copy()? */ -+ -+ /* init regs that differ from the parent thread. */ -+ target_cpu_clone_regs(new_env, info.param.stack_base); -+ new_env->opaque = ts; -+ ts->bprm = parent_ts->bprm; -+ ts->info = parent_ts->info; -+ -+ target_cpu_set_tls(new_env, info.param.tls_base); -+ -+ /* Grab a mutex so that thread setup appears atomic. */ -+ pthread_mutex_lock(new_freebsd_thread_lock_ptr); -+ -+ pthread_mutex_init(&info.mutex, NULL); -+ pthread_mutex_lock(&info.mutex); -+ pthread_cond_init(&info.cond, NULL); -+ info.env = new_env; -+ -+ /* XXX check return values... */ -+ pthread_attr_init(&attr); -+ pthread_attr_setstacksize(&attr, NEW_STACK_SIZE); -+ pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); -+ if (rtp_ptr) { -+ rtp_to_schedparam(&rtp, &sched_policy, &sched_param); -+ pthread_attr_setschedpolicy(&attr, sched_policy); -+ pthread_attr_setschedparam(&attr, &sched_param); -+ } -+ -+ /* -+ * It is not safe to deliver signals until the child has finished -+ * initializing, so temporarily block all signals. -+ */ -+ sigfillset(&sigmask); -+ sigprocmask(SIG_BLOCK, &sigmask, &info.sigmask); -+ -+ ret = pthread_create(&info.thread, &attr, new_freebsd_thread_start, &info); -+ /* XXX Free new CPU state if thread creation fails. */ -+ -+ sigprocmask(SIG_SETMASK, &info.sigmask, NULL); -+ pthread_attr_destroy(&attr); -+ if (ret == 0) { -+ /* Wait for the child to initialize. */ -+ pthread_cond_wait(&info.cond, &info.mutex); -+ } else { -+ /* Creation of new thread failed. */ -+ ret = -host_to_target_errno(errno); -+ } -+ -+ pthread_mutex_unlock(&info.mutex); -+ pthread_cond_destroy(&info.cond); -+ pthread_mutex_destroy(&info.mutex); -+ pthread_mutex_unlock(new_freebsd_thread_lock_ptr); -+ -+ return ret; -+} -diff --git a/bsd-user/freebsd/os-thread.h b/bsd-user/freebsd/os-thread.h -new file mode 100644 -index 0000000..5e24852 ---- /dev/null -+++ b/bsd-user/freebsd/os-thread.h -@@ -0,0 +1,511 @@ -+/* -+ * FreeBSD thread and user mutex related system call shims -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+#ifndef __FREEBSD_OS_THREAD_H_ -+#define __FREEBSD_OS_THREAD_H_ -+ -+#include <sys/thr.h> -+#include <sys/rtprio.h> -+#include <sys/umtx.h> -+ -+#include "qemu-os.h" -+ -+static abi_long do_freebsd_thr_create(CPUArchState *env, abi_ulong target_ctx, -+ abi_ulong target_id, int flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_create()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_self(abi_ulong target_id) -+{ -+ abi_long ret; -+ long tid; -+ -+ ret = get_errno(thr_self(&tid)); -+ if (!is_error(ret)) { -+ if (put_user_sal(tid, target_id)) { -+ return -TARGET_EFAULT; -+ } -+ } -+ return ret; -+} -+ -+static abi_long do_freebsd_thr_exit(CPUArchState *cpu_env, abi_ulong tid_addr) -+{ -+ CPUState *cpu = ENV_GET_CPU(cpu_env); -+ TaskState *ts; -+ -+ /* -+ * XXX This probably breaks if a signal arrives. -+ * We should disable signals. -+ */ -+ cpu_list_lock(); -+ /* Remove the CPU from the list. */ -+ QTAILQ_REMOVE(&cpus, cpu, node); -+ cpu_list_unlock(); -+ if (tid_addr) { -+ /* Signal target userland that it can free the stack. */ -+ if (!put_user_sal(1, tid_addr)) { -+ freebsd_umtx_wake(tid_addr, INT_MAX); -+ } -+ } -+ thread_cpu = NULL; -+ object_unref(OBJECT(ENV_GET_CPU(cpu_env))); -+ ts = ((CPUArchState *)cpu_env)->opaque; -+ g_free(ts); -+ pthread_exit(NULL); -+ /* Doesn't return */ -+ return 0; -+} -+ -+static abi_long do_freebsd_thr_kill(long id, int sig) -+{ -+ -+ return get_errno(thr_kill(id, sig)); -+} -+ -+static abi_long do_freebsd_thr_kill2(pid_t pid, long id, int sig) -+{ -+ -+ return get_errno(thr_kill2(pid, id, sig)); -+} -+ -+static abi_long do_freebsd_thr_suspend(abi_ulong target_ts) -+{ -+ abi_long ret; -+ struct timespec ts; -+ -+ if (target_ts != 0) { -+ if (t2h_freebsd_timespec(&ts, target_ts)) { -+ return -TARGET_EFAULT; -+ } -+ ret = thr_suspend(&ts); -+ } else { -+ ret = thr_suspend(NULL); -+ } -+ return ret; -+} -+ -+static abi_long do_freebsd_thr_wake(long tid) -+{ -+ -+ return get_errno(thr_wake(tid)); -+} -+ -+static abi_long do_freebsd_thr_set_name(long tid, abi_ulong target_name) -+{ -+ abi_long ret; -+ void *p; -+ -+ p = lock_user_string(target_name); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = thr_set_name(tid, p); -+ unlock_user(p, target_name, 0); -+ -+ return ret; -+} -+ -+static abi_long do_freebsd_rtprio_thread(int function, lwpid_t lwpid, -+ abi_ulong target_addr) -+{ -+ int ret; -+ struct rtprio rtp; -+ -+ ret = t2h_freebsd_rtprio(&rtp, target_addr); -+ if (!is_error(ret)) { -+ ret = get_errno(rtprio_thread(function, lwpid, &rtp)); -+ } -+ if (!is_error(ret)) { -+ ret = h2t_freebsd_rtprio(target_addr, &rtp); -+ } -+ return ret; -+} -+ -+static abi_long do_freebsd_getcontext(void *cpu_env, abi_ulong arg1) -+{ -+ abi_long ret; -+ target_ucontext_t *ucp; -+ sigset_t sigmask; -+ -+ if (arg1 == 0) { -+ return -TARGET_EINVAL; -+ } -+ ret = get_errno(sigprocmask(0, NULL, &sigmask)); -+ if (!is_error(ret)) { -+ ucp = lock_user(VERIFY_WRITE, arg1, sizeof(target_ucontext_t), 0); -+ if (ucp == 0) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_mcontext(cpu_env, &ucp->uc_mcontext, TARGET_MC_GET_CLEAR_RET); -+ host_to_target_sigset(&ucp->uc_sigmask, &sigmask); -+ memset(ucp->__spare__, 0, sizeof(ucp->__spare__)); -+ unlock_user(ucp, arg1, sizeof(target_ucontext_t)); -+ } -+ return ret; -+} -+ -+static abi_long do_freebsd_setcontext(void *cpu_env, abi_ulong arg1) -+{ -+ abi_long ret; -+ target_ucontext_t *ucp; -+ sigset_t sigmask; -+ if (arg1 == 0) { -+ return -TARGET_EINVAL; -+ } -+ ucp = lock_user(VERIFY_READ, arg1, sizeof(target_ucontext_t), 1); -+ if (ucp == 0) { -+ return -TARGET_EFAULT; -+ } -+ ret = set_mcontext(cpu_env, &ucp->uc_mcontext, 0); -+ target_to_host_sigset(&sigmask, &ucp->uc_sigmask); -+ unlock_user(ucp, arg1, sizeof(target_ucontext_t)); -+ if (!is_error(ret)) { -+ (void)sigprocmask(SIG_SETMASK, &sigmask, NULL); -+ } -+ return ret; -+} -+ -+/* swapcontext(2) */ -+static abi_long do_freebsd_swapcontext(void *cpu_env, abi_ulong arg1, -+ abi_ulong arg2) -+{ -+ abi_long ret; -+ target_ucontext_t *ucp; -+ sigset_t sigmask; -+ -+ if (arg1 == 0 || arg2 == 0) { -+ return -TARGET_EINVAL; -+ } -+ /* Save current context in arg1. */ -+ ret = get_errno(sigprocmask(0, NULL, &sigmask)); -+ if (!is_error(ret)) { -+ ucp = lock_user(VERIFY_WRITE, arg1, sizeof(target_ucontext_t), 0); -+ if (ucp == 0) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_mcontext(cpu_env, &ucp->uc_mcontext, TARGET_MC_GET_CLEAR_RET); -+ host_to_target_sigset(&ucp->uc_sigmask, &sigmask); -+ memset(ucp->__spare__, 0, sizeof(ucp->__spare__)); -+ unlock_user(ucp, arg1, sizeof(target_ucontext_t)); -+ } -+ if (is_error(ret)) { -+ return ret; -+ } -+ -+ /* Restore the context in arg2 to the current context. */ -+ ucp = lock_user(VERIFY_READ, arg2, sizeof(target_ucontext_t), 1); -+ if (ucp == 0) { -+ return -TARGET_EFAULT; -+ } -+ ret = set_mcontext(cpu_env, &ucp->uc_mcontext, 0); -+ target_to_host_sigset(&sigmask, &ucp->uc_sigmask); -+ unlock_user(ucp, arg2, sizeof(target_ucontext_t)); -+ if (!is_error(ret)) { -+ (void)sigprocmask(SIG_SETMASK, &sigmask, NULL); -+ } -+ return ret; -+} -+ -+ -+/* undocumented _umtx_lock() */ -+static inline abi_long do_freebsd__umtx_lock(abi_ulong target_addr) -+{ -+ abi_long ret; -+ long tid; -+ -+ ret = get_errno(thr_self(&tid)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ return freebsd_lock_umtx(target_addr, tid, NULL); -+} -+ -+/* undocumented _umtx_unlock() */ -+static inline abi_long do_freebsd__umtx_unlock(abi_ulong target_addr) -+{ -+ abi_long ret; -+ long tid; -+ -+ ret = get_errno(thr_self(&tid)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ return freebsd_unlock_umtx(target_addr, tid); -+} -+ -+/* undocumented _umtx_op(void *obj, int op, u_long val, void *uaddr, -+ void *target_ts); */ -+static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, -+ abi_ulong uaddr, abi_ulong target_ts) -+{ -+ abi_long ret; -+ struct timespec ts; -+ long tid; -+ -+ switch (op) { -+ case TARGET_UMTX_OP_LOCK: -+ ret = get_errno(thr_self(&tid)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ if (target_ts != 0) { -+ if (t2h_freebsd_timespec(&ts, target_ts)) { -+ return -TARGET_EFAULT; -+ } -+ ret = freebsd_lock_umtx(obj, tid, &ts); -+ } else { -+ ret = freebsd_lock_umtx(obj, tid, NULL); -+ } -+ break; -+ -+ case TARGET_UMTX_OP_UNLOCK: -+ ret = get_errno(thr_self(&tid)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ ret = freebsd_unlock_umtx(obj, tid); -+ break; -+ -+ case TARGET_UMTX_OP_WAIT: -+ /* args: obj *, val, ts * */ -+ if (target_ts != 0) { -+ if (t2h_freebsd_timespec(&ts, target_ts)) { -+ return -TARGET_EFAULT; -+ } -+ ret = freebsd_umtx_wait(obj, tswapal(val), &ts); -+ } else { -+ ret = freebsd_umtx_wait(obj, tswapal(val), NULL); -+ } -+ break; -+ -+ case TARGET_UMTX_OP_WAKE: -+ /* args: obj *, nr_wakeup */ -+ ret = freebsd_umtx_wake(obj, val); -+ break; -+ -+ case TARGET_UMTX_OP_MUTEX_LOCK: -+ ret = get_errno(thr_self(&tid)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ if (target_ts) { -+ if (t2h_freebsd_timespec(&ts, target_ts)) { -+ return -TARGET_EFAULT; -+ } -+ ret = freebsd_lock_umutex(obj, tid, &ts, 0); -+ } else { -+ ret = freebsd_lock_umutex(obj, tid, NULL, 0); -+ } -+ break; -+ -+ case TARGET_UMTX_OP_MUTEX_UNLOCK: -+ ret = get_errno(thr_self(&tid)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ ret = freebsd_unlock_umutex(obj, tid); -+ break; -+ -+ case TARGET_UMTX_OP_MUTEX_TRYLOCK: -+ ret = get_errno(thr_self(&tid)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ ret = freebsd_lock_umutex(obj, tid, NULL, TARGET_UMUTEX_TRY); -+ break; -+ -+ case TARGET_UMTX_OP_MUTEX_WAIT: -+ ret = get_errno(thr_self(&tid)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ if (target_ts != 0) { -+ if (t2h_freebsd_timespec(&ts, target_ts)) { -+ return -TARGET_EFAULT; -+ } -+ ret = freebsd_lock_umutex(obj, tid, &ts, TARGET_UMUTEX_WAIT); -+ } else { -+ ret = freebsd_lock_umutex(obj, tid, NULL, TARGET_UMUTEX_WAIT); -+ } -+ break; -+ -+ case TARGET_UMTX_OP_MUTEX_WAKE: -+ /* Don't need to do access_ok(). */ -+ ret = freebsd_umtx_mutex_wake(obj, val); -+ break; -+ -+ case TARGET_UMTX_OP_SET_CEILING: -+ ret = 0; /* XXX quietly ignore these things for now */ -+ break; -+ -+ case TARGET_UMTX_OP_CV_WAIT: -+ /* -+ * Initialization of the struct conv is done by -+ * bzero'ing everything in userland. -+ */ -+ if (target_ts != 0) { -+ if (t2h_freebsd_timespec(&ts, target_ts)) { -+ return -TARGET_EFAULT; -+ } -+ ret = freebsd_cv_wait(obj, uaddr, &ts, val); -+ } else { -+ ret = freebsd_cv_wait(obj, uaddr, NULL, val); -+ } -+ break; -+ -+ case TARGET_UMTX_OP_CV_SIGNAL: -+ /* -+ * XXX -+ * User code may check if c_has_waiters is zero. Other -+ * than that it is assume that user code doesn't do -+ * much with the struct conv fields and is pretty -+ * much opauque to userland. -+ */ -+ ret = freebsd_cv_signal(obj); -+ break; -+ -+ case TARGET_UMTX_OP_CV_BROADCAST: -+ /* -+ * XXX -+ * User code may check if c_has_waiters is zero. Other -+ * than that it is assume that user code doesn't do -+ * much with the struct conv fields and is pretty -+ * much opauque to userland. -+ */ -+ ret = freebsd_cv_broadcast(obj); -+ break; -+ -+ case TARGET_UMTX_OP_WAIT_UINT: -+ if (!access_ok(VERIFY_READ, obj, sizeof(abi_ulong))) { -+ return -TARGET_EFAULT; -+ } -+ if (target_ts != 0) { -+ if (t2h_freebsd_timespec(&ts, target_ts)) { -+ return -TARGET_EFAULT; -+ } -+ ret = freebsd_umtx_wait_uint(obj, tswap32((uint32_t)val), &ts); -+ } else { -+ ret = freebsd_umtx_wait_uint(obj, tswap32((uint32_t)val), NULL); -+ } -+ break; -+ -+ case TARGET_UMTX_OP_WAIT_UINT_PRIVATE: -+ if (!access_ok(VERIFY_READ, obj, sizeof(abi_ulong))) { -+ return -TARGET_EFAULT; -+ } -+ if (target_ts != 0) { -+ if (t2h_freebsd_timespec(&ts, target_ts)) { -+ return -TARGET_EFAULT; -+ } -+ ret = freebsd_umtx_wait_uint_private(obj, tswap32((uint32_t)val), -+ &ts); -+ } else { -+ ret = freebsd_umtx_wait_uint_private(obj, tswap32((uint32_t)val), -+ NULL); -+ } -+ break; -+ -+ case TARGET_UMTX_OP_WAKE_PRIVATE: -+ /* Don't need to do access_ok(). */ -+ ret = freebsd_umtx_wake_private(obj, val); -+ break; -+ -+ case TARGET_UMTX_OP_RW_RDLOCK: -+ if (target_ts != 0) { -+ if (t2h_freebsd_timespec(&ts, target_ts)) { -+ return -TARGET_EFAULT; -+ } -+ ret = freebsd_rw_rdlock(obj, val, &ts); -+ } else { -+ ret = freebsd_rw_rdlock(obj, val, NULL); -+ } -+ break; -+ -+ case TARGET_UMTX_OP_RW_WRLOCK: -+ if (target_ts != 0) { -+ if (t2h_freebsd_timespec(&ts, target_ts)) { -+ return -TARGET_EFAULT; -+ } -+ ret = freebsd_rw_wrlock(obj, val, &ts); -+ } else { -+ ret = freebsd_rw_wrlock(obj, val, NULL); -+ } -+ break; -+ -+ case TARGET_UMTX_OP_RW_UNLOCK: -+ ret = freebsd_rw_unlock(obj); -+ break; -+ -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 -+#ifdef UMTX_OP_MUTEX_WAKE2 -+ case TARGET_UMTX_OP_MUTEX_WAKE2: -+ ret = freebsd_umtx_mutex_wake2(obj, val); -+ break; -+#endif /* UMTX_OP_MUTEX_WAKE2 */ -+ -+#ifdef UMTX_OP_NWAKE_PRIVATE -+ case TARGET_UMTX_OP_NWAKE_PRIVATE: -+ { -+ int i; -+ abi_ulong *uaddr; -+ uint32_t imax = tswap32(INT_MAX); -+ -+ if (!access_ok(VERIFY_READ, obj, val * sizeof(uint32_t))) { -+ return -TARGET_EFAULT; -+ } -+ ret = freebsd_umtx_nwake_private(obj, val); -+ -+ uaddr = (abi_ulong *)g2h(obj); -+ ret = 0; -+ for (i = 0; i < (int32_t)val; i++) { -+ ret = freebsd_umtx_wake_private(tswapal(uaddr[i]), imax); -+ if (is_error(ret)) { -+ break; -+ } -+ } -+ } -+ break; -+#endif /* UMTX_OP_NWAKE_PRIVATE */ -+ -+ case TARGET_UMTX_OP_SEM_WAIT: -+ if (target_ts != 0) { -+ if (t2h_freebsd_timespec(&ts, target_ts)) { -+ return -TARGET_EFAULT; -+ } -+ ret = freebsd_umtx_sem_wait(obj, &ts); -+ } else { -+ ret = freebsd_umtx_sem_wait(obj, NULL); -+ } -+ break; -+ -+ case TARGET_UMTX_OP_SEM_WAKE: -+ /* Don't need to do access_ok(). */ -+ ret = freebsd_umtx_sem_wake(obj, val); -+ break; -+#endif -+ default: -+ return -TARGET_EINVAL; -+ } -+ return ret; -+} -+ -+#endif /* !__FREEBSD_OS_THREAD_H_ */ -diff --git a/bsd-user/freebsd/os-time.c b/bsd-user/freebsd/os-time.c -new file mode 100644 -index 0000000..7ac4397 ---- /dev/null -+++ b/bsd-user/freebsd/os-time.c -@@ -0,0 +1,205 @@ -+/* -+ * FreeBSD time related system call helpers -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#include <time.h> -+#include <sys/timex.h> -+#include <sys/select.h> -+ -+#include "qemu.h" -+#include "qemu-os.h" -+ -+/* -+ * FreeBSD time conversion functions -+ */ -+abi_long t2h_freebsd_timeval(struct timeval *tv, abi_ulong target_tv_addr) -+{ -+ struct target_freebsd_timeval *target_tv; -+ -+ if (!lock_user_struct(VERIFY_READ, target_tv, target_tv_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(tv->tv_sec, &target_tv->tv_sec); -+ __get_user(tv->tv_usec, &target_tv->tv_usec); -+ unlock_user_struct(target_tv, target_tv_addr, 1); -+ -+ return 0; -+} -+ -+abi_long h2t_freebsd_timeval(struct timeval *tv, abi_ulong target_tv_addr) -+{ -+ struct target_freebsd_timeval *target_tv; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_tv, target_tv_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __put_user(tv->tv_sec, &target_tv->tv_sec); -+ __put_user(tv->tv_usec, &target_tv->tv_usec); -+ unlock_user_struct(target_tv, target_tv_addr, 1); -+ -+ return 0; -+} -+ -+abi_long t2h_freebsd_timespec(struct timespec *ts, abi_ulong target_ts_addr) -+{ -+ struct target_freebsd_timespec *target_ts; -+ -+ if (!lock_user_struct(VERIFY_READ, target_ts, target_ts_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(ts->tv_sec, &target_ts->tv_sec); -+ __get_user(ts->tv_nsec, &target_ts->tv_nsec); -+ unlock_user_struct(target_ts, target_ts_addr, 1); -+ -+ return 0; -+} -+ -+abi_long h2t_freebsd_timespec(abi_ulong target_ts_addr, struct timespec *ts) -+{ -+ struct target_freebsd_timespec *target_ts; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_ts, target_ts_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __put_user(ts->tv_sec, &target_ts->tv_sec); -+ __put_user(ts->tv_nsec, &target_ts->tv_nsec); -+ unlock_user_struct(target_ts, target_ts_addr, 1); -+ -+ return 0; -+} -+ -+abi_long t2h_freebsd_timex(struct timex *host_tx, abi_ulong target_tx_addr) -+{ -+ struct target_freebsd_timex *target_tx; -+ -+ if (!lock_user_struct(VERIFY_READ, target_tx, target_tx_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(host_tx->modes, &target_tx->modes); -+ __get_user(host_tx->offset, &target_tx->offset); -+ __get_user(host_tx->freq, &target_tx->freq); -+ __get_user(host_tx->maxerror, &target_tx->maxerror); -+ __get_user(host_tx->esterror, &target_tx->esterror); -+ __get_user(host_tx->status, &target_tx->status); -+ __get_user(host_tx->constant, &target_tx->constant); -+ __get_user(host_tx->precision, &target_tx->precision); -+ __get_user(host_tx->ppsfreq, &target_tx->ppsfreq); -+ __get_user(host_tx->jitter, &target_tx->jitter); -+ __get_user(host_tx->shift, &target_tx->shift); -+ __get_user(host_tx->stabil, &target_tx->stabil); -+ __get_user(host_tx->jitcnt, &target_tx->jitcnt); -+ __get_user(host_tx->calcnt, &target_tx->calcnt); -+ __get_user(host_tx->errcnt, &target_tx->errcnt); -+ __get_user(host_tx->stbcnt, &target_tx->stbcnt); -+ unlock_user_struct(target_tx, target_tx_addr, 1); -+ -+ return 0; -+} -+ -+abi_long h2t_freebsd_ntptimeval(abi_ulong target_ntv_addr, -+ struct ntptimeval *ntv) -+{ -+ struct target_freebsd_ntptimeval *target_ntv; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_ntv, target_ntv_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __put_user(ntv->time.tv_sec, &target_ntv->time.tv_sec); -+ __put_user(ntv->time.tv_nsec, &target_ntv->time.tv_nsec); -+ __put_user(ntv->maxerror, &target_ntv->maxerror); -+ __put_user(ntv->esterror, &target_ntv->esterror); -+ __put_user(ntv->tai, &target_ntv->tai); -+ __put_user(ntv->time_state, &target_ntv->time_state); -+ -+ return 0; -+} -+ -+/* -+ * select(2) fdset copy functions -+ */ -+abi_ulong copy_from_user_fdset(fd_set *fds, abi_ulong target_fds_addr, int n) -+{ -+ int i, nw, j, k; -+ abi_ulong b, *target_fds; -+ -+ nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS; -+ target_fds = lock_user(VERIFY_READ, target_fds_addr, -+ sizeof(abi_ulong) * nw, 1); -+ if (target_fds == NULL) { -+ return -TARGET_EFAULT; -+ } -+ FD_ZERO(fds); -+ k = 0; -+ for (i = 0; i < nw; i++) { -+ /* grab the abi_ulong */ -+ __get_user(b, &target_fds[i]); -+ for (j = 0; j < TARGET_ABI_BITS; j++) { -+ /* check the bit inside the abi_ulong */ -+ if ((b >> j) & 1) { -+ FD_SET(k, fds); -+ } -+ k++; -+ } -+ } -+ unlock_user(target_fds, target_fds_addr, 0); -+ -+ return 0; -+} -+ -+abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr, -+ abi_ulong target_fds_addr, int n) -+{ -+ -+ if (target_fds_addr) { -+ if (copy_from_user_fdset(fds, target_fds_addr, n)) { -+ return -TARGET_EFAULT; -+ } -+ *fds_ptr = fds; -+ } else { -+ *fds_ptr = NULL; -+ } -+ -+ return 0; -+} -+ -+abi_long copy_to_user_fdset(abi_ulong target_fds_addr, const fd_set *fds, int n) -+{ -+ int i, nw, j, k; -+ abi_long v; -+ abi_ulong *target_fds; -+ -+ nw = (n + TARGET_ABI_BITS - 1) / TARGET_ABI_BITS; -+ target_fds = lock_user(VERIFY_WRITE, target_fds_addr, -+ sizeof(abi_ulong) * nw, 0); -+ if (target_fds == NULL) { -+ return -TARGET_EFAULT; -+ } -+ k = 0; -+ for (i = 0; i < nw; i++) { -+ v = 0; -+ for (j = 0; j < TARGET_ABI_BITS; j++) { -+ v |= ((FD_ISSET(k, fds) != 0) << j); -+ k++; -+ } -+ __put_user(v, &target_fds[i]); -+ } -+ unlock_user(target_fds, target_fds_addr, sizeof(abi_ulong) * nw); -+ -+ return 0; -+} -+ -diff --git a/bsd-user/freebsd/os-time.h b/bsd-user/freebsd/os-time.h -new file mode 100644 -index 0000000..c6b5b28 ---- /dev/null -+++ b/bsd-user/freebsd/os-time.h -@@ -0,0 +1,643 @@ -+/* -+ * FreeBSD time related system call shims -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef __FREEBSD_OS_TIME_H_ -+#define __FREEBSD_OS_TIME_H_ -+ -+#include <sys/types.h> -+#include <sys/event.h> -+#include <sys/select.h> -+#include <sys/timex.h> -+#include <signal.h> -+#include <time.h> -+ -+#include "qemu-os.h" -+ -+/* nanosleep(2) */ -+static inline abi_long do_freebsd_nanosleep(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ struct timespec req, rem; -+ -+ ret = t2h_freebsd_timespec(&req, arg1); -+ if (!is_error(ret)) { -+ ret = get_errno(nanosleep(&req, &rem)); -+ if (!is_error(ret) && arg2) { -+ h2t_freebsd_timespec(arg2, &rem); -+ } -+ } -+ -+ return ret; -+} -+ -+/* clock_gettime(2) */ -+static inline abi_long do_freebsd_clock_gettime(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ struct timespec ts; -+ -+ ret = get_errno(clock_gettime(arg1, &ts)); -+ if (!is_error(ret)) { -+ if (h2t_freebsd_timespec(arg2, &ts)) { -+ return -TARGET_EFAULT; -+ } -+ } -+ -+ return ret; -+} -+ -+/* clock_settime(2) */ -+static inline abi_long do_freebsd_clock_settime(abi_long arg1, abi_long arg2) -+{ -+ struct timespec ts; -+ -+ if (t2h_freebsd_timespec(&ts, arg2) != 0) { -+ return -TARGET_EFAULT; -+ } -+ -+ return get_errno(clock_settime(arg1, &ts)); -+} -+ -+/* clock_getres(2) */ -+static inline abi_long do_freebsd_clock_getres(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ struct timespec ts; -+ -+ ret = get_errno(clock_getres(arg1, &ts)); -+ if (!is_error(ret)) { -+ if (h2t_freebsd_timespec(arg2, &ts)) { -+ return -TARGET_EFAULT; -+ } -+ } -+ -+ return ret; -+} -+ -+/* gettimeofday(2) */ -+static inline abi_long do_freebsd_gettimeofday(abi_ulong arg1, abi_ulong arg2) -+{ -+ abi_long ret; -+ struct timeval tv; -+ struct timezone tz, *target_tz; /* XXX */ -+ -+ if (arg2 != 0) { -+ if (!lock_user_struct(VERIFY_READ, target_tz, arg2, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(tz.tz_minuteswest, &target_tz->tz_minuteswest); -+ __get_user(tz.tz_dsttime, &target_tz->tz_dsttime); -+ unlock_user_struct(target_tz, arg2, 1); -+ } -+ ret = get_errno(gettimeofday(&tv, arg2 != 0 ? &tz : NULL)); -+ if (!is_error(ret)) { -+ if (h2t_freebsd_timeval(&tv, arg1)) { -+ return -TARGET_EFAULT; -+ } -+ } -+ -+ return ret; -+} -+ -+/* settimeofday(2) */ -+static inline abi_long do_freebsd_settimeofday(abi_long arg1, abi_long arg2) -+{ -+ struct timeval tv; -+ struct timezone tz, *target_tz; /* XXX */ -+ -+ if (arg2 != 0) { -+ if (!lock_user_struct(VERIFY_READ, target_tz, arg2, 0)) { -+ return -TARGET_EFAULT; -+ } -+ __get_user(tz.tz_minuteswest, &target_tz->tz_minuteswest); -+ __get_user(tz.tz_dsttime, &target_tz->tz_dsttime); -+ unlock_user_struct(target_tz, arg2, 1); -+ } -+ if (t2h_freebsd_timeval(&tv, arg1)) { -+ return -TARGET_EFAULT; -+ } -+ -+ return get_errno(settimeofday(&tv, arg2 != 0 ? &tz : NULL)); -+} -+ -+/* adjtime(2) */ -+static inline abi_long do_freebsd_adjtime(abi_ulong target_delta_addr, -+ abi_ulong target_old_addr) -+{ -+ abi_long ret; -+ struct timeval host_delta, host_old; -+ -+ ret = t2h_freebsd_timeval(&host_delta, target_delta_addr); -+ if (is_error(ret)) { -+ return ret; -+ } -+ -+ if (target_old_addr) { -+ ret = get_errno(adjtime(&host_delta, &host_old)); -+ if (is_error(ret)) { -+ return ret; -+ } -+ ret = h2t_freebsd_timeval(&host_old, target_old_addr); -+ } else { -+ ret = get_errno(adjtime(&host_delta, NULL)); -+ } -+ -+ return ret; -+} -+ -+/* ntp_adjtime(2) */ -+static abi_long do_freebsd_ntp_adjtime(abi_ulong target_tx_addr) -+{ -+ abi_long ret; -+ struct timex host_tx; -+ -+ ret = t2h_freebsd_timex(&host_tx, target_tx_addr); -+ if (ret == 0) { -+ ret = get_errno(ntp_adjtime(&host_tx)); -+ } -+ -+ return ret; -+} -+ -+/* ntp_gettime(2) */ -+static abi_long do_freebsd_ntp_gettime(abi_ulong target_ntv_addr) -+{ -+ abi_long ret; -+ struct ntptimeval host_ntv; -+ -+ ret = get_errno(ntp_gettime(&host_ntv)); -+ if (ret == 0) { -+ ret = h2t_freebsd_ntptimeval(target_ntv_addr, &host_ntv); -+ } -+ -+ return ret; -+} -+ -+ -+/* utimes(2) */ -+static inline abi_long do_freebsd_utimes(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ struct timeval *tvp, tv[2]; -+ -+ if (arg2 != 0) { -+ if (t2h_freebsd_timeval(&tv[0], arg2) || -+ t2h_freebsd_timeval(&tv[1], arg2 + -+ sizeof(struct target_freebsd_timeval))) { -+ return -TARGET_EFAULT; -+ } -+ tvp = tv; -+ } else { -+ tvp = NULL; -+ } -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(utimes(p, tvp)); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* lutimes(2) */ -+static inline abi_long do_freebsd_lutimes(abi_long arg1, abi_long arg2) -+{ -+ abi_long ret; -+ void *p; -+ struct timeval *tvp, tv[2]; -+ -+ if (arg2 != 0) { -+ if (t2h_freebsd_timeval(&tv[0], arg2) || -+ t2h_freebsd_timeval(&tv[1], arg2 + -+ sizeof(struct target_freebsd_timeval))) { -+ return -TARGET_EFAULT; -+ } -+ tvp = tv; -+ } else { -+ tvp = NULL; -+ } -+ p = lock_user_string(arg1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(lutimes(p, tvp)); -+ unlock_user(p, arg1, 0); -+ -+ return ret; -+} -+ -+/* futimes(2) */ -+static inline abi_long do_freebsd_futimes(abi_long arg1, abi_long arg2) -+{ -+ struct timeval *tvp, tv[2]; -+ -+ if (arg2 != 0) { -+ if (t2h_freebsd_timeval(&tv[0], arg2) || -+ t2h_freebsd_timeval(&tv[1], arg2 + -+ sizeof(struct target_freebsd_timeval))) { -+ return -TARGET_EFAULT; -+ } -+ tvp = tv; -+ } else { -+ tvp = NULL; -+ } -+ -+ return get_errno(futimes(arg1, tvp)); -+} -+ -+/* futimesat(2) */ -+static inline abi_long do_freebsd_futimesat(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ abi_long ret; -+ void *p; -+ struct timeval *tvp, tv[2]; -+ -+ if (arg3 != 0) { -+ if (t2h_freebsd_timeval(&tv[0], arg3) || -+ t2h_freebsd_timeval(&tv[1], arg3 + -+ sizeof(struct target_freebsd_timeval))) { -+ return -TARGET_EFAULT; -+ } -+ tvp = tv; -+ } else { -+ tvp = NULL; -+ } -+ -+ p = lock_user_string(arg2); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ ret = get_errno(futimesat(arg1, p, tvp)); -+ unlock_user(p, arg2, 0); -+ -+ return ret; -+} -+ -+/* -+ * undocumented ktimer_create(clockid_t clock_id, struct sigevent *evp, -+ * int *timerid) syscall -+ */ -+static inline abi_long do_freebsd_ktimer_create(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall ktimer_create()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* undocumented ktimer_delete(int timerid) syscall */ -+static inline abi_long do_freebsd_ktimer_delete(abi_long arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall ktimer_delete()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * undocumented ktimer_settime(int timerid, int flags, -+ * const struct itimerspec *value, struct itimerspec *ovalue) syscall -+ */ -+static inline abi_long do_freebsd_ktimer_settime(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4) -+{ -+ -+ qemu_log("qemu: Unsupported syscall ktimer_settime()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * undocumented ktimer_gettime(int timerid, struct itimerspec *value) -+ * syscall -+ */ -+static inline abi_long do_freebsd_ktimer_gettime(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall ktimer_gettime()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * undocumented ktimer_getoverrun(int timerid) syscall -+ */ -+static inline abi_long do_freebsd_ktimer_getoverrun(abi_long arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall ktimer_getoverrun()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* select(2) */ -+static inline abi_long do_freebsd_select(int n, abi_ulong rfd_addr, -+ abi_ulong wfd_addr, abi_ulong efd_addr, abi_ulong target_tv_addr) -+{ -+ fd_set rfds, wfds, efds; -+ fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; -+ struct timeval tv, *tv_ptr; -+ abi_long ret, error; -+ -+ ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n); -+ if (ret != 0) { -+ return ret; -+ } -+ ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n); -+ if (ret != 0) { -+ return ret; -+ } -+ ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n); -+ if (ret != 0) { -+ return ret; -+ } -+ -+ if (target_tv_addr != 0) { -+ if (t2h_freebsd_timeval(&tv, target_tv_addr)) { -+ return -TARGET_EFAULT; -+ } -+ tv_ptr = &tv; -+ } else { -+ tv_ptr = NULL; -+ } -+ -+ ret = get_errno(select(n, rfds_ptr, wfds_ptr, efds_ptr, tv_ptr)); -+ -+ if (!is_error(ret)) { -+ if (rfd_addr != 0) { -+ error = copy_to_user_fdset(rfd_addr, &rfds, n); -+ if (error != 0) { -+ return error; -+ } -+ } -+ if (wfd_addr != 0) { -+ error = copy_to_user_fdset(wfd_addr, &wfds, n); -+ if (error != 0) { -+ return error; -+ } -+ } -+ if (efd_addr != 0) { -+ error = copy_to_user_fdset(efd_addr, &efds, n); -+ if (error != 0) { -+ return error; -+ } -+ } -+ if (target_tv_addr != 0) { -+ error = h2t_freebsd_timeval(&tv, target_tv_addr); -+ if (is_error(error)) { -+ return error; -+ } -+ } -+ } -+ return ret; -+} -+ -+/* pselect(2) */ -+static inline abi_long do_freebsd_pselect(int n, abi_ulong rfd_addr, -+ abi_ulong wfd_addr, abi_ulong efd_addr, abi_ulong ts_addr, -+ abi_ulong set_addr) -+{ -+ fd_set rfds, wfds, efds; -+ fd_set *rfds_ptr, *wfds_ptr, *efds_ptr; -+ sigset_t set, *set_ptr; -+ struct timespec ts, *ts_ptr; -+ void *p; -+ abi_long ret; -+ -+ ret = copy_from_user_fdset_ptr(&rfds, &rfds_ptr, rfd_addr, n); -+ if (is_error(ret)) { -+ return ret; -+ } -+ ret = copy_from_user_fdset_ptr(&wfds, &wfds_ptr, wfd_addr, n); -+ if (is_error(ret)) { -+ return ret; -+ } -+ ret = copy_from_user_fdset_ptr(&efds, &efds_ptr, efd_addr, n); -+ if (is_error(ret)) { -+ return ret; -+ } -+ -+ /* Unlike select(), pselect() uses struct timespec instead of timeval */ -+ if (ts_addr) { -+ if (t2h_freebsd_timespec(&ts, ts_addr)) { -+ return -TARGET_EFAULT; -+ } -+ ts_ptr = &ts; -+ } else { -+ ts_ptr = NULL; -+ } -+ -+ if (set_addr != 0) { -+ p = lock_user(VERIFY_READ, set_addr, sizeof(target_sigset_t), 1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ target_to_host_sigset(&set, p); -+ unlock_user(p, set_addr, 0); -+ set_ptr = &set; -+ } else { -+ set_ptr = NULL; -+ } -+ -+ ret = get_errno(pselect(n, rfds_ptr, wfds_ptr, efds_ptr, ts_ptr, set_ptr)); -+ -+ if (!is_error(ret)) { -+ if (rfd_addr != 0) { -+ ret = copy_to_user_fdset(rfd_addr, &rfds, n); -+ if (is_error(ret)) { -+ return ret; -+ } -+ } -+ if (wfd_addr != 0) { -+ ret = copy_to_user_fdset(wfd_addr, &wfds, n); -+ if (is_error(ret)) { -+ return ret; -+ } -+ } -+ if (efd_addr != 0) { -+ ret = copy_to_user_fdset(efd_addr, &efds, n); -+ if (is_error(ret)) { -+ return ret; -+ } -+ } -+ if (ts_addr != 0) { -+ ret = h2t_freebsd_timespec(ts_addr, &ts); -+ if (is_error(ret)) { -+ return ret; -+ } -+ } -+ } -+ return ret; -+} -+ -+/* kqueue(2) */ -+static inline abi_long do_freebsd_kqueue(void) -+{ -+ -+ return get_errno(kqueue()); -+} -+ -+/* kevent(2) */ -+static inline abi_long do_freebsd_kevent(abi_long arg1, abi_ulong arg2, -+ abi_long arg3, abi_ulong arg4, abi_long arg5, abi_long arg6) -+{ -+ abi_long ret; -+ struct kevent *changelist = NULL, *eventlist = NULL; -+ struct target_freebsd_kevent *target_changelist, *target_eventlist; -+ struct timespec ts; -+ int i; -+ -+ if (arg3 != 0) { -+ target_changelist = lock_user(VERIFY_READ, arg2, -+ sizeof(struct target_freebsd_kevent) * arg3, 1); -+ if (target_changelist == NULL) { -+ return -TARGET_EFAULT; -+ } -+ -+ changelist = alloca(sizeof(struct kevent) * arg3); -+ for (i = 0; i < arg3; i++) { -+ __get_user(changelist[i].ident, &target_changelist[i].ident); -+ __get_user(changelist[i].filter, &target_changelist[i].filter); -+ __get_user(changelist[i].flags, &target_changelist[i].flags); -+ __get_user(changelist[i].fflags, &target_changelist[i].fflags); -+ __get_user(changelist[i].data, &target_changelist[i].data); -+ /* __get_user(changelist[i].udata, &target_changelist[i].udata); */ -+#if TARGET_ABI_BITS == 32 -+ changelist[i].udata = (void *)(uintptr_t)target_changelist[i].udata; -+ tswap32s((uint32_t *)&changelist[i].udata); -+#else -+ changelist[i].udata = (void *)(uintptr_t)target_changelist[i].udata; -+ tswap64s((uint64_t *)&changelist[i].udata); -+#endif -+ } -+ unlock_user(target_changelist, arg2, 0); -+ } -+ -+ if (arg5 != 0) { -+ eventlist = alloca(sizeof(struct kevent) * arg5); -+ } -+ if (arg6 != 0) { -+ if (t2h_freebsd_timespec(&ts, arg6)) { -+ return -TARGET_EFAULT; -+ } -+ } -+ ret = get_errno(kevent(arg1, changelist, arg3, eventlist, arg5, -+ arg6 != 0 ? &ts : NULL)); -+ if (!is_error(ret)) { -+ target_eventlist = lock_user(VERIFY_WRITE, arg4, -+ sizeof(struct target_freebsd_kevent) * arg5, 0); -+ if (target_eventlist == NULL) { -+ return -TARGET_EFAULT; -+ } -+ for (i = 0; i < arg5; i++) { -+ __put_user(eventlist[i].ident, &target_eventlist[i].ident); -+ __put_user(eventlist[i].filter, &target_eventlist[i].filter); -+ __put_user(eventlist[i].flags, &target_eventlist[i].flags); -+ __put_user(eventlist[i].fflags, &target_eventlist[i].fflags); -+ __put_user(eventlist[i].data, &target_eventlist[i].data); -+ /* __put_user(eventlist[i].udata, &target_eventlist[i].udata);*/ -+#if TARGET_ABI_BITS == 32 -+ tswap32s((uint32_t *)&eventlist[i].data); -+ target_eventlist[i].data = (uintptr_t)eventlist[i].data; -+#else -+ tswap64s((uint64_t *)&eventlist[i].data); -+ target_eventlist[i].data = (uintptr_t)eventlist[i].data; -+#endif -+ } -+ unlock_user(target_eventlist, arg4, -+ sizeof(struct target_freebsd_kevent) * arg5); -+ } -+ return ret; -+} -+ -+/* sigtimedwait(2) */ -+static inline abi_long do_freebsd_sigtimedwait(abi_ulong arg1, abi_ulong arg2, -+ abi_ulong arg3) -+{ -+ abi_long ret; -+ void *p; -+ sigset_t set; -+ struct timespec uts, *puts; -+ siginfo_t uinfo; -+ -+ p = lock_user(VERIFY_READ, arg1, sizeof(target_sigset_t), 1); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ target_to_host_sigset(&set, p); -+ unlock_user(p, arg1, 0); -+ if (arg3) { -+ puts = &uts; -+ t2h_freebsd_timespec(puts, arg3); -+ } else { -+ puts = NULL; -+ } -+ ret = get_errno(sigtimedwait(&set, &uinfo, puts)); -+ if (!is_error(ret) && arg2) { -+ p = lock_user(VERIFY_WRITE, arg2, sizeof(target_siginfo_t), 0); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ host_to_target_siginfo(p, &uinfo); -+ unlock_user(p, arg2, sizeof(target_siginfo_t)); -+ } -+ return ret; -+} -+ -+/* setitimer(2) */ -+static inline abi_long do_freebsd_setitimer(int arg1, abi_ulong arg2, abi_ulong arg3) -+{ -+ abi_long ret = 0; -+ struct itimerval value, ovalue, *pvalue; -+ -+ if (arg2) { -+ pvalue = &value; -+ if (t2h_freebsd_timeval(&pvalue->it_interval, arg2) || -+ t2h_freebsd_timeval(&pvalue->it_value, arg2 + sizeof(struct target_freebsd_timeval))) { -+ return -TARGET_EFAULT; -+ } -+ } else { -+ pvalue = NULL; -+ } -+ ret = get_errno(setitimer(arg1, pvalue, &ovalue)); -+ if (!is_error(ret) && arg3) { -+ if (h2t_freebsd_timeval(&ovalue.it_interval, arg3) -+ || h2t_freebsd_timeval(&ovalue.it_value, arg3 + sizeof(struct target_freebsd_timeval))) { -+ return -TARGET_EFAULT; -+ } -+ } -+ return ret; -+} -+ -+/* getitimer(2) */ -+static inline abi_long do_freebsd_getitimer(int arg1, abi_ulong arg2) -+{ -+ abi_long ret = 0; -+ struct itimerval value; -+ -+ ret = get_errno(getitimer(arg1, &value)); -+ if (!is_error(ret) && arg2) { -+ if (h2t_freebsd_timeval(&value.it_interval, arg2) || -+ h2t_freebsd_timeval(&value.it_value, arg2 + sizeof(struct target_freebsd_timeval))) { -+ return -TARGET_EFAULT; -+ } -+ } -+ return ret; -+} -+ -+#endif /* __FREEBSD_OS_TIME_H_ */ -diff --git a/bsd-user/freebsd/qemu-os.h b/bsd-user/freebsd/qemu-os.h -new file mode 100644 -index 0000000..7d79e52 ---- /dev/null -+++ b/bsd-user/freebsd/qemu-os.h -@@ -0,0 +1,79 @@ -+/* -+ * FreeBSD conversion extern declarations -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef _QEMU_OS_H_ -+#define _QEMU_OS_H_ -+ -+#include <sys/types.h> -+#include <sys/acl.h> -+#include <sys/mount.h> -+#include <sys/timex.h> -+#include <sys/rtprio.h> -+#include <sys/select.h> -+#include <sys/socket.h> -+#include <sys/stat.h> -+#include <netinet/in.h> -+ -+#include <time.h> -+ -+/* os-time.c */ -+abi_long t2h_freebsd_timeval(struct timeval *tv, abi_ulong target_tv_addr); -+abi_long h2t_freebsd_timeval(struct timeval *tv, abi_ulong target_tv_addr); -+ -+abi_long t2h_freebsd_timespec(struct timespec *ts, abi_ulong target_ts_addr); -+abi_long h2t_freebsd_timespec(abi_ulong target_ts_addr, struct timespec *ts); -+ -+abi_long t2h_freebsd_timex(struct timex *host_tx, abi_ulong target_tx_addr); -+ -+abi_long h2t_freebsd_ntptimeval(abi_ulong target_ntv_addr, -+ struct ntptimeval *ntv); -+ -+abi_ulong copy_from_user_fdset(fd_set *fds, abi_ulong target_fds_addr, int n); -+abi_ulong copy_from_user_fdset_ptr(fd_set *fds, fd_set **fds_ptr, -+ abi_ulong target_fds_addr, int n); -+abi_long copy_to_user_fdset(abi_ulong target_fds_addr, const fd_set *fds, -+ int n); -+ -+/* os-socket.c */ -+abi_long t2h_freebsd_cmsg(struct msghdr *msgh, -+ struct target_msghdr *target_msgh); -+abi_long h2t_freebsd_cmsg(struct target_msghdr *target_msgh, -+ struct msghdr *msgh); -+ -+/* os-stat.c */ -+abi_long h2t_freebsd_stat(abi_ulong target_addr, struct stat *host_st); -+abi_long h2t_freebsd_nstat(abi_ulong target_addr, struct stat *host_st); -+abi_long t2h_freebsd_fhandle(fhandle_t *host_fh, abi_ulong target_addr); -+abi_long h2t_freebsd_fhandle(abi_ulong target_addr, fhandle_t *host_fh); -+abi_long h2t_freebsd_statfs(abi_ulong target_addr, struct statfs *host_statfs); -+abi_long target_to_host_fcntl_cmd(int cmd); -+ -+/* os-thread.c */ -+abi_long t2h_freebsd_rtprio(struct rtprio *host_rtp, abi_ulong target_addr); -+abi_long h2t_freebsd_rtprio(abi_ulong target_addr, struct rtprio *host_rtp); -+abi_long do_freebsd_thr_new(CPUArchState *env, abi_ulong target_param_addr, -+ int32_t param_size); -+ -+/* os-extattr.c */ -+struct acl; -+abi_long t2h_freebsd_acl(struct acl *host_acl, abi_ulong target_addr); -+abi_long h2t_freebsd_acl(abi_ulong target_addr, struct acl *host_acl); -+abi_long t2h_freebsd_acl_type(acl_type_t *host_type, abi_long target_type); -+ -+#endif /* !_QEMU_OS_H_ */ -diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list -index 1edf412..ae2a4a3 100644 ---- a/bsd-user/freebsd/strace.list -+++ b/bsd-user/freebsd/strace.list -@@ -1,7 +1,38 @@ -+/* -+ * FreeBSD strace list -+ * -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+{ TARGET_FREEBSD_NR___acl_aclcheck_fd, "__acl_get_fd", "%s(%d, %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_aclcheck_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_aclcheck_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_delete_fd, "__acl_delete_fd", "%s(%d, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_delete_file, "__acl_delete_file", "%s(\"%s\", %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_delete_link, "__acl_delete_link", "%s(\"%s\", %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_get_fd, "__acl_get_fd", "%s(\"%s\", %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_get_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_get_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_set_fd, "__acl_get_fd", "%s(\"%s\", %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_set_file, "__acl_get_file", "%s(\"%s\", %d, %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR___acl_set_link, "__acl_get_link", "%s(\"%s\", %d, %#x)", NULL, NULL }, - { TARGET_FREEBSD_NR___getcwd, "__getcwd", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR___semctl, "__semctl", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR___syscall, "__syscall", NULL, NULL, NULL }, --{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, print_sysctl, NULL }, -+{ TARGET_FREEBSD_NR__umtx_op, "_umtx_op", "%s(%#x, %d, %d, %#x, %#x)", NULL, NULL }, - { TARGET_FREEBSD_NR_accept, "accept", "%s(%d,%#x,%#x)", NULL, NULL }, - { TARGET_FREEBSD_NR_access, "access", "%s(\"%s\",%#o)", NULL, NULL }, - { TARGET_FREEBSD_NR_acct, "acct", NULL, NULL, NULL }, -@@ -20,24 +51,41 @@ - { TARGET_FREEBSD_NR_connect, "connect", "%s(%d,%#x,%d)", NULL, NULL }, - { TARGET_FREEBSD_NR_dup, "dup", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_dup2, "dup2", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_eaccess, "eaccess", "%s(%s,%#x)", NULL, NULL }, - { TARGET_FREEBSD_NR_execve, "execve", NULL, print_execve, NULL }, - { TARGET_FREEBSD_NR_exit, "exit", "%s(%d)\n", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattrctl, "extattrctl", "%s(\"%s\", %d, \"%s\", %d, \"%s\"", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_delete_fd, "extattr_delete_fd", "%s(%d, %d, \"%s\")", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_delete_file, "extattr_delete_file", "%s(\"%s\", %d, \"%s\")", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_delete_link, "extattr_delete_link", "%s(\"%s\", %d, \"%s\")", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_get_fd, "extattr_get_fd", "%s(%d, %d, \"%s\", %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_get_file, "extattr_get_file", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_get_file, "extattr_get_link", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_list_fd, "extattr_list_fd", "%s(%d, %d, %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_list_file, "extattr_list_file", "%s(\"%s\", %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_list_link, "extattr_list_link", "%s(\"%s\", %d, %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_set_fd, "extattr_set_fd", "%s(%d, %d, \"%s\", %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_set_file, "extattr_set_file", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_extattr_set_link, "extattr_set_link", "%s(\"%s\", %d, \"%s\", %#x, %d)", NULL, NULL }, - { TARGET_FREEBSD_NR_fchdir, "fchdir", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_fchflags, "fchflags", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_fchmod, "fchmod", "%s(%d,%#o)", NULL, NULL }, --{ TARGET_FREEBSD_NR_fchown, "fchown", "%s(\"%s\",%d,%d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_fchown, "fchown", "%s(%d,%d,%d)", NULL, NULL }, - { TARGET_FREEBSD_NR_fcntl, "fcntl", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_fexecve, "fexecve", NULL, print_execve, NULL }, - { TARGET_FREEBSD_NR_fhopen, "fhopen", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_fhstat, "fhstat", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_fhstatfs, "fhstatfs", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_flock, "flock", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_fork, "fork", "%s()", NULL, NULL }, - { TARGET_FREEBSD_NR_fpathconf, "fpathconf", NULL, NULL, NULL }, --{ TARGET_FREEBSD_NR_fstat, "fstat", "%s(%d,%p)", NULL, NULL }, --{ TARGET_FREEBSD_NR_fstatfs, "fstatfs", "%s(%d,%p)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_fstat, "fstat", "%s(%d,%#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_fstatat, "fstatat", "%s(%d,\"%s\", %#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_fstatfs, "fstatfs", "%s(%d,%#x)", NULL, NULL }, - { TARGET_FREEBSD_NR_fsync, "fsync", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_ftruncate, "ftruncate", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_futimes, "futimes", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_getcontext, "getcontext", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_getdirentries, "getdirentries", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_freebsd6_mmap, "freebsd6_mmap", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_getegid, "getegid", "%s()", NULL, NULL }, -@@ -63,7 +111,7 @@ - { TARGET_FREEBSD_NR_getsockopt, "getsockopt", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_gettimeofday, "gettimeofday", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_getuid, "getuid", "%s()", NULL, NULL }, --{ TARGET_FREEBSD_NR_ioctl, "ioctl", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_ioctl, "ioctl", NULL, print_ioctl, NULL }, - { TARGET_FREEBSD_NR_issetugid, "issetugid", "%s()", NULL, NULL }, - { TARGET_FREEBSD_NR_kevent, "kevent", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_kill, "kill", NULL, NULL, NULL }, -@@ -72,6 +120,7 @@ - { TARGET_FREEBSD_NR_lchown, "lchown", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_link, "link", "%s(\"%s\",\"%s\")", NULL, NULL }, - { TARGET_FREEBSD_NR_listen, "listen", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_lpathconf, "lpathconf", "%s(\"%s\", %d)", NULL, NULL }, - { TARGET_FREEBSD_NR_lseek, "lseek", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_lstat, "lstat", "%s(\"%s\",%p)", NULL, NULL }, - { TARGET_FREEBSD_NR_madvise, "madvise", NULL, NULL, NULL }, -@@ -96,7 +145,9 @@ - { TARGET_FREEBSD_NR_nanosleep, "nanosleep", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_nfssvc, "nfssvc", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_open, "open", "%s(\"%s\",%#x,%#o)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_openat, "openat", "%s(%d, \"%s\",%#x,%#o)", NULL, NULL }, - { TARGET_FREEBSD_NR_pathconf, "pathconf", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_pathconf, "pathconf", "%s(\"%s\", %d)", NULL, NULL }, - { TARGET_FREEBSD_NR_pipe, "pipe", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_poll, "poll", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_pread, "pread", NULL, NULL, NULL }, -@@ -116,6 +167,7 @@ - { TARGET_FREEBSD_NR_revoke, "revoke", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_rfork, "rfork", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_rmdir, "rmdir", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_rtprio_thread, "rtprio_thread", "%s(%d, %d, %p)", NULL, NULL }, - { TARGET_FREEBSD_NR_sbrk, "sbrk", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_sched_yield, "sched_yield", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_select, "select", NULL, NULL, NULL }, -@@ -123,6 +175,7 @@ - { TARGET_FREEBSD_NR_semop, "semop", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_sendmsg, "sendmsg", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_sendto, "sendto", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_setcontext, "setcontext", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_setegid, "setegid", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_seteuid, "seteuid", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_setgid, "setgid", NULL, NULL, NULL }, -@@ -151,15 +204,24 @@ - { TARGET_FREEBSD_NR_sigprocmask, "sigprocmask", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_sigreturn, "sigreturn", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_sigsuspend, "sigsuspend", NULL, NULL, NULL }, --{ TARGET_FREEBSD_NR_socket, "socket", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_socket, "socket", "%s(%d,%d,%d)", NULL, NULL }, - { TARGET_FREEBSD_NR_socketpair, "socketpair", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_sstk, "sstk", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_stat, "stat", "%s(\"%s\",%p)", NULL, NULL }, - { TARGET_FREEBSD_NR_statfs, "statfs", "%s(\"%s\",%p)", NULL, NULL }, - { TARGET_FREEBSD_NR_symlink, "symlink", "%s(\"%s\",\"%s\")", NULL, NULL }, - { TARGET_FREEBSD_NR_sync, "sync", NULL, NULL, NULL }, --{ TARGET_FREEBSD_NR_sysarch, "sysarch", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_sysarch, "sysarch", NULL, print_sysarch, NULL }, - { TARGET_FREEBSD_NR_syscall, "syscall", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_create, "thr_create", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_exit, "thr_exit", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_kill, "thr_kill", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_kill2, "thr_kill2", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_new, "thr_new", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_self, "thr_self", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_set_name, "thr_set_name", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_suspend, "thr_suspend", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_thr_wake, "thr_wake", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_truncate, "truncate", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_umask, "umask", "%s(%#o)", NULL, NULL }, - { TARGET_FREEBSD_NR_unlink, "unlink", "%s(\"%s\")", NULL, NULL }, -@@ -169,3 +231,4 @@ - { TARGET_FREEBSD_NR_wait4, "wait4", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_write, "write", "%s(%d,%#x,%d)", NULL, NULL }, - { TARGET_FREEBSD_NR_writev, "writev", "%s(%d,%p,%#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_posix_openpt, "posix_openpt", "%s(%d)", NULL, NULL }, -diff --git a/bsd-user/freebsd/syscall_nr.h b/bsd-user/freebsd/syscall_nr.h -index 36336ab..d849024 100644 ---- a/bsd-user/freebsd/syscall_nr.h -+++ b/bsd-user/freebsd/syscall_nr.h -@@ -1,373 +1,450 @@ - /* - * System call numbers. - * -- * $FreeBSD: src/sys/sys/syscall.h,v 1.224 2008/08/24 21:23:08 rwatson Exp $ -- * created from FreeBSD: head/sys/kern/syscalls.master 182123 2008-08-24 21:20:35Z rwatson -+ * created from FreeBSD: releng/9.1/sys/kern/syscalls.master 229723 -+ * 2012-01-06 19:29:16Z jhb - */ - --#define TARGET_FREEBSD_NR_syscall 0 --#define TARGET_FREEBSD_NR_exit 1 --#define TARGET_FREEBSD_NR_fork 2 --#define TARGET_FREEBSD_NR_read 3 --#define TARGET_FREEBSD_NR_write 4 --#define TARGET_FREEBSD_NR_open 5 --#define TARGET_FREEBSD_NR_close 6 --#define TARGET_FREEBSD_NR_wait4 7 --#define TARGET_FREEBSD_NR_link 9 --#define TARGET_FREEBSD_NR_unlink 10 --#define TARGET_FREEBSD_NR_chdir 12 --#define TARGET_FREEBSD_NR_fchdir 13 --#define TARGET_FREEBSD_NR_mknod 14 --#define TARGET_FREEBSD_NR_chmod 15 --#define TARGET_FREEBSD_NR_chown 16 --#define TARGET_FREEBSD_NR_break 17 --#define TARGET_FREEBSD_NR_freebsd4_getfsstat 18 --#define TARGET_FREEBSD_NR_getpid 20 --#define TARGET_FREEBSD_NR_mount 21 --#define TARGET_FREEBSD_NR_unmount 22 --#define TARGET_FREEBSD_NR_setuid 23 --#define TARGET_FREEBSD_NR_getuid 24 --#define TARGET_FREEBSD_NR_geteuid 25 --#define TARGET_FREEBSD_NR_ptrace 26 --#define TARGET_FREEBSD_NR_recvmsg 27 --#define TARGET_FREEBSD_NR_sendmsg 28 --#define TARGET_FREEBSD_NR_recvfrom 29 --#define TARGET_FREEBSD_NR_accept 30 --#define TARGET_FREEBSD_NR_getpeername 31 --#define TARGET_FREEBSD_NR_getsockname 32 --#define TARGET_FREEBSD_NR_access 33 --#define TARGET_FREEBSD_NR_chflags 34 --#define TARGET_FREEBSD_NR_fchflags 35 --#define TARGET_FREEBSD_NR_sync 36 --#define TARGET_FREEBSD_NR_kill 37 --#define TARGET_FREEBSD_NR_getppid 39 --#define TARGET_FREEBSD_NR_dup 41 --#define TARGET_FREEBSD_NR_pipe 42 --#define TARGET_FREEBSD_NR_getegid 43 --#define TARGET_FREEBSD_NR_profil 44 --#define TARGET_FREEBSD_NR_ktrace 45 --#define TARGET_FREEBSD_NR_getgid 47 --#define TARGET_FREEBSD_NR_getlogin 49 --#define TARGET_FREEBSD_NR_setlogin 50 --#define TARGET_FREEBSD_NR_acct 51 --#define TARGET_FREEBSD_NR_sigaltstack 53 --#define TARGET_FREEBSD_NR_ioctl 54 --#define TARGET_FREEBSD_NR_reboot 55 --#define TARGET_FREEBSD_NR_revoke 56 --#define TARGET_FREEBSD_NR_symlink 57 --#define TARGET_FREEBSD_NR_readlink 58 --#define TARGET_FREEBSD_NR_execve 59 --#define TARGET_FREEBSD_NR_umask 60 --#define TARGET_FREEBSD_NR_chroot 61 --#define TARGET_FREEBSD_NR_msync 65 --#define TARGET_FREEBSD_NR_vfork 66 --#define TARGET_FREEBSD_NR_sbrk 69 --#define TARGET_FREEBSD_NR_sstk 70 --#define TARGET_FREEBSD_NR_vadvise 72 --#define TARGET_FREEBSD_NR_munmap 73 --#define TARGET_FREEBSD_NR_mprotect 74 --#define TARGET_FREEBSD_NR_madvise 75 --#define TARGET_FREEBSD_NR_mincore 78 --#define TARGET_FREEBSD_NR_getgroups 79 --#define TARGET_FREEBSD_NR_setgroups 80 --#define TARGET_FREEBSD_NR_getpgrp 81 --#define TARGET_FREEBSD_NR_setpgid 82 --#define TARGET_FREEBSD_NR_setitimer 83 --#define TARGET_FREEBSD_NR_swapon 85 --#define TARGET_FREEBSD_NR_getitimer 86 --#define TARGET_FREEBSD_NR_getdtablesize 89 --#define TARGET_FREEBSD_NR_dup2 90 --#define TARGET_FREEBSD_NR_fcntl 92 --#define TARGET_FREEBSD_NR_select 93 --#define TARGET_FREEBSD_NR_fsync 95 --#define TARGET_FREEBSD_NR_setpriority 96 --#define TARGET_FREEBSD_NR_socket 97 --#define TARGET_FREEBSD_NR_connect 98 --#define TARGET_FREEBSD_NR_getpriority 100 --#define TARGET_FREEBSD_NR_bind 104 --#define TARGET_FREEBSD_NR_setsockopt 105 --#define TARGET_FREEBSD_NR_listen 106 --#define TARGET_FREEBSD_NR_gettimeofday 116 --#define TARGET_FREEBSD_NR_getrusage 117 --#define TARGET_FREEBSD_NR_getsockopt 118 --#define TARGET_FREEBSD_NR_readv 120 --#define TARGET_FREEBSD_NR_writev 121 --#define TARGET_FREEBSD_NR_settimeofday 122 --#define TARGET_FREEBSD_NR_fchown 123 --#define TARGET_FREEBSD_NR_fchmod 124 --#define TARGET_FREEBSD_NR_setreuid 126 --#define TARGET_FREEBSD_NR_setregid 127 --#define TARGET_FREEBSD_NR_rename 128 --#define TARGET_FREEBSD_NR_flock 131 --#define TARGET_FREEBSD_NR_mkfifo 132 --#define TARGET_FREEBSD_NR_sendto 133 --#define TARGET_FREEBSD_NR_shutdown 134 --#define TARGET_FREEBSD_NR_socketpair 135 --#define TARGET_FREEBSD_NR_mkdir 136 --#define TARGET_FREEBSD_NR_rmdir 137 --#define TARGET_FREEBSD_NR_utimes 138 --#define TARGET_FREEBSD_NR_adjtime 140 --#define TARGET_FREEBSD_NR_setsid 147 --#define TARGET_FREEBSD_NR_quotactl 148 --#define TARGET_FREEBSD_NR_nlm_syscall 154 --#define TARGET_FREEBSD_NR_nfssvc 155 --#define TARGET_FREEBSD_NR_freebsd4_statfs 157 --#define TARGET_FREEBSD_NR_freebsd4_fstatfs 158 --#define TARGET_FREEBSD_NR_lgetfh 160 --#define TARGET_FREEBSD_NR_getfh 161 --#define TARGET_FREEBSD_NR_getdomainname 162 --#define TARGET_FREEBSD_NR_setdomainname 163 --#define TARGET_FREEBSD_NR_uname 164 --#define TARGET_FREEBSD_NR_sysarch 165 --#define TARGET_FREEBSD_NR_rtprio 166 --#define TARGET_FREEBSD_NR_semsys 169 --#define TARGET_FREEBSD_NR_msgsys 170 --#define TARGET_FREEBSD_NR_shmsys 171 --#define TARGET_FREEBSD_NR_freebsd6_pread 173 --#define TARGET_FREEBSD_NR_freebsd6_pwrite 174 --#define TARGET_FREEBSD_NR_setfib 175 --#define TARGET_FREEBSD_NR_ntp_adjtime 176 --#define TARGET_FREEBSD_NR_setgid 181 --#define TARGET_FREEBSD_NR_setegid 182 --#define TARGET_FREEBSD_NR_seteuid 183 --#define TARGET_FREEBSD_NR_stat 188 --#define TARGET_FREEBSD_NR_fstat 189 --#define TARGET_FREEBSD_NR_lstat 190 --#define TARGET_FREEBSD_NR_pathconf 191 --#define TARGET_FREEBSD_NR_fpathconf 192 --#define TARGET_FREEBSD_NR_getrlimit 194 --#define TARGET_FREEBSD_NR_setrlimit 195 --#define TARGET_FREEBSD_NR_getdirentries 196 --#define TARGET_FREEBSD_NR_freebsd6_mmap 197 --#define TARGET_FREEBSD_NR___syscall 198 --#define TARGET_FREEBSD_NR_freebsd6_lseek 199 --#define TARGET_FREEBSD_NR_freebsd6_truncate 200 --#define TARGET_FREEBSD_NR_freebsd6_ftruncate 201 --#define TARGET_FREEBSD_NR___sysctl 202 --#define TARGET_FREEBSD_NR_mlock 203 --#define TARGET_FREEBSD_NR_munlock 204 --#define TARGET_FREEBSD_NR_undelete 205 --#define TARGET_FREEBSD_NR_futimes 206 --#define TARGET_FREEBSD_NR_getpgid 207 --#define TARGET_FREEBSD_NR_poll 209 --#define TARGET_FREEBSD_NR___semctl 220 --#define TARGET_FREEBSD_NR_semget 221 --#define TARGET_FREEBSD_NR_semop 222 --#define TARGET_FREEBSD_NR_msgctl 224 --#define TARGET_FREEBSD_NR_msgget 225 --#define TARGET_FREEBSD_NR_msgsnd 226 --#define TARGET_FREEBSD_NR_msgrcv 227 --#define TARGET_FREEBSD_NR_shmat 228 --#define TARGET_FREEBSD_NR_shmctl 229 --#define TARGET_FREEBSD_NR_shmdt 230 --#define TARGET_FREEBSD_NR_shmget 231 --#define TARGET_FREEBSD_NR_clock_gettime 232 --#define TARGET_FREEBSD_NR_clock_settime 233 --#define TARGET_FREEBSD_NR_clock_getres 234 --#define TARGET_FREEBSD_NR_ktimer_create 235 --#define TARGET_FREEBSD_NR_ktimer_delete 236 --#define TARGET_FREEBSD_NR_ktimer_settime 237 --#define TARGET_FREEBSD_NR_ktimer_gettime 238 --#define TARGET_FREEBSD_NR_ktimer_getoverrun 239 --#define TARGET_FREEBSD_NR_nanosleep 240 --#define TARGET_FREEBSD_NR_ntp_gettime 248 --#define TARGET_FREEBSD_NR_minherit 250 --#define TARGET_FREEBSD_NR_rfork 251 --#define TARGET_FREEBSD_NR_openbsd_poll 252 --#define TARGET_FREEBSD_NR_issetugid 253 --#define TARGET_FREEBSD_NR_lchown 254 --#define TARGET_FREEBSD_NR_aio_read 255 --#define TARGET_FREEBSD_NR_aio_write 256 --#define TARGET_FREEBSD_NR_lio_listio 257 --#define TARGET_FREEBSD_NR_getdents 272 --#define TARGET_FREEBSD_NR_lchmod 274 --#define TARGET_FREEBSD_NR_netbsd_lchown 275 --#define TARGET_FREEBSD_NR_lutimes 276 --#define TARGET_FREEBSD_NR_netbsd_msync 277 --#define TARGET_FREEBSD_NR_nstat 278 --#define TARGET_FREEBSD_NR_nfstat 279 --#define TARGET_FREEBSD_NR_nlstat 280 --#define TARGET_FREEBSD_NR_preadv 289 --#define TARGET_FREEBSD_NR_pwritev 290 --#define TARGET_FREEBSD_NR_freebsd4_fhstatfs 297 --#define TARGET_FREEBSD_NR_fhopen 298 --#define TARGET_FREEBSD_NR_fhstat 299 --#define TARGET_FREEBSD_NR_modnext 300 --#define TARGET_FREEBSD_NR_modstat 301 --#define TARGET_FREEBSD_NR_modfnext 302 --#define TARGET_FREEBSD_NR_modfind 303 --#define TARGET_FREEBSD_NR_kldload 304 --#define TARGET_FREEBSD_NR_kldunload 305 --#define TARGET_FREEBSD_NR_kldfind 306 --#define TARGET_FREEBSD_NR_kldnext 307 --#define TARGET_FREEBSD_NR_kldstat 308 --#define TARGET_FREEBSD_NR_kldfirstmod 309 --#define TARGET_FREEBSD_NR_getsid 310 --#define TARGET_FREEBSD_NR_setresuid 311 --#define TARGET_FREEBSD_NR_setresgid 312 --#define TARGET_FREEBSD_NR_aio_return 314 --#define TARGET_FREEBSD_NR_aio_suspend 315 --#define TARGET_FREEBSD_NR_aio_cancel 316 --#define TARGET_FREEBSD_NR_aio_error 317 --#define TARGET_FREEBSD_NR_oaio_read 318 --#define TARGET_FREEBSD_NR_oaio_write 319 --#define TARGET_FREEBSD_NR_olio_listio 320 --#define TARGET_FREEBSD_NR_yield 321 --#define TARGET_FREEBSD_NR_mlockall 324 --#define TARGET_FREEBSD_NR_munlockall 325 --#define TARGET_FREEBSD_NR___getcwd 326 --#define TARGET_FREEBSD_NR_sched_setparam 327 --#define TARGET_FREEBSD_NR_sched_getparam 328 --#define TARGET_FREEBSD_NR_sched_setscheduler 329 --#define TARGET_FREEBSD_NR_sched_getscheduler 330 --#define TARGET_FREEBSD_NR_sched_yield 331 --#define TARGET_FREEBSD_NR_sched_get_priority_max 332 --#define TARGET_FREEBSD_NR_sched_get_priority_min 333 --#define TARGET_FREEBSD_NR_sched_rr_get_interval 334 --#define TARGET_FREEBSD_NR_utrace 335 --#define TARGET_FREEBSD_NR_freebsd4_sendfile 336 --#define TARGET_FREEBSD_NR_kldsym 337 --#define TARGET_FREEBSD_NR_jail 338 --#define TARGET_FREEBSD_NR_sigprocmask 340 --#define TARGET_FREEBSD_NR_sigsuspend 341 --#define TARGET_FREEBSD_NR_freebsd4_sigaction 342 --#define TARGET_FREEBSD_NR_sigpending 343 --#define TARGET_FREEBSD_NR_freebsd4_sigreturn 344 --#define TARGET_FREEBSD_NR_sigtimedwait 345 --#define TARGET_FREEBSD_NR_sigwaitinfo 346 --#define TARGET_FREEBSD_NR___acl_get_file 347 --#define TARGET_FREEBSD_NR___acl_set_file 348 --#define TARGET_FREEBSD_NR___acl_get_fd 349 --#define TARGET_FREEBSD_NR___acl_set_fd 350 --#define TARGET_FREEBSD_NR___acl_delete_file 351 --#define TARGET_FREEBSD_NR___acl_delete_fd 352 --#define TARGET_FREEBSD_NR___acl_aclcheck_file 353 --#define TARGET_FREEBSD_NR___acl_aclcheck_fd 354 --#define TARGET_FREEBSD_NR_extattrctl 355 --#define TARGET_FREEBSD_NR_extattr_set_file 356 --#define TARGET_FREEBSD_NR_extattr_get_file 357 --#define TARGET_FREEBSD_NR_extattr_delete_file 358 --#define TARGET_FREEBSD_NR_aio_waitcomplete 359 --#define TARGET_FREEBSD_NR_getresuid 360 --#define TARGET_FREEBSD_NR_getresgid 361 --#define TARGET_FREEBSD_NR_kqueue 362 --#define TARGET_FREEBSD_NR_kevent 363 --#define TARGET_FREEBSD_NR_extattr_set_fd 371 --#define TARGET_FREEBSD_NR_extattr_get_fd 372 --#define TARGET_FREEBSD_NR_extattr_delete_fd 373 --#define TARGET_FREEBSD_NR___setugid 374 --#define TARGET_FREEBSD_NR_nfsclnt 375 --#define TARGET_FREEBSD_NR_eaccess 376 --#define TARGET_FREEBSD_NR_nmount 378 --#define TARGET_FREEBSD_NR___mac_get_proc 384 --#define TARGET_FREEBSD_NR___mac_set_proc 385 --#define TARGET_FREEBSD_NR___mac_get_fd 386 --#define TARGET_FREEBSD_NR___mac_get_file 387 --#define TARGET_FREEBSD_NR___mac_set_fd 388 --#define TARGET_FREEBSD_NR___mac_set_file 389 --#define TARGET_FREEBSD_NR_kenv 390 --#define TARGET_FREEBSD_NR_lchflags 391 --#define TARGET_FREEBSD_NR_uuidgen 392 --#define TARGET_FREEBSD_NR_sendfile 393 --#define TARGET_FREEBSD_NR_mac_syscall 394 --#define TARGET_FREEBSD_NR_getfsstat 395 --#define TARGET_FREEBSD_NR_statfs 396 --#define TARGET_FREEBSD_NR_fstatfs 397 --#define TARGET_FREEBSD_NR_fhstatfs 398 --#define TARGET_FREEBSD_NR_ksem_close 400 --#define TARGET_FREEBSD_NR_ksem_post 401 --#define TARGET_FREEBSD_NR_ksem_wait 402 --#define TARGET_FREEBSD_NR_ksem_trywait 403 --#define TARGET_FREEBSD_NR_ksem_init 404 --#define TARGET_FREEBSD_NR_ksem_open 405 --#define TARGET_FREEBSD_NR_ksem_unlink 406 --#define TARGET_FREEBSD_NR_ksem_getvalue 407 --#define TARGET_FREEBSD_NR_ksem_destroy 408 --#define TARGET_FREEBSD_NR___mac_get_pid 409 --#define TARGET_FREEBSD_NR___mac_get_link 410 --#define TARGET_FREEBSD_NR___mac_set_link 411 --#define TARGET_FREEBSD_NR_extattr_set_link 412 --#define TARGET_FREEBSD_NR_extattr_get_link 413 --#define TARGET_FREEBSD_NR_extattr_delete_link 414 --#define TARGET_FREEBSD_NR___mac_execve 415 --#define TARGET_FREEBSD_NR_sigaction 416 --#define TARGET_FREEBSD_NR_sigreturn 417 --#define TARGET_FREEBSD_NR_getcontext 421 --#define TARGET_FREEBSD_NR_setcontext 422 --#define TARGET_FREEBSD_NR_swapcontext 423 --#define TARGET_FREEBSD_NR_swapoff 424 --#define TARGET_FREEBSD_NR___acl_get_link 425 --#define TARGET_FREEBSD_NR___acl_set_link 426 --#define TARGET_FREEBSD_NR___acl_delete_link 427 --#define TARGET_FREEBSD_NR___acl_aclcheck_link 428 --#define TARGET_FREEBSD_NR_sigwait 429 --#define TARGET_FREEBSD_NR_thr_create 430 --#define TARGET_FREEBSD_NR_thr_exit 431 --#define TARGET_FREEBSD_NR_thr_self 432 --#define TARGET_FREEBSD_NR_thr_kill 433 --#define TARGET_FREEBSD_NR__umtx_lock 434 --#define TARGET_FREEBSD_NR__umtx_unlock 435 --#define TARGET_FREEBSD_NR_jail_attach 436 --#define TARGET_FREEBSD_NR_extattr_list_fd 437 --#define TARGET_FREEBSD_NR_extattr_list_file 438 --#define TARGET_FREEBSD_NR_extattr_list_link 439 --#define TARGET_FREEBSD_NR_ksem_timedwait 441 --#define TARGET_FREEBSD_NR_thr_suspend 442 --#define TARGET_FREEBSD_NR_thr_wake 443 --#define TARGET_FREEBSD_NR_kldunloadf 444 --#define TARGET_FREEBSD_NR_audit 445 --#define TARGET_FREEBSD_NR_auditon 446 --#define TARGET_FREEBSD_NR_getauid 447 --#define TARGET_FREEBSD_NR_setauid 448 --#define TARGET_FREEBSD_NR_getaudit 449 --#define TARGET_FREEBSD_NR_setaudit 450 --#define TARGET_FREEBSD_NR_getaudit_addr 451 --#define TARGET_FREEBSD_NR_setaudit_addr 452 --#define TARGET_FREEBSD_NR_auditctl 453 --#define TARGET_FREEBSD_NR__umtx_op 454 --#define TARGET_FREEBSD_NR_thr_new 455 --#define TARGET_FREEBSD_NR_sigqueue 456 --#define TARGET_FREEBSD_NR_kmq_open 457 --#define TARGET_FREEBSD_NR_kmq_setattr 458 --#define TARGET_FREEBSD_NR_kmq_timedreceive 459 --#define TARGET_FREEBSD_NR_kmq_timedsend 460 --#define TARGET_FREEBSD_NR_kmq_notify 461 --#define TARGET_FREEBSD_NR_kmq_unlink 462 --#define TARGET_FREEBSD_NR_abort2 463 --#define TARGET_FREEBSD_NR_thr_set_name 464 --#define TARGET_FREEBSD_NR_aio_fsync 465 --#define TARGET_FREEBSD_NR_rtprio_thread 466 --#define TARGET_FREEBSD_NR_sctp_peeloff 471 --#define TARGET_FREEBSD_NR_sctp_generic_sendmsg 472 --#define TARGET_FREEBSD_NR_sctp_generic_sendmsg_iov 473 --#define TARGET_FREEBSD_NR_sctp_generic_recvmsg 474 --#define TARGET_FREEBSD_NR_pread 475 --#define TARGET_FREEBSD_NR_pwrite 476 --#define TARGET_FREEBSD_NR_mmap 477 --#define TARGET_FREEBSD_NR_lseek 478 --#define TARGET_FREEBSD_NR_truncate 479 --#define TARGET_FREEBSD_NR_ftruncate 480 --#define TARGET_FREEBSD_NR_thr_kill2 481 --#define TARGET_FREEBSD_NR_shm_open 482 --#define TARGET_FREEBSD_NR_shm_unlink 483 --#define TARGET_FREEBSD_NR_cpuset 484 --#define TARGET_FREEBSD_NR_cpuset_setid 485 --#define TARGET_FREEBSD_NR_cpuset_getid 486 --#define TARGET_FREEBSD_NR_cpuset_getaffinity 487 --#define TARGET_FREEBSD_NR_cpuset_setaffinity 488 --#define TARGET_FREEBSD_NR_faccessat 489 --#define TARGET_FREEBSD_NR_fchmodat 490 --#define TARGET_FREEBSD_NR_fchownat 491 --#define TARGET_FREEBSD_NR_fexecve 492 --#define TARGET_FREEBSD_NR_fstatat 493 --#define TARGET_FREEBSD_NR_futimesat 494 --#define TARGET_FREEBSD_NR_linkat 495 --#define TARGET_FREEBSD_NR_mkdirat 496 --#define TARGET_FREEBSD_NR_mkfifoat 497 --#define TARGET_FREEBSD_NR_mknodat 498 --#define TARGET_FREEBSD_NR_openat 499 --#define TARGET_FREEBSD_NR_readlinkat 500 --#define TARGET_FREEBSD_NR_renameat 501 --#define TARGET_FREEBSD_NR_symlinkat 502 --#define TARGET_FREEBSD_NR_unlinkat 503 --#define TARGET_FREEBSD_NR_posix_openpt 504 -+#define TARGET_FREEBSD_NR_syscall 0 -+#define TARGET_FREEBSD_NR_exit 1 -+#define TARGET_FREEBSD_NR_fork 2 -+#define TARGET_FREEBSD_NR_read 3 -+#define TARGET_FREEBSD_NR_write 4 -+#define TARGET_FREEBSD_NR_open 5 -+#define TARGET_FREEBSD_NR_close 6 -+#define TARGET_FREEBSD_NR_wait4 7 -+ /* 8 is old creat */ -+#define TARGET_FREEBSD_NR_link 9 -+#define TARGET_FREEBSD_NR_unlink 10 -+ /* 11 is obsolete execv */ -+#define TARGET_FREEBSD_NR_chdir 12 -+#define TARGET_FREEBSD_NR_fchdir 13 -+#define TARGET_FREEBSD_NR_mknod 14 -+#define TARGET_FREEBSD_NR_chmod 15 -+#define TARGET_FREEBSD_NR_chown 16 -+#define TARGET_FREEBSD_NR_break 17 -+#define TARGET_FREEBSD_NR_freebsd4_getfsstat 18 -+ /* 19 is old lseek */ -+#define TARGET_FREEBSD_NR_getpid 20 -+#define TARGET_FREEBSD_NR_mount 21 -+#define TARGET_FREEBSD_NR_unmount 22 -+#define TARGET_FREEBSD_NR_setuid 23 -+#define TARGET_FREEBSD_NR_getuid 24 -+#define TARGET_FREEBSD_NR_geteuid 25 -+#define TARGET_FREEBSD_NR_ptrace 26 -+#define TARGET_FREEBSD_NR_recvmsg 27 -+#define TARGET_FREEBSD_NR_sendmsg 28 -+#define TARGET_FREEBSD_NR_recvfrom 29 -+#define TARGET_FREEBSD_NR_accept 30 -+#define TARGET_FREEBSD_NR_getpeername 31 -+#define TARGET_FREEBSD_NR_getsockname 32 -+#define TARGET_FREEBSD_NR_access 33 -+#define TARGET_FREEBSD_NR_chflags 34 -+#define TARGET_FREEBSD_NR_fchflags 35 -+#define TARGET_FREEBSD_NR_sync 36 -+#define TARGET_FREEBSD_NR_kill 37 -+ /* 38 is old stat */ -+#define TARGET_FREEBSD_NR_getppid 39 -+ /* 40 is old lstat */ -+#define TARGET_FREEBSD_NR_dup 41 -+#define TARGET_FREEBSD_NR_pipe 42 -+#define TARGET_FREEBSD_NR_getegid 43 -+#define TARGET_FREEBSD_NR_profil 44 -+#define TARGET_FREEBSD_NR_ktrace 45 -+ /* 46 is old sigaction */ -+#define TARGET_FREEBSD_NR_getgid 47 -+ /* 48 is old sigprocmask */ -+#define TARGET_FREEBSD_NR_getlogin 49 -+#define TARGET_FREEBSD_NR_setlogin 50 -+#define TARGET_FREEBSD_NR_acct 51 -+ /* 52 is old sigpending */ -+#define TARGET_FREEBSD_NR_sigaltstack 53 -+#define TARGET_FREEBSD_NR_ioctl 54 -+#define TARGET_FREEBSD_NR_reboot 55 -+#define TARGET_FREEBSD_NR_revoke 56 -+#define TARGET_FREEBSD_NR_symlink 57 -+#define TARGET_FREEBSD_NR_readlink 58 -+#define TARGET_FREEBSD_NR_execve 59 -+#define TARGET_FREEBSD_NR_umask 60 -+#define TARGET_FREEBSD_NR_chroot 61 -+ /* 62 is old fstat */ -+ /* 63 is old getkerninfo */ -+ /* 64 is old getpagesize */ -+#define TARGET_FREEBSD_NR_msync 65 -+#define TARGET_FREEBSD_NR_vfork 66 -+ /* 67 is obsolete vread */ -+ /* 68 is obsolete vwrite */ -+#define TARGET_FREEBSD_NR_sbrk 69 -+#define TARGET_FREEBSD_NR_sstk 70 -+ /* 71 is old mmap */ -+#define TARGET_FREEBSD_NR_vadvise 72 -+#define TARGET_FREEBSD_NR_munmap 73 -+#define TARGET_FREEBSD_NR_mprotect 74 -+#define TARGET_FREEBSD_NR_madvise 75 -+ /* 76 is obsolete vhangup */ -+ /* 77 is obsolete vlimit */ -+#define TARGET_FREEBSD_NR_mincore 78 -+#define TARGET_FREEBSD_NR_getgroups 79 -+#define TARGET_FREEBSD_NR_setgroups 80 -+#define TARGET_FREEBSD_NR_getpgrp 81 -+#define TARGET_FREEBSD_NR_setpgid 82 -+#define TARGET_FREEBSD_NR_setitimer 83 -+ /* 84 is old wait */ -+#define TARGET_FREEBSD_NR_swapon 85 -+#define TARGET_FREEBSD_NR_getitimer 86 -+ /* 87 is old gethostname */ -+ /* 88 is old sethostname */ -+#define TARGET_FREEBSD_NR_getdtablesize 89 -+#define TARGET_FREEBSD_NR_dup2 90 -+#define TARGET_FREEBSD_NR_fcntl 92 -+#define TARGET_FREEBSD_NR_select 93 -+#define TARGET_FREEBSD_NR_fsync 95 -+#define TARGET_FREEBSD_NR_setpriority 96 -+#define TARGET_FREEBSD_NR_socket 97 -+#define TARGET_FREEBSD_NR_connect 98 -+ /* 99 is old accept */ -+#define TARGET_FREEBSD_NR_getpriority 100 -+ /* 101 is old send */ -+ /* 102 is old recv */ -+ /* 103 is old sigreturn */ -+#define TARGET_FREEBSD_NR_bind 104 -+#define TARGET_FREEBSD_NR_setsockopt 105 -+#define TARGET_FREEBSD_NR_listen 106 -+ /* 107 is obsolete vtimes */ -+ /* 108 is old sigvec */ -+ /* 109 is old sigblock */ -+ /* 110 is old sigsetmask */ -+ /* 111 is old sigsuspend */ -+ /* 112 is old sigstack */ -+ /* 113 is old recvmsg */ -+ /* 114 is old sendmsg */ -+ /* 115 is obsolete vtrace */ -+#define TARGET_FREEBSD_NR_gettimeofday 116 -+#define TARGET_FREEBSD_NR_getrusage 117 -+#define TARGET_FREEBSD_NR_getsockopt 118 -+#define TARGET_FREEBSD_NR_readv 120 -+#define TARGET_FREEBSD_NR_writev 121 -+#define TARGET_FREEBSD_NR_settimeofday 122 -+#define TARGET_FREEBSD_NR_fchown 123 -+#define TARGET_FREEBSD_NR_fchmod 124 -+ /* 125 is old recvfrom */ -+#define TARGET_FREEBSD_NR_setreuid 126 -+#define TARGET_FREEBSD_NR_setregid 127 -+#define TARGET_FREEBSD_NR_rename 128 -+ /* 129 is old truncate */ -+ /* 130 is old ftruncate */ -+#define TARGET_FREEBSD_NR_flock 131 -+#define TARGET_FREEBSD_NR_mkfifo 132 -+#define TARGET_FREEBSD_NR_sendto 133 -+#define TARGET_FREEBSD_NR_shutdown 134 -+#define TARGET_FREEBSD_NR_socketpair 135 -+#define TARGET_FREEBSD_NR_mkdir 136 -+#define TARGET_FREEBSD_NR_rmdir 137 -+#define TARGET_FREEBSD_NR_utimes 138 -+ /* 139 is obsolete 4.2 sigreturn */ -+#define TARGET_FREEBSD_NR_adjtime 140 -+ /* 141 is old getpeername */ -+ /* 142 is old gethostid */ -+ /* 143 is old sethostid */ -+ /* 144 is old getrlimit */ -+ /* 145 is old setrlimit */ -+ /* 146 is old killpg */ -+#define TARGET_FREEBSD_NR_killpg 146 /* COMPAT */ -+#define TARGET_FREEBSD_NR_setsid 147 -+#define TARGET_FREEBSD_NR_quotactl 148 -+ /* 149 is old quota */ -+ /* 150 is old getsockname */ -+#define TARGET_FREEBSD_NR_nlm_syscall 154 -+#define TARGET_FREEBSD_NR_nfssvc 155 -+ /* 156 is old getdirentries */ -+#define TARGET_FREEBSD_NR_freebsd4_statfs 157 -+#define TARGET_FREEBSD_NR_freebsd4_fstatfs 158 -+#define TARGET_FREEBSD_NR_lgetfh 160 -+#define TARGET_FREEBSD_NR_getfh 161 -+#define TARGET_FREEBSD_NR_freebsd4_getdomainname 162 -+#define TARGET_FREEBSD_NR_freebsd4_setdomainname 163 -+#define TARGET_FREEBSD_NR_freebsd4_uname 164 -+#define TARGET_FREEBSD_NR_sysarch 165 -+#define TARGET_FREEBSD_NR_rtprio 166 -+#define TARGET_FREEBSD_NR_semsys 169 -+#define TARGET_FREEBSD_NR_msgsys 170 -+#define TARGET_FREEBSD_NR_shmsys 171 -+#define TARGET_FREEBSD_NR_freebsd6_pread 173 -+#define TARGET_FREEBSD_NR_freebsd6_pwrite 174 -+#define TARGET_FREEBSD_NR_setfib 175 -+#define TARGET_FREEBSD_NR_ntp_adjtime 176 -+#define TARGET_FREEBSD_NR_setgid 181 -+#define TARGET_FREEBSD_NR_setegid 182 -+#define TARGET_FREEBSD_NR_seteuid 183 -+#define TARGET_FREEBSD_NR_stat 188 -+#define TARGET_FREEBSD_NR_fstat 189 -+#define TARGET_FREEBSD_NR_lstat 190 -+#define TARGET_FREEBSD_NR_pathconf 191 -+#define TARGET_FREEBSD_NR_fpathconf 192 -+#define TARGET_FREEBSD_NR_getrlimit 194 -+#define TARGET_FREEBSD_NR_setrlimit 195 -+#define TARGET_FREEBSD_NR_getdirentries 196 -+#define TARGET_FREEBSD_NR_freebsd6_mmap 197 -+#define TARGET_FREEBSD_NR___syscall 198 -+#define TARGET_FREEBSD_NR_freebsd6_lseek 199 -+#define TARGET_FREEBSD_NR_freebsd6_truncate 200 -+#define TARGET_FREEBSD_NR_freebsd6_ftruncate 201 -+#define TARGET_FREEBSD_NR___sysctl 202 -+#define TARGET_FREEBSD_NR_mlock 203 -+#define TARGET_FREEBSD_NR_munlock 204 -+#define TARGET_FREEBSD_NR_undelete 205 -+#define TARGET_FREEBSD_NR_futimes 206 -+#define TARGET_FREEBSD_NR_getpgid 207 -+#define TARGET_FREEBSD_NR_poll 209 -+#define TARGET_FREEBSD_NR_freebsd7___semctl 220 -+#define TARGET_FREEBSD_NR_semget 221 -+#define TARGET_FREEBSD_NR_semop 222 -+#define TARGET_FREEBSD_NR_freebsd7_msgctl 224 -+#define TARGET_FREEBSD_NR_msgget 225 -+#define TARGET_FREEBSD_NR_msgsnd 226 -+#define TARGET_FREEBSD_NR_msgrcv 227 -+#define TARGET_FREEBSD_NR_shmat 228 -+#define TARGET_FREEBSD_NR_freebsd7_shmctl 229 -+#define TARGET_FREEBSD_NR_shmdt 230 -+#define TARGET_FREEBSD_NR_shmget 231 -+#define TARGET_FREEBSD_NR_clock_gettime 232 -+#define TARGET_FREEBSD_NR_clock_settime 233 -+#define TARGET_FREEBSD_NR_clock_getres 234 -+#define TARGET_FREEBSD_NR_ktimer_create 235 -+#define TARGET_FREEBSD_NR_ktimer_delete 236 -+#define TARGET_FREEBSD_NR_ktimer_settime 237 -+#define TARGET_FREEBSD_NR_ktimer_gettime 238 -+#define TARGET_FREEBSD_NR_ktimer_getoverrun 239 -+#define TARGET_FREEBSD_NR_nanosleep 240 -+#define TARGET_FREEBSD_NR_ntp_gettime 248 -+#define TARGET_FREEBSD_NR_minherit 250 -+#define TARGET_FREEBSD_NR_rfork 251 -+#define TARGET_FREEBSD_NR_openbsd_poll 252 -+#define TARGET_FREEBSD_NR_issetugid 253 -+#define TARGET_FREEBSD_NR_lchown 254 -+#define TARGET_FREEBSD_NR_aio_read 255 -+#define TARGET_FREEBSD_NR_aio_write 256 -+#define TARGET_FREEBSD_NR_lio_listio 257 -+#define TARGET_FREEBSD_NR_getdents 272 -+#define TARGET_FREEBSD_NR_lchmod 274 -+#define TARGET_FREEBSD_NR_netbsd_lchown 275 -+#define TARGET_FREEBSD_NR_lutimes 276 -+#define TARGET_FREEBSD_NR_netbsd_msync 277 -+#define TARGET_FREEBSD_NR_nstat 278 -+#define TARGET_FREEBSD_NR_nfstat 279 -+#define TARGET_FREEBSD_NR_nlstat 280 -+#define TARGET_FREEBSD_NR_preadv 289 -+#define TARGET_FREEBSD_NR_pwritev 290 -+#define TARGET_FREEBSD_NR_freebsd4_fhstatfs 297 -+#define TARGET_FREEBSD_NR_fhopen 298 -+#define TARGET_FREEBSD_NR_fhstat 299 -+#define TARGET_FREEBSD_NR_modnext 300 -+#define TARGET_FREEBSD_NR_modstat 301 -+#define TARGET_FREEBSD_NR_modfnext 302 -+#define TARGET_FREEBSD_NR_modfind 303 -+#define TARGET_FREEBSD_NR_kldload 304 -+#define TARGET_FREEBSD_NR_kldunload 305 -+#define TARGET_FREEBSD_NR_kldfind 306 -+#define TARGET_FREEBSD_NR_kldnext 307 -+#define TARGET_FREEBSD_NR_kldstat 308 -+#define TARGET_FREEBSD_NR_kldfirstmod 309 -+#define TARGET_FREEBSD_NR_getsid 310 -+#define TARGET_FREEBSD_NR_setresuid 311 -+#define TARGET_FREEBSD_NR_setresgid 312 -+ /* 313 is obsolete signanosleep */ -+#define TARGET_FREEBSD_NR_aio_return 314 -+#define TARGET_FREEBSD_NR_aio_suspend 315 -+#define TARGET_FREEBSD_NR_aio_cancel 316 -+#define TARGET_FREEBSD_NR_aio_error 317 -+#define TARGET_FREEBSD_NR_oaio_read 318 -+#define TARGET_FREEBSD_NR_oaio_write 319 -+#define TARGET_FREEBSD_NR_olio_listio 320 -+#define TARGET_FREEBSD_NR_yield 321 -+ /* 322 is obsolete thr_sleep */ -+ /* 323 is obsolete thr_wakeup */ -+#define TARGET_FREEBSD_NR_mlockall 324 -+#define TARGET_FREEBSD_NR_munlockall 325 -+#define TARGET_FREEBSD_NR___getcwd 326 -+#define TARGET_FREEBSD_NR_sched_setparam 327 -+#define TARGET_FREEBSD_NR_sched_getparam 328 -+#define TARGET_FREEBSD_NR_sched_setscheduler 329 -+#define TARGET_FREEBSD_NR_sched_getscheduler 330 -+#define TARGET_FREEBSD_NR_sched_yield 331 -+#define TARGET_FREEBSD_NR_sched_get_priority_max 332 -+#define TARGET_FREEBSD_NR_sched_get_priority_min 333 -+#define TARGET_FREEBSD_NR_sched_rr_get_interval 334 -+#define TARGET_FREEBSD_NR_utrace 335 -+#define TARGET_FREEBSD_NR_freebsd4_sendfile 336 -+#define TARGET_FREEBSD_NR_kldsym 337 -+#define TARGET_FREEBSD_NR_jail 338 -+#define TARGET_FREEBSD_NR_nnpfs_syscall 339 -+#define TARGET_FREEBSD_NR_sigprocmask 340 -+#define TARGET_FREEBSD_NR_sigsuspend 341 -+#define TARGET_FREEBSD_NR_freebsd4_sigaction 342 -+#define TARGET_FREEBSD_NR_sigpending 343 -+#define TARGET_FREEBSD_NR_freebsd4_sigreturn 344 -+#define TARGET_FREEBSD_NR_sigtimedwait 345 -+#define TARGET_FREEBSD_NR_sigwaitinfo 346 -+#define TARGET_FREEBSD_NR___acl_get_file 347 -+#define TARGET_FREEBSD_NR___acl_set_file 348 -+#define TARGET_FREEBSD_NR___acl_get_fd 349 -+#define TARGET_FREEBSD_NR___acl_set_fd 350 -+#define TARGET_FREEBSD_NR___acl_delete_file 351 -+#define TARGET_FREEBSD_NR___acl_delete_fd 352 -+#define TARGET_FREEBSD_NR___acl_aclcheck_file 353 -+#define TARGET_FREEBSD_NR___acl_aclcheck_fd 354 -+#define TARGET_FREEBSD_NR_extattrctl 355 -+#define TARGET_FREEBSD_NR_extattr_set_file 356 -+#define TARGET_FREEBSD_NR_extattr_get_file 357 -+#define TARGET_FREEBSD_NR_extattr_delete_file 358 -+#define TARGET_FREEBSD_NR_aio_waitcomplete 359 -+#define TARGET_FREEBSD_NR_getresuid 360 -+#define TARGET_FREEBSD_NR_getresgid 361 -+#define TARGET_FREEBSD_NR_kqueue 362 -+#define TARGET_FREEBSD_NR_kevent 363 -+#define TARGET_FREEBSD_NR_extattr_set_fd 371 -+#define TARGET_FREEBSD_NR_extattr_get_fd 372 -+#define TARGET_FREEBSD_NR_extattr_delete_fd 373 -+#define TARGET_FREEBSD_NR___setugid 374 -+#define TARGET_FREEBSD_NR_eaccess 376 -+#define TARGET_FREEBSD_NR_afs3_syscall 377 -+#define TARGET_FREEBSD_NR_nmount 378 -+#define TARGET_FREEBSD_NR___mac_get_proc 384 -+#define TARGET_FREEBSD_NR___mac_set_proc 385 -+#define TARGET_FREEBSD_NR___mac_get_fd 386 -+#define TARGET_FREEBSD_NR___mac_get_file 387 -+#define TARGET_FREEBSD_NR___mac_set_fd 388 -+#define TARGET_FREEBSD_NR___mac_set_file 389 -+#define TARGET_FREEBSD_NR_kenv 390 -+#define TARGET_FREEBSD_NR_lchflags 391 -+#define TARGET_FREEBSD_NR_uuidgen 392 -+#define TARGET_FREEBSD_NR_sendfile 393 -+#define TARGET_FREEBSD_NR_mac_syscall 394 -+#define TARGET_FREEBSD_NR_getfsstat 395 -+#define TARGET_FREEBSD_NR_statfs 396 -+#define TARGET_FREEBSD_NR_fstatfs 397 -+#define TARGET_FREEBSD_NR_fhstatfs 398 -+#define TARGET_FREEBSD_NR_ksem_close 400 -+#define TARGET_FREEBSD_NR_ksem_post 401 -+#define TARGET_FREEBSD_NR_ksem_wait 402 -+#define TARGET_FREEBSD_NR_ksem_trywait 403 -+#define TARGET_FREEBSD_NR_ksem_init 404 -+#define TARGET_FREEBSD_NR_ksem_open 405 -+#define TARGET_FREEBSD_NR_ksem_unlink 406 -+#define TARGET_FREEBSD_NR_ksem_getvalue 407 -+#define TARGET_FREEBSD_NR_ksem_destroy 408 -+#define TARGET_FREEBSD_NR___mac_get_pid 409 -+#define TARGET_FREEBSD_NR___mac_get_link 410 -+#define TARGET_FREEBSD_NR___mac_set_link 411 -+#define TARGET_FREEBSD_NR_extattr_set_link 412 -+#define TARGET_FREEBSD_NR_extattr_get_link 413 -+#define TARGET_FREEBSD_NR_extattr_delete_link 414 -+#define TARGET_FREEBSD_NR___mac_execve 415 -+#define TARGET_FREEBSD_NR_sigaction 416 -+#define TARGET_FREEBSD_NR_sigreturn 417 -+#define TARGET_FREEBSD_NR_getcontext 421 -+#define TARGET_FREEBSD_NR_setcontext 422 -+#define TARGET_FREEBSD_NR_swapcontext 423 -+#define TARGET_FREEBSD_NR_swapoff 424 -+#define TARGET_FREEBSD_NR___acl_get_link 425 -+#define TARGET_FREEBSD_NR___acl_set_link 426 -+#define TARGET_FREEBSD_NR___acl_delete_link 427 -+#define TARGET_FREEBSD_NR___acl_aclcheck_link 428 -+#define TARGET_FREEBSD_NR_sigwait 429 -+#define TARGET_FREEBSD_NR_thr_create 430 -+#define TARGET_FREEBSD_NR_thr_exit 431 -+#define TARGET_FREEBSD_NR_thr_self 432 -+#define TARGET_FREEBSD_NR_thr_kill 433 -+#define TARGET_FREEBSD_NR__umtx_lock 434 -+#define TARGET_FREEBSD_NR__umtx_unlock 435 -+#define TARGET_FREEBSD_NR_jail_attach 436 -+#define TARGET_FREEBSD_NR_extattr_list_fd 437 -+#define TARGET_FREEBSD_NR_extattr_list_file 438 -+#define TARGET_FREEBSD_NR_extattr_list_link 439 -+#define TARGET_FREEBSD_NR_ksem_timedwait 441 -+#define TARGET_FREEBSD_NR_thr_suspend 442 -+#define TARGET_FREEBSD_NR_thr_wake 443 -+#define TARGET_FREEBSD_NR_kldunloadf 444 -+#define TARGET_FREEBSD_NR_audit 445 -+#define TARGET_FREEBSD_NR_auditon 446 -+#define TARGET_FREEBSD_NR_getauid 447 -+#define TARGET_FREEBSD_NR_setauid 448 -+#define TARGET_FREEBSD_NR_getaudit 449 -+#define TARGET_FREEBSD_NR_setaudit 450 -+#define TARGET_FREEBSD_NR_getaudit_addr 451 -+#define TARGET_FREEBSD_NR_setaudit_addr 452 -+#define TARGET_FREEBSD_NR_auditctl 453 -+#define TARGET_FREEBSD_NR__umtx_op 454 -+#define TARGET_FREEBSD_NR_thr_new 455 -+#define TARGET_FREEBSD_NR_sigqueue 456 -+#define TARGET_FREEBSD_NR_kmq_open 457 -+#define TARGET_FREEBSD_NR_kmq_setattr 458 -+#define TARGET_FREEBSD_NR_kmq_timedreceive 459 -+#define TARGET_FREEBSD_NR_kmq_timedsend 460 -+#define TARGET_FREEBSD_NR_kmq_notify 461 -+#define TARGET_FREEBSD_NR_kmq_unlink 462 -+#define TARGET_FREEBSD_NR_abort2 463 -+#define TARGET_FREEBSD_NR_thr_set_name 464 -+#define TARGET_FREEBSD_NR_aio_fsync 465 -+#define TARGET_FREEBSD_NR_rtprio_thread 466 -+#define TARGET_FREEBSD_NR_sctp_peeloff 471 -+#define TARGET_FREEBSD_NR_sctp_generic_sendmsg 472 -+#define TARGET_FREEBSD_NR_sctp_generic_sendmsg_iov 473 -+#define TARGET_FREEBSD_NR_sctp_generic_recvmsg 474 -+#define TARGET_FREEBSD_NR_pread 475 -+#define TARGET_FREEBSD_NR_pwrite 476 -+#define TARGET_FREEBSD_NR_mmap 477 -+#define TARGET_FREEBSD_NR_lseek 478 -+#define TARGET_FREEBSD_NR_truncate 479 -+#define TARGET_FREEBSD_NR_ftruncate 480 -+#define TARGET_FREEBSD_NR_thr_kill2 481 -+#define TARGET_FREEBSD_NR_shm_open 482 -+#define TARGET_FREEBSD_NR_shm_unlink 483 -+#define TARGET_FREEBSD_NR_cpuset 484 -+#define TARGET_FREEBSD_NR_cpuset_setid 485 -+#define TARGET_FREEBSD_NR_cpuset_getid 486 -+#define TARGET_FREEBSD_NR_cpuset_getaffinity 487 -+#define TARGET_FREEBSD_NR_cpuset_setaffinity 488 -+#define TARGET_FREEBSD_NR_faccessat 489 -+#define TARGET_FREEBSD_NR_fchmodat 490 -+#define TARGET_FREEBSD_NR_fchownat 491 -+#define TARGET_FREEBSD_NR_fexecve 492 -+#define TARGET_FREEBSD_NR_fstatat 493 -+#define TARGET_FREEBSD_NR_futimesat 494 -+#define TARGET_FREEBSD_NR_linkat 495 -+#define TARGET_FREEBSD_NR_mkdirat 496 -+#define TARGET_FREEBSD_NR_mkfifoat 497 -+#define TARGET_FREEBSD_NR_mknodat 498 -+#define TARGET_FREEBSD_NR_openat 499 -+#define TARGET_FREEBSD_NR_readlinkat 500 -+#define TARGET_FREEBSD_NR_renameat 501 -+#define TARGET_FREEBSD_NR_symlinkat 502 -+#define TARGET_FREEBSD_NR_unlinkat 503 -+#define TARGET_FREEBSD_NR_posix_openpt 504 -+#define TARGET_FREEBSD_NR_gssd_syscall 505 -+#define TARGET_FREEBSD_NR_jail_get 506 -+#define TARGET_FREEBSD_NR_jail_set 507 -+#define TARGET_FREEBSD_NR_jail_remove 508 -+#define TARGET_FREEBSD_NR_closefrom 509 -+#define TARGET_FREEBSD_NR___semctl 510 -+#define TARGET_FREEBSD_NR_msgctl 511 -+#define TARGET_FREEBSD_NR_shmctl 512 -+#define TARGET_FREEBSD_NR_lpathconf 513 -+#define TARGET_FREEBSD_NR_cap_new 514 -+#define TARGET_FREEBSD_NR_cap_getrights 515 -+#define TARGET_FREEBSD_NR_cap_enter 516 -+#define TARGET_FREEBSD_NR_cap_getmode 517 -+#define TARGET_FREEBSD_NR_pdfork 518 -+#define TARGET_FREEBSD_NR_pdkill 519 -+#define TARGET_FREEBSD_NR_pdgetpid 520 -+#define TARGET_FREEBSD_NR_pselect 522 -+#define TARGET_FREEBSD_NR_getloginclass 523 -+#define TARGET_FREEBSD_NR_setloginclass 524 -+#define TARGET_FREEBSD_NR_rctl_get_racct 525 -+#define TARGET_FREEBSD_NR_rctl_get_rules 526 -+#define TARGET_FREEBSD_NR_rctl_get_limits 527 -+#define TARGET_FREEBSD_NR_rctl_add_rule 528 -+#define TARGET_FREEBSD_NR_rctl_remove_rule 529 -+#define TARGET_FREEBSD_NR_posix_fallocate 530 -+#define TARGET_FREEBSD_NR_posix_fadvise 531 -+#define TARGET_FREEBSD_NR_MAXSYSCALL 532 -diff --git a/bsd-user/freebsd/target_os_elf.h b/bsd-user/freebsd/target_os_elf.h -new file mode 100644 -index 0000000..67637a0 ---- /dev/null -+++ b/bsd-user/freebsd/target_os_elf.h -@@ -0,0 +1,145 @@ -+/* -+ * freebsd ELF 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 _TARGET_OS_ELF_H_ -+#define _TARGET_OS_ELF_H_ -+ -+#include "target_arch_elf.h" -+#include "elf.h" -+ -+/* this flag is uneffective under linux too, should be deleted */ -+#ifndef MAP_DENYWRITE -+#define MAP_DENYWRITE 0 -+#endif -+ -+/* should probably go in elf.h */ -+#ifndef ELIBBAD -+#define ELIBBAD 80 -+#endif -+ -+#ifndef ELF_PLATFORM -+#define ELF_PLATFORM (NULL) -+#endif -+ -+#ifndef ELF_HWCAP -+#define ELF_HWCAP 0 -+#endif -+ -+#ifdef TARGET_ABI32 -+#undef ELF_CLASS -+#define ELF_CLASS ELFCLASS32 -+#undef bswaptls -+#define bswaptls(ptr) bswap32s(ptr) -+#endif -+ -+struct exec -+{ -+ unsigned int a_info; /* Use macros N_MAGIC, etc for access */ -+ unsigned int a_text; /* length of text, in bytes */ -+ unsigned int a_data; /* length of data, in bytes */ -+ unsigned int a_bss; /* length of uninitialized data area, in bytes */ -+ unsigned int a_syms; /* length of symbol table data in file, in bytes */ -+ unsigned int a_entry; /* start address */ -+ unsigned int a_trsize; /* length of relocation info for text, in bytes */ -+ unsigned int a_drsize; /* length of relocation info for data, in bytes */ -+}; -+ -+ -+#define N_MAGIC(exec) ((exec).a_info & 0xffff) -+#define OMAGIC 0407 -+#define NMAGIC 0410 -+#define ZMAGIC 0413 -+#define QMAGIC 0314 -+ -+/* max code+data+bss space allocated to elf interpreter */ -+#define INTERP_MAP_SIZE (32 * 1024 * 1024) -+ -+/* max code+data+bss+brk space allocated to ET_DYN executables */ -+#define ET_DYN_MAP_SIZE (128 * 1024 * 1024) -+ -+/* Necessary parameters */ -+#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE -+#define TARGET_ELF_PAGESTART(_v) ((_v) & \ -+ ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1)) -+#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1)) -+ -+#define INTERPRETER_NONE 0 -+#define INTERPRETER_AOUT 1 -+#define INTERPRETER_ELF 2 -+ -+#define DLINFO_ITEMS 12 -+ -+static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc, -+ struct elfhdr * exec, -+ abi_ulong load_addr, -+ abi_ulong load_bias, -+ abi_ulong interp_load_addr, int ibcs, -+ struct image_info *info) -+{ -+ abi_ulong sp; -+ int size; -+ const int n = sizeof(elf_addr_t); -+ -+ sp = p; -+ /* -+ * Force 16 byte _final_ alignment here for generality. -+ */ -+ sp = sp &~ (abi_ulong)15; -+ size = (DLINFO_ITEMS + 1) * 2; -+ size += envc + argc + 2; -+ size += (!ibcs ? 3 : 1); /* argc itself */ -+ size *= n; -+ if (size & 15) -+ sp -= 16 - (size & 15); -+ -+ /* This is correct because Linux defines -+ * elf_addr_t as Elf32_Off / Elf64_Off -+ */ -+#define NEW_AUX_ENT(id, val) do { \ -+ sp -= n; put_user_ual(val, sp); \ -+ sp -= n; put_user_ual(id, sp); \ -+ } while(0) -+ -+ NEW_AUX_ENT (AT_NULL, 0); -+ -+ /* There must be exactly DLINFO_ITEMS entries here. */ -+ NEW_AUX_ENT(AT_PHDR, (abi_ulong)(load_addr + exec->e_phoff)); -+ NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr))); -+ NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum)); -+ NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(TARGET_PAGE_SIZE)); -+ NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_load_addr)); -+ NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0); -+ NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry); -+ NEW_AUX_ENT(AT_UID, (abi_ulong) getuid()); -+ NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid()); -+ NEW_AUX_ENT(AT_GID, (abi_ulong) getgid()); -+ NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid()); -+#ifdef ARCH_DLINFO -+ /* -+ * ARCH_DLINFO must come last so platform specific code can enforce -+ * special alignment requirements on the AUXV if necessary (eg. PPC). -+ */ -+ ARCH_DLINFO; -+#endif -+#undef NEW_AUX_ENT -+ -+ sp = loader_build_argptr(envc, argc, sp, p, !ibcs); -+ return sp; -+} -+ -+#endif /* _TARGET_OS_ELF_H_ */ -diff --git a/bsd-user/freebsd/target_os_siginfo.h b/bsd-user/freebsd/target_os_siginfo.h -new file mode 100644 -index 0000000..39180ec ---- /dev/null -+++ b/bsd-user/freebsd/target_os_siginfo.h -@@ -0,0 +1,110 @@ -+/* -+ * FreeBSD siginfo related 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 _TARGET_OS_SIGINFO_H_ -+#define _TARGET_OS_SIGINFO_H_ -+ -+#define TARGET_NSIG 128 -+#define TARGET_NSIG_BPW (sizeof(uint32_t) * 8) -+#define TARGET_NSIG_WORDS (TARGET_NSIG / TARGET_NSIG_BPW) -+ -+/* this struct defines a stack used during syscall handling */ -+typedef struct target_sigaltstack { -+ abi_long ss_sp; -+ abi_ulong ss_size; -+ abi_long ss_flags; -+} target_stack_t; -+ -+typedef struct { -+ uint32_t __bits[TARGET_NSIG_WORDS]; -+} target_sigset_t; -+ -+struct target_sigaction { -+ abi_ulong _sa_handler; -+ int32_t sa_flags; -+ target_sigset_t sa_mask; -+}; -+ -+union target_sigval { -+ int32_t sival_int; -+ abi_ulong sival_ptr; -+ int32_t sigval_int; -+ abi_ulong sigval_ptr; -+}; -+ -+typedef struct target_siginfo { -+ int32_t si_signo; /* signal number */ -+ int32_t si_errno; /* errno association */ -+ int32_t si_code; /* signal code */ -+ int32_t si_pid; /* sending process */ -+ int32_t si_uid; /* sender's ruid */ -+ int32_t si_status; /* exit value */ -+ abi_ulong si_addr; /* faulting instruction */ -+ union target_sigval si_value; /* signal value */ -+ union { -+ struct { -+ int32_t _trapno; /* machine specific trap code */ -+ } _fault; -+ -+ /* POSIX.1b timers */ -+ struct { -+ int32_t _timerid; -+ int32_t _overrun; -+ } _timer; -+ -+ struct { -+ int32_t _mqd; -+ } _mesgp; -+ -+ /* SIGPOLL */ -+ struct { -+ int _band; /* POLL_IN, POLL_OUT, POLL_MSG */ -+ } _poll; -+ -+ struct { -+ abi_long __spare1__; -+ int32_t __spare2_[7]; -+ } __spare__; -+ } _reason; -+} target_siginfo_t; -+ -+#define target_si_signo si_signo -+#define target_si_code si_code -+#define target_si_errno si_errno -+#define target_si_addr si_addr -+ -+/* SIGILL si_codes */ -+#define TARGET_ILL_ILLOPC (1) /* Illegal opcode. */ -+#define TARGET_ILL_ILLOPN (2) /* Illegal operand. */ -+#define TARGET_ILL_ILLADR (3) /* Illegal addressing mode. */ -+#define TARGET_ILL_ILLTRP (4) /* Illegal trap. */ -+#define TARGET_ILL_PRVOPC (5) /* Privileged opcode. */ -+#define TARGET_ILL_PRVREG (6) /* Privileged register. */ -+#define TARGET_ILL_COPROC (7) /* Coprocessor error. */ -+#define TARGET_ILL_BADSTK (8) /* Internal stack error. */ -+ -+/* SIGSEGV si_codes */ -+#define TARGET_SEGV_MAPERR (1) /* address not mapped to object */ -+#define TARGET_SEGV_ACCERR (2) /* invalid permissions for mapped -+ object */ -+ -+/* SIGTRAP si_codes */ -+#define TARGET_TRAP_BRKPT (1) /* process beakpoint */ -+#define TARGET_TRAP_TRACE (2) /* process trace trap */ -+ -+#endif /* !_TARGET_OS_SIGINFO_H_ */ -diff --git a/bsd-user/freebsd/target_os_signal.h b/bsd-user/freebsd/target_os_signal.h -new file mode 100644 -index 0000000..d7004c8 ---- /dev/null -+++ b/bsd-user/freebsd/target_os_signal.h -@@ -0,0 +1,79 @@ -+#ifndef _TARGET_OS_SIGNAL_H_ -+#define _TARGET_OS_SIGNAL_H_ -+ -+#include "target_os_siginfo.h" -+#include "target_arch_signal.h" -+ -+/* Compare to sys/signal.h */ -+#define TARGET_SIGHUP 1 /* hangup */ -+#define TARGET_SIGINT 2 /* interrupt */ -+#define TARGET_SIGQUIT 3 /* quit */ -+#define TARGET_SIGILL 4 /* illegal instruction (not reset when caught) */ -+#define TARGET_SIGTRAP 5 /* trace trap (not reset when caught) */ -+#define TARGET_SIGABRT 6 /* abort() */ -+#define TARGET_SIGIOT SIGABRT /* compatibility */ -+#define TARGET_SIGEMT 7 /* EMT instruction */ -+#define TARGET_SIGFPE 8 /* floating point exception */ -+#define TARGET_SIGKILL 9 /* kill (cannot be caught or ignored) */ -+#define TARGET_SIGBUS 10 /* bus error */ -+#define TARGET_SIGSEGV 11 /* segmentation violation */ -+#define TARGET_SIGSYS 12 /* bad argument to system call */ -+#define TARGET_SIGPIPE 13 /* write on a pipe with no one to read it */ -+#define TARGET_SIGALRM 14 /* alarm clock */ -+#define TARGET_SIGTERM 15 /* software termination signal from kill */ -+#define TARGET_SIGURG 16 /* urgent condition on IO channel */ -+#define TARGET_SIGSTOP 17 /* sendable stop signal not from tty */ -+#define TARGET_SIGTSTP 18 /* stop signal from tty */ -+#define TARGET_SIGCONT 19 /* continue a stopped process */ -+#define TARGET_SIGCHLD 20 /* to parent on child stop or exit */ -+#define TARGET_SIGTTIN 21 /* to readers pgrp upon background tty read */ -+#define TARGET_SIGTTOU 22 /* like TTIN for output if(tp->t_local<OSTOP)*/ -+#define TARGET_SIGIO 23 /* input/output possible signal */ -+#define TARGET_SIGXCPU 24 /* exceeded CPU time limit */ -+#define TARGET_SIGXFSZ 25 /* exceeded file size limit */ -+#define TARGET_SIGVTALRM 26 /* virtual time alarm */ -+#define TARGET_SIGPROF 27 /* profiling time alarm */ -+#define TARGET_SIGWINCH 28 /* window size changes */ -+#define TARGET_SIGINFO 29 /* information request */ -+#define TARGET_SIGUSR1 30 /* user defined signal 1 */ -+#define TARGET_SIGUSR2 31 /* user defined signal 2 */ -+#define TARGET_SIGTHR 32 /* reserved by thread library */ -+#define TARGET_SIGLWP SIGTHR /* compatibility */ -+#define TARGET_SIGLIBRT 33 /* reserved by the real-time library */ -+#define TARGET_SIGRTMIN 65 -+#define TARGET_SIGRTMAX 126 -+#define TARGET_QEMU_ESIGRETURN 255 /* fake errno value for use by sigreturn */ -+ -+/* -+ * Language spec says we must list exactly one parameter, even though we -+ * actually supply three. Ugh! -+ */ -+#define TARGET_SIG_DFL ((abi_long)0) /* default signal handling */ -+#define TARGET_SIG_IGN ((abi_long)1) /* ignore signal */ -+#define TARGET_SIG_ERR ((abi_long)-1) /* error return from signal */ -+ -+#define TARGET_SA_ONSTACK 0x0001 /* take signal on signal stack */ -+#define TARGET_SA_RESTART 0x0002 /* restart system on signal return */ -+#define TARGET_SA_RESETHAND 0x0004 /* reset to SIG_DFL when taking signal */ -+#define TARGET_SA_NODEFER 0x0010 /* don't mask the signal we're delivering */ -+#define TARGET_SA_NOCLDWAIT 0x0020 /* don't create zombies (assign to pid 1) */ -+#define TARGET_SA_USERTRAMP 0x0100 /* do not bounce off kernel's sigtramp */ -+#define TARGET_SA_NOCLDSTOP 0x0008 /* do not generate SIGCHLD on child stop */ -+#define TARGET_SA_SIGINFO 0x0040 /* generate siginfo_t */ -+ -+/* -+ * Flags for sigprocmask: -+ */ -+#define TARGET_SIG_BLOCK 1 /* block specified signal set */ -+#define TARGET_SIG_UNBLOCK 2 /* unblock specified signal set */ -+#define TARGET_SIG_SETMASK 3 /* set specified signal set */ -+ -+#define TARGET_BADSIG SIG_ERR -+ -+/* -+ * sigaltstack control -+ */ -+#define TARGET_SS_ONSTACK 0x0001 /* take signals on alternate stack */ -+#define TARGET_SS_DISABLE 0x0004 /* disable taking signals on alternate stack*/ -+ -+#endif /* !_TARGET_OS_SIGNAL_H_ */ -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/freebsd/target_os_thread.h b/bsd-user/freebsd/target_os_thread.h -new file mode 100644 -index 0000000..519aad8 ---- /dev/null -+++ b/bsd-user/freebsd/target_os_thread.h -@@ -0,0 +1,6 @@ -+#ifndef _TARGET_OS_THREAD_H_ -+#define _TARGET_OS_THREAD_H_ -+ -+#include "target_arch_thread.h" -+ -+#endif /* !_TARGET_OS_THREAD_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/syscall.h b/bsd-user/i386/syscall.h -index 9b34c61..52de302 100644 ---- a/bsd-user/i386/syscall.h -+++ b/bsd-user/i386/syscall.h -@@ -1,3 +1,23 @@ -+/* -+ * i386 system call definitions -+ * -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+#ifndef _I386_SYSCALL_H_ -+#define _I386_SYSCALL_H_ -+ - /* default linux values for the selectors */ - #define __USER_CS (0x23) - #define __USER_DS (0x2B) -@@ -158,4 +178,7 @@ struct target_vm86plus_struct { - - - #define UNAME_MACHINE "i386" -+#define TARGET_HW_MACHINE UNAME_MACHINE -+#define TARGET_HW_MACHINE_ARCH UNAME_MACHINE - -+#endif /* ! _I386_SYSCALL_H_ */ -diff --git a/bsd-user/i386/target_arch.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..c3df814 ---- /dev/null -+++ b/bsd-user/i386/target_arch_cpu.h -@@ -0,0 +1,302 @@ -+/* -+ * 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; -+ -+ cpu_x86_set_cpl(env, 3); -+ -+ 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_elf.h b/bsd-user/i386/target_arch_elf.h -new file mode 100644 -index 0000000..83b2197 ---- /dev/null -+++ b/bsd-user/i386/target_arch_elf.h -@@ -0,0 +1,62 @@ -+/* -+ * i386 ELF 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 _TARGET_ARCH_ELF_H_ -+#define _TARGET_ARCH_ELF_H_ -+ -+#define ELF_START_MMAP 0x80000000 -+ -+/* -+ * This is used to ensure we don't load something for the wrong architecture. -+ */ -+#define elf_check_arch(x) ( ((x) == EM_386) || ((x) == EM_486) ) -+ -+/* -+ * These are used to set parameters in the core dumps. -+ */ -+#define ELF_CLASS ELFCLASS32 -+#define ELF_DATA ELFDATA2LSB -+#define ELF_ARCH EM_386 -+ -+#define USE_ELF_CORE_DUMP -+#define ELF_EXEC_PAGESIZE 4096 -+ -+/* XXX */ -+#ifndef __FreeBSD__ -+#define ELF_PLATFORM target_elf_get_platform() -+ -+static const char *target_elf_get_platform(void) -+{ -+ static char elf_platform[] = "i386"; -+ int family = (thread_env->cpuid_version >> 8) & 0xff; -+ if (family > 6) -+ family = 6; -+ if (family >= 3) -+ elf_platform[1] = '0' + family; -+ return elf_platform; -+} -+ -+#define ELF_HWCAP target_elf_get_hwcap() -+ -+static uint32_t target_elf_get_hwcap(void) -+{ -+ return thread_env->features[FEAT_1_EDX]; -+} -+#endif /* ! __FreeBSD__ */ -+ -+#endif /* _TARGET_ARCH_ELF_H_ */ -diff --git a/bsd-user/i386/target_arch_signal.h b/bsd-user/i386/target_arch_signal.h -new file mode 100644 -index 0000000..e2387b2 ---- /dev/null -+++ b/bsd-user/i386/target_arch_signal.h -@@ -0,0 +1,94 @@ -+/* -+ * i386 dependent signal 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 TARGET_ARCH_SIGNAL_H -+#define TARGET_ARCH_SIGNAL_H -+ -+#include "cpu.h" -+ -+/* Size of the signal trampolin code placed on the stack. */ -+/* #define TARGET_SZSIGCODE (0) */ /* XXX to be added. */ -+ -+/* compare to x86/include/_limits.h */ -+#define TARGET_MINSIGSTKSZ (512 * 4) /* min sig stack size */ -+#define TARGET_SIGSTKSZ (MINSIGSTKSZ + 32768) /* recommended size */ -+ -+#define TARGET_MC_GET_CLEAR_RET 0x0001 -+ -+struct target_sigcontext { -+ /* to be added */ -+}; -+ -+typedef struct target_mcontext { -+} target_mcontext_t; -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ abi_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __spare__[4]; -+} target_ucontext_t; -+ -+struct target_sigframe { -+ abi_ulong sf_signum; -+ abi_ulong sf_siginfo; /* code or pointer to sf_si */ -+ abi_ulong sf_ucontext; /* points to sf_uc */ -+ abi_ulong sf_addr; /* undocumented 4th arg */ -+ target_ucontext_t sf_uc; /* = *sf_uncontext */ -+ target_siginfo_t sf_si; /* = *sf_siginfo (SA_SIGINFO case)*/ -+ uint32_t __spare__[2]; -+}; -+ -+/* -+ * Compare to i386/i386/machdep.c sendsig() -+ * Assumes that target stack frame memory is locked. -+ */ -+static inline abi_long set_sigtramp_args(CPUX86State *regs, -+ int sig, struct target_sigframe *frame, abi_ulong frame_addr, -+ struct target_sigaction *ka) -+{ -+ /* XXX */ -+ return -TARGET_EOPNOTSUPP; -+} -+ -+/* Compare to i386/i386/machdep.c get_mcontext() */ -+static inline abi_long get_mcontext(CPUX86State *regs, -+ target_mcontext_t *mcp, int flags) -+{ -+ /* XXX */ -+ return -TARGET_EOPNOTSUPP; -+} -+ -+/* Compare to i386/i386/machdep.c set_mcontext() */ -+static inline abi_long set_mcontext(CPUX86State *regs, -+ target_mcontext_t *mcp, int srflag) -+{ -+ /* XXX */ -+ return -TARGET_EOPNOTSUPP; -+} -+ -+static inline abi_long get_ucontext_sigreturn(CPUX86State *regs, -+ abi_ulong target_sf, abi_ulong *target_uc) -+{ -+ /* XXX */ -+ *target_uc = 0; -+ return -TARGET_EOPNOTSUPP; -+} -+ -+#endif /* TARGET_ARCH_SIGNAL_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/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/i386/target_arch_thread.h b/bsd-user/i386/target_arch_thread.h -new file mode 100644 -index 0000000..407aa6c ---- /dev/null -+++ b/bsd-user/i386/target_arch_thread.h -@@ -0,0 +1,45 @@ -+/* -+ * i386 thread support -+ * -+ * 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 _TARGET_ARCH_THREAD_H_ -+#define _TARGET_ARCH_THREAD_H_ -+ -+/* Compare to vm_machdep.c cpu_set_upcall_kse() */ -+static inline void target_thread_set_upcall(CPUX86State *regs, abi_ulong entry, -+ abi_ulong arg, abi_ulong stack_base, abi_ulong stack_size) -+{ -+ /* XXX */ -+} -+ -+static inline void target_thread_init(struct target_pt_regs *regs, -+ struct image_info *infop) -+{ -+ regs->esp = infop->start_stack; -+ regs->eip = infop->entry; -+ -+ /* SVR4/i386 ABI (pages 3-31, 3-32) says that when the program -+ starts %edx contains a pointer to a function which might be -+ registered using `atexit'. This provides a mean for the -+ dynamic linker to call DT_FINI functions for shared libraries -+ that have been loaded before the code runs. -+ -+ A value of 0 tells we have no such handler. */ -+ regs->edx = 0; -+} -+ -+#endif /* !_TARGET_ARCH_THREAD_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 f81ba55..f27fcbc 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,183 @@ - #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 = CONFIG_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; -- --void gemu_log(const char *fmt, ...) --{ -- va_list ap; -- -- 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) --{ --} -+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 */ - --static inline void cpu_exec_end(CPUArchState *env) --{ --} -+char qemu_proc_pathname[PATH_MAX]; /* full path to exeutable */ - --static inline void start_exclusive(void) --{ --} -+/* Helper routines for implementing atomic operations. */ - --static inline void end_exclusive(void) --{ --} -+/* -+ * 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; - -+/* 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) -+/* -+ * Wait for pending exclusive operations to complete. The exclusive lock -+ * must be held. -+ */ -+static inline void exclusive_idle(void) - { -+ while (pending_cpus) { -+ pthread_cond_wait(&exclusive_resume, &exclusive_lock); -+ } - } - --void cpu_list_unlock(void) -+/* Start an exclusive operation. Must only be called outside of cpu_exec. */ -+void start_exclusive(void) - { --} -+ CPUState *other_cpu; - --#ifdef TARGET_I386 --/***********************************************************/ --/* CPUX86 core interface */ -+ pthread_mutex_lock(&exclusive_lock); -+ exclusive_idle(); - --void cpu_smm_update(CPUX86State *env) --{ --} -- --uint64_t cpu_get_tsc(CPUX86State *env) --{ -- return cpu_get_real_ticks(); -+ pending_cpus = 1; -+ /* Make all other cpus stop executing. */ -+ CPU_FOREACH(other_cpu) { -+ if (other_cpu->running) { -+ pending_cpus++; -+ cpu_exit(other_cpu); -+ } -+ } -+ if (pending_cpus > 1) { -+ pthread_cond_wait(&exclusive_cond, &exclusive_lock); -+ } - } - --static void write_dt(void *ptr, unsigned long addr, unsigned long limit, -- int flags) -+/* Finish an exclusive operation. */ -+void end_exclusive(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); -+ pending_cpus = 0; -+ pthread_cond_broadcast(&exclusive_resume); -+ pthread_mutex_unlock(&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) -+/* Wait for exclusive ops to finish, and begin cpu execution. */ -+void cpu_exec_start(CPUState *cpu) - { -- 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); -+ pthread_mutex_lock(&exclusive_lock); -+ exclusive_idle(); -+ cpu->running = true; -+ pthread_mutex_unlock(&exclusive_lock); - } - --/* only dpl matters as we do only user space emulation */ --static void set_idt(int n, unsigned int dpl) -+/* Mark cpu as not excuting, and release pending exclusive ops. */ -+void cpu_exec_end(CPUState *cpu) - { -- set_gate(idt_table + n, 0, dpl, 0, 0); --} --#endif -- --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(); -+ pthread_mutex_lock(&exclusive_lock); -+ cpu->running = false; -+ if (pending_cpus > 1) { -+ pending_cpus--; -+ if (pending_cpus == 1) { -+ pthread_cond_signal(&exclusive_cond); - } -- process_pending_signals(env); - } -+ exclusive_idle(); -+ pthread_mutex_unlock(&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) --{ -- 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 inline 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)]; --#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); -- } --} -- --static void save_window(CPUSPARCState *env) -+void cpu_list_lock(void) - { --#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(&cpu_list_mutex); - } - --static void restore_window(CPUSPARCState *env) --{ --#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 --} -- --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 +241,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 +269,54 @@ void init_task_state(TaskState *ts) - ts->sigqueue_table[i].next = NULL; - } - -+CPUArchState *cpu_copy(CPUArchState *env) -+{ -+ CPUArchState *new_env = cpu_init(cpu_model); -+#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(&env->breakpoints); -+ QTAILQ_INIT(&env->watchpoints); -+#if defined(TARGET_HAS_ICE) -+ QTAILQ_FOREACH(bp, &env->breakpoints, entry) { -+ cpu_breakpoint_insert(new_env, bp->pc, bp->flags, NULL); -+ } -+ QTAILQ_FOREACH(wp, &env->watchpoints, entry) { -+ cpu_watchpoint_insert(new_env, 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 = ®s1; - struct image_info info1, *info = &info1; -+ struct bsd_binprm bprm; - TaskState ts1, *ts = &ts1; - CPUArchState *env; - CPUState *cpu; -@@ -744,11 +325,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 +350,7 @@ int main(int argc, char **argv) - #endif - - optind = 1; -- for(;;) { -+ for (;;) { - if (optind >= argc) - break; - r = argv[optind]; -@@ -803,13 +386,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 +469,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 +478,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 +490,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 +529,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, &bprm)) { - printf("Error loading %s\n", filename); - _exit(1); - } -@@ -1000,139 +574,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) -- cpu_x86_set_cpl(env, 3); -- -- 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; -- } --#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/mips/syscall.h b/bsd-user/mips/syscall.h -new file mode 100644 -index 0000000..aacc6dd ---- /dev/null -+++ b/bsd-user/mips/syscall.h -@@ -0,0 +1,52 @@ -+/* -+ * mips system call definitions -+ * -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+#ifndef _MIPS_SYSCALL_H_ -+#define _MIPS_SYSCALL_H_ -+ -+/* -+ * struct target_pt_regs defines the way the registers are stored on the stack -+ * during a system call. -+ */ -+ -+struct target_pt_regs { -+ /* Saved main processor registers. */ -+ abi_ulong regs[32]; -+ -+ /* Saved special registers. */ -+ abi_ulong cp0_status; -+ abi_ulong lo; -+ abi_ulong hi; -+ abi_ulong cp0_badvaddr; -+ abi_ulong cp0_cause; -+ abi_ulong cp0_epc; -+}; -+ -+#if defined(TARGET_WORDS_BIGENDIAN) -+#define UNAME_MACHINE "mips" -+#else -+#define UNAME_MACHINE "mipsel" -+#endif -+ -+#define TARGET_HW_MACHINE "mips" -+#define TARGET_HW_MACHINE_ARCH UNAME_MACHINE -+ -+/* sysarch() commands */ -+#define TARGET_MIPS_SET_TLS 1 -+#define TARGET_MIPS_GET_TLS 2 -+ -+#endif /* !_MIPS_SYSCALL_H_ */ -diff --git a/bsd-user/mips/target_arch.h b/bsd-user/mips/target_arch.h -new file mode 100644 -index 0000000..b3d32ba ---- /dev/null -+++ b/bsd-user/mips/target_arch.h -@@ -0,0 +1,10 @@ -+ -+#ifndef _TARGET_ARCH_H_ -+#define _TARGET_ARCH_H_ -+ -+#include "qemu.h" -+ -+void target_cpu_set_tls(CPUMIPSState *env, target_ulong newtls); -+target_ulong target_cpu_get_tls(CPUMIPSState *env); -+ -+#endif /* !_TARGET_ARCH_H_ */ -diff --git a/bsd-user/mips/target_arch_cpu.c b/bsd-user/mips/target_arch_cpu.c -new file mode 100644 -index 0000000..dd59435 ---- /dev/null -+++ b/bsd-user/mips/target_arch_cpu.c -@@ -0,0 +1,27 @@ -+/* -+ * mips 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 "target_arch.h" -+ -+void target_cpu_set_tls(CPUMIPSState *env, target_ulong newtls) -+{ -+ env->tls_value = newtls; -+} -+ -+target_ulong target_cpu_get_tls(CPUMIPSState *env) -+{ -+ return (env->tls_value); -+} -diff --git a/bsd-user/mips/target_arch_cpu.h b/bsd-user/mips/target_arch_cpu.h -new file mode 100644 -index 0000000..5098b7d ---- /dev/null -+++ b/bsd-user/mips/target_arch_cpu.h -@@ -0,0 +1,257 @@ -+/* -+ * mips cpu init and loop -+ * -+ * 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 _TARGET_ARCH_CPU_H_ -+#define _TARGET_ARCH_CPU_H_ -+ -+#include "target_arch.h" -+ -+#if defined(TARGET_ABI_MIPSN32) -+# define TARGET_DEFAULT_CPU_MODEL "24Kc" -+#else -+# define TARGET_DEFAULT_CPU_MODEL "24Kf" -+#endif -+ -+#define TARGET_CPU_RESET(env) -+ -+static inline void target_cpu_init(CPUMIPSState *env, -+ struct target_pt_regs *regs) -+{ -+ int i; -+ -+ for (i = 0; i < 32; i++) { -+ env->active_tc.gpr[i] = regs->regs[i]; -+ } -+ env->active_tc.PC = regs->cp0_epc & ~(target_ulong)1; -+ if (regs->cp0_epc & 1) { -+ env->hflags |= MIPS_HFLAG_M16; -+ } -+} -+ -+static int do_store_exclusive(CPUMIPSState *env) -+{ -+ target_ulong addr; -+ target_ulong page_addr; -+ target_ulong val; -+ int flags; -+ int segv = 0; -+ int reg; -+ int d; -+ -+ addr = env->lladdr; -+ page_addr = addr & TARGET_PAGE_MASK; -+ start_exclusive(); -+ mmap_lock(); -+ flags = page_get_flags(page_addr); -+ if ((flags & PAGE_READ) == 0) { -+ segv = 1; -+ } else { -+ reg = env->llreg & 0x1f; -+ d = (env->llreg & 0x20) != 0; -+ if (d) { -+ segv = get_user_s64(val, addr); -+ } else { -+ segv = get_user_s32(val, addr); -+ } -+ if (!segv) { -+ if (val != env->llval) { -+ env->active_tc.gpr[reg] = 0; -+ } else { -+ if (d) { -+ segv = put_user_u64(env->llnewval, addr); -+ } else { -+ segv = put_user_u32(env->llnewval, addr); -+ } -+ if (!segv) { -+ env->active_tc.gpr[reg] = 1; -+ } -+ } -+ } -+ } -+ env->lladdr = -1; -+ if (!segv) { -+ env->active_tc.PC += 4; -+ } -+ mmap_unlock(); -+ end_exclusive(); -+ return segv; -+} -+ -+static inline void target_cpu_loop(CPUMIPSState *env) -+{ -+ CPUState *cs = CPU(mips_env_get_cpu(env)); -+ target_siginfo_t info; -+ int trapnr; -+ abi_long ret; -+ unsigned int syscall_num; -+ -+ for (;;) { -+ cpu_exec_start(cs); -+ trapnr = cpu_mips_exec(env); -+ cpu_exec_end(cs); -+ switch (trapnr) { -+ case EXCP_SYSCALL: /* syscall exception */ -+ if (bsd_type == target_freebsd) { -+ syscall_num = env->active_tc.gpr[2]; /* v0 */ -+ env->active_tc.PC += TARGET_INSN_SIZE; -+ if (syscall_num >= TARGET_FREEBSD_NR_MAXSYSCALL) { -+ ret = -TARGET_ENOSYS; -+ } else { -+ abi_ulong arg4 = 0, arg5 = 0, arg6 = 0, arg7 =0; -+ abi_ulong sp_reg = env->active_tc.gpr[29]; -+ -+# ifdef TARGET_ABI_MIPSO32 -+ get_user_ual(arg4, sp_reg + 16); -+ get_user_ual(arg5, sp_reg + 20); -+ get_user_ual(arg6, sp_reg + 24); -+ get_user_ual(arg7, sp_reg + 28); -+#else -+ arg4 = env->active_tc.gpr[12]; /* t4/arg4 */ -+ arg5 = env->active_tc.gpr[13]; /* t5/arg5 */ -+ arg6 = env->active_tc.gpr[14]; /* t6/arg6 */ -+ arg7 = env->active_tc.gpr[15]; /* t7/arg7 */ -+#endif -+ /* mips(32) uses regs 4-7,12-15 for args */ -+ if (TARGET_FREEBSD_NR___syscall == syscall_num || -+ TARGET_FREEBSD_NR_syscall == syscall_num) { -+ /* indirect syscall */ -+ ret = do_freebsd_syscall(env, -+ env->active_tc.gpr[4],/* syscall #*/ -+ env->active_tc.gpr[5], /* a1/arg0 */ -+ env->active_tc.gpr[6], /* a2/arg1 */ -+ env->active_tc.gpr[7], /* a3/arg2 */ -+ arg4, -+ arg5, -+ arg6, -+ arg7, -+ 0 /* no arg7 */ -+ ); -+ } else { -+ /* direct syscall */ -+ ret = do_freebsd_syscall(env, -+ syscall_num, -+ env->active_tc.gpr[4], /* a0/arg0 */ -+ env->active_tc.gpr[5], /* a1/arg1 */ -+ env->active_tc.gpr[6], /* a2/arg2 */ -+ env->active_tc.gpr[7], /* a3/arg3 */ -+ arg4, -+ arg5, -+ arg6, -+ arg7 -+ ); -+ } -+ } -+ /* Compare to mips/mips/vm_machdep.c cpu_set_syscall_retval() */ -+ if (-TARGET_EJUSTRETURN == ret) { -+ /* -+ * Returning from a successful sigreturn -+ * syscall. Avoid clobbering register state. -+ */ -+ break; -+ } -+ if (-TARGET_ERESTART == ret) { -+ /* Backup the pc to point at the swi. */ -+ env->active_tc.PC -= TARGET_INSN_SIZE; -+ break; -+ } -+ if ((unsigned int)ret >= (unsigned int)(-1133)) { -+ env->active_tc.gpr[7] = 1; -+ ret = -ret; -+ } else { -+ env->active_tc.gpr[7] = 0; -+ } -+ env->active_tc.gpr[2] = ret; /* v0 <- ret */ -+ } /* else if (bsd_type == target_openbsd)... */ -+ else { -+ fprintf(stderr, "qemu: bsd_type (= %d) syscall not supported\n", -+ bsd_type); -+ } -+ break; -+ -+ case EXCP_TLBL: /* TLB miss on load */ -+ case EXCP_TLBS: /* TLB miss on store */ -+ case EXCP_AdEL: /* bad address on load */ -+ case EXCP_AdES: /* bad address on store */ -+ info.target_si_signo = TARGET_SIGSEGV; -+ info.target_si_errno = 0; -+ /* XXX: check env->error_code */ -+ info.target_si_code = TARGET_SEGV_MAPERR; -+ info.target_si_addr = env->CP0_BadVAddr; -+ queue_signal(env, info.si_signo, &info); -+ break; -+ -+ case EXCP_CpU: /* coprocessor unusable */ -+ case EXCP_RI: /* reserved instruction */ -+ info.target_si_signo = TARGET_SIGILL; -+ info.target_si_errno = 0; -+ info.target_si_code = 0; -+ queue_signal(env, info.target_si_signo, &info); -+ break; -+ -+ case EXCP_INTERRUPT: /* async interrupt */ -+ /* just indicate that signals should be handled asap */ -+ break; -+ -+ case EXCP_DEBUG: /* cpu stopped after a breakpoint */ -+ { -+ int sig; -+ -+ sig = gdb_handlesig(cs, TARGET_SIGTRAP); -+ if (sig) { -+ info.target_si_signo = sig; -+ info.target_si_errno = 0; -+ info.target_si_code = TARGET_TRAP_BRKPT; -+ queue_signal(env, info.target_si_signo, &info); -+ } -+ } -+ break; -+ -+ case EXCP_SC: -+ if (do_store_exclusive(env)) { -+ info.target_si_signo = TARGET_SIGSEGV; -+ info.target_si_errno = 0; -+ info.target_si_code = TARGET_SEGV_MAPERR; -+ info.target_si_addr = env->active_tc.PC; -+ queue_signal(env, info.target_si_signo, &info); -+ } -+ break; -+ -+ default: -+ fprintf(stderr, "qemu: unhandled CPU exception " -+ "0x%x - aborting\n", trapnr); -+ cpu_dump_state(cs, stderr, fprintf, 0); -+ abort(); -+ } -+ process_pending_signals(env); -+ } -+} -+ -+static inline void target_cpu_clone_regs(CPUMIPSState *env, target_ulong newsp) -+{ -+ if (newsp) -+ env->active_tc.gpr[29] = newsp; -+ env->active_tc.gpr[7] = 0; -+ env->active_tc.gpr[2] = 0; -+} -+ -+static inline void target_cpu_reset(CPUArchState *cpu) -+{ -+} -+ -+#endif /* ! _TARGET_ARCH_CPU_H_ */ -diff --git a/bsd-user/mips/target_arch_elf.h b/bsd-user/mips/target_arch_elf.h -new file mode 100644 -index 0000000..8630f34 ---- /dev/null -+++ b/bsd-user/mips/target_arch_elf.h -@@ -0,0 +1,36 @@ -+/* -+ * mips ELF 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 _TARGET_ARCH_ELF_H_ -+#define _TARGET_ARCH_ELF_H_ -+ -+#define elf_check_arch(x) ( (x) == EM_MIPS ) -+#define ELF_START_MMAP 0x80000000 -+#define ELF_CLASS ELFCLASS32 -+ -+#ifdef TARGET_WORDS_BIGENDIAN -+#define ELF_DATA ELFDATA2MSB -+#else -+#define ELF_DATA ELFDATA2LSB -+#endif -+#define ELF_ARCH EM_MIPS -+ -+#define USE_ELF_CORE_DUMP -+#define ELF_EXEC_PAGESIZE 4096 -+ -+#endif /* _TARGET_ARCH_ELF_H_ */ -diff --git a/bsd-user/mips/target_arch_signal.h b/bsd-user/mips/target_arch_signal.h -new file mode 100644 -index 0000000..79d6f65 ---- /dev/null -+++ b/bsd-user/mips/target_arch_signal.h -@@ -0,0 +1,237 @@ -+/* -+ * mips signal 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 _TARGET_ARCH_SIGNAL_H_ -+#define _TARGET_ARCH_SIGNAL_H_ -+ -+#include "cpu.h" -+ -+#define TARGET_INSN_SIZE 4 /* mips instruction size */ -+ -+/* Size of the signal trampolin code. See insall_sigtramp(). */ -+#define TARGET_SZSIGCODE ((abi_ulong)(4 * TARGET_INSN_SIZE)) -+ -+/* compare to mips/include/_limits.h */ -+#define TARGET_MINSIGSTKSZ (512 * 4) /* min sig stack size */ -+#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) /* recommended size */ -+ -+/* compare to sys/mips/include/asm.h */ -+#define TARGET_SZREG 8 -+#define TARGET_CALLFRAME_SIZ (TARGET_SZREG * 4) -+ -+/* mips/mips/pm_machdep.c */ -+#define TARGET_UCONTEXT_MAGIC 0xACEDBADE -+#define TARGET_MC_GET_CLEAR_RET 0x0001 -+#define TARGET_MC_ADD_MAGIC 0x0002 -+#define TARGET_MC_SET_ONSTACK 0x0004 -+ -+struct target_sigcontext { -+ target_sigset_t sc_mask; /* signal mask to retstore */ -+ int32_t sc_onstack; /* sigstack state to restore */ -+ abi_long sc_pc; /* pc at time of signal */ -+ abi_long sc_reg[32]; /* processor regs 0 to 31 */ -+ abi_long mullo, mulhi; /* mullo and mulhi registers */ -+ int32_t sc_fpused; /* fp has been used */ -+ abi_long sc_fpregs[33]; /* fp regs 0 to 31 & csr */ -+ abi_long sc_fpc_eir; /* fp exception instr reg */ -+ /* int32_t reserved[8]; */ -+}; -+ -+typedef struct target_mcontext { -+ int32_t mc_onstack; /* sigstack state to restore */ -+ abi_long mc_pc; /* pc at time of signal */ -+ abi_long mc_regs[32]; /* process regs 0 to 31 */ -+ abi_long sr; /* status register */ -+ abi_long mullo, mulhi; -+ int32_t mc_fpused; /* fp has been used */ -+ abi_long mc_fpregs[33]; /* fp regs 0 to 32 & csr */ -+ abi_long mc_fpc_eir; /* fp exception instr reg */ -+ abi_ulong mc_tls; /* pointer to TLS area */ -+} target_mcontext_t; -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ abi_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __spare__[4]; -+} target_ucontext_t; -+ -+struct target_sigframe { -+ abi_ulong sf_signum; -+ abi_ulong sf_siginfo; /* code or pointer to sf_si */ -+ abi_ulong sf_ucontext; /* points to sf_uc */ -+ abi_ulong sf_addr; /* undocumented 4th arg */ -+ target_ucontext_t sf_uc; /* = *sf_uncontext */ -+ target_siginfo_t sf_si; /* = *sf_siginfo (SA_SIGINFO case)*/ -+ uint32_t __spare__[2]; -+}; -+ -+/* -+ * Compare to mips/mips/pm_machdep.c sendsig() -+ * Assumes that target stack frame memory is locked. -+ */ -+static inline abi_long -+set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame, -+ abi_ulong frame_addr, struct target_sigaction *ka) -+{ -+ -+ /* frame->sf_si.si_addr = regs->CP0_BadVAddr; */ -+ -+ /* MIPS only struct target_sigframe members: */ -+ frame->sf_signum = sig; -+ frame->sf_siginfo = frame_addr + offsetof(struct target_sigframe, sf_si); -+ frame->sf_ucontext = frame_addr + offsetof(struct target_sigframe, sf_uc); -+ -+ /* -+ * Arguments to signal handler: -+ * a0 ($4) = signal number -+ * a1 ($5) = siginfo pointer -+ * a2 ($6) = ucontext pointer -+ * PC = signal handler pointer -+ * t9 ($25) = signal handler pointer -+ * $29 = point to sigframe struct -+ * ra ($31) = sigtramp at base of user stack -+ */ -+ regs->active_tc.gpr[4] = sig; -+ regs->active_tc.gpr[5] = frame_addr + -+ offsetof(struct target_sigframe, sf_si); -+ regs->active_tc.gpr[6] = frame_addr + -+ offsetof(struct target_sigframe, sf_uc); -+ regs->active_tc.gpr[25] = regs->active_tc.PC = ka->_sa_handler; -+ regs->active_tc.gpr[29] = frame_addr; -+ regs->active_tc.gpr[31] = TARGET_PS_STRINGS - TARGET_SZSIGCODE; -+ -+ return 0; -+} -+ -+/* -+ * Compare to mips/mips/pm_machdep.c get_mcontext() -+ * Assumes that the memory is locked if mcp points to user memory. -+ */ -+static inline abi_long get_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, -+ int flags) -+{ -+ int i, err = 0; -+ -+ if (flags & TARGET_MC_ADD_MAGIC) { -+ mcp->mc_regs[0] = tswapal(TARGET_UCONTEXT_MAGIC); -+ } else { -+ mcp->mc_regs[0] = 0; -+ } -+ -+ if (flags & TARGET_MC_SET_ONSTACK) { -+ mcp->mc_onstack = tswapal(1); -+ } else { -+ mcp->mc_onstack = 0; -+ } -+ -+ for (i = 1; i < 32; i++) { -+ mcp->mc_regs[i] = tswapal(regs->active_tc.gpr[i]); -+ } -+ -+#if 0 /* XXX FP is not used right now */ -+ abi_ulong used_fp = used_math() ? TARGET_MDTD_FPUSED : 0; -+ -+ mcp->mc_fpused = used_fp; -+ if (used_fp) { -+ preempt_disable(); -+ if (!is_fpu_owner()) { -+ own_fpu(); -+ for (i = 0; i < 33; i++) { -+ mcp->mc_fpregs[i] = tswapal(regs->active_fpu.fpr[i]); -+ } -+ } -+ preempt_enable(); -+ } -+#else -+ mcp->mc_fpused = 0; -+#endif -+ -+ if (flags & TARGET_MC_GET_CLEAR_RET) { -+ mcp->mc_regs[2] = 0; /* v0 = 0 */ -+ mcp->mc_regs[3] = 0; /* v1 = 0 */ -+ mcp->mc_regs[7] = 0; /* a3 = 0 */ -+ } -+ -+ mcp->mc_pc = tswapal(regs->active_tc.PC); -+ mcp->mullo = tswapal(regs->active_tc.LO[0]); -+ mcp->mulhi = tswapal(regs->active_tc.HI[0]); -+ mcp->mc_tls = tswapal(regs->tls_value); -+ -+ /* Don't do any of the status and cause registers. */ -+ -+ return err; -+} -+ -+/* Compare to mips/mips/pm_machdep.c set_mcontext() */ -+static inline abi_long set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, -+ int srflag) -+{ -+ int i, err = 0; -+ -+ for (i = 1; i < 32; i++) { -+ regs->active_tc.gpr[i] = tswapal(mcp->mc_regs[i]); -+ } -+ -+#if 0 /* XXX FP is not used right now */ -+ abi_ulong used_fp = 0; -+ -+ used_fp = tswapal(mcp->mc_fpused) -+ conditional_used_math(used_fp); -+ -+ preempt_disabled(); -+ if (used_math()) { -+ /* restore fpu context if we have used it before */ -+ own_fpu(); -+ for (i = 0; i < 32; i++) { -+ regs->active_fpu.fpr[i] = tswapal(mcp->mc_fpregs[i]); -+ } -+ } else { -+ /* Signal handler may have used FPU. Give it up. */ -+ lose_fpu(); -+ } -+ preempt_enable(); -+#endif -+ -+ regs->CP0_EPC = tswapal(mcp->mc_pc); -+ regs->active_tc.LO[0] = tswapal(mcp->mullo); -+ regs->active_tc.HI[0] = tswapal(mcp->mulhi); -+ regs->tls_value = tswapal(mcp->mc_tls); -+ -+ if (srflag) { -+ /* doing sigreturn() */ -+ regs->active_tc.PC = regs->CP0_EPC; -+ regs->CP0_EPC = 0; /* XXX for nested signals ? */ -+ } -+ -+ /* Don't do any of the status and cause registers. */ -+ -+ return err; -+} -+ -+static inline abi_long get_ucontext_sigreturn(CPUMIPSState *regs, -+ abi_ulong target_sf, abi_ulong *target_uc) -+{ -+ -+ *target_uc = target_sf; -+ return 0; -+} -+ -+ -+#endif /* !_TARGET_ARCH_SIGNAL_H_ */ -diff --git a/bsd-user/mips/target_arch_sigtramp.h b/bsd-user/mips/target_arch_sigtramp.h -new file mode 100644 -index 0000000..5e3c69a ---- /dev/null -+++ b/bsd-user/mips/target_arch_sigtramp.h -@@ -0,0 +1,23 @@ -+ -+#ifndef _TARGET_ARCH_SIGTRAMP_H_ -+#define _TARGET_ARCH_SIGTRAMP_H_ -+ -+/* Compare to mips/mips/locore.S sigcode() */ -+static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc, -+ unsigned sys_sigreturn) -+{ -+ int i; -+ uint32_t sigtramp_code[TARGET_SZSIGCODE/TARGET_INSN_SIZE] = { -+ /* 1 */ 0x67A40000 + sigf_uc, /* daddu $a0, $sp, (sigf_uc) */ -+ /* 2 */ 0x24020000 + sys_sigreturn, /* li $v0, (sys_sigreturn) */ -+ /* 3 */ 0x0000000C, /* syscall */ -+ /* 4 */ 0x0000000D /* break */ -+ }; -+ -+ for (i = 0; i < 4; i++) { -+ tswap32s(&sigtramp_code[i]); -+ } -+ -+ return memcpy_to_target(offset, sigtramp_code, TARGET_SZSIGCODE); -+} -+#endif /* _TARGET_ARCH_SIGTRAMP_H_ */ -diff --git a/bsd-user/mips/target_arch_sysarch.h b/bsd-user/mips/target_arch_sysarch.h -new file mode 100644 -index 0000000..d333740 ---- /dev/null -+++ b/bsd-user/mips/target_arch_sysarch.h -@@ -0,0 +1,69 @@ -+/* -+ * mips sysarch() system call emulation -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef __ARCH_SYSARCH_H_ -+#define __ARCH_SYSARCH_H_ -+ -+#include "syscall.h" -+#include "target_arch.h" -+ -+static inline abi_long do_freebsd_arch_sysarch(CPUMIPSState *env, int op, -+ abi_ulong parms) -+{ -+ int ret = 0; -+ -+ switch (op) { -+ case TARGET_MIPS_SET_TLS: -+ target_cpu_set_tls(env, parms); -+ break; -+ -+ case TARGET_MIPS_GET_TLS: -+ if (put_user(target_cpu_get_tls(env), parms, abi_ulong)) { -+ ret = -TARGET_EFAULT; -+ } -+ break; -+ -+ default: -+ ret = -TARGET_EINVAL; -+ break; -+ } -+ -+ return ret; -+} -+ -+static inline void do_freebsd_arch_print_sysarch( -+ const struct syscallname *name, abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6) -+{ -+ -+ switch (arg1) { -+ case TARGET_MIPS_SET_TLS: -+ gemu_log("%s(SET_TLS, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2); -+ break; -+ -+ case TARGET_MIPS_GET_TLS: -+ gemu_log("%s(GET_TLS, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2); -+ break; -+ -+ default: -+ gemu_log("UNKNOWN OP: %d, " TARGET_ABI_FMT_lx ")", (int)arg1, arg2); -+ } -+} -+ -+#endif /*!__ARCH_SYSARCH_H_ */ -diff --git a/bsd-user/mips/target_arch_thread.h b/bsd-user/mips/target_arch_thread.h -new file mode 100644 -index 0000000..c76b0d6 ---- /dev/null -+++ b/bsd-user/mips/target_arch_thread.h -@@ -0,0 +1,54 @@ -+/* -+ * mips thread support -+ * -+ * 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 _TARGET_ARCH_THREAD_H_ -+#define _TARGET_ARCH_THREAD_H_ -+ -+/* Compare to mips/mips/vm_machdep.c cpu_set_upcall_kse() */ -+static inline void target_thread_set_upcall(CPUMIPSState *regs, abi_ulong entry, -+ abi_ulong arg, abi_ulong stack_base, abi_ulong stack_size) -+{ -+ abi_ulong sp; -+ -+ /* -+ * At the point where a function is called, sp must be 8 -+ * byte aligned[for compatibility with 64-bit CPUs] -+ * in ``See MIPS Run'' by D. Sweetman, p. 269 -+ * align stack -+ */ -+ sp = ((stack_base + stack_size) & ~0x7) - TARGET_CALLFRAME_SIZ; -+ -+ /* t9 = pc = start function entry */ -+ regs->active_tc.gpr[25] = regs->active_tc.PC = entry; -+ /* a0 = arg */ -+ regs->active_tc.gpr[4] = arg; -+ /* sp = top of the stack */ -+ regs->active_tc.gpr[29] = sp; -+} -+ -+static inline void target_thread_init(struct target_pt_regs *regs, -+ struct image_info *infop) -+{ -+ regs->cp0_status = 2 << CP0St_KSU; -+ regs->regs[25] = regs->cp0_epc = infop->entry & ~3; /* t9/pc = entry */ -+ regs->regs[4] = regs->regs[29] = infop->start_stack; /* a0/sp = stack */ -+ regs->regs[5] = regs->regs[6] = 0; /* a1/a2 = 0 */ -+ regs->regs[7] = TARGET_PS_STRINGS; /* a3 = ps_strings */ -+} -+ -+#endif /* !_TARGET_ARCH_THREAD_H_ */ -diff --git a/bsd-user/mips/target_arch_vmparam.h b/bsd-user/mips/target_arch_vmparam.h -new file mode 100644 -index 0000000..695877a ---- /dev/null -+++ b/bsd-user/mips/target_arch_vmparam.h -@@ -0,0 +1,50 @@ -+/* -+ * mips VM parameters 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 _TARGET_ARCH_VMPARAM_H_ -+#define _TARGET_ARCH_VMPARAM_H_ -+ -+#include "cpu.h" -+ -+/* compare to sys/mips/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 (1*1024UL*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 */ -+ -+/* MIPS only supports 31 bits of virtual address space for user space */ -+#define TARGET_RESERVED_VA 0x77000000 -+ -+#define TARGET_VM_MINUSER_ADDRESS (0x00000000) -+#define TARGET_VM_MAXUSER_ADDRESS (0x80000000) -+ -+#define TARGET_USRSTACK (TARGET_VM_MAXUSER_ADDRESS - TARGET_PAGE_SIZE) -+ -+static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state) -+{ -+ return state->active_tc.gpr[29]; -+} -+ -+static inline void set_second_rval(CPUMIPSState *state, abi_ulong retval2) -+{ -+ state->active_tc.gpr[3] = retval2; -+} -+ -+#endif /* ! _TARGET_ARCH_VMPARAM_H_ */ -diff --git a/bsd-user/mips64/syscall.h b/bsd-user/mips64/syscall.h -new file mode 100644 -index 0000000..bf4c598 ---- /dev/null -+++ b/bsd-user/mips64/syscall.h -@@ -0,0 +1,53 @@ -+/* -+ * mips64 system call definitions -+ * -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+#ifndef _MIPS64_SYSCALL_H_ -+#define _MIPS64_SYSCALL_H_ -+ -+/* -+ * struct target_pt_regs defines the way the registers are stored on the stack -+ * during a system call. -+ */ -+ -+struct target_pt_regs { -+ /* Saved main processor registers. */ -+ abi_ulong regs[32]; -+ -+ /* Saved special registers. */ -+ abi_ulong cp0_status; -+ abi_ulong lo; -+ abi_ulong hi; -+ abi_ulong cp0_badvaddr; -+ abi_ulong cp0_cause; -+ abi_ulong cp0_epc; -+}; -+ -+ -+#if defined(TARGET_WORDS_BIGENDIAN) -+#define UNAME_MACHINE "mips64" -+#else -+#define UNAME_MACHINE "mips64el" -+#endif -+ -+#define TARGET_HW_MACHINE "mips" -+#define TARGET_HW_MACHINE_ARCH UNAME_MACHINE -+ -+/* sysarch() commands */ -+#define TARGET_MIPS_SET_TLS 1 -+#define TARGET_MIPS_GET_TLS 2 -+ -+#endif /* !_MIPS64_SYSCALL_H_ */ -diff --git a/bsd-user/mips64/target_arch.h b/bsd-user/mips64/target_arch.h -new file mode 100644 -index 0000000..b3d32ba ---- /dev/null -+++ b/bsd-user/mips64/target_arch.h -@@ -0,0 +1,10 @@ -+ -+#ifndef _TARGET_ARCH_H_ -+#define _TARGET_ARCH_H_ -+ -+#include "qemu.h" -+ -+void target_cpu_set_tls(CPUMIPSState *env, target_ulong newtls); -+target_ulong target_cpu_get_tls(CPUMIPSState *env); -+ -+#endif /* !_TARGET_ARCH_H_ */ -diff --git a/bsd-user/mips64/target_arch_cpu.c b/bsd-user/mips64/target_arch_cpu.c -new file mode 100644 -index 0000000..9d016a3 ---- /dev/null -+++ b/bsd-user/mips64/target_arch_cpu.c -@@ -0,0 +1,27 @@ -+/* -+ * mips64 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 "target_arch.h" -+ -+void target_cpu_set_tls(CPUMIPSState *env, target_ulong newtls) -+{ -+ env->tls_value = newtls; -+} -+ -+target_ulong target_cpu_get_tls(CPUMIPSState *env) -+{ -+ return (env->tls_value); -+} -diff --git a/bsd-user/mips64/target_arch_cpu.h b/bsd-user/mips64/target_arch_cpu.h -new file mode 100644 -index 0000000..f4e212f ---- /dev/null -+++ b/bsd-user/mips64/target_arch_cpu.h -@@ -0,0 +1,243 @@ -+/* -+ * mips64 cpu init and loop -+ * -+ * 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 _TARGET_ARCH_CPU_H_ -+#define _TARGET_ARCH_CPU_H_ -+ -+#include "target_arch.h" -+ -+#if defined(TARGET_ABI_MIPSN32) || defined(TARGET_ABI_MIPSN64) -+# define TARGET_DEFAULT_CPU_MODEL "MIPS64R2-generic" -+#else -+# define TARGET_DEFAULT_CPU_MODEL "24f" -+#endif -+ -+#define TARGET_CPU_RESET(env) -+ -+static inline void target_cpu_init(CPUMIPSState *env, -+ struct target_pt_regs *regs) -+{ -+ int i; -+ -+ for (i = 0; i < 32; i++) { -+ env->active_tc.gpr[i] = regs->regs[i]; -+ } -+ env->active_tc.PC = regs->cp0_epc & ~(target_ulong)1; -+ if (regs->cp0_epc & 1) { -+ env->hflags |= MIPS_HFLAG_M16; -+ } -+ env->hflags |= MIPS_HFLAG_UX | MIPS_HFLAG_64; -+} -+ -+static int do_store_exclusive(CPUMIPSState *env) -+{ -+ target_ulong addr; -+ target_ulong page_addr; -+ target_ulong val; -+ int flags; -+ int segv = 0; -+ int reg; -+ int d; -+ -+ addr = env->lladdr; -+ page_addr = addr & TARGET_PAGE_MASK; -+ start_exclusive(); -+ mmap_lock(); -+ flags = page_get_flags(page_addr); -+ if ((flags & PAGE_READ) == 0) { -+ segv = 1; -+ } else { -+ reg = env->llreg & 0x1f; -+ d = (env->llreg & 0x20) != 0; -+ if (d) { -+ segv = get_user_s64(val, addr); -+ } else { -+ segv = get_user_s32(val, addr); -+ } -+ if (!segv) { -+ if (val != env->llval) { -+ env->active_tc.gpr[reg] = 0; -+ } else { -+ if (d) { -+ segv = put_user_u64(env->llnewval, addr); -+ } else { -+ segv = put_user_u32(env->llnewval, addr); -+ } -+ if (!segv) { -+ env->active_tc.gpr[reg] = 1; -+ } -+ } -+ } -+ } -+ env->lladdr = -1; -+ if (!segv) { -+ env->active_tc.PC += 4; -+ } -+ mmap_unlock(); -+ end_exclusive(); -+ return segv; -+} -+ -+static inline void target_cpu_loop(CPUMIPSState *env) -+{ -+ CPUState *cs = CPU(mips_env_get_cpu(env)); -+ target_siginfo_t info; -+ int trapnr; -+ abi_long ret; -+ unsigned int syscall_num; -+ -+ for (;;) { -+ cpu_exec_start(cs); -+ trapnr = cpu_mips_exec(env); -+ cpu_exec_end(cs); -+ switch (trapnr) { -+ case EXCP_SYSCALL: /* syscall exception */ -+ if (bsd_type == target_freebsd) { -+ syscall_num = env->active_tc.gpr[2]; /* v0 */ -+ env->active_tc.PC += TARGET_INSN_SIZE; -+ if (syscall_num >= TARGET_FREEBSD_NR_MAXSYSCALL) { -+ ret = -TARGET_ENOSYS; -+ } else { -+ /* mips64 uses regs 4-11 for args */ -+ if (TARGET_FREEBSD_NR___syscall == syscall_num || -+ TARGET_FREEBSD_NR_syscall == syscall_num) { -+ /* indirect syscall */ -+ ret = do_freebsd_syscall(env, -+ env->active_tc.gpr[4],/* syscall #*/ -+ env->active_tc.gpr[5], /* arg0 */ -+ env->active_tc.gpr[6], /* arg1 */ -+ env->active_tc.gpr[7], /* arg2 */ -+ env->active_tc.gpr[8], /* arg3 */ -+ env->active_tc.gpr[9], /* arg4 */ -+ env->active_tc.gpr[10],/* arg5 */ -+ env->active_tc.gpr[11],/* arg6 */ -+ 0 /* no arg 7 */); -+ } else { -+ /* direct syscall */ -+ ret = do_freebsd_syscall(env, -+ syscall_num, -+ env->active_tc.gpr[4], -+ env->active_tc.gpr[5], -+ env->active_tc.gpr[6], -+ env->active_tc.gpr[7], -+ env->active_tc.gpr[8], -+ env->active_tc.gpr[9], -+ env->active_tc.gpr[10], -+ env->active_tc.gpr[11] -+ ); -+ } -+ } -+ /* Compare to mips/mips/vm_machdep.c cpu_set_syscall_retval() */ -+ if (-TARGET_EJUSTRETURN == ret) { -+ /* -+ * Returning from a successful sigreturn -+ * syscall. Avoid clobbering register state. -+ */ -+ break; -+ } -+ if (-TARGET_ERESTART == ret) { -+ /* Backup the pc to point at the swi. */ -+ env->active_tc.PC -= TARGET_INSN_SIZE; -+ break; -+ } -+ if ((unsigned int)ret >= (unsigned int)(-1133)) { -+ env->active_tc.gpr[7] = 1; -+ ret = -ret; -+ } else { -+ env->active_tc.gpr[7] = 0; -+ } -+ env->active_tc.gpr[2] = ret; /* v0 <- ret */ -+ } /* else if (bsd_type == target_openbsd)... */ -+ else { -+ fprintf(stderr, "qemu: bsd_type (= %d) syscall not supported\n", -+ bsd_type); -+ } -+ break; -+ -+ case EXCP_TLBL: /* TLB miss on load */ -+ case EXCP_TLBS: /* TLB miss on store */ -+ case EXCP_AdEL: /* bad address on load */ -+ case EXCP_AdES: /* bad address on store */ -+ info.target_si_signo = TARGET_SIGSEGV; -+ info.target_si_errno = 0; -+ /* XXX: check env->error_code */ -+ info.target_si_code = TARGET_SEGV_MAPERR; -+ info.target_si_addr = env->CP0_BadVAddr; -+ queue_signal(env, info.si_signo, &info); -+ break; -+ -+ case EXCP_CpU: /* coprocessor unusable */ -+ case EXCP_RI: /* reserved instruction */ -+ info.target_si_signo = TARGET_SIGILL; -+ info.target_si_errno = 0; -+ info.target_si_code = 0; -+ queue_signal(env, info.target_si_signo, &info); -+ break; -+ -+ case EXCP_INTERRUPT: /* async interrupt */ -+ /* just indicate that signals should be handled asap */ -+ break; -+ -+ case EXCP_DEBUG: /* cpu stopped after a breakpoint */ -+ { -+ int sig; -+ -+ sig = gdb_handlesig(cs, TARGET_SIGTRAP); -+ if (sig) { -+ info.target_si_signo = sig; -+ info.target_si_errno = 0; -+ info.target_si_code = TARGET_TRAP_BRKPT; -+ queue_signal(env, info.target_si_signo, &info); -+ } -+ } -+ break; -+ -+ case EXCP_SC: -+ if (do_store_exclusive(env)) { -+ info.target_si_signo = TARGET_SIGSEGV; -+ info.target_si_errno = 0; -+ info.target_si_code = TARGET_SEGV_MAPERR; -+ info.target_si_addr = env->active_tc.PC; -+ queue_signal(env, info.target_si_signo, &info); -+ } -+ break; -+ -+ default: -+ fprintf(stderr, "qemu: unhandled CPU exception " -+ "0x%x - aborting\n", trapnr); -+ cpu_dump_state(cs, stderr, fprintf, 0); -+ abort(); -+ } -+ process_pending_signals(env); -+ } -+} -+ -+static inline void target_cpu_clone_regs(CPUMIPSState *env, target_ulong newsp) -+{ -+ if (newsp) -+ env->active_tc.gpr[29] = newsp; -+ env->active_tc.gpr[7] = 0; -+ env->active_tc.gpr[2] = 0; -+} -+ -+static inline void target_cpu_reset(CPUArchState *cpu) -+{ -+} -+ -+#endif /* ! _TARGET_ARCH_CPU_H_ */ -diff --git a/bsd-user/mips64/target_arch_elf.h b/bsd-user/mips64/target_arch_elf.h -new file mode 100644 -index 0000000..ca0da03 ---- /dev/null -+++ b/bsd-user/mips64/target_arch_elf.h -@@ -0,0 +1,36 @@ -+/* -+ * mips64 ELF 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 _TARGET_ARCH_ELF_H_ -+#define _TARGET_ARCH_ELF_H_ -+ -+#define elf_check_arch(x) ( (x) == EM_MIPS ) -+#define ELF_START_MMAP 0x2aaaaab000ULL -+#define ELF_CLASS ELFCLASS64 -+ -+#ifdef TARGET_WORDS_BIGENDIAN -+#define ELF_DATA ELFDATA2MSB -+#else -+#define ELF_DATA ELFDATA2LSB -+#endif -+#define ELF_ARCH EM_MIPS -+ -+#define USE_ELF_CORE_DUMP -+#define ELF_EXEC_PAGESIZE 4096 -+ -+#endif /* _TARGET_ARCH_ELF_H_ */ -diff --git a/bsd-user/mips64/target_arch_signal.h b/bsd-user/mips64/target_arch_signal.h -new file mode 100644 -index 0000000..2f79a24 ---- /dev/null -+++ b/bsd-user/mips64/target_arch_signal.h -@@ -0,0 +1,214 @@ -+/* -+ * mips64 signal 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 _TARGET_ARCH_SIGNAL_H_ -+#define _TARGET_ARCH_SIGNAL_H_ -+ -+#include "cpu.h" -+ -+#define TARGET_INSN_SIZE 4 /* mips64 instruction size */ -+ -+/* Size of the signal trampolin code placed on the stack. */ -+#define TARGET_SZSIGCODE ((abi_ulong)(4 * TARGET_INSN_SIZE)) -+ -+#define TARGET_MINSIGSTKSZ (512 * 4) -+#define TARGET_SIGSTKSZ (TARGET_MINSIGSTKSZ + 32768) -+ -+/* compare to sys/mips/include/asm.h */ -+#define TARGET_SZREG 8 -+#define TARGET_CALLFRAME_SIZ (TARGET_SZREG * 4) -+ -+/* mips/mips/pm_machdep.c */ -+#define TARGET_UCONTEXT_MAGIC 0xACEDBADE -+#define TARGET_MC_GET_CLEAR_RET 0x0001 -+#define TARGET_MC_ADD_MAGIC 0x0002 -+#define TARGET_MC_SET_ONSTACK 0x0004 -+ -+struct target_sigcontext { -+ target_sigset_t sc_mask; /* signal mask to retstore */ -+ int32_t sc_onstack; /* sigstack state to restore */ -+ abi_long sc_pc; /* pc at time of signal */ -+ abi_long sc_reg[32]; /* processor regs 0 to 31 */ -+ abi_long mullo, mulhi; /* mullo and mulhi registers */ -+ int32_t sc_fpused; /* fp has been used */ -+ abi_long sc_fpregs[33]; /* fp regs 0 to 31 & csr */ -+ abi_long sc_fpc_eir; /* fp exception instr reg */ -+ /* int32_t reserved[8]; */ -+}; -+ -+typedef struct target_mcontext { -+ int32_t mc_onstack; /* sigstack state to restore */ -+ abi_long mc_pc; /* pc at time of signal */ -+ abi_long mc_regs[32]; /* process regs 0 to 31 */ -+ abi_long sr; /* status register */ -+ abi_long mullo, mulhi; -+ int32_t mc_fpused; /* fp has been used */ -+ abi_long mc_fpregs[33]; /* fp regs 0 to 32 & csr */ -+ abi_long mc_fpc_eir; /* fp exception instr reg */ -+ abi_ulong mc_tls; /* pointer to TLS area */ -+} target_mcontext_t; -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ abi_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __spare__[4]; -+} target_ucontext_t; -+ -+struct target_sigframe { -+ abi_ulong sf_signum; -+ abi_ulong sf_siginfo; /* code or pointer to sf_si */ -+ abi_ulong sf_ucontext; /* points to sf_uc */ -+ abi_ulong sf_addr; /* undocumented 4th arg */ -+ target_ucontext_t sf_uc; /* = *sf_uncontext */ -+ target_siginfo_t sf_si; /* = *sf_siginfo (SA_SIGINFO case)*/ -+ uint32_t __spare__[2]; -+}; -+ -+/* -+ * Compare to mips/mips/pm_machdep.c sendsig() -+ * Assumes that target stack frame memory is locked. -+ */ -+static inline abi_long -+set_sigtramp_args(CPUMIPSState *regs, int sig, struct target_sigframe *frame, -+ abi_ulong frame_addr, struct target_sigaction *ka) -+{ -+ -+ /* frame->sf_si.si_addr = regs->CP0_BadVAddr; */ -+ -+ /* MIPS only struct target_sigframe members: */ -+ frame->sf_signum = sig; -+ frame->sf_siginfo = frame_addr + offsetof(struct target_sigframe, sf_si); -+ frame->sf_ucontext = frame_addr + offsetof(struct target_sigframe, sf_uc); -+ -+ /* -+ * Arguments to signal handler: -+ * a0 ($4) = signal number -+ * a1 ($5) = siginfo pointer -+ * a2 ($6) = ucontext pointer -+ * PC = signal handler pointer -+ * t9 ($25) = signal handler pointer -+ * $29 = point to sigframe struct -+ * ra ($31) = sigtramp at base of user stack -+ */ -+ regs->active_tc.gpr[4] = sig; -+ regs->active_tc.gpr[5] = frame_addr + -+ offsetof(struct target_sigframe, sf_si); -+ regs->active_tc.gpr[6] = frame_addr + -+ offsetof(struct target_sigframe, sf_uc); -+ regs->active_tc.gpr[25] = regs->active_tc.PC = ka->_sa_handler; -+ regs->active_tc.gpr[29] = frame_addr; -+ regs->active_tc.gpr[31] = TARGET_PS_STRINGS - TARGET_SZSIGCODE; -+ -+ return 0; -+} -+ -+/* -+ * Compare to mips/mips/pm_machdep.c get_mcontext() -+ * Assumes that the memory is locked if mcp points to user memory. -+ */ -+static inline abi_long get_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, -+ int flags) -+{ -+ int i, err = 0; -+ -+ if (flags & TARGET_MC_ADD_MAGIC) { -+ mcp->mc_regs[0] = tswapal(TARGET_UCONTEXT_MAGIC); -+ } else { -+ mcp->mc_regs[0] = 0; -+ } -+ -+ if (flags & TARGET_MC_SET_ONSTACK) { -+ mcp->mc_onstack = tswapal(1); -+ } else { -+ mcp->mc_onstack = 0; -+ } -+ -+ for (i = 1; i < 32; i++) { -+ mcp->mc_regs[i] = tswapal(regs->active_tc.gpr[i]); -+ } -+ -+ mcp->mc_fpused = 1; -+ for (i = 0; i < 32; i++) { -+ mcp->mc_fpregs[i] = tswapal(regs->active_fpu.fpr[i].d); -+ } -+ mcp->mc_fpregs[32] = tswapal(regs->active_fpu.fcr0); -+ mcp->mc_fpc_eir = tswapal(regs->active_fpu.fcr31); -+ -+ if (flags & TARGET_MC_GET_CLEAR_RET) { -+ mcp->mc_regs[2] = 0; /* v0 = 0 */ -+ mcp->mc_regs[3] = 0; /* v1 = 0 */ -+ mcp->mc_regs[7] = 0; /* a3 = 0 */ -+ } -+ -+ mcp->mc_pc = tswapal(regs->active_tc.PC); -+ mcp->mullo = tswapal(regs->active_tc.LO[0]); -+ mcp->mulhi = tswapal(regs->active_tc.HI[0]); -+ mcp->mc_tls = tswapal(regs->tls_value); -+ -+ /* Don't do any of the status and cause registers. */ -+ -+ return err; -+} -+ -+/* Compare to mips/mips/pm_machdep.c set_mcontext() */ -+static inline abi_long set_mcontext(CPUMIPSState *regs, target_mcontext_t *mcp, -+ int srflag) -+{ -+ int i, err = 0; -+ -+ for (i = 1; i < 32; i++) { -+ regs->active_tc.gpr[i] = tswapal(mcp->mc_regs[i]); -+ } -+ -+ if (mcp->mc_fpused) { -+ /* restore fpu context if we have used it before */ -+ for (i = 0; i < 32; i++) { -+ regs->active_fpu.fpr[i].d = tswapal(mcp->mc_fpregs[i]); -+ } -+ regs->active_fpu.fcr0 = tswapal(mcp->mc_fpregs[32]); -+ regs->active_fpu.fcr31 = tswapal(mcp->mc_fpc_eir); -+ } -+ -+ regs->CP0_EPC = tswapal(mcp->mc_pc); -+ regs->active_tc.LO[0] = tswapal(mcp->mullo); -+ regs->active_tc.HI[0] = tswapal(mcp->mulhi); -+ regs->tls_value = tswapal(mcp->mc_tls); -+ -+ if (srflag) { -+ /* doing sigreturn() */ -+ regs->active_tc.PC = regs->CP0_EPC; -+ regs->CP0_EPC = 0; /* XXX for nested signals ? */ -+ } -+ -+ /* Don't do any of the status and cause registers. */ -+ -+ return err; -+} -+ -+static inline abi_long get_ucontext_sigreturn(CPUMIPSState *regs, -+ abi_ulong target_sf, abi_ulong *target_uc) -+{ -+ -+ /* mips passes ucontext struct as the stack frame */ -+ *target_uc = target_sf; -+ return 0; -+} -+ -+#endif /* !_TARGET_ARCH_SIGNAL_H_ */ -diff --git a/bsd-user/mips64/target_arch_sigtramp.h b/bsd-user/mips64/target_arch_sigtramp.h -new file mode 100644 -index 0000000..5e3c69a ---- /dev/null -+++ b/bsd-user/mips64/target_arch_sigtramp.h -@@ -0,0 +1,23 @@ -+ -+#ifndef _TARGET_ARCH_SIGTRAMP_H_ -+#define _TARGET_ARCH_SIGTRAMP_H_ -+ -+/* Compare to mips/mips/locore.S sigcode() */ -+static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc, -+ unsigned sys_sigreturn) -+{ -+ int i; -+ uint32_t sigtramp_code[TARGET_SZSIGCODE/TARGET_INSN_SIZE] = { -+ /* 1 */ 0x67A40000 + sigf_uc, /* daddu $a0, $sp, (sigf_uc) */ -+ /* 2 */ 0x24020000 + sys_sigreturn, /* li $v0, (sys_sigreturn) */ -+ /* 3 */ 0x0000000C, /* syscall */ -+ /* 4 */ 0x0000000D /* break */ -+ }; -+ -+ for (i = 0; i < 4; i++) { -+ tswap32s(&sigtramp_code[i]); -+ } -+ -+ return memcpy_to_target(offset, sigtramp_code, TARGET_SZSIGCODE); -+} -+#endif /* _TARGET_ARCH_SIGTRAMP_H_ */ -diff --git a/bsd-user/mips64/target_arch_sysarch.h b/bsd-user/mips64/target_arch_sysarch.h -new file mode 100644 -index 0000000..95b4e78 ---- /dev/null -+++ b/bsd-user/mips64/target_arch_sysarch.h -@@ -0,0 +1,69 @@ -+/* -+ * mips64 sysarch() system call emulation -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef __ARCH_SYSARCH_H_ -+#define __ARCH_SYSARCH_H_ -+ -+#include "syscall.h" -+#include "target_arch.h" -+ -+static inline abi_long do_freebsd_arch_sysarch(CPUMIPSState *env, int op, -+ abi_ulong parms) -+{ -+ int ret = 0; -+ -+ switch (op) { -+ case TARGET_MIPS_SET_TLS: -+ target_cpu_set_tls(env, parms); -+ break; -+ -+ case TARGET_MIPS_GET_TLS: -+ if (put_user(target_cpu_get_tls(env), parms, abi_ulong)) { -+ ret = -TARGET_EFAULT; -+ } -+ break; -+ -+ default: -+ ret = -TARGET_EINVAL; -+ break; -+ } -+ -+ return ret; -+} -+ -+static inline void do_freebsd_arch_print_sysarch( -+ const struct syscallname *name, abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4, abi_long arg5, abi_long arg6) -+{ -+ -+ switch (arg1) { -+ case TARGET_MIPS_SET_TLS: -+ gemu_log("%s(SET_TLS, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2); -+ break; -+ -+ case TARGET_MIPS_GET_TLS: -+ gemu_log("%s(GET_TLS, 0x" TARGET_ABI_FMT_lx ")", name->name, arg2); -+ break; -+ -+ default: -+ gemu_log("UNKNOWN OP: %d, " TARGET_ABI_FMT_lx ")", (int)arg1, arg2); -+ } -+} -+ -+#endif /*!__ARCH_SYSARCH_H_ */ -diff --git a/bsd-user/mips64/target_arch_thread.h b/bsd-user/mips64/target_arch_thread.h -new file mode 100644 -index 0000000..7fcd866 ---- /dev/null -+++ b/bsd-user/mips64/target_arch_thread.h -@@ -0,0 +1,54 @@ -+/* -+ * mips64 thread support -+ * -+ * 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 _MIPS64_ARCH_THREAD_H_ -+#define _MIPS64_ARCH_THREAD_H_ -+ -+/* Compare to mips/mips/vm_machdep.c cpu_set_upcall_kse() */ -+static inline void target_thread_set_upcall(CPUMIPSState *regs, abi_ulong entry, -+ abi_ulong arg, abi_ulong stack_base, abi_ulong stack_size) -+{ -+ abi_ulong sp; -+ -+ /* -+ * At the point where a function is called, sp must be 8 -+ * byte aligned[for compatibility with 64-bit CPUs] -+ * in ``See MIPS Run'' by D. Sweetman, p. 269 -+ * align stack -+ */ -+ sp = ((stack_base + stack_size) & ~0x7) - TARGET_CALLFRAME_SIZ; -+ -+ /* t9 = pc = start function entry */ -+ regs->active_tc.gpr[25] = regs->active_tc.PC = entry; -+ /* a0 = arg */ -+ regs->active_tc.gpr[4] = arg; -+ /* sp = top of the stack */ -+ regs->active_tc.gpr[29] = sp; -+} -+ -+static inline void target_thread_init(struct target_pt_regs *regs, -+ struct image_info *infop) -+{ -+ regs->cp0_status = 2 << CP0St_KSU; -+ regs->regs[25] = regs->cp0_epc = infop->entry & ~3; /* t9/pc = entry */ -+ regs->regs[4] = regs->regs[29] = infop->start_stack; /* a0/sp = stack */ -+ regs->regs[5] = regs->regs[6] = 0; /* a1/a2 = 0 */ -+ regs->regs[7] = TARGET_PS_STRINGS; /* a3 = ps_strings */ -+} -+ -+#endif /* !_MIPS64_ARCH_THREAD_H_ */ -diff --git a/bsd-user/mips64/target_arch_vmparam.h b/bsd-user/mips64/target_arch_vmparam.h -new file mode 100644 -index 0000000..1ba09e0 ---- /dev/null -+++ b/bsd-user/mips64/target_arch_vmparam.h -@@ -0,0 +1,47 @@ -+/* -+ * mips64 VM parameters 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 _TARGET_ARCH_VMPARAM_H_ -+#define _TARGET_ARCH_VMPARAM_H_ -+ -+#include "cpu.h" -+ -+/* compare to sys/mips/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 (1*1024UL*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_VM_MINUSER_ADDRESS (0x0000000000000000UL) -+#define TARGET_VM_MAXUSER_ADDRESS (0x0000008000000000UL) -+ -+#define TARGET_USRSTACK (TARGET_VM_MAXUSER_ADDRESS - TARGET_PAGE_SIZE) -+ -+static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state) -+{ -+ return state->active_tc.gpr[29]; -+} -+ -+static inline void set_second_rval(CPUMIPSState *state, abi_ulong retval2) -+{ -+ state->active_tc.gpr[3] = retval2; -+} -+ -+#endif /* ! _TARGET_ARCH_VMPARAM_H_ */ -diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c -index aae8ea1..96a09f3 100644 ---- a/bsd-user/mmap.c -+++ b/bsd-user/mmap.c -@@ -1,4 +1,4 @@ --/* -+/** - * mmap support for qemu - * - * Copyright (c) 2003 - 2008 Fabrice Bellard -@@ -26,13 +26,11 @@ - - #include "qemu.h" - #include "qemu-common.h" --#include "bsd-mman.h" - --//#define DEBUG_MMAP -+// #define DEBUG_MMAP - --#if defined(CONFIG_USE_NPTL) --pthread_mutex_t mmap_mutex; --static int __thread mmap_lock_count; -+pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER; -+static __thread int mmap_lock_count; - - void mmap_lock(void) - { -@@ -63,76 +61,6 @@ void mmap_fork_end(int child) - else - pthread_mutex_unlock(&mmap_mutex); - } --#else --/* We aren't threadsafe to start with, so no need to worry about locking. */ --void mmap_lock(void) --{ --} -- --void mmap_unlock(void) --{ --} --#endif -- --static void *bsd_vmalloc(size_t size) --{ -- void *p; -- mmap_lock(); -- /* Use map and mark the pages as used. */ -- p = mmap(NULL, size, PROT_READ | PROT_WRITE, -- MAP_PRIVATE | MAP_ANON, -1, 0); -- -- if (h2g_valid(p)) { -- /* Allocated region overlaps guest address space. -- This may recurse. */ -- abi_ulong addr = h2g(p); -- page_set_flags(addr & TARGET_PAGE_MASK, TARGET_PAGE_ALIGN(addr + size), -- PAGE_RESERVED); -- } -- -- mmap_unlock(); -- return p; --} -- --void *g_malloc(size_t size) --{ -- char * p; -- size += 16; -- p = bsd_vmalloc(size); -- *(size_t *)p = size; -- return p + 16; --} -- --/* We use map, which is always zero initialized. */ --void * g_malloc0(size_t size) --{ -- return g_malloc(size); --} -- --void g_free(void *ptr) --{ -- /* FIXME: We should unmark the reserved pages here. However this gets -- complicated when one target page spans multiple host pages, so we -- don't bother. */ -- size_t *p; -- p = (size_t *)((char *)ptr - 16); -- munmap(p, *p); --} -- --void *g_realloc(void *ptr, size_t size) --{ -- size_t old_size, copy; -- void *new_ptr; -- -- if (!ptr) -- return g_malloc(size); -- old_size = *(size_t *)((char *)ptr - 16); -- copy = old_size < size ? old_size : size; -- new_ptr = g_malloc(size); -- memcpy(new_ptr, ptr, copy); -- g_free(ptr); -- return new_ptr; --} - - /* NOTE: all the constants are the HOST ones, but addresses are target. */ - int target_mprotect(abi_ulong start, abi_ulong len, int prot) -@@ -164,11 +92,11 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot) - if (start > host_start) { - /* handle host page containing start */ - prot1 = prot; -- for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) { -+ for (addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) { - prot1 |= page_get_flags(addr); - } - if (host_end == host_start + qemu_host_page_size) { -- for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { -+ for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { - prot1 |= page_get_flags(addr); - } - end = host_end; -@@ -180,7 +108,7 @@ int target_mprotect(abi_ulong start, abi_ulong len, int prot) - } - if (end < host_end) { - prot1 = prot; -- for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { -+ for (addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) { - prot1 |= page_get_flags(addr); - } - ret = mprotect(g2h(host_end - qemu_host_page_size), qemu_host_page_size, -@@ -218,7 +146,7 @@ static int mmap_frag(abi_ulong real_start, - - /* get the protection of the target pages outside the mapping */ - prot1 = 0; -- for(addr = real_start; addr < real_end; addr++) { -+ for (addr = real_start; addr < real_end; addr++) { - if (addr < start || addr >= end) - prot1 |= page_get_flags(addr); - } -@@ -238,15 +166,19 @@ static int mmap_frag(abi_ulong real_start, - /* msync() won't work here, so we return an error if write is - possible while it is a shared mapping */ - if ((flags & TARGET_BSD_MAP_FLAGMASK) == MAP_SHARED && -- (prot & PROT_WRITE)) -+ (prot & PROT_WRITE)) { - return -1; -+ } - - /* adjust protection to be able to read */ -- if (!(prot1 & PROT_WRITE)) -+ if (!(prot1 & PROT_WRITE)) { - mprotect(host_start, qemu_host_page_size, prot1 | PROT_WRITE); -+ } - - /* read the corresponding file data */ -- pread(fd, g2h(start), end - start, offset); -+ if (pread(fd, g2h(start), end - start, offset) == -1) { -+ return -1; -+ } - - /* put final protection */ - if (prot_new != (prot1 | PROT_WRITE)) -@@ -269,13 +201,14 @@ static abi_ulong mmap_next_start = 0x40000000; - - unsigned long last_brk; - --/* find a free memory area of size 'size'. The search starts at -- 'start'. If 'start' == 0, then a default start address is used. -- Return -1 if error. --*/ -+/* -+ * Find a free memory area of size 'size'. The search starts at -+ * 'start'. If 'start' == 0, then a default start address is used. -+ * Return -1 if error. -+ */ - /* page_init() marks pages used by the host as reserved to be sure not - to use them. */ --static abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) -+abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) - { - abi_ulong addr, addr1, addr_start; - int prot; -@@ -300,9 +233,9 @@ static abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) - if (addr == 0) - addr = mmap_next_start; - addr_start = addr; -- for(;;) { -+ for (;;) { - prot = 0; -- for(addr1 = addr; addr1 < (addr + size); addr1 += TARGET_PAGE_SIZE) { -+ for (addr1 = addr; addr1 < (addr + size); addr1 += TARGET_PAGE_SIZE) { - prot |= page_get_flags(addr1); - } - if (prot == 0) -@@ -319,9 +252,10 @@ static abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size) - - /* NOTE: all the constants are the HOST ones */ - abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, -- int flags, int fd, abi_ulong offset) -+ int flags, int fd, off_t offset) - { -- abi_ulong ret, end, real_start, real_end, retaddr, host_offset, host_len; -+ abi_ulong ret, end, real_start, real_end, retaddr, host_len; -+ off_t host_offset; - unsigned long host_start; - - mmap_lock(); -@@ -337,21 +271,38 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, - printf("MAP_FIXED "); - if (flags & MAP_ANON) - printf("MAP_ANON "); -- switch(flags & TARGET_BSD_MAP_FLAGMASK) { -- case MAP_PRIVATE: -- printf("MAP_PRIVATE "); -- break; -- case MAP_SHARED: -- printf("MAP_SHARED "); -- break; -- default: -- printf("[MAP_FLAGMASK=0x%x] ", flags & TARGET_BSD_MAP_FLAGMASK); -- break; -- } -- printf("fd=%d offset=" TARGET_FMT_lx "\n", fd, offset); -+ if (flags & MAP_PRIVATE) -+ printf("MAP_PRIVATE "); -+ if (flags & MAP_SHARED) -+ printf("MAP_SHARED "); -+ if (flags & MAP_NOCORE) -+ printf("MAP_NOCORE "); -+#ifdef MAP_STACK -+ if (flags & MAP_STACK) -+ printf("MAP_STACK "); -+#endif -+ printf("fd=%d offset=0x%llx\n", fd, offset); - } - #endif - -+ /* -+ * Enforce the constraints. -+ */ -+ if (len == 0 && fd != -1) { -+ errno = EINVAL; -+ goto fail; -+ } -+ -+#ifdef MAP_STACK -+ if (flags & MAP_STACK) { -+ if ((fd != -1) || ((prot & (PROT_READ | PROT_WRITE)) != -+ (PROT_READ | PROT_WRITE))) { -+ errno = EINVAL; -+ goto fail; -+ } -+ } -+#endif /* MAP_STACK */ -+ - if (offset & ~TARGET_PAGE_MASK) { - errno = EINVAL; - goto fail; -@@ -378,8 +329,9 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, - qemu_real_host_page_size */ - p = mmap(g2h(mmap_start), - host_len, prot, flags | MAP_FIXED, fd, host_offset); -- if (p == MAP_FAILED) -+ if (p == MAP_FAILED) { - goto fail; -+ } - /* update start so that it points to the file position at 'offset' */ - host_start = (unsigned long)p; - if (!(flags & MAP_ANON)) -@@ -396,7 +348,7 @@ abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, - end = start + len; - real_end = HOST_PAGE_ALIGN(end); - -- for(addr = real_start; addr < real_end; addr += TARGET_PAGE_SIZE) { -+ for (addr = real_start; addr < real_end; addr += TARGET_PAGE_SIZE) { - flg = page_get_flags(addr); - if (flg & PAGE_RESERVED) { - errno = ENXIO; -@@ -493,7 +445,9 @@ int target_munmap(abi_ulong start, abi_ulong len) - int prot, ret; - - #ifdef DEBUG_MMAP -- printf("munmap: start=0x%lx len=0x%lx\n", start, len); -+ printf("munmap: start=0x" TARGET_ABI_FMT_lx " len=0x" -+ TARGET_ABI_FMT_lx "\n", -+ start, len); - #endif - if (start & ~TARGET_PAGE_MASK) - return -EINVAL; -@@ -508,11 +462,11 @@ int target_munmap(abi_ulong start, abi_ulong len) - if (start > real_start) { - /* handle host page containing start */ - prot = 0; -- for(addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) { -+ for (addr = real_start; addr < start; addr += TARGET_PAGE_SIZE) { - prot |= page_get_flags(addr); - } - if (real_end == real_start + qemu_host_page_size) { -- for(addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) { -+ for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) { - prot |= page_get_flags(addr); - } - end = real_end; -@@ -522,7 +476,7 @@ int target_munmap(abi_ulong start, abi_ulong len) - } - if (end < real_end) { - prot = 0; -- for(addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) { -+ for (addr = end; addr < real_end; addr += TARGET_PAGE_SIZE) { - prot |= page_get_flags(addr); - } - if (prot != 0) -@@ -535,8 +489,10 @@ int target_munmap(abi_ulong start, abi_ulong len) - ret = munmap(g2h(real_start), real_end - real_start); - } - -- if (ret == 0) -+ if (ret == 0) { - page_set_flags(start, start + len, 0); -+ tb_invalidate_phys_range(start, start + len, 0); -+ } - mmap_unlock(); - return ret; - } -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-extattr.h b/bsd-user/netbsd/os-extattr.h -new file mode 100644 -index 0000000..c2f42ac ---- /dev/null -+++ b/bsd-user/netbsd/os-extattr.h -@@ -0,0 +1,247 @@ -+/* -+ * NetBSD extended attributes and ACL system call support -+ * -+ * 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/>. -+ */ -+ -+/* XXX To support FreeBSD targets the following will need to be added. */ -+ -+/* extattrctl() */ -+static inline abi_long do_freebsd_extattrctl(abi_ulong arg1, abi_ulong arg2, -+ abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattrctl()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_set_file(2) */ -+static inline abi_long do_freebsd_extattr_set_file(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_set_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_get_file(2) */ -+static inline abi_long do_freebsd_extattr_get_file(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_get_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_delete_file(2) */ -+static inline abi_long do_freebsd_extattr_delete_file(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_delete_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_set_fd(2) */ -+static inline abi_long do_freebsd_extattr_set_fd(abi_long arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_set_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_get_fd(2) */ -+static inline abi_long do_freebsd_extattr_get_fd(abi_long arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_get_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_delete_fd(2) */ -+static inline abi_long do_freebsd_extattr_delete_fd(abi_long arg1, -+ abi_long arg2, abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_delete_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_get_link(2) */ -+static inline abi_long do_freebsd_extattr_get_link(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_get_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_set_link(2) */ -+static inline abi_long do_freebsd_extattr_set_link(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_set_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_delete_link(2) */ -+static inline abi_long do_freebsd_extattr_delete_link(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_delete_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_list_fd(2) */ -+static inline abi_long do_freebsd_extattr_list_fd(abi_long arg1, abi_long arg2, -+ abi_ulong arg3, abi_ulong arg4) -+{ -+ -+ qemu_log("qemu: Unsupported syscall exattr_list_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_list_file(2) */ -+static inline abi_long do_freebsd_extattr_list_file(abi_long arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_list_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_list_link(2) */ -+static inline abi_long do_freebsd_extattr_list_link(abi_long arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_list_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * Access Control Lists -+ */ -+ -+/* __acl_aclcheck_fd(int filedes, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_aclcheck_fd(abi_long arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_aclcheck_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __acl_aclcheck_file(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_aclcheck_file(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_aclcheck_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __acl_aclcheck_link(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_aclcheck_link(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_aclcheck_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_delete_fd(int filedes, acl_type_t type); */ -+static inline abi_long do_freebsd__acl_delete_fd(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_delete_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_delete_file(const char *path, acl_type_t type); */ -+static inline abi_long do_freebsd__acl_delete_file(abi_ulong arg1, -+ abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_delete_fil()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_delete_link(const char *path, acl_type_t type); */ -+static inline abi_long do_freebsd__acl_delete_link(abi_ulong arg1, -+ abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_delete_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_get_fd(int filedes, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_get_fd(abi_long arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_get_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __acl_get_file(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_get_file(abi_ulong arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_get_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_get_link(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_get_link(abi_ulong arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall _acl_get_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_get_fd(int filedes, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_set_fd(abi_long arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_set_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_set_file(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_set_file(abi_ulong arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_set_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_set_link(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_set_link(abi_ulong arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_set_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -diff --git a/bsd-user/netbsd/os-ioctl-cmds.h b/bsd-user/netbsd/os-ioctl-cmds.h -new file mode 100644 -index 0000000..12af33c ---- /dev/null -+++ b/bsd-user/netbsd/os-ioctl-cmds.h -@@ -0,0 +1,48 @@ -+/* XXX should be fixed for NetBSD ioctl cmds */ -+ -+/* sys/ttycom.h tty(4) */ -+IOCTL(TIOCSETD, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGETD, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSBRK, IOC_, TYPE_NULL) -+IOCTL(TIOCCBRK, IOC_, TYPE_NULL) -+IOCTL(TIOCSDTR, IOC_, TYPE_NULL) -+IOCTL(TIOCCDTR, IOC_, TYPE_NULL) -+IOCTL(TIOCGPGRP, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSPGRP, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGETA, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCSETA, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCSETAW, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCSETAF, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCOUTQ, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSTI, IOC_W, MK_PTR(TYPE_CHAR)) -+IOCTL(TIOCNOTTY, IOC_, TYPE_NULL) -+IOCTL(TIOCSTOP, IOC_, TYPE_NULL) -+IOCTL(TIOCSTART, IOC_, TYPE_NULL) -+IOCTL(TIOCSCTTY, IOC_, TYPE_NULL) -+IOCTL(TIOCDRAIN, IOC_, TYPE_NULL) -+IOCTL(TIOCEXCL, IOC_, TYPE_NULL) -+IOCTL(TIOCNXCL, IOC_, TYPE_NULL) -+IOCTL(TIOCFLUSH, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGWINSZ, IOC_R, MK_PTR(MK_STRUCT(STRUCT_winsize))) -+IOCTL(TIOCSWINSZ, IOC_W, MK_PTR(MK_STRUCT(STRUCT_winsize))) -+IOCTL(TIOCCONS, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMSET, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMGET, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMBIS, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMBIC, IOC_W, MK_PTR(TYPE_INT)) -+ -+/* sys/filio.h */ -+IOCTL(FIOCLEX, IOC_, TYPE_NULL) -+IOCTL(FIONCLEX, IOC_, TYPE_NULL) -+IOCTL(FIONREAD, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIONBIO, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(FIOASYNC, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(FIOSETOWN, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(FIOGETOWN, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIODTYPE, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIOGETLBA, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIODGNAME, IOC_W, MK_PTR(MK_STRUCT(STRUCT_fiodgname_arg))) -+IOCTL(FIONWRITE, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIONSPACE, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIOSEEKDATA, IOC_RW, MK_PTR(TYPE_ULONG)) -+IOCTL(FIOSEEKHOLE, IOC_RW, MK_PTR(TYPE_ULONG)) -diff --git a/bsd-user/netbsd/os-ioctl-filio.h b/bsd-user/netbsd/os-ioctl-filio.h -new file mode 100644 -index 0000000..24b63ae ---- /dev/null -+++ b/bsd-user/netbsd/os-ioctl-filio.h -@@ -0,0 +1,29 @@ -+#ifndef _IOCTL_FILIO_H_ -+#define _IOCTL_FILIO_H_ -+ -+/* XXX needs to be fixed for NetBSD dependencies */ -+ -+/* see sys/filio.h */ -+#define TARGET_FIOCLEX TARGET_IO('f', 1) -+#define TARGET_FIONCLEX TARGET_IO('f', 2) -+#define TARGET_FIONREAD TARGET_IOR('f', 127, int) -+#define TARGET_FIONBIO TARGET_IOW('f', 126, int) -+#define TARGET_FIOASYNC TARGET_IOW('f', 125, int) -+#define TARGET_FIOSETOWN TARGET_IOW('f', 124, int) -+#define TARGET_FIOGETOWN TARGET_IOR('f', 123, int) -+#define TARGET_FIODTYPE TARGET_IOR('f', 122, int) -+#define TARGET_FIOGETLBA TARGET_IOR('f', 121, int) -+ -+struct target_fiodgname_arg { -+ int32_t len; -+ abi_ulong buf; -+}; -+ -+#define TARGET_FIODGNAME TARGET_IOW('f', 120, \ -+ struct target_fiodgname_arg) -+#define TARGET_FIONWRITE TARGET_IOR('f', 119, int) -+#define TARGET_FIONSPACE TARGET_IOR('f', 118, int) -+#define TARGET_FIOSEEKDATA TARGET_IOWR('f', 97, off_t) -+#define TARGET_FIOSEEKHOLE TARGET_IOWR('f', 98, off_t) -+ -+#endif /* !_IOCTL_FILIO_H_ */ -diff --git a/bsd-user/netbsd/os-ioctl-ioccom.h b/bsd-user/netbsd/os-ioctl-ioccom.h -new file mode 100644 -index 0000000..e193a16 ---- /dev/null -+++ b/bsd-user/netbsd/os-ioctl-ioccom.h -@@ -0,0 +1,38 @@ -+#ifndef _IOCTL_IOCCOM_H_ -+#define _IOCTL_IOCCOM_H_ -+ -+/* XXX needs to be fixed for NetBSD dependencies */ -+ -+/* -+ * Ioctl's have the command encoded in the lower word, and the size of -+ * any in or out parameters in the upper word. The high 3 bits of the -+ * upper word are used to encode the in/out status of the parameter. -+ */ -+/* number of bits for ioctl size */ -+#define TARGET_IOCPARM_SHIFT 13 -+ -+/* parameter length mask */ -+#define TARGET_IOCPARM_MASK ((1 << TARGET_IOCPARM_SHIFT) - 1) -+ -+#define TARGET_IOCPARM_LEN(x) (((x) >> 16) & TARGET_IOCPARM_MASK) -+#define TARGET_IOCBASECMD(x) ((x) & ~(TARGET_IOCPARM_MASK << 16)) -+#define TARGET_IOCGROUP(x) (((x) >> 8) & 0xff) -+ -+#define TARGET_IOCPARM_MAX (1 << TARGET_IOCPARM_SHIFT) /* max size of ioctl */ -+#define TARGET_IOC_VOID 0x20000000 /* no parameters */ -+#define TARGET_IOC_OUT 0x40000000 /* copy out parameters */ -+#define TARGET_IOC_IN 0x80000000 /* copy in parameters */ -+#define TARGET_IOC_INOUT (TARGET_IOC_IN|TARGET_IOC_OUT) -+#define TARGET_IOC_DIRMASK (TARGET_IOC_VOID|TARGET_IOC_OUT|TARGET_IOC_IN) -+ -+#define TARGET_IOC(inout, group, num, len) ((abi_ulong) \ -+ ((inout) | (((len) & TARGET_IOCPARM_MASK) << 16) | ((group) << 8) \ -+ | (num))) -+#define TARGET_IO(g, n) TARGET_IOC(IOC_VOID, (g), (n), 0) -+#define TARGET_IOWINT(g, n) TARGET_IOC(IOC_VOID, (g), (n), sizeof(int)) -+#define TARGET_IOR(g, n, t) TARGET_IOC(IOC_OUT, (g), (n), sizeof(t)) -+#define TARGET_IOW(g, n, t) TARGET_IOC(IOC_IN, (g), (n), sizeof(t)) -+/* this should be _IORW, but stdio got there first */ -+#define TARGET_IOWR(g, n, t) TARGET_IOC(IOC_INOUT, (g), (n), sizeof(t)) -+ -+#endif /* !_IOCTL_IOCCOM_H_ */ -diff --git a/bsd-user/netbsd/os-ioctl-ttycom.h b/bsd-user/netbsd/os-ioctl-ttycom.h -new file mode 100644 -index 0000000..9086635 ---- /dev/null -+++ b/bsd-user/netbsd/os-ioctl-ttycom.h -@@ -0,0 +1,240 @@ -+#ifndef _IOCTL_TTYCOM_H_ -+#define _IOCTL_TTYCOM_H_ -+ -+/* XXX Needs to be fixed for NetBSD dependencies */ -+ -+#include "os-ioctl-ioccom.h" -+ -+/* From sys/ttycom.h and sys/_termios.h */ -+ -+#define TARGET_VEOF 0 /* ICANON */ -+#define TARGET_VEOL 1 /* ICANON */ -+#define TARGET_VEOL2 2 /* ICANON together with IEXTEN */ -+#define TARGET_VERASE 3 /* ICANON */ -+#define TARGET_VWERASE 4 /* ICANON together with IEXTEN */ -+#define TARGET_VKILL 5 /* ICANON */ -+#define TARGET_VREPRINT 6 /* ICANON together with IEXTEN */ -+#define TARGET_VERASE2 7 /* ICANON */ -+#define TARGET_VINTR 8 /* ISIG */ -+#define TARGET_VQUIT 9 /* ISIG */ -+#define TARGET_VSUSP 10 /* ISIG */ -+#define TARGET_VDSUSP 11 /* ISIG together with IEXTEN */ -+#define TARGET_VSTART 12 /* IXON, IXOFF */ -+#define TARGET_VSTOP 13 /* IXON, IXOFF */ -+#define TARGET_VLNEXT 14 /* IEXTEN */ -+#define TARGET_VDISCARD 15 /* IEXTEN */ -+#define TARGET_VMIN 16 /* !ICANON */ -+#define TARGET_VTIME 17 /* !ICANON */ -+#define TARGET_VSTATUS 18 /* ICANON together with IEXTEN */ -+/* 19 spare 2 */ -+#define TARGET_NCCS 20 -+ -+/* -+ * Input flags - software input processing -+ */ -+#define TARGET_IGNBRK 0x00000001 /* ignore BREAK condition */ -+#define TARGET_BRKINT 0x00000002 /* map BREAK to SIGINTR */ -+#define TARGET_IGNPAR 0x00000004 /* ignore (discard) parity errors */ -+#define TARGET_PARMRK 0x00000008 /* mark parity and framing errors */ -+#define TARGET_INPCK 0x00000010 /* enable checking of parity errors */ -+#define TARGET_ISTRIP 0x00000020 /* strip 8th bit off chars */ -+#define TARGET_INLCR 0x00000040 /* map NL into CR */ -+#define TARGET_IGNCR 0x00000080 /* ignore CR */ -+#define TARGET_ICRNL 0x00000100 /* map CR to NL (ala CRMOD) */ -+#define TARGET_IXON 0x00000200 /* enable output flow control */ -+#define TARGET_IXOFF 0x00000400 /* enable input flow control */ -+#define TARGET_IXANY 0x00000800 /* any char will restart after stop */ -+#define TARGET_IMAXBEL 0x00002000 /* ring bell on input queue full */ -+ -+/* -+ * Output flags - software output processing -+ */ -+#define TARGET_OPOST 0x00000001 /* enable following output processing */ -+#define TARGET_ONLCR 0x00000002 /* map NL to CR-NL (ala CRMOD) */ -+#define TARGET_TABDLY 0x00000004 /* tab delay mask */ -+#define TARGET_TAB0 0x00000000 /* no tab delay and expansion */ -+#define TARGET_TAB3 0x00000004 /* expand tabs to spaces */ -+#define TARGET_ONOEOT 0x00000008 /* discard EOT's (^D) on output) */ -+#define TARGET_OCRNL 0x00000010 /* map CR to NL on output */ -+#define TARGET_ONOCR 0x00000020 /* no CR output at column 0 */ -+#define TARGET_ONLRET 0x00000040 /* NL performs CR function */ -+ -+/* -+ * Control flags - hardware control of terminal -+ */ -+#define TARGET_CIGNORE 0x00000001 /* ignore control flags */ -+#define TARGET_CSIZE 0x00000300 /* character size mask */ -+#define TARGET_CS5 0x00000000 /* 5 bits (pseudo) */ -+#define TARGET_CS6 0x00000100 /* 6 bits */ -+#define TARGET_CS7 0x00000200 /* 7 bits */ -+#define TARGET_CS8 0x00000300 /* 8 bits */ -+#define TARGET_CSTOPB 0x00000400 /* send 2 stop bits */ -+#define TARGET_CREAD 0x00000800 /* enable receiver */ -+#define TARGET_PARENB 0x00001000 /* parity enable */ -+#define TARGET_PARODD 0x00002000 /* odd parity, else even */ -+#define TARGET_HUPCL 0x00004000 /* hang up on last close */ -+#define TARGET_CLOCAL 0x00008000 /* ignore modem status lines */ -+#define TARGET_CCTS_OFLOW 0x00010000 /* CTS flow control of output */ -+#define TARGET_CRTSCTS (TARGET_CCTS_OFLOW | TARGET_CRTS_IFLOW) -+#define TARGET_CRTS_IFLOW 0x00020000 /* RTS flow control of input */ -+#define TARGET_CDTR_IFLOW 0x00040000 /* DTR flow control of input */ -+#define TARGET_CDSR_OFLOW 0x00080000 /* DSR flow control of output */ -+#define TARGET_CCAR_OFLOW 0x00100000 /* DCD flow control of output */ -+ -+/* -+ * "Local" flags - dumping ground for other state -+ */ -+#define TARGET_ECHOKE 0x00000001 /* visual erase for line kill */ -+#define TARGET_ECHOE 0x00000002 /* visually erase chars */ -+#define TARGET_ECHOK 0x00000004 /* echo NL after line kill */ -+#define TARGET_ECHO 0x00000008 /* enable echoing */ -+#define TARGET_ECHONL 0x00000010 /* echo NL even if ECHO is off */ -+#define TARGET_ECHOPRT 0x00000020 /* visual erase mode for hardcopy */ -+#define TARGET_ECHOCTL 0x00000040 /* echo control chars as ^(Char) */ -+#define TARGET_ISIG 0x00000080 /* enable signals INTR, QUIT, [D]SUSP */ -+#define TARGET_ICANON 0x00000100 /* canonicalize input lines */ -+#define TARGET_ALTWERASE 0x00000200 /* use alternate WERASE algorithm */ -+#define TARGET_IEXTEN 0x00000400 /* enable DISCARD and LNEXT */ -+#define TARGET_EXTPROC 0x00000800 /* external processing */ -+#define TARGET_TOSTOP 0x00400000 /* stop background jobs from output */ -+#define TARGET_FLUSHO 0x00800000 /* output being flushed (state) */ -+#define TARGET_NOKERNINFO 0x02000000 /* no kernel output from VSTATUS */ -+#define TARGET_PENDIN 0x20000000 /* XXX retype pending input (state) */ -+#define TARGET_NOFLSH 0x80000000 /* don't flush after interrupt */ -+ -+struct target_termios { -+ uint32_t c_iflag; /* input flags */ -+ uint32_t c_oflag; /* output flags */ -+ uint32_t c_cflag; /* control flags */ -+ uint32_t c_lflag; /* local flags */ -+ uint8_t c_cc[TARGET_NCCS]; /* control chars */ -+ uint32_t c_ispeed; /* input speed */ -+ uint32_t c_ospeed; /* output speed */ -+}; -+ -+ -+struct target_winsize { -+ uint16_t ws_row; /* rows, in characters */ -+ uint16_t ws_col; /* columns, in characters */ -+ uint16_t ws_xpixel; /* horizontal size, pixels */ -+ uint16_t ws_ypixel; /* vertical size, pixels */ -+}; -+ -+ /* 0-2 compat */ -+ /* 3-7 unused */ -+ /* 8-10 compat */ -+ /* 11-12 unused */ -+#define TARGET_TIOCEXCL TARGET_IO('t', 13) /* set exclusive use of tty */ -+#define TARGET_TIOCNXCL TARGET_IO('t', 14) /* reset exclusive use of tty */ -+#define TARGET_TIOCGPTN TARGET_IOR('t', 15, int) /* Get pts number. */ -+#define TARGET_TIOCFLUSH TARGET_IOW('t', 16, int) /* flush buffers */ -+ /* 17-18 compat */ -+/* get termios struct */ -+#define TARGET_TIOCGETA TARGET_IOR('t', 19, struct target_termios) -+/* set termios struct */ -+#define TARGET_TIOCSETA TARGET_IOW('t', 20, struct target_termios) -+/* drain output, set */ -+#define TARGET_TIOCSETAW TARGET_IOW('t', 21, struct target_termios) -+/* drn out, fls in, set */ -+#define TARGET_TIOCSETAF TARGET_IOW('t', 22, struct target_termios) -+ /* 23-25 unused */ -+#define TARGET_TIOCGETD TARGET_IOR('t', 26, int) /* get line discipline */ -+#define TARGET_TIOCSETD TARGET_IOW('t', 27, int) /* set line discipline */ -+#define TARGET_TIOCPTMASTER TARGET_IO('t', 28) /* pts master validation */ -+ /* 29-85 unused */ -+/* get ttywait timeout */ -+#define TARGET_TIOCGDRAINWAIT TARGET_IOR('t', 86, int) -+/* set ttywait timeout */ -+#define TARGET_TIOCSDRAINWAIT TARGET_IOW('t', 87, int) -+ /* 88 unused */ -+ /* 89-91 conflicts: tun and tap */ -+/* enable/get timestamp of last input event */ -+#define TARGET_TIOCTIMESTAMP TARGET_IOR('t', 89, struct target_timeval) -+/* modem: get wait on close */ -+#define TARGET_TIOCMGDTRWAIT TARGET_IOR('t', 90, int) -+/* modem: set wait on close */ -+#define TARGET_TIOCMSDTRWAIT TARGET_IOW('t', 91, int) -+ /* 92-93 tun and tap */ -+ /* 94-97 conflicts: tun and tap */ -+/* wait till output drained */ -+#define TARGET_TIOCDRAIN TARGET_IO('t', 94) -+ /* pty: generate signal */ -+#define TARGET_TIOCSIG TARGET_IOWINT('t', 95) -+/* pty: external processing */ -+#define TARGET_TIOCEXT TARGET_IOW('t', 96, int) -+/* become controlling tty */ -+#define TARGET_TIOCSCTTY TARGET_IO('t', 97) -+/* become virtual console */ -+#define TARGET_TIOCCONS TARGET_IOW('t', 98, int) -+/* get session id */ -+#define TARGET_TIOCGSID TARGET_IOR('t', 99, int) -+ /* 100 unused */ -+/* simulate ^T status message */ -+#define TARGET_TIOCSTAT TARGET_IO('t', 101) -+ /* pty: set/clr usr cntl mode */ -+#define TARGET_TIOCUCNTL TARGET_IOW('t', 102, int) -+/* usr cntl op "n" */ -+#define TARGET_TIOCCMD(n) TARGET_IO('u', n) -+/* set window size */ -+#define TARGET_TIOCSWINSZ TARGET_IOW('t', 103, struct target_winsize) -+/* get window size */ -+#define TARGET_TIOCGWINSZ TARGET_IOR('t', 104, struct target_winsize) -+ /* 105 unused */ -+/* get all modem bits */ -+#define TARGET_TIOCMGET TARGET_IOR('t', 106, int) -+#define TARGET_TIOCM_LE 0001 /* line enable */ -+#define TARGET_TIOCM_DTR 0002 /* data terminal ready */ -+#define TARGET_TIOCM_RTS 0004 /* request to send */ -+#define TARGET_TIOCM_ST 0010 /* secondary transmit */ -+#define TARGET_TIOCM_SR 0020 /* secondary receive */ -+#define TARGET_TIOCM_CTS 0040 /* clear to send */ -+#define TARGET_TIOCM_DCD 0100 /* data carrier detect */ -+#define TARGET_TIOCM_RI 0200 /* ring indicate */ -+#define TARGET_TIOCM_DSR 0400 /* data set ready */ -+#define TARGET_TIOCM_CD TARGET_TIOCM_DCD -+#define TARGET_TIOCM_CAR TARGET_TIOCM_DCD -+#define TARGET_TIOCM_RNG TARGET_TIOCM_RI -+#define TARGET_TIOCMBIC TARGET_IOW('t', 107, int) /* bic modem bits */ -+#define TARGET_TIOCMBIS TARGET_IOW('t', 108, int) /* bis modem bits */ -+#define TARGET_TIOCMSET TARGET_IOW('t', 109, int) /* set all modem bits */ -+/* start output, like ^Q */ -+#define TARGET_TIOCSTART TARGET_IO('t', 110) -+/* stop output, like ^S */ -+#define TARGET_TIOCSTOP TARGET_IO('t', 111) -+/* pty: set/clear packet mode */ -+#define TARGET_TIOCPKT TARGET_IOW('t', 112, int) -+#define TARGET_TIOCPKT_DATA 0x00 /* data packet */ -+#define TARGET_TIOCPKT_FLUSHREAD 0x01 /* flush packet */ -+#define TARGET_TIOCPKT_FLUSHWRITE 0x02 /* flush packet */ -+#define TARGET_TIOCPKT_STOP 0x04 /* stop output */ -+#define TARGET_TIOCPKT_START 0x08 /* start output */ -+#define TARGET_TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */ -+#define TARGET_TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */ -+#define TARGET_TIOCPKT_IOCTL 0x40 /* state change of pty -+ driver */ -+#define TARGET_TIOCNOTTY TARGET_IO('t', 113) /* void tty -+ association */ -+#define TARGET_TIOCSTI TARGET_IOW('t', 114, char) /* simulate -+ terminal input */ -+#define TARGET_TIOCOUTQ TARGET_IOR('t', 115, int) /* output queue size */ -+ /* 116-117 compat */ -+#define TARGET_TIOCSPGRP TARGET_IOW('t', 118, int) /* set pgrp of tty */ -+#define TARGET_TIOCGPGRP TARGET_IOR('t', 119, int) /* get pgrp of tty */ -+#define TARGET_TIOCCDTR TARGET_IO('t', 120) /* clear data terminal -+ ready */ -+#define TARGET_TIOCSDTR TARGET_IO('t', 121) /* set data terminal -+ ready */ -+#define TARGET_TIOCCBRK TARGET_IO('t', 122) /* clear break bit */ -+#define TARGET_TIOCSBRK TARGET_IO('t', 123) /* set break bit */ -+ /* 124-127 compat */ -+ -+#define TARGET_TTYDISC 0 /* termios tty line -+ discipline */ -+#define TARGET_SLIPDISC 4 /* serial IP discipline */ -+#define TARGET_PPPDISC 5 /* PPP discipline */ -+#define TARGET_NETGRAPHDISC 6 /* Netgraph tty node -+ discipline */ -+#define TARGET_H4DISC 7 /* Netgraph Bluetooth H4 -+ discipline */ -+ -+#endif /*! _IOCTL_TTYCOM_H_ */ -diff --git a/bsd-user/netbsd/os-ioctl-types.h b/bsd-user/netbsd/os-ioctl-types.h -new file mode 100644 -index 0000000..e761c20 ---- /dev/null -+++ b/bsd-user/netbsd/os-ioctl-types.h -@@ -0,0 +1,7 @@ -+/* XXX should be fixed for NetBSD types and structs */ -+STRUCT_SPECIAL(termios) -+ -+STRUCT(winsize, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT) -+ -+STRUCT(fiodgname_arg, TYPE_INT, TYPE_PTRVOID) -+ -diff --git a/bsd-user/netbsd/os-misc.h b/bsd-user/netbsd/os-misc.h -new file mode 100644 -index 0000000..8be3662 ---- /dev/null -+++ b/bsd-user/netbsd/os-misc.h -@@ -0,0 +1,375 @@ -+/* -+ * miscellaneous NetBSD system call shims -+ * -+ * 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 __OS_MISC_H_ -+#define __OS_MISC_H_ -+ -+/* -+ * XXX To support FreeBSD binaries on NetBSD these syscalls will need -+ * to be emulated. -+ */ -+ -+/* sched_setparam(2) */ -+static inline abi_long do_freebsd_sched_setparam(pid_t pid, -+ abi_ulong target_sp_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sched_setparam()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sched_get_param(2) */ -+static inline abi_long do_freebsd_sched_getparam(pid_t pid, -+ abi_ulong target_sp_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sched_getparam()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sched_setscheduler(2) */ -+static inline abi_long do_freebsd_sched_setscheduler(pid_t pid, int policy, -+ abi_ulong target_sp_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sched_setscheduler()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sched_getscheduler(2) */ -+static inline abi_long do_freebsd_sched_getscheduler(pid_t pid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sched_getscheduler()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sched_getscheduler(2) */ -+static inline abi_long do_freebsd_sched_rr_get_interval(pid_t pid, -+ abi_ulong target_ts_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sched_rr_get_interval()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cpuset(2) */ -+static inline abi_long do_freebsd_cpuset(abi_ulong target_cpuid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cpuset()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cpuset_setid(2) */ -+static inline abi_long do_freebsd_cpuset_setid(void *cpu_env, abi_long arg1, -+ abi_ulong arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cpuset_setid()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cpuset_getid(2) */ -+static inline abi_long do_freebsd_cpuset_getid(abi_long arg1, abi_ulong arg2, -+ abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cpuset_getid()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cpuset_getaffinity(2) */ -+static inline abi_long do_freebsd_cpuset_getaffinity(abi_long arg1, -+ abi_ulong arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5, -+ abi_ulong arg6) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cpuset_getaffinity()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cpuset_setaffinity(2) */ -+static inline abi_long do_freebsd_cpuset_setaffinity(abi_long arg1, -+ abi_ulong arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5, -+ abi_ulong arg6) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cpuset_setaffinity()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* modfnext(2) */ -+static inline abi_long do_freebsd_modfnext(abi_long modid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall modfnext()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* modfind(2) */ -+static inline abi_long do_freebsd_modfind(abi_ulong target_name) -+{ -+ -+ qemu_log("qemu: Unsupported syscall modfind()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldload(2) */ -+static inline abi_long do_freebsd_kldload(abi_ulong target_name) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldload()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldunload(2) */ -+static inline abi_long do_freebsd_kldunload(abi_long fileid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldunload()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldunloadf(2) */ -+static inline abi_long do_freebsd_kldunloadf(abi_long fileid, abi_long flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldunloadf()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldfind(2) */ -+static inline abi_long do_freebsd_kldfind(abi_ulong target_name) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldfind()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldnext(2) */ -+static inline abi_long do_freebsd_kldnext(abi_long fileid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldnext()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* kldstat(2) */ -+static inline abi_long do_freebsd_kldstat(abi_long fileid, -+ abi_ulong target_stat) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldstat()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldfirstmod(2) */ -+static inline abi_long do_freebsd_kldfirstmod(abi_long fileid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldfirstmod()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldsym(2) */ -+static inline abi_long do_freebsd_kldsym(abi_long fileid, abi_long cmd, -+ abi_ulong target_data) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldsym()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * Resource limits (undocumented except for rctl(8) and rctl.conf(5) ) -+ */ -+/* rctl_get_racct() */ -+static inline abi_long do_freebsd_rctl_get_racct(abi_ulong target_inbufp, -+ abi_ulong inbuflen, abi_ulong target_outbufp, abi_ulong outbuflen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rctl_get_racct()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* rctl_get_rules() */ -+static inline abi_long do_freebsd_rctl_get_rules(abi_ulong target_inbufp, -+ abi_ulong inbuflen, abi_ulong target_outbufp, abi_ulong outbuflen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rctl_get_rules()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* rctl_add_rule() */ -+static inline abi_long do_freebsd_rctl_add_rule(abi_ulong target_inbufp, -+ abi_ulong inbuflen, abi_ulong target_outbufp, abi_ulong outbuflen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rctl_add_rule()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* rctl_remove_rule() */ -+static inline abi_long do_freebsd_rctl_remove_rule(abi_ulong target_inbufp, -+ abi_ulong inbuflen, abi_ulong target_outbufp, abi_ulong outbuflen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rctl_remove_rule()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* rctl_get_limits() */ -+static inline abi_long do_freebsd_rctl_get_limits(abi_ulong target_inbufp, -+ abi_ulong inbuflen, abi_ulong target_outbufp, abi_ulong outbuflen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rctl_get_limits()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * Kernel environment -+ */ -+ -+/* kenv(2) */ -+static inline abi_long do_freebsd_kenv(abi_long what, abi_ulong target_name, -+ abi_ulong target_value, abi_long len) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kenv()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* -+ * Mandatory Access Control -+ */ -+ -+/* __mac_get_proc */ -+static inline abi_long do_freebsd___mac_get_proc(abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_get_proc()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_set_proc */ -+static inline abi_long do_freebsd___mac_set_proc(abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_set_proc()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* __mac_get_fd */ -+static inline abi_long do_freebsd___mac_get_fd(abi_long fd, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_get_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_set_fd */ -+static inline abi_long do_freebsd___mac_set_fd(abi_long fd, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_set_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_get_file */ -+static inline abi_long do_freebsd___mac_get_file(abi_ulong target_path, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_get_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_set_file */ -+static inline abi_long do_freebsd___mac_set_file(abi_ulong target_path, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_set_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_get_link */ -+static inline abi_long do_freebsd___mac_get_link(abi_ulong target_path, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_get_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_set_link */ -+static inline abi_long do_freebsd___mac_set_link(abi_ulong target_path, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_set_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* mac_syscall */ -+static inline abi_long do_freebsd_mac_syscall(abi_ulong target_policy, -+ abi_long call, abi_ulong target_arg) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_syscall()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* -+ * New posix calls -+ */ -+/* posix_fallocate(2) */ -+static inline abi_long do_freebsd_posix_fallocate(abi_long fd, abi_ulong offset, -+ abi_ulong len) -+{ -+ -+ qemu_log("qemu: Unsupported syscall posix_fallocate()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* posix_openpt(2) */ -+static inline abi_long do_freebsd_posix_openpt(abi_long flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall posix_openpt()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* posix_fadvise(2) */ -+static inline abi_long do_freebsd_posix_fadvise(abi_long fd, abi_ulong offset, -+ abi_ulong len, abi_long advise) -+{ -+ -+ qemu_log("qemu: Unsupported syscall posix_fadvise()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* ! __OS_MISC_H_ */ -diff --git a/bsd-user/netbsd/os-proc.c b/bsd-user/netbsd/os-proc.c -new file mode 100644 -index 0000000..bc11d29 ---- /dev/null -+++ b/bsd-user/netbsd/os-proc.c -@@ -0,0 +1,11 @@ -+/* -+ * XXX To support FreeBSD binaries on NetBSD the following will need to be -+ * emulated. -+ */ -+abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, -+ abi_ulong guest_envp, int do_fexec) -+{ -+ -+ qemu_log("qemu: Unsupported %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -diff --git a/bsd-user/netbsd/os-proc.h b/bsd-user/netbsd/os-proc.h -new file mode 100644 -index 0000000..f34d616 ---- /dev/null -+++ b/bsd-user/netbsd/os-proc.h -@@ -0,0 +1,243 @@ -+#ifndef __NETBSD_PROC_H_ -+#define __NETBSD_PROC_H_ -+ -+/* -+ * XXX To support FreeBSD binaries on NetBSD these syscalls will need -+ * to be emulated. -+ */ -+ -+/* execve(2) */ -+static inline abi_long do_freebsd_execve(abi_ulong path_or_fd, abi_ulong argp, -+ abi_ulong envp) -+{ -+ -+ qemu_log("qemu: Unsupported syscall execve()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* fexecve(2) */ -+static inline abi_long do_freebsd_fexecve(abi_ulong path_or_fd, abi_ulong argp, -+ abi_ulong envp) -+{ -+ -+ qemu_log("qemu: Unsupported syscall fexecve()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* wait4(2) */ -+static inline abi_long do_freebsd_wait4(abi_long arg1, abi_ulong target_status, -+ abi_long arg3, abi_ulong target_rusage) -+{ -+ -+ qemu_log("qemu: Unsupported syscall wait4()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* setloginclass(2) */ -+static inline abi_long do_freebsd_setloginclass(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall setloginclass()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getloginclass(2) */ -+static inline abi_long do_freebsd_getloginclass(abi_ulong arg1, abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getloginclass()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* pdwait4(2) */ -+static inline abi_long do_freebsd_pdwait4(abi_long arg1, -+ abi_ulong target_status, abi_long arg3, abi_ulong target_rusage) -+{ -+ -+ qemu_log("qemu: Unsupported syscall pdwait4()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* pdgetpid(2) */ -+static inline abi_long do_freebsd_pdgetpid(abi_long fd, abi_ulong target_pidp) -+{ -+ -+ qemu_log("qemu: Unsupported syscall pdgetpid()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* undocumented __setugid */ -+static inline abi_long do_freebsd___setugid(abi_long arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __setugid()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* fork(2) */ -+static inline abi_long do_freebsd_fork(void *cpu_env) -+{ -+ -+ qemu_log("qemu: Unsupported syscall fork()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* vfork(2) */ -+static inline abi_long do_freebsd_vfork(void *cpu_env) -+{ -+ -+ qemu_log("qemu: Unsupported syscall vfork()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* rfork(2) */ -+static inline abi_long do_freebsd_rfork(void *cpu_env, abi_long flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rfork()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* pdfork(2) */ -+static inline abi_long do_freebsd_pdfork(void *cpu_env, abi_ulong arg1, -+ abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall pdfork()\n"); -+ return -TARGET_ENOSYS -+} -+ -+/* jail(2) */ -+static inline abi_long do_freebsd_jail(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall jail()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* jail_attach(2) */ -+static inline abi_long do_freebsd_jail_attach(abi_long arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall jail_attach()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* jail_remove(2) */ -+static inline abi_long do_freebsd_jail_remove(abi_long arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall jail_remove()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* jail_get(2) */ -+static inline abi_long do_freebsd_jail_get(abi_ulong arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall jail_get()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* jail_set(2) */ -+static inline abi_long do_freebsd_jail_set(abi_ulong arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall jail_set()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_enter(2) */ -+static inline abi_long do_freebsd_cap_enter(void) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_enter()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_new(2) */ -+static inline abi_long do_freebsd_cap_new(abi_long arg1, abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_new()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_getrights(2) */ -+static inline abi_long do_freebsd_cap_getrights(abi_long arg1, abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_getrights()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_getmode(2) */ -+static inline abi_long do_freebsd_cap_getmode(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_getmode()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* audit(2) */ -+static inline abi_long do_freebsd_audit(abi_ulong arg1, abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall audit()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* auditon(2) */ -+static inline abi_long do_freebsd_auditon(abi_long arg1, abi_ulong arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall auditon()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getaudit(2) */ -+static inline abi_long do_freebsd_getaudit(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getaudit()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* setaudit(2) */ -+static inline abi_long do_freebsd_setaudit(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall setaudit()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getaudit_addr(2) */ -+static inline abi_long do_freebsd_getaudit_addr(abi_ulong arg1, -+ abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getaudit_addr()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* setaudit_addr(2) */ -+static inline abi_long do_freebsd_setaudit_addr(abi_ulong arg1, -+ abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall setaudit_addr()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* auditctl(2) */ -+static inline abi_long do_freebsd_auditctl(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall auditctl()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* ! __NETBSD_PROC_H_ */ -diff --git a/bsd-user/netbsd/os-socket.c b/bsd-user/netbsd/os-socket.c -new file mode 100644 -index 0000000..d983c34 ---- /dev/null -+++ b/bsd-user/netbsd/os-socket.c -@@ -0,0 +1 @@ -+/* XXX NetBSD socket related helpers */ -diff --git a/bsd-user/netbsd/os-socket.h b/bsd-user/netbsd/os-socket.h -new file mode 100644 -index 0000000..a49c41d ---- /dev/null -+++ b/bsd-user/netbsd/os-socket.h -@@ -0,0 +1,98 @@ -+/* -+ * NetBSD socket related system call shims -+ * -+ * -+ * 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 __NETBSD_SOCKET_H_ -+#define __NETBSD_SOCKET_H_ -+ -+/* -+ * XXX To support FreeBSD binaries on NetBSD these syscalls will need -+ * to be emulated. -+ */ -+ -+/* sendmsg(2) */ -+static inline abi_long do_freebsd_sendmsg(int fd, abi_ulong target_msg, -+ int flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sendmsg()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* recvmsg(2) */ -+static inline abi_long do_freebsd_recvmsg(int fd, abi_ulong target_msg, -+ int flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall recvmsg()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* setsockopt(2) */ -+static inline abi_long do_bsd_setsockopt(int sockfd, int level, int optname, -+ abi_ulong optval_addr, socklen_t optlen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall setsockopt()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getsockopt(2) */ -+static inline abi_long do_bsd_getsockopt(int sockfd, int level, int optname, -+ abi_ulong optval_addr, abi_ulong optlen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getsockopt()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* setfib(2) */ -+static inline abi_long do_freebsd_setfib(abi_long fib) -+{ -+ -+ qemu_log("qemu: Unsupported syscall setfib()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sctp_peeloff(2) */ -+static inline abi_long do_freebsd_sctp_peeloff(abi_long s, abi_ulong id) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sctp_peeloff()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sctp_generic_sendmsg(2) */ -+static inline abi_long do_freebsd_sctp_generic_sendmsg(abi_long s, -+ abi_ulong target_msg, abi_long msglen, abi_ulong target_to, -+ abi_ulong len, abi_ulong target_sinfo, abi_long flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sctp_generic_sendmsg()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sctp_generic_recvmsg(2) */ -+static inline abi_long do_freebsd_sctp_generic_recvmsg(abi_long s, -+ abi_ulong target_iov, abi_long iovlen, abi_ulong target_from, -+ abi_ulong fromlen, abi_ulong target_sinfo, abi_ulong target_msgflags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sctp_generic_recvmsg()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* !__NETBSD_SOCKET_H_ */ -diff --git a/bsd-user/netbsd/os-stat.c b/bsd-user/netbsd/os-stat.c -new file mode 100644 -index 0000000..11ea122 ---- /dev/null -+++ b/bsd-user/netbsd/os-stat.c -@@ -0,0 +1 @@ -+/* XXX NetBSD stat related helpers */ -diff --git a/bsd-user/netbsd/os-stat.h b/bsd-user/netbsd/os-stat.h -new file mode 100644 -index 0000000..11ea122 ---- /dev/null -+++ b/bsd-user/netbsd/os-stat.h -@@ -0,0 +1 @@ -+/* XXX NetBSD stat related helpers */ -diff --git a/bsd-user/netbsd/os-strace.h b/bsd-user/netbsd/os-strace.h -new file mode 100644 -index 0000000..70cf51d ---- /dev/null -+++ b/bsd-user/netbsd/os-strace.h -@@ -0,0 +1 @@ -+/* XXX NetBSD dependent strace print functions */ -diff --git a/bsd-user/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/os-thread.c b/bsd-user/netbsd/os-thread.c -new file mode 100644 -index 0000000..a4af765 ---- /dev/null -+++ b/bsd-user/netbsd/os-thread.c -@@ -0,0 +1 @@ -+/* XXX NetBSD thread related helpers */ -diff --git a/bsd-user/netbsd/os-thread.h b/bsd-user/netbsd/os-thread.h -new file mode 100644 -index 0000000..073b0a0 ---- /dev/null -+++ b/bsd-user/netbsd/os-thread.h -@@ -0,0 +1,133 @@ -+#ifndef __NETBSD_OS_THREAD_H_ -+#define __NETBSD_OS_THREAD_H_ -+ -+/* -+ * XXX To support FreeBSD binaries on NetBSD these syscalls will need to -+ * be emulated. -+ */ -+static abi_long do_freebsd_thr_create(CPUArchState *env, abi_ulong target_ctx, -+ abi_ulong target_id, int flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_create()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_create(CPUArchState *env, abi_ulong thread_ctx, -+ abi_ulong target_id, int flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_create()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_new(CPUArchState *env, -+ abi_ulong target_param_addr, int32_t param_size) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_new()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_self(abi_ulong target_id) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_self()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_exit(CPUArchState *cpu_env, abi_ulong tid_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_exit()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_kill(long id, int sig) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_kill()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_kill2(pid_t pid, long id, int sig) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_kill2()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_suspend(abi_ulong target_ts) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_suspend()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_wake(long tid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_wake()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_set_name(long tid, abi_ulong target_name) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_set_name()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_rtprio_thread(int function, lwpid_t lwpid, -+ abi_ulong target_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rtprio_thread()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_getcontext(void *cpu_env, abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getcontext()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_setcontext(void *cpu_env, abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall setcontext()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_swapcontext(void *cpu_env, abi_ulong arg1, -+ abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall swapcontext()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd__umtx_lock(abi_ulong target_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall _umtx_lock()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd__umtx_unlock(abi_ulong target_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall _umtx_unlock()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, -+ abi_ulong uaddr, abi_ulong target_ts) -+{ -+ -+ qemu_log("qemu: Unsupported syscall _umtx_op()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* ! __NETBSD_OS_THREAD_H_ */ -diff --git a/bsd-user/netbsd/os-time.c b/bsd-user/netbsd/os-time.c -new file mode 100644 -index 0000000..ee2c7a0 ---- /dev/null -+++ b/bsd-user/netbsd/os-time.c -@@ -0,0 +1 @@ -+/* XXX NetBSD time related helpers */ -diff --git a/bsd-user/netbsd/os-time.h b/bsd-user/netbsd/os-time.h -new file mode 100644 -index 0000000..6d0f1de ---- /dev/null -+++ b/bsd-user/netbsd/os-time.h -@@ -0,0 +1,179 @@ -+#ifndef __NETBSD_OS_TIME_H_ -+#define __NETBSD_OS_TIME_H_ -+ -+/* -+ * XXX To support FreeBSD binaries on NetBSD these syscalls will need to -+ * be emulated. -+ */ -+static inline abi_long do_freebsd_nanosleep(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_clock_gettime(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_clock_settime(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_clock_getres(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_gettimeofday(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_settimeofday(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_adjtime(abi_ulong target_delta_addr, -+ abi_ulong target_old_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_ntp_adjtime(abi_ulong target_tx_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_ntp_gettime(abi_ulong target_ntv_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_utimes(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_lutimes(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_futimes(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_futimesat(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_ktimer_create(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_ktimer_delete(abi_long arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_ktimer_settime(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_ktimer_gettime(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_ktimer_getoverrun(abi_long arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_select(int n, abi_ulong rfd_addr, -+ abi_ulong wfd_addr, abi_ulong efd_addr, abi_ulong target_tv_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+ -+static inline abi_long do_freebsd_pselect(int n, abi_ulong rfd_addr, -+ abi_ulong wfd_addr, abi_ulong efd_addr, abi_ulong ts_addr, -+ abi_ulong set_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_kqueue(void) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_kevent(abi_long arg1, abi_ulong arg2, -+ abi_long arg3, abi_ulong arg4, abi_long arg5, abi_long arg6) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_sigtimedwait(abi_ulong arg1, abi_ulong arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* ! __NETBSD_OS_TIME_H_ */ -diff --git a/bsd-user/netbsd/qemu-os.h b/bsd-user/netbsd/qemu-os.h -new file mode 100644 -index 0000000..016618b ---- /dev/null -+++ b/bsd-user/netbsd/qemu-os.h -@@ -0,0 +1 @@ -+/* NetBSD conversion extern declarations */ -diff --git a/bsd-user/netbsd/target_os_elf.h b/bsd-user/netbsd/target_os_elf.h -new file mode 100644 -index 0000000..bf663d2 ---- /dev/null -+++ b/bsd-user/netbsd/target_os_elf.h -@@ -0,0 +1,226 @@ -+/* -+ * netbsd ELF 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 _TARGET_OS_ELF_H_ -+#define _TARGET_OS_ELF_H_ -+ -+#include "target_arch_elf.h" -+#include "elf.h" -+ -+/* from personality.h */ -+ -+/* -+ * Flags for bug emulation. -+ * -+ * These occupy the top three bytes. -+ */ -+enum { -+ ADDR_NO_RANDOMIZE = 0x0040000, /* disable randomization of VA -+ space */ -+ FDPIC_FUNCPTRS = 0x0080000, /* userspace function ptrs -+ point to descriptors -+ (signal handling) */ -+ MMAP_PAGE_ZERO = 0x0100000, -+ ADDR_COMPAT_LAYOUT = 0x0200000, -+ READ_IMPLIES_EXEC = 0x0400000, -+ ADDR_LIMIT_32BIT = 0x0800000, -+ SHORT_INODE = 0x1000000, -+ WHOLE_SECONDS = 0x2000000, -+ STICKY_TIMEOUTS = 0x4000000, -+ ADDR_LIMIT_3GB = 0x8000000, -+}; -+ -+/* -+ * Personality types. -+ * -+ * These go in the low byte. Avoid using the top bit, it will -+ * conflict with error returns. -+ */ -+enum { -+ PER_LINUX = 0x0000, -+ PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT, -+ PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS, -+ PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, -+ PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE, -+ PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS | -+ WHOLE_SECONDS | SHORT_INODE, -+ PER_OSR5 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS, -+ PER_WYSEV386 = 0x0004 | STICKY_TIMEOUTS | SHORT_INODE, -+ PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS, -+ PER_BSD = 0x0006, -+ PER_SUNOS = 0x0006 | STICKY_TIMEOUTS, -+ PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE, -+ PER_LINUX32 = 0x0008, -+ PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB, -+ PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */ -+ PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */ -+ PER_IRIX64 = 0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */ -+ PER_RISCOS = 0x000c, -+ PER_SOLARIS = 0x000d | STICKY_TIMEOUTS, -+ PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, -+ PER_OSF4 = 0x000f, /* OSF/1 v4 */ -+ PER_HPUX = 0x0010, -+ PER_MASK = 0x00ff, -+}; -+ -+/* -+ * Return the base personality without flags. -+ */ -+#define personality(pers) (pers & PER_MASK) -+ -+/* this flag is uneffective under linux too, should be deleted */ -+#ifndef MAP_DENYWRITE -+#define MAP_DENYWRITE 0 -+#endif -+ -+/* should probably go in elf.h */ -+#ifndef ELIBBAD -+#define ELIBBAD 80 -+#endif -+ -+#ifndef ELF_PLATFORM -+#define ELF_PLATFORM (NULL) -+#endif -+ -+#ifndef ELF_HWCAP -+#define ELF_HWCAP 0 -+#endif -+ -+#ifdef TARGET_ABI32 -+#undef ELF_CLASS -+#define ELF_CLASS ELFCLASS32 -+#undef bswaptls -+#define bswaptls(ptr) bswap32s(ptr) -+#endif -+ -+struct exec -+{ -+ unsigned int a_info; /* Use macros N_MAGIC, etc for access */ -+ unsigned int a_text; /* length of text, in bytes */ -+ unsigned int a_data; /* length of data, in bytes */ -+ unsigned int a_bss; /* length of uninitialized data area, in bytes */ -+ unsigned int a_syms; /* length of symbol table data in file, in bytes */ -+ unsigned int a_entry; /* start address */ -+ unsigned int a_trsize; /* length of relocation info for text, in bytes */ -+ unsigned int a_drsize; /* length of relocation info for data, in bytes */ -+}; -+ -+ -+#define N_MAGIC(exec) ((exec).a_info & 0xffff) -+#define OMAGIC 0407 -+#define NMAGIC 0410 -+#define ZMAGIC 0413 -+#define QMAGIC 0314 -+ -+/* max code+data+bss space allocated to elf interpreter */ -+#define INTERP_MAP_SIZE (32 * 1024 * 1024) -+ -+/* max code+data+bss+brk space allocated to ET_DYN executables */ -+#define ET_DYN_MAP_SIZE (128 * 1024 * 1024) -+ -+/* Necessary parameters */ -+#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE -+#define TARGET_ELF_PAGESTART(_v) ((_v) & \ -+ ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1)) -+#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1)) -+ -+#define INTERPRETER_NONE 0 -+#define INTERPRETER_AOUT 1 -+#define INTERPRETER_ELF 2 -+ -+#define DLINFO_ITEMS 12 -+ -+static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc, -+ struct elfhdr * exec, -+ abi_ulong load_addr, -+ abi_ulong load_bias, -+ abi_ulong interp_load_addr, int ibcs, -+ struct image_info *info) -+{ -+ abi_ulong sp; -+ int size; -+ abi_ulong u_platform; -+ const char *k_platform; -+ const int n = sizeof(elf_addr_t); -+ -+ sp = p; -+ u_platform = 0; -+ k_platform = ELF_PLATFORM; -+ if (k_platform) { -+ size_t len = strlen(k_platform) + 1; -+ sp -= (len + n - 1) & ~(n - 1); -+ u_platform = sp; -+ /* FIXME - check return value of memcpy_to_target() for failure */ -+ memcpy_to_target(sp, k_platform, len); -+ } -+ /* -+ * Force 16 byte _final_ alignment here for generality. -+ */ -+ sp = sp &~ (abi_ulong)15; -+ size = (DLINFO_ITEMS + 1) * 2; -+ if (k_platform) -+ size += 2; -+#ifdef DLINFO_ARCH_ITEMS -+ size += DLINFO_ARCH_ITEMS * 2; -+#endif -+ size += envc + argc + 2; -+ size += (!ibcs ? 3 : 1); /* argc itself */ -+ size *= n; -+ if (size & 15) -+ sp -= 16 - (size & 15); -+ -+ /* This is correct because Linux defines -+ * elf_addr_t as Elf32_Off / Elf64_Off -+ */ -+#define NEW_AUX_ENT(id, val) do { \ -+ sp -= n; put_user_ual(val, sp); \ -+ sp -= n; put_user_ual(id, sp); \ -+ } while(0) -+ -+ NEW_AUX_ENT (AT_NULL, 0); -+ -+ /* There must be exactly DLINFO_ITEMS entries here. */ -+ NEW_AUX_ENT(AT_PHDR, (abi_ulong)(load_addr + exec->e_phoff)); -+ NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr))); -+ NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum)); -+ NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(TARGET_PAGE_SIZE)); -+ NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_load_addr)); -+ NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0); -+ NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry); -+ NEW_AUX_ENT(AT_UID, (abi_ulong) getuid()); -+ NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid()); -+ NEW_AUX_ENT(AT_GID, (abi_ulong) getgid()); -+ NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid()); -+ NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP); -+ NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK)); -+ if (k_platform) -+ NEW_AUX_ENT(AT_PLATFORM, u_platform); -+#ifdef ARCH_DLINFO -+ /* -+ * ARCH_DLINFO must come last so platform specific code can enforce -+ * special alignment requirements on the AUXV if necessary (eg. PPC). -+ */ -+ ARCH_DLINFO; -+#endif -+#undef NEW_AUX_ENT -+ -+ sp = loader_build_argptr(envc, argc, sp, p, !ibcs); -+ return sp; -+} -+ -+#endif /* _TARGET_OS_ELF_H_ */ -diff --git a/bsd-user/netbsd/target_os_siginfo.h b/bsd-user/netbsd/target_os_siginfo.h -new file mode 100644 -index 0000000..667c19c ---- /dev/null -+++ b/bsd-user/netbsd/target_os_siginfo.h -@@ -0,0 +1,82 @@ -+#ifndef _TARGET_OS_SIGINFO_H_ -+#define _TARGET_OS_SIGINFO_H_ -+ -+#define TARGET_NSIG 32 /* counting 0; could be 33 (mask is 1-32) */ -+#define TARGET_NSIG_BPW (sizeof(uint32_t) * 8) -+#define TARGET_NSIG_WORDS (TARGET_NSIG / TARGET_NSIG_BPW) -+ -+/* this struct defines a stack used during syscall handling */ -+typedef struct target_sigaltstack { -+ abi_long ss_sp; -+ abi_ulong ss_size; -+ abi_long ss_flags; -+} target_stack_t; -+ -+typedef struct { -+ uint32_t __bits[TARGET_NSIG_WORDS]; -+} target_sigset_t -+ -+struct target_sigaction { -+ abi_ulong _sa_handler; -+ int32_t sa_flags; -+ target_sigset_t sa_mask; -+}; -+ -+/* Compare to sys/siginfo.h */ -+typedef union target_sigval { -+ int sival_int; -+ abi_ulong sival_ptr; -+} target_sigval_t; -+ -+struct target_ksiginfo { -+ int32_t _signo; -+ int32_t _code; -+ int32_t _errno; -+#if TARGET_ABI_BITS == 64 -+ int32_t _pad; -+#endif -+ union { -+ struct { -+ int32_t _pid; -+ int32_t _uid; -+ target_sigval_t _value; -+ } _rt; -+ -+ struct { -+ int32_t _pid; -+ int32_t _uid; -+ int32_t _struct; -+ /* clock_t _utime; */ -+ /* clock_t _stime; */ -+ } _child; -+ -+ struct { -+ abi_ulong _addr; -+ int32_t _trap; -+ } _fault; -+ -+ struct { -+ long _band; -+ int _fd; -+ } _poll; -+ } _reason; -+}; -+ -+typedef union target_siginfo { -+ int8_t si_pad[128]; -+ struct target_ksiginfo _info; -+} target_siginfo_t; -+ -+#define target_si_signo _info._signo -+#define target_si_code _info._code -+#define target_si_errno _info._errno -+#define target_si_addr _info._reason._fault._addr -+ -+#define TARGET_SEGV_MAPERR 1 -+#define TARGET_SEGV_ACCERR 2 -+ -+#define TARGET_TRAP_BRKPT 1 -+#define TARGET_TRAP_TRACE 2 -+ -+ -+#endif /* ! _TARGET_OS_SIGINFO_H_ */ -diff --git a/bsd-user/netbsd/target_os_signal.h b/bsd-user/netbsd/target_os_signal.h -new file mode 100644 -index 0000000..d39a26f ---- /dev/null -+++ b/bsd-user/netbsd/target_os_signal.h -@@ -0,0 +1,70 @@ -+#ifndef _TARGET_OS_SIGNAL_H_ -+#define _TARGET_OS_SIGNAL_H_ -+ -+#include "target_os_siginfo.h" -+#include "target_arch_signal.h" -+ -+#define TARGET_SIGHUP 1 /* hangup */ -+#define TARGET_SIGINT 2 /* interrupt */ -+#define TARGET_SIGQUIT 3 /* quit */ -+#define TARGET_SIGILL 4 /* illegal instruction (not reset when caught) */ -+#define TARGET_SIGTRAP 5 /* trace trap (not reset when caught) */ -+#define TARGET_SIGABRT 6 /* abort() */ -+#define TARGET_SIGIOT SIGABRT /* compatibility */ -+#define TARGET_SIGEMT 7 /* EMT instruction */ -+#define TARGET_SIGFPE 8 /* floating point exception */ -+#define TARGET_SIGKILL 9 /* kill (cannot be caught or ignored) */ -+#define TARGET_SIGBUS 10 /* bus error */ -+#define TARGET_SIGSEGV 11 /* segmentation violation */ -+#define TARGET_SIGSYS 12 /* bad argument to system call */ -+#define TARGET_SIGPIPE 13 /* write on a pipe with no one to read it */ -+#define TARGET_SIGALRM 14 /* alarm clock */ -+#define TARGET_SIGTERM 15 /* software termination signal from kill */ -+#define TARGET_SIGURG 16 /* urgent condition on IO channel */ -+#define TARGET_SIGSTOP 17 /* sendable stop signal not from tty */ -+#define TARGET_SIGTSTP 18 /* stop signal from tty */ -+#define TARGET_SIGCONT 19 /* continue a stopped process */ -+#define TARGET_SIGCHLD 20 /* to parent on child stop or exit */ -+#define TARGET_SIGTTIN 21 /* to readers pgrp upon background tty read */ -+#define TARGET_SIGTTOU 22 /* like TTIN for output if -+ (tp->t_local<OSTOP) */ -+#define TARGET_SIGIO 23 /* input/output possible signal */ -+#define TARGET_SIGXCPU 24 /* exceeded CPU time limit */ -+#define TARGET_SIGXFSZ 25 /* exceeded file size limit */ -+#define TARGET_SIGVTALRM 26 /* virtual time alarm */ -+#define TARGET_SIGPROF 27 /* profiling time alarm */ -+#define TARGET_SIGWINCH 28 /* window size changes */ -+#define TARGET_SIGINFO 29 /* information request */ -+#define TARGET_SIGUSR1 30 /* user defined signal 1 */ -+#define TARGET_SIGUSR2 31 /* user defined signal 2 */ -+ -+/* -+ * Language spec says we must list exactly one parameter, even though we -+ * actually supply three. Ugh! -+ */ -+#define TARGET_SIG_DFL ((void (*)(int))0) -+#define TARGET_SIG_IGN ((void (*)(int))1) -+#define TARGET_SIG_ERR ((void (*)(int))-1) -+ -+#define TARGET_SA_ONSTACK 0x0001 /* take signal on signal stack */ -+#define TARGET_SA_RESTART 0x0002 /* restart system on signal return */ -+#define TARGET_SA_RESETHAND 0x0004 /* reset to SIG_DFL when taking signal */ -+#define TARGET_SA_NODEFER 0x0010 /* don't mask the signal we're delivering */ -+#define TARGET_SA_NOCLDWAIT 0x0020 /* don't create zombies (assign to pid 1) */ -+#define TARGET_SA_USERTRAMP 0x0100 /* do not bounce off kernel's sigtramp */ -+#define TARGET_SA_NOCLDSTOP 0x0008 /* do not generate SIGCHLD on child stop */ -+#define TARGET_SA_SIGINFO 0x0040 /* generate siginfo_t */ -+ -+/* -+ * Flags for sigprocmask: -+ */ -+#define TARGET_SIG_BLOCK 1 /* block specified signal set */ -+#define TARGET_SIG_UNBLOCK 2 /* unblock specified signal set */ -+#define TARGET_SIG_SETMASK 3 /* set specified signal set */ -+ -+#define TARGET_BADSIG SIG_ERR -+ -+#define TARGET_SS_ONSTACK 0x0001 /* take signals on alternate stack */ -+#define TARGET_SS_DISABLE 0x0004 /* disable taking signals on alternate stack */ -+ -+#endif /* !_TARGET_OS_SIGNAL_H_ */ -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/netbsd/target_os_thread.h b/bsd-user/netbsd/target_os_thread.h -new file mode 100644 -index 0000000..519aad8 ---- /dev/null -+++ b/bsd-user/netbsd/target_os_thread.h -@@ -0,0 +1,6 @@ -+#ifndef _TARGET_OS_THREAD_H_ -+#define _TARGET_OS_THREAD_H_ -+ -+#include "target_arch_thread.h" -+ -+#endif /* !_TARGET_OS_THREAD_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-extattr.h b/bsd-user/openbsd/os-extattr.h -new file mode 100644 -index 0000000..5c23af3 ---- /dev/null -+++ b/bsd-user/openbsd/os-extattr.h -@@ -0,0 +1,247 @@ -+/* -+ * OpenBSD extended attributes and ACL system call support -+ * -+ * 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/>. -+ */ -+ -+/* XXX To support FreeBSD targets the following will need to be added. */ -+ -+/* extattrctl() */ -+static inline abi_long do_freebsd_extattrctl(abi_ulong arg1, abi_ulong arg2, -+ abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattrctl()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_set_file(2) */ -+static inline abi_long do_freebsd_extattr_set_file(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_set_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_get_file(2) */ -+static inline abi_long do_freebsd_extattr_get_file(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_get_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_delete_file(2) */ -+static inline abi_long do_freebsd_extattr_delete_file(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_delete_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_set_fd(2) */ -+static inline abi_long do_freebsd_extattr_set_fd(abi_long arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_set_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_get_fd(2) */ -+static inline abi_long do_freebsd_extattr_get_fd(abi_long arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_get_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_delete_fd(2) */ -+static inline abi_long do_freebsd_extattr_delete_fd(abi_long arg1, -+ abi_long arg2, abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_delete_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_get_link(2) */ -+static inline abi_long do_freebsd_extattr_get_link(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_get_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_set_link(2) */ -+static inline abi_long do_freebsd_extattr_set_link(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_set_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_delete_link(2) */ -+static inline abi_long do_freebsd_extattr_delete_link(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_delete_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_list_fd(2) */ -+static inline abi_long do_freebsd_extattr_list_fd(abi_long arg1, abi_long arg2, -+ abi_ulong arg3, abi_ulong arg4) -+{ -+ -+ qemu_log("qemu: Unsupported syscall exattr_list_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_list_file(2) */ -+static inline abi_long do_freebsd_extattr_list_file(abi_long arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_list_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* extattr_list_link(2) */ -+static inline abi_long do_freebsd_extattr_list_link(abi_long arg1, -+ abi_long arg2, abi_ulong arg3, abi_ulong arg4) -+{ -+ -+ qemu_log("qemu: Unsupported syscall extattr_list_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * Access Control Lists -+ */ -+ -+/* __acl_aclcheck_fd(int filedes, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_aclcheck_fd(abi_long arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_aclcheck_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __acl_aclcheck_file(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_aclcheck_file(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_aclcheck_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __acl_aclcheck_link(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_aclcheck_link(abi_ulong arg1, -+ abi_long arg2, abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_aclcheck_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_delete_fd(int filedes, acl_type_t type); */ -+static inline abi_long do_freebsd__acl_delete_fd(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_delete_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_delete_file(const char *path, acl_type_t type); */ -+static inline abi_long do_freebsd__acl_delete_file(abi_ulong arg1, -+ abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_delete_fil()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_delete_link(const char *path, acl_type_t type); */ -+static inline abi_long do_freebsd__acl_delete_link(abi_ulong arg1, -+ abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_delete_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_get_fd(int filedes, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_get_fd(abi_long arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_get_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __acl_get_file(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_get_file(abi_ulong arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_get_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_get_link(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_get_link(abi_ulong arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall _acl_get_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_get_fd(int filedes, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_set_fd(abi_long arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_set_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_set_file(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_set_file(abi_ulong arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_set_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* int __acl_set_link(const char *path, acl_type_t type, struct acl *aclp); */ -+static inline abi_long do_freebsd__acl_set_link(abi_ulong arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __acl_set_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -diff --git a/bsd-user/openbsd/os-ioctl-cmds.h b/bsd-user/openbsd/os-ioctl-cmds.h -new file mode 100644 -index 0000000..a15f056 ---- /dev/null -+++ b/bsd-user/openbsd/os-ioctl-cmds.h -@@ -0,0 +1,48 @@ -+/* XXX should be fixed for OpenBSD ioctl cmds */ -+ -+/* sys/ttycom.h tty(4) */ -+IOCTL(TIOCSETD, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGETD, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSBRK, IOC_, TYPE_NULL) -+IOCTL(TIOCCBRK, IOC_, TYPE_NULL) -+IOCTL(TIOCSDTR, IOC_, TYPE_NULL) -+IOCTL(TIOCCDTR, IOC_, TYPE_NULL) -+IOCTL(TIOCGPGRP, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSPGRP, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGETA, IOC_R, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCSETA, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCSETAW, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCSETAF, IOC_W, MK_PTR(MK_STRUCT(STRUCT_termios))) -+IOCTL(TIOCOUTQ, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCSTI, IOC_W, MK_PTR(TYPE_CHAR)) -+IOCTL(TIOCNOTTY, IOC_, TYPE_NULL) -+IOCTL(TIOCSTOP, IOC_, TYPE_NULL) -+IOCTL(TIOCSTART, IOC_, TYPE_NULL) -+IOCTL(TIOCSCTTY, IOC_, TYPE_NULL) -+IOCTL(TIOCDRAIN, IOC_, TYPE_NULL) -+IOCTL(TIOCEXCL, IOC_, TYPE_NULL) -+IOCTL(TIOCNXCL, IOC_, TYPE_NULL) -+IOCTL(TIOCFLUSH, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCGWINSZ, IOC_R, MK_PTR(MK_STRUCT(STRUCT_winsize))) -+IOCTL(TIOCSWINSZ, IOC_W, MK_PTR(MK_STRUCT(STRUCT_winsize))) -+IOCTL(TIOCCONS, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMSET, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMGET, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMBIS, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(TIOCMBIC, IOC_W, MK_PTR(TYPE_INT)) -+ -+/* sys/filio.h */ -+IOCTL(FIOCLEX, IOC_, TYPE_NULL) -+IOCTL(FIONCLEX, IOC_, TYPE_NULL) -+IOCTL(FIONREAD, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIONBIO, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(FIOASYNC, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(FIOSETOWN, IOC_W, MK_PTR(TYPE_INT)) -+IOCTL(FIOGETOWN, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIODTYPE, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIOGETLBA, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIODGNAME, IOC_W, MK_PTR(MK_STRUCT(STRUCT_fiodgname_arg))) -+IOCTL(FIONWRITE, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIONSPACE, IOC_R, MK_PTR(TYPE_INT)) -+IOCTL(FIOSEEKDATA, IOC_RW, MK_PTR(TYPE_ULONG)) -+IOCTL(FIOSEEKHOLE, IOC_RW, MK_PTR(TYPE_ULONG)) -diff --git a/bsd-user/openbsd/os-ioctl-filio.h b/bsd-user/openbsd/os-ioctl-filio.h -new file mode 100644 -index 0000000..e3f7474 ---- /dev/null -+++ b/bsd-user/openbsd/os-ioctl-filio.h -@@ -0,0 +1,29 @@ -+#ifndef _IOCTL_FILIO_H_ -+#define _IOCTL_FILIO_H_ -+ -+/* XXX needs to be fixed for OpenBSD dependencies */ -+ -+/* see sys/filio.h */ -+#define TARGET_FIOCLEX TARGET_IO('f', 1) -+#define TARGET_FIONCLEX TARGET_IO('f', 2) -+#define TARGET_FIONREAD TARGET_IOR('f', 127, int) -+#define TARGET_FIONBIO TARGET_IOW('f', 126, int) -+#define TARGET_FIOASYNC TARGET_IOW('f', 125, int) -+#define TARGET_FIOSETOWN TARGET_IOW('f', 124, int) -+#define TARGET_FIOGETOWN TARGET_IOR('f', 123, int) -+#define TARGET_FIODTYPE TARGET_IOR('f', 122, int) -+#define TARGET_FIOGETLBA TARGET_IOR('f', 121, int) -+ -+struct target_fiodgname_arg { -+ int32_t len; -+ abi_ulong buf; -+}; -+ -+#define TARGET_FIODGNAME TARGET_IOW('f', 120, \ -+ struct target_fiodgname_arg) -+#define TARGET_FIONWRITE TARGET_IOR('f', 119, int) -+#define TARGET_FIONSPACE TARGET_IOR('f', 118, int) -+#define TARGET_FIOSEEKDATA TARGET_IOWR('f', 97, off_t) -+#define TARGET_FIOSEEKHOLE TARGET_IOWR('f', 98, off_t) -+ -+#endif /* !_IOCTL_FILIO_H_ */ -diff --git a/bsd-user/openbsd/os-ioctl-ioccom.h b/bsd-user/openbsd/os-ioctl-ioccom.h -new file mode 100644 -index 0000000..fa1c6b4 ---- /dev/null -+++ b/bsd-user/openbsd/os-ioctl-ioccom.h -@@ -0,0 +1,38 @@ -+#ifndef _IOCTL_IOCCOM_H_ -+#define _IOCTL_IOCCOM_H_ -+ -+/* XXX needs to be fixed for OpenBSD dependencies */ -+ -+/* -+ * Ioctl's have the command encoded in the lower word, and the size of -+ * any in or out parameters in the upper word. The high 3 bits of the -+ * upper word are used to encode the in/out status of the parameter. -+ */ -+/* number of bits for ioctl size */ -+#define TARGET_IOCPARM_SHIFT 13 -+ -+/* parameter length mask */ -+#define TARGET_IOCPARM_MASK ((1 << TARGET_IOCPARM_SHIFT) - 1) -+ -+#define TARGET_IOCPARM_LEN(x) (((x) >> 16) & TARGET_IOCPARM_MASK) -+#define TARGET_IOCBASECMD(x) ((x) & ~(TARGET_IOCPARM_MASK << 16)) -+#define TARGET_IOCGROUP(x) (((x) >> 8) & 0xff) -+ -+#define TARGET_IOCPARM_MAX (1 << TARGET_IOCPARM_SHIFT) /* max size of ioctl */ -+#define TARGET_IOC_VOID 0x20000000 /* no parameters */ -+#define TARGET_IOC_OUT 0x40000000 /* copy out parameters */ -+#define TARGET_IOC_IN 0x80000000 /* copy in parameters */ -+#define TARGET_IOC_INOUT (TARGET_IOC_IN|TARGET_IOC_OUT) -+#define TARGET_IOC_DIRMASK (TARGET_IOC_VOID|TARGET_IOC_OUT|TARGET_IOC_IN) -+ -+#define TARGET_IOC(inout, group, num, len) ((abi_ulong) \ -+ ((inout) | (((len) & TARGET_IOCPARM_MASK) << 16) | ((group) << 8) \ -+ | (num))) -+#define TARGET_IO(g, n) TARGET_IOC(IOC_VOID, (g), (n), 0) -+#define TARGET_IOWINT(g, n) TARGET_IOC(IOC_VOID, (g), (n), sizeof(int)) -+#define TARGET_IOR(g, n, t) TARGET_IOC(IOC_OUT, (g), (n), sizeof(t)) -+#define TARGET_IOW(g, n, t) TARGET_IOC(IOC_IN, (g), (n), sizeof(t)) -+/* this should be _IORW, but stdio got there first */ -+#define TARGET_IOWR(g, n, t) TARGET_IOC(IOC_INOUT, (g), (n), sizeof(t)) -+ -+#endif /* !_IOCTL_IOCCOM_H_ */ -diff --git a/bsd-user/openbsd/os-ioctl-ttycom.h b/bsd-user/openbsd/os-ioctl-ttycom.h -new file mode 100644 -index 0000000..745d702 ---- /dev/null -+++ b/bsd-user/openbsd/os-ioctl-ttycom.h -@@ -0,0 +1,240 @@ -+#ifndef _IOCTL_TTYCOM_H_ -+#define _IOCTL_TTYCOM_H_ -+ -+/* XXX Needs to be fixed for OpenBSD dependencies */ -+ -+#include "os-ioctl-ioccom.h" -+ -+/* From sys/ttycom.h and sys/_termios.h */ -+ -+#define TARGET_VEOF 0 /* ICANON */ -+#define TARGET_VEOL 1 /* ICANON */ -+#define TARGET_VEOL2 2 /* ICANON together with IEXTEN */ -+#define TARGET_VERASE 3 /* ICANON */ -+#define TARGET_VWERASE 4 /* ICANON together with IEXTEN */ -+#define TARGET_VKILL 5 /* ICANON */ -+#define TARGET_VREPRINT 6 /* ICANON together with IEXTEN */ -+#define TARGET_VERASE2 7 /* ICANON */ -+#define TARGET_VINTR 8 /* ISIG */ -+#define TARGET_VQUIT 9 /* ISIG */ -+#define TARGET_VSUSP 10 /* ISIG */ -+#define TARGET_VDSUSP 11 /* ISIG together with IEXTEN */ -+#define TARGET_VSTART 12 /* IXON, IXOFF */ -+#define TARGET_VSTOP 13 /* IXON, IXOFF */ -+#define TARGET_VLNEXT 14 /* IEXTEN */ -+#define TARGET_VDISCARD 15 /* IEXTEN */ -+#define TARGET_VMIN 16 /* !ICANON */ -+#define TARGET_VTIME 17 /* !ICANON */ -+#define TARGET_VSTATUS 18 /* ICANON together with IEXTEN */ -+/* 19 spare 2 */ -+#define TARGET_NCCS 20 -+ -+/* -+ * Input flags - software input processing -+ */ -+#define TARGET_IGNBRK 0x00000001 /* ignore BREAK condition */ -+#define TARGET_BRKINT 0x00000002 /* map BREAK to SIGINTR */ -+#define TARGET_IGNPAR 0x00000004 /* ignore (discard) parity errors */ -+#define TARGET_PARMRK 0x00000008 /* mark parity and framing errors */ -+#define TARGET_INPCK 0x00000010 /* enable checking of parity errors */ -+#define TARGET_ISTRIP 0x00000020 /* strip 8th bit off chars */ -+#define TARGET_INLCR 0x00000040 /* map NL into CR */ -+#define TARGET_IGNCR 0x00000080 /* ignore CR */ -+#define TARGET_ICRNL 0x00000100 /* map CR to NL (ala CRMOD) */ -+#define TARGET_IXON 0x00000200 /* enable output flow control */ -+#define TARGET_IXOFF 0x00000400 /* enable input flow control */ -+#define TARGET_IXANY 0x00000800 /* any char will restart after stop */ -+#define TARGET_IMAXBEL 0x00002000 /* ring bell on input queue full */ -+ -+/* -+ * Output flags - software output processing -+ */ -+#define TARGET_OPOST 0x00000001 /* enable following output processing */ -+#define TARGET_ONLCR 0x00000002 /* map NL to CR-NL (ala CRMOD) */ -+#define TARGET_TABDLY 0x00000004 /* tab delay mask */ -+#define TARGET_TAB0 0x00000000 /* no tab delay and expansion */ -+#define TARGET_TAB3 0x00000004 /* expand tabs to spaces */ -+#define TARGET_ONOEOT 0x00000008 /* discard EOT's (^D) on output) */ -+#define TARGET_OCRNL 0x00000010 /* map CR to NL on output */ -+#define TARGET_ONOCR 0x00000020 /* no CR output at column 0 */ -+#define TARGET_ONLRET 0x00000040 /* NL performs CR function */ -+ -+/* -+ * Control flags - hardware control of terminal -+ */ -+#define TARGET_CIGNORE 0x00000001 /* ignore control flags */ -+#define TARGET_CSIZE 0x00000300 /* character size mask */ -+#define TARGET_CS5 0x00000000 /* 5 bits (pseudo) */ -+#define TARGET_CS6 0x00000100 /* 6 bits */ -+#define TARGET_CS7 0x00000200 /* 7 bits */ -+#define TARGET_CS8 0x00000300 /* 8 bits */ -+#define TARGET_CSTOPB 0x00000400 /* send 2 stop bits */ -+#define TARGET_CREAD 0x00000800 /* enable receiver */ -+#define TARGET_PARENB 0x00001000 /* parity enable */ -+#define TARGET_PARODD 0x00002000 /* odd parity, else even */ -+#define TARGET_HUPCL 0x00004000 /* hang up on last close */ -+#define TARGET_CLOCAL 0x00008000 /* ignore modem status lines */ -+#define TARGET_CCTS_OFLOW 0x00010000 /* CTS flow control of output */ -+#define TARGET_CRTSCTS (TARGET_CCTS_OFLOW | TARGET_CRTS_IFLOW) -+#define TARGET_CRTS_IFLOW 0x00020000 /* RTS flow control of input */ -+#define TARGET_CDTR_IFLOW 0x00040000 /* DTR flow control of input */ -+#define TARGET_CDSR_OFLOW 0x00080000 /* DSR flow control of output */ -+#define TARGET_CCAR_OFLOW 0x00100000 /* DCD flow control of output */ -+ -+/* -+ * "Local" flags - dumping ground for other state -+ */ -+#define TARGET_ECHOKE 0x00000001 /* visual erase for line kill */ -+#define TARGET_ECHOE 0x00000002 /* visually erase chars */ -+#define TARGET_ECHOK 0x00000004 /* echo NL after line kill */ -+#define TARGET_ECHO 0x00000008 /* enable echoing */ -+#define TARGET_ECHONL 0x00000010 /* echo NL even if ECHO is off */ -+#define TARGET_ECHOPRT 0x00000020 /* visual erase mode for hardcopy */ -+#define TARGET_ECHOCTL 0x00000040 /* echo control chars as ^(Char) */ -+#define TARGET_ISIG 0x00000080 /* enable signals INTR, QUIT, [D]SUSP */ -+#define TARGET_ICANON 0x00000100 /* canonicalize input lines */ -+#define TARGET_ALTWERASE 0x00000200 /* use alternate WERASE algorithm */ -+#define TARGET_IEXTEN 0x00000400 /* enable DISCARD and LNEXT */ -+#define TARGET_EXTPROC 0x00000800 /* external processing */ -+#define TARGET_TOSTOP 0x00400000 /* stop background jobs from output */ -+#define TARGET_FLUSHO 0x00800000 /* output being flushed (state) */ -+#define TARGET_NOKERNINFO 0x02000000 /* no kernel output from VSTATUS */ -+#define TARGET_PENDIN 0x20000000 /* XXX retype pending input (state) */ -+#define TARGET_NOFLSH 0x80000000 /* don't flush after interrupt */ -+ -+struct target_termios { -+ uint32_t c_iflag; /* input flags */ -+ uint32_t c_oflag; /* output flags */ -+ uint32_t c_cflag; /* control flags */ -+ uint32_t c_lflag; /* local flags */ -+ uint8_t c_cc[TARGET_NCCS]; /* control chars */ -+ uint32_t c_ispeed; /* input speed */ -+ uint32_t c_ospeed; /* output speed */ -+}; -+ -+ -+struct target_winsize { -+ uint16_t ws_row; /* rows, in characters */ -+ uint16_t ws_col; /* columns, in characters */ -+ uint16_t ws_xpixel; /* horizontal size, pixels */ -+ uint16_t ws_ypixel; /* vertical size, pixels */ -+}; -+ -+ /* 0-2 compat */ -+ /* 3-7 unused */ -+ /* 8-10 compat */ -+ /* 11-12 unused */ -+#define TARGET_TIOCEXCL TARGET_IO('t', 13) /* set exclusive use of tty */ -+#define TARGET_TIOCNXCL TARGET_IO('t', 14) /* reset exclusive use of tty */ -+#define TARGET_TIOCGPTN TARGET_IOR('t', 15, int) /* Get pts number. */ -+#define TARGET_TIOCFLUSH TARGET_IOW('t', 16, int) /* flush buffers */ -+ /* 17-18 compat */ -+/* get termios struct */ -+#define TARGET_TIOCGETA TARGET_IOR('t', 19, struct target_termios) -+/* set termios struct */ -+#define TARGET_TIOCSETA TARGET_IOW('t', 20, struct target_termios) -+/* drain output, set */ -+#define TARGET_TIOCSETAW TARGET_IOW('t', 21, struct target_termios) -+/* drn out, fls in, set */ -+#define TARGET_TIOCSETAF TARGET_IOW('t', 22, struct target_termios) -+ /* 23-25 unused */ -+#define TARGET_TIOCGETD TARGET_IOR('t', 26, int) /* get line discipline */ -+#define TARGET_TIOCSETD TARGET_IOW('t', 27, int) /* set line discipline */ -+#define TARGET_TIOCPTMASTER TARGET_IO('t', 28) /* pts master validation */ -+ /* 29-85 unused */ -+/* get ttywait timeout */ -+#define TARGET_TIOCGDRAINWAIT TARGET_IOR('t', 86, int) -+/* set ttywait timeout */ -+#define TARGET_TIOCSDRAINWAIT TARGET_IOW('t', 87, int) -+ /* 88 unused */ -+ /* 89-91 conflicts: tun and tap */ -+/* enable/get timestamp of last input event */ -+#define TARGET_TIOCTIMESTAMP TARGET_IOR('t', 89, struct target_timeval) -+/* modem: get wait on close */ -+#define TARGET_TIOCMGDTRWAIT TARGET_IOR('t', 90, int) -+/* modem: set wait on close */ -+#define TARGET_TIOCMSDTRWAIT TARGET_IOW('t', 91, int) -+ /* 92-93 tun and tap */ -+ /* 94-97 conflicts: tun and tap */ -+/* wait till output drained */ -+#define TARGET_TIOCDRAIN TARGET_IO('t', 94) -+ /* pty: generate signal */ -+#define TARGET_TIOCSIG TARGET_IOWINT('t', 95) -+/* pty: external processing */ -+#define TARGET_TIOCEXT TARGET_IOW('t', 96, int) -+/* become controlling tty */ -+#define TARGET_TIOCSCTTY TARGET_IO('t', 97) -+/* become virtual console */ -+#define TARGET_TIOCCONS TARGET_IOW('t', 98, int) -+/* get session id */ -+#define TARGET_TIOCGSID TARGET_IOR('t', 99, int) -+ /* 100 unused */ -+/* simulate ^T status message */ -+#define TARGET_TIOCSTAT TARGET_IO('t', 101) -+ /* pty: set/clr usr cntl mode */ -+#define TARGET_TIOCUCNTL TARGET_IOW('t', 102, int) -+/* usr cntl op "n" */ -+#define TARGET_TIOCCMD(n) TARGET_IO('u', n) -+/* set window size */ -+#define TARGET_TIOCSWINSZ TARGET_IOW('t', 103, struct target_winsize) -+/* get window size */ -+#define TARGET_TIOCGWINSZ TARGET_IOR('t', 104, struct target_winsize) -+ /* 105 unused */ -+/* get all modem bits */ -+#define TARGET_TIOCMGET TARGET_IOR('t', 106, int) -+#define TARGET_TIOCM_LE 0001 /* line enable */ -+#define TARGET_TIOCM_DTR 0002 /* data terminal ready */ -+#define TARGET_TIOCM_RTS 0004 /* request to send */ -+#define TARGET_TIOCM_ST 0010 /* secondary transmit */ -+#define TARGET_TIOCM_SR 0020 /* secondary receive */ -+#define TARGET_TIOCM_CTS 0040 /* clear to send */ -+#define TARGET_TIOCM_DCD 0100 /* data carrier detect */ -+#define TARGET_TIOCM_RI 0200 /* ring indicate */ -+#define TARGET_TIOCM_DSR 0400 /* data set ready */ -+#define TARGET_TIOCM_CD TARGET_TIOCM_DCD -+#define TARGET_TIOCM_CAR TARGET_TIOCM_DCD -+#define TARGET_TIOCM_RNG TARGET_TIOCM_RI -+#define TARGET_TIOCMBIC TARGET_IOW('t', 107, int) /* bic modem bits */ -+#define TARGET_TIOCMBIS TARGET_IOW('t', 108, int) /* bis modem bits */ -+#define TARGET_TIOCMSET TARGET_IOW('t', 109, int) /* set all modem bits */ -+/* start output, like ^Q */ -+#define TARGET_TIOCSTART TARGET_IO('t', 110) -+/* stop output, like ^S */ -+#define TARGET_TIOCSTOP TARGET_IO('t', 111) -+/* pty: set/clear packet mode */ -+#define TARGET_TIOCPKT TARGET_IOW('t', 112, int) -+#define TARGET_TIOCPKT_DATA 0x00 /* data packet */ -+#define TARGET_TIOCPKT_FLUSHREAD 0x01 /* flush packet */ -+#define TARGET_TIOCPKT_FLUSHWRITE 0x02 /* flush packet */ -+#define TARGET_TIOCPKT_STOP 0x04 /* stop output */ -+#define TARGET_TIOCPKT_START 0x08 /* start output */ -+#define TARGET_TIOCPKT_NOSTOP 0x10 /* no more ^S, ^Q */ -+#define TARGET_TIOCPKT_DOSTOP 0x20 /* now do ^S ^Q */ -+#define TARGET_TIOCPKT_IOCTL 0x40 /* state change of pty -+ driver */ -+#define TARGET_TIOCNOTTY TARGET_IO('t', 113) /* void tty -+ association */ -+#define TARGET_TIOCSTI TARGET_IOW('t', 114, char) /* simulate -+ terminal input */ -+#define TARGET_TIOCOUTQ TARGET_IOR('t', 115, int) /* output queue size */ -+ /* 116-117 compat */ -+#define TARGET_TIOCSPGRP TARGET_IOW('t', 118, int) /* set pgrp of tty */ -+#define TARGET_TIOCGPGRP TARGET_IOR('t', 119, int) /* get pgrp of tty */ -+#define TARGET_TIOCCDTR TARGET_IO('t', 120) /* clear data terminal -+ ready */ -+#define TARGET_TIOCSDTR TARGET_IO('t', 121) /* set data terminal -+ ready */ -+#define TARGET_TIOCCBRK TARGET_IO('t', 122) /* clear break bit */ -+#define TARGET_TIOCSBRK TARGET_IO('t', 123) /* set break bit */ -+ /* 124-127 compat */ -+ -+#define TARGET_TTYDISC 0 /* termios tty line -+ discipline */ -+#define TARGET_SLIPDISC 4 /* serial IP discipline */ -+#define TARGET_PPPDISC 5 /* PPP discipline */ -+#define TARGET_NETGRAPHDISC 6 /* Netgraph tty node -+ discipline */ -+#define TARGET_H4DISC 7 /* Netgraph Bluetooth H4 -+ discipline */ -+ -+#endif /*! _IOCTL_TTYCOM_H_ */ -diff --git a/bsd-user/openbsd/os-ioctl-types.h b/bsd-user/openbsd/os-ioctl-types.h -new file mode 100644 -index 0000000..6f8b97b ---- /dev/null -+++ b/bsd-user/openbsd/os-ioctl-types.h -@@ -0,0 +1,7 @@ -+/* XXX should be fixed for OpenBSD types and structs */ -+STRUCT_SPECIAL(termios) -+ -+STRUCT(winsize, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT, TYPE_SHORT) -+ -+STRUCT(fiodgname_arg, TYPE_INT, TYPE_PTRVOID) -+ -diff --git a/bsd-user/openbsd/os-misc.h b/bsd-user/openbsd/os-misc.h -new file mode 100644 -index 0000000..5a17ac9 ---- /dev/null -+++ b/bsd-user/openbsd/os-misc.h -@@ -0,0 +1,375 @@ -+/* -+ * miscellaneous OpenBSD system call shims -+ * -+ * 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 __OS_MISC_H_ -+#define __OS_MISC_H_ -+ -+/* -+ * XXX To support FreeBSD binaries on OpenBSD these syscalls will need -+ * to be emulated. -+ */ -+ -+/* sched_setparam(2) */ -+static inline abi_long do_freebsd_sched_setparam(pid_t pid, -+ abi_ulong target_sp_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sched_setparam()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sched_get_param(2) */ -+static inline abi_long do_freebsd_sched_getparam(pid_t pid, -+ abi_ulong target_sp_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sched_getparam()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sched_setscheduler(2) */ -+static inline abi_long do_freebsd_sched_setscheduler(pid_t pid, int policy, -+ abi_ulong target_sp_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sched_setscheduler()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sched_getscheduler(2) */ -+static inline abi_long do_freebsd_sched_getscheduler(pid_t pid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sched_getscheduler()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sched_getscheduler(2) */ -+static inline abi_long do_freebsd_sched_rr_get_interval(pid_t pid, -+ abi_ulong target_ts_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sched_rr_get_interval()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cpuset(2) */ -+static inline abi_long do_freebsd_cpuset(abi_ulong target_cpuid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cpuset()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cpuset_setid(2) */ -+static inline abi_long do_freebsd_cpuset_setid(void *cpu_env, abi_long arg1, -+ abi_ulong arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cpuset_setid()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cpuset_getid(2) */ -+static inline abi_long do_freebsd_cpuset_getid(abi_long arg1, abi_ulong arg2, -+ abi_ulong arg3, abi_ulong arg4, abi_ulong arg5) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cpuset_getid()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cpuset_getaffinity(2) */ -+static inline abi_long do_freebsd_cpuset_getaffinity(abi_long arg1, -+ abi_ulong arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5, -+ abi_ulong arg6) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cpuset_getaffinity()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cpuset_setaffinity(2) */ -+static inline abi_long do_freebsd_cpuset_setaffinity(abi_long arg1, -+ abi_ulong arg2, abi_ulong arg3, abi_ulong arg4, abi_ulong arg5, -+ abi_ulong arg6) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cpuset_setaffinity()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* modfnext(2) */ -+static inline abi_long do_freebsd_modfnext(abi_long modid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall modfnext()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* modfind(2) */ -+static inline abi_long do_freebsd_modfind(abi_ulong target_name) -+{ -+ -+ qemu_log("qemu: Unsupported syscall modfind()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldload(2) */ -+static inline abi_long do_freebsd_kldload(abi_ulong target_name) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldload()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldunload(2) */ -+static inline abi_long do_freebsd_kldunload(abi_long fileid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldunload()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldunloadf(2) */ -+static inline abi_long do_freebsd_kldunloadf(abi_long fileid, abi_long flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldunloadf()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldfind(2) */ -+static inline abi_long do_freebsd_kldfind(abi_ulong target_name) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldfind()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldnext(2) */ -+static inline abi_long do_freebsd_kldnext(abi_long fileid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldnext()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* kldstat(2) */ -+static inline abi_long do_freebsd_kldstat(abi_long fileid, -+ abi_ulong target_stat) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldstat()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldfirstmod(2) */ -+static inline abi_long do_freebsd_kldfirstmod(abi_long fileid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldfirstmod()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* kldsym(2) */ -+static inline abi_long do_freebsd_kldsym(abi_long fileid, abi_long cmd, -+ abi_ulong target_data) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kldsym()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * Resource limits (undocumented except for rctl(8) and rctl.conf(5) ) -+ */ -+/* rctl_get_racct() */ -+static inline abi_long do_freebsd_rctl_get_racct(abi_ulong target_inbufp, -+ abi_ulong inbuflen, abi_ulong target_outbufp, abi_ulong outbuflen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rctl_get_racct()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* rctl_get_rules() */ -+static inline abi_long do_freebsd_rctl_get_rules(abi_ulong target_inbufp, -+ abi_ulong inbuflen, abi_ulong target_outbufp, abi_ulong outbuflen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rctl_get_rules()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* rctl_add_rule() */ -+static inline abi_long do_freebsd_rctl_add_rule(abi_ulong target_inbufp, -+ abi_ulong inbuflen, abi_ulong target_outbufp, abi_ulong outbuflen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rctl_add_rule()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* rctl_remove_rule() */ -+static inline abi_long do_freebsd_rctl_remove_rule(abi_ulong target_inbufp, -+ abi_ulong inbuflen, abi_ulong target_outbufp, abi_ulong outbuflen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rctl_remove_rule()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* rctl_get_limits() */ -+static inline abi_long do_freebsd_rctl_get_limits(abi_ulong target_inbufp, -+ abi_ulong inbuflen, abi_ulong target_outbufp, abi_ulong outbuflen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rctl_get_limits()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* -+ * Kernel environment -+ */ -+ -+/* kenv(2) */ -+static inline abi_long do_freebsd_kenv(abi_long what, abi_ulong target_name, -+ abi_ulong target_value, abi_long len) -+{ -+ -+ qemu_log("qemu: Unsupported syscall kenv()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* -+ * Mandatory Access Control -+ */ -+ -+/* __mac_get_proc */ -+static inline abi_long do_freebsd___mac_get_proc(abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_get_proc()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_set_proc */ -+static inline abi_long do_freebsd___mac_set_proc(abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_set_proc()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* __mac_get_fd */ -+static inline abi_long do_freebsd___mac_get_fd(abi_long fd, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_get_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_set_fd */ -+static inline abi_long do_freebsd___mac_set_fd(abi_long fd, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_set_fd()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_get_file */ -+static inline abi_long do_freebsd___mac_get_file(abi_ulong target_path, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_get_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_set_file */ -+static inline abi_long do_freebsd___mac_set_file(abi_ulong target_path, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_set_file()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_get_link */ -+static inline abi_long do_freebsd___mac_get_link(abi_ulong target_path, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_get_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* __mac_set_link */ -+static inline abi_long do_freebsd___mac_set_link(abi_ulong target_path, -+ abi_ulong target_mac) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_set_link()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* mac_syscall */ -+static inline abi_long do_freebsd_mac_syscall(abi_ulong target_policy, -+ abi_long call, abi_ulong target_arg) -+{ -+ -+ qemu_log("qemu: Unsupported syscall mac_syscall()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+ -+/* -+ * New posix calls -+ */ -+/* posix_fallocate(2) */ -+static inline abi_long do_freebsd_posix_fallocate(abi_long fd, abi_ulong offset, -+ abi_ulong len) -+{ -+ -+ qemu_log("qemu: Unsupported syscall posix_fallocate()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* posix_openpt(2) */ -+static inline abi_long do_freebsd_posix_openpt(abi_long flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall posix_openpt()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* posix_fadvise(2) */ -+static inline abi_long do_freebsd_posix_fadvise(abi_long fd, abi_ulong offset, -+ abi_ulong len, abi_long advise) -+{ -+ -+ qemu_log("qemu: Unsupported syscall posix_fadvise()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* ! __OS_MISC_H_ */ -diff --git a/bsd-user/openbsd/os-proc.c b/bsd-user/openbsd/os-proc.c -new file mode 100644 -index 0000000..bc11d29 ---- /dev/null -+++ b/bsd-user/openbsd/os-proc.c -@@ -0,0 +1,11 @@ -+/* -+ * XXX To support FreeBSD binaries on NetBSD the following will need to be -+ * emulated. -+ */ -+abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, -+ abi_ulong guest_envp, int do_fexec) -+{ -+ -+ qemu_log("qemu: Unsupported %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -diff --git a/bsd-user/openbsd/os-proc.h b/bsd-user/openbsd/os-proc.h -new file mode 100644 -index 0000000..9cce719 ---- /dev/null -+++ b/bsd-user/openbsd/os-proc.h -@@ -0,0 +1,243 @@ -+#ifndef __OPENBSD_PROC_H_ -+#define __OPENBSD_PROC_H_ -+ -+/* -+ * XXX To support FreeBSD binaries on OpenBSD these syscalls will need -+ * to be emulated. -+ */ -+ -+/* execve(2) */ -+static inline abi_long do_freebsd_execve(abi_ulong path_or_fd, abi_ulong argp, -+ abi_ulong envp) -+{ -+ -+ qemu_log("qemu: Unsupported syscall execve()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* fexecve(2) */ -+static inline abi_long do_freebsd_fexecve(abi_ulong path_or_fd, abi_ulong argp, -+ abi_ulong envp) -+{ -+ -+ qemu_log("qemu: Unsupported syscall fexecve()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* wait4(2) */ -+static inline abi_long do_freebsd_wait4(abi_long arg1, abi_ulong target_status, -+ abi_long arg3, abi_ulong target_rusage) -+{ -+ -+ qemu_log("qemu: Unsupported syscall wait4()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* setloginclass(2) */ -+static inline abi_long do_freebsd_setloginclass(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall setloginclass()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getloginclass(2) */ -+static inline abi_long do_freebsd_getloginclass(abi_ulong arg1, abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getloginclass()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* pdwait4(2) */ -+static inline abi_long do_freebsd_pdwait4(abi_long arg1, -+ abi_ulong target_status, abi_long arg3, abi_ulong target_rusage) -+{ -+ -+ qemu_log("qemu: Unsupported syscall pdwait4()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* pdgetpid(2) */ -+static inline abi_long do_freebsd_pdgetpid(abi_long fd, abi_ulong target_pidp) -+{ -+ -+ qemu_log("qemu: Unsupported syscall pdgetpid()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* undocumented __setugid */ -+static inline abi_long do_freebsd___setugid(abi_long arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall __setugid()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* fork(2) */ -+static inline abi_long do_freebsd_fork(void *cpu_env) -+{ -+ -+ qemu_log("qemu: Unsupported syscall fork()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* vfork(2) */ -+static inline abi_long do_freebsd_vfork(void *cpu_env) -+{ -+ -+ qemu_log("qemu: Unsupported syscall vfork()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* rfork(2) */ -+static inline abi_long do_freebsd_rfork(void *cpu_env, abi_long flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rfork()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* pdfork(2) */ -+static inline abi_long do_freebsd_pdfork(void *cpu_env, abi_ulong arg1, -+ abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall pdfork()\n"); -+ return -TARGET_ENOSYS -+} -+ -+/* jail(2) */ -+static inline abi_long do_freebsd_jail(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall jail()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* jail_attach(2) */ -+static inline abi_long do_freebsd_jail_attach(abi_long arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall jail_attach()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* jail_remove(2) */ -+static inline abi_long do_freebsd_jail_remove(abi_long arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall jail_remove()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* jail_get(2) */ -+static inline abi_long do_freebsd_jail_get(abi_ulong arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall jail_get()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* jail_set(2) */ -+static inline abi_long do_freebsd_jail_set(abi_ulong arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall jail_set()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_enter(2) */ -+static inline abi_long do_freebsd_cap_enter(void) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_enter()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_new(2) */ -+static inline abi_long do_freebsd_cap_new(abi_long arg1, abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_new()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_getrights(2) */ -+static inline abi_long do_freebsd_cap_getrights(abi_long arg1, abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_getrights()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_getmode(2) */ -+static inline abi_long do_freebsd_cap_getmode(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_getmode()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* audit(2) */ -+static inline abi_long do_freebsd_audit(abi_ulong arg1, abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall audit()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* auditon(2) */ -+static inline abi_long do_freebsd_auditon(abi_long arg1, abi_ulong arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall auditon()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getaudit(2) */ -+static inline abi_long do_freebsd_getaudit(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getaudit()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* setaudit(2) */ -+static inline abi_long do_freebsd_setaudit(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall setaudit()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getaudit_addr(2) */ -+static inline abi_long do_freebsd_getaudit_addr(abi_ulong arg1, -+ abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getaudit_addr()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* setaudit_addr(2) */ -+static inline abi_long do_freebsd_setaudit_addr(abi_ulong arg1, -+ abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall setaudit_addr()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* auditctl(2) */ -+static inline abi_long do_freebsd_auditctl(abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall auditctl()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* ! __OPENBSD_PROC_H_ */ -diff --git a/bsd-user/openbsd/os-socket.c b/bsd-user/openbsd/os-socket.c -new file mode 100644 -index 0000000..183002d ---- /dev/null -+++ b/bsd-user/openbsd/os-socket.c -@@ -0,0 +1 @@ -+/* XXX OpenBSD socket related helpers */ -diff --git a/bsd-user/openbsd/os-socket.h b/bsd-user/openbsd/os-socket.h -new file mode 100644 -index 0000000..b8b1e99 ---- /dev/null -+++ b/bsd-user/openbsd/os-socket.h -@@ -0,0 +1,98 @@ -+/* -+ * OpenBSD socket related system call shims -+ * -+ * -+ * 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 __OPENBSD_SOCKET_H_ -+#define __OPENBSD_SOCKET_H_ -+ -+/* -+ * XXX To support FreeBSD binaries on OpenBSD these syscalls will need -+ * to be emulated. -+ */ -+ -+/* sendmsg(2) */ -+static inline abi_long do_freebsd_sendmsg(int fd, abi_ulong target_msg, -+ int flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sendmsg()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* recvmsg(2) */ -+static inline abi_long do_freebsd_recvmsg(int fd, abi_ulong target_msg, -+ int flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall recvmsg()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* setsockopt(2) */ -+static inline abi_long do_bsd_setsockopt(int sockfd, int level, int optname, -+ abi_ulong optval_addr, socklen_t optlen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall setsockopt()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getsockopt(2) */ -+static inline abi_long do_bsd_getsockopt(int sockfd, int level, int optname, -+ abi_ulong optval_addr, abi_ulong optlen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getsockopt()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* setfib(2) */ -+static inline abi_long do_freebsd_setfib(abi_long fib) -+{ -+ -+ qemu_log("qemu: Unsupported syscall setfib()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sctp_peeloff(2) */ -+static inline abi_long do_freebsd_sctp_peeloff(abi_long s, abi_ulong id) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sctp_peeloff()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sctp_generic_sendmsg(2) */ -+static inline abi_long do_freebsd_sctp_generic_sendmsg(abi_long s, -+ abi_ulong target_msg, abi_long msglen, abi_ulong target_to, -+ abi_ulong len, abi_ulong target_sinfo, abi_long flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sctp_generic_sendmsg()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* sctp_generic_recvmsg(2) */ -+static inline abi_long do_freebsd_sctp_generic_recvmsg(abi_long s, -+ abi_ulong target_iov, abi_long iovlen, abi_ulong target_from, -+ abi_ulong fromlen, abi_ulong target_sinfo, abi_ulong target_msgflags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall sctp_generic_recvmsg()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* !__OPENBSD_SOCKET_H_ */ -diff --git a/bsd-user/openbsd/os-stat.c b/bsd-user/openbsd/os-stat.c -new file mode 100644 -index 0000000..de4e3f5 ---- /dev/null -+++ b/bsd-user/openbsd/os-stat.c -@@ -0,0 +1 @@ -+/* XXX OpenBSD stat related helpers */ -diff --git a/bsd-user/openbsd/os-stat.h b/bsd-user/openbsd/os-stat.h -new file mode 100644 -index 0000000..1d3850d ---- /dev/null -+++ b/bsd-user/openbsd/os-stat.h -@@ -0,0 +1,176 @@ -+/* -+ * OpenBSD stat related system call shims 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 __OPENBSD_STAT_H_ -+#define __OPENBSD_STAT_H_ -+ -+/* -+ * XXX To support FreeBSD binaries on OpenBSD these syscalls will need -+ * to be emulated. -+ */ -+ -+/* stat(2) */ -+static inline abi_long do_freebsd_stat(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall stat()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* lstat(2) */ -+static inline abi_long do_freebsd_lstat(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall lstat()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* fstat(2) */ -+static inline abi_long do_freebsd_fstat(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall fstat()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* fstatat(2) */ -+static inline abi_long do_freebsd_fstatat(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4) -+{ -+ -+ qemu_log("qemu: Unsupported syscall fstatat()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* undocummented nstat(char *path, struct nstat *ub) syscall */ -+static abi_long do_freebsd_nstat(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall nstat()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* undocummented nfstat(int fd, struct nstat *sb) syscall */ -+static abi_long do_freebsd_nfstat(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall nfstat()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* undocummented nlstat(char *path, struct nstat *ub) syscall */ -+static abi_long do_freebsd_nlstat(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall nlstat()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getfh(2) */ -+static abi_long do_freebsd_getfh(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getfh()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* lgetfh(2) */ -+static inline abi_long do_freebsd_lgetfh(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall lgetfh()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* fhopen(2) */ -+static inline abi_long do_freebsd_fhopen(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall fhopen()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* fhstat(2) */ -+static inline abi_long do_freebsd_fhstat(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall fhstat()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* fhstatfs(2) */ -+static inline abi_long do_freebsd_fhstatfs(abi_ulong target_fhp_addr, -+ abi_ulong target_stfs_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall fhstatfs()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* statfs(2) */ -+static inline abi_long do_freebsd_statfs(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall statfs()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* fstatfs(2) */ -+static inline abi_long do_freebsd_fstatfs(abi_long fd, abi_ulong target_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall fstatfs()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getfsstat(2) */ -+static inline abi_long do_freebsd_getfsstat(abi_ulong target_addr, -+ abi_long bufsize, abi_long flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getfsstat()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getdents(2) */ -+static inline abi_long do_freebsd_getdents(abi_long arg1, abi_ulong arg2, -+ abi_long nbytes) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getdents()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* getdirecentries(2) */ -+static inline abi_long do_freebsd_getdirentries(abi_long arg1, abi_ulong arg2, -+ abi_long nbytes, abi_ulong arg4) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getdirecentries()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* fcntl(2) */ -+static inline abi_long do_freebsd_fcntl(abi_long arg1, abi_long arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall fcntl()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* ! __OPENBSD_STAT_H_ */ -diff --git a/bsd-user/openbsd/os-strace.h b/bsd-user/openbsd/os-strace.h -new file mode 100644 -index 0000000..9161390 ---- /dev/null -+++ b/bsd-user/openbsd/os-strace.h -@@ -0,0 +1 @@ -+/* XXX OpenBSD dependent strace print functions */ -diff --git a/bsd-user/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/os-thread.c b/bsd-user/openbsd/os-thread.c -new file mode 100644 -index 0000000..d125281 ---- /dev/null -+++ b/bsd-user/openbsd/os-thread.c -@@ -0,0 +1 @@ -+/* XXX OpenBSD thread related helpers */ -diff --git a/bsd-user/openbsd/os-thread.h b/bsd-user/openbsd/os-thread.h -new file mode 100644 -index 0000000..962a769 ---- /dev/null -+++ b/bsd-user/openbsd/os-thread.h -@@ -0,0 +1,133 @@ -+#ifndef __OPENBSD_OS_THREAD_H_ -+#define __OPENBSD_OS_THREAD_H_ -+ -+/* -+ * XXX To support FreeBSD binaries on OpenBSD these syscalls will need to -+ * be emulated. -+ */ -+static abi_long do_freebsd_thr_create(CPUArchState *env, abi_ulong target_ctx, -+ abi_ulong target_id, int flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_create()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_create(CPUArchState *env, abi_ulong thread_ctx, -+ abi_ulong target_id, int flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_create()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_new(CPUArchState *env, -+ abi_ulong target_param_addr, int32_t param_size) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_new()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_self(abi_ulong target_id) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_self()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_exit(CPUArchState *cpu_env, abi_ulong tid_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_exit()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_kill(long id, int sig) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_kill()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_kill2(pid_t pid, long id, int sig) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_kill2()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_suspend(abi_ulong target_ts) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_suspend()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_wake(long tid) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_wake()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_thr_set_name(long tid, abi_ulong target_name) -+{ -+ -+ qemu_log("qemu: Unsupported syscall thr_set_name()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_rtprio_thread(int function, lwpid_t lwpid, -+ abi_ulong target_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall rtprio_thread()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_getcontext(void *cpu_env, abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall getcontext()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_setcontext(void *cpu_env, abi_ulong arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall setcontext()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_swapcontext(void *cpu_env, abi_ulong arg1, -+ abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall swapcontext()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd__umtx_lock(abi_ulong target_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall _umtx_lock()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd__umtx_unlock(abi_ulong target_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall _umtx_unlock()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd__umtx_op(abi_ulong obj, int op, abi_ulong val, -+ abi_ulong uaddr, abi_ulong target_ts) -+{ -+ -+ qemu_log("qemu: Unsupported syscall _umtx_op()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* ! __OPENBSD_OS_THREAD_H_ */ -diff --git a/bsd-user/openbsd/os-time.c b/bsd-user/openbsd/os-time.c -new file mode 100644 -index 0000000..accd886 ---- /dev/null -+++ b/bsd-user/openbsd/os-time.c -@@ -0,0 +1 @@ -+/* XXX OpenBSD time related helpers */ -diff --git a/bsd-user/openbsd/os-time.h b/bsd-user/openbsd/os-time.h -new file mode 100644 -index 0000000..fc444bb ---- /dev/null -+++ b/bsd-user/openbsd/os-time.h -@@ -0,0 +1,179 @@ -+#ifndef __OPENBSD_OS_TIME_H_ -+#define __OPENBSD_OS_TIME_H_ -+ -+/* -+ * XXX To support FreeBSD binaries on OpenBSD these syscalls will need to -+ * be emulated. -+ */ -+static inline abi_long do_freebsd_nanosleep(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_clock_gettime(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_clock_settime(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_clock_getres(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_gettimeofday(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_settimeofday(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_adjtime(abi_ulong target_delta_addr, -+ abi_ulong target_old_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_ntp_adjtime(abi_ulong target_tx_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static abi_long do_freebsd_ntp_gettime(abi_ulong target_ntv_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_utimes(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_lutimes(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_futimes(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_futimesat(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_ktimer_create(abi_long arg1, abi_long arg2, -+ abi_long arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_ktimer_delete(abi_long arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_ktimer_settime(abi_long arg1, abi_long arg2, -+ abi_long arg3, abi_long arg4) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_ktimer_gettime(abi_long arg1, abi_long arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_ktimer_getoverrun(abi_long arg1) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_select(int n, abi_ulong rfd_addr, -+ abi_ulong wfd_addr, abi_ulong efd_addr, abi_ulong target_tv_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+ -+static inline abi_long do_freebsd_pselect(int n, abi_ulong rfd_addr, -+ abi_ulong wfd_addr, abi_ulong efd_addr, abi_ulong ts_addr, -+ abi_ulong set_addr) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_kqueue(void) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_kevent(abi_long arg1, abi_ulong arg2, -+ abi_long arg3, abi_ulong arg4, abi_long arg5, abi_long arg6) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_freebsd_sigtimedwait(abi_ulong arg1, abi_ulong arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall %s\n", __func__); -+ return -TARGET_ENOSYS; -+} -+ -+#endif /* ! __OPENBSD_OS_TIME_H_ */ -diff --git a/bsd-user/openbsd/qemu-os.h b/bsd-user/openbsd/qemu-os.h -new file mode 100644 -index 0000000..f4ad3be ---- /dev/null -+++ b/bsd-user/openbsd/qemu-os.h -@@ -0,0 +1 @@ -+/* OpenBSD conversion extern declarations */ -diff --git a/bsd-user/openbsd/target_os_elf.h b/bsd-user/openbsd/target_os_elf.h -new file mode 100644 -index 0000000..978d944 ---- /dev/null -+++ b/bsd-user/openbsd/target_os_elf.h -@@ -0,0 +1,226 @@ -+/* -+ * openbsd ELF 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 _TARGET_OS_ELF_H_ -+#define _TARGET_OS_ELF_H_ -+ -+#include "target_arch_elf.h" -+#include "elf.h" -+ -+/* from personality.h */ -+ -+/* -+ * Flags for bug emulation. -+ * -+ * These occupy the top three bytes. -+ */ -+enum { -+ ADDR_NO_RANDOMIZE = 0x0040000, /* disable randomization of VA -+ space */ -+ FDPIC_FUNCPTRS = 0x0080000, /* userspace function ptrs -+ point to descriptors -+ (signal handling) */ -+ MMAP_PAGE_ZERO = 0x0100000, -+ ADDR_COMPAT_LAYOUT = 0x0200000, -+ READ_IMPLIES_EXEC = 0x0400000, -+ ADDR_LIMIT_32BIT = 0x0800000, -+ SHORT_INODE = 0x1000000, -+ WHOLE_SECONDS = 0x2000000, -+ STICKY_TIMEOUTS = 0x4000000, -+ ADDR_LIMIT_3GB = 0x8000000, -+}; -+ -+/* -+ * Personality types. -+ * -+ * These go in the low byte. Avoid using the top bit, it will -+ * conflict with error returns. -+ */ -+enum { -+ PER_LINUX = 0x0000, -+ PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT, -+ PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS, -+ PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, -+ PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE, -+ PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS | -+ WHOLE_SECONDS | SHORT_INODE, -+ PER_OSR5 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS, -+ PER_WYSEV386 = 0x0004 | STICKY_TIMEOUTS | SHORT_INODE, -+ PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS, -+ PER_BSD = 0x0006, -+ PER_SUNOS = 0x0006 | STICKY_TIMEOUTS, -+ PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE, -+ PER_LINUX32 = 0x0008, -+ PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB, -+ PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */ -+ PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */ -+ PER_IRIX64 = 0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */ -+ PER_RISCOS = 0x000c, -+ PER_SOLARIS = 0x000d | STICKY_TIMEOUTS, -+ PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, -+ PER_OSF4 = 0x000f, /* OSF/1 v4 */ -+ PER_HPUX = 0x0010, -+ PER_MASK = 0x00ff, -+}; -+ -+/* -+ * Return the base personality without flags. -+ */ -+#define personality(pers) (pers & PER_MASK) -+ -+/* this flag is uneffective under linux too, should be deleted */ -+#ifndef MAP_DENYWRITE -+#define MAP_DENYWRITE 0 -+#endif -+ -+/* should probably go in elf.h */ -+#ifndef ELIBBAD -+#define ELIBBAD 80 -+#endif -+ -+#ifndef ELF_PLATFORM -+#define ELF_PLATFORM (NULL) -+#endif -+ -+#ifndef ELF_HWCAP -+#define ELF_HWCAP 0 -+#endif -+ -+#ifdef TARGET_ABI32 -+#undef ELF_CLASS -+#define ELF_CLASS ELFCLASS32 -+#undef bswaptls -+#define bswaptls(ptr) bswap32s(ptr) -+#endif -+ -+struct exec -+{ -+ unsigned int a_info; /* Use macros N_MAGIC, etc for access */ -+ unsigned int a_text; /* length of text, in bytes */ -+ unsigned int a_data; /* length of data, in bytes */ -+ unsigned int a_bss; /* length of uninitialized data area, in bytes */ -+ unsigned int a_syms; /* length of symbol table data in file, in bytes */ -+ unsigned int a_entry; /* start address */ -+ unsigned int a_trsize; /* length of relocation info for text, in bytes */ -+ unsigned int a_drsize; /* length of relocation info for data, in bytes */ -+}; -+ -+ -+#define N_MAGIC(exec) ((exec).a_info & 0xffff) -+#define OMAGIC 0407 -+#define NMAGIC 0410 -+#define ZMAGIC 0413 -+#define QMAGIC 0314 -+ -+/* max code+data+bss space allocated to elf interpreter */ -+#define INTERP_MAP_SIZE (32 * 1024 * 1024) -+ -+/* max code+data+bss+brk space allocated to ET_DYN executables */ -+#define ET_DYN_MAP_SIZE (128 * 1024 * 1024) -+ -+/* Necessary parameters */ -+#define TARGET_ELF_EXEC_PAGESIZE TARGET_PAGE_SIZE -+#define TARGET_ELF_PAGESTART(_v) ((_v) & \ -+ ~(unsigned long)(TARGET_ELF_EXEC_PAGESIZE-1)) -+#define TARGET_ELF_PAGEOFFSET(_v) ((_v) & (TARGET_ELF_EXEC_PAGESIZE-1)) -+ -+#define INTERPRETER_NONE 0 -+#define INTERPRETER_AOUT 1 -+#define INTERPRETER_ELF 2 -+ -+#define DLINFO_ITEMS 12 -+ -+static abi_ulong target_create_elf_tables(abi_ulong p, int argc, int envc, -+ struct elfhdr * exec, -+ abi_ulong load_addr, -+ abi_ulong load_bias, -+ abi_ulong interp_load_addr, int ibcs, -+ struct image_info *info) -+{ -+ abi_ulong sp; -+ int size; -+ abi_ulong u_platform; -+ const char *k_platform; -+ const int n = sizeof(elf_addr_t); -+ -+ sp = p; -+ u_platform = 0; -+ k_platform = ELF_PLATFORM; -+ if (k_platform) { -+ size_t len = strlen(k_platform) + 1; -+ sp -= (len + n - 1) & ~(n - 1); -+ u_platform = sp; -+ /* FIXME - check return value of memcpy_to_target() for failure */ -+ memcpy_to_target(sp, k_platform, len); -+ } -+ /* -+ * Force 16 byte _final_ alignment here for generality. -+ */ -+ sp = sp &~ (abi_ulong)15; -+ size = (DLINFO_ITEMS + 1) * 2; -+ if (k_platform) -+ size += 2; -+#ifdef DLINFO_ARCH_ITEMS -+ size += DLINFO_ARCH_ITEMS * 2; -+#endif -+ size += envc + argc + 2; -+ size += (!ibcs ? 3 : 1); /* argc itself */ -+ size *= n; -+ if (size & 15) -+ sp -= 16 - (size & 15); -+ -+ /* This is correct because Linux defines -+ * elf_addr_t as Elf32_Off / Elf64_Off -+ */ -+#define NEW_AUX_ENT(id, val) do { \ -+ sp -= n; put_user_ual(val, sp); \ -+ sp -= n; put_user_ual(id, sp); \ -+ } while(0) -+ -+ NEW_AUX_ENT (AT_NULL, 0); -+ -+ /* There must be exactly DLINFO_ITEMS entries here. */ -+ NEW_AUX_ENT(AT_PHDR, (abi_ulong)(load_addr + exec->e_phoff)); -+ NEW_AUX_ENT(AT_PHENT, (abi_ulong)(sizeof (struct elf_phdr))); -+ NEW_AUX_ENT(AT_PHNUM, (abi_ulong)(exec->e_phnum)); -+ NEW_AUX_ENT(AT_PAGESZ, (abi_ulong)(TARGET_PAGE_SIZE)); -+ NEW_AUX_ENT(AT_BASE, (abi_ulong)(interp_load_addr)); -+ NEW_AUX_ENT(AT_FLAGS, (abi_ulong)0); -+ NEW_AUX_ENT(AT_ENTRY, load_bias + exec->e_entry); -+ NEW_AUX_ENT(AT_UID, (abi_ulong) getuid()); -+ NEW_AUX_ENT(AT_EUID, (abi_ulong) geteuid()); -+ NEW_AUX_ENT(AT_GID, (abi_ulong) getgid()); -+ NEW_AUX_ENT(AT_EGID, (abi_ulong) getegid()); -+ NEW_AUX_ENT(AT_HWCAP, (abi_ulong) ELF_HWCAP); -+ NEW_AUX_ENT(AT_CLKTCK, (abi_ulong) sysconf(_SC_CLK_TCK)); -+ if (k_platform) -+ NEW_AUX_ENT(AT_PLATFORM, u_platform); -+#ifdef ARCH_DLINFO -+ /* -+ * ARCH_DLINFO must come last so platform specific code can enforce -+ * special alignment requirements on the AUXV if necessary (eg. PPC). -+ */ -+ ARCH_DLINFO; -+#endif -+#undef NEW_AUX_ENT -+ -+ sp = loader_build_argptr(envc, argc, sp, p, !ibcs); -+ return sp; -+} -+ -+#endif /* _TARGET_OS_ELF_H_ */ -diff --git a/bsd-user/openbsd/target_os_siginfo.h b/bsd-user/openbsd/target_os_siginfo.h -new file mode 100644 -index 0000000..baf646a ---- /dev/null -+++ b/bsd-user/openbsd/target_os_siginfo.h -@@ -0,0 +1,82 @@ -+#ifndef _TARGET_OS_SIGINFO_H_ -+#define _TARGET_OS_SIGINFO_H_ -+ -+#define TARGET_NSIG 32 /* counting 0; could be 33 (mask is 1-32) */ -+#define TARGET_NSIG_BPW (sizeof(uint32_t) * 8) -+#define TARGET_NSIG_WORDS (TARGET_NSIG / TARGET_NSIG_BPW) -+ -+/* this struct defines a stack used during syscall handling */ -+typedef struct target_sigaltstack { -+ abi_long ss_sp; -+ abi_ulong ss_size; -+ abi_long ss_flags; -+} target_stack_t; -+ -+typedef struct { -+ uint32_t __bits[TARGET_NSIG_WORDS]; -+} target_sigset_t -+ -+struct target_sigaction { -+ abi_ulong _sa_handler; -+ int32_t sa_flags; -+ target_sigset_t sa_mask; -+}; -+ -+/* Compare to sys/siginfo.h */ -+typedef union target_sigval { -+ int sival_int; -+ abi_ulong sival_ptr; -+} target_sigval_t; -+ -+struct target_ksiginfo { -+ int32_t _signo; -+ int32_t _code; -+ int32_t _errno; -+#if TARGET_ABI_BITS == 64 -+ int32_t _pad; -+#endif -+ union { -+ struct { -+ int32_t _pid; -+ int32_t _uid; -+ target_sigval_t _value; -+ } _rt; -+ -+ struct { -+ int32_t _pid; -+ int32_t _uid; -+ int32_t _struct; -+ /* clock_t _utime; */ -+ /* clock_t _stime; */ -+ } _child; -+ -+ struct { -+ abi_ulong _addr; -+ int32_t _trap; -+ } _fault; -+ -+ struct { -+ long _band; -+ int _fd; -+ } _poll; -+ } _reason; -+}; -+ -+typedef union target_siginfo { -+ int8_t si_pad[128]; -+ struct target_ksiginfo _info; -+} target_siginfo_t; -+ -+#define target_si_signo _info._signo -+#define target_si_code _info._code -+#define target_si_errno _info._errno -+#define target_si_addr _info._reason._fault._addr -+ -+#define TARGET_SEGV_MAPERR 1 -+#define TARGET_SEGV_ACCERR 2 -+ -+#define TARGET_TRAP_BRKPT 1 -+#define TARGET_TRAP_TRACE 2 -+ -+ -+#endif /* ! _TARGET_OS_SIGINFO_H_ */ -diff --git a/bsd-user/openbsd/target_os_signal.h b/bsd-user/openbsd/target_os_signal.h -new file mode 100644 -index 0000000..d39a26f ---- /dev/null -+++ b/bsd-user/openbsd/target_os_signal.h -@@ -0,0 +1,70 @@ -+#ifndef _TARGET_OS_SIGNAL_H_ -+#define _TARGET_OS_SIGNAL_H_ -+ -+#include "target_os_siginfo.h" -+#include "target_arch_signal.h" -+ -+#define TARGET_SIGHUP 1 /* hangup */ -+#define TARGET_SIGINT 2 /* interrupt */ -+#define TARGET_SIGQUIT 3 /* quit */ -+#define TARGET_SIGILL 4 /* illegal instruction (not reset when caught) */ -+#define TARGET_SIGTRAP 5 /* trace trap (not reset when caught) */ -+#define TARGET_SIGABRT 6 /* abort() */ -+#define TARGET_SIGIOT SIGABRT /* compatibility */ -+#define TARGET_SIGEMT 7 /* EMT instruction */ -+#define TARGET_SIGFPE 8 /* floating point exception */ -+#define TARGET_SIGKILL 9 /* kill (cannot be caught or ignored) */ -+#define TARGET_SIGBUS 10 /* bus error */ -+#define TARGET_SIGSEGV 11 /* segmentation violation */ -+#define TARGET_SIGSYS 12 /* bad argument to system call */ -+#define TARGET_SIGPIPE 13 /* write on a pipe with no one to read it */ -+#define TARGET_SIGALRM 14 /* alarm clock */ -+#define TARGET_SIGTERM 15 /* software termination signal from kill */ -+#define TARGET_SIGURG 16 /* urgent condition on IO channel */ -+#define TARGET_SIGSTOP 17 /* sendable stop signal not from tty */ -+#define TARGET_SIGTSTP 18 /* stop signal from tty */ -+#define TARGET_SIGCONT 19 /* continue a stopped process */ -+#define TARGET_SIGCHLD 20 /* to parent on child stop or exit */ -+#define TARGET_SIGTTIN 21 /* to readers pgrp upon background tty read */ -+#define TARGET_SIGTTOU 22 /* like TTIN for output if -+ (tp->t_local<OSTOP) */ -+#define TARGET_SIGIO 23 /* input/output possible signal */ -+#define TARGET_SIGXCPU 24 /* exceeded CPU time limit */ -+#define TARGET_SIGXFSZ 25 /* exceeded file size limit */ -+#define TARGET_SIGVTALRM 26 /* virtual time alarm */ -+#define TARGET_SIGPROF 27 /* profiling time alarm */ -+#define TARGET_SIGWINCH 28 /* window size changes */ -+#define TARGET_SIGINFO 29 /* information request */ -+#define TARGET_SIGUSR1 30 /* user defined signal 1 */ -+#define TARGET_SIGUSR2 31 /* user defined signal 2 */ -+ -+/* -+ * Language spec says we must list exactly one parameter, even though we -+ * actually supply three. Ugh! -+ */ -+#define TARGET_SIG_DFL ((void (*)(int))0) -+#define TARGET_SIG_IGN ((void (*)(int))1) -+#define TARGET_SIG_ERR ((void (*)(int))-1) -+ -+#define TARGET_SA_ONSTACK 0x0001 /* take signal on signal stack */ -+#define TARGET_SA_RESTART 0x0002 /* restart system on signal return */ -+#define TARGET_SA_RESETHAND 0x0004 /* reset to SIG_DFL when taking signal */ -+#define TARGET_SA_NODEFER 0x0010 /* don't mask the signal we're delivering */ -+#define TARGET_SA_NOCLDWAIT 0x0020 /* don't create zombies (assign to pid 1) */ -+#define TARGET_SA_USERTRAMP 0x0100 /* do not bounce off kernel's sigtramp */ -+#define TARGET_SA_NOCLDSTOP 0x0008 /* do not generate SIGCHLD on child stop */ -+#define TARGET_SA_SIGINFO 0x0040 /* generate siginfo_t */ -+ -+/* -+ * Flags for sigprocmask: -+ */ -+#define TARGET_SIG_BLOCK 1 /* block specified signal set */ -+#define TARGET_SIG_UNBLOCK 2 /* unblock specified signal set */ -+#define TARGET_SIG_SETMASK 3 /* set specified signal set */ -+ -+#define TARGET_BADSIG SIG_ERR -+ -+#define TARGET_SS_ONSTACK 0x0001 /* take signals on alternate stack */ -+#define TARGET_SS_DISABLE 0x0004 /* disable taking signals on alternate stack */ -+ -+#endif /* !_TARGET_OS_SIGNAL_H_ */ -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/openbsd/target_os_thread.h b/bsd-user/openbsd/target_os_thread.h -new file mode 100644 -index 0000000..519aad8 ---- /dev/null -+++ b/bsd-user/openbsd/target_os_thread.h -@@ -0,0 +1,6 @@ -+#ifndef _TARGET_OS_THREAD_H_ -+#define _TARGET_OS_THREAD_H_ -+ -+#include "target_arch_thread.h" -+ -+#endif /* !_TARGET_OS_THREAD_H_ */ -diff --git a/bsd-user/qemu-bsd.h b/bsd-user/qemu-bsd.h -new file mode 100644 -index 0000000..771245d ---- /dev/null -+++ b/bsd-user/qemu-bsd.h -@@ -0,0 +1,79 @@ -+/* -+ * BSD conversion extern declarations -+ * -+ * Copyright (c) 2013 Stacey D. Son -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ -+#ifndef _QEMU_BSD_H_ -+#define _QEMU_BSD_H_ -+ -+#include <sys/types.h> -+#include <sys/ipc.h> -+#include <sys/msg.h> -+#include <sys/resource.h> -+#include <sys/sem.h> -+#include <sys/shm.h> -+#include <sys/socket.h> -+#include <sys/un.h> -+#include <sys/uuid.h> -+#include <sys/wait.h> -+#include <netinet/in.h> -+ -+/* bsd-mem.c */ -+abi_long target_to_host_ipc_perm(struct ipc_perm *host_ip, -+ abi_ulong target_addr); -+abi_long host_to_target_ipc_perm(abi_ulong target_addr, -+ struct ipc_perm *host_ip); -+abi_long target_to_host_shmid_ds(struct shmid_ds *host_sd, -+ abi_ulong target_addr); -+abi_long host_to_target_shmid_ds(abi_ulong target_addr, -+ struct shmid_ds *host_sd); -+ -+/* bsd-proc.c */ -+int target_to_host_resource(int code); -+rlim_t target_to_host_rlim(abi_ulong target_rlim); -+abi_ulong host_to_target_rlim(rlim_t rlim); -+abi_long host_to_target_rusage(abi_ulong target_addr, -+ const struct rusage *rusage); -+int host_to_target_waitstatus(int status); -+ -+/* bsd-socket.c */ -+abi_long target_to_host_sockaddr(struct sockaddr *addr, abi_ulong target_addr, -+ socklen_t len); -+abi_long host_to_target_sockaddr(abi_ulong target_addr, struct sockaddr *addr, -+ socklen_t len); -+abi_long target_to_host_ip_mreq(struct ip_mreqn *mreqn, abi_ulong target_addr, -+ socklen_t len); -+ -+/* bsd-misc.c */ -+abi_long host_to_target_uuid(abi_ulong target_addr, struct uuid *host_uuid); -+ -+abi_long target_to_host_semarray(int semid, unsigned short **host_array, -+ abi_ulong target_addr); -+abi_long host_to_target_semarray(int semid, abi_ulong target_addr, -+ unsigned short **host_array); -+ -+abi_long target_to_host_semid_ds(struct semid_ds *host_sd, -+ abi_ulong target_addr); -+abi_long host_to_target_semid_ds(abi_ulong target_addr, -+ struct semid_ds *host_sd); -+ -+abi_long target_to_host_msqid_ds(struct msqid_ds *host_md, -+ abi_ulong target_addr); -+abi_long host_to_target_msqid_ds(abi_ulong target_addr, -+ struct msqid_ds *host_md); -+ -+#endif /* !_QEMU_BSD_H_ */ -diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h -index ddc74ed..10d0fc4 100644 ---- a/bsd-user/qemu.h -+++ b/bsd-user/qemu.h -@@ -1,3 +1,19 @@ -+/* -+ * qemu bsd user mode definition -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ - #ifndef QEMU_H - #define QEMU_H - -@@ -20,16 +36,14 @@ enum BSDType { - }; - extern enum BSDType bsd_type; - -+#include "exec/user/thunk.h" - #include "syscall_defs.h" - #include "syscall.h" --#include "target_signal.h" -+#include "target_os_vmparam.h" -+#include "target_os_signal.h" - #include "exec/gdbstub.h" - --#if defined(CONFIG_USE_NPTL) - #define THREAD __thread --#else --#define THREAD --#endif - - /* This struct is used to hold certain information about the image. - * Basically, it replicates in user space what would be certain -@@ -50,21 +64,23 @@ struct image_info { - abi_ulong entry; - abi_ulong code_offset; - abi_ulong data_offset; -+ abi_ulong arg_start; -+ abi_ulong arg_end; - int personality; - }; - - #define MAX_SIGQUEUE_SIZE 1024 - --struct sigqueue { -- struct sigqueue *next; -- //target_siginfo_t info; -+struct qemu_sigqueue { -+ struct qemu_sigqueue *next; -+ target_siginfo_t info; - }; - - struct emulated_sigtable { - int pending; /* true if signal is pending */ -- struct sigqueue *first; -- struct sigqueue info; /* in order to always have memory for the -- first signal, we put it here */ -+ struct qemu_sigqueue *first; -+ struct qemu_sigqueue info; /* in order to always have memory for the -+ first signal, we put it here */ - }; - - /* NOTE: we force a big alignment so that the stack stored after is -@@ -72,17 +88,28 @@ struct emulated_sigtable { - typedef struct TaskState { - struct TaskState *next; - int used; /* non zero if used */ -+#ifdef TARGET_ARM -+ int swi_errno; -+#endif -+#if defined(TARGET_ARM) || defined(TARGET_M68K) || defined(TARGET_UNICORE32) -+ /* Extra fields for semihosted binaries. */ -+ uint32_t heap_base; -+ uint32_t heap_limit; -+ uint32_t stack_base; -+#endif - struct image_info *info; -+ struct bsd_binprm *bprm; - - struct emulated_sigtable sigtab[TARGET_NSIG]; -- struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ -- struct sigqueue *first_free; /* first free siginfo queue entry */ -+ struct qemu_sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */ -+ struct qemu_sigqueue *first_free; /* first free siginfo queue entry */ - int signal_pending; /* non zero if a signal may be pending */ - - uint8_t stack[0]; - } __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; -@@ -100,7 +127,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; -@@ -109,19 +136,23 @@ struct linux_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 linux_binprm * bprm, struct target_pt_regs * regs, -- struct image_info * info); --int load_flt_binary(struct linux_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); -@@ -149,6 +180,16 @@ void fork_end(int child); - #include "qemu/log.h" - - /* strace.c */ -+struct syscallname { -+ int nr; -+ const char *name; -+ const char *format; -+ void (*call)(const struct syscallname *, -+ abi_long, abi_long, abi_long, -+ abi_long, abi_long, abi_long); -+ void (*result)(const struct syscallname *, abi_long); -+}; -+ - void - print_freebsd_syscall(int num, - abi_long arg1, abi_long arg2, abi_long arg3, -@@ -169,17 +210,24 @@ extern int do_strace; - /* signal.c */ - void process_pending_signals(CPUArchState *cpu_env); - void signal_init(void); --//int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info); --//void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info); --//void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo); --long do_sigreturn(CPUArchState *env); -+int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info); -+void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info); -+void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo); -+int target_to_host_signal(int sig); -+int host_to_target_signal(int sig); -+void host_to_target_sigset(target_sigset_t *d, const sigset_t *s); -+void target_to_host_sigset(sigset_t *d, const target_sigset_t *s); -+long do_sigreturn(CPUArchState *env, abi_ulong addr); - long do_rt_sigreturn(CPUArchState *env); - abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp); -+int do_sigaction(int sig, const struct target_sigaction *act, -+ struct target_sigaction *oact); -+void QEMU_NORETURN force_sig(int target_sig); - - /* mmap.c */ - int target_mprotect(abi_ulong start, abi_ulong len, int prot); - abi_long target_mmap(abi_ulong start, abi_ulong len, int prot, -- int flags, int fd, abi_ulong offset); -+ int flags, int fd, off_t offset); - int target_munmap(abi_ulong start, abi_ulong len); - abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size, - abi_ulong new_size, unsigned long flags, -@@ -188,15 +236,73 @@ int target_msync(abi_ulong start, abi_ulong len, int flags); - extern unsigned long last_brk; - void mmap_lock(void); - void mmap_unlock(void); -+abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size); - void cpu_list_lock(void); - void cpu_list_unlock(void); --#if defined(CONFIG_USE_NPTL) - 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); -+ -+/* syscall.c */ -+abi_long get_errno(abi_long ret); -+int is_error(abi_long ret); -+int host_to_target_errno(int err); -+ -+/* os-proc.c */ -+abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, -+ abi_ulong guest_envp, int do_fexec); -+ -+/* 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); -+ -+/* os-thread.c */ -+extern pthread_mutex_t *new_freebsd_thread_lock_ptr; -+void *new_freebsd_thread_start(void *arg); -+abi_long freebsd_lock_umtx(abi_ulong target_addr, abi_long tid, -+ struct timespec *timeout); -+abi_long freebsd_unlock_umtx(abi_ulong target_addr, abi_long id); -+abi_long freebsd_umtx_wait(abi_ulong targ_addr, abi_ulong id, -+ struct timespec *ts); -+abi_long freebsd_umtx_wake(abi_ulong target_addr, uint32_t n_wake); -+abi_long freebsd_umtx_mutex_wake(abi_ulong target_addr, abi_long val); -+abi_long freebsd_umtx_wait_uint(abi_ulong obj, uint32_t val, -+ struct timespec *timeout); -+abi_long freebsd_umtx_wait_uint_private(abi_ulong obj, uint32_t val, -+ struct timespec *timeout); -+abi_long freebsd_umtx_wake_private(abi_ulong obj, uint32_t val); -+#if defined(__FreeBSD_version) && __FreeBSD_version > 900000 -+abi_long freebsd_umtx_nwake_private(abi_ulong obj, uint32_t val); -+abi_long freebsd_umtx_mutex_wake2(abi_ulong obj, uint32_t val); -+abi_long freebsd_umtx_sem_wait(abi_ulong obj, struct timespec *timeout); -+abi_long freebsd_umtx_sem_wake(abi_ulong obj, uint32_t val); -+#endif -+abi_long freebsd_lock_umutex(abi_ulong target_addr, uint32_t id, -+ struct timespec *ts, int mode); -+abi_long freebsd_unlock_umutex(abi_ulong target_addr, uint32_t id); -+abi_long freebsd_cv_wait(abi_ulong target_ucond_addr, -+ abi_ulong target_umtx_addr, struct timespec *ts, int wflags); -+abi_long freebsd_cv_signal(abi_ulong target_ucond_addr); -+abi_long freebsd_cv_broadcast(abi_ulong target_ucond_addr); -+abi_long freebsd_rw_rdlock(abi_ulong target_addr, long fflag, -+ struct timespec *ts); -+abi_long freebsd_rw_wrlock(abi_ulong target_addr, long fflag, -+ struct timespec *ts); -+abi_long freebsd_rw_unlock(abi_ulong target_addr); -+ - - /* user access */ - -@@ -387,8 +493,42 @@ 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) --#include <pthread.h> -+#if TARGET_ABI_BITS == 32 -+static inline uint64_t -+target_offset64(uint32_t word0, uint32_t word1) -+{ -+#ifdef TARGET_WORDS_BIGENDIAN -+ return ((uint64_t)word0 << 32) | word1; -+#else -+ return ((uint64_t)word1 << 32) | word0; - #endif -+} -+#else /* TARGET_ABI_BITS != 32 */ -+static inline uint64_t -+target_offset64(uint64_t word0, uint64_t word1) -+{ -+ return word0; -+} -+#endif /* TARGET_ABI_BITS != 32 */ -+ -+/* ARM EABI and MIPS expect 64bit types aligned even on pairs of registers */ -+#ifdef TARGET_ARM -+static inline int -+regpairs_aligned(void *cpu_env) { -+ return ((((CPUARMState *)cpu_env)->eabi) == 1); -+} -+#elif defined(TARGET_MIPS) && TARGET_ABI_BITS == 32 -+static inline int regpairs_aligned(void *cpu_env) -+{ -+ return 1; -+} -+#else -+static inline int regpairs_aligned(void *cpu_env) -+{ -+ return 0; -+} -+#endif -+ -+#include <pthread.h> - - #endif /* QEMU_H */ -diff --git a/bsd-user/signal.c b/bsd-user/signal.c -index 445f69e..3619b00 100644 ---- a/bsd-user/signal.c -+++ b/bsd-user/signal.c -@@ -2,6 +2,7 @@ - * Emulation of BSD signals - * - * 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,16 +24,920 @@ - #include <unistd.h> - #include <signal.h> - #include <errno.h> -+#include <sys/types.h> -+#include <sys/time.h> -+#include <sys/resource.h> - - #include "qemu.h" --#include "target_signal.h" - - //#define DEBUG_SIGNAL - -+static target_stack_t target_sigaltstack_used = { -+ .ss_sp = 0, -+ .ss_size = 0, -+ .ss_flags = TARGET_SS_DISABLE, -+}; -+ -+static uint8_t host_to_target_signal_table[TARGET_NSIG] = { -+ [SIGHUP] = TARGET_SIGHUP, -+ [SIGINT] = TARGET_SIGINT, -+ [SIGQUIT] = TARGET_SIGQUIT, -+ [SIGILL] = TARGET_SIGILL, -+ [SIGTRAP] = TARGET_SIGTRAP, -+ [SIGABRT] = TARGET_SIGABRT, -+ [SIGEMT] = TARGET_SIGEMT, -+ [SIGFPE] = TARGET_SIGFPE, -+ [SIGKILL] = TARGET_SIGKILL, -+ [SIGBUS] = TARGET_SIGBUS, -+ [SIGSEGV] = TARGET_SIGSEGV, -+ [SIGSYS] = TARGET_SIGSYS, -+ [SIGPIPE] = TARGET_SIGPIPE, -+ [SIGALRM] = TARGET_SIGALRM, -+ [SIGTERM] = TARGET_SIGTERM, -+ [SIGURG] = TARGET_SIGURG, -+ [SIGSTOP] = TARGET_SIGSTOP, -+ [SIGTSTP] = TARGET_SIGTSTP, -+ [SIGCONT] = TARGET_SIGCONT, -+ [SIGCHLD] = TARGET_SIGCHLD, -+ [SIGTTIN] = TARGET_SIGTTIN, -+ [SIGTTOU] = TARGET_SIGTTOU, -+ [SIGIO] = TARGET_SIGIO, -+ [SIGXCPU] = TARGET_SIGXCPU, -+ [SIGXFSZ] = TARGET_SIGXFSZ, -+ [SIGVTALRM] = TARGET_SIGVTALRM, -+ [SIGPROF] = TARGET_SIGPROF, -+ [SIGWINCH] = TARGET_SIGWINCH, -+ [SIGINFO] = TARGET_SIGINFO, -+ [SIGUSR1] = TARGET_SIGUSR1, -+ [SIGUSR2] = TARGET_SIGUSR2, -+#ifdef SIGTHR -+ [SIGTHR + 3] = TARGET_SIGTHR, -+#endif -+ /* [SIGLWP] = TARGET_SIGLWP, */ -+#ifdef SIGLIBRT -+ [SIGLIBRT] = TARGET_SIGLIBRT, -+#endif -+ -+ /* -+ * The following signals stay the same. -+ * Nasty hack: Reverse SIGRTMIN and SIGRTMAX to avoid overlap with -+ * host libpthread signals. This assumes no one actually uses -+ * SIGRTMAX. To fix this properly we need to manual signal delivery -+ * multiplexed over a single host signal. -+ */ -+ [SIGRTMIN] = SIGRTMAX, -+ [SIGRTMAX] = SIGRTMIN, -+}; -+ -+static uint8_t target_to_host_signal_table[TARGET_NSIG]; -+static struct target_sigaction sigact_table[TARGET_NSIG]; -+static void host_signal_handler(int host_signum, siginfo_t *info, void *puc); -+static void target_to_host_sigset_internal(sigset_t *d, -+ const target_sigset_t *s); -+ -+static inline int on_sig_stack(unsigned long sp) -+{ -+ return sp - target_sigaltstack_used.ss_sp < target_sigaltstack_used.ss_size; -+} -+ -+static inline int sas_ss_flags(unsigned long sp) -+{ -+ return target_sigaltstack_used.ss_size == 0 ? SS_DISABLE : on_sig_stack(sp) -+ ? SS_ONSTACK : 0; -+} -+ -+int host_to_target_signal(int sig) -+{ -+ -+ if (sig < 0 || sig >= TARGET_NSIG) { -+ return sig; -+ } -+ -+ return host_to_target_signal_table[sig]; -+} -+ -+int target_to_host_signal(int sig) -+{ -+ -+ if (sig >= TARGET_NSIG) { -+ return sig; -+ } -+ -+ return target_to_host_signal_table[sig]; -+} -+ -+static inline void target_sigemptyset(target_sigset_t *set) -+{ -+ -+ memset(set, 0, sizeof(*set)); -+} -+ -+static inline void target_sigaddset(target_sigset_t *set, int signum) -+{ -+ -+ signum--; -+ uint32_t mask = (uint32_t)1 << (signum % TARGET_NSIG_BPW); -+ set->__bits[signum / TARGET_NSIG_BPW] |= mask; -+} -+ -+static inline int target_sigismember(const target_sigset_t *set, int signum) -+{ -+ -+ signum--; -+ abi_ulong mask = (abi_ulong)1 << (signum % TARGET_NSIG_BPW); -+ return (set->__bits[signum / TARGET_NSIG_BPW] & mask) != 0; -+} -+ -+static void host_to_target_sigset_internal(target_sigset_t *d, -+ const sigset_t *s) -+{ -+ int i; -+ -+ target_sigemptyset(d); -+ for (i = 1; i <= TARGET_NSIG; i++) { -+ if (sigismember(s, i)) { -+ target_sigaddset(d, host_to_target_signal(i)); -+ } -+ } -+} -+ -+void host_to_target_sigset(target_sigset_t *d, const sigset_t *s) -+{ -+ target_sigset_t d1; -+ int i; -+ -+ host_to_target_sigset_internal(&d1, s); -+ for (i = 0; i < TARGET_NSIG_WORDS; i++) { -+ d->__bits[i] = tswap32(d1.__bits[i]); -+ } -+} -+ -+static void target_to_host_sigset_internal(sigset_t *d, -+ const target_sigset_t *s) -+{ -+ int i; -+ -+ sigemptyset(d); -+ for (i = 1; i <= TARGET_NSIG; i++) { -+ if (target_sigismember(s, i)) { -+ sigaddset(d, target_to_host_signal(i)); -+ } -+ } -+} -+ -+void target_to_host_sigset(sigset_t *d, const target_sigset_t *s) -+{ -+ target_sigset_t s1; -+ int i; -+ -+ for (i = 0; i < TARGET_NSIG_WORDS; i++) { -+ s1.__bits[i] = tswap32(s->__bits[i]); -+ } -+ target_to_host_sigset_internal(d, &s1); -+} -+ -+/* Siginfo conversion. */ -+static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, -+ const siginfo_t *info) -+{ -+ int sig, code; -+ -+ sig = host_to_target_signal(info->si_signo); -+ /* XXX should have host_to_target_si_code() */ -+ code = tswap32(info->si_code); -+ tinfo->si_signo = sig; -+ tinfo->si_errno = info->si_errno; -+ tinfo->si_code = info->si_code; -+ tinfo->si_pid = info->si_pid; -+ tinfo->si_uid = info->si_uid; -+ tinfo->si_addr = (abi_ulong)(unsigned long)info->si_addr; -+ /* si_value is opaque to kernel */ -+ tinfo->si_value.sival_ptr = -+ (abi_ulong)(unsigned long)info->si_value.sival_ptr; -+ if (SIGILL == sig || SIGFPE == sig || SIGSEGV == sig || SIGBUS == sig || -+ SIGTRAP == sig) { -+ tinfo->_reason._fault._trapno = info->_reason._fault._trapno; -+ } -+#ifdef SIGPOLL -+ if (SIGPOLL == sig) { -+ tinfo->_reason._poll._band = info->_reason._poll._band; -+ } -+#endif -+ if (SI_TIMER == code) { -+ tinfo->_reason._timer._timerid = info->_reason._timer._timerid; -+ tinfo->_reason._timer._overrun = info->_reason._timer._overrun; -+ } -+} -+ -+static void tswap_siginfo(target_siginfo_t *tinfo, const target_siginfo_t *info) -+{ -+ int sig, code; -+ -+ sig = info->si_signo; -+ code = info->si_code; -+ tinfo->si_signo = tswap32(sig); -+ tinfo->si_errno = tswap32(info->si_errno); -+ tinfo->si_code = tswap32(info->si_code); -+ tinfo->si_pid = tswap32(info->si_pid); -+ tinfo->si_uid = tswap32(info->si_uid); -+ tinfo->si_addr = tswapal(info->si_addr); -+ if (SIGILL == sig || SIGFPE == sig || SIGSEGV == sig || SIGBUS == sig || -+ SIGTRAP == sig) { -+ tinfo->_reason._fault._trapno = tswap32(info->_reason._fault._trapno); -+ } -+#ifdef SIGPOLL -+ if (SIGPOLL == sig) { -+ tinfo->_reason._poll._band = tswap32(info->_reason._poll._band); -+ } -+#endif -+ if (SI_TIMER == code) { -+ tinfo->_reason._timer._timerid = tswap32(info->_reason._timer._timerid); -+ tinfo->_reason._timer._overrun = tswap32(info->_reason._timer._overrun); -+ } -+} -+ -+void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info) -+{ -+ -+ host_to_target_siginfo_noswap(tinfo, info); -+ tswap_siginfo(tinfo, tinfo); -+} -+ -+/* Returns 1 if given signal should dump core if not handled. */ -+static int core_dump_signal(int sig) -+{ -+ switch (sig) { -+ case TARGET_SIGABRT: -+ case TARGET_SIGFPE: -+ case TARGET_SIGILL: -+ case TARGET_SIGQUIT: -+ case TARGET_SIGSEGV: -+ case TARGET_SIGTRAP: -+ case TARGET_SIGBUS: -+ return 1; -+ default: -+ return 0; -+ } -+} -+ -+/* Signal queue handling. */ -+static inline struct qemu_sigqueue *alloc_sigqueue(CPUArchState *env) -+{ -+ TaskState *ts = env->opaque; -+ struct qemu_sigqueue *q = ts->first_free; -+ -+ if (!q) { -+ return NULL; -+ } -+ ts->first_free = q->next; -+ return q; -+} -+ -+static inline void free_sigqueue(CPUArchState *env, struct qemu_sigqueue *q) -+{ -+ -+ TaskState *ts = env->opaque; -+ q->next = ts->first_free; -+ ts->first_free = q; -+} -+ -+/* Abort execution with signal. */ -+void QEMU_NORETURN force_sig(int target_sig) -+{ -+ CPUArchState *env = thread_cpu->env_ptr; -+ TaskState *ts = (TaskState *)env->opaque; -+ int core_dumped = 0; -+ int host_sig; -+ struct sigaction act; -+ -+ host_sig = target_to_host_signal(target_sig); -+ gdb_signalled(env, target_sig); -+ -+ /* Dump core if supported by target binary format */ -+ if (core_dump_signal(target_sig) && (ts->bprm->core_dump != NULL)) { -+ stop_all_tasks(); -+ core_dumped = -+ ((*ts->bprm->core_dump)(target_sig, env) == 0); -+ } -+ if (core_dumped) { -+ struct rlimit nodump; -+ -+ /* -+ * We already dumped the core of target process, we don't want -+ * a coredump of qemu itself. -+ */ -+ getrlimit(RLIMIT_CORE, &nodump); -+ nodump.rlim_cur = 0; -+ setrlimit(RLIMIT_CORE, &nodump); -+ (void) fprintf(stderr, "qemu: uncaught target signal %d (%s) " -+ "- %s\n", target_sig, strsignal(host_sig), "core dumped"); -+ } -+ -+ /* -+ * The proper exit code for dying from an uncaught signal is -+ * -<signal>. The kernel doesn't allow exit() or _exit() to pass -+ * a negative value. To get the proper exit code we need to -+ * actually die from an uncaught signal. Here the default signal -+ * handler is installed, we send ourself a signal and we wait for -+ * it to arrive. -+ */ -+ memset(&act, 0, sizeof(act)); -+ sigfillset(&act.sa_mask); -+ act.sa_handler = SIG_DFL; -+ sigaction(host_sig, &act, NULL); -+ -+ kill(getpid(), host_sig); -+ -+ /* -+ * Make sure the signal isn't masked (just reuse the mask inside -+ * of act). -+ */ -+ sigdelset(&act.sa_mask, host_sig); -+ sigsuspend(&act.sa_mask); -+ -+ /* unreachable */ -+ abort(); -+} -+ -+/* -+ * Queue a signal so that it will be send to the virtual CPU as soon as -+ * possible. -+ */ -+int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info) -+{ -+ TaskState *ts = env->opaque; -+ struct emulated_sigtable *k; -+ struct qemu_sigqueue *q, **pq; -+ abi_ulong handler; -+ int queue; -+ -+ k = &ts->sigtab[sig - 1]; -+ queue = gdb_queuesig(); -+ handler = sigact_table[sig - 1]._sa_handler; -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "queue_signal: sig=%d handler=0x%lx flags=0x%x\n", sig, -+ handler, (uint32_t)sigact_table[sig - 1].sa_flags); -+#endif -+ if (!queue && (TARGET_SIG_DFL == handler)) { -+ if (sig == TARGET_SIGTSTP || sig == TARGET_SIGTTIN || -+ sig == TARGET_SIGTTOU) { -+ kill(getpid(), SIGSTOP); -+ return 0; -+ } else { -+ if (sig != TARGET_SIGCHLD && -+ sig != TARGET_SIGURG && -+ sig != TARGET_SIGWINCH && -+ sig != TARGET_SIGCONT) { -+ force_sig(sig); -+ } else { -+ return 0; /* The signal was ignored. */ -+ } -+ } -+ } else if (!queue && (TARGET_SIG_IGN == handler)) { -+ return 0; /* Ignored signal. */ -+ } else if (!queue && (TARGET_SIG_ERR == handler)) { -+ force_sig(sig); -+ } else { -+ pq = &k->first; -+ -+ /* -+ * FreeBSD signals are always queued. -+ * Linux only queues real time signals. -+ * XXX this code is not thread safe. -+ */ -+ if (!k->pending) { -+ /* first signal */ -+ q = &k->info; -+ } else { -+ q = alloc_sigqueue(env); -+ if (!q) { -+ return -EAGAIN; -+ } -+ while (*pq != NULL) { -+ pq = &(*pq)->next; -+ } -+ } -+ *pq = q; -+ q->info = *info; -+ q->next = NULL; -+ k->pending = 1; -+ /* Signal that a new signal is pending. */ -+ ts->signal_pending = 1; -+ return 1; /* Indicates that the signal was queued. */ -+ } -+} -+ -+static void host_signal_handler(int host_signum, siginfo_t *info, void *puc) -+{ -+ CPUArchState *env = thread_cpu->env_ptr; -+ int sig; -+ target_siginfo_t tinfo; -+ -+ /* -+ * The CPU emulator uses some host signal to detect exceptions so -+ * we forward to it some signals. -+ */ -+ if ((host_signum == SIGSEGV || host_signum == SIGBUS) && -+ info->si_code < 0x10000) { -+ if (cpu_signal_handler(host_signum, info, puc)) { -+ return; -+ } -+ } -+ -+ /* Get the target signal number. */ -+ sig = host_to_target_signal(host_signum); -+ if (sig < 1 || sig > TARGET_NSIG) { -+ return; -+ } -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "qemu: got signal %d\n", sig); -+#endif -+ host_to_target_siginfo_noswap(&tinfo, info); -+ if (queue_signal(env, sig, &tinfo) == 1) { -+ /* Interrupt the virtual CPU as soon as possible. */ -+ cpu_exit(thread_cpu); -+ } -+} -+ -+/* do_sigaltstack() returns target values and errnos. */ -+/* compare to kern/kern_sig.c sys_sigaltstack() and kern_sigaltstack() */ -+abi_long do_sigaltstack(abi_ulong uss_addr, abi_ulong uoss_addr, abi_ulong sp) -+{ -+ int ret = 0; -+ target_stack_t ss, oss, *uss; -+ -+ if (uoss_addr) { -+ /* Save current signal stack params */ -+ oss.ss_sp = tswapl(target_sigaltstack_used.ss_sp); -+ oss.ss_size = tswapl(target_sigaltstack_used.ss_size); -+ oss.ss_flags = tswapl(sas_ss_flags(sp)); -+ } -+ -+ if (uss_addr) { -+ -+ if (!lock_user_struct(VERIFY_READ, uss, uss_addr, 1) || -+ __get_user(ss.ss_sp, &uss->ss_sp) || -+ __get_user(ss.ss_size, &uss->ss_size) || -+ __get_user(ss.ss_flags, &uss->ss_flags)) { -+ ret = -TARGET_EFAULT; -+ goto out; -+ } -+ unlock_user_struct(uss, uss_addr, 0); -+ -+ if (on_sig_stack(sp)) { -+ ret = -TARGET_EPERM; -+ goto out; -+ } -+ -+ if ((ss.ss_flags & ~TARGET_SS_DISABLE) != 0) { -+ ret = -TARGET_EINVAL; -+ goto out; -+ } -+ -+ if (!(ss.ss_flags & ~TARGET_SS_DISABLE)) { -+ if (ss.ss_size < TARGET_MINSIGSTKSZ) { -+ ret = -TARGET_ENOMEM; -+ goto out; -+ } -+ } else { -+ ss.ss_size = 0; -+ ss.ss_sp = 0; -+ } -+ -+ target_sigaltstack_used.ss_sp = ss.ss_sp; -+ target_sigaltstack_used.ss_size = ss.ss_size; -+ } -+ -+ if (uoss_addr) { -+ /* Copy out to user saved signal stack params */ -+ if (copy_to_user(uoss_addr, &oss, sizeof(oss))) { -+ ret = -TARGET_EFAULT; -+ goto out; -+ } -+ } -+ -+out: -+ return ret; -+} -+ -+static int fatal_signal(int sig) -+{ -+ -+ switch (sig) { -+ case TARGET_SIGCHLD: -+ case TARGET_SIGURG: -+ case TARGET_SIGWINCH: -+ /* Ignored by default. */ -+ return 0; -+ case TARGET_SIGCONT: -+ case TARGET_SIGSTOP: -+ case TARGET_SIGTSTP: -+ case TARGET_SIGTTIN: -+ case TARGET_SIGTTOU: -+ /* Job control signals. */ -+ return 0; -+ default: -+ return 1; -+ } -+} -+ -+/* do_sigaction() return host values and errnos */ -+int do_sigaction(int sig, const struct target_sigaction *act, -+ struct target_sigaction *oact) -+{ -+ struct target_sigaction *k; -+ struct sigaction act1; -+ int host_sig; -+ int ret = 0; -+ -+ if (sig < 1 || sig > TARGET_NSIG || TARGET_SIGKILL == sig || -+ TARGET_SIGSTOP == sig) { -+ return -EINVAL; -+ } -+ k = &sigact_table[sig - 1]; -+#if defined(DEBUG_SIGNAL) -+ fprintf(stderr, "do_sigaction sig=%d act=%p, oact=%p\n", -+ sig, act, oact); -+#endif -+ if (oact) { -+ oact->_sa_handler = tswapal(k->_sa_handler); -+ oact->sa_flags = tswap32(k->sa_flags); -+ oact->sa_mask = k->sa_mask; -+ } -+ if (act) { -+ /* XXX: this is most likely not threadsafe. */ -+ k->_sa_handler = tswapal(act->_sa_handler); -+ k->sa_flags = tswap32(act->sa_flags); -+ k->sa_mask = act->sa_mask; -+ -+ /* Update the host signal state. */ -+ host_sig = target_to_host_signal(sig); -+ if (host_sig != SIGSEGV && host_sig != SIGBUS) { -+ memset(&act1, 0, sizeof(struct sigaction)); -+ sigfillset(&act1.sa_mask); -+ if (k->sa_flags & TARGET_SA_RESTART) { -+ act1.sa_flags |= SA_RESTART; -+ } -+ /* -+ * Note: It is important to update the host kernel signal mask to -+ * avoid getting unexpected interrupted system calls. -+ */ -+ if (k->_sa_handler == TARGET_SIG_IGN) { -+ act1.sa_sigaction = (void *)SIG_IGN; -+ } else if (k->_sa_handler == TARGET_SIG_DFL) { -+ if (fatal_signal(sig)) { -+ act1.sa_flags = SA_SIGINFO; -+ act1.sa_sigaction = host_signal_handler; -+ } else { -+ act1.sa_sigaction = (void *)SIG_DFL; -+ } -+ } else { -+ act1.sa_flags = SA_SIGINFO; -+ act1.sa_sigaction = host_signal_handler; -+ } -+ ret = sigaction(host_sig, &act1, NULL); -+#if defined(DEBUG_SIGNAL) -+ fprintf(stderr, "sigaction (action = %p " -+ "(host_signal_handler = %p)) returned: %d\n", -+ act1.sa_sigaction, host_signal_handler, ret); -+#endif -+ } -+ } -+ return ret; -+} -+ -+static inline abi_ulong get_sigframe(struct target_sigaction *ka, -+ CPUArchState *regs, size_t frame_size) -+{ -+ abi_ulong sp; -+ -+ /* Use default user stack */ -+ sp = get_sp_from_cpustate(regs); -+ -+ if ((ka->sa_flags & TARGET_SA_ONSTACK) && (sas_ss_flags(sp) == 0)) { -+ sp = target_sigaltstack_used.ss_sp + -+ target_sigaltstack_used.ss_size; -+ } -+ -+#if defined(TARGET_MIPS) || defined(TARGET_ARM) -+ return (sp - frame_size) & ~7; -+#else -+ return sp - frame_size; -+#endif -+} -+ -+/* compare to mips/mips/pm_machdep.c and sparc64/sparc64/machdep.c sendsig() */ -+static void setup_frame(int sig, int code, struct target_sigaction *ka, -+ target_sigset_t *set, target_siginfo_t *tinfo, CPUArchState *regs) -+{ -+ struct target_sigframe *frame; -+ abi_ulong frame_addr; -+ int i; -+ -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "setup_frame()\n"); -+#endif -+ frame_addr = get_sigframe(ka, regs, sizeof(*frame)); -+ if (!lock_user_struct(VERIFY_WRITE, frame, frame_addr, 0)) { -+ goto give_sigsegv; -+ } -+ -+ memset(frame, 0, sizeof(*frame)); -+#if defined(TARGET_MIPS) -+ int mflags = on_sig_stack(frame_addr) ? TARGET_MC_ADD_MAGIC : -+ TARGET_MC_SET_ONSTACK | TARGET_MC_ADD_MAGIC; -+#else -+ int mflags = 0; -+#endif -+ if (get_mcontext(regs, &frame->sf_uc.uc_mcontext, mflags)) { -+ goto give_sigsegv; -+ } -+ -+ for (i = 0; i < TARGET_NSIG_WORDS; i++) { -+ if (__put_user(set->__bits[i], &frame->sf_uc.uc_sigmask.__bits[i])) { -+ goto give_sigsegv; -+ } -+ } -+ -+ if (tinfo) { -+ frame->sf_si.si_signo = tinfo->si_signo; -+ frame->sf_si.si_errno = tinfo->si_errno; -+ frame->sf_si.si_code = tinfo->si_code; -+ frame->sf_si.si_pid = tinfo->si_pid; -+ frame->sf_si.si_uid = tinfo->si_uid; -+ frame->sf_si.si_status = tinfo->si_status; -+ frame->sf_si.si_addr = tinfo->si_addr; -+ -+ if (TARGET_SIGILL == sig || TARGET_SIGFPE == sig || -+ TARGET_SIGSEGV == sig || TARGET_SIGBUS == sig || -+ TARGET_SIGTRAP == sig) { -+ frame->sf_si._reason._fault._trapno = tinfo->_reason._fault._trapno; -+ } -+ -+ /* -+ * If si_code is one of SI_QUEUE, SI_TIMER, SI_ASYNCIO, or -+ * SI_MESGQ, then si_value contains the application-specified -+ * signal value. Otherwise, the contents of si_value are -+ * undefined. -+ */ -+ if (SI_QUEUE == code || SI_TIMER == code || SI_ASYNCIO == code || -+ SI_MESGQ == code) { -+ frame->sf_si.si_value.sival_int = tinfo->si_value.sival_int; -+ } -+ -+ if (SI_TIMER == code) { -+ frame->sf_si._reason._timer._timerid = -+ tinfo->_reason._timer._timerid; -+ frame->sf_si._reason._timer._overrun = -+ tinfo->_reason._timer._overrun; -+ } -+ -+#ifdef SIGPOLL -+ if (SIGPOLL == sig) { -+ frame->sf_si._reason._band = tinfo->_reason._band; -+ } -+#endif -+ -+ } -+ -+ if (set_sigtramp_args(regs, sig, frame, frame_addr, ka)) { -+ goto give_sigsegv; -+ } -+ -+ unlock_user_struct(frame, frame_addr, 1); -+ return; -+ -+give_sigsegv: -+ unlock_user_struct(frame, frame_addr, 1); -+ force_sig(TARGET_SIGSEGV); -+} -+ -+static int reset_signal_mask(target_ucontext_t *ucontext) -+{ -+ int i; -+ sigset_t blocked; -+ target_sigset_t target_set; -+ -+ for (i = 0; i < TARGET_NSIG_WORDS; i++) -+ if (__get_user(target_set.__bits[i], -+ &ucontext->uc_sigmask.__bits[i])) { -+ return -TARGET_EFAULT; -+ } -+ target_to_host_sigset_internal(&blocked, &target_set); -+ sigprocmask(SIG_SETMASK, &blocked, NULL); -+ -+ return 0; -+} -+ -+long do_sigreturn(CPUArchState *regs, abi_ulong addr) -+{ -+ long ret; -+ abi_ulong target_ucontext; -+ target_ucontext_t *ucontext = NULL; -+ -+ /* Get the target ucontext address from the stack frame */ -+ ret = get_ucontext_sigreturn(regs, addr, &target_ucontext); -+ if (is_error(ret)) { -+ return ret; -+ } -+ if (!lock_user_struct(VERIFY_READ, ucontext, target_ucontext, 0)) { -+ goto badframe; -+ } -+ -+ /* Set the register state back to before the signal. */ -+ if (set_mcontext(regs, &ucontext->uc_mcontext, 1)) { -+ goto badframe; -+ } -+ -+ /* And reset the signal mask. */ -+ if (reset_signal_mask(ucontext)) { -+ goto badframe; -+ } -+ -+ unlock_user_struct(ucontext, target_ucontext, 0); -+ return -TARGET_EJUSTRETURN; -+ -+badframe: -+ if (ucontext != NULL) { -+ unlock_user_struct(ucontext, target_ucontext, 0); -+ } -+ force_sig(TARGET_SIGSEGV); -+ return -TARGET_EFAULT; -+} -+ - void signal_init(void) - { -+ struct sigaction act; -+ struct sigaction oact; -+ int i, j; -+ int host_sig; -+ -+ /* Generate the signal conversion tables. */ -+ for (i = 1; i < TARGET_NSIG; i++) { -+ if (host_to_target_signal_table[i] == 0) { -+ host_to_target_signal_table[i] = i; -+ } -+ } -+ for (i = 1; i < TARGET_NSIG; i++) { -+ j = host_to_target_signal_table[i]; -+ target_to_host_signal_table[j] = i; -+ } -+ -+ /* -+ * Set all host signal handlers. ALL signals are blocked during the -+ * handlers to serialize them. -+ */ -+ memset(sigact_table, 0, sizeof(sigact_table)); -+ -+ sigfillset(&act.sa_mask); -+ act.sa_sigaction = host_signal_handler; -+ act.sa_flags = SA_SIGINFO; -+ -+ for (i = 1; i <= TARGET_NSIG; i++) { -+ host_sig = target_to_host_signal(i); -+ sigaction(host_sig, NULL, &oact); -+ if (oact.sa_sigaction == (void *)SIG_IGN) { -+ sigact_table[i - 1]._sa_handler = TARGET_SIG_IGN; -+ } else if (oact.sa_sigaction == (void *)SIG_DFL) { -+ sigact_table[i - 1]._sa_handler = TARGET_SIG_DFL; -+ } -+ /* -+ * If there's already a handler installed then something has -+ * gone horribly wrong, so don't even try to handle that case. -+ * Install some handlers for our own use. We need at least -+ * SIGSEGV and SIGBUS, to detect exceptions. We can not just -+ * trap all signals because it affects syscall interrupt -+ * behavior. But do trap all default-fatal signals. -+ */ -+ if (fatal_signal(i)) { -+ sigaction(host_sig, &act, NULL); -+ } -+ } - } - - void process_pending_signals(CPUArchState *cpu_env) - { -+ CPUState *cpu = ENV_GET_CPU(cpu_env); -+ int sig, code; -+ abi_ulong handler; -+ sigset_t set, old_set; -+ target_sigset_t target_old_set; -+ target_siginfo_t tinfo; -+ struct emulated_sigtable *k; -+ struct target_sigaction *sa; -+ struct qemu_sigqueue *q; -+ TaskState *ts = cpu_env->opaque; -+ -+ if (!ts->signal_pending) { -+ return; -+ } -+ -+ /* FIXME: This is not threadsafe. */ -+ k = ts->sigtab; -+ for (sig = 1; sig <= TARGET_NSIG; sig++) { -+ if (k->pending) { -+ goto handle_signal; -+ } -+ k++; -+ } -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "qemu: process_pending_signals has no signals\n"); -+#endif -+ /* If no signal is pending then just return. */ -+ ts->signal_pending = 0; -+ return; -+ -+handle_signal: -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "qemu: process signal %d\n", sig); -+#endif -+ -+ /* Dequeue signal. */ -+ q = k->first; -+ k->first = q->next; -+ if (!k->first) { -+ k->pending = 0; -+ } -+ -+ sig = gdb_handlesig(cpu, sig); -+ if (!sig) { -+ sa = NULL; -+ handler = TARGET_SIG_IGN; -+ } else { -+ sa = &sigact_table[sig - 1]; -+ handler = sa->_sa_handler; -+ } -+ -+ if (handler == TARGET_SIG_DFL) { -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "qemu: TARGET_SIG_DFL\n"); -+#endif -+ /* -+ * default handler : ignore some signal. The other are job -+ * control or fatal. -+ */ -+ if (TARGET_SIGTSTP == sig || TARGET_SIGTTIN == sig || -+ TARGET_SIGTTOU == sig) { -+ kill(getpid(), SIGSTOP); -+ } else if (TARGET_SIGCHLD != sig && TARGET_SIGURG != sig && -+ TARGET_SIGWINCH != sig && TARGET_SIGCONT != sig) { -+ force_sig(sig); -+ } -+ } else if (TARGET_SIG_IGN == handler) { -+ /* ignore sig */ -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "qemu: TARGET_SIG_IGN\n"); -+#endif -+ } else if (TARGET_SIG_ERR == handler) { -+#ifdef DEBUG_SIGNAL -+ fprintf(stderr, "qemu: TARGET_SIG_ERR\n"); -+#endif -+ force_sig(sig); -+ } else { -+ /* compute the blocked signals during the handler execution */ -+ target_to_host_sigset(&set, &sa->sa_mask); -+ /* -+ * SA_NODEFER indicates that the current signal should not be -+ * blocked during the handler. -+ */ -+ if (!(sa->sa_flags & TARGET_SA_NODEFER)) { -+ sigaddset(&set, target_to_host_signal(sig)); -+ } -+ -+ /* block signals in the handler */ -+ sigprocmask(SIG_BLOCK, &set, &old_set); -+ -+ /* -+ * Save the previous blocked signal state to restore it at the -+ * end of the signal execution (see do_sigreturn). -+ */ -+ host_to_target_sigset_internal(&target_old_set, &old_set); -+ -+#if 0 /* not yet */ -+#if defined(TARGET_I386) && !defined(TARGET_X86_64) -+ /* if the CPU is in VM86 mode, we restore the 32 bit values */ -+ { -+ CPUX86State *env = cpu_env; -+ if (env->eflags & VM_MASK) { -+ save_v86_state(env); -+ } -+ } -+#endif -+#endif /* not yet */ -+ -+ code = q->info.si_code; -+ /* prepare the stack frame of the virtual CPU */ -+ if (sa->sa_flags & TARGET_SA_SIGINFO) { -+ tswap_siginfo(&tinfo, &q->info); -+ setup_frame(sig, code, sa, &target_old_set, &tinfo, cpu_env); -+ } else { -+ setup_frame(sig, code, sa, &target_old_set, NULL, cpu_env); -+ } -+ if (sa->sa_flags & TARGET_SA_RESETHAND) { -+ sa->_sa_handler = TARGET_SIG_DFL; -+ } -+ } -+ if (q != &k->info) { -+ free_sigqueue(cpu_env, q); -+ } - } -diff --git a/bsd-user/sparc/syscall.h b/bsd-user/sparc/syscall.h -index 5a9bb7e..3a5b1e2 100644 ---- a/bsd-user/sparc/syscall.h -+++ b/bsd-user/sparc/syscall.h -@@ -1,3 +1,23 @@ -+/* -+ * sparc dependent system call definitions -+ * -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+#ifndef _SPARC_SYSCALL_H_ -+#define _SPARC_SYSCALL_H_ -+ - struct target_pt_regs { - abi_ulong psr; - abi_ulong pc; -@@ -6,4 +26,11 @@ struct target_pt_regs { - abi_ulong u_regs[16]; - }; - --#define UNAME_MACHINE "sun4" -+#define UNAME_MACHINE "sun4" -+#define TARGET_HW_MACHINE "sparc" -+#define TARGET_HW_MACHINE_ARCH "sparc" -+ -+#define TARGET_SPARC_UTRAP_INSTALL 1 -+#define TARGET_SPARC_SIGTRAMP_INSTALL 2 -+ -+#endif /* ! _SPARC_SYSCALL_H_ */ -diff --git a/bsd-user/sparc/target_arch.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_elf.h b/bsd-user/sparc/target_arch_elf.h -new file mode 100644 -index 0000000..b93e2ed ---- /dev/null -+++ b/bsd-user/sparc/target_arch_elf.h -@@ -0,0 +1,30 @@ -+/* -+ * sparc ELF 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 _TARGET_ARCH_ELF_H_ -+#define _TARGET_ARCH_ELF_H_ -+ -+#define ELF_START_MMAP 0x80000000 -+ -+#define elf_check_arch(x) ( (x) == EM_SPARC ) -+ -+#define ELF_CLASS ELFCLASS32 -+#define ELF_DATA ELFDATA2MSB -+#define ELF_ARCH EM_SPARC -+ -+#endif /* _TARGET_ARCH_ELF_H_ */ -diff --git a/bsd-user/sparc/target_arch_signal.h b/bsd-user/sparc/target_arch_signal.h -new file mode 100644 -index 0000000..f934f8c ---- /dev/null -+++ b/bsd-user/sparc/target_arch_signal.h -@@ -0,0 +1,77 @@ -+#ifndef TARGET_ARCH_SIGNAL_H -+#define TARGET_ARCH_SIGNAL_H -+ -+#include "cpu.h" -+ -+/* Size of the signal trampolin code placed on the stack. */ -+/* #define TARGET_SZSIGCODE (0) */ /* XXX to be added. */ -+ -+/* compare to sparc64/include/_limits.h */ -+#define TARGET_MINSIGSTKSZ (1024 * 4) /* min sig stack size */ -+#define TARGET_SIGSTKSZ (MINSIGSTKSZ + 32768) /* recommended size */ -+ -+#define TARGET_MC_GET_CLEAR_RET 0x0001 -+ -+struct target_sigcontext { -+ /* to be added */ -+}; -+ -+typedef struct target_mcontext { -+} target_mcontext_t; -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ abi_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __spare__[4]; -+} target_ucontext_t; -+ -+struct target_sigframe { -+ abi_ulong sf_signum; -+ abi_ulong sf_siginfo; /* code or pointer to sf_si */ -+ abi_ulong sf_ucontext; /* points to sf_uc */ -+ abi_ulong sf_addr; /* undocumented 4th arg */ -+ target_ucontext_t sf_uc; /* = *sf_uncontext */ -+ target_siginfo_t sf_si; /* = *sf_siginfo (SA_SIGINFO case)*/ -+ uint32_t __spare__[2]; -+}; -+ -+/* -+ * Compare to sparc64/sparc64/machdep.c sendsig() -+ * Assumes that target stack frame memory is locked. -+ */ -+static inline abi_long set_sigtramp_args(CPUSPARCState *regs, -+ int sig, struct target_sigframe *frame, abi_ulong frame_addr, -+ struct target_sigaction *ka) -+{ -+ /* XXX */ -+ return -TARGET_EOPNOTSUPP; -+} -+ -+/* Compare to sparc64/sparc64/machdep.c get_mcontext() */ -+static inline abi_long get_mcontext(CPUSPARCState *regs, -+ target_mcontext_t *mcp, int flags) -+{ -+ /* XXX */ -+ return -TARGET_EOPNOTSUPP; -+} -+ -+/* Compare to sparc64/space64/machdep.c set_mcontext() */ -+static inline abi_long set_mcontext(CPUSPARCState *regs, -+ target_mcontext_t *mcp, int srflag) -+{ -+ /* XXX */ -+ return -TARGET_EOPNOTSUPP; -+} -+ -+static inline abi_long get_ucontext_sigreturn(CPUSPARCState *regs, -+ abi_ulong target_sf, abi_ulong *target_uc) -+{ -+ /* XXX */ -+ *target_uc = 0; -+ return -TARGET_EOPNOTSUPP; -+} -+ -+#endif /* TARGET_ARCH_SIGNAL_H */ -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/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/sparc/target_arch_thread.h b/bsd-user/sparc/target_arch_thread.h -new file mode 100644 -index 0000000..fe607be ---- /dev/null -+++ b/bsd-user/sparc/target_arch_thread.h -@@ -0,0 +1,39 @@ -+/* -+ * sparc thread support -+ * -+ * 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 _TARGET_ARCH_THREAD_H_ -+#define _TARGET_ARCH_THREAD_H_ -+ -+/* Compare to vm_machdep.c cpu_set_upcall_kse() */ -+static inline void target_thread_set_upcall(CPUSPARCState *regs, -+ abi_ulong entry, abi_ulong arg, abi_ulong stack_base, abi_ulong stack_size) -+{ -+ /* XXX */ -+} -+ -+static inline void target_thread_init(struct target_pt_regs *regs, -+ struct image_info *infop) -+{ -+ regs->psr = 0; -+ regs->pc = infop->entry; -+ regs->npc = regs->pc + 4; -+ regs->y = 0; -+ regs->u_regs[14] = infop->start_stack - 16 * 4; -+} -+ -+#endif /* !_TARGET_ARCH_THREAD_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/syscall.h b/bsd-user/sparc64/syscall.h -index 81a816d..58cc38d 100644 ---- a/bsd-user/sparc64/syscall.h -+++ b/bsd-user/sparc64/syscall.h -@@ -1,3 +1,22 @@ -+/* -+ * sparc64 dependent system call definitions -+ * -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+#ifndef _SPARC64_SYSCALL_H_ -+#define _SPARC64_SYSCALL_H_ - struct target_pt_regs { - abi_ulong u_regs[16]; - abi_ulong tstate; -@@ -7,4 +26,11 @@ struct target_pt_regs { - abi_ulong fprs; - }; - --#define UNAME_MACHINE "sun4u" -+#define UNAME_MACHINE "sun4u" -+#define TARGET_HW_MACHINE "sparc" -+#define TARGET_HW_MACHINE_ARCH "sparc64" -+ -+#define TARGET_SPARC_UTRAP_INSTALL 1 -+#define TARGET_SPARC_SIGTRAMP_INSTALL 2 -+ -+#endif /* !_SPARC64_SYSCALL_H_ */ -diff --git a/bsd-user/sparc64/target_arch.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_elf.h b/bsd-user/sparc64/target_arch_elf.h -new file mode 100644 -index 0000000..f2b8e12 ---- /dev/null -+++ b/bsd-user/sparc64/target_arch_elf.h -@@ -0,0 +1,34 @@ -+/* -+ * sparc64 ELF 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 _TARGET_ARCH_ELF_H_ -+#define _TARGET_ARCH_ELF_H_ -+ -+#define ELF_START_MMAP 0x80000000 -+ -+#ifndef TARGET_ABI32 -+#define elf_check_arch(x) ( (x) == EM_SPARCV9 || (x) == EM_SPARC32PLUS ) -+#else -+#define elf_check_arch(x) ( (x) == EM_SPARC32PLUS || (x) == EM_SPARC ) -+#endif -+ -+#define ELF_CLASS ELFCLASS64 -+#define ELF_DATA ELFDATA2MSB -+#define ELF_ARCH EM_SPARCV9 -+ -+#endif /* _TARGET_ARCH_ELF_H_ */ -diff --git a/bsd-user/sparc64/target_arch_signal.h b/bsd-user/sparc64/target_arch_signal.h -new file mode 100644 -index 0000000..1529b0f ---- /dev/null -+++ b/bsd-user/sparc64/target_arch_signal.h -@@ -0,0 +1,94 @@ -+/* -+ * sparc64 dependent signal 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 _TARGET_ARCH_SIGNAL_H_ -+#define _TARGET_ARCH_SIGNAL_H_ -+ -+#include "cpu.h" -+ -+/* Size of the signal trampolin code placed on the stack. */ -+/* #define TARGET_SZSIGCODE (0) */ /* XXX to be added. */ -+ -+/* compare to sparc64/include/_limits.h */ -+#define TARGET_MINSIGSTKSZ (1024 * 4) /* min sig stack size */ -+#define TARGET_SIGSTKSZ (MINSIGSTKSZ + 32768) /* recommended size */ -+ -+#define TARGET_MC_GET_CLEAR_RET 0x0001 -+ -+struct target_sigcontext { -+ /* to be added */ -+}; -+ -+typedef struct target_mcontext { -+} target_mcontext_t; -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ abi_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __spare__[4]; -+} target_ucontext_t; -+ -+struct target_sigframe { -+ abi_ulong sf_signum; -+ abi_ulong sf_siginfo; /* code or pointer to sf_si */ -+ abi_ulong sf_ucontext; /* points to sf_uc */ -+ abi_ulong sf_addr; /* undocumented 4th arg */ -+ target_ucontext_t sf_uc; /* = *sf_uncontext */ -+ target_siginfo_t sf_si; /* = *sf_siginfo (SA_SIGINFO case)*/ -+ uint32_t __spare__[2]; -+}; -+ -+/* -+ * Compare to sparc64/sparc64/machdep.c sendsig() -+ * Assumes that target stack frame memory is locked. -+ */ -+static inline abi_long set_sigtramp_args(CPUSPARCState *regs, -+ int sig, struct target_sigframe *frame, abi_ulong frame_addr, -+ struct target_sigaction *ka) -+{ -+ /* XXX */ -+ return -TARGET_EOPNOTSUPP; -+} -+ -+/* Compare to sparc64/sparc64/machdep.c get_mcontext() */ -+static inline abi_long get_mcontext(CPUSPARCState *regs, -+ target_mcontext_t *mcp, int flags) -+{ -+ /* XXX */ -+ return -TARGET_EOPNOTSUPP; -+} -+ -+/* Compare to sparc64/space64/machdep.c set_mcontext() */ -+static inline abi_long set_mcontext(CPUSPARCState *regs, -+ target_mcontext_t *mcp, int srflag) -+{ -+ /* XXX */ -+ return -TARGET_EOPNOTSUPP; -+} -+ -+static inline abi_long get_ucontext_sigreturn(CPUSPARCState *regs, -+ abi_ulong target_sf, abi_ulong *target_uc) -+{ -+ /* XXX */ -+ *target_uc = 0; -+ return -TARGET_EOPNOTSUPP; -+} -+ -+#endif /* !_TARGET_ARCH_SIGNAL_H_ */ -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/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/sparc64/target_arch_thread.h b/bsd-user/sparc64/target_arch_thread.h -new file mode 100644 -index 0000000..2e5585a ---- /dev/null -+++ b/bsd-user/sparc64/target_arch_thread.h -@@ -0,0 +1,55 @@ -+/* -+ * sparc64 thread support -+ * -+ * 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 _TARGET_ARCH_THREAD_H_ -+#define _TARGET_ARCH_THREAD_H_ -+ -+#define STACK_BIAS 2047 -+ -+/* Compare to vm_machdep.c cpu_set_upcall_kse() */ -+static inline void target_thread_set_upcall(CPUSPARCState *regs, -+ abi_ulong entry, abi_ulong arg, abi_ulong stack_base, abi_ulong stack_size) -+{ -+ /* XXX */ -+} -+ -+static inline void target_thread_init(struct target_pt_regs *regs, -+ struct image_info *infop) -+{ -+#ifndef TARGET_ABI32 -+ regs->tstate = 0; -+#endif -+ regs->pc = infop->entry; -+ regs->npc = regs->pc + 4; -+ regs->y = 0; -+#ifdef TARGET_ABI32 -+ regs->u_regs[14] = infop->start_stack - 16 * 4; -+#else -+ if (personality(infop->personality) == PER_LINUX32) -+ regs->u_regs[14] = infop->start_stack - 16 * 4; -+ else { -+ regs->u_regs[14] = infop->start_stack - 16 * 8 - STACK_BIAS; -+ if (bsd_type == target_freebsd) { -+ regs->u_regs[8] = infop->start_stack; -+ regs->u_regs[11] = infop->start_stack; -+ } -+ } -+#endif -+} -+ -+#endif /* !_TARGET_ARCH_THREAD_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/strace.c b/bsd-user/strace.c -index d73bbca..60aabc3 100644 ---- a/bsd-user/strace.c -+++ b/bsd-user/strace.c -@@ -1,37 +1,73 @@ -+/* -+ * System call tracing and debugging -+ * -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+ - #include <stdio.h> - #include <errno.h> - #include <sys/select.h> - #include <sys/types.h> - #include <unistd.h> - #include <sys/syscall.h> -+#include <sys/ioccom.h> -+#include <ctype.h> -+ - #include "qemu.h" - --int do_strace=0; -+#include "os-strace.h" /* OS dependent strace print functions */ - --struct syscallname { -- int nr; -- const char *name; -- const char *format; -- void (*call)(const struct syscallname *, -- abi_long, abi_long, abi_long, -- abi_long, abi_long, abi_long); -- void (*result)(const struct syscallname *, abi_long); --}; -+int do_strace; - - /* - * Utility functions - */ - --static void --print_execve(const struct syscallname *name, -- abi_long arg1, abi_long arg2, abi_long arg3, -- abi_long arg4, abi_long arg5, abi_long arg6) -+static void print_sysctl(const struct syscallname *name, abi_long arg1, -+ abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, -+ abi_long arg6) -+{ -+ uint32_t i; -+ int32_t *namep; -+ -+ gemu_log("%s({ ", name->name); -+ namep = lock_user(VERIFY_READ, arg1, sizeof(int32_t) * arg2, 1); -+ if (namep) { -+ int32_t *p = namep; -+ -+ for (i = 0; i < (uint32_t)arg2; i++) { -+ gemu_log("%d ", tswap32(*p++)); -+ } -+ unlock_user(namep, arg1, 0); -+ } -+ gemu_log("}, %u, 0x" TARGET_ABI_FMT_lx ", 0x" TARGET_ABI_FMT_lx ", 0x" -+ TARGET_ABI_FMT_lx ", 0x" TARGET_ABI_FMT_lx ")", -+ (uint32_t)arg2, arg3, arg4, arg5, arg6); -+} -+ -+static void print_execve(const struct syscallname *name, abi_long arg1, -+ abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, -+ abi_long arg6) - { - abi_ulong arg_ptr_addr; - char *s; - -- if (!(s = lock_user_string(arg1))) -+ s = lock_user_string(arg1); -+ if (s == NULL) { - return; -+ } - gemu_log("%s(\"%s\",{", name->name, s); - unlock_user(s, arg1, 0); - -@@ -39,29 +75,56 @@ print_execve(const struct syscallname *name, - abi_ulong *arg_ptr, arg_addr; - - arg_ptr = lock_user(VERIFY_READ, arg_ptr_addr, sizeof(abi_ulong), 1); -- if (!arg_ptr) -+ if (!arg_ptr) { - return; -+ } - arg_addr = tswapl(*arg_ptr); - unlock_user(arg_ptr, arg_ptr_addr, 0); -- if (!arg_addr) -+ if (!arg_addr) { - break; -+ } - if ((s = lock_user_string(arg_addr))) { - gemu_log("\"%s\",", s); - unlock_user(s, arg_addr, 0); - } - } -- - gemu_log("NULL})"); - } - -+static void print_ioctl(const struct syscallname *name, -+ abi_long arg1, abi_long arg2, abi_long arg3, abi_long arg4, -+ abi_long arg5, abi_long arg6) -+{ -+ /* Decode the ioctl request */ -+ gemu_log("%s(%d, 0x%0lx { IO%s%s GRP:0x%x('%c') CMD:%d LEN:%d }, 0x" -+ TARGET_ABI_FMT_lx ", ...)", -+ name->name, -+ (int)arg1, -+ (unsigned long)arg2, -+ arg2 & IOC_OUT ? "R" : "", -+ arg2 & IOC_IN ? "W" : "", -+ (unsigned)IOCGROUP(arg2), -+ isprint(IOCGROUP(arg2)) ? (char)IOCGROUP(arg2) : '?', -+ (int)arg2 & 0xFF, -+ (int)IOCPARM_LEN(arg2), -+ arg3); -+} -+ -+static void print_sysarch(const struct syscallname *name, abi_long arg1, -+ abi_long arg2, abi_long arg3, abi_long arg4, abi_long arg5, -+ abi_long arg6) -+{ -+ /* This is os dependent. */ -+ do_os_print_sysarch(name, arg1, arg2, arg3, arg4, arg5, arg6); -+} -+ - /* - * Variants for the return value output function - */ - --static void --print_syscall_ret_addr(const struct syscallname *name, abi_long ret) -+static void print_syscall_ret_addr(const struct syscallname *name, abi_long ret) - { --if( ret == -1 ) { -+ if (ret == -1) { - gemu_log(" = -1 errno=%d (%s)\n", errno, strerror(errno)); - } else { - gemu_log(" = 0x" TARGET_ABI_FMT_lx "\n", ret); -@@ -90,10 +153,9 @@ static const struct syscallname openbsd_scnames[] = { - #include "openbsd/strace.list" - }; - --static void --print_syscall(int num, const struct syscallname *scnames, unsigned int nscnames, -- abi_long arg1, abi_long arg2, abi_long arg3, -- abi_long arg4, abi_long arg5, abi_long arg6) -+static void print_syscall(int num, const struct syscallname *scnames, -+ unsigned int nscnames, abi_long arg1, abi_long arg2, abi_long arg3, -+ abi_long arg4, abi_long arg5, abi_long arg6) - { - unsigned int i; - const char *format="%s(" TARGET_ABI_FMT_ld "," TARGET_ABI_FMT_ld "," -@@ -102,36 +164,37 @@ print_syscall(int num, const struct syscallname *scnames, unsigned int nscnames, - - gemu_log("%d ", getpid() ); - -- for (i = 0; i < nscnames; i++) -+ for (i = 0; i < nscnames; i++) { - if (scnames[i].nr == num) { - if (scnames[i].call != NULL) { - scnames[i].call(&scnames[i], arg1, arg2, arg3, arg4, arg5, -- arg6); -+ arg6); - } else { - /* XXX: this format system is broken because it uses - host types and host pointers for strings */ -- if (scnames[i].format != NULL) -+ if (scnames[i].format != NULL) { - format = scnames[i].format; -- gemu_log(format, scnames[i].name, arg1, arg2, arg3, arg4, -- arg5, arg6); -+ } -+ gemu_log(format, scnames[i].name, arg1, arg2, arg3, arg4, arg5, -+ arg6); - } - return; - } -+ } - gemu_log("Unknown syscall %d\n", num); - } - --static void --print_syscall_ret(int num, abi_long ret, const struct syscallname *scnames, -- unsigned int nscnames) -+static void print_syscall_ret(int num, abi_long ret, -+ const struct syscallname *scnames, unsigned int nscnames) - { - unsigned int i; - -- for (i = 0; i < nscnames; i++) -+ for (i = 0; i < nscnames; i++) { - if (scnames[i].nr == num) { - if (scnames[i].result != NULL) { - scnames[i].result(&scnames[i], ret); - } else { -- if( ret < 0 ) { -+ if (ret < 0) { - gemu_log(" = -1 errno=" TARGET_ABI_FMT_ld " (%s)\n", -ret, - strerror(-ret)); - } else { -@@ -140,52 +203,50 @@ print_syscall_ret(int num, abi_long ret, const struct syscallname *scnames, - } - break; - } -+ } - } - - /* - * The public interface to this module. - */ --void --print_freebsd_syscall(int num, -- abi_long arg1, abi_long arg2, abi_long arg3, -- abi_long arg4, abi_long arg5, abi_long arg6) -+void print_freebsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3, -+ abi_long arg4, abi_long arg5, abi_long arg6) - { -- print_syscall(num, freebsd_scnames, ARRAY_SIZE(freebsd_scnames), -- arg1, arg2, arg3, arg4, arg5, arg6); -+ -+ print_syscall(num, freebsd_scnames, ARRAY_SIZE(freebsd_scnames), arg1, arg2, -+ arg3, arg4, arg5, arg6); - } - --void --print_freebsd_syscall_ret(int num, abi_long ret) -+void print_freebsd_syscall_ret(int num, abi_long ret) - { -+ - print_syscall_ret(num, ret, freebsd_scnames, ARRAY_SIZE(freebsd_scnames)); - } - --void --print_netbsd_syscall(int num, -- abi_long arg1, abi_long arg2, abi_long arg3, -- abi_long arg4, abi_long arg5, abi_long arg6) -+void print_netbsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3, -+ abi_long arg4, abi_long arg5, abi_long arg6) - { -+ - print_syscall(num, netbsd_scnames, ARRAY_SIZE(netbsd_scnames), - arg1, arg2, arg3, arg4, arg5, arg6); - } - --void --print_netbsd_syscall_ret(int num, abi_long ret) -+void print_netbsd_syscall_ret(int num, abi_long ret) - { -+ - print_syscall_ret(num, ret, netbsd_scnames, ARRAY_SIZE(netbsd_scnames)); - } - --void --print_openbsd_syscall(int num, -- abi_long arg1, abi_long arg2, abi_long arg3, -- abi_long arg4, abi_long arg5, abi_long arg6) -+void print_openbsd_syscall(int num, abi_long arg1, abi_long arg2, abi_long arg3, -+ abi_long arg4, abi_long arg5, abi_long arg6) - { -- print_syscall(num, openbsd_scnames, ARRAY_SIZE(openbsd_scnames), -- arg1, arg2, arg3, arg4, arg5, arg6); -+ -+ print_syscall(num, openbsd_scnames, ARRAY_SIZE(openbsd_scnames), arg1, arg2, -+ arg3, arg4, arg5, arg6); - } - --void --print_openbsd_syscall_ret(int num, abi_long ret) -+void print_openbsd_syscall_ret(int num, abi_long ret) - { -+ - print_syscall_ret(num, ret, openbsd_scnames, ARRAY_SIZE(openbsd_scnames)); - } -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index a4d1583..35bf394 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 -@@ -16,403 +17,1538 @@ - * 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 <stdlib.h> - #include <stdio.h> - #include <stdint.h> - #include <stdarg.h> - #include <string.h> - #include <errno.h> --#include <unistd.h> --#include <fcntl.h> - #include <time.h> --#include <limits.h> - #include <sys/types.h> --#include <sys/mman.h> - #include <sys/syscall.h> - #include <sys/param.h> - #include <sys/sysctl.h> --#include <utime.h> - - #include "qemu.h" - #include "qemu-common.h" - --//#define DEBUG -+#define target_to_host_bitmask(x, tbl) (x) -+ -+/* BSD independent syscall shims */ -+#include "bsd-file.h" -+#include "bsd-ioctl.h" -+#include "bsd-mem.h" -+#include "bsd-misc.h" -+#include "bsd-proc.h" -+#include "bsd-signal.h" -+#include "bsd-socket.h" -+ -+/* *BSD dependent syscall shims */ -+#include "os-extattr.h" -+#include "os-time.h" -+#include "os-misc.h" -+#include "os-proc.h" -+#include "os-signal.h" -+#include "os-socket.h" -+#include "os-stat.h" -+#include "os-thread.h" -+ -+/* #define DEBUG */ -+ -+/* -+ * errno conversion. -+ */ -+abi_long get_errno(abi_long ret) -+{ -+ -+ if (ret == -1) { -+ /* XXX need to translate host -> target errnos here */ -+ return -(errno); -+ } else { -+ return ret; -+ } -+} -+ -+int host_to_target_errno(int err) -+{ -+ /* XXX need to translate host errnos here */ -+ return err; -+} -+ -+int is_error(abi_long ret) -+{ -+ -+ return (abi_ulong)ret >= (abi_ulong)(-4096); -+} -+ -+/* 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. -+ */ -+static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr, -+ int count, int copy) -+{ -+ struct target_iovec *target_vec; -+ abi_ulong base; -+ int i; -+ -+ target_vec = lock_user(VERIFY_READ, target_addr, -+ count * sizeof(struct target_iovec), 1); -+ if (!target_vec) { -+ return -TARGET_EFAULT; -+ } -+ for (i = 0; i < count; i++) { -+ base = tswapl(target_vec[i].iov_base); -+ vec[i].iov_len = tswapl(target_vec[i].iov_len); -+ if (vec[i].iov_len != 0) { -+ vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); -+ /* Don't check lock_user return value. We must call writev even -+ if a element has invalid base address. */ -+ } else { -+ /* zero length pointer is ignored */ -+ vec[i].iov_base = NULL; -+ } -+ } -+ unlock_user (target_vec, target_addr, 0); -+ return 0; -+} -+ -+static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr, -+ int count, int copy) -+{ -+ struct target_iovec *target_vec; -+ abi_ulong base; -+ int i; -+ -+ target_vec = lock_user(VERIFY_READ, target_addr, -+ count * sizeof(struct target_iovec), 1); -+ if (!target_vec) -+ return -TARGET_EFAULT; -+ for (i = 0; i < count; i++) { -+ if (target_vec[i].iov_base) { -+ base = tswapl(target_vec[i].iov_base); -+ unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); -+ } -+ } -+ unlock_user (target_vec, target_addr, 0); -+ -+ return 0; -+} -+ -+ -+/* stub for arm semihosting support */ -+abi_long do_brk(abi_ulong new_brk) -+{ -+ return do_obreak(new_brk); -+} -+ -+/* do_syscall() should always have a single exit point at the end so -+ that actions, such as logging of syscall results, can be performed. -+ All errnos that do_syscall() returns must be -TARGET_<errcode>. */ -+abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, -+ abi_long arg2, abi_long arg3, abi_long arg4, -+ abi_long arg5, abi_long arg6, abi_long arg7, -+ abi_long arg8) -+{ -+ abi_long ret; -+ -+#ifdef DEBUG -+ gemu_log("freebsd syscall %d\n", num); -+#endif -+ if(do_strace) -+ print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); -+ -+ switch(num) { -+ /* -+ * process system calls -+ */ -+ case TARGET_FREEBSD_NR_fork: /* fork(2) */ -+ ret = do_freebsd_fork(cpu_env); -+ break; -+ -+ case TARGET_FREEBSD_NR_vfork: /* vfork(2) */ -+ ret = do_freebsd_vfork(cpu_env); -+ break; -+ -+ case TARGET_FREEBSD_NR_rfork: /* rfork(2) */ -+ ret = do_freebsd_rfork(cpu_env, arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_pdfork: /* pdfork(2) */ -+ ret = do_freebsd_pdfork(cpu_env, arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_execve: /* execve(2) */ -+ ret = do_freebsd_execve(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_fexecve: /* fexecve(2) */ -+ ret = do_freebsd_fexecve(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_wait4: /* wait4(2) */ -+ ret = do_freebsd_wait4(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_exit: /* exit(2) */ -+ ret = do_bsd_exit(cpu_env, arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_getgroups: /* getgroups(2) */ -+ ret = do_bsd_getgroups(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_setgroups: /* setgroups(2) */ -+ ret = do_bsd_setgroups(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_umask: /* umask(2) */ -+ ret = do_bsd_umask(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_setlogin: /* setlogin(2) */ -+ ret = do_bsd_setlogin(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_getlogin: /* getlogin(2) */ -+ ret = do_bsd_getlogin(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_getrusage: /* getrusage(2) */ -+ ret = do_bsd_getrusage(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_getrlimit: /* getrlimit(2) */ -+ ret = do_bsd_getrlimit(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_setrlimit: /* setrlimit(2) */ -+ ret = do_bsd_setrlimit(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_getpid: /* getpid(2) */ -+ ret = do_bsd_getpid(); -+ break; -+ -+ case TARGET_FREEBSD_NR_getppid: /* getppid(2) */ -+ ret = do_bsd_getppid(); -+ break; -+ -+ case TARGET_FREEBSD_NR_getuid: /* getuid(2) */ -+ ret = do_bsd_getuid(); -+ break; -+ -+ case TARGET_FREEBSD_NR_geteuid: /* geteuid(2) */ -+ ret = do_bsd_geteuid(); -+ break; -+ -+ case TARGET_FREEBSD_NR_getgid: /* getgid(2) */ -+ ret = do_bsd_getgid(); -+ break; -+ -+ case TARGET_FREEBSD_NR_getegid: /* getegid(2) */ -+ ret = do_bsd_getegid(); -+ break; -+ -+ case TARGET_FREEBSD_NR_setuid: /* setuid(2) */ -+ ret = do_bsd_setuid(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_seteuid: /* seteuid(2) */ -+ ret = do_bsd_seteuid(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_setgid: /* setgid(2) */ -+ ret = do_bsd_setgid(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_setegid: /* setegid(2) */ -+ ret = do_bsd_setegid(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_getpgrp: /* getpgrp(2) */ -+ ret = do_bsd_getpgrp(); -+ break; -+ -+ case TARGET_FREEBSD_NR_setreuid: /* setreuid(2) */ -+ ret = do_bsd_setreuid(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_setregid: /* setregid(2) */ -+ ret = do_bsd_setregid(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_getresuid: /* getresuid(2) */ -+ ret = do_bsd_getresuid(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_getresgid: /* getresgid(2) */ -+ ret = do_bsd_getresgid(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_getsid: /* getsid(2) */ -+ ret = do_bsd_getsid(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_setsid: /* setsid(2) */ -+ ret = do_bsd_setsid(); -+ break; -+ -+ case TARGET_FREEBSD_NR_issetugid: /* issetugid(2) */ -+ ret = do_bsd_issetugid(); -+ break; -+ -+ case TARGET_FREEBSD_NR_profil: /* profil(2) */ -+ ret = do_bsd_profil(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_ktrace: /* ktrace(2) */ -+ ret = do_bsd_ktrace(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_setloginclass: /* setloginclass(2) */ -+ ret = do_freebsd_setloginclass(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_getloginclass: /* getloginclass(2) */ -+ ret = do_freebsd_getloginclass(arg1, arg2); -+ break; -+ -+#if 0 -+ case TARGET_FREEBSD_NR_pdwait4: /* pdwait4(2) */ -+ ret = do_freebsd_pdwait4(arg1, arg2, arg3, arg4); -+ break; -+#endif -+ -+ case TARGET_FREEBSD_NR_pdgetpid: /* pdgetpid(2) */ -+ ret = do_freebsd_pdgetpid(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR___setugid: /* undocumented */ -+ ret = do_freebsd___setugid(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_jail: /* jail(2) */ -+ ret = do_freebsd_jail(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_jail_attach: /* jail_attach(2) */ -+ ret = do_freebsd_jail_attach(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_jail_remove: /* jail_remove(2) */ -+ ret = do_freebsd_jail_remove(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_jail_get: /* jail_get(2) */ -+ ret = do_freebsd_jail_get(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_jail_set: /* jail_set(2) */ -+ ret = do_freebsd_jail_set(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_cap_enter: /* cap_enter(2) */ -+ ret = do_freebsd_cap_enter(); -+ break; -+ -+ case TARGET_FREEBSD_NR_cap_new: /* cap_new(2) */ -+ ret = do_freebsd_cap_new(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_cap_getrights: /* cap_getrights(2) */ -+ ret = do_freebsd_cap_getrights(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_cap_getmode: /* cap_getmode(2) */ -+ ret = do_freebsd_cap_getmode(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_audit: /* audit(2) */ -+ ret = do_freebsd_audit(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_auditon: /* auditon(2) */ -+ ret = do_freebsd_auditon(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_getaudit: /* getaudit(2) */ -+ ret = do_freebsd_getaudit(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_setaudit: /* setaudit(2) */ -+ ret = do_freebsd_setaudit(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_getaudit_addr: /* getaudit_addr(2) */ -+ ret = do_freebsd_getaudit_addr(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_setaudit_addr: /* setaudit_addr(2) */ -+ ret = do_freebsd_setaudit_addr(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_auditctl: /* auditctl(2) */ -+ ret = do_freebsd_auditctl(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_utrace: /* utrace(2) */ -+ ret = do_bsd_utrace(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_ptrace: /* ptrace(2) */ -+ ret = do_bsd_ptrace(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_getpriority: /* getpriority(2) */ -+ ret = do_bsd_getpriority(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_setpriority: /* setpriority(2) */ -+ ret = do_bsd_setpriority(arg1, arg2, arg3); -+ break; -+ -+ -+ -+ /* -+ * File system calls. -+ */ -+ case TARGET_FREEBSD_NR_read: /* read(2) */ -+ ret = do_bsd_read(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_pread: /* pread(2) */ -+ ret = do_bsd_pread(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6); -+ break; -+ -+ case TARGET_FREEBSD_NR_readv: /* readv(2) */ -+ ret = do_bsd_read(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_write: /* write(2) */ -+ ret = do_bsd_write(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_pwrite: /* pwrite(2) */ -+ ret = do_bsd_pwrite(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6); -+ break; -+ -+ case TARGET_FREEBSD_NR_writev: /* writev(2) */ -+ ret = do_bsd_writev(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_pwritev: /* pwritev(2) */ -+ ret = do_bsd_pwritev(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6); -+ break; -+ -+ case TARGET_FREEBSD_NR_open: /* open(2) */ -+ ret = do_bsd_open(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_openat: /* openat(2) */ -+ ret = do_bsd_openat(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_close: /* close(2) */ -+ ret = do_bsd_close(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_closefrom: /* closefrom(2) */ -+ ret = do_bsd_closefrom(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_revoke: /* revoke(2) */ -+ ret = do_bsd_revoke(arg1); -+ break; -+ -+#ifdef TARGET_FREEBSD_NR_creat -+ case TARGET_FREEBSD_NR_creat: /* creat(2) (obsolete) */ -+ ret = do_bsd_creat(arg1); -+ break; -+#endif -+ -+ case TARGET_FREEBSD_NR_access: /* access(2) */ -+ ret = do_bsd_access(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_eaccess: /* eaccess(2) */ -+ ret = do_bsd_eaccess(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_faccessat: /* faccessat(2) */ -+ ret = do_bsd_faccessat(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_chdir: /* chdir(2) */ -+ ret = do_bsd_chdir(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_fchdir: /* fchdir(2) */ -+ ret = do_bsd_fchdir(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_rename: /* rename(2) */ -+ ret = do_bsd_rename(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_renameat: /* renameat(2) */ -+ ret = do_bsd_renameat(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_link: /* link(2) */ -+ ret = do_bsd_link(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_linkat: /* linkat(2) */ -+ ret = do_bsd_linkat(arg1, arg2, arg3, arg4, arg5); -+ break; -+ -+ case TARGET_FREEBSD_NR_unlink: /* unlink(2) */ -+ ret = do_bsd_unlink(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_unlinkat: /* unlinkat(2) */ -+ ret = do_bsd_unlinkat(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_mkdir: /* mkdir(2) */ -+ ret = do_bsd_mkdir(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_mkdirat: /* mkdirat(2) */ -+ ret = do_bsd_mkdirat(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_rmdir: /* rmdir(2) (XXX no rmdirat()?) */ -+ ret = do_bsd_rmdir(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR___getcwd: /* undocumented __getcwd() */ -+ ret = do_bsd___getcwd(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_dup: /* dup(2) */ -+ ret = do_bsd_dup(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_dup2: /* dup2(2) */ -+ ret = do_bsd_dup2(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_truncate: /* truncate(2) */ -+ ret = do_bsd_truncate(cpu_env, arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_ftruncate: /* ftruncate(2) */ -+ ret = do_bsd_ftruncate(cpu_env, arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_acct: /* acct(2) */ -+ ret = do_bsd_acct(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_sync: /* sync(2) */ -+ ret = do_bsd_sync(); -+ break; -+ -+ case TARGET_FREEBSD_NR_mount: /* mount(2) */ -+ ret = do_bsd_mount(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_unmount: /* unmount(2) */ -+ ret = do_bsd_unmount(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_nmount: /* nmount(2) */ -+ ret = do_bsd_nmount(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_symlink: /* symlink(2) */ -+ ret = do_bsd_symlink(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_symlinkat: /* symlinkat(2) */ -+ ret = do_bsd_symlinkat(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_readlink: /* readlink(2) */ -+ ret = do_bsd_readlink(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_readlinkat: /* readlinkat(2) */ -+ ret = do_bsd_readlinkat(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_chmod: /* chmod(2) */ -+ ret = do_bsd_chmod(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_fchmod: /* fchmod(2) */ -+ ret = do_bsd_fchmod(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_lchmod: /* lchmod(2) */ -+ ret = do_bsd_lchmod(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_fchmodat: /* fchmodat(2) */ -+ ret = do_bsd_fchmodat(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_mknod: /* mknod(2) */ -+ ret = do_bsd_mknod(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_mknodat: /* mknodat(2) */ -+ ret = do_bsd_mknodat(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_chown: /* chown(2) */ -+ ret = do_bsd_chown(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_fchown: /* fchown(2) */ -+ ret = do_bsd_fchown(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_lchown: /* lchown(2) */ -+ ret = do_bsd_lchown(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_fchownat: /* fchownat(2) */ -+ ret = do_bsd_fchownat(arg1, arg2, arg3, arg4, arg5); -+ break; -+ -+ case TARGET_FREEBSD_NR_chflags: /* chflags(2) */ -+ ret = do_bsd_chflags(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_lchflags: /* lchflags(2) */ -+ ret = do_bsd_lchflags(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_fchflags: /* fchflags(2) */ -+ ret = do_bsd_fchflags(arg2, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_chroot: /* chroot(2) */ -+ ret = do_bsd_chroot(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_flock: /* flock(2) */ -+ ret = do_bsd_flock(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_mkfifo: /* mkfifo(2) */ -+ ret = do_bsd_mkfifo(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_mkfifoat: /* mkfifoat(2) */ -+ ret = do_bsd_mkfifoat(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_pathconf: /* pathconf(2) */ -+ ret = do_bsd_pathconf(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_lpathconf: /* lpathconf(2) */ -+ ret = do_bsd_lpathconf(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_fpathconf: /* fpathconf(2) */ -+ ret = do_bsd_fpathconf(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_undelete: /* undelete(2) */ -+ ret = do_bsd_undelete(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_poll: /* poll(2) */ -+ ret = do_bsd_poll(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_openbsd_poll: /* undocumented openbsd_poll() */ -+ ret = do_bsd_openbsd_poll(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_lseek: /* lseek(2) */ -+ ret = do_bsd_lseek(cpu_env, arg1, arg2, arg3, arg4, arg5); -+ break; -+ -+ case TARGET_FREEBSD_NR_pipe: /* pipe(2) */ -+ ret = do_bsd_pipe(cpu_env, arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_swapon: /* swapon(2) */ -+ ret = do_bsd_swapon(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_swapoff: /* swapoff(2) */ -+ ret = do_bsd_swapoff(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_freebsd6_pread: /* undocumented freebsd6_pread() */ -+ ret = do_bsd_freebsd6_pread(arg1, arg2, arg3, arg4, arg5); -+ break; -+ -+ case TARGET_FREEBSD_NR_freebsd6_pwrite: /* undocumented freebsd6_pwrite() */ -+ ret = do_bsd_freebsd6_pwrite(arg1, arg2, arg3, arg4, arg5); -+ break; -+ -+ case TARGET_FREEBSD_NR_freebsd6_lseek: /* undocumented freebsd6_lseek() */ -+ ret = do_bsd_freebsd6_lseek(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_freebsd6_truncate: /* undocumented */ -+ ret = do_bsd_freebsd6_truncate(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_freebsd6_ftruncate: /* undocumented */ -+ ret = do_bsd_freebsd6_ftruncate(arg1, arg2, arg3); -+ break; -+ -+ /* -+ * stat system calls -+ */ -+ case TARGET_FREEBSD_NR_stat: /* stat(2) */ -+ ret = do_freebsd_stat(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_lstat: /* lstat(2) */ -+ ret = do_freebsd_lstat(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_fstat: /* fstat(2) */ -+ ret = do_freebsd_fstat(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_fstatat: /* fstatat(2) */ -+ ret = do_freebsd_fstatat(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_nstat: /* undocumented */ -+ ret = do_freebsd_nstat(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_nfstat: /* undocumented */ -+ ret = do_freebsd_nfstat(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_nlstat: /* undocumented */ -+ ret = do_freebsd_nlstat(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_getfh: /* getfh(2) */ -+ ret = do_freebsd_getfh(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_lgetfh: /* lgetfh(2) */ -+ ret = do_freebsd_lgetfh(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_fhopen: /* fhopen(2) */ -+ ret = do_freebsd_fhopen(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_fhstat: /* fhstat(2) */ -+ ret = do_freebsd_fhstat(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_fhstatfs: /* fhstatfs(2) */ -+ ret = do_freebsd_fhstatfs(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_statfs: /* statfs(2) */ -+ ret = do_freebsd_statfs(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_fstatfs: /* fstatfs(2) */ -+ ret = do_freebsd_fstatfs(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_getfsstat: /* getfsstat(2) */ -+ ret = do_freebsd_getfsstat(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_getdents: /* getdents(2) */ -+ ret = do_freebsd_getdents(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_getdirentries: /* getdirentries(2) */ -+ ret = do_freebsd_getdirentries(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_fcntl: /* fcntl(2) */ -+ ret = do_freebsd_fcntl(arg1, arg2, arg3); -+ break; -+ -+ -+ /* -+ * Memory management system calls. -+ */ -+ case TARGET_FREEBSD_NR_mmap: /* mmap(2) */ -+ ret = do_bsd_mmap(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6, arg7, -+ arg8); -+ break; -+ -+ case TARGET_FREEBSD_NR_munmap: /* munmap(2) */ -+ ret = do_bsd_munmap(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_mprotect: /* mprotect(2) */ -+ ret = do_bsd_mprotect(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_msync: /* msync(2) */ -+ ret = do_bsd_msync(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_mlock: /* mlock(2) */ -+ ret = do_bsd_mlock(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_munlock: /* munlock(2) */ -+ ret = do_bsd_munlock(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_mlockall: /* mlockall(2) */ -+ ret = do_bsd_mlockall(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_munlockall: /* munlockall(2) */ -+ ret = do_bsd_munlockall(); -+ break; -+ -+ case TARGET_FREEBSD_NR_madvise: /* madvise(2) */ -+ ret = do_bsd_madvise(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_minherit: /* minherit(2) */ -+ ret = do_bsd_minherit(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_mincore: /* mincore(2) */ -+ ret = do_bsd_mincore(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_shm_open: /* shm_open(2) */ -+ ret = do_bsd_shm_open(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_shm_unlink: /* shm_unlink(2) */ -+ ret = do_bsd_shm_unlink(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_shmget: /* shmget(2) */ -+ ret = do_bsd_shmget(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_shmctl: /* shmctl(2) */ -+ ret = do_bsd_shmctl(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_shmat: /* shmat(2) */ -+ ret = do_bsd_shmat(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_shmdt: /* shmdt(2) */ -+ ret = do_bsd_shmdt(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_vadvise: -+ ret = do_bsd_vadvise(); -+ break; -+ -+ case TARGET_FREEBSD_NR_sbrk: -+ ret = do_bsd_sbrk(); -+ break; -+ -+ case TARGET_FREEBSD_NR_sstk: -+ ret = do_bsd_sstk(); -+ break; -+ -+ case TARGET_FREEBSD_NR_freebsd6_mmap: /* undocumented */ -+ ret = do_bsd_freebsd6_mmap(arg1, arg2, arg3, arg4, arg5, arg6, arg7); -+ break; -+ -+ -+ /* -+ * time related system calls. -+ */ -+ case TARGET_FREEBSD_NR_nanosleep: /* nanosleep(2) */ -+ ret = do_freebsd_nanosleep(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_clock_gettime: /* clock_gettime(2) */ -+ ret = do_freebsd_clock_gettime(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_clock_settime: /* clock_settime(2) */ -+ ret = do_freebsd_clock_settime(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_clock_getres: /* clock_getres(2) */ -+ ret = do_freebsd_clock_getres(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_gettimeofday: /* gettimeofday(2) */ -+ ret = do_freebsd_gettimeofday(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_settimeofday: /* settimeofday(2) */ -+ ret = do_freebsd_settimeofday(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_adjtime: /* adjtime(2) */ -+ ret = do_freebsd_adjtime(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_ntp_adjtime: /* ntp_adjtime(2) */ -+ ret = do_freebsd_ntp_adjtime(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_ntp_gettime: /* ntp_gettime(2) */ -+ ret = do_freebsd_ntp_gettime(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_utimes: /* utimes(2) */ -+ ret = do_freebsd_utimes(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_lutimes: /* lutimes(2) */ -+ ret = do_freebsd_lutimes(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_futimes: /* futimes(2) */ -+ ret = do_freebsd_futimes(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_futimesat: /* futimesat(2) */ -+ ret = do_freebsd_futimesat(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_ktimer_create: /* undocumented */ -+ ret = do_freebsd_ktimer_create(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_ktimer_delete: /* undocumented */ -+ ret = do_freebsd_ktimer_delete(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_ktimer_settime: /* undocumented */ -+ ret = do_freebsd_ktimer_settime(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_ktimer_gettime: /* undocumented */ -+ ret = do_freebsd_ktimer_gettime(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_ktimer_getoverrun: /* undocumented */ -+ ret = do_freebsd_ktimer_getoverrun(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_select: /* select(2) */ -+ ret = do_freebsd_select(arg1, arg2, arg3, arg4, arg5); -+ break; -+ -+ case TARGET_FREEBSD_NR_pselect: /* pselect(2) */ -+ ret = do_freebsd_pselect(arg1, arg2, arg3, arg4, arg5, arg6); -+ break; -+ -+ case TARGET_FREEBSD_NR_kqueue: /* kqueue(2) */ -+ ret = do_freebsd_kqueue(); -+ break; -+ -+ case TARGET_FREEBSD_NR_kevent: /* kevent(2) */ -+ ret = do_freebsd_kevent(arg1, arg2, arg3, arg4, arg5, arg6); -+ break; -+ -+ case TARGET_FREEBSD_NR_setitimer: /* setitimer(2) */ -+ ret = do_freebsd_setitimer(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_getitimer: /* getitimer(2) */ -+ ret = do_freebsd_getitimer(arg1, arg2); -+ break; -+ -+ /* -+ * signal system calls -+ */ -+ case TARGET_FREEBSD_NR_sigtimedwait: /* sigtimedwait(2) */ -+ ret = do_freebsd_sigtimedwait(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_sigaction: /* sigaction(2) */ -+ ret = do_bsd_sigaction(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_sigprocmask: /* sigprocmask(2) */ -+ ret = do_bsd_sigprocmask(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_sigpending: /* sigpending(2) */ -+ ret = do_bsd_sigpending(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_sigsuspend: /* sigsuspend(2) */ -+ ret = do_bsd_sigsuspend(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_sigreturn: /* sigreturn(2) */ -+ ret = do_bsd_sigreturn(cpu_env, arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_sigwait: /* sigwait(2) */ -+ ret = do_bsd_sigwait(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_sigwaitinfo: /* sigwaitinfo(2) */ -+ ret = do_bsd_sigwaitinfo(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_sigqueue: /* sigqueue(2) */ -+ ret = do_bsd_sigqueue(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_sigaltstack: /* sigaltstack(2) */ -+ ret = do_bsd_sigaltstack(cpu_env, arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_kill: /* kill(2) */ -+ ret = do_bsd_kill(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_killpg: /* killpg(2) */ -+ ret = do_bsd_killpg(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_pdkill: /* pdkill(2) */ -+ ret = do_freebsd_pdkill(arg1, arg2); -+ break; -+ -+ /* -+ * socket related system calls -+ */ -+ case TARGET_FREEBSD_NR_accept: /* accept(2) */ -+ ret = do_bsd_accept(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_bind: /* bind(2) */ -+ ret = do_bsd_bind(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_connect: /* connect(2) */ -+ ret = do_bsd_connect(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_getpeername: /* getpeername(2) */ -+ ret = do_bsd_getpeername(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_getsockname: /* getsockname(2) */ -+ ret = do_bsd_getsockname(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_getsockopt: /* getsockopt(2) */ -+ ret = do_bsd_getsockopt(arg1, arg2, arg3, arg4, arg5); -+ break; -+ -+ case TARGET_FREEBSD_NR_setsockopt: /* setsockopt(2) */ -+ ret = do_bsd_setsockopt(arg1, arg2, arg3, arg4, arg5); -+ break; -+ -+ case TARGET_FREEBSD_NR_listen: /* listen(2) */ -+ ret = get_errno(listen(arg1, arg2)); -+ break; -+ -+ case TARGET_FREEBSD_NR_recvfrom: /* recvfrom(2) */ -+ ret = do_bsd_recvfrom(arg1, arg2, arg3, arg4, arg5, arg6); -+ break; -+ -+ case TARGET_FREEBSD_NR_recvmsg: /* recvmsg(2) */ -+ ret = do_freebsd_recvmsg(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_sendmsg: /* sendmsg(2) */ -+ ret = do_freebsd_sendmsg(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_sendto: /* sendto(2) */ -+ ret = do_bsd_sendto(arg1, arg2, arg3, arg4, arg5, arg6); -+ break; -+ -+ case TARGET_FREEBSD_NR_socket: /* socket(2) */ -+ ret = do_bsd_socket(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_socketpair: /* socketpair(2) */ -+ ret = do_bsd_socketpair(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_shutdown: /* shutdown(2) */ -+ ret = do_bsd_shutdown(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_setfib: /* setfib(2) */ -+ ret = do_freebsd_setfib(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_sctp_peeloff: /* sctp_peeloff(2) */ -+ ret = do_freebsd_sctp_peeloff(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_sctp_generic_sendmsg: /* sctp_generic_sendmsg(2) */ -+ ret = do_freebsd_sctp_generic_sendmsg(arg1, arg2, arg2, arg4, arg5, -+ arg6, arg7); -+ break; -+ -+ case TARGET_FREEBSD_NR_sctp_generic_recvmsg: /* sctp_generic_recvmsg(2) */ -+ ret = do_freebsd_sctp_generic_recvmsg(arg1, arg2, arg2, arg4, arg5, -+ arg6, arg7); -+ break; -+ -+ case TARGET_FREEBSD_NR_sendfile: /* sendfile(2) */ -+ ret = do_freebsd_sendfile(arg1, arg2, arg2, arg4, arg5, arg6, arg7, -+ arg8); -+ break; -+ -+ case TARGET_FREEBSD_NR_freebsd4_sendfile: /* freebsd4_sendfile(2) */ -+ ret = do_freebsd_freebsd4_sendfile(arg1, arg2, arg2, arg4, arg5, -+ arg6, arg7, arg8); -+ break; -+ -+ /* -+ * thread system calls -+ */ -+ case TARGET_FREEBSD_NR_thr_create: /* thr_create(2) */ -+ ret = do_freebsd_thr_create(cpu_env, arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_thr_new: /* thr_new(2) */ -+ ret = do_freebsd_thr_new(cpu_env, arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_thr_set_name: /* thr_set_name(2) */ -+ ret = do_freebsd_thr_set_name(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_thr_self: /* thr_self(2) */ -+ ret = do_freebsd_thr_self(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_thr_suspend: /* thr_suspend(2) */ -+ ret = do_freebsd_thr_suspend(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_thr_wake: /* thr_wake(2) */ -+ ret = do_freebsd_thr_wake(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_thr_kill: /* thr_kill(2) */ -+ ret = do_freebsd_thr_kill(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_thr_kill2: /* thr_kill2(2) */ -+ ret = do_freebsd_thr_kill2(arg1, arg2, arg3); -+ break; - --static abi_ulong target_brk; --static abi_ulong target_original_brk; -+ case TARGET_FREEBSD_NR_thr_exit: /* thr_exit(2) */ -+ ret = do_freebsd_thr_exit(cpu_env, arg1); -+ break; - --static inline abi_long get_errno(abi_long ret) --{ -- if (ret == -1) -- /* XXX need to translate host -> target errnos here */ -- return -(errno); -- else -- return ret; --} -+ case TARGET_FREEBSD_NR_rtprio_thread: /* rtprio_thread(2) */ -+ ret = do_freebsd_rtprio_thread(arg1, arg2, arg3); -+ break; - --#define target_to_host_bitmask(x, tbl) (x) -+ case TARGET_FREEBSD_NR_getcontext: /* getcontext(2) */ -+ ret = do_freebsd_getcontext(cpu_env, arg1); -+ break; - --static inline int is_error(abi_long ret) --{ -- return (abi_ulong)ret >= (abi_ulong)(-4096); --} -+ case TARGET_FREEBSD_NR_setcontext: /* setcontext(2) */ -+ ret = do_freebsd_setcontext(cpu_env, arg1); -+ break; - --void target_set_brk(abi_ulong new_brk) --{ -- target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk); --} -+ case TARGET_FREEBSD_NR_swapcontext: /* swapcontext(2) */ -+ ret = do_freebsd_swapcontext(cpu_env, arg1, arg2); -+ break; - --/* do_obreak() must return target errnos. */ --static abi_long do_obreak(abi_ulong new_brk) --{ -- abi_ulong brk_page; -- abi_long mapped_addr; -- int new_alloc_size; -+ case TARGET_FREEBSD_NR__umtx_lock: /* undocumented */ -+ ret = do_freebsd__umtx_lock(arg1); -+ break; - -- if (!new_brk) -- return 0; -- if (new_brk < target_original_brk) -- return -TARGET_EINVAL; -+ case TARGET_FREEBSD_NR__umtx_unlock: /* undocumented */ -+ ret = do_freebsd__umtx_unlock(arg1); -+ break; - -- brk_page = HOST_PAGE_ALIGN(target_brk); -+ case TARGET_FREEBSD_NR__umtx_op: /* undocumented */ -+ ret = do_freebsd__umtx_op(arg1, arg2, arg3, arg4, arg5); -+ break; - -- /* If the new brk is less than this, set it and we're done... */ -- if (new_brk < brk_page) { -- target_brk = new_brk; -- return 0; -- } -+ /* -+ * ioctl(2) -+ */ -+ case TARGET_FREEBSD_NR_ioctl: /* ioctl(2) */ -+ ret = do_bsd_ioctl(arg1, arg2, arg3); -+ break; - -- /* We need to allocate more memory after the brk... */ -- new_alloc_size = HOST_PAGE_ALIGN(new_brk - brk_page + 1); -- mapped_addr = get_errno(target_mmap(brk_page, new_alloc_size, -- PROT_READ|PROT_WRITE, -- MAP_ANON|MAP_FIXED|MAP_PRIVATE, -1, 0)); -+ /* -+ * sys{ctl, arch, call} -+ */ -+ case TARGET_FREEBSD_NR___sysctl: /* sysctl(3) */ -+ ret = do_freebsd_sysctl(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6); -+ break; - -- if (!is_error(mapped_addr)) -- target_brk = new_brk; -- else -- return mapped_addr; -+ case TARGET_FREEBSD_NR_sysarch: /* sysarch(2) */ -+ ret = do_freebsd_sysarch(cpu_env, arg1, arg2); -+ break; - -- return 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; - --#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; -+ /* -+ * extended attributes system calls -+ */ -+ case TARGET_FREEBSD_NR_extattrctl: /* extattrctl() */ -+ ret = do_freebsd_extattrctl(arg1, arg2, arg3, arg4, arg5); - 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 -+ case TARGET_FREEBSD_NR_extattr_set_file: /* extattr_set_file(2) */ -+ ret = do_freebsd_extattr_set_file(arg1, arg2, arg3, arg4, arg4); -+ break; - --#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; -+ case TARGET_FREEBSD_NR_extattr_get_file: /* extattr_get_file(2) */ -+ ret = do_freebsd_extattr_get_file(arg1, arg2, arg3, arg4, arg4); -+ break; - -- qoid[0] = 0; -- qoid[1] = 4; -- memcpy(qoid + 2, oid, len * sizeof(int)); -+ case TARGET_FREEBSD_NR_extattr_delete_file: /* extattr_delete_file(2) */ -+ ret = do_freebsd_extattr_delete_file(arg1, arg2, arg3); -+ break; - -- j = sizeof(buf); -- i = sysctl(qoid, len + 2, buf, &j, 0, 0); -- if (i) -- return i; -+ case TARGET_FREEBSD_NR_extattr_set_fd: /* extattr_set_fd(2) */ -+ ret = do_freebsd_extattr_set_fd(arg1, arg2, arg3, arg4, arg5); -+ break; - -- if (kind) -- *kind = *(uint32_t *)buf; -+ case TARGET_FREEBSD_NR_extattr_get_fd: /* extattr_get_fd(2) */ -+ ret = do_freebsd_extattr_get_fd(arg1, arg2, arg3, arg4, arg5); -+ break; - -- if (fmt) -- strcpy(fmt, (char *)(buf + sizeof(uint32_t))); -- return (0); --} -+ case TARGET_FREEBSD_NR_extattr_delete_fd: /* extattr_delete_fd(2) */ -+ ret = do_freebsd_extattr_delete_fd(arg1, arg2, arg3); -+ break; - --/* -- * 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); -+ case TARGET_FREEBSD_NR_extattr_get_link: /* extattr_get_link(2) */ -+ ret = do_freebsd_extattr_get_link(arg1, arg2, arg3, arg4, arg4); - break; --#endif --#ifdef CTLTYPE_U64 -- case CTLTYPE_S64: -- case CTLTYPE_U64: --#else -- case CTLTYPE_QUAD: --#endif -- *(uint64_t *)holdp = tswap64(*(uint64_t *)holdp); -+ -+ case TARGET_FREEBSD_NR_extattr_set_link: /* extattr_set_link(2) */ -+ ret = do_freebsd_extattr_set_link(arg1, arg2, arg3, arg4, arg4); - break; -- case CTLTYPE_STRING: -+ -+ case TARGET_FREEBSD_NR_extattr_delete_link: /* extattr_delete_link(2) */ -+ ret = do_freebsd_extattr_delete_link(arg1, arg2, arg3); - 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 -+ case TARGET_FREEBSD_NR_extattr_list_fd: /* extattr_list_fd(2) */ -+ ret = do_freebsd_extattr_list_fd(arg1, arg2, arg3, arg4); -+ break; - --/* 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. -- */ --static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr, -- int count, int copy) --{ -- struct target_iovec *target_vec; -- abi_ulong base; -- int i; -+ case TARGET_FREEBSD_NR_extattr_list_file: /* extattr_list_file(2) */ -+ ret = do_freebsd_extattr_list_file(arg1, arg2, arg3, arg4); -+ break; - -- target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1); -- if (!target_vec) -- return -TARGET_EFAULT; -- for(i = 0;i < count; i++) { -- base = tswapl(target_vec[i].iov_base); -- vec[i].iov_len = tswapl(target_vec[i].iov_len); -- if (vec[i].iov_len != 0) { -- vec[i].iov_base = lock_user(type, base, vec[i].iov_len, copy); -- /* Don't check lock_user return value. We must call writev even -- if a element has invalid base address. */ -- } else { -- /* zero length pointer is ignored */ -- vec[i].iov_base = NULL; -- } -- } -- unlock_user (target_vec, target_addr, 0); -- return 0; --} -+ case TARGET_FREEBSD_NR_extattr_list_link: /* extattr_list_link(2) */ -+ ret = do_freebsd_extattr_list_link(arg1, arg2, arg3, arg4); -+ break; - --static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr, -- int count, int copy) --{ -- struct target_iovec *target_vec; -- abi_ulong base; -- int i; -+ case TARGET_FREEBSD_NR___acl_aclcheck_fd: /* __acl_aclcheck_fd() */ -+ ret = do_freebsd__acl_aclcheck_fd(arg1, arg2, arg3); -+ break; - -- target_vec = lock_user(VERIFY_READ, target_addr, count * sizeof(struct target_iovec), 1); -- if (!target_vec) -- return -TARGET_EFAULT; -- for(i = 0;i < count; i++) { -- if (target_vec[i].iov_base) { -- base = tswapl(target_vec[i].iov_base); -- unlock_user(vec[i].iov_base, base, copy ? vec[i].iov_len : 0); -- } -- } -- unlock_user (target_vec, target_addr, 0); -+ case TARGET_FREEBSD_NR___acl_aclcheck_file: /* __acl_aclcheck_file() */ -+ ret = do_freebsd__acl_aclcheck_file(arg1, arg2, arg3); -+ break; - -- return 0; --} -+ case TARGET_FREEBSD_NR___acl_aclcheck_link: /* __acl_aclcheck_link() */ -+ ret = do_freebsd__acl_aclcheck_link(arg1, arg2, arg3); -+ break; - --/* do_syscall() should always have a single exit point at the end so -- that actions, such as logging of syscall results, can be performed. -- All errnos that do_syscall() returns must be -TARGET_<errcode>. */ --abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, -- abi_long arg2, abi_long arg3, abi_long arg4, -- abi_long arg5, abi_long arg6, abi_long arg7, -- abi_long arg8) --{ -- abi_long ret; -- void *p; -+ case TARGET_FREEBSD_NR___acl_delete_fd: /* __acl_delete_fd() */ -+ ret = do_freebsd__acl_delete_fd(arg1, arg2); -+ break; - --#ifdef DEBUG -- gemu_log("freebsd syscall %d\n", num); --#endif -- if(do_strace) -- print_freebsd_syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); -+ case TARGET_FREEBSD_NR___acl_delete_file: /* __acl_delete_file() */ -+ ret = do_freebsd__acl_delete_file(arg1, arg2); -+ break; - -- switch(num) { -- case TARGET_FREEBSD_NR_exit: --#ifdef TARGET_GPROF -- _mcleanup(); --#endif -- gdb_exit(cpu_env, arg1); -- /* XXX: should free thread stack and CPU env */ -- _exit(arg1); -- ret = 0; /* avoid warning */ -- break; -- case TARGET_FREEBSD_NR_read: -- if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) -- goto efault; -- ret = get_errno(read(arg1, p, arg3)); -- unlock_user(p, arg2, ret); -- break; -- case TARGET_FREEBSD_NR_write: -- if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) -- goto efault; -- ret = get_errno(write(arg1, p, arg3)); -- unlock_user(p, arg2, 0); -- break; -- case TARGET_FREEBSD_NR_writev: -- { -- int count = arg3; -- struct iovec *vec; -- -- vec = alloca(count * sizeof(struct iovec)); -- if (lock_iovec(VERIFY_READ, vec, arg2, count, 1) < 0) -- goto efault; -- ret = get_errno(writev(arg1, vec, count)); -- unlock_iovec(vec, arg2, count, 0); -- } -+ case TARGET_FREEBSD_NR___acl_delete_link: /* __acl_delete_link() */ -+ ret = do_freebsd__acl_delete_link(arg1, arg2); - break; -- case TARGET_FREEBSD_NR_open: -- if (!(p = lock_user_string(arg1))) -- goto efault; -- ret = get_errno(open(path(p), -- target_to_host_bitmask(arg2, fcntl_flags_tbl), -- arg3)); -- unlock_user(p, arg1, 0); -+ -+ case TARGET_FREEBSD_NR___acl_get_fd: /* __acl_get_fd() */ -+ ret = do_freebsd__acl_get_fd(arg1, arg2, arg3); - break; -- case TARGET_FREEBSD_NR_mmap: -- ret = get_errno(target_mmap(arg1, arg2, arg3, -- target_to_host_bitmask(arg4, mmap_flags_tbl), -- arg5, -- arg6)); -+ -+ case TARGET_FREEBSD_NR___acl_get_file: /* __acl_get_file() */ -+ ret = do_freebsd__acl_get_file(arg1, arg2, arg3); - break; -- case TARGET_FREEBSD_NR_mprotect: -- ret = get_errno(target_mprotect(arg1, arg2, arg3)); -+ -+ case TARGET_FREEBSD_NR___acl_get_link: /* __acl_get_link() */ -+ ret = do_freebsd__acl_get_link(arg1, arg2, arg3); - break; -- case TARGET_FREEBSD_NR_break: -- ret = do_obreak(arg1); -+ -+ case TARGET_FREEBSD_NR___acl_set_fd: /* __acl_get_fd() */ -+ ret = do_freebsd__acl_set_fd(arg1, arg2, arg3); - break; --#ifdef __FreeBSD__ -- case TARGET_FREEBSD_NR___sysctl: -- ret = do_freebsd_sysctl(arg1, arg2, arg3, arg4, arg5, arg6); -+ -+ case TARGET_FREEBSD_NR___acl_set_file: /* __acl_set_file() */ -+ ret = do_freebsd__acl_set_file(arg1, arg2, arg3); - break; --#endif -- case TARGET_FREEBSD_NR_sysarch: -- ret = do_freebsd_sysarch(cpu_env, arg1, arg2); -+ -+ case TARGET_FREEBSD_NR___acl_set_link: /* __acl_set_link() */ -+ ret = do_freebsd__acl_set_link(arg1, arg2, arg3); -+ break; -+ -+ /* -+ * SysV Semaphores -+ */ -+ case TARGET_FREEBSD_NR_semget: /* semget(2) */ -+ ret = do_bsd_semget(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_semop: /* semop(2) */ -+ ret = do_bsd_semop(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR___semctl: /* __semctl() undocumented */ -+ ret = do_bsd___semctl(arg1, arg2, arg3, -+ (union target_semun)(abi_ulong)arg4); -+ break; -+ -+ /* -+ * SysV Messages -+ */ -+ case TARGET_FREEBSD_NR_msgctl: /* msgctl(2) */ -+ ret = do_bsd_msgctl(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_msgsnd: /* msgsnd(2) */ -+ ret = do_bsd_msgsnd(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_msgrcv: /* msgrcv(2) */ -+ ret = do_bsd_msgrcv(arg1, arg2, arg3, arg4, arg5); -+ break; -+ -+ /* -+ * FreeBSD scheduler control -+ */ -+ case TARGET_FREEBSD_NR_sched_setparam: /* sched_setparam(2) */ -+ ret = do_freebsd_sched_setparam(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_sched_getparam: /* sched_getparam(2) */ -+ ret = do_freebsd_sched_getparam(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_sched_setscheduler: /* sched_setscheduler(2) */ -+ ret = do_freebsd_sched_setscheduler(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_sched_getscheduler: /* sched_getscheduler(2) */ -+ ret = do_freebsd_sched_getscheduler(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_sched_rr_get_interval: /* sched_rr_get_interval(2) */ -+ ret = do_freebsd_sched_rr_get_interval(arg1, arg2); -+ break; -+ -+ /* -+ * FreeBSD CPU affinity sets management -+ */ -+ case TARGET_FREEBSD_NR_cpuset: /* cpuset(2) */ -+ ret = do_freebsd_cpuset(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_cpuset_setid: /* cpuset_setid(2) */ -+ ret = do_freebsd_cpuset_setid(cpu_env, arg1, arg2, arg3, arg4, arg5); -+ break; -+ -+ case TARGET_FREEBSD_NR_cpuset_getid: /* cpuset_getid(2) */ -+ ret = do_freebsd_cpuset_getid(arg1, arg2, arg3, arg4, arg5); -+ break; -+ -+ case TARGET_FREEBSD_NR_cpuset_getaffinity: /* cpuset_getaffinity(2) */ -+ ret = do_freebsd_cpuset_getaffinity(arg1, arg2, arg3, arg4, arg5, arg6); -+ break; -+ -+ case TARGET_FREEBSD_NR_cpuset_setaffinity: /* cpuset_setaffinity(2) */ -+ ret = do_freebsd_cpuset_setaffinity(arg1, arg2, arg3, arg4, arg5, arg6); -+ break; -+ -+ -+ /* -+ * FreeBSD kernel module -+ */ -+ case TARGET_FREEBSD_NR_modfnext: /* modfnext(2) */ -+ ret = do_freebsd_modfnext(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_modfind: /* modfind(2) */ -+ ret = do_freebsd_modfind(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_kldload: /* kldload(2) */ -+ ret = do_freebsd_kldload(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_kldunload: /* kldunload(2) */ -+ ret = do_freebsd_kldunload(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_kldunloadf: /* kldunloadf(2) */ -+ ret = do_freebsd_kldunloadf(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_kldfind: /* kldfind(2) */ -+ ret = do_freebsd_kldfind(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_kldnext: /* kldnext(2) */ -+ ret = do_freebsd_kldnext(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_kldstat: /* kldstat(2) */ -+ ret = do_freebsd_kldstat(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_kldfirstmod: /* kldfirstmod(2) */ -+ ret = do_freebsd_kldfirstmod(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_kldsym: /* kldsym(2) */ -+ ret = do_freebsd_kldsym(arg1, arg2, arg3); -+ break; -+ -+ /* -+ * FreeBSD resource controls (undocumented except for rctl(8) -+ * and rctl.conf(5) ) -+ */ -+ case TARGET_FREEBSD_NR_rctl_get_racct: /* rctl_get_racct() */ -+ ret = do_freebsd_rctl_get_racct(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_rctl_get_rules: /* rctl_get_rules() */ -+ ret = do_freebsd_rctl_get_rules(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_rctl_add_rule: /* rctl_add_rule() */ -+ ret = do_freebsd_rctl_add_rule(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_rctl_remove_rule: /* rctl_remove_rule() */ -+ ret = do_freebsd_rctl_remove_rule(arg1, arg2, arg3, arg4); -+ break; -+ -+ case TARGET_FREEBSD_NR_rctl_get_limits: /* rctl_get_limits() */ -+ ret = do_freebsd_rctl_get_limits(arg1, arg2, arg3, arg4); -+ break; -+ -+ /* -+ * FreeBSD Mandatory Access Control -+ */ -+ case TARGET_FREEBSD_NR___mac_get_proc: /* __mac_get_proc() */ -+ ret = do_freebsd___mac_get_proc(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR___mac_set_proc: /* __mac_set_proc() */ -+ ret = do_freebsd___mac_set_proc(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR___mac_get_fd: /* __mac_get_fd() */ -+ ret = do_freebsd___mac_get_fd(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR___mac_set_fd: /* __mac_set_fd() */ -+ ret = do_freebsd___mac_set_fd(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR___mac_get_file: /* __mac_get_file() */ -+ ret = do_freebsd___mac_get_proc(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR___mac_set_file: /* __mac_set_file() */ -+ ret = do_freebsd___mac_set_file(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR___mac_get_link: /* __mac_get_link() */ -+ ret = do_freebsd___mac_get_link(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR___mac_set_link: /* __mac_set_link() */ -+ ret = do_freebsd___mac_set_link(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_mac_syscall: /* mac_syscall() */ -+ ret = do_freebsd_mac_syscall(arg1, arg2, arg3); -+ break; -+ -+ /* -+ * FreeBSD additional posix support -+ */ -+ case TARGET_FREEBSD_NR_posix_fallocate: /* posix_fallocate(2) */ -+ ret = do_freebsd_posix_fallocate(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_posix_openpt: /* posix_openpt(2) */ -+ ret = do_freebsd_posix_openpt(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_posix_fadvise: /* posix_fadvise(2) */ -+ ret = do_freebsd_posix_fadvise(arg1, arg2, arg3, arg4); -+ break; -+ -+ /* -+ * Misc -+ */ -+ case TARGET_FREEBSD_NR_quotactl: /* quotactl(2) */ -+ ret = do_bsd_quotactl(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_reboot: /* reboot(2) */ -+ ret = do_bsd_reboot(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_uuidgen: /* uuidgen(2) */ -+ ret = do_bsd_uuidgen(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_getdtablesize: /* getdtablesize(2) */ -+ ret = do_bsd_getdtablesize(); -+ break; -+ -+ case TARGET_FREEBSD_NR_kenv: /* kenv(2) */ -+ ret = do_freebsd_kenv(arg1, arg2, arg2, arg4); - 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_break: -+ ret = do_obreak(arg1); - 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: -+ - #ifdef DEBUG - gemu_log(" = %ld\n", ret); - #endif - if (do_strace) - print_freebsd_syscall_ret(num, ret); - return ret; -- efault: -- ret = -TARGET_EFAULT; -- goto fail; - } - - abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1, -@@ -420,7 +1556,6 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1, - abi_long arg5, abi_long arg6) - { - abi_long ret; -- void *p; - - #ifdef DEBUG - gemu_log("netbsd syscall %d\n", num); -@@ -430,43 +1565,26 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1, - - switch(num) { - case TARGET_NETBSD_NR_exit: --#ifdef TARGET_GPROF -- _mcleanup(); --#endif -- gdb_exit(cpu_env, arg1); -- /* XXX: should free thread stack and CPU env */ -- _exit(arg1); -- ret = 0; /* avoid warning */ -+ ret = do_bsd_exit(cpu_env, arg1); - break; -+ - case TARGET_NETBSD_NR_read: -- if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) -- goto efault; -- ret = get_errno(read(arg1, p, arg3)); -- unlock_user(p, arg2, ret); -+ ret = do_bsd_read(arg1, arg2, arg3); - break; - case TARGET_NETBSD_NR_write: -- if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) -- goto efault; -- ret = get_errno(write(arg1, p, arg3)); -- unlock_user(p, arg2, 0); -+ ret = do_bsd_write(arg1, arg2, arg3); - break; - case TARGET_NETBSD_NR_open: -- if (!(p = lock_user_string(arg1))) -- goto efault; -- ret = get_errno(open(path(p), -- target_to_host_bitmask(arg2, fcntl_flags_tbl), -- arg3)); -- unlock_user(p, arg1, 0); -+ ret = do_bsd_open(arg1, arg2, arg3); - break; -+ - case TARGET_NETBSD_NR_mmap: -- ret = get_errno(target_mmap(arg1, arg2, arg3, -- target_to_host_bitmask(arg4, mmap_flags_tbl), -- arg5, -- arg6)); -+ ret = do_bsd_mmap(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6, 0, 0); - break; - case TARGET_NETBSD_NR_mprotect: -- ret = get_errno(target_mprotect(arg1, arg2, arg3)); -+ ret = do_bsd_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); -@@ -475,16 +1593,12 @@ abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1, - ret = syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); - break; - } -- fail: - #ifdef DEBUG - gemu_log(" = %ld\n", ret); - #endif - if (do_strace) - print_netbsd_syscall_ret(num, ret); - return ret; -- efault: -- ret = -TARGET_EFAULT; -- goto fail; - } - - abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1, -@@ -492,7 +1606,6 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1, - abi_long arg5, abi_long arg6) - { - abi_long ret; -- void *p; - - #ifdef DEBUG - gemu_log("openbsd syscall %d\n", num); -@@ -502,43 +1615,26 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1, - - switch(num) { - case TARGET_OPENBSD_NR_exit: --#ifdef TARGET_GPROF -- _mcleanup(); --#endif -- gdb_exit(cpu_env, arg1); -- /* XXX: should free thread stack and CPU env */ -- _exit(arg1); -- ret = 0; /* avoid warning */ -+ ret = do_bsd_exit(cpu_env, arg1); - break; -+ - case TARGET_OPENBSD_NR_read: -- if (!(p = lock_user(VERIFY_WRITE, arg2, arg3, 0))) -- goto efault; -- ret = get_errno(read(arg1, p, arg3)); -- unlock_user(p, arg2, ret); -+ ret = do_bsd_read(arg1, arg2, arg3); - break; - case TARGET_OPENBSD_NR_write: -- if (!(p = lock_user(VERIFY_READ, arg2, arg3, 1))) -- goto efault; -- ret = get_errno(write(arg1, p, arg3)); -- unlock_user(p, arg2, 0); -+ ret = do_bsd_write(arg1, arg2, arg3); - break; - case TARGET_OPENBSD_NR_open: -- if (!(p = lock_user_string(arg1))) -- goto efault; -- ret = get_errno(open(path(p), -- target_to_host_bitmask(arg2, fcntl_flags_tbl), -- arg3)); -- unlock_user(p, arg1, 0); -+ ret = do_bsd_open(arg1, arg2, arg3); - break; -+ - case TARGET_OPENBSD_NR_mmap: -- ret = get_errno(target_mmap(arg1, arg2, arg3, -- target_to_host_bitmask(arg4, mmap_flags_tbl), -- arg5, -- arg6)); -+ ret = do_bsd_mmap(cpu_env, arg1, arg2, arg3, arg4, arg5, arg6, 0, 0); - break; - case TARGET_OPENBSD_NR_mprotect: -- ret = get_errno(target_mprotect(arg1, arg2, arg3)); -+ ret = do_bsd_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); -@@ -547,18 +1643,16 @@ abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1, - ret = syscall(num, arg1, arg2, arg3, arg4, arg5, arg6); - break; - } -- fail: - #ifdef DEBUG - gemu_log(" = %ld\n", ret); - #endif - if (do_strace) - print_openbsd_syscall_ret(num, ret); - return ret; -- efault: -- ret = -TARGET_EFAULT; -- goto fail; - } - - void syscall_init(void) - { -+ -+ init_bsd_ioctl(); - } -diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h -index 207ddee..13678d4 100644 ---- a/bsd-user/syscall_defs.h -+++ b/bsd-user/syscall_defs.h -@@ -1,105 +1,5 @@ --/* $OpenBSD: signal.h,v 1.19 2006/01/08 14:20:16 millert Exp $ */ --/* $NetBSD: signal.h,v 1.21 1996/02/09 18:25:32 christos Exp $ */ -- --/* -- * Copyright (c) 1982, 1986, 1989, 1991, 1993 -- * The Regents of the University of California. All rights reserved. -- * (c) UNIX System Laboratories, Inc. -- * All or some portions of this file are derived from material licensed -- * to the University of California by American Telephone and Telegraph -- * Co. or Unix System Laboratories, Inc. and are reproduced herein with -- * the permission of UNIX System Laboratories, Inc. -- * -- * Redistribution and use in source and binary forms, with or without -- * modification, are permitted provided that the following conditions -- * are met: -- * 1. Redistributions of source code must retain the above copyright -- * notice, this list of conditions and the following disclaimer. -- * 2. Redistributions in binary form must reproduce the above copyright -- * notice, this list of conditions and the following disclaimer in the -- * documentation and/or other materials provided with the distribution. -- * 3. Neither the name of the University nor the names of its contributors -- * may be used to endorse or promote products derived from this software -- * without specific prior written permission. -- * -- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -- * SUCH DAMAGE. -- * -- * @(#)signal.h 8.2 (Berkeley) 1/21/94 -- */ -- --#define TARGET_NSIG 32 /* counting 0; could be 33 (mask is 1-32) */ -- --#define TARGET_SIGHUP 1 /* hangup */ --#define TARGET_SIGINT 2 /* interrupt */ --#define TARGET_SIGQUIT 3 /* quit */ --#define TARGET_SIGILL 4 /* illegal instruction (not reset when caught) */ --#define TARGET_SIGTRAP 5 /* trace trap (not reset when caught) */ --#define TARGET_SIGABRT 6 /* abort() */ --#define TARGET_SIGIOT SIGABRT /* compatibility */ --#define TARGET_SIGEMT 7 /* EMT instruction */ --#define TARGET_SIGFPE 8 /* floating point exception */ --#define TARGET_SIGKILL 9 /* kill (cannot be caught or ignored) */ --#define TARGET_SIGBUS 10 /* bus error */ --#define TARGET_SIGSEGV 11 /* segmentation violation */ --#define TARGET_SIGSYS 12 /* bad argument to system call */ --#define TARGET_SIGPIPE 13 /* write on a pipe with no one to read it */ --#define TARGET_SIGALRM 14 /* alarm clock */ --#define TARGET_SIGTERM 15 /* software termination signal from kill */ --#define TARGET_SIGURG 16 /* urgent condition on IO channel */ --#define TARGET_SIGSTOP 17 /* sendable stop signal not from tty */ --#define TARGET_SIGTSTP 18 /* stop signal from tty */ --#define TARGET_SIGCONT 19 /* continue a stopped process */ --#define TARGET_SIGCHLD 20 /* to parent on child stop or exit */ --#define TARGET_SIGTTIN 21 /* to readers pgrp upon background tty read */ --#define TARGET_SIGTTOU 22 /* like TTIN for output if (tp->t_local<OSTOP) */ --#define TARGET_SIGIO 23 /* input/output possible signal */ --#define TARGET_SIGXCPU 24 /* exceeded CPU time limit */ --#define TARGET_SIGXFSZ 25 /* exceeded file size limit */ --#define TARGET_SIGVTALRM 26 /* virtual time alarm */ --#define TARGET_SIGPROF 27 /* profiling time alarm */ --#define TARGET_SIGWINCH 28 /* window size changes */ --#define TARGET_SIGINFO 29 /* information request */ --#define TARGET_SIGUSR1 30 /* user defined signal 1 */ --#define TARGET_SIGUSR2 31 /* user defined signal 2 */ -- --/* -- * Language spec says we must list exactly one parameter, even though we -- * actually supply three. Ugh! -- */ --#define TARGET_SIG_DFL (void (*)(int))0 --#define TARGET_SIG_IGN (void (*)(int))1 --#define TARGET_SIG_ERR (void (*)(int))-1 -- --#define TARGET_SA_ONSTACK 0x0001 /* take signal on signal stack */ --#define TARGET_SA_RESTART 0x0002 /* restart system on signal return */ --#define TARGET_SA_RESETHAND 0x0004 /* reset to SIG_DFL when taking signal */ --#define TARGET_SA_NODEFER 0x0010 /* don't mask the signal we're delivering */ --#define TARGET_SA_NOCLDWAIT 0x0020 /* don't create zombies (assign to pid 1) */ --#define TARGET_SA_USERTRAMP 0x0100 /* do not bounce off kernel's sigtramp */ --#define TARGET_SA_NOCLDSTOP 0x0008 /* do not generate SIGCHLD on child stop */ --#define TARGET_SA_SIGINFO 0x0040 /* generate siginfo_t */ -- --/* -- * Flags for sigprocmask: -- */ --#define TARGET_SIG_BLOCK 1 /* block specified signal set */ --#define TARGET_SIG_UNBLOCK 2 /* unblock specified signal set */ --#define TARGET_SIG_SETMASK 3 /* set specified signal set */ -- --#define TARGET_BADSIG SIG_ERR -- --#define TARGET_SS_ONSTACK 0x0001 /* take signals on alternate stack */ --#define TARGET_SS_DISABLE 0x0004 /* disable taking signals on alternate stack */ -+#ifndef _SYSCALL_DEFS_H_ -+#define _SYSCALL_DEFS_H_ - - #include "errno_defs.h" - -@@ -112,3 +12,759 @@ struct target_iovec { - abi_long iov_len; /* Number of bytes */ - }; - -+/* -+ * sys/ipc.h -+ */ -+struct target_ipc_perm { -+ uint32_t cuid; /* creator user id */ -+ uint32_t cgid; /* creator group id */ -+ uint32_t uid; /* user id */ -+ uint32_t gid; /* group id */ -+ uint16_t mode; /* r/w permission */ -+ uint16_t seq; /* sequence # */ -+ abi_long key; /* user specified msg/sem/shm key */ -+}; -+ -+#define TARGET_IPC_RMID 0 /* remove identifier */ -+#define TARGET_IPC_SET 1 /* set options */ -+#define TARGET_IPC_STAT 2 /* get options */ -+ -+/* -+ * sys/sem.h -+ */ -+#define TARGET_GETNCNT 3 /* Return the value of semncnt {READ} */ -+#define TARGET_GETPID 4 /* Return the value of sempid {READ} */ -+#define TARGET_GETVAL 5 /* Return the value of semval {READ} */ -+#define TARGET_GETALL 6 /* Return semvals into arg.array {READ} */ -+#define TARGET_GETZCNT 7 /* Return the value of semzcnt {READ} */ -+#define TARGET_SETVAL 8 /* Set the value of semval to arg.val {ALTER} */ -+#define TARGET_SETALL 9 /* Set semvals from arg.array {ALTER} */ -+#define TARGET_SEM_STAT 10 /* Like IPC_STAT but treats semid as sema-index */ -+#define TARGET_SEM_INFO 11 /* Like IPC_INFO but treats semid as sema-index */ -+ -+struct target_sembuf { -+ unsigned short sem_num; /* semaphore # */ -+ short sem_op; /* semaphore operation */ -+ short sem_flg; /* operation flags */ -+}; -+ -+union target_semun { -+ int val; /* value for SETVAL */ -+ abi_ulong buf; /* buffer for IPC_STAT & IPC_SET */ -+ abi_ulong array; /* array for GETALL & SETALL */ -+}; -+ -+struct target_semid_ds { -+ struct target_ipc_perm sem_perm; /* operation permission struct */ -+ abi_ulong sem_base; /* pointer to first semaphore in set */ -+ uint16_t sem_nsems; /* number of sems in set */ -+ abi_ulong sem_otime; /* last operation time */ -+ abi_ulong sem_ctime; /* times measured in secs */ -+}; -+ -+/* -+ * sys/shm.h -+ */ -+struct target_shmid_ds { -+ struct target_ipc_perm shm_perm; /* peration permission structure */ -+ abi_ulong shm_segsz; /* size of segment in bytes */ -+ int32_t shm_lpid; /* process ID of last shared memory op */ -+ int32_t shm_cpid; /* process ID of creator */ -+ int32_t shm_nattch; /* number of current attaches */ -+ abi_ulong shm_atime; /* time of last shmat() */ -+ abi_ulong shm_dtime; /* time of last shmdt() */ -+ abi_ulong shm_ctime; /* time of last change by shmctl() */ -+}; -+ -+#define N_BSD_SHM_REGIONS 32 -+struct bsd_shm_regions { -+ abi_long start; -+ abi_long size; -+}; -+ -+/* -+ * sys/msg.h -+ */ -+struct target_msqid_ds { -+ struct target_ipc_perm msg_perm; /* msg queue permission bits */ -+ abi_ulong msg_first; /* first message in the queue */ -+ abi_ulong msg_last; /* last message in the queue */ -+ abi_ulong msg_cbytes; /* # of bytes in use on the queue */ -+ abi_ulong msg_qnum; /* number of msgs in the queue */ -+ abi_ulong msg_qbytes; /* max # of bytes on the queue */ -+ int32_t msg_lspid; /* pid of last msgsnd() */ -+ int32_t msg_lrpid; /* pid of last msgrcv() */ -+ abi_ulong msg_stime; /* time of last msgsnd() */ -+ abi_ulong msg_rtime; /* time of last msgrcv() */ -+ abi_ulong msg_ctime; /* time of last msgctl() */ -+}; -+ -+struct target_msgbuf { -+ abi_long mtype; /* message type */ -+ char mtext[1]; /* body of message */ -+}; -+ -+/* -+ * sched.h -+ */ -+struct target_sched_param { -+ int32_t sched_priority; -+}; -+ -+/* -+ * sys/mman.h -+ */ -+#define TARGET_FREEBSD_MAP_RESERVED0080 0x0080 /* previously misimplemented -+ MAP_INHERIT */ -+#define TARGET_FREEBSD_MAP_RESERVED0100 0x0100 /* previously unimplemented -+ MAP_NOEXTEND */ -+#define TARGET_FREEBSD_MAP_STACK 0x0400 /* region grows down, like a -+ stack */ -+#define TARGET_FREEBSD_MAP_NOSYNC 0x0800 /* page to but do not sync -+ underlying file */ -+ -+#define TARGET_FREEBSD_MAP_FLAGMASK 0x1ff7 -+ -+#define TARGET_NETBSD_MAP_INHERIT 0x0080 /* region is retained after -+ exec */ -+#define TARGET_NETBSD_MAP_TRYFIXED 0x0400 /* attempt hint address, even -+ within break */ -+#define TARGET_NETBSD_MAP_WIRED 0x0800 /* mlock() mapping when it is -+ established */ -+ -+#define TARGET_NETBSD_MAP_STACK 0x2000 /* allocated from memory, swap -+ space (stack) */ -+ -+#define TARGET_NETBSD_MAP_FLAGMASK 0x3ff7 -+ -+#define TARGET_OPENBSD_MAP_INHERIT 0x0080 /* region is retained after -+ exec */ -+#define TARGET_OPENBSD_MAP_NOEXTEND 0x0100 /* for MAP_FILE, don't change -+ file size */ -+#define TARGET_OPENBSD_MAP_TRYFIXED 0x0400 /* attempt hint address, -+ even within heap */ -+ -+#define TARGET_OPENBSD_MAP_FLAGMASK 0x17f7 -+ -+/* XXX */ -+#define TARGET_BSD_MAP_FLAGMASK 0x3ff7 -+ -+/* -+ * sys/time.h -+ * sys/timex.h -+ */ -+ -+/* -+ * time_t seems to be very inconsistly defined for the different *BSD's... -+ * -+ * FreeBSD/{arm, mips} uses a 64bits time_t, even in 32bits mode, -+ * so we have to add a special case here. -+ * -+ * On NetBSD time_t is always defined as an int64_t. On OpenBSD time_t -+ * is always defined as an int. -+ * -+ */ -+#if (defined(TARGET_ARM) || defined(TARGET_MIPS)) -+typedef int64_t target_freebsd_time_t; -+#else -+typedef abi_long target_freebsd_time_t; -+#endif -+ -+typedef abi_long target_freebsd_suseconds_t; -+ -+/* compare to sys/timespec.h */ -+struct target_freebsd_timespec { -+ target_freebsd_time_t tv_sec; /* seconds */ -+ abi_long tv_nsec; /* and nanoseconds */ -+#if (defined(TARGET_ARM) || defined(TARGET_MIPS)) && TARGET_ABI_BITS == 32 -+ abi_long _pad; -+#endif -+} __packed; -+ -+struct target_freebsd_timeval { -+ target_freebsd_time_t tv_sec; /* seconds */ -+ target_freebsd_suseconds_t tv_usec;/* and microseconds */ -+#if (defined(TARGET_ARM) || defined(TARGET_MIPS)) && TARGET_ABI_BITS == 32 -+ abi_long _pad; -+#endif -+} __packed; -+ -+/* compare to sys/timex.h */ -+struct target_freebsd_ntptimeval { -+ struct target_freebsd_timespec time; -+ abi_long maxerror; -+ abi_long esterror; -+ abi_long tai; -+ int32_t time_state; -+}; -+ -+struct target_freebsd_timex { -+ uint32_t modes; -+ abi_long offset; -+ abi_long freq; -+ abi_long maxerror; -+ abi_long esterror; -+ int32_t status; -+ abi_long constant; -+ abi_long precision; -+ abi_long tolerance; -+ -+ abi_long ppsfreq; -+ abi_long jitter; -+ int32_t shift; -+ abi_long stabil; -+ abi_long jitcnt; -+ abi_long calcnt; -+ abi_long errcnt; -+ abi_long stbcnt; -+}; -+ -+/* -+ * sys/event.h -+ */ -+struct target_freebsd_kevent { -+ abi_ulong ident; -+ int16_t filter; -+ uint16_t flags; -+ uint32_t fflags; -+ abi_long data; -+ abi_ulong udata; -+} __packed; -+ -+/* -+ * sys/resource.h -+ */ -+#if defined(__FreeBSD__) && defined(TARGET_ALPHA) -+#define TARGET_RLIM_INFINITY 0x7fffffffffffffffull -+#elif defined(__FreeBSD__) && (defined(TARGET_MIPS) || \ -+ (defined(TARGET_SPARC) && TARGET_ABI_BITS == 32)) -+#define TARGET_RLIM_INFINITY 0x7fffffffUL -+#else -+#define TARGET_RLIM_INFINITY ((abi_ulong)-1) -+#endif -+ -+#define TARGET_RLIMIT_CPU 0 -+#define TARGET_RLIMIT_FSIZE 1 -+#define TARGET_RLIMIT_DATA 2 -+#define TARGET_RLIMIT_STACK 3 -+#define TARGET_RLIMIT_CORE 4 -+#define TARGET_RLIMIT_RSS 5 -+#define TARGET_RLIMIT_MEMLOCK 6 -+#define TARGET_RLIMIT_NPROC 7 -+#define TARGET_RLIMIT_NOFILE 8 -+#define TARGET_RLIMIT_SBSIZE 9 -+#define TARGET_RLIMIT_AS 10 -+#define TARGET_RLIMIT_NPTS 11 -+#define TARGET_RLIMIT_SWAP 12 -+ -+struct target_rlimit { -+ uint64_t rlim_cur; -+ uint64_t rlim_max; -+}; -+ -+struct target_freebsd_rusage { -+ struct target_freebsd_timeval ru_utime; /* user time used */ -+ struct target_freebsd_timeval ru_stime; /* system time used */ -+ abi_long ru_maxrss; /* maximum resident set size */ -+ abi_long ru_ixrss; /* integral shared memory size */ -+ abi_long ru_idrss; /* integral unshared data size */ -+ abi_long ru_isrss; /* integral unshared stack size */ -+ abi_long ru_minflt; /* page reclaims */ -+ abi_long ru_majflt; /* page faults */ -+ abi_long ru_nswap; /* swaps */ -+ abi_long ru_inblock; /* block input operations */ -+ abi_long ru_oublock; /* block output operations */ -+ abi_long ru_msgsnd; /* messages sent */ -+ abi_long ru_msgrcv; /* messages received */ -+ abi_long ru_nsignals; /* signals received */ -+ abi_long ru_nvcsw; /* voluntary context switches */ -+ abi_long ru_nivcsw; /* involuntary context switches */ -+}; -+ -+/* -+ * sys/socket.h -+ */ -+ -+/* -+ * Types -+ */ -+#define TARGET_SOCK_STREAM 1 /* stream socket */ -+#define TARGET_SOCK_DGRAM 2 /* datagram socket */ -+#define TARGET_SOCK_RAW 3 /* raw-protocol interface */ -+#define TARGET_SOCK_RDM 4 /* reliably-delivered message */ -+#define TARGET_SOCK_SEQPACKET 5 /* sequenced packet stream */ -+ -+ -+/* -+ * Option flags per-socket. -+ */ -+ -+#define TARGET_SO_DEBUG 0x0001 /* turn on debugging info recording */ -+#define TARGET_SO_ACCEPTCONN 0x0002 /* socket has had listen() */ -+#define TARGET_SO_REUSEADDR 0x0004 /* allow local address reuse */ -+#define TARGET_SO_KEEPALIVE 0x0008 /* keep connections alive */ -+#define TARGET_SO_DONTROUTE 0x0010 /* just use interface addresses */ -+#define TARGET_SO_BROADCAST 0x0020 /* permit sending of broadcast msgs */ -+#define TARGET_SO_USELOOPBACK 0x0040 /* bypass hardware when possible */ -+#define TARGET_SO_LINGER 0x0080 /* linger on close if data present */ -+#define TARGET_SO_OOBINLINE 0x0100 /* leave received OOB data in line */ -+#define TARGET_SO_REUSEPORT 0x0200 /* allow local address & port reuse */ -+#define TARGET_SO_TIMESTAMP 0x0400 /* timestamp received dgram traffic */ -+#define TARGET_SO_NOSIGPIPE 0x0800 /* no SIGPIPE from EPIPE */ -+#define TARGET_SO_ACCEPTFILTER 0x1000 /* there is an accept filter */ -+#define TARGET_SO_BINTIME 0x2000 /* timestamp received dgram traffic */ -+#define TARGET_SO_NO_OFFLOAD 0x4000 /* socket cannot be offloaded */ -+#define TARGET_SO_NO_DDP 0x8000 /* disable direct data placement */ -+ -+/* -+ * Additional options, not kept in so_options. -+ */ -+#define TARGET_SO_SNDBUF 0x1001 /* send buffer size */ -+#define TARGET_SO_RCVBUF 0x1002 /* receive buffer size */ -+#define TARGET_SO_SNDLOWAT 0x1003 /* send low-water mark */ -+#define TARGET_SO_RCVLOWAT 0x1004 /* receive low-water mark */ -+#define TARGET_SO_SNDTIMEO 0x1005 /* send timeout */ -+#define TARGET_SO_RCVTIMEO 0x1006 /* receive timeout */ -+#define TARGET_SO_ERROR 0x1007 /* get error status and clear */ -+#define TARGET_SO_TYPE 0x1008 /* get socket type */ -+#define TARGET_SO_LABEL 0x1009 /* socket's MAC label */ -+#define TARGET_SO_PEERLABEL 0x1010 /* socket's peer's MAC label */ -+#define TARGET_SO_LISTENQLIMIT 0x1011 /* socket's backlog limit */ -+#define TARGET_SO_LISTENQLEN 0x1012 /* socket's complete queue length */ -+#define TARGET_SO_LISTENINCQLEN 0x1013 /* socket's incomplete queue length */ -+#define TARGET_SO_SETFIB 0x1014 /* use this FIB to route */ -+#define TARGET_SO_USER_COOKIE 0x1015 /* user cookie (dummynet etc.) */ -+#define TARGET_SO_PROTOCOL 0x1016 /* get socket protocol (Linux name) */ -+ -+/* alias for SO_PROTOCOL (SunOS name) */ -+#define TARGET_SO_PROTOTYPE TARGET_SO_PROTOCOL -+ -+/* -+ * Level number for (get/set)sockopt() to apply to socket itself. -+ */ -+#define TARGET_SOL_SOCKET 0xffff /* options for socket level */ -+ -+#ifndef CMSG_ALIGN -+#define CMSG_ALIGN(len) (((len)+sizeof(long)-1) & ~(sizeof(long)-1)) -+#endif -+ -+struct target_msghdr { -+ abi_long msg_name; /* So cket name */ -+ int32_t msg_namelen; /* Length of name */ -+ abi_long msg_iov; /* Data blocks */ -+ abi_long msg_iovlen; /* Number of blocks */ -+ abi_long msg_control; /* Per protocol magic -+ (eg BSD file descriptor passing) */ -+ abi_long msg_controllen; /* Length of cmsg list */ -+ int32_t msg_flags; /* flags on received message */ -+}; -+ -+struct target_sockaddr { -+ uint8_t sa_len; -+ uint8_t sa_family; -+ uint8_t sa_data[14]; -+} QEMU_PACKED; -+ -+struct target_in_addr { -+ uint32_t s_addr; /* big endian */ -+}; -+ -+struct target_cmsghdr { -+ abi_long cmsg_len; -+ int32_t cmsg_level; -+ int32_t cmsg_type; -+}; -+ -+#define TARGET_CMSG_DATA(cmsg) \ -+ ((unsigned char *)((struct target_cmsghdr *) (cmsg) + 1)) -+#define TARGET_CMSG_NXTHDR(mhdr, cmsg) __target_cmsg_nxthdr(mhdr, cmsg) -+#define TARGET_CMSG_ALIGN(len) (((len) + sizeof(abi_long) - 1) \ -+ & (size_t) ~(sizeof(abi_long) - 1)) -+#define TARGET_CMSG_SPACE(len) (TARGET_CMSG_ALIGN(len) \ -+ + TARGET_CMSG_ALIGN(sizeof(struct target_cmsghdr))) -+#define TARGET_CMSG_LEN(len) \ -+ (TARGET_CMSG_ALIGN(sizeof(struct target_cmsghdr)) + (len)) -+ -+static inline struct target_cmsghdr *__target_cmsg_nxthdr( -+ struct target_msghdr *__mhdr, struct target_cmsghdr *__cmsg) -+{ -+ struct target_cmsghdr *__ptr; -+ -+ __ptr = (struct target_cmsghdr *)((unsigned char *) __cmsg + -+ TARGET_CMSG_ALIGN(tswapal(__cmsg->cmsg_len))); -+ if ((unsigned long)((char *)(__ptr+1) - -+ (char *)(size_t)tswapal(__mhdr->msg_control)) > -+ tswapal(__mhdr->msg_controllen)) { -+ /* No more entries. */ -+ return (struct target_cmsghdr *)0; -+ } -+ return __cmsg; -+} -+ -+/* -+ * netinet/in.h -+ */ -+struct target_ip_mreq { -+ struct target_in_addr imr_multiaddr; -+ struct target_in_addr imr_interface; -+}; -+ -+struct target_ip_mreqn { -+ struct target_in_addr imr_multiaddr; -+ struct target_in_addr imr_address; -+ int32_t imr_ifindex; -+}; -+ -+/* -+ * sys/stat.h -+ */ -+#if defined(__FreeBSD_version) && __FreeBSD_version < 900000 -+#define st_atim st_atimespec -+#define st_ctim st_ctimespec -+#define st_mtim st_mtimespec -+#define st_birthtim st_birthtimespec -+#endif -+ -+struct target_freebsd_stat { -+ uint32_t st_dev; /* inode's device */ -+ uint32_t st_ino; /* inode's number */ -+ int16_t st_mode; /* inode protection mode */ -+ int16_t st_nlink; /* number of hard links */ -+ uint32_t st_uid; /* user ID of the file's owner */ -+ uint32_t st_gid; /* group ID of the file's group */ -+ uint32_t st_rdev; /* device type */ -+ struct target_freebsd_timespec st_atim; /* time last accessed */ -+ struct target_freebsd_timespec st_mtim; /* time last data modification */ -+ struct target_freebsd_timespec st_ctim; /* time last file status change */ -+ int64_t st_size; /* file size, in bytes */ -+ int64_t st_blocks; /* blocks allocated for file */ -+ uint32_t st_blksize; /* optimal blocksize for I/O */ -+ uint32_t st_flags; /* user defined flags for file */ -+ __uint32_t st_gen; /* file generation number */ -+ __int32_t st_lspare; -+ struct target_freebsd_timespec st_birthtim; /* time of file creation */ -+ /* -+ * Explicitly pad st_birthtim to 16 bytes so that the size of -+ * struct stat is backwards compatible. We use bitfields instead -+ * of an array of chars so that this doesn't require a C99 compiler -+ * to compile if the size of the padding is 0. We use 2 bitfields -+ * to cover up to 64 bits on 32-bit machines. We assume that -+ * CHAR_BIT is 8... -+ */ -+ unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec)); -+ unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec)); -+} __packed; -+ -+/* struct nstat is the same as stat above but without the st_lspare field */ -+struct target_freebsd_nstat { -+ uint32_t st_dev; /* inode's device */ -+ uint32_t st_ino; /* inode's number */ -+ int16_t st_mode; /* inode protection mode */ -+ int16_t st_nlink; /* number of hard links */ -+ uint32_t st_uid; /* user ID of the file's owner */ -+ uint32_t st_gid; /* group ID of the file's group */ -+ uint32_t st_rdev; /* device type */ -+ struct target_freebsd_timespec st_atim; /* time last accessed */ -+ struct target_freebsd_timespec st_mtim; /* time last data modification */ -+ struct target_freebsd_timespec st_ctim; /* time last file status change */ -+ int64_t st_size; /* file size, in bytes */ -+ int64_t st_blocks; /* blocks allocated for file */ -+ uint32_t st_blksize; /* optimal blocksize for I/O */ -+ uint32_t st_flags; /* user defined flags for file */ -+ __uint32_t st_gen; /* file generation number */ -+ /* __int32_t st_lspare; */ -+ struct target_freebsd_timespec st_birthtim; /* time of file creation */ -+ /* -+ * Explicitly pad st_birthtim to 16 bytes so that the size of -+ * struct stat is backwards compatible. We use bitfields instead -+ * of an array of chars so that this doesn't require a C99 compiler -+ * to compile if the size of the padding is 0. We use 2 bitfields -+ * to cover up to 64 bits on 32-bit machines. We assume that -+ * CHAR_BIT is 8... -+ */ -+ unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec)); -+ unsigned int:(8 / 2) * (16 - (int)sizeof(struct target_freebsd_timespec)); -+} __packed; -+ -+/* -+ * sys/mount.h -+ */ -+ -+/* filesystem id type */ -+typedef struct target_freebsd_fsid { int32_t val[2]; } target_freebsd_fsid_t; -+ -+/* filesystem statistics */ -+#define TARGET_MFSNAMELEN 16 /* length of type name include null */ -+#define TARGET_MNAMELEN 88 /* size of on/from name bufs */ -+#define TARGET_STATFS_VERSION 0x20030518 /* current version number */ -+struct target_freebsd_statfs { -+ uint32_t f_version; /* structure version number */ -+ uint32_t f_type; /* type of filesystem */ -+ uint64_t f_flags; /* copy of mount exported flags */ -+ uint64_t f_bsize; /* filesystem fragment size */ -+ uint64_t f_iosize; /* optimal transfer block size */ -+ uint64_t f_blocks; /* total data blocks in filesystem */ -+ uint64_t f_bfree; /* free blocks in filesystem */ -+ int64_t f_bavail; /* free blocks avail to non-superuser */ -+ uint64_t f_files; /* total file nodes in filesystem */ -+ int64_t f_ffree; /* free nodes avail to non-superuser */ -+ uint64_t f_syncwrites; /* count of sync writes since mount */ -+ uint64_t f_asyncwrites; /* count of async writes since mount */ -+ uint64_t f_syncreads; /* count of sync reads since mount */ -+ uint64_t f_asyncreads; /* count of async reads since mount */ -+ uint64_t f_spare[10]; /* unused spare */ -+ uint32_t f_namemax; /* maximum filename length */ -+ uint32_t f_owner; /* user that mounted the filesystem */ -+ target_freebsd_fsid_t f_fsid; /* filesystem id */ -+ char f_charspare[80]; /* spare string space */ -+ char f_fstypename[TARGET_MFSNAMELEN]; /* filesys type name */ -+ char f_mntfromname[TARGET_MNAMELEN]; /* mount filesystem */ -+ char f_mntonname[TARGET_MNAMELEN]; /* dir on which mounted*/ -+}; -+ -+/* File identifier. These are unique per filesystem on a single machine. */ -+#define TARGET_MAXFIDSZ 16 -+ -+struct target_freebsd_fid { -+ u_short fid_len; /* len of data in bytes */ -+ u_short fid_data0; /* force longword align */ -+ char fid_data[TARGET_MAXFIDSZ]; /* data (variable len) */ -+}; -+ -+/* Generic file handle */ -+struct target_freebsd_fhandle { -+ target_freebsd_fsid_t fh_fsid; /* Filesystem id of mount point */ -+ struct target_freebsd_fid fh_fid; /* Filesys specific id */ -+}; -+typedef struct target_freebsd_fhandle target_freebsd_fhandle_t; -+ -+/* -+ * sys/fcntl.h -+ */ -+#define TARGET_F_DUPFD 0 -+#define TARGET_F_GETFD 1 -+#define TARGET_F_SETFD 2 -+#define TARGET_F_GETFL 3 -+#define TARGET_F_SETFL 4 -+#define TARGET_F_GETOWN 5 -+#define TARGET_F_SETOWN 6 -+#define TARGET_F_OGETLK 7 -+#define TARGET_F_OSETLK 8 -+#define TARGET_F_OSETLKW 9 -+#define TARGET_F_DUP2FD 10 -+#define TARGET_F_GETLK 11 -+#define TARGET_F_SETLK 12 -+#define TARGET_F_SETLKW 13 -+#define TARGET_F_SETLK_REMOTE 14 -+#define TARGET_F_READAHEAD 15 -+#define TARGET_F_RDAHEAD 16 -+#define TARGET_F_DUPFD_CLOEXEC 17 -+#define TARGET_F_DUP2FD_CLOEXEC 18 -+ -+struct target_freebsd_flock { -+ int64_t l_start; -+ int64_t l_len; -+ int32_t l_pid; -+ int16_t l_type; -+ int16_t l_whence; -+ int32_t l_sysid; -+} QEMU_PACKED; -+ -+/* -+ * FreeBSD thread and user mutex support. -+ */ -+ -+/* sys/thr.h */ -+#define TARGET_THR_SUSPENDED 0x0001 -+#define TARGET_THR_SYSTEM_SCOPE 0x0002 -+ -+struct target_freebsd_thr_param { -+ abi_ulong start_func; /* thread entry function. */ -+ abi_ulong arg; /* argument for entry function. */ -+ abi_ulong stack_base; /* stack base address. */ -+ abi_ulong stack_size; /* stack size. */ -+ abi_ulong tls_base; /* tls base address. */ -+ abi_ulong tls_size; /* tls size. */ -+ abi_ulong child_tid; /* address to store new TID. */ -+ abi_ulong parent_tid; /* parent access the new TID here. */ -+ int32_t flags; /* thread flags. */ -+ abi_ulong rtp; /* Real-time scheduling priority. */ -+ abi_ulong spare[3]; /* spares. */ -+}; -+ -+/* sys/rtprio.h */ -+struct target_freebsd_rtprio { -+ uint16_t type; -+ uint16_t prio; -+}; -+ -+typedef struct { -+ CPUArchState *env; -+ long parent_tid; -+ pthread_mutex_t mutex; -+ pthread_cond_t cond; -+ pthread_t thread; -+ sigset_t sigmask; -+ struct target_freebsd_thr_param param; -+} new_freebsd_thread_info_t; -+ -+/* sys/utmx.h */ -+/* op code for _umtx_op */ -+#define TARGET_UMTX_OP_LOCK 0 -+#define TARGET_UMTX_OP_UNLOCK 1 -+#define TARGET_UMTX_OP_WAIT 2 -+#define TARGET_UMTX_OP_WAKE 3 -+#define TARGET_UMTX_OP_MUTEX_TRYLOCK 4 -+#define TARGET_UMTX_OP_MUTEX_LOCK 5 -+#define TARGET_UMTX_OP_MUTEX_UNLOCK 6 -+#define TARGET_UMTX_OP_SET_CEILING 7 -+#define TARGET_UMTX_OP_CV_WAIT 8 -+#define TARGET_UMTX_OP_CV_SIGNAL 9 -+#define TARGET_UMTX_OP_CV_BROADCAST 10 -+#define TARGET_UMTX_OP_WAIT_UINT 11 -+#define TARGET_UMTX_OP_RW_RDLOCK 12 -+#define TARGET_UMTX_OP_RW_WRLOCK 13 -+#define TARGET_UMTX_OP_RW_UNLOCK 14 -+#define TARGET_UMTX_OP_WAIT_UINT_PRIVATE 15 -+#define TARGET_UMTX_OP_WAKE_PRIVATE 16 -+#define TARGET_UMTX_OP_MUTEX_WAIT 17 -+#define TARGET_UMTX_OP_MUTEX_WAKE 18 -+#define TARGET_UMTX_OP_SEM_WAIT 19 -+#define TARGET_UMTX_OP_SEM_WAKE 20 -+#define TARGET_UMTX_OP_NWAKE_PRIVATE 21 -+#define TARGET_UMTX_OP_MUTEX_WAKE2 22 -+#define TARGET_UMTX_OP_MAX 23 -+ -+/* flags for UMTX_OP_CV_WAIT */ -+#define TARGET_CVWAIT_CHECK_UNPARKING 0x01 -+#define TARGET_CVWAIT_ABSTIME 0x02 -+#define TARGET_CVWAIT_CLOCKID 0x04 -+ -+#define TARGET_UMTX_UNOWNED 0x0 -+#define TARGET_UMUTEX_UNOWNED 0x0 -+#define TARGET_UMTX_CONTESTED (abi_ulong)(-1) -+#define TARGET_UMUTEX_CONTESTED 0x80000000U -+ -+/* flags for umutex */ -+#define TARGET_UMUTEX_ERROR_CHECK 0x0002 /* Error-checking mutex */ -+#define TARGET_UMUTEX_PRIO_INHERIT 0x0004 /* Priority inherited mutex */ -+#define TARGET_UMUTEX_PRIO_PROTECT 0x0008 /* Priority protect mutex */ -+ -+#define TARGET_UMUTEX_TRY 1 -+#define TARGET_UMUTEX_WAIT 2 -+ -+/* urwlock flags */ -+#define TARGET_URWLOCK_PREFER_READER 0x0002 -+#define TARGET_URWLOCK_WRITE_OWNER 0x80000000U -+#define TARGET_URWLOCK_WRITE_WAITERS 0x40000000U -+#define TARGET_URWLOCK_READ_WAITERS 0x20000000U -+#define TARGET_URWLOCK_MAX_READERS 0x1fffffffU -+#define TARGET_URWLOCK_READER_COUNT(c) ((c) & TARGET_URWLOCK_MAX_READERS) -+ -+/* -+ * sys/acl.h -+ */ -+#define TARGET_FREEBSD_ACL_MAX_ENTRIES 254 -+ -+/* vaild acl_type_t arguments */ -+#define TARGET_FREEBSD_ACL_TYPE_ACCESS_OLD 0x00000000 -+#define TARGET_FREEBSD_ACL_TYPE_DEFAULT_OLD 0x00000001 -+#define TARGET_FREEBSD_ACL_TYPE_ACCESS 0x00000002 -+#define TARGET_FREEBSD_ACL_TYPE_DEFAULT 0x00000003 -+#define TARGET_FREEBSD_ACL_TYPE_NFS4 0x00000004 -+ -+struct target_freebsd_acl_entry { -+ uint32_t ae_tag; -+ uint32_t ae_id; -+ uint32_t ae_perm; -+ uint16_t ae_entry_type; -+ uint16_t ae_flags; -+}; -+ -+struct target_freebsd_acl { -+ uint32_t acl_maxcnt; -+ uint32_t acl_cnt; -+ int32_t acl_spare[4]; -+ struct target_freebsd_acl_entry acl_entry[TARGET_FREEBSD_ACL_MAX_ENTRIES]; -+}; -+ -+/* -+ * sys/uuid.h -+ */ -+ -+#define TARGET_UUID_NODE_LEN 6 -+ -+struct target_uuid { -+ uint32_t time_low; -+ uint16_t time_mid; -+ uint16_t time_hi_and_version; -+ uint8_t clock_seq_hi_and_reserved; -+ uint8_t clock_seq_low; -+ uint8_t node[TARGET_UUID_NODE_LEN]; -+}; -+ -+ -+/* -+ * from personality.h -+ */ -+ -+/* -+ * Flags for bug emulation. -+ * -+ * These occupy the top three bytes. -+ */ -+enum { -+ ADDR_NO_RANDOMIZE = 0x0040000, /* disable randomization of VA -+ space */ -+ FDPIC_FUNCPTRS = 0x0080000, /* userspace function ptrs -+ point to descriptors -+ (signal handling) */ -+ MMAP_PAGE_ZERO = 0x0100000, -+ ADDR_COMPAT_LAYOUT = 0x0200000, -+ READ_IMPLIES_EXEC = 0x0400000, -+ ADDR_LIMIT_32BIT = 0x0800000, -+ SHORT_INODE = 0x1000000, -+ WHOLE_SECONDS = 0x2000000, -+ STICKY_TIMEOUTS = 0x4000000, -+ ADDR_LIMIT_3GB = 0x8000000, -+}; -+ -+/* -+ * Personality types. -+ * -+ * These go in the low byte. Avoid using the top bit, it will -+ * conflict with error returns. -+ */ -+enum { -+ PER_LINUX = 0x0000, -+ PER_LINUX_32BIT = 0x0000 | ADDR_LIMIT_32BIT, -+ PER_LINUX_FDPIC = 0x0000 | FDPIC_FUNCPTRS, -+ PER_SVR4 = 0x0001 | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, -+ PER_SVR3 = 0x0002 | STICKY_TIMEOUTS | SHORT_INODE, -+ PER_SCOSVR3 = 0x0003 | STICKY_TIMEOUTS | -+ WHOLE_SECONDS | SHORT_INODE, -+ PER_OSR5 = 0x0003 | STICKY_TIMEOUTS | WHOLE_SECONDS, -+ PER_WYSEV386 = 0x0004 | STICKY_TIMEOUTS | SHORT_INODE, -+ PER_ISCR4 = 0x0005 | STICKY_TIMEOUTS, -+ PER_BSD = 0x0006, -+ PER_SUNOS = 0x0006 | STICKY_TIMEOUTS, -+ PER_XENIX = 0x0007 | STICKY_TIMEOUTS | SHORT_INODE, -+ PER_LINUX32 = 0x0008, -+ PER_LINUX32_3GB = 0x0008 | ADDR_LIMIT_3GB, -+ PER_IRIX32 = 0x0009 | STICKY_TIMEOUTS,/* IRIX5 32-bit */ -+ PER_IRIXN32 = 0x000a | STICKY_TIMEOUTS,/* IRIX6 new 32-bit */ -+ PER_IRIX64 = 0x000b | STICKY_TIMEOUTS,/* IRIX6 64-bit */ -+ PER_RISCOS = 0x000c, -+ PER_SOLARIS = 0x000d | STICKY_TIMEOUTS, -+ PER_UW7 = 0x000e | STICKY_TIMEOUTS | MMAP_PAGE_ZERO, -+ PER_OSF4 = 0x000f, /* OSF/1 v4 */ -+ PER_HPUX = 0x0010, -+ PER_MASK = 0x00ff, -+}; -+ -+/* -+ * Return the base personality without flags. -+ */ -+#define personality(pers) (pers & PER_MASK) -+ -+#endif /* ! _SYSCALL_DEFS_H_ */ -diff --git a/bsd-user/x86_64/syscall.h b/bsd-user/x86_64/syscall.h -index 630514a..4fff6a5 100644 ---- a/bsd-user/x86_64/syscall.h -+++ b/bsd-user/x86_64/syscall.h -@@ -1,3 +1,23 @@ -+/* -+ * x86_64 system call definitions -+ * -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, see <http://www.gnu.org/licenses/>. -+ */ -+#ifndef _X86_64_SYSCALL_H_ -+#define _X86_64_SYSCALL_H_ -+ - #define __USER_CS (0x33) - #define __USER_DS (0x2B) - -@@ -108,9 +128,13 @@ struct target_msqid64_ds { - #define TARGET_FREEBSD_AMD64_SET_GSBASE 131 - - --#define UNAME_MACHINE "x86_64" -+#define UNAME_MACHINE "x86_64" -+#define TARGET_HW_MACHINE "amd64" -+#define TARGET_HW_MACHINE_ARCH "amd64" - - #define TARGET_ARCH_SET_GS 0x1001 - #define TARGET_ARCH_SET_FS 0x1002 - #define TARGET_ARCH_GET_FS 0x1003 - #define TARGET_ARCH_GET_GS 0x1004 -+ -+#endif /* ! _X86_64_SYSCALL_H_ */ -diff --git a/bsd-user/x86_64/target_arch.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..9a66b67 ---- /dev/null -+++ b/bsd-user/x86_64/target_arch_cpu.h -@@ -0,0 +1,324 @@ -+/* -+ * 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; -+ -+ cpu_x86_set_cpl(env, 3); -+ -+ 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_elf.h b/bsd-user/x86_64/target_arch_elf.h -new file mode 100644 -index 0000000..bc7c6a1 ---- /dev/null -+++ b/bsd-user/x86_64/target_arch_elf.h -@@ -0,0 +1,55 @@ -+/* -+ * x86_64 ELF 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 _TARGET_ARCH_ELF_H_ -+#define _TARGET_ARCH_ELF_H_ -+ -+#define ELF_START_MMAP 0x2aaaaab000ULL -+#define elf_check_arch(x) ( ((x) == ELF_ARCH) ) -+ -+#define ELF_CLASS ELFCLASS64 -+#define ELF_DATA ELFDATA2LSB -+#define ELF_ARCH EM_X86_64 -+ -+#define USE_ELF_CORE_DUMP -+#define ELF_EXEC_PAGESIZE 4096 -+ -+/* XXX */ -+#ifndef __FreeBSD__ -+#define ELF_PLATFORM target_elf_get_platform() -+ -+static const char *target_elf_get_platform(void) -+{ -+ static char elf_platform[] = "i386"; -+ int family = (thread_env->cpuid_version >> 8) & 0xff; -+ if (family > 6) -+ family = 6; -+ if (family >= 3) -+ elf_platform[1] = '0' + family; -+ return elf_platform; -+} -+ -+#define ELF_HWCAP target_elf_get_hwcap() -+ -+static uint32_t target_elf_get_hwcap(void) -+{ -+ return thread_env->features[FEAT_1_EDX]; -+} -+#endif /* ! __FreeBSD__ */ -+ -+#endif /* _TARGET_ARCH_ELF_H_ */ -diff --git a/bsd-user/x86_64/target_arch_signal.h b/bsd-user/x86_64/target_arch_signal.h -new file mode 100644 -index 0000000..1998570 ---- /dev/null -+++ b/bsd-user/x86_64/target_arch_signal.h -@@ -0,0 +1,94 @@ -+/* -+ * x86_64 signal 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 _TARGET_ARCH_SIGNAL_H_ -+#define _TARGET_ARCH_SIGNAL_H_ -+ -+#include "cpu.h" -+ -+/* Size of the signal trampolin code placed on the stack. */ -+/* #define TARGET_SZSIGCODE (0) */ /* XXX to be added */ -+ -+/* compare to x86/include/_limits.h */ -+#define TARGET_MINSIGSTKSZ (512 * 4) /* min sig stack size */ -+#define TARGET_SIGSTKSZ (MINSIGSTKSZ + 32768) /* recommended size */ -+ -+#define TARGET_MC_GET_CLEAR_RET 0x0001 -+ -+struct target_sigcontext { -+ /* to be added */ -+}; -+ -+typedef struct target_mcontext { -+} target_mcontext_t; -+ -+typedef struct target_ucontext { -+ target_sigset_t uc_sigmask; -+ target_mcontext_t uc_mcontext; -+ abi_ulong uc_link; -+ target_stack_t uc_stack; -+ int32_t uc_flags; -+ int32_t __spare__[4]; -+} target_ucontext_t; -+ -+struct target_sigframe { -+ abi_ulong sf_signum; -+ abi_ulong sf_siginfo; /* code or pointer to sf_si */ -+ abi_ulong sf_ucontext; /* points to sf_uc */ -+ abi_ulong sf_addr; /* undocumented 4th arg */ -+ target_ucontext_t sf_uc; /* = *sf_uncontext */ -+ target_siginfo_t sf_si; /* = *sf_siginfo (SA_SIGINFO case)*/ -+ uint32_t __spare__[2]; -+}; -+ -+/* -+ * Compare to amd64/amd64/machdep.c sendsig() -+ * Assumes that target stack frame memory is locked. -+ */ -+static inline abi_long set_sigtramp_args(CPUX86State *regs, -+ int sig, struct target_sigframe *frame, abi_ulong frame_addr, -+ struct target_sigaction *ka) -+{ -+ /* XXX */ -+ return -TARGET_EOPNOTSUPP; -+} -+ -+/* Compare to amd64/amd64/machdep.c get_mcontext() */ -+static inline abi_long get_mcontext(CPUX86State *regs, -+ target_mcontext_t *mcp, int flags) -+{ -+ /* XXX */ -+ return -TARGET_EOPNOTSUPP; -+} -+ -+/* Compare to amd64/amd64/machdep.c set_mcontext() */ -+static inline abi_long set_mcontext(CPUX86State *regs, -+ target_mcontext_t *mcp, int srflag) -+{ -+ /* XXX */ -+ return -TARGET_EOPNOTSUPP; -+} -+ -+static inline abi_long get_ucontext_sigreturn(CPUX86State *regs, -+ abi_ulong target_sf, abi_ulong *target_uc) -+{ -+ /* XXX */ -+ *target_uc = 0; -+ return -TARGET_EOPNOTSUPP; -+} -+ -+#endif /* !TARGET_ARCH_SIGNAL_H_ */ -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_ */ -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_ */ -diff --git a/bsd-user/x86_64/target_arch_thread.h b/bsd-user/x86_64/target_arch_thread.h -new file mode 100644 -index 0000000..d105e43 ---- /dev/null -+++ b/bsd-user/x86_64/target_arch_thread.h -@@ -0,0 +1,40 @@ -+/* -+ * x86_64 thread support -+ * -+ * 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 _TARGET_ARCH_THREAD_H_ -+#define _TARGET_ARCH_THREAD_H_ -+ -+/* Compare to vm_machdep.c cpu_set_upcall_kse() */ -+static inline void target_thread_set_upcall(CPUX86State *regs, abi_ulong entry, -+ abi_ulong arg, abi_ulong stack_base, abi_ulong stack_size) -+{ -+ /* XXX */ -+} -+ -+static inline void target_thread_init(struct target_pt_regs *regs, -+ struct image_info *infop) -+{ -+ regs->rax = 0; -+ regs->rsp = infop->start_stack; -+ regs->rip = infop->entry; -+ if (bsd_type == target_freebsd) { -+ regs->rdi = infop->start_stack; -+ } -+} -+ -+#endif /* !_TARGET_ARCH_THREAD_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..5e13076 ---- /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 (0x0000800000000000UL) -+ -+#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 */ -diff --git a/configure b/configure -index aae617e..f0b4da7 100755 ---- a/configure -+++ b/configure -@@ -526,6 +526,9 @@ fi - - # OS specific - -+# host *BSD for user mode -+HOST_VARIANT_DIR="" -+ - case $targetos in - CYGWIN*) - mingw32="yes" -@@ -551,12 +554,14 @@ FreeBSD) - # needed for kinfo_getvmmap(3) in libutil.h - LIBS="-lutil $LIBS" - netmap="" # enable netmap autodetect -+ HOST_VARIANT_DIR="freebsd" - ;; - DragonFly) - bsd="yes" - make="${MAKE-gmake}" - audio_drv_list="oss" - audio_possible_drivers="oss sdl esd pa" -+ HOST_VARIANT_DIR="dragonfly" - ;; - NetBSD) - bsd="yes" -@@ -564,12 +569,14 @@ NetBSD) - audio_drv_list="oss" - audio_possible_drivers="oss sdl esd" - oss_lib="-lossaudio" -+ HOST_VARIANT_DIR="netbsd" - ;; - OpenBSD) - bsd="yes" - make="${MAKE-gmake}" - audio_drv_list="sdl" - audio_possible_drivers="sdl esd" -+ HOST_VARIANT_DIR="openbsd" - ;; - Darwin) - bsd="yes" -@@ -587,6 +594,7 @@ Darwin) - # Disable attempts to use ObjectiveC features in os/object.h since they - # won't work when we're compiling with gcc as a C compiler. - QEMU_CFLAGS="-DOS_OBJECT_USE_OBJC=0 $QEMU_CFLAGS" -+ HOST_VARIANT_DIR="darwin" - ;; - SunOS) - solaris="yes" -@@ -4894,6 +4902,9 @@ if [ "$TARGET_ABI_DIR" = "" ]; then - TARGET_ABI_DIR=$TARGET_ARCH - fi - echo "TARGET_ABI_DIR=$TARGET_ABI_DIR" >> $config_target_mak -+if [ "$HOST_VARIANT_DIR" != "" ]; then -+ echo "HOST_VARIANT_DIR=$HOST_VARIANT_DIR" >> $config_target_mak -+fi - case "$target_name" in - i386|x86_64) - if test "$xen" = "yes" -a "$target_softmmu" = "yes" ; then -diff --git a/default-configs/arm-bsd-user.mak b/default-configs/arm-bsd-user.mak -new file mode 100644 -index 0000000..869e6fb ---- /dev/null -+++ b/default-configs/arm-bsd-user.mak -@@ -0,0 +1,3 @@ -+# Default configuration for arm-bsd-user -+ -+CONFIG_GDBSTUB_XML=y -diff --git a/default-configs/mips-bsd-user.mak b/default-configs/mips-bsd-user.mak -new file mode 100644 -index 0000000..3fb129a ---- /dev/null -+++ b/default-configs/mips-bsd-user.mak -@@ -0,0 +1 @@ -+# Default configuration for mips-bsd-user -diff --git a/default-configs/mips64-bsd-user.mak b/default-configs/mips64-bsd-user.mak -new file mode 100644 -index 0000000..d4e72a6 ---- /dev/null -+++ b/default-configs/mips64-bsd-user.mak -@@ -0,0 +1 @@ -+# Default configuration for mips64-bsd-user -diff --git a/default-configs/mips64el-bsd-user.mak b/default-configs/mips64el-bsd-user.mak -new file mode 100644 -index 0000000..b879228 ---- /dev/null -+++ b/default-configs/mips64el-bsd-user.mak -@@ -0,0 +1 @@ -+# Default configuration for mips64el-bsd-user -diff --git a/default-configs/mipsel-bsd-user.mak b/default-configs/mipsel-bsd-user.mak -new file mode 100644 -index 0000000..312b9d5 ---- /dev/null -+++ b/default-configs/mipsel-bsd-user.mak -@@ -0,0 +1 @@ -+# Default configuration for mipsel-bsd-user -diff --git a/include/qemu/aes.h b/include/qemu/aes.h -index e79c707..6d253a3 100644 ---- a/include/qemu/aes.h -+++ b/include/qemu/aes.h -@@ -10,6 +10,15 @@ struct aes_key_st { - }; - typedef struct aes_key_st AES_KEY; - -+/* FreeBSD has it's own AES_set_decrypt_key in -lcrypto, avoid conflicts. */ -+#ifdef __FreeBSD__ -+#define AES_set_encrypt_key QEMU_AES_set_encrypt_key -+#define AES_set_decrypt_key QEMU_AES_set_decrypt_key -+#define AES_encrypt QEMU_AES_encrypt -+#define AES_decrypt QEMU_AES_decrypt -+#define AES_cbc_encrypt QEMU_AES_cbc_encrypt -+#endif -+ - int AES_set_encrypt_key(const unsigned char *userKey, const int bits, - AES_KEY *key); - int AES_set_decrypt_key(const unsigned char *userKey, const int bits, -diff --git a/include/qemu/tls.h b/include/qemu/tls.h -index b92ea9d..ae7d79d 100644 ---- a/include/qemu/tls.h -+++ b/include/qemu/tls.h -@@ -38,7 +38,7 @@ - * TODO: proper implementations via Win32 .tls sections and - * POSIX pthread_getspecific. - */ --#ifdef __linux__ -+#if defined(__linux__) || defined(__FreeBSD__) - #define DECLARE_TLS(type, x) extern DEFINE_TLS(type, x) - #define DEFINE_TLS(type, x) __thread __typeof__(type) tls__##x - #define tls_var(x) tls__##x diff --git a/emulators/qemu-devel/files/extra-patch-8267ad2cb92b106bb16e91234f04abc49ab32036 b/emulators/qemu-devel/files/extra-patch-8267ad2cb92b106bb16e91234f04abc49ab32036 deleted file mode 100644 index ea3a4b5143ba..000000000000 --- a/emulators/qemu-devel/files/extra-patch-8267ad2cb92b106bb16e91234f04abc49ab32036 +++ /dev/null @@ -1,33 +0,0 @@ -From 8267ad2cb92b106bb16e91234f04abc49ab32036 Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Wed, 26 Nov 2014 21:07:00 +0000 -Subject: [PATCH] Bug fix for hw.machine and hw.machine_arch sysctl's. - -For a NULL buffer sysctl needs to return just the length of the buffer. ---- - bsd-user/freebsd/os-sys.c | 8 ++++++-- - 1 file changed, 6 insertions(+), 2 deletions(-) - -diff --git a/bsd-user/freebsd/os-sys.c b/bsd-user/freebsd/os-sys.c -index 3ab4f8e..dbdc9ef 100644 ---- a/bsd-user/freebsd/os-sys.c -+++ b/bsd-user/freebsd/os-sys.c -@@ -336,12 +336,16 @@ abi_long do_freebsd_sysctl(CPUArchState *env, abi_ulong namep, int32_t namelen, - case CTL_HW: - switch (snamep[1]) { - case HW_MACHINE: -- strlcpy(holdp, TARGET_HW_MACHINE, oldlen); -+ holdlen = sizeof(TARGET_HW_MACHINE); -+ if (holdp) -+ strlcpy(holdp, TARGET_HW_MACHINE, oldlen); - ret = 0; - goto out; - - case HW_MACHINE_ARCH: -- strlcpy(holdp, TARGET_HW_MACHINE_ARCH, oldlen); -+ holdlen = sizeof(TARGET_HW_MACHINE_ARCH); -+ if (holdp) -+ strlcpy(holdp, TARGET_HW_MACHINE_ARCH, oldlen); - ret = 0; - goto out; - diff --git a/emulators/qemu-devel/files/extra-patch-93cf90cb04fee057a710be43614b033e6b2e86d1 b/emulators/qemu-devel/files/extra-patch-93cf90cb04fee057a710be43614b033e6b2e86d1 deleted file mode 100644 index da4f6ccd35f8..000000000000 --- a/emulators/qemu-devel/files/extra-patch-93cf90cb04fee057a710be43614b033e6b2e86d1 +++ /dev/null @@ -1,100 +0,0 @@ -From 93cf90cb04fee057a710be43614b033e6b2e86d1 Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Fri, 7 Nov 2014 05:35:17 +0000 -Subject: [PATCH] Add support for legacy system calls. - -This change adds support for some legacy system calls so qemu bsd -user-mode will still work on older versions of FreeBSD (i.e. 9.X). ---- - bsd-user/freebsd/make_syscall_nr_h.sh | 19 +++++++++++++++++++ - bsd-user/freebsd/strace.list | 11 +++++++++++ - bsd-user/freebsd/syscall_nr.h | 16 ++++++++++++++++ - 3 files changed, 46 insertions(+) - -diff --git a/bsd-user/freebsd/make_syscall_nr_h.sh b/bsd-user/freebsd/make_syscall_nr_h.sh -index cc180df..f73dfc9 100644 ---- a/bsd-user/freebsd/make_syscall_nr_h.sh -+++ b/bsd-user/freebsd/make_syscall_nr_h.sh -@@ -24,3 +24,22 @@ echo " */" >> $sysnr - echo "" >> $sysnr - - /usr/bin/sed -e 's:SYS_:TARGET_FREEBSD_NR_:' < $syshdr >> $sysnr -+ -+cat << _EOF >> $sysnr -+/* Legacy system calls. */ -+#ifndef TARGET_FREEBSD_NR_killpg -+#define TARGET_FREEBSD_NR_killpg 146 -+#endif -+#ifndef TARGET_FREEBSD_NR__umtx_lock -+#define TARGET_FREEBSD_NR__umtx_lock 434 -+#endif -+#ifndef TARGET_FREEBSD_NR__umtx_unlock -+#define TARGET_FREEBSD_NR__umtx_unlock 435 -+#endif -+#ifndef TARGET_FREEBSD_NR_cap_new -+#define TARGET_FREEBSD_NR_cap_new 514 -+#endif -+#ifndef TARGET_FREEBSD_NR_cap_getrights -+#define TARGET_FREEBSD_NR_cap_getrights 515 -+#endif -+_EOF -diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list -index e09048f..6202790 100644 ---- a/bsd-user/freebsd/strace.list -+++ b/bsd-user/freebsd/strace.list -@@ -33,6 +33,10 @@ - { TARGET_FREEBSD_NR___syscall, "__syscall", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, print_sysctl, NULL }, - { TARGET_FREEBSD_NR__umtx_op, "_umtx_op", "%s(%#x, %d, %d, %#x, %#x)", NULL, NULL }, -+#if defined(__FreeBSD_version) && __FreeBSD_version < 1000000 -+{ TARGET_FREEBSD_NR__umtx_lock, "__umtx_lock", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR__umtx_unlock, "__umtx_unlock", NULL, NULL, NULL }, -+#endif - { TARGET_FREEBSD_NR_accept, "accept", "%s(%d,%#x,%#x)", NULL, NULL }, - { TARGET_FREEBSD_NR_accept4, "accept4", "%s(%d,%d,%#x,%#x)", NULL, NULL }, - { TARGET_FREEBSD_NR_access, "access", "%s(\"%s\",%#o)", NULL, NULL }, -@@ -45,6 +49,10 @@ - { TARGET_FREEBSD_NR_cap_fcntls_get, "cap_fcntls_get", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_cap_fcntls_limit, "cap_fcntls_limit", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_cap_getmode, "cap_getmode", NULL, NULL, NULL }, -+#if defined(__FreeBSD_version) && __FreeBSD_version < 1000000 -+{ TARGET_FREEBSD_NR_cap_getrights, "cap_getrights", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_cap_new, "cap_new", NULL, NULL, NULL }, -+#endif - { TARGET_FREEBSD_NR_cap_ioctls_get, "cap_ioctls_get", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_cap_ioctls_limit, "cap_ioctls_limit", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_cap_rights_limit, "cap_rights_limit", NULL, NULL, NULL }, -@@ -126,6 +134,9 @@ - { TARGET_FREEBSD_NR_issetugid, "issetugid", "%s()", NULL, NULL }, - { TARGET_FREEBSD_NR_kevent, "kevent", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_kill, "kill", NULL, NULL, NULL }, -+#if defined(__FreeBSD_version) && __FreeBSD_version < 1000000 -+{ TARGET_FREEBSD_NR_killpg, "killpg", NULL, NULL, NULL }, -+#endif - { TARGET_FREEBSD_NR_kqueue, "kqueue", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_ktrace, "ktrace", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_lchown, "lchown", NULL, NULL, NULL }, -diff --git a/bsd-user/freebsd/syscall_nr.h b/bsd-user/freebsd/syscall_nr.h -index 74c3135..dd3cb4f 100644 ---- a/bsd-user/freebsd/syscall_nr.h -+++ b/bsd-user/freebsd/syscall_nr.h -@@ -467,3 +467,19 @@ - #define TARGET_FREEBSD_NR_aio_mlock 543 - #define TARGET_FREEBSD_NR_procctl 544 - #define TARGET_FREEBSD_NR_MAXSYSCALL 545 -+/* Legacy system calls. */ -+#ifndef TARGET_FREEBSD_NR_killpg -+#define TARGET_FREEBSD_NR_killpg 146 -+#endif -+#ifndef TARGET_FREEBSD_NR__umtx_lock -+#define TARGET_FREEBSD_NR__umtx_lock 434 -+#endif -+#ifndef TARGET_FREEBSD_NR__umtx_unlock -+#define TARGET_FREEBSD_NR__umtx_unlock 435 -+#endif -+#ifndef TARGET_FREEBSD_NR_cap_new -+#define TARGET_FREEBSD_NR_cap_new 514 -+#endif -+#ifndef TARGET_FREEBSD_NR_cap_getrights -+#define TARGET_FREEBSD_NR_cap_getrights 515 -+#endif diff --git a/emulators/qemu-devel/files/extra-patch-9ac2c49c734a49025fe1647ce84728d3988ea5d2 b/emulators/qemu-devel/files/extra-patch-9ac2c49c734a49025fe1647ce84728d3988ea5d2 deleted file mode 100644 index 048a3ede5414..000000000000 --- a/emulators/qemu-devel/files/extra-patch-9ac2c49c734a49025fe1647ce84728d3988ea5d2 +++ /dev/null @@ -1,14 +0,0 @@ -diff --git a/bsd-user/freebsd/os-sys.c b/bsd-user/freebsd/os-sys.c -index c8f999f..2578645 100644 ---- a/bsd-user/freebsd/os-sys.c -+++ b/bsd-user/freebsd/os-sys.c -@@ -130,7 +130,8 @@ abi_long do_freebsd_sysctl(CPUArchState *env, abi_ulong namep, int32_t namelen, - abi_ulong oldlen = 0; - int32_t *snamep = g_malloc(sizeof(int32_t) * namelen), *p, *q, i; - uint32_t kind = 0; -- TaskState *ts = (TaskState *)env->opaque; -+ CPUState *cpu = ENV_GET_CPU(env); -+ TaskState *ts = cpu->opaque; - - if (oldlenp) { - if (get_user_ual(oldlen, oldlenp)) { diff --git a/emulators/qemu-devel/files/extra-patch-9ed0e07e2e07791858339874eb4d20daca858c8a b/emulators/qemu-devel/files/extra-patch-9ed0e07e2e07791858339874eb4d20daca858c8a deleted file mode 100644 index f2561fe3ff4e..000000000000 --- a/emulators/qemu-devel/files/extra-patch-9ed0e07e2e07791858339874eb4d20daca858c8a +++ /dev/null @@ -1,77 +0,0 @@ -From 9ed0e07e2e07791858339874eb4d20daca858c8a Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Fri, 7 Nov 2014 22:17:58 +0000 -Subject: [PATCH] Fix typo and some other build issues. - ---- - bsd-user/bsd-proc.c | 5 +++-- - bsd-user/freebsd/os-proc.c | 4 ++++ - bsd-user/freebsd/os-proc.h | 1 + - 3 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/bsd-user/bsd-proc.c b/bsd-user/bsd-proc.c -index 503e928..248bcfb 100644 ---- a/bsd-user/bsd-proc.c -+++ b/bsd-user/bsd-proc.c -@@ -17,6 +17,7 @@ - * along with this program; if not, see <http://www.gnu.org/licenses/>. - */ - -+#include <sys/param.h> - #include <sys/types.h> - #include <sys/resource.h> - #include <sys/wait.h> -@@ -147,7 +148,7 @@ abi_long host_to_target_rusage(abi_ulong target_addr, - return 0; - } - --:#if defined(__FreeBSD_version) && __FreeBSD_version >= 1000000 -+#if defined(__FreeBSD_version) && __FreeBSD_version >= 1000000 - abi_long host_to_target_wrusage(abi_ulong target_addr, - const struct __wrusage *wrusage) - { -@@ -162,7 +163,7 @@ abi_long host_to_target_wrusage(abi_ulong target_addr, - - return 0; - } --#endif /* ! __FreeBSD_version >= 1000000 */ -+#endif /* __FreeBSD_version >= 1000000 */ - - /* - * wait status conversion. -diff --git a/bsd-user/freebsd/os-proc.c b/bsd-user/freebsd/os-proc.c -index b185439..fd0b64f 100644 ---- a/bsd-user/freebsd/os-proc.c -+++ b/bsd-user/freebsd/os-proc.c -@@ -234,7 +234,9 @@ abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, - } - - if (do_fexec) { -+#if defined(__FreeBSD_version) && __FreeBSD_version < 1100000 - char execpath[PATH_MAX], *scriptargs; -+#endif /* __FreeBSD_version < 1100000 */ - - if (((int)path_or_fd > 0 && - is_target_elf_binary((int)path_or_fd)) == 1) { -@@ -291,7 +293,9 @@ abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, - } - } else { - int fd; -+#if defined(__FreeBSD_version) && __FreeBSD_version < 1100000 - char execpath[PATH_MAX], *scriptargs; -+#endif - - p = lock_user_string(path_or_fd); - if (p == NULL) { -diff --git a/bsd-user/freebsd/os-proc.h b/bsd-user/freebsd/os-proc.h -index 193e1fc..487aef3 100644 ---- a/bsd-user/freebsd/os-proc.h -+++ b/bsd-user/freebsd/os-proc.h -@@ -20,6 +20,7 @@ - #ifndef __FREEBSD_PROC_H_ - #define __FREEBSD_PROC_H_ - -+#include <sys/param.h> - #if defined(__FreeBSD_version) && __FreeBSD_version >= 1000000 - #include <sys/procctl.h> - #include <sys/signal.h> diff --git a/emulators/qemu-devel/files/extra-patch-a3129eea10f188bfd39ce83b18b25dcefbc5bffc b/emulators/qemu-devel/files/extra-patch-a3129eea10f188bfd39ce83b18b25dcefbc5bffc deleted file mode 100644 index 11056d010961..000000000000 --- a/emulators/qemu-devel/files/extra-patch-a3129eea10f188bfd39ce83b18b25dcefbc5bffc +++ /dev/null @@ -1,53 +0,0 @@ -diff --git a/bsd-user/signal.c b/bsd-user/signal.c -index 3619b00..01374a6 100644 ---- a/bsd-user/signal.c -+++ b/bsd-user/signal.c -@@ -283,7 +283,8 @@ static int core_dump_signal(int sig) - /* Signal queue handling. */ - static inline struct qemu_sigqueue *alloc_sigqueue(CPUArchState *env) - { -- TaskState *ts = env->opaque; -+ CPUState *cpu = thread_cpu; -+ TaskState *ts = (TaskState *)cpu->opaque; - struct qemu_sigqueue *q = ts->first_free; - - if (!q) { -@@ -296,7 +297,8 @@ static inline struct qemu_sigqueue *alloc_sigqueue(CPUArchState *env) - static inline void free_sigqueue(CPUArchState *env, struct qemu_sigqueue *q) - { - -- TaskState *ts = env->opaque; -+ CPUState *cpu = thread_cpu; -+ TaskState *ts = (TaskState *)cpu->opaque; - q->next = ts->first_free; - ts->first_free = q; - } -@@ -305,7 +307,8 @@ static inline void free_sigqueue(CPUArchState *env, struct qemu_sigqueue *q) - void QEMU_NORETURN force_sig(int target_sig) - { - CPUArchState *env = thread_cpu->env_ptr; -- TaskState *ts = (TaskState *)env->opaque; -+ CPUState *cpu = thread_cpu; -+ TaskState *ts = (TaskState *)cpu->opaque; - int core_dumped = 0; - int host_sig; - struct sigaction act; -@@ -365,7 +368,8 @@ void QEMU_NORETURN force_sig(int target_sig) - */ - int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info) - { -- TaskState *ts = env->opaque; -+ CPUState *cpu = thread_cpu; -+ TaskState *ts = (TaskState *)cpu->opaque; - struct emulated_sigtable *k; - struct qemu_sigqueue *q, **pq; - abi_ulong handler; -@@ -826,7 +830,7 @@ void process_pending_signals(CPUArchState *cpu_env) - struct emulated_sigtable *k; - struct target_sigaction *sa; - struct qemu_sigqueue *q; -- TaskState *ts = cpu_env->opaque; -+ TaskState *ts = cpu->opaque; - - if (!ts->signal_pending) { - return; diff --git a/emulators/qemu-devel/files/extra-patch-a6402a4b7077af85733a1c98d63ab09f02d980ec b/emulators/qemu-devel/files/extra-patch-a6402a4b7077af85733a1c98d63ab09f02d980ec deleted file mode 100644 index 372aabe74f55..000000000000 --- a/emulators/qemu-devel/files/extra-patch-a6402a4b7077af85733a1c98d63ab09f02d980ec +++ /dev/null @@ -1,173 +0,0 @@ -From a6402a4b7077af85733a1c98d63ab09f02d980ec Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Wed, 5 Nov 2014 22:35:23 +0000 -Subject: [PATCH] Add stubs for the new aio_*() system calls. - -This change adds stubs for the asynchronous I/O system calls including: -aio_cancel(2), aio_error(2), aio_return(2), aio_read(2), aio_write(2), -aio_syspend(2), aio_waitcomplete(2), aio_fsync(2), and aio_mlock(2). ---- - bsd-user/freebsd/os-file.h | 78 +++++++++++++++++++++++++++++++++++++++++++ - bsd-user/freebsd/syscall_nr.h | 4 ++- - bsd-user/syscall.c | 43 ++++++++++++++++++++++++ - 3 files changed, 124 insertions(+), 1 deletion(-) - -diff --git a/bsd-user/freebsd/os-file.h b/bsd-user/freebsd/os-file.h -index 2c6bc24..0b3e8c5 100644 ---- a/bsd-user/freebsd/os-file.h -+++ b/bsd-user/freebsd/os-file.h -@@ -21,10 +21,88 @@ - #define __FREEBSD_OS_FILE_H_ - - #include <sys/stat.h> -+#include <aio.h> - #include <unistd.h> - - #include "qemu-os.h" - -+/* -+ * Asynchronous I/O. -+ */ -+ -+/* aio_read(2) */ -+static abi_long do_freebsd_aio_read(__unused abi_ulong iocb) -+{ -+ qemu_log("qemu: Unsupported syscall aio_read()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* aio_write(2) */ -+static abi_long do_freebsd_aio_write(__unused abi_ulong iocb) -+{ -+ qemu_log("qemu: Unsupported syscall aio_write()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* aio_suspend(2) */ -+static abi_long do_freebsd_aio_suspend(__unused abi_ulong iocbs, -+ __unused int niocb, __unused abi_ulong timeout) -+{ -+ qemu_log("qemu: Unsupported syscall aio_suspend()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* aio_cancel(2) */ -+static abi_long do_freebsd_aio_cancel(__unused int fildes, -+ __unused abi_ulong iocb) -+{ -+ qemu_log("qemu: Unsupported syscall aio_cancel()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* aio_error(2) */ -+static abi_long do_freebsd_aio_error(__unused abi_ulong iocb) -+{ -+ qemu_log("qemu: Unsupported syscall aio_error()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* oaio_read(2) */ -+static abi_long do_freebsd_oaio_read(__unused abi_ulong iocb) -+{ -+ qemu_log("qemu: Unsupported syscall oaio_read()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* oaio_write(2) */ -+static abi_long do_freebsd_oaio_write(__unused abi_ulong iocb) -+{ -+ qemu_log("qemu: Unsupported syscall oaio_write()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* aio_waitcomplete(2) */ -+static abi_long do_freebsd_aio_waitcomplete(__unused abi_ulong iocbp, -+ __unused abi_ulong timeout) -+{ -+ qemu_log("qemu: Unsupported syscall aio_waitcomplete()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* aio_fsync(2) */ -+static abi_long do_freebsd_aio_fsync(__unused int op, -+ __unused abi_ulong iocb) -+{ -+ qemu_log("qemu: Unsupported syscall aio_fsync()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* aio_mlock(2) */ -+static abi_long do_freebsd_aio_mlock(__unused abi_ulong iocb) -+{ -+ qemu_log("qemu: Unsupported syscall aio_mlock()\n"); -+ return -TARGET_ENOSYS; -+} - - #if defined(__FreeBSD_version) && __FreeBSD_version >= 1000000 - /* pipe2(2) */ -diff --git a/bsd-user/freebsd/syscall_nr.h b/bsd-user/freebsd/syscall_nr.h -index b44545b..7d6bef8 100644 ---- a/bsd-user/freebsd/syscall_nr.h -+++ b/bsd-user/freebsd/syscall_nr.h -@@ -458,4 +458,6 @@ - #define TARGET_FREEBSD_NR_chflagsat 540 - #define TARGET_FREEBSD_NR_accept4 541 - #define TARGET_FREEBSD_NR_pipe2 542 --#define TARGET_FREEBSD_NR_MAXSYSCALL 543 -+#define TARGET_FREEBSD_NR_aio_mlock 543 -+#define TARGET_FREEBSD_NR_procctl 544 -+#define TARGET_FREEBSD_NR_MAXSYSCALL 545 -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 0a2ab88..30dc2f3 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -1582,6 +1582,49 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - ret = do_obreak(arg1); - break; - -+ /* -+ * Asynchronous I/O -+ */ -+ case TARGET_FREEBSD_NR_aio_read: /* aio_read(2) */ -+ ret = do_freebsd_aio_read(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_aio_write: /* aio_write(2) */ -+ ret = do_freebsd_aio_write(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_aio_suspend: /* aio_suspend(2) */ -+ ret = do_freebsd_aio_suspend(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_aio_cancel: /* aio_cancel(2) */ -+ ret = do_freebsd_aio_cancel(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_aio_error: /* aio_error(2) */ -+ ret = do_freebsd_aio_error(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_oaio_read: /* oaio_read(2) */ -+ ret = do_freebsd_oaio_read(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_oaio_write: /* oaio_write(2) */ -+ ret = do_freebsd_oaio_write(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_aio_waitcomplete: /* aio_waitcomplete(2) */ -+ ret = do_freebsd_aio_waitcomplete(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_aio_fsync: /* aio_fsync(2) */ -+ ret = do_freebsd_aio_fsync(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_aio_mlock: /* aio_mlock(2) */ -+ ret = do_freebsd_aio_mlock(arg1); -+ break; -+ - default: - ret = get_errno(syscall(num, arg1, arg2, arg3, arg4, arg5, arg6, arg7, - arg8)); diff --git a/emulators/qemu-devel/files/extra-patch-a72c668c8ab84c24372ff664d9b853c2a42d37b1 b/emulators/qemu-devel/files/extra-patch-a72c668c8ab84c24372ff664d9b853c2a42d37b1 deleted file mode 100644 index d3c58a53e914..000000000000 --- a/emulators/qemu-devel/files/extra-patch-a72c668c8ab84c24372ff664d9b853c2a42d37b1 +++ /dev/null @@ -1,91 +0,0 @@ -From a72c668c8ab84c24372ff664d9b853c2a42d37b1 Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Mon, 1 Dec 2014 22:06:58 +0000 -Subject: [PATCH] Fix the pipe(2) and pipe2(2) so the file descriptors are - returned correctly. - -The pipe(2) system call returns the file descriptors in registers. The -pipe2(2) system call copies out the file descriptors. They are not the -same. ---- - bsd-user/bsd-file.h | 13 ++++++++----- - bsd-user/freebsd/os-file.h | 27 ++++++++++++++------------- - 2 files changed, 22 insertions(+), 18 deletions(-) - -diff --git a/bsd-user/bsd-file.h b/bsd-user/bsd-file.h -index defa8bb..02698a3 100644 ---- a/bsd-user/bsd-file.h -+++ b/bsd-user/bsd-file.h -@@ -1009,7 +1009,7 @@ static abi_long do_bsd_lseek(void *cpu_env, abi_long arg1, abi_long arg2, - ret = ((res >> 32) & 0xFFFFFFFF); - set_second_rval(cpu_env, res & 0xFFFFFFFF); - #else -- ret = res & 0xFFFFFFFF; -+ ret = res & 0xFFFFFFFF; - set_second_rval(cpu_env, (res >> 32) & 0xFFFFFFFF); - #endif - } -@@ -1027,12 +1027,15 @@ static abi_long do_bsd_pipe(void *cpu_env, abi_ulong pipedes) - int host_ret = pipe(host_pipe); - - if (host_ret != -1) { -+ /* XXX pipe(2), unlike pipe2(), returns the second FD in a register. */ - set_second_rval(cpu_env, host_pipe[1]); - ret = host_pipe[0]; -- if (put_user_s32(host_pipe[0], pipedes) || -- put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0]))) { -- return -TARGET_EFAULT; -- } -+ /* XXX Not needed for pipe(): -+ if (put_user_s32(host_pipe[0], pipedes) || -+ put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0]))) { -+ return -TARGET_EFAULT; -+ } -+ */ - } else { - ret = get_errno(host_ret); - } -diff --git a/bsd-user/freebsd/os-file.h b/bsd-user/freebsd/os-file.h -index 0b3e8c5..bd94c84 100644 ---- a/bsd-user/freebsd/os-file.h -+++ b/bsd-user/freebsd/os-file.h -@@ -108,25 +108,26 @@ static abi_long do_freebsd_aio_mlock(__unused abi_ulong iocb) - /* pipe2(2) */ - static abi_long do_bsd_pipe2(void *cpu_env, abi_ulong pipedes, int flags) - { -- abi_long ret; - int host_pipe[2]; -- int host_ret = pipe2(host_pipe, flags); -+ int host_ret = pipe2(host_pipe, flags); /* XXXss - flags should be -+ translated from target to host. */ - - if (is_error(host_ret)) { -- return get_errno(host_ret); -+ return get_errno(host_ret); - } -- if (host_ret != -1) { -- set_second_rval(cpu_env, host_pipe[1]); -- ret = host_pipe[0]; -+ /* -+ * XXX pipe2() returns it's second FD by copying it back to -+ * userspace and not in a second register like pipe(2): -+ * set_second_rval(cpu_env, host_pipe[1]); -+ * -+ * Copy the FD's back to userspace: -+ */ - if (put_user_s32(host_pipe[0], pipedes) || -- put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0]))) { -- return -TARGET_EFAULT; -+ put_user_s32(host_pipe[1], pipedes + sizeof(host_pipe[0]))) { -+ return -TARGET_EFAULT; - } -- } else { -- ret = get_errno(host_ret); -- } -- return ret; --} -+ return 0; -+} - - /* chflagsat(2) */ - static inline abi_long do_bsd_chflagsat(int fd, abi_ulong path, diff --git a/emulators/qemu-devel/files/extra-patch-a8dc4de7f73bc6f8363c0fc81c4c6e53733c444b b/emulators/qemu-devel/files/extra-patch-a8dc4de7f73bc6f8363c0fc81c4c6e53733c444b deleted file mode 100644 index 322dc7e823fe..000000000000 --- a/emulators/qemu-devel/files/extra-patch-a8dc4de7f73bc6f8363c0fc81c4c6e53733c444b +++ /dev/null @@ -1,108 +0,0 @@ -From a8dc4de7f73bc6f8363c0fc81c4c6e53733c444b Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Fri, 7 Nov 2014 22:24:56 +0000 -Subject: [PATCH] Make bindat(2), connectat(2) and accept4(2) syscall handlers - consistent. - -The stubs for bindat(2) and connectat(2) didn't have the correct number of -arguments. Also, since bindat, connectat and accept4 are freebsd-only -system calls the handlers should be do_freebsd_* instead of do_bsd_*. ---- - bsd-user/freebsd/os-socket.h | 18 ++++++++++-------- - bsd-user/syscall.c | 6 +++--- - 2 files changed, 13 insertions(+), 11 deletions(-) - -diff --git a/bsd-user/freebsd/os-socket.h b/bsd-user/freebsd/os-socket.h -index 4212f0a..31bd1b3 100644 ---- a/bsd-user/freebsd/os-socket.h -+++ b/bsd-user/freebsd/os-socket.h -@@ -559,8 +559,8 @@ static inline abi_long do_freebsd_sendfile(abi_long fd, abi_long s, - - #if defined(__FreeBSD_version) && __FreeBSD_version >= 1000000 - /* bindat(2) */ --static inline abi_long do_bsd_bindat(int fd, int sockfd, abi_ulong target_addr, -- socklen_t addrlen) -+static inline abi_long do_freebsd_bindat(int fd, int sockfd, -+ abi_ulong target_addr, socklen_t addrlen) - { - abi_long ret; - void *addr; -@@ -579,7 +579,7 @@ static inline abi_long do_bsd_bindat(int fd, int sockfd, abi_ulong target_addr, - } - - /* connectat(2) */ --static inline abi_long do_bsd_connectat(int fd, int sockfd, -+static inline abi_long do_freebsd_connectat(int fd, int sockfd, - abi_ulong target_addr, socklen_t addrlen) - { - abi_long ret; -@@ -600,7 +600,7 @@ static inline abi_long do_bsd_connectat(int fd, int sockfd, - } - - /* accept4(2) */ --static inline abi_long do_bsd_accept4(int fd, abi_ulong target_addr, -+static inline abi_long do_freebsd_accept4(int fd, abi_ulong target_addr, - abi_ulong target_addrlen_addr, int flags) - { - socklen_t addrlen; -@@ -635,7 +635,7 @@ static inline abi_long do_bsd_accept4(int fd, abi_ulong target_addr, - #else /* ! __FreeBSD_version >= 1000000 */ - - /* bindat(2) */ --static inline abi_long do_bsd_bindat(__unused int sockfd, -+static inline abi_long do_freebsd_bindat(__unused int fd, __unused int sockfd, - __unused abi_ulong target_addr, __unused socklen_t addrlen) - { - -@@ -644,15 +644,17 @@ static inline abi_long do_bsd_bindat(__unused int sockfd, - } - - /* connectat(2) */ --static inline abi_long do_bsd_connectat(__unused int sockfd, -- __unused abi_ulong target_addr, __unused socklen_t addrlen) -+static inline abi_long do_freebsd_connectat(__unused int fd, -+ __unused int sockfd, __unused abi_ulong target_addr, -+ __unused socklen_t addrlen) - { - - qemu_log("qemu: Unsupported syscall connectat()\n"); - return -TARGET_ENOSYS; - } - --static inline abi_long do_bsd_accept4(__unused int fd, -+/* accept4(2) */ -+static inline abi_long do_freebsd_accept4(__unused int fd, - __unused abi_ulong target_addr, __unused abi_ulong target_addrlen_addr, - __unused int flags) - { -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 4a743e8..243eb13 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -1072,7 +1072,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - break; - - case TARGET_FREEBSD_NR_accept4: /* accept4(2) */ -- ret = do_bsd_accept4(arg1, arg2, arg3, arg4); -+ ret = do_freebsd_accept4(arg1, arg2, arg3, arg4); - break; - - case TARGET_FREEBSD_NR_bind: /* bind(2) */ -@@ -1080,7 +1080,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - break; - - case TARGET_FREEBSD_NR_bindat: /* bindat(2) */ -- ret = do_bsd_bindat(arg1, arg2, arg3, arg4); -+ ret = do_freebsd_bindat(arg1, arg2, arg3, arg4); - break; - - case TARGET_FREEBSD_NR_connect: /* connect(2) */ -@@ -1088,7 +1088,7 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - break; - - case TARGET_FREEBSD_NR_connectat: /* connectat(2) */ -- ret = do_bsd_connectat(arg1, arg2, arg3, arg4); -+ ret = do_freebsd_connectat(arg1, arg2, arg3, arg4); - break; - - case TARGET_FREEBSD_NR_getpeername: /* getpeername(2) */ diff --git a/emulators/qemu-devel/files/extra-patch-ac9f83019a2059d4bfe5cedfae35ba4151d5ac88 b/emulators/qemu-devel/files/extra-patch-ac9f83019a2059d4bfe5cedfae35ba4151d5ac88 deleted file mode 100644 index 20be77475efa..000000000000 --- a/emulators/qemu-devel/files/extra-patch-ac9f83019a2059d4bfe5cedfae35ba4151d5ac88 +++ /dev/null @@ -1,226 +0,0 @@ -From ac9f83019a2059d4bfe5cedfae35ba4151d5ac88 Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Tue, 4 Nov 2014 21:34:25 +0000 -Subject: [PATCH] Add support for the wait6(2) system call. - ---- - bsd-user/bsd-proc.c | 37 ++++++++++++++++++++++------- - bsd-user/freebsd/os-proc.h | 55 ++++++++++++++++++++++++++++++++++++++++++- - bsd-user/freebsd/syscall_nr.h | 3 ++- - bsd-user/qemu-bsd.h | 2 ++ - bsd-user/syscall.c | 6 ++++- - bsd-user/syscall_defs.h | 5 ++++ - 6 files changed, 97 insertions(+), 11 deletions(-) - -diff --git a/bsd-user/bsd-proc.c b/bsd-user/bsd-proc.c -index a4bcdc8..7f0b21c 100644 ---- a/bsd-user/bsd-proc.c -+++ b/bsd-user/bsd-proc.c -@@ -1,7 +1,7 @@ - /* - * BSD process related system call helpers - * -- * Copyright (c) 2013 Stacey D. Son -+ * Copyright (c) 2013-14 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 -@@ -108,14 +108,9 @@ abi_ulong host_to_target_rlim(rlim_t rlim) - return result; - } - --abi_long host_to_target_rusage(abi_ulong target_addr, -- const struct rusage *rusage) -+static void h2t_rusage(const struct rusage *rusage, -+ struct target_freebsd_rusage *target_rusage) - { -- struct target_freebsd_rusage *target_rusage; -- -- if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0)) { -- return -TARGET_EFAULT; -- } - __put_user(rusage->ru_utime.tv_sec, &target_rusage->ru_utime.tv_sec); - __put_user(rusage->ru_utime.tv_usec, &target_rusage->ru_utime.tv_usec); - -@@ -136,11 +131,37 @@ abi_long host_to_target_rusage(abi_ulong target_addr, - __put_user(rusage->ru_nsignals, &target_rusage->ru_nsignals); - __put_user(rusage->ru_nvcsw, &target_rusage->ru_nvcsw); - __put_user(rusage->ru_nivcsw, &target_rusage->ru_nivcsw); -+} -+ -+abi_long host_to_target_rusage(abi_ulong target_addr, -+ const struct rusage *rusage) -+{ -+ struct target_freebsd_rusage *target_rusage; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_rusage, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ h2t_rusage(rusage, target_rusage); - unlock_user_struct(target_rusage, target_addr, 1); - - return 0; - } - -+abi_long host_to_target_wrusage(abi_ulong target_addr, -+ const struct __wrusage *wrusage) -+{ -+ struct target_freebsd__wrusage *target_wrusage; -+ -+ if (!lock_user_struct(VERIFY_WRITE, target_wrusage, target_addr, 0)) { -+ return -TARGET_EFAULT; -+ } -+ h2t_rusage(&wrusage->wru_self, &target_wrusage->wru_self); -+ h2t_rusage(&wrusage->wru_children, &target_wrusage->wru_children); -+ unlock_user_struct(target_wrusage, target_addr, 1); -+ -+ return 0; -+} -+ - /* - * wait status conversion. - * -diff --git a/bsd-user/freebsd/os-proc.h b/bsd-user/freebsd/os-proc.h -index b31f7c4..8e28f04 100644 ---- a/bsd-user/freebsd/os-proc.h -+++ b/bsd-user/freebsd/os-proc.h -@@ -1,7 +1,7 @@ - /* - * process related system call shims and definitions - * -- * Copyright (c) 2013 Stacey D. Son -+ * Copyright (c) 2013-14 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 -@@ -20,6 +20,9 @@ - #ifndef __FREEBSD_PROC_H_ - #define __FREEBSD_PROC_H_ - -+#if defined(__FreeBSD_version) && __FreeBSD_version > 1100000 -+#include <sys/signal.h> -+#endif - #include <sys/types.h> - #if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - #include <sys/procdesc.h> -@@ -72,6 +75,56 @@ static inline abi_long do_freebsd_wait4(abi_long arg1, abi_ulong target_status, - return ret; - } - -+#if defined(__FreeBSD_version) && __FreeBSD_version > 1100000 -+/* wait6(2) */ -+static inline abi_long do_freebsd_wait6(abi_long idtype, abi_long id, -+ abi_ulong target_status, abi_long options, abi_ulong target_wrusage, -+ abi_ulong target_infop) -+{ -+ abi_long ret; -+ int status; -+ struct __wrusage wrusage, *wrusage_ptr = NULL; -+ siginfo_t info; -+ void *p; -+ -+ if (target_wrusage) { -+ wrusage_ptr = &wrusage; -+ } -+ ret = get_errno(wait6(idtype, id, &status, options, wrusage_ptr, &info)); -+ if (!is_error(ret)) { -+ status = host_to_target_waitstatus(status); -+ if (put_user_s32(status, target_status) != 0) { -+ return -TARGET_EFAULT; -+ } -+ if (target_wrusage != 0) { -+ host_to_target_wrusage(target_wrusage, &wrusage); -+ } -+ if (target_infop != 0) { -+ p = lock_user(VERIFY_WRITE, target_infop, sizeof(target_siginfo_t), -+ 0); -+ if (p == NULL) { -+ return -TARGET_EFAULT; -+ } -+ host_to_target_siginfo(p, &info); -+ unlock_user(p, target_infop, sizeof(target_siginfo_t)); -+ } -+ } -+ return ret; -+} -+ -+#else /* ! __FreeBSD_version > 1100000 */ -+ -+static inline abi_long do_freebsd_wait6( __unused abi_long idtype, -+ __unused abi_long id, __unused abi_ulong target_status, -+ __unused abi_long options, __unused abi_ulong target_wrusage, -+ __unused abi_ulong target_infop) -+{ -+ -+ qemu_log("qemu: Unsupported syscall wait6()\n"); -+ return -TARGET_ENOSYS; -+} -+#endif /* __FreeBSD_version > 1100000 */ -+ - #if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - /* setloginclass(2) */ - static inline abi_long do_freebsd_setloginclass(abi_ulong arg1) -diff --git a/bsd-user/freebsd/syscall_nr.h b/bsd-user/freebsd/syscall_nr.h -index d849024..779e192 100644 ---- a/bsd-user/freebsd/syscall_nr.h -+++ b/bsd-user/freebsd/syscall_nr.h -@@ -447,4 +447,5 @@ - #define TARGET_FREEBSD_NR_rctl_remove_rule 529 - #define TARGET_FREEBSD_NR_posix_fallocate 530 - #define TARGET_FREEBSD_NR_posix_fadvise 531 --#define TARGET_FREEBSD_NR_MAXSYSCALL 532 -+#define TARGET_FREEBSD_NR_wait6 532 -+#define TARGET_FREEBSD_NR_MAXSYSCALL 533 -diff --git a/bsd-user/qemu-bsd.h b/bsd-user/qemu-bsd.h -index 771245d..e58fdd7 100644 ---- a/bsd-user/qemu-bsd.h -+++ b/bsd-user/qemu-bsd.h -@@ -48,6 +48,8 @@ rlim_t target_to_host_rlim(abi_ulong target_rlim); - abi_ulong host_to_target_rlim(rlim_t rlim); - abi_long host_to_target_rusage(abi_ulong target_addr, - const struct rusage *rusage); -+abi_long host_to_target_wrusage(abi_ulong target_addr, -+ const struct __wrusage *wrusage); - int host_to_target_waitstatus(int status); - - /* bsd-socket.c */ -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index ac27584..4f5a008 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -2,7 +2,7 @@ - * BSD syscalls - * - * Copyright (c) 2003 - 2008 Fabrice Bellard -- * Copyright (c) 2013 Stacey D. Son -+ * Copyright (c) 2013-14 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 -@@ -189,6 +189,10 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - ret = do_freebsd_wait4(arg1, arg2, arg3, arg4); - break; - -+ case TARGET_FREEBSD_NR_wait6: /* wait6(2) */ -+ ret = do_freebsd_wait6(arg1, arg2, arg3, arg4, arg5, arg6); -+ break; -+ - case TARGET_FREEBSD_NR_exit: /* exit(2) */ - ret = do_bsd_exit(cpu_env, arg1); - break; -diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h -index d02476c..1af31da 100644 ---- a/bsd-user/syscall_defs.h -+++ b/bsd-user/syscall_defs.h -@@ -281,6 +281,11 @@ struct target_freebsd_rusage { - abi_long ru_nivcsw; /* involuntary context switches */ - }; - -+struct target_freebsd__wrusage { -+ struct target_freebsd_rusage wru_self; -+ struct target_freebsd_rusage wru_children; -+}; -+ - /* - * sys/socket.h - */ diff --git a/emulators/qemu-devel/files/extra-patch-ad225b8412847303d48d8e7852589456325e8f9b b/emulators/qemu-devel/files/extra-patch-ad225b8412847303d48d8e7852589456325e8f9b deleted file mode 100644 index 1c4dcf552384..000000000000 --- a/emulators/qemu-devel/files/extra-patch-ad225b8412847303d48d8e7852589456325e8f9b +++ /dev/null @@ -1,36 +0,0 @@ -From ad225b8412847303d48d8e7852589456325e8f9b Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Fri, 7 Nov 2014 16:07:27 +0000 -Subject: [PATCH] Correctly deal with new sem_wait2 and sem_wake2 _umtx ops for - 9.x builds. - ---- - bsd-user/freebsd/os-thread.c | 7 ++++--- - 1 file changed, 4 insertions(+), 3 deletions(-) - -diff --git a/bsd-user/freebsd/os-thread.c b/bsd-user/freebsd/os-thread.c -index cca46cf..baec878 100644 ---- a/bsd-user/freebsd/os-thread.c -+++ b/bsd-user/freebsd/os-thread.c -@@ -241,9 +241,9 @@ abi_long freebsd_umtx_sem_wake(abi_ulong obj, uint32_t val) - - return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM2_WAKE, val, NULL, NULL)); - } --#endif - --#else -+#else /* ! __FreeBSD_version > 1100000 */ -+ - abi_long freebsd_umtx_sem_wait(abi_ulong obj, struct timespec *timeout) - { - -@@ -259,7 +259,8 @@ abi_long freebsd_umtx_sem_wake(abi_ulong obj, uint32_t val) - - return get_errno(_umtx_op(g2h(obj), UMTX_OP_SEM_WAKE, val, NULL, NULL)); - } --#endif -+#endif /* ! __FreeBSD_version > 110000 */ -+#endif /* ! __FreeBSD_version > 900000 */ - - abi_long t2h_freebsd_rtprio(struct rtprio *host_rtp, abi_ulong target_addr) - { diff --git a/emulators/qemu-devel/files/extra-patch-ad92220df37d1ab3120316fcc436071c78817561 b/emulators/qemu-devel/files/extra-patch-ad92220df37d1ab3120316fcc436071c78817561 deleted file mode 100644 index c627b9be892b..000000000000 --- a/emulators/qemu-devel/files/extra-patch-ad92220df37d1ab3120316fcc436071c78817561 +++ /dev/null @@ -1,59 +0,0 @@ -From ad92220df37d1ab3120316fcc436071c78817561 Mon Sep 17 00:00:00 2001 -From: Sean Bruno <sbruno@chips.ysv.freebsd.org> -Date: Sat, 4 Oct 2014 20:36:32 +0000 -Subject: [PATCH] Ancillary data in the msghdr struct is optional, not - mandatory. - -If it doesn't exist, that's ok sendmsg() anyway. Fixes pkg repo -issues now that pkg uses sendmsg. ---- - bsd-user/freebsd/os-socket.h | 22 +++++++++++++++++----- - 1 file changed, 17 insertions(+), 5 deletions(-) - -diff --git a/bsd-user/freebsd/os-socket.h b/bsd-user/freebsd/os-socket.h -index 9339ffb..a5f5ca7 100644 ---- a/bsd-user/freebsd/os-socket.h -+++ b/bsd-user/freebsd/os-socket.h -@@ -54,9 +54,15 @@ static inline abi_long do_freebsd_sendmsg(int fd, abi_ulong target_msg, - msg.msg_name = NULL; - msg.msg_namelen = 0; - } -- msg.msg_controllen = 2 * tswapal(msgp->msg_controllen); -- msg.msg_control = alloca(msg.msg_controllen); -- msg.msg_flags = tswap32(msgp->msg_flags); -+ if (tswapal(msgp->msg_controllen) > 0) { -+ msg.msg_controllen = 2 * tswapal(msgp->msg_controllen); -+ msg.msg_control = alloca(msg.msg_controllen); -+ msg.msg_flags = tswap32(msgp->msg_flags); -+ } else { -+ msg.msg_controllen = 0; -+ msg.msg_control = NULL; -+ msg.msg_flags = 0; -+ } - - count = tswapal(msgp->msg_iovlen); - vec = alloca(count * sizeof(struct iovec)); -@@ -65,7 +71,10 @@ static inline abi_long do_freebsd_sendmsg(int fd, abi_ulong target_msg, - msg.msg_iovlen = count; - msg.msg_iov = vec; - -- ret = t2h_freebsd_cmsg(&msg, msgp); -+ if (msg.msg_controllen > 0) -+ ret = t2h_freebsd_cmsg(&msg, msgp); -+ else /* no ancillary data */ -+ ret = 0; - if (!is_error(ret)) { - ret = get_errno(sendmsg(fd, &msg, flags)); - } -@@ -116,7 +125,10 @@ static inline abi_long do_freebsd_recvmsg(int fd, abi_ulong target_msg, - ret = get_errno(recvmsg(fd, &msg, flags)); - if (!is_error(ret)) { - len = ret; -- ret = h2t_freebsd_cmsg(msgp, &msg); -+ if (msg.msg_controllen > 0) -+ ret = h2t_freebsd_cmsg(msgp, &msg); -+ else /* no ancillary data */ -+ ret = 0; - if (!is_error(ret)) { - msgp->msg_namelen = tswap32(msg.msg_namelen); - if (msg.msg_name != NULL) { diff --git a/emulators/qemu-devel/files/extra-patch-bsd-user-arm-signal b/emulators/qemu-devel/files/extra-patch-bsd-user-arm-signal deleted file mode 100644 index 55604c367022..000000000000 --- a/emulators/qemu-devel/files/extra-patch-bsd-user-arm-signal +++ /dev/null @@ -1,51 +0,0 @@ -diff --git a/bsd-user/arm/target_arch_signal.h b/bsd-user/arm/target_arch_signal.h -index 048bd4f..0b14b0b 100644 ---- a/bsd-user/arm/target_arch_signal.h -+++ b/bsd-user/arm/target_arch_signal.h -@@ -47,7 +47,7 @@ - #define TARGET_INSN_SIZE 4 /* arm instruction size */ - - /* Size of the signal trampolin code. See _sigtramp(). */ --#define TARGET_SZSIGCODE ((abi_ulong)(8 * TARGET_INSN_SIZE)) -+#define TARGET_SZSIGCODE ((abi_ulong)(9 * TARGET_INSN_SIZE)) - - /* compare to arm/include/_limits.h */ - #define TARGET_MINSIGSTKSZ (1024 * 4) /* min sig stack size */ -@@ -248,7 +248,7 @@ static inline abi_long get_ucontext_sigreturn(CPUARMState *regs, - return -TARGET_EINVAL; - } - -- *target_uc = target_sf + offsetof(struct target_sigframe, sf_uc); -+ *target_uc = target_sf; - - return 0; - } -diff --git a/bsd-user/arm/target_arch_sigtramp.h b/bsd-user/arm/target_arch_sigtramp.h -index 98dc313..5b7424c 100644 ---- a/bsd-user/arm/target_arch_sigtramp.h -+++ b/bsd-user/arm/target_arch_sigtramp.h -@@ -15,16 +15,17 @@ static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc, - */ - uint32_t sigtramp_code[] = { - /* 1 */ 0xE1A0000D, /* mov r0, sp */ -- /* 2 */ 0xE59F700C, /* ldr r7, [pc, #12] */ -- /* 3 */ 0xEF000000 + sys_sigreturn, /* swi (SYS_sigreturn) */ -- /* 4 */ 0xE59F7008, /* ldr r7, [pc, #8] */ -- /* 5 */ 0xEF000000 + sys_exit, /* swi (SYS_exit)*/ -- /* 6 */ 0xEAFFFFFA, /* b . -16 */ -- /* 7 */ sys_sigreturn, -- /* 8 */ sys_exit -+ /* 2 */ 0xE2800000 + sigf_uc, /* add r0, r0, #SIGF_UC */ -+ /* 3 */ 0xE59F700C, /* ldr r7, [pc, #12] */ -+ /* 4 */ 0xEF000000 + sys_sigreturn, /* swi (SYS_sigreturn) */ -+ /* 5 */ 0xE59F7008, /* ldr r7, [pc, #8] */ -+ /* 6 */ 0xEF000000 + sys_exit, /* swi (SYS_exit)*/ -+ /* 7 */ 0xEAFFFFFA, /* b . -16 */ -+ /* 8 */ sys_sigreturn, -+ /* 9 */ sys_exit - }; - -- for (i = 0; i < 8; i++) { -+ for (i = 0; i < 9; i++) { - tswap32s(&sigtramp_code[i]); - } diff --git a/emulators/qemu-devel/files/extra-patch-bsd-user-arm-target_arch_thread.h b/emulators/qemu-devel/files/extra-patch-bsd-user-arm-target_arch_thread.h deleted file mode 100644 index 5876e74de3fd..000000000000 --- a/emulators/qemu-devel/files/extra-patch-bsd-user-arm-target_arch_thread.h +++ /dev/null @@ -1,15 +0,0 @@ -diff --git a/bsd-user/arm/target_arch_thread.h b/bsd-user/arm/target_arch_thread.h -index e69f612..ee4d67d 100644 ---- a/bsd-user/arm/target_arch_thread.h -+++ b/bsd-user/arm/target_arch_thread.h -@@ -29,8 +29,8 @@ static inline void target_thread_set_upcall(CPUARMState *regs, abi_ulong entry, - * Make sure the stack is properly aligned. - * arm/include/param.h (STACKLIGN() macro) - */ -- sp = ((u_int)(stack_base + stack_size) & ~(8-1)) - -- sizeof(struct target_trapframe); -+ sp = (u_int)((stack_base + stack_size) - -+ sizeof(struct target_trapframe)) & ~0x7; - - /* sp = stack base */ - regs->regs[13] = sp; diff --git a/emulators/qemu-devel/files/extra-patch-bsd-user-freebsd-os-proc.c b/emulators/qemu-devel/files/extra-patch-bsd-user-freebsd-os-proc.c deleted file mode 100644 index b53b82e72d69..000000000000 --- a/emulators/qemu-devel/files/extra-patch-bsd-user-freebsd-os-proc.c +++ /dev/null @@ -1,127 +0,0 @@ -From nox Mon Sep 17 00:00:00 2001 -From: Juergen Lock <nox@jelal.kn-bremen.de> -Date: 22 Mar 2014 00:21:00 +0100 -Subject: Fix bsd-user targets running scripts with shebang args - -This fixes running scripts starting like: - - #! /usr/bin/perl -w - -Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de> - ---- a/bsd-user/freebsd/os-proc.c ---- b/bsd-user/freebsd/os-proc.c -@@ -83,7 +83,7 @@ out: - } - - static int --is_target_shell_script(int fd, char *interp, size_t size) -+is_target_shell_script(int fd, char *interp, size_t size, char **interp_args) - { - char buf[2], *p, *b; - ssize_t n; -@@ -120,7 +120,21 @@ is_target_shell_script(int fd, char *int - return 0; - } - if ((p = memchr(b, '\n', size)) != NULL) { -+ int hasargs = 0; - *p = 0; -+ -+ *interp_args = NULL; -+ p = interp; -+ while (*p) { -+ if ((*p == ' ') || (*p == '\t')) { -+ hasargs = 1; -+ *p = 0; -+ } else if (hasargs) { -+ *interp_args = p; -+ break; -+ } -+ ++p; -+ } - return 1; - } - b += n; -@@ -136,7 +150,7 @@ is_target_shell_script(int fd, char *int - abi_long freebsd_exec_common(abi_ulong path_or_fd, abi_ulong guest_argp, - abi_ulong guest_envp, int do_fexec) - { -- char **argp, **envp, **qargp, **qarg1, **qarg0; -+ char **argp, **envp, **qargp, **qarg1, **qarg0, **qargend; - int argc, envc; - abi_ulong gp; - abi_ulong addr; -@@ -166,7 +180,7 @@ abi_long freebsd_exec_common(abi_ulong p - envc++; - } - -- qarg0 = argp = alloca((argc + 4) * sizeof(void *)); -+ qarg0 = argp = alloca((argc + 5) * sizeof(void *)); - /* save the first agrument for the emulator */ - *argp++ = (char *)getprogname(); - qargp = argp; -@@ -188,7 +202,8 @@ abi_long freebsd_exec_common(abi_ulong p - } - total_size += strlen(*q) + 1; - } -- *q = NULL; -+ *q++ = NULL; -+ qargend = q; - - for (gp = guest_envp, q = envp; gp; gp += sizeof(abi_ulong), q++) { - if (get_user_ual(addr, gp)) { -@@ -217,7 +232,7 @@ abi_long freebsd_exec_common(abi_ulong p - } - - if (do_fexec) { -- char execpath[PATH_MAX]; -+ char execpath[PATH_MAX], *scriptargs; - - if (((int)path_or_fd > 0 && - is_target_elf_binary((int)path_or_fd)) == 1) { -@@ -238,7 +253,7 @@ abi_long freebsd_exec_common(abi_ulong p - goto execve_end; - } - } else if (is_target_shell_script((int)path_or_fd, execpath, -- sizeof(execpath)) != 0) { -+ sizeof(execpath), &scriptargs) != 0) { - char scriptpath[PATH_MAX]; - - /* execve() as a target script using emulator. */ -@@ -246,6 +261,10 @@ abi_long freebsd_exec_common(abi_ulong p - sizeof(scriptpath)) != NULL) { - *qargp = execpath; - *qarg1 = scriptpath; -+ if (scriptargs) { -+ memmove(qarg1 + 1, qarg1, (qargend-qarg1) * sizeof(*qarg1)); -+ *qarg1 = scriptargs; -+ } - ret = get_errno(execve(qemu_proc_pathname, qarg0, envp)); - } else { - ret = -TARGET_EBADF; -@@ -256,7 +275,7 @@ abi_long freebsd_exec_common(abi_ulong p - } - } else { - int fd; -- char execpath[PATH_MAX]; -+ char execpath[PATH_MAX], *scriptargs; - - p = lock_user_string(path_or_fd); - if (p == NULL) { -@@ -275,11 +294,15 @@ abi_long freebsd_exec_common(abi_ulong p - *qarg1 = (char *)p; - ret = get_errno(execve(qemu_proc_pathname, qargp, envp)); - } else if (is_target_shell_script(fd, execpath, -- sizeof(execpath)) != 0) { -+ sizeof(execpath), &scriptargs) != 0) { - close(fd); - /* execve() as a target script using emulator. */ - *qargp = execpath; - *qarg1 = (char *)p; -+ if (scriptargs) { -+ memmove(qarg1 + 1, qarg1, (qargend-qarg1) * sizeof(*qarg1)); -+ *qarg1 = scriptargs; -+ } - ret = get_errno(execve(qemu_proc_pathname, qarg0, envp)); - } else { - close(fd); diff --git a/emulators/qemu-devel/files/extra-patch-bsd-user-freebsd-os-socket.h b/emulators/qemu-devel/files/extra-patch-bsd-user-freebsd-os-socket.h deleted file mode 100644 index a1f133712815..000000000000 --- a/emulators/qemu-devel/files/extra-patch-bsd-user-freebsd-os-socket.h +++ /dev/null @@ -1,22 +0,0 @@ ---- a/bsd-user/freebsd/os-socket.h -+++ b/bsd-user/freebsd/os-socket.h -@@ -181,7 +181,9 @@ static inline abi_long do_bsd_setsockopt - case IP_PORTRANGE: /* int; range to choose for unspec port */ - case IP_RECVIF: /* bool; receive reception if w/dgram */ - case IP_IPSEC_POLICY: /* int; set/get security policy */ -+#ifdef IP_FAITH - case IP_FAITH: /* bool; accept FAITH'ed connections */ -+#endif - case IP_RECVTTL: /* bool; receive reception TTL w/dgram */ - val = 0; - if (optlen >= sizeof(uint32_t)) { -@@ -454,7 +456,9 @@ int_case: - case IP_MULTICAST_LOOP: - case IP_PORTRANGE: - case IP_IPSEC_POLICY: -+#ifdef IP_FAITH - case IP_FAITH: -+#endif - case IP_ONESBCAST: - case IP_BINDANY: - if (get_user_u32(len, optlen)) { diff --git a/emulators/qemu-devel/files/extra-patch-bsd-user-freebsd-os-sys.c b/emulators/qemu-devel/files/extra-patch-bsd-user-freebsd-os-sys.c deleted file mode 100644 index a9f01f34a38c..000000000000 --- a/emulators/qemu-devel/files/extra-patch-bsd-user-freebsd-os-sys.c +++ /dev/null @@ -1,13 +0,0 @@ ---- a/bsd-user/freebsd/os-sys.c -+++ b/bsd-user/freebsd/os-sys.c -@@ -75,8 +75,10 @@ host_to_target_vfc_flags(int flags) - ret |= TARGET_VFCF_JAIL; - if (flags & VFCF_DELEGADMIN) - ret |= TARGET_VFCF_DELEGADMIN; -+#ifdef VFCF_SBDRY - if (flags & VFCF_SBDRY) - ret |= TARGET_VFCF_SBDRY; -+#endif - - return ret; - } diff --git a/emulators/qemu-devel/files/extra-patch-bsd-user-freebsd-target_os_stack.h b/emulators/qemu-devel/files/extra-patch-bsd-user-freebsd-target_os_stack.h deleted file mode 100644 index c4f901257e72..000000000000 --- a/emulators/qemu-devel/files/extra-patch-bsd-user-freebsd-target_os_stack.h +++ /dev/null @@ -1,50 +0,0 @@ -diff --git a/bsd-user/freebsd/target_os_stack.h b/bsd-user/freebsd/target_os_stack.h -index c84b69e..73aea8f 100644 ---- a/bsd-user/freebsd/target_os_stack.h -+++ b/bsd-user/freebsd/target_os_stack.h -@@ -1,3 +1,22 @@ -+/* -+ * FreeBSD setup_initial_stack() implementation. -+ * -+ * Copyright (c) 2013-14 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 _TARGET_OS_STACK_H_ - #define _TARGET_OS_STACK_H_ - -@@ -64,9 +83,7 @@ static inline int setup_initial_stack(struct bsd_binprm *bprm, - 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; -@@ -85,9 +102,9 @@ static inline int setup_initial_stack(struct bsd_binprm *bprm, - } - - /* 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)); -+ argvp = roundup(p - TARGET_SPACE_USRSPACE - (TARGET_ARG_MAX - stringspace), -+ sizeof(abi_ulong)); -+ p = destp = p - TARGET_SPACE_USRSPACE - TARGET_ARG_MAX; - - /* - * Add argv strings. Note that the argv[] vectors are added by diff --git a/emulators/qemu-devel/files/extra-patch-bsd-user-mips-target_arch_vmparam.h b/emulators/qemu-devel/files/extra-patch-bsd-user-mips-target_arch_vmparam.h deleted file mode 100644 index ec347bbb8d6f..000000000000 --- a/emulators/qemu-devel/files/extra-patch-bsd-user-mips-target_arch_vmparam.h +++ /dev/null @@ -1,22 +0,0 @@ -From nox Mon Sep 17 00:00:00 2001 -From: Juergen Lock <nox@jelal.kn-bremen.de> -Date: 04 Apr 2014 02:09:00 +0200 -Subject: Lower 32bit mips TARGET_USRSTACK - -Lower 32bit mips TARGET_USRSTACK to fix an assert starting mips-bsd-user -processes on 64bit hosts. (like amd64) - -Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de> - ---- a/bsd-user/mips/target_arch_vmparam.h -+++ b/bsd-user/mips/target_arch_vmparam.h -@@ -35,7 +35,8 @@ - #define TARGET_VM_MINUSER_ADDRESS (0x00000000) - #define TARGET_VM_MAXUSER_ADDRESS (0x80000000) - --#define TARGET_USRSTACK (TARGET_VM_MAXUSER_ADDRESS - TARGET_PAGE_SIZE) -+// #define TARGET_USRSTACK (TARGET_VM_MAXUSER_ADDRESS - TARGET_PAGE_SIZE) -+#define TARGET_USRSTACK (TARGET_RESERVED_VA - TARGET_PAGE_SIZE * 0x10) - - static inline abi_ulong get_sp_from_cpustate(CPUMIPSState *state) - { diff --git a/emulators/qemu-devel/files/extra-patch-bsd-user-mmap.c b/emulators/qemu-devel/files/extra-patch-bsd-user-mmap.c deleted file mode 100644 index f8b393397839..000000000000 --- a/emulators/qemu-devel/files/extra-patch-bsd-user-mmap.c +++ /dev/null @@ -1,28 +0,0 @@ -From nox Mon Sep 17 00:00:00 2001 -From: Juergen Lock <nox@jelal.kn-bremen.de> -Date: 06 Apr 2014 02:20:00 +0200 -Subject: Wrap bsd-user mmap(2) allocation search to low memory - -Wrap bsd-user mmap(2) allocation search to low memory to avoid -another assert on 64bit hosts. - -Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de> - ---- a/bsd-user/mmap.c -+++ b/bsd-user/mmap.c -@@ -238,8 +238,13 @@ abi_ulong mmap_find_vma(abi_ulong start, - for (addr1 = addr; addr1 < (addr + size); addr1 += TARGET_PAGE_SIZE) { - prot |= page_get_flags(addr1); - } -- if (prot == 0) -- break; -+ if (prot == 0) { -+ if (reserved_va && addr + size >= reserved_va) { -+ addr = 0; -+ } else { -+ break; -+ } -+ } - addr += qemu_host_page_size; - /* we found nothing */ - if (addr == addr_start) diff --git a/emulators/qemu-devel/files/extra-patch-bsd-user-sparc64-target_arch_cpu.h b/emulators/qemu-devel/files/extra-patch-bsd-user-sparc64-target_arch_cpu.h deleted file mode 100644 index 4407bb6cce77..000000000000 --- a/emulators/qemu-devel/files/extra-patch-bsd-user-sparc64-target_arch_cpu.h +++ /dev/null @@ -1,20 +0,0 @@ -From nox Mon Sep 17 00:00:00 2001 -From: Juergen Lock <nox@jelal.kn-bremen.de> -Date: 06 Jul 2014 13:23:00 +0200 -Subject: sparc64-bsd-user: sync ccr before changing carry flag - -Sync ccr so that changing carry flag manually after syscall works -properly. - -Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de> - ---- a/bsd-user/sparc64/target_arch_cpu.h -+++ b/bsd-user/sparc64/target_arch_cpu.h -@@ -77,6 +77,7 @@ static inline void target_cpu_loop(CPUSP - env->regwptr[2], env->regwptr[3], - env->regwptr[4], env->regwptr[5]); - } -+ cpu_put_ccr(env, cpu_get_ccr(env)); - if ((unsigned int)ret >= (unsigned int)(-515)) { - ret = -ret; - #if !defined(TARGET_ABI32) diff --git a/emulators/qemu-devel/files/extra-patch-bsd-user-syscall.c b/emulators/qemu-devel/files/extra-patch-bsd-user-syscall.c deleted file mode 100644 index 1dda197e9c3d..000000000000 --- a/emulators/qemu-devel/files/extra-patch-bsd-user-syscall.c +++ /dev/null @@ -1,20 +0,0 @@ -From nox Mon Sep 17 00:00:00 2001 -From: Juergen Lock <nox@jelal.kn-bremen.de> -Date: 05 Apr 2014 02:04:00 +0200 -Subject: Fix bsd-user FreeBSD fchflags() syscall (typo) - -Fix bsd-user FreeBSD fchflags() syscall. (typo) - -Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de> - ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -627,7 +627,7 @@ abi_long do_freebsd_syscall(void *cpu_en - break; - - case TARGET_FREEBSD_NR_fchflags: /* fchflags(2) */ -- ret = do_bsd_fchflags(arg2, arg2); -+ ret = do_bsd_fchflags(arg1, arg2); - break; - - case TARGET_FREEBSD_NR_chroot: /* chroot(2) */ diff --git a/emulators/qemu-devel/files/extra-patch-bsd-user-trapsig b/emulators/qemu-devel/files/extra-patch-bsd-user-trapsig deleted file mode 100644 index d19de61578e3..000000000000 --- a/emulators/qemu-devel/files/extra-patch-bsd-user-trapsig +++ /dev/null @@ -1,22 +0,0 @@ -From nox Mon Sep 17 00:00:00 2001 -From: Juergen Lock <nox@jelal.kn-bremen.de> -Date: 06 Jul 2014 16:37:00 +0200 -Subject: bsd-user: writing to readonly page can cause trap 0xc on FreeBSD too - -Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de> - ---- a/user-exec.c -+++ b/user-exec.c -@@ -230,7 +230,12 @@ int cpu_signal_handler(int host_signum, - - pc = PC_sig(uc); - return handle_cpu_signal(pc, (unsigned long)info->si_addr, -+#if defined(__FreeBSD__) || defined(__DragonFly__) -+ (TRAP_sig(uc) == 0xe || -+ TRAP_sig(uc) == 0xc) ? -+#else - TRAP_sig(uc) == 0xe ? -+#endif - (ERROR_sig(uc) >> 1) & 1 : 0, - &MASK_sig(uc), puc); - } diff --git a/emulators/qemu-devel/files/extra-patch-bsd-user-x86_64-target_arch_vmparam.h b/emulators/qemu-devel/files/extra-patch-bsd-user-x86_64-target_arch_vmparam.h deleted file mode 100644 index f6c18b3d28d7..000000000000 --- a/emulators/qemu-devel/files/extra-patch-bsd-user-x86_64-target_arch_vmparam.h +++ /dev/null @@ -1,19 +0,0 @@ -From nox Mon Sep 17 00:00:00 2001 -From: Juergen Lock <nox@jelal.kn-bremen.de> -Date: 12 Jun 2014 19:55:52 +0200 -Subject: Fix bsd-user x86_64 target failing with stk mmap: Invalid argument - -Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de> - ---- a/bsd-user/x86_64/target_arch_vmparam.h -+++ b/bsd-user/x86_64/target_arch_vmparam.h -@@ -11,7 +11,8 @@ - #define TARGET_MAXSSIZ (512UL*1024*1024) /* max stack size */ - #define TARGET_SGROWSIZ (128UL*1024) /* amount to grow stack */ - --#define TARGET_VM_MAXUSER_ADDRESS (0x0000800000000000UL) -+/* #define TARGET_VM_MAXUSER_ADDRESS (0x0000800000000000UL) */ -+#define TARGET_VM_MAXUSER_ADDRESS (0x00007fffff000000UL) - - #define TARGET_USRSTACK (TARGET_VM_MAXUSER_ADDRESS - TARGET_PAGE_SIZE) - diff --git a/emulators/qemu-devel/files/extra-patch-c13_tls2 b/emulators/qemu-devel/files/extra-patch-c13_tls2 deleted file mode 100644 index fca58f546c57..000000000000 --- a/emulators/qemu-devel/files/extra-patch-c13_tls2 +++ /dev/null @@ -1,15 +0,0 @@ ---- a/bsd-user/arm/target_arch_cpu.c -+++ b/bsd-user/arm/target_arch_cpu.c -@@ -18,10 +18,10 @@ - - void target_cpu_set_tls(CPUARMState *env, target_ulong newtls) - { -- env->cp15.c13_tls2 = newtls; -+ env->cp15.tpidrro_el0 = newtls; - } - - target_ulong target_cpu_get_tls(CPUARMState *env) - { -- return (env->cp15.c13_tls2); -+ return (env->cp15.tpidrro_el0); - } diff --git a/emulators/qemu-devel/files/extra-patch-c9c55ac786f09ce575b5f67b35241ce9452896c9 b/emulators/qemu-devel/files/extra-patch-c9c55ac786f09ce575b5f67b35241ce9452896c9 deleted file mode 100644 index 315b99e258b8..000000000000 --- a/emulators/qemu-devel/files/extra-patch-c9c55ac786f09ce575b5f67b35241ce9452896c9 +++ /dev/null @@ -1,224 +0,0 @@ -From c9c55ac786f09ce575b5f67b35241ce9452896c9 Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Tue, 4 Nov 2014 23:38:38 +0000 -Subject: [PATCH] Add support for new socket system calls. - -This change adds support for bindat(2), connectat(2), and accept4(2) -system calls. ---- - bsd-user/freebsd/os-socket.h | 106 +++++++++++++++++++++++++++++++++++++++++- - bsd-user/freebsd/strace.list | 13 ++++++ - bsd-user/freebsd/syscall_nr.h | 6 ++- - bsd-user/syscall.c | 12 +++++ - 4 files changed, 135 insertions(+), 2 deletions(-) - -diff --git a/bsd-user/freebsd/os-socket.h b/bsd-user/freebsd/os-socket.h -index 6530a07..61e3440 100644 ---- a/bsd-user/freebsd/os-socket.h -+++ b/bsd-user/freebsd/os-socket.h -@@ -1,7 +1,7 @@ - /* - * FreeBSD socket related system call shims - * -- * Copyright (c) 2013 Stacey D. Son -+ * Copyright (c) 2013-14 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 -@@ -557,4 +557,108 @@ static inline abi_long do_freebsd_sendfile(abi_long fd, abi_long s, - return -TARGET_ENOSYS; - } - -+#if defined(__FreeBSD_version) && __FreeBSD_version > 1100000 -+/* bindat(2) */ -+static inline abi_long do_bsd_bindat(int fd, int sockfd, abi_ulong target_addr, -+ socklen_t addrlen) -+{ -+ abi_long ret; -+ void *addr; -+ -+ if ((int)addrlen < 0) { -+ return -TARGET_EINVAL; -+ } -+ -+ addr = alloca(addrlen + 1); -+ ret = target_to_host_sockaddr(addr, target_addr, addrlen); -+ if (is_error(ret)) { -+ return ret; -+ } -+ -+ return get_errno(bindat(fd, sockfd, addr, addrlen)); -+} -+ -+/* connectat(2) */ -+static inline abi_long do_bsd_connectat(int fd, int sockfd, -+ abi_ulong target_addr, socklen_t addrlen) -+{ -+ abi_long ret; -+ void *addr; -+ -+ if ((int)addrlen < 0) { -+ return -TARGET_EINVAL; -+ } -+ addr = alloca(addrlen); -+ -+ ret = target_to_host_sockaddr(addr, target_addr, addrlen); -+ -+ if (is_error(ret)) { -+ return ret; -+ } -+ -+ return get_errno(connectat(fd, sockfd, addr, addrlen)); -+} -+ -+/* accept4(2) */ -+static inline abi_long do_bsd_accept4(int fd, abi_ulong target_addr, -+ abi_ulong target_addrlen_addr, int flags) -+{ -+ socklen_t addrlen; -+ void *addr; -+ abi_long ret; -+ -+ if (target_addr == 0) { -+ return get_errno(accept(fd, NULL, NULL)); -+ } -+ /* return EINVAL if addrlen pointer is invalid */ -+ if (get_user_u32(addrlen, target_addrlen_addr)) { -+ return -TARGET_EINVAL; -+ } -+ if ((int)addrlen < 0) { -+ return -TARGET_EINVAL; -+ } -+ if (!access_ok(VERIFY_WRITE, target_addr, addrlen)) { -+ return -TARGET_EINVAL; -+ } -+ addr = alloca(addrlen); -+ -+ ret = get_errno(accept4(fd, addr, &addrlen, flags)); -+ if (!is_error(ret)) { -+ host_to_target_sockaddr(target_addr, addr, addrlen); -+ if (put_user_u32(addrlen, target_addrlen_addr)) { -+ ret = -TARGET_EFAULT; -+ } -+ } -+ return ret; -+} -+ -+#else /* ! __FreeBSD_version > 1100000 */ -+ -+/* bindat(2) */ -+static inline abi_long do_bsd_bindat(__unused int sockfd, -+ __unused abi_ulong target_addr, __unused socklen_t addrlen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall bindat()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* connectat(2) */ -+static inline abi_long do_bsd_connectat(__unused int sockfd, -+ __unused abi_ulong target_addr, __unused socklen_t addrlen) -+{ -+ -+ qemu_log("qemu: Unsupported syscall connectat()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+static inline abi_long do_bsd_accept4(__unused int fd, -+ __unused abi_ulong target_addr, __unused abi_ulong target_addrlen_addr, -+ __unused int flags) -+{ -+ -+ qemu_log("qemu: Unsupported syscall accept4()\n"); -+ return -TARGET_ENOSYS; -+} -+#endif /* ! __FreeBSD_version > 1100000 */ - #endif /* !__FREEBSD_SOCKET_H_ */ -diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list -index f8858aa..991cbe2 100644 ---- a/bsd-user/freebsd/strace.list -+++ b/bsd-user/freebsd/strace.list -@@ -34,11 +34,22 @@ - { TARGET_FREEBSD_NR___sysctl, "__sysctl", NULL, print_sysctl, NULL }, - { TARGET_FREEBSD_NR__umtx_op, "_umtx_op", "%s(%#x, %d, %d, %#x, %#x)", NULL, NULL }, - { TARGET_FREEBSD_NR_accept, "accept", "%s(%d,%#x,%#x)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_accept4, "accept4", "%s(%d,%d,%#x,%#x)", NULL, NULL }, - { TARGET_FREEBSD_NR_access, "access", "%s(\"%s\",%#o)", NULL, NULL }, - { TARGET_FREEBSD_NR_acct, "acct", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_adjtime, "adjtime", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_bind, "bind", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_bindat, "bindat", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_break, "break", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_cap_enter, "cap_enter", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_cap_fcntls_get, "cap_fcntls_get", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_cap_fcntls_limit, "cap_fcntls_limit", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_cap_getmode, "cap_getmode", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_cap_getrights, "cap_getrights", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_cap_ioctls_get, "cap_ioctls_get", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_cap_ioctls_limit, "cap_ioctls_limit", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_cap_new, "cap_new", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_cap_rights_limit, "cap_rights_limit", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_chdir, "chdir", "%s(\"%s\")", NULL, NULL }, - { TARGET_FREEBSD_NR_chflags, "chflags", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_chmod, "chmod", "%s(\"%s\",%#o)", NULL, NULL }, -@@ -49,6 +60,7 @@ - { TARGET_FREEBSD_NR_clock_settime, "clock_settime", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_close, "close", "%s(%d)", NULL, NULL }, - { TARGET_FREEBSD_NR_connect, "connect", "%s(%d,%#x,%d)", NULL, NULL }, -+{ TARGET_FREEBSD_NR_connectat, "connectat", "%s(%d,%d,%#x,%d)", NULL, NULL }, - { TARGET_FREEBSD_NR_dup, "dup", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_dup2, "dup2", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_eaccess, "eaccess", "%s(\"%s\",%#x)", NULL, NULL }, -@@ -228,6 +240,7 @@ - { TARGET_FREEBSD_NR_utimes, "utimes", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_vfork, "vfork", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_wait4, "wait4", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_wait6, "wait6", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_write, "write", "%s(%d,%#x,%d)", NULL, NULL }, - { TARGET_FREEBSD_NR_writev, "writev", "%s(%d,%p,%#x)", NULL, NULL }, - { TARGET_FREEBSD_NR_posix_openpt, "posix_openpt", "%s(%d)", NULL, NULL }, -diff --git a/bsd-user/freebsd/syscall_nr.h b/bsd-user/freebsd/syscall_nr.h -index 2ab3e1e..260fd82 100644 ---- a/bsd-user/freebsd/syscall_nr.h -+++ b/bsd-user/freebsd/syscall_nr.h -@@ -453,4 +453,8 @@ - #define TARGET_FREEBSD_NR_cap_ioctls_get 535 - #define TARGET_FREEBSD_NR_cap_fcntls_limit 536 - #define TARGET_FREEBSD_NR_cap_fcntls_get 537 --#define TARGET_FREEBSD_NR_MAXSYSCALL 538 -+#define TARGET_FREEBSD_NR_bindat 538 -+#define TARGET_FREEBSD_NR_connectat 539 -+#define TARGET_FREEBSD_NR_chflagsat 540 -+#define TARGET_FREEBSD_NR_accept4 541 -+#define TARGET_FREEBSD_NR_MAXSYSCALL 542 -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index c615bb8..e043396 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -1056,14 +1056,26 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - ret = do_bsd_accept(arg1, arg2, arg3); - break; - -+ case TARGET_FREEBSD_NR_accept4: /* accept4(2) */ -+ ret = do_bsd_accept4(arg1, arg2, arg3, arg4); -+ break; -+ - case TARGET_FREEBSD_NR_bind: /* bind(2) */ - ret = do_bsd_bind(arg1, arg2, arg3); - break; - -+ case TARGET_FREEBSD_NR_bindat: /* bindat(2) */ -+ ret = do_bsd_bindat(arg1, arg2, arg3, arg4); -+ break; -+ - case TARGET_FREEBSD_NR_connect: /* connect(2) */ - ret = do_bsd_connect(arg1, arg2, arg3); - break; - -+ case TARGET_FREEBSD_NR_connectat: /* connectat(2) */ -+ ret = do_bsd_connectat(arg1, arg2, arg3, arg4); -+ break; -+ - case TARGET_FREEBSD_NR_getpeername: /* getpeername(2) */ - ret = do_bsd_getpeername(arg1, arg2, arg3); - break; diff --git a/emulators/qemu-devel/files/extra-patch-cab0d36ffd4e70b1879dc2cf860c975a7965afc3 b/emulators/qemu-devel/files/extra-patch-cab0d36ffd4e70b1879dc2cf860c975a7965afc3 deleted file mode 100644 index 166f97b4b53d..000000000000 --- a/emulators/qemu-devel/files/extra-patch-cab0d36ffd4e70b1879dc2cf860c975a7965afc3 +++ /dev/null @@ -1,29 +0,0 @@ -From cab0d36ffd4e70b1879dc2cf860c975a7965afc3 Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Sat, 22 Nov 2014 19:59:32 +0000 -Subject: [PATCH] Convert signal number for thr_kill() to host signum. - ---- - bsd-user/freebsd/os-thread.h | 4 ++-- - 1 file changed, 2 insertions(+), 2 deletions(-) - -diff --git a/bsd-user/freebsd/os-thread.h b/bsd-user/freebsd/os-thread.h -index eef58fb..a41fde5 100644 ---- a/bsd-user/freebsd/os-thread.h -+++ b/bsd-user/freebsd/os-thread.h -@@ -85,13 +85,13 @@ static abi_long do_freebsd_thr_exit(CPUArchState *cpu_env, abi_ulong tid_addr) - static abi_long do_freebsd_thr_kill(long id, int sig) - { - -- return get_errno(thr_kill(id, sig)); -+ return get_errno(thr_kill(id, target_to_host_signal(sig))); - } - - static abi_long do_freebsd_thr_kill2(pid_t pid, long id, int sig) - { - -- return get_errno(thr_kill2(pid, id, sig)); -+ return get_errno(thr_kill2(pid, id, target_to_host_signal(sig))); - } - - static abi_long do_freebsd_thr_suspend(abi_ulong target_ts) diff --git a/emulators/qemu-devel/files/extra-patch-d5c3fb7b75b4ea80e09bf3cb7ff6dd1061968d6e b/emulators/qemu-devel/files/extra-patch-d5c3fb7b75b4ea80e09bf3cb7ff6dd1061968d6e deleted file mode 100644 index 3cf18818a909..000000000000 --- a/emulators/qemu-devel/files/extra-patch-d5c3fb7b75b4ea80e09bf3cb7ff6dd1061968d6e +++ /dev/null @@ -1,86 +0,0 @@ -From d5c3fb7b75b4ea80e09bf3cb7ff6dd1061968d6e Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Tue, 2 Dec 2014 00:52:03 +0000 -Subject: [PATCH] Add sched_yield(2) and sched_get_priority_{max, min}(2) - syscall handlers. - -This change adds system call handlers and strace support for -sched_yield(2), sched_get_priority_max(2) and sched_get_priority_min(2). ---- - bsd-user/bsd-proc.h | 21 ++++++++++++++++++++- - bsd-user/freebsd/strace.list | 2 ++ - bsd-user/syscall.c | 13 +++++++++++++ - 3 files changed, 35 insertions(+), 1 deletion(-) - -diff --git a/bsd-user/bsd-proc.h b/bsd-user/bsd-proc.h -index 5c1f91a..85dff61 100644 ---- a/bsd-user/bsd-proc.h -+++ b/bsd-user/bsd-proc.h -@@ -443,6 +443,25 @@ static inline abi_long do_bsd_setpriority(abi_long which, abi_long who, - return get_errno(setpriority(which, who, prio)); - } - -+/* sched_yield(2) */ -+static inline abi_long do_bsd_sched_yield(void) -+{ - --#endif /* !__BSD_PROC_H_ */ -+ return get_errno(sched_yield()); -+} -+ -+/* sched_get_priority_min(2) */ -+static inline abi_long do_bsd_sched_get_priority_min(int policy) -+{ -+ -+ return get_errno(sched_get_priority_min(policy)); -+} -+ -+/* sched_get_priority_max(2) */ -+static inline abi_long do_bsd_sched_get_priority_max(int policy) -+{ - -+ return get_errno(sched_get_priority_max(policy)); -+} -+ -+#endif /* !__BSD_PROC_H_ */ -diff --git a/bsd-user/freebsd/strace.list b/bsd-user/freebsd/strace.list -index 6202790..b0e32fd 100644 ---- a/bsd-user/freebsd/strace.list -+++ b/bsd-user/freebsd/strace.list -@@ -191,6 +191,8 @@ - { TARGET_FREEBSD_NR_rmdir, "rmdir", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_rtprio_thread, "rtprio_thread", "%s(%d, %d, %p)", NULL, NULL }, - { TARGET_FREEBSD_NR_sbrk, "sbrk", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_sched_get_priority_max, "sched_get_priority_max", NULL, NULL, NULL }, -+{ TARGET_FREEBSD_NR_sched_get_priority_min, "sched_get_priority_min", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_sched_yield, "sched_yield", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_select, "select", NULL, NULL, NULL }, - { TARGET_FREEBSD_NR_semget, "semget", NULL, NULL, NULL }, -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 6f467f8..0e090f4 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -1425,10 +1425,23 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - ret = do_freebsd_sched_getscheduler(arg1); - break; - -+ case TARGET_FREEBSD_NR_sched_get_priority_max: /* sched_get_priority_max(2)*/ -+ ret = do_bsd_sched_get_priority_max(arg1); -+ break; -+ -+ case TARGET_FREEBSD_NR_sched_get_priority_min: /* sched_get_priority_min(2)*/ -+ ret = do_bsd_sched_get_priority_min(arg1); -+ break; -+ - case TARGET_FREEBSD_NR_sched_rr_get_interval: /* sched_rr_get_interval(2) */ - ret = do_freebsd_sched_rr_get_interval(arg1, arg2); - break; - -+ case TARGET_FREEBSD_NR_sched_yield: /* sched_yield(2)*/ -+ ret = do_bsd_sched_yield(); -+ break; -+ -+ - /* - * FreeBSD CPU affinity sets management - */ diff --git a/emulators/qemu-devel/files/extra-patch-d62553b108aa27c0c020dbb771d29f8673807a3b b/emulators/qemu-devel/files/extra-patch-d62553b108aa27c0c020dbb771d29f8673807a3b deleted file mode 100644 index 11da6554b90c..000000000000 --- a/emulators/qemu-devel/files/extra-patch-d62553b108aa27c0c020dbb771d29f8673807a3b +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/bsd-user/mips/target_arch_sigtramp.h b/bsd-user/mips/target_arch_sigtramp.h -index 5e3c69a..2ec591f 100644 ---- a/bsd-user/mips/target_arch_sigtramp.h -+++ b/bsd-user/mips/target_arch_sigtramp.h -@@ -8,7 +8,7 @@ static inline abi_long setup_sigtramp(abi_ulong offset, unsigned sigf_uc, - { - int i; - uint32_t sigtramp_code[TARGET_SZSIGCODE/TARGET_INSN_SIZE] = { -- /* 1 */ 0x67A40000 + sigf_uc, /* daddu $a0, $sp, (sigf_uc) */ -+ /* 1 */ 0x27A40000 + sigf_uc, /* daddu $a0, $sp, (sigf_uc) */ - /* 2 */ 0x24020000 + sys_sigreturn, /* li $v0, (sys_sigreturn) */ - /* 3 */ 0x0000000C, /* syscall */ - /* 4 */ 0x0000000D /* break */ diff --git a/emulators/qemu-devel/files/extra-patch-d9388715135ed1f36e12e6cdbcc1be09d1657916 b/emulators/qemu-devel/files/extra-patch-d9388715135ed1f36e12e6cdbcc1be09d1657916 deleted file mode 100644 index 9b84e18ec838..000000000000 --- a/emulators/qemu-devel/files/extra-patch-d9388715135ed1f36e12e6cdbcc1be09d1657916 +++ /dev/null @@ -1,112 +0,0 @@ -From d9388715135ed1f36e12e6cdbcc1be09d1657916 Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Tue, 4 Nov 2014 22:14:50 +0000 -Subject: [PATCH] Add stubs for the new cap_*() system calls. - -This change adds stubs for cap_right_limit(2), cap_ioctls_limit(2), -cap_ioctls_get(2), cap_fcntls_limit(2), and cap_fcntls_get(2) system calls. ---- - bsd-user/freebsd/os-proc.h | 42 ++++++++++++++++++++++++++++++++++++++++++ - bsd-user/freebsd/syscall_nr.h | 7 ++++++- - bsd-user/syscall.c | 20 ++++++++++++++++++++ - 3 files changed, 68 insertions(+), 1 deletion(-) - -diff --git a/bsd-user/freebsd/os-proc.h b/bsd-user/freebsd/os-proc.h -index 8e28f04..cd05e96 100644 ---- a/bsd-user/freebsd/os-proc.h -+++ b/bsd-user/freebsd/os-proc.h -@@ -419,6 +419,48 @@ static inline abi_long do_freebsd_cap_getmode(abi_ulong arg1) - return -TARGET_ENOSYS; - } - -+/* cap_rights_limit(2) */ -+static inline abi_long do_freebsd_cap_rights_limit(int arg1, abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_rights_limit()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_ioctls_limit(2) */ -+static inline abi_long do_freebsd_cap_ioctls_limit(int arg1, abi_ulong arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_ioctls_limit()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_ioctls_get(2) */ -+static inline abi_long do_freebsd_cap_ioctls_get(int arg1, abi_ulong arg2, -+ abi_ulong arg3) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_ioctls_limit()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_fcntls_limit(2) */ -+static inline abi_long do_freebsd_cap_fcntls_limit(int arg1, abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_fcntls_limit()\n"); -+ return -TARGET_ENOSYS; -+} -+ -+/* cap_fcntls_get(2) */ -+static inline abi_long do_freebsd_cap_fcntls_get(int arg1, abi_ulong arg2) -+{ -+ -+ qemu_log("qemu: Unsupported syscall cap_fcntls_get()\n"); -+ return -TARGET_ENOSYS; -+} -+ - /* audit(2) */ - static inline abi_long do_freebsd_audit(abi_ulong arg1, abi_ulong arg2) - { -diff --git a/bsd-user/freebsd/syscall_nr.h b/bsd-user/freebsd/syscall_nr.h -index 779e192..2ab3e1e 100644 ---- a/bsd-user/freebsd/syscall_nr.h -+++ b/bsd-user/freebsd/syscall_nr.h -@@ -448,4 +448,9 @@ - #define TARGET_FREEBSD_NR_posix_fallocate 530 - #define TARGET_FREEBSD_NR_posix_fadvise 531 - #define TARGET_FREEBSD_NR_wait6 532 --#define TARGET_FREEBSD_NR_MAXSYSCALL 533 -+#define TARGET_FREEBSD_NR_cap_rights_limit 533 -+#define TARGET_FREEBSD_NR_cap_ioctls_limit 534 -+#define TARGET_FREEBSD_NR_cap_ioctls_get 535 -+#define TARGET_FREEBSD_NR_cap_fcntls_limit 536 -+#define TARGET_FREEBSD_NR_cap_fcntls_get 537 -+#define TARGET_FREEBSD_NR_MAXSYSCALL 538 -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 4f5a008..c615bb8 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -367,6 +367,26 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - ret = do_freebsd_cap_getmode(arg1); - break; - -+ case TARGET_FREEBSD_NR_cap_rights_limit: /* cap_rights_limit(2) */ -+ ret = do_freebsd_cap_rights_limit(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_cap_ioctls_limit: /* cap_ioctls_limit(2) */ -+ ret = do_freebsd_cap_ioctls_limit(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_cap_ioctls_get: /* cap_ioctls_get(2) */ -+ ret = do_freebsd_cap_ioctls_get(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_cap_fcntls_limit: /* cap_fcntls_limit(2) */ -+ ret = do_freebsd_cap_fcntls_limit(arg1, arg2); -+ break; -+ -+ case TARGET_FREEBSD_NR_cap_fcntls_get: /* cap_fcntls_get(2) */ -+ ret = do_freebsd_cap_fcntls_get(arg1, arg2); -+ break; -+ - case TARGET_FREEBSD_NR_audit: /* audit(2) */ - ret = do_freebsd_audit(arg1, arg2); - break; diff --git a/emulators/qemu-devel/files/extra-patch-f254372f13ab5cd8f25bd1ca8641ce6d67bff3fe b/emulators/qemu-devel/files/extra-patch-f254372f13ab5cd8f25bd1ca8641ce6d67bff3fe deleted file mode 100644 index 8c5f47b3678e..000000000000 --- a/emulators/qemu-devel/files/extra-patch-f254372f13ab5cd8f25bd1ca8641ce6d67bff3fe +++ /dev/null @@ -1,170 +0,0 @@ -From f254372f13ab5cd8f25bd1ca8641ce6d67bff3fe Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Tue, 2 Dec 2014 13:57:27 +0000 -Subject: [PATCH] Eliminate "Qemu unsupported ioctl" warnings for cryptodev. - -The host may have /dev/crypto (cryptodev) support but emulation of it -for qemu targets is not supported. Therefore, return an error if -it used to eliminate the generic warning message. ---- - bsd-user/bsd-ioctl.c | 17 ++++++- - bsd-user/freebsd/os-ioctl-cmds.h | 3 ++ - bsd-user/freebsd/os-ioctl-cryptodev.h | 85 +++++++++++++++++++++++++++++++++++ - 3 files changed, 104 insertions(+), 1 deletion(-) - create mode 100644 bsd-user/freebsd/os-ioctl-cryptodev.h - -diff --git a/bsd-user/bsd-ioctl.c b/bsd-user/bsd-ioctl.c -index 10e8e54..ae4784a 100644 ---- a/bsd-user/bsd-ioctl.c -+++ b/bsd-user/bsd-ioctl.c -@@ -1,7 +1,7 @@ - /* - * BSD ioctl(2) emulation - * -- * Copyright (c) 2013 Stacey D. Son -+ * Copyright (c) 2013-14 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 -@@ -29,10 +29,13 @@ - #include <sys/ttycom.h> - #include <sys/filio.h> - -+#include <crypto/cryptodev.h> -+ - #include "qemu.h" - #include "qemu-common.h" - - #include "bsd-ioctl.h" -+#include "os-ioctl-cryptodev.h" - #include "os-ioctl-filio.h" - #include "os-ioctl-ttycom.h" - -@@ -295,6 +298,10 @@ typedef struct IOCTLEntry IOCTLEntry; - - #define MAX_STRUCT_SIZE 4096 - -+static abi_long do_ioctl_unsupported(__unused const IOCTLEntry *ie, -+ __unused uint8_t *buf_temp, __unused int fd, -+ __unused abi_long cmd, __unused abi_long arg); -+ - static IOCTLEntry ioctl_entries[] = { - #define IOC_ 0x0000 - #define IOC_R 0x0001 -@@ -331,6 +338,14 @@ static void log_unsupported_ioctl(unsigned long cmd) - gemu_log(" '%c' %3d %lu\n", (char)IOCGROUP(cmd), (int)(cmd & 0xff), IOCPARM_LEN(cmd)); - } - -+static abi_long do_ioctl_unsupported(__unused const IOCTLEntry *ie, -+ __unused uint8_t *buf_temp, __unused int fd, -+ __unused abi_long cmd, __unused abi_long arg) -+{ -+ -+ return -TARGET_ENXIO; -+} -+ - abi_long do_bsd_ioctl(int fd, abi_long cmd, abi_long arg) - { - const IOCTLEntry *ie; -diff --git a/bsd-user/freebsd/os-ioctl-cmds.h b/bsd-user/freebsd/os-ioctl-cmds.h -index 0129f9e..f10d560 100644 ---- a/bsd-user/freebsd/os-ioctl-cmds.h -+++ b/bsd-user/freebsd/os-ioctl-cmds.h -@@ -47,3 +47,6 @@ IOCTL(FIONWRITE, IOC_R, MK_PTR(TYPE_INT)) - IOCTL(FIONSPACE, IOC_R, MK_PTR(TYPE_INT)) - IOCTL(FIOSEEKDATA, IOC_RW, MK_PTR(TYPE_ULONG)) - IOCTL(FIOSEEKHOLE, IOC_RW, MK_PTR(TYPE_ULONG)) -+ -+/* crypto/cryptodev.h */ -+IOCTL_SPECIAL(CRIOGET, IOC_RW, do_ioctl_unsupported, TYPE_INT) -diff --git a/bsd-user/freebsd/os-ioctl-cryptodev.h b/bsd-user/freebsd/os-ioctl-cryptodev.h -new file mode 100644 -index 0000000..bb0d90f ---- /dev/null -+++ b/bsd-user/freebsd/os-ioctl-cryptodev.h -@@ -0,0 +1,85 @@ -+/* -+ * FreeBSD cryptodev definitions for ioctl(2) emulation -+ * -+ * Copyright (c) 2014 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 _IOCTL_CRYPTODEV_H_ -+#define _IOCTL_CRYPTODEV_H_ -+ -+/* see opencrypto/cryptodev.h */ -+ -+struct target_session_op { -+ u_int32_t cipher; -+ u_int32_t mac; -+ -+ u_int32_t keylen; -+ abi_ulong key; -+ int32_t mackeylen; -+ abi_ulong mackey; -+ -+ u_int32_t ses; -+}; -+ -+ -+struct target_session2_op { -+ u_int32_t cipher; -+ u_int32_t mac; -+ -+ u_int32_t keylen; -+ abi_ulong key; -+ int32_t mackeylen; -+ abi_ulong mackey; -+ -+ u_int32_t ses; -+ int32_t crid; -+ int pad[4]; -+}; -+ -+struct target_crypt_find_op { -+ int crid; -+ char name[32]; -+}; -+ -+struct target_crparam { -+ abi_ulong crp_p; -+ u_int crp_nbits; -+}; -+ -+#define TARGET_CRK_MAXPARAM 8 -+ -+struct target_crypt_kop { -+ u_int crk_op; -+ u_int crk_status; -+ u_short crk_iparams; -+ u_short crk_oparams; -+ u_int crk_crid; -+ struct target_crparam crk_param[TARGET_CRK_MAXPARAM]; -+}; -+ -+#define TARGET_CRIOGET TARGET_IOWR('c', 100, u_int32_t) -+#define TARGET_CRIOASYMFEAT TARGET_CIOCASYMFEAT -+#define TARGET_CRIOFINDDEV TARGET_CIOCFINDDEV -+ -+#define TARGET_CIOCGSESSION TARGET_IOWR('c', 101, struct target_session_op) -+#define TARGET_CIOCFSESSION TARGET_IOW('c', 102, u_int32_t) -+#define TARGET_CIOCCRYPT TARGET_IOWR('c', 103, struct target_crypt_op) -+#define TARGET_CIOCKEY TARGET_IOWR('c', 104, struct target_crypt_kop) -+#define TARGET_CIOCASYMFEAT TARGET_IOR('c', 105, u_int32_t) -+#define TARGET_CIOCGSESSION2 TARGET_IOWR('c', 106, struct target_session2_op) -+#define TARGET_CIOCKEY2 TARGET_IOWR('c', 107, struct target_crypt_kop) -+#define TARGET_CIOCFINDDEV TARGET_IOWR('c', 108, struct target_crypt_find_op) -+ -+#endif /* !_IOCTL_CRYPTODEV_H_ */ diff --git a/emulators/qemu-devel/files/extra-patch-f32d585446698e1faa319c95df6b4d00c16f866c b/emulators/qemu-devel/files/extra-patch-f32d585446698e1faa319c95df6b4d00c16f866c deleted file mode 100644 index dddad5432bcf..000000000000 --- a/emulators/qemu-devel/files/extra-patch-f32d585446698e1faa319c95df6b4d00c16f866c +++ /dev/null @@ -1,81 +0,0 @@ -From f32d585446698e1faa319c95df6b4d00c16f866c Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Wed, 5 Nov 2014 20:55:35 +0000 -Subject: [PATCH] The new system calls were actually added in 10.0. - -This change fixes when cap_*[_limit, _get](2), bindat(2), connectat(2), -and wait6(2) were actually added to the FreeBSD kernel. ---- - bsd-user/freebsd/os-proc.h | 8 ++++---- - bsd-user/freebsd/os-socket.h | 6 +++--- - 2 files changed, 7 insertions(+), 7 deletions(-) - -diff --git a/bsd-user/freebsd/os-proc.h b/bsd-user/freebsd/os-proc.h -index cd05e96..612a5fd 100644 ---- a/bsd-user/freebsd/os-proc.h -+++ b/bsd-user/freebsd/os-proc.h -@@ -20,7 +20,7 @@ - #ifndef __FREEBSD_PROC_H_ - #define __FREEBSD_PROC_H_ - --#if defined(__FreeBSD_version) && __FreeBSD_version > 1100000 -+#if defined(__FreeBSD_version) && __FreeBSD_version >= 1000000 - #include <sys/signal.h> - #endif - #include <sys/types.h> -@@ -75,7 +75,7 @@ static inline abi_long do_freebsd_wait4(abi_long arg1, abi_ulong target_status, - return ret; - } - --#if defined(__FreeBSD_version) && __FreeBSD_version > 1100000 -+#if defined(__FreeBSD_version) && __FreeBSD_version >= 1000000 - /* wait6(2) */ - static inline abi_long do_freebsd_wait6(abi_long idtype, abi_long id, - abi_ulong target_status, abi_long options, abi_ulong target_wrusage, -@@ -112,7 +112,7 @@ static inline abi_long do_freebsd_wait6(abi_long idtype, abi_long id, - return ret; - } - --#else /* ! __FreeBSD_version > 1100000 */ -+#else /* ! __FreeBSD_version >= 1000000 */ - - static inline abi_long do_freebsd_wait6( __unused abi_long idtype, - __unused abi_long id, __unused abi_ulong target_status, -@@ -123,7 +123,7 @@ static inline abi_long do_freebsd_wait6( __unused abi_long idtype, - qemu_log("qemu: Unsupported syscall wait6()\n"); - return -TARGET_ENOSYS; - } --#endif /* __FreeBSD_version > 1100000 */ -+#endif /* __FreeBSD_version >= 1000000 */ - - #if defined(__FreeBSD_version) && __FreeBSD_version > 900000 - /* setloginclass(2) */ -diff --git a/bsd-user/freebsd/os-socket.h b/bsd-user/freebsd/os-socket.h -index 61e3440..4212f0a 100644 ---- a/bsd-user/freebsd/os-socket.h -+++ b/bsd-user/freebsd/os-socket.h -@@ -557,7 +557,7 @@ static inline abi_long do_freebsd_sendfile(abi_long fd, abi_long s, - return -TARGET_ENOSYS; - } - --#if defined(__FreeBSD_version) && __FreeBSD_version > 1100000 -+#if defined(__FreeBSD_version) && __FreeBSD_version >= 1000000 - /* bindat(2) */ - static inline abi_long do_bsd_bindat(int fd, int sockfd, abi_ulong target_addr, - socklen_t addrlen) -@@ -632,7 +632,7 @@ static inline abi_long do_bsd_accept4(int fd, abi_ulong target_addr, - return ret; - } - --#else /* ! __FreeBSD_version > 1100000 */ -+#else /* ! __FreeBSD_version >= 1000000 */ - - /* bindat(2) */ - static inline abi_long do_bsd_bindat(__unused int sockfd, -@@ -660,5 +660,5 @@ static inline abi_long do_bsd_accept4(__unused int fd, - qemu_log("qemu: Unsupported syscall accept4()\n"); - return -TARGET_ENOSYS; - } --#endif /* ! __FreeBSD_version > 1100000 */ -+#endif /* ! __FreeBSD_version >= 1000000 */ - #endif /* !__FREEBSD_SOCKET_H_ */ diff --git a/emulators/qemu-devel/files/extra-patch-f4319eb1a3a8393930570f061bdac6abe007b2bb b/emulators/qemu-devel/files/extra-patch-f4319eb1a3a8393930570f061bdac6abe007b2bb deleted file mode 100644 index f374c4be66e7..000000000000 --- a/emulators/qemu-devel/files/extra-patch-f4319eb1a3a8393930570f061bdac6abe007b2bb +++ /dev/null @@ -1,56 +0,0 @@ -From f4319eb1a3a8393930570f061bdac6abe007b2bb Mon Sep 17 00:00:00 2001 -From: Stacey Son <sson@FreeBSD.org> -Date: Tue, 2 Dec 2014 01:23:34 +0000 -Subject: [PATCH] Add missing setresgid(2) and setresuid(2) system call - handlers. - ---- - bsd-user/bsd-proc.h | 12 +++++++++--- - bsd-user/syscall.c | 8 ++++++++ - 2 files changed, 17 insertions(+), 3 deletions(-) - -diff --git a/bsd-user/bsd-proc.h b/bsd-user/bsd-proc.h -index 85dff61..459d321 100644 ---- a/bsd-user/bsd-proc.h -+++ b/bsd-user/bsd-proc.h -@@ -303,12 +303,18 @@ static inline abi_long do_bsd_setregid(abi_long arg1, abi_long arg2) - return get_errno(setregid(arg1, arg2)); - } - -+/* setresgid(2) */ -+static inline abi_long do_bsd_setresgid(gid_t rgid, gid_t egid, gid_t sgid) -+{ -+ -+ return get_errno(setresgid(rgid, egid, sgid)); -+} -+ - /* setresuid(2) */ --static inline abi_long do_bsd_setresuid(abi_long arg1, abi_long arg2, -- abi_long arg3) -+static inline abi_long do_bsd_setresuid(uid_t ruid, uid_t euid, uid_t suid) - { - -- return get_errno(setresuid(arg1, arg2, arg3)); -+ return get_errno(setresuid(ruid, euid, suid)); - } - - /* getresuid(2) */ -diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c -index 0e090f4..0a1e294 100644 ---- a/bsd-user/syscall.c -+++ b/bsd-user/syscall.c -@@ -298,6 +298,14 @@ abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1, - ret = do_bsd_getresgid(arg1, arg2, arg3); - break; - -+ case TARGET_FREEBSD_NR_setresuid: /* setresuid(2) */ -+ ret = do_bsd_setresuid(arg1, arg2, arg3); -+ break; -+ -+ case TARGET_FREEBSD_NR_setresgid: /* setresgid(2) */ -+ ret = do_bsd_setresgid(arg1, arg2, arg3); -+ break; -+ - case TARGET_FREEBSD_NR_getsid: /* getsid(2) */ - ret = do_bsd_getsid(arg1); - break; diff --git a/emulators/qemu-devel/files/extra-patch-fd7ec8e06cd1876ef478975f052ff64134d19c6c b/emulators/qemu-devel/files/extra-patch-fd7ec8e06cd1876ef478975f052ff64134d19c6c deleted file mode 100644 index 27bc834a9844..000000000000 --- a/emulators/qemu-devel/files/extra-patch-fd7ec8e06cd1876ef478975f052ff64134d19c6c +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/bsd-user/freebsd/os-thread.h b/bsd-user/freebsd/os-thread.h -index 5e24852..28f737f 100644 ---- a/bsd-user/freebsd/os-thread.h -+++ b/bsd-user/freebsd/os-thread.h -@@ -68,7 +68,7 @@ static abi_long do_freebsd_thr_exit(CPUArchState *cpu_env, abi_ulong tid_addr) - } - thread_cpu = NULL; - object_unref(OBJECT(ENV_GET_CPU(cpu_env))); -- ts = ((CPUArchState *)cpu_env)->opaque; -+ ts = cpu->opaque; - g_free(ts); - pthread_exit(NULL); - /* Doesn't return */ diff --git a/emulators/qemu-devel/files/extra-patch-getvfsbyname b/emulators/qemu-devel/files/extra-patch-getvfsbyname deleted file mode 100644 index e0ee3d2fa460..000000000000 --- a/emulators/qemu-devel/files/extra-patch-getvfsbyname +++ /dev/null @@ -1,153 +0,0 @@ -diff --git a/bsd-user/freebsd/os-sys.c b/bsd-user/freebsd/os-sys.c -index 6012562..87a6aa7 100644 ---- a/bsd-user/freebsd/os-sys.c -+++ b/bsd-user/freebsd/os-sys.c -@@ -1,7 +1,7 @@ - /* - * FreeBSD sysctl() and sysarch() system call emulation - * -- * Copyright (c) 2013 Stacey D. Son -+ * Copyright (c) 2013-14 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 -@@ -19,6 +19,7 @@ - - #include <sys/types.h> - #include <sys/param.h> -+#include <sys/mount.h> - #include <sys/sysctl.h> - #include <string.h> - -@@ -28,6 +29,59 @@ - #include "target_os_vmparam.h" - - /* -+ * XXX The following should maybe go some place else. Also, see the note -+ * about using "thunk" for sysctl's that pass data using structures. -+ */ -+/* From sys/mount.h: */ -+#define TARGET_MFSNAMELEN 16 /* length of type name including null */ -+struct target_xvfsconf { -+ abi_ulong vfc_vfsops; /* filesystem op vector - not used */ -+ char vfc_name[TARGET_MFSNAMELEN]; /* filesystem type name */ -+ int32_t vfc_typenum; /* historic fs type number */ -+ int32_t vfc_refcount; /* number mounted of this type */ -+ int32_t vfc_flags; /* permanent flags */ -+ abi_ulong vfc_next; /* next int list - not used */ -+}; -+ -+/* vfc_flag definitions */ -+#define TARGET_VFCF_STATIC 0x00010000 /* statically compiled into kernel */ -+#define TARGET_VFCF_NETWORK 0x00020000 /* may get data over the network */ -+#define TARGET_VFCF_READONLY 0x00040000 /* writes are not implemented */ -+#define TARGET_VFCF_SYNTHETIC 0x00080000 /* doesn't represent real files */ -+#define TARGET_VFCF_LOOPBACK 0x00100000 /* aliases some other mounted FS */ -+#define TARGET_VFCF_UNICODE 0x00200000 /* stores file names as Unicode */ -+#define TARGET_VFCF_JAIL 0x00400000 /* can be mounted within a jail */ -+#define TARGET_VFCF_DELEGADMIN 0x00800000 /* supports delegated admin */ -+#define TARGET_VFCF_SBDRY 0x01000000 /* defer stop requests */ -+ -+static int -+host_to_target_vfc_flags(int flags) -+{ -+ int ret = 0; -+ -+ if (flags & VFCF_STATIC) -+ ret |= TARGET_VFCF_STATIC; -+ if (flags & VFCF_NETWORK) -+ ret |= TARGET_VFCF_NETWORK; -+ if (flags & VFCF_READONLY) -+ ret |= TARGET_VFCF_READONLY; -+ if (flags & VFCF_SYNTHETIC) -+ ret |= TARGET_VFCF_SYNTHETIC; -+ if (flags & VFCF_LOOPBACK) -+ ret |= TARGET_VFCF_LOOPBACK; -+ if (flags & VFCF_UNICODE) -+ ret |= TARGET_VFCF_UNICODE; -+ if (flags & VFCF_JAIL) -+ ret |= TARGET_VFCF_JAIL; -+ if (flags & VFCF_DELEGADMIN) -+ ret |= TARGET_VFCF_DELEGADMIN; -+ if (flags & VFCF_SBDRY) -+ ret |= TARGET_VFCF_SBDRY; -+ -+ return ret; -+} -+ -+/* - * 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) -@@ -161,6 +215,7 @@ abi_long do_freebsd_sysctl(CPUArchState *env, abi_ulong namep, int32_t namelen, - oidfmt(snamep, namelen, NULL, &kind); - - /* Handle some arch/emulator dependent sysctl()'s here. */ -+ /* XXX sysctl()'s that pass structs should use thunk like ioctl(). */ - switch (snamep[0]) { - case CTL_KERN: - switch (snamep[1]) { -@@ -212,6 +267,63 @@ abi_long do_freebsd_sysctl(CPUArchState *env, abi_ulong namep, int32_t namelen, - } - break; - -+ case CTL_VFS: -+ { -+ static int oid_vfs_conflist; -+ -+ if (!oid_vfs_conflist) { -+ int real_oid[CTL_MAXNAME+2]; -+ size_t len = sizeof(real_oid) / sizeof(int); -+ -+ if (sysctlnametomib("vfs.conflist", real_oid, &len) >= 0) -+ oid_vfs_conflist = real_oid[1]; -+ } -+ -+ if (oid_vfs_conflist && snamep[1] == oid_vfs_conflist) { -+ struct xvfsconf *xvfsp; -+ struct target_xvfsconf *txp; -+ int cnt, i; -+ -+ if (sysctlbyname("vfs.conflist", NULL, &holdlen, NULL, 0) < 0) { -+ ret = -1; -+ goto out; -+ } -+ cnt = holdlen / sizeof(struct xvfsconf); -+ if (!holdp) { -+ holdlen = cnt * sizeof(struct target_xvfsconf); -+ ret = 0; -+ goto out; -+ } -+ xvfsp = (struct xvfsconf *)g_malloc(holdlen); -+ if (xvfsp == NULL) { -+ ret = -TARGET_ENOMEM; -+ goto out; -+ } -+ if (sysctlbyname("vfs.conflist", xvfsp, &holdlen, NULL, 0) < 0){ -+ g_free(xvfsp); -+ ret = -1; -+ goto out; -+ } -+ cnt = holdlen / sizeof(struct xvfsconf); -+ holdlen = cnt * sizeof(struct target_xvfsconf); -+ txp = (struct target_xvfsconf *)holdp; -+ for (i = 0; i < cnt; i++) { -+ txp[i].vfc_vfsops = 0; -+ strlcpy(txp[i].vfc_name, xvfsp[i].vfc_name, -+ TARGET_MFSNAMELEN); -+ txp[i].vfc_typenum = tswap32(xvfsp[i].vfc_typenum); -+ txp[i].vfc_refcount = tswap32(xvfsp[i].vfc_refcount); -+ txp[i].vfc_flags = tswap32( -+ host_to_target_vfc_flags(xvfsp[i].vfc_flags)); -+ txp[i].vfc_next = 0; -+ } -+ g_free(xvfsp); -+ ret = 0; -+ goto out; -+ } -+ } -+ break; -+ - case CTL_HW: - switch (snamep[1]) { - case HW_MACHINE: diff --git a/emulators/qemu-devel/files/extra-patch-inherit-interp_prefix b/emulators/qemu-devel/files/extra-patch-inherit-interp_prefix deleted file mode 100644 index 3d1c360b8e07..000000000000 --- a/emulators/qemu-devel/files/extra-patch-inherit-interp_prefix +++ /dev/null @@ -1,94 +0,0 @@ -From nox Mon Sep 17 00:00:00 2001 -From: Juergen Lock <nox@jelal.kn-bremen.de> -Date: 04 Apr 2014 16:36:00 +0200 -Subject: Pass down interp_prefix (-L arg) to bsd-user child processes - -Pass down interp_prefix (-L arg) to bsd-user target child processes -so running shared target binaries as subprocesses works. - -Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de> - ---- a/bsd-user/main.c -+++ b/bsd-user/main.c -@@ -58,7 +58,7 @@ unsigned long reserved_va; - #endif - #endif /* CONFIG_USE_GUEST_BASE */ - --static const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX; -+const char *interp_prefix = CONFIG_QEMU_INTERP_PREFIX; - const char *qemu_uname_release = CONFIG_UNAME_RELEASE; - extern char **environ; - enum BSDType bsd_type; ---- a/bsd-user/qemu.h -+++ b/bsd-user/qemu.h -@@ -110,6 +110,7 @@ typedef struct TaskState { - - void init_task_state(TaskState *ts); - void stop_all_tasks(void); -+extern const char *interp_prefix; - extern const char *qemu_uname_release; - #if defined(CONFIG_USE_GUEST_BASE) - extern unsigned long mmap_min_addr; ---- a/bsd-user/freebsd/os-proc.c -+++ b/bsd-user/freebsd/os-proc.c -@@ -180,7 +180,7 @@ abi_long freebsd_exec_common(abi_ulong p - envc++; - } - -- qarg0 = argp = alloca((argc + 5) * sizeof(void *)); -+ qarg0 = argp = alloca((argc + 7) * sizeof(void *)); - /* save the first agrument for the emulator */ - *argp++ = (char *)getprogname(); - qargp = argp; -@@ -246,6 +246,11 @@ abi_long freebsd_exec_common(abi_ulong p - if (get_filename_from_fd(getpid(), (int)path_or_fd, execpath, - sizeof(execpath)) != NULL) { - *qarg1 = execpath; -+#ifndef DONT_INHERIT_INTERP_PREFIX -+ memmove(qarg1 + 2, qarg1, (qargend-qarg1) * sizeof(*qarg1)); -+ *qarg1++ = (char *)"-L"; -+ *qarg1++ = (char *)interp_prefix; -+#endif - ret = get_errno(execve(qemu_proc_pathname, qargp, envp)); - } else { - /* Getting the filename path failed. */ -@@ -261,6 +266,13 @@ abi_long freebsd_exec_common(abi_ulong p - sizeof(scriptpath)) != NULL) { - *qargp = execpath; - *qarg1 = scriptpath; -+#ifndef DONT_INHERIT_INTERP_PREFIX -+ memmove(qargp + 2, qargp, (qargend-qargp) * sizeof(*qargp)); -+ qargp[0] = (char *)"-L"; -+ qargp[1] = (char *)interp_prefix; -+ qarg1 += 2; -+ qargend += 2; -+#endif - if (scriptargs) { - memmove(qarg1 + 1, qarg1, (qargend-qarg1) * sizeof(*qarg1)); - *qarg1 = scriptargs; -@@ -292,6 +304,11 @@ abi_long freebsd_exec_common(abi_ulong p - close(fd); - /* execve() as a target binary using emulator. */ - *qarg1 = (char *)p; -+#ifndef DONT_INHERIT_INTERP_PREFIX -+ memmove(qarg1 + 2, qarg1, (qargend-qarg1) * sizeof(*qarg1)); -+ *qarg1++ = (char *)"-L"; -+ *qarg1++ = (char *)interp_prefix; -+#endif - ret = get_errno(execve(qemu_proc_pathname, qargp, envp)); - } else if (is_target_shell_script(fd, execpath, - sizeof(execpath), &scriptargs) != 0) { -@@ -299,6 +316,13 @@ abi_long freebsd_exec_common(abi_ulong p - /* execve() as a target script using emulator. */ - *qargp = execpath; - *qarg1 = (char *)p; -+#ifndef DONT_INHERIT_INTERP_PREFIX -+ memmove(qargp + 2, qargp, (qargend-qargp) * sizeof(*qargp)); -+ qargp[0] = (char *)"-L"; -+ qargp[1] = (char *)interp_prefix; -+ qarg1 += 2; -+ qargend += 2; -+#endif - if (scriptargs) { - memmove(qarg1 + 1, qarg1, (qargend-qarg1) * sizeof(*qarg1)); - *qarg1 = scriptargs; diff --git a/emulators/qemu-devel/files/extra-patch-kernproc b/emulators/qemu-devel/files/extra-patch-kernproc deleted file mode 100644 index dd5e7952a36f..000000000000 --- a/emulators/qemu-devel/files/extra-patch-kernproc +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/bsd-user/bsdload.c b/bsd-user/bsdload.c -index 28a8bba..a1d8747 100644 ---- a/bsd-user/bsdload.c -+++ b/bsd-user/bsdload.c -@@ -228,7 +228,7 @@ int loader_exec(const char * filename, char ** argv, char ** envp, - bprm->fullpath = g_strdup(fullpath); - } else { - retval = open(execname, O_RDONLY); -- bprm->fullpath = NULL; -+ bprm->fullpath = g_strdup(execname); - } - if (execname) { - g_free((void *)execname); diff --git a/emulators/qemu-devel/files/extra-patch-max-arg-pages b/emulators/qemu-devel/files/extra-patch-max-arg-pages deleted file mode 100644 index ca447f0d6090..000000000000 --- a/emulators/qemu-devel/files/extra-patch-max-arg-pages +++ /dev/null @@ -1,28 +0,0 @@ -From 200e09e4bf497b43cace6b2b2b85b943f5d59dc1 Mon Sep 17 00:00:00 2001 -From: Sean Bruno <sbruno@freebsd.org> -Date: Fri, 29 Aug 2014 14:56:00 +0000 -Subject: [PATCH] Increase MAX_ARG_PAGES to 64 (256k total arg). - -I've found that building packages, like binutils, exceeded 128k easily ---- - bsd-user/qemu.h | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h -index 09af1b4..0731c64 100644 ---- a/bsd-user/qemu.h -+++ b/bsd-user/qemu.h -@@ -121,10 +121,10 @@ extern unsigned long mmap_min_addr; - /* ??? See if we can avoid exposing so much of the loader internals. */ - /* - * MAX_ARG_PAGES defines the number of pages allocated for arguments -- * and envelope for the new program. 32 should suffice, this gives -- * a maximum env+arg of 128kB w/4KB pages! -+ * and envelope for the new program. 64 should suffice, this gives -+ * a maximum env+arg of 256kB w/4KB pages! - */ --#define MAX_ARG_PAGES 32 -+#define MAX_ARG_PAGES 64 - - /* - * This structure is used to hold the arguments that are diff --git a/emulators/qemu-devel/files/extra-patch-sysctl-0oldlen b/emulators/qemu-devel/files/extra-patch-sysctl-0oldlen deleted file mode 100644 index 0f2d96e5ee1d..000000000000 --- a/emulators/qemu-devel/files/extra-patch-sysctl-0oldlen +++ /dev/null @@ -1,34 +0,0 @@ -From nox Mon Sep 17 00:00:00 2001 -From: Juergen Lock <nox@jelal.kn-bremen.de> -Date: 05 Apr 2014 23:36:00 +0200 -Subject: Fix FreeBSD sysctls kern.usrstack and kern.ps_strings - -Fix FreeBSD sysctls kern.usrstack and kern.ps_strings invoked with -oidlen zero. (like from sysctl(8)) - -Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de> - ---- a/bsd-user/freebsd/os-sys.c -+++ b/bsd-user/freebsd/os-sys.c -@@ -165,7 +165,9 @@ abi_long do_freebsd_sysctl(CPUArchState - switch (snamep[1]) { - case KERN_USRSTACK: - #if TARGET_USRSTACK != 0 -- (*(abi_ulong *)holdp) = tswapal(TARGET_USRSTACK); -+ if (oldlen) { -+ (*(abi_ulong *)holdp) = tswapal(TARGET_USRSTACK); -+ } - holdlen = sizeof(abi_ulong); - ret = 0; - #else -@@ -175,7 +177,9 @@ abi_long do_freebsd_sysctl(CPUArchState - - case KERN_PS_STRINGS: - #if defined(TARGET_PS_STRINGS) -- (*(abi_ulong *)holdp) = tswapal(TARGET_PS_STRINGS); -+ if (oldlen) { -+ (*(abi_ulong *)holdp) = tswapal(TARGET_PS_STRINGS); -+ } - holdlen = sizeof(abi_ulong); - ret = 0; - #else diff --git a/emulators/qemu-devel/files/extra-patch-sysctl-hw-availpages b/emulators/qemu-devel/files/extra-patch-sysctl-hw-availpages deleted file mode 100644 index 5253802430bc..000000000000 --- a/emulators/qemu-devel/files/extra-patch-sysctl-hw-availpages +++ /dev/null @@ -1,63 +0,0 @@ -From nox Mon Sep 17 00:00:00 2001 -From: Juergen Lock <nox@jelal.kn-bremen.de> -Date: 05 Apr 2014 21:06:00 +0200 -Subject: Fix bsd-user FreeBSD hw.availpages sysctl - -hw.availpages is defined as OID_AUTO so the mib can change; find out -it's value at the first hw.* sysctl syscall. - -Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de> - ---- a/bsd-user/freebsd/os-sys.c -+++ b/bsd-user/freebsd/os-sys.c -@@ -219,24 +219,36 @@ abi_long do_freebsd_sysctl(CPUArchState - ret = 0; - goto out; - -- case 851: /* hw.availpages */ -+ default: - { -- long lvalue; -- size_t len = sizeof(lvalue); -+ static int oid_hw_availpages; -+ -+ if (!oid_hw_availpages) { -+ int real_oid[CTL_MAXNAME+2]; -+ size_t len = sizeof(real_oid) / sizeof(int); - -- 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; -+ if (sysctlnametomib("hw.availpages", real_oid, &len) >= 0) -+ oid_hw_availpages = real_oid[1]; - } -- } -- goto out; - -- default: -- break; -+ if (oid_hw_availpages && snamep[1] == oid_hw_availpages) { -+ long lvalue; -+ size_t len = sizeof(lvalue); -+ -+ if (sysctlbyname("hw.availpages", &lvalue, &len, NULL, 0) -+ == -1) { -+ ret = -1; -+ } else { -+ if (oldlen) { -+ (*(abi_ulong *)holdp) = tswapal((abi_ulong)lvalue); -+ } -+ holdlen = sizeof(abi_ulong); -+ ret = 0; -+ } -+ goto out; -+ } -+ break; -+ } - } - default: - break; diff --git a/emulators/qemu-devel/files/extra-patch-sysctl-hw-pagesizes b/emulators/qemu-devel/files/extra-patch-sysctl-hw-pagesizes deleted file mode 100644 index d54af5435574..000000000000 --- a/emulators/qemu-devel/files/extra-patch-sysctl-hw-pagesizes +++ /dev/null @@ -1,53 +0,0 @@ -From nox Mon Sep 17 00:00:00 2001 -From: Juergen Lock <nox@jelal.kn-bremen.de> -Date: 05 May 2014 00:54:00 +0200 -Subject: Handle bsd-user FreeBSD hw.pagesizes sysctl - -hw.pagesizes is defined as OID_AUTO so the mib can change; find out -it's value at the first hw.* sysctl syscall. -Handle it by returning only getpagesize() for now. - -Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de> - ---- a/bsd-user/freebsd/os-sys.c -+++ b/bsd-user/freebsd/os-sys.c -@@ -227,6 +227,7 @@ abi_long do_freebsd_sysctl(CPUArchState - default: - { - static int oid_hw_availpages; -+ static int oid_hw_pagesizes; - - if (!oid_hw_availpages) { - int real_oid[CTL_MAXNAME+2]; -@@ -235,6 +236,13 @@ abi_long do_freebsd_sysctl(CPUArchState - if (sysctlnametomib("hw.availpages", real_oid, &len) >= 0) - oid_hw_availpages = real_oid[1]; - } -+ if (!oid_hw_pagesizes) { -+ int real_oid[CTL_MAXNAME+2]; -+ size_t len = sizeof(real_oid) / sizeof(int); -+ -+ if (sysctlnametomib("hw.pagesizes", real_oid, &len) >= 0) -+ oid_hw_pagesizes = real_oid[1]; -+ } - - if (oid_hw_availpages && snamep[1] == oid_hw_availpages) { - long lvalue; -@@ -252,6 +260,17 @@ abi_long do_freebsd_sysctl(CPUArchState - } - goto out; - } -+ -+ if (oid_hw_pagesizes && snamep[1] == oid_hw_pagesizes) { -+ // XXX some targets do superpages now too... */ -+ if (oldlen) { -+ (*(abi_ulong *)holdp) = tswapal((abi_ulong)getpagesize()); -+ ((abi_ulong *)holdp)[1] = 0; -+ } -+ holdlen = sizeof(abi_ulong) * 2; -+ ret = 0; -+ goto out; -+ } - break; - } - } diff --git a/emulators/qemu-devel/files/extra-patch-sysctl-hw-physmem b/emulators/qemu-devel/files/extra-patch-sysctl-hw-physmem deleted file mode 100644 index 304000d093b6..000000000000 --- a/emulators/qemu-devel/files/extra-patch-sysctl-hw-physmem +++ /dev/null @@ -1,40 +0,0 @@ -From nox Mon Sep 17 00:00:00 2001 -From: Juergen Lock <nox@jelal.kn-bremen.de> -Date: 23 Aug 2014 00:24:00 +0200 -Subject: Fix FreeBSD sysctl hw.physmem - -Fix FreeBSD sysctl hw.physmem if host bitsize != target's. - -Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de> - ---- a/bsd-user/freebsd/os-sys.c -+++ b/bsd-user/freebsd/os-sys.c -@@ -338,6 +338,28 @@ abi_long do_freebsd_sysctl(CPUArchState - ret = 0; - goto out; - -+#if TARGET_ABI_BITS != HOST_LONG_BITS -+ case HW_PHYSMEM: -+ holdlen = sizeof(abi_ulong); -+ ret = 0; -+ -+ if (oldlen) { -+ unsigned long lvalue; -+ size_t len = sizeof(lvalue); -+ -+ if (sysctlbyname("hw.physmem", &lvalue, &len, NULL, 0) -+ == -1) { -+ ret = -1; -+ } else { -+ abi_ulong maxmem = -0x100c000; -+ if (((unsigned long)maxmem) < lvalue) -+ lvalue = maxmem; -+ (*(abi_ulong *)holdp) = lvalue; -+ } -+ } -+ goto out; -+#endif -+ - default: - { - static int oid_hw_availpages; diff --git a/emulators/qemu-devel/files/extra-patch-target_siginfo b/emulators/qemu-devel/files/extra-patch-target_siginfo deleted file mode 100644 index 4058f191eed9..000000000000 --- a/emulators/qemu-devel/files/extra-patch-target_siginfo +++ /dev/null @@ -1,37 +0,0 @@ -From nox Mon Sep 17 00:00:00 2001 -From: Juergen Lock <nox@jelal.kn-bremen.de> -Date: 22 Jun 2014 00:52:23 +0200 -Subject: Fix bsd-user default TARGET_SIGINFO handling - -TARGET_SIGINFO doesn't kill the process and also doesn't cause EINTR -by default so add it to fatal_signal() appropriately; and also don't -call force_sig() on it should it end up being handled. - -Signed-off-by: Juergen Lock <nox@jelal.kn-bremen.de> - ---- a/bsd-user/signal.c -+++ b/bsd-user/signal.c -@@ -391,6 +391,7 @@ int queue_signal(CPUArchState *env, int - if (sig != TARGET_SIGCHLD && - sig != TARGET_SIGURG && - sig != TARGET_SIGWINCH && -+ sig != TARGET_SIGINFO && - sig != TARGET_SIGCONT) { - force_sig(sig); - } else { -@@ -531,6 +532,7 @@ static int fatal_signal(int sig) - case TARGET_SIGCHLD: - case TARGET_SIGURG: - case TARGET_SIGWINCH: -+ case TARGET_SIGINFO: - /* Ignored by default. */ - return 0; - case TARGET_SIGCONT: -@@ -884,6 +886,7 @@ handle_signal: - TARGET_SIGTTOU == sig) { - kill(getpid(), SIGSTOP); - } else if (TARGET_SIGCHLD != sig && TARGET_SIGURG != sig && -+ TARGET_SIGINFO != sig && - TARGET_SIGWINCH != sig && TARGET_SIGCONT != sig) { - force_sig(sig); - } diff --git a/emulators/qemu-devel/files/patch-90_security b/emulators/qemu-devel/files/patch-90_security index 65c340549de4..ffd22741dd2e 100644 --- a/emulators/qemu-devel/files/patch-90_security +++ b/emulators/qemu-devel/files/patch-90_security @@ -14,27 +14,6 @@ Index: qemu/hw/dma/i8257.c ldebug ("dma_pos %d size %d\n", n, (r->base[COUNT] + 1) << ncont); } -Index: qemu/hw/block/fdc.c -@@ -1445,7 +1445,8 @@ static uint32_t fdctrl_read_data(FDCtrl - fd_sector(cur_drv)); - return 0; - } -- if (bdrv_read(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) { -+ if (cur_drv->bs == NULL || -+ bdrv_read(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) { - FLOPPY_DPRINTF("error getting sector %d\n", - fd_sector(cur_drv)); - /* Sure, image size is too small... */ -@@ -1905,7 +1906,8 @@ static void fdctrl_write_data(FDCtrl *fd - if (pos == FD_SECTOR_LEN - 1 || - fdctrl->data_pos == fdctrl->data_len) { - cur_drv = get_cur_drv(fdctrl); -- if (bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) { -+ if (cur_drv->bs == NULL || -+ bdrv_write(cur_drv->bs, fd_sector(cur_drv), fdctrl->fifo, 1) < 0) { - FLOPPY_DPRINTF("error writing sector %d\n", - fd_sector(cur_drv)); - return; Index: qemu-0.8.2/hw/audio/sb16.c @@ -1235,8 +1235,10 @@ static int SB_read_DMA (void *opaque, in s->block_size); @@ -49,14 +28,3 @@ Index: qemu-0.8.2/hw/audio/sb16.c } return dma_pos; -Index: qemu/hw/intc/i8259.c -@@ -291,7 +291,8 @@ static void pic_ioport_write(void *opaqu - s->init4 = val & 1; - s->single_mode = val & 2; - if (val & 0x08) { -- hw_error("level sensitive irq not supported"); -+ /* hw_error("level sensitive irq not supported"); */ -+ return; - } - } else if (val & 0x08) { - if (val & 0x04) { diff --git a/emulators/qemu-devel/files/patch-configure b/emulators/qemu-devel/files/patch-configure index e87341476e6b..7a0be6132bbb 100644 --- a/emulators/qemu-devel/files/patch-configure +++ b/emulators/qemu-devel/files/patch-configure @@ -1,24 +1,24 @@ --- a/configure +++ a/configure -@@ -192,7 +192,7 @@ gcov="no" - gcov_tool="gcov" - EXESUF="" +@@ -273,7 +273,7 @@ DSOSUF=".so" + LDFLAGS_SHARED="-shared" + modules="no" prefix="/usr/local" -mandir="\${prefix}/share/man" +mandir="\${prefix}/man" datadir="\${prefix}/share" qemu_docdir="\${prefix}/share/doc/qemu" bindir="\${prefix}/bin" -@@ -1980,7 +1980,7 @@ if test "$gtk" != "no"; then - if $pkg_config --exists "$gtkpackage >= $gtkversion"; then - gtk_cflags=`$pkg_config --cflags $gtkpackage` - gtk_libs=`$pkg_config --libs $gtkpackage` +@@ -2062,7 +2062,7 @@ if test "$gtk" != "no"; then + if $pkg_config --exists "$gtkx11package >= $gtkversion"; then + gtk_libs="$gtk_libs -lX11" + fi - libs_softmmu="$gtk_libs $libs_softmmu" + libs_softmmu="$gtk_libs -lintl $libs_softmmu" gtk="yes" elif test "$gtk" = "yes"; then - feature_not_found "gtk" "Install gtk2 or gtk3 (requires --with-gtkabi=3.0 option to configure) devel" -@@ -3320,15 +3320,18 @@ if compile_prog "" "" ; then + feature_not_found "gtk" "Install gtk2 or gtk3 devel" +@@ -3500,15 +3500,18 @@ if compile_prog "" "" ; then fi # Check if tools are available to build documentation. @@ -45,7 +45,7 @@ fi # Search for bswap_32 function -@@ -3498,6 +3501,17 @@ fi +@@ -3650,6 +3653,17 @@ fi # check for libusb if test "$libusb" != "no" ; then @@ -63,7 +63,7 @@ if $pkg_config --atleast-version=1.0.13 libusb-1.0; then libusb="yes" libusb_cflags=$($pkg_config --cflags libusb-1.0) -@@ -3510,6 +3524,7 @@ if test "$libusb" != "no" ; then +@@ -3662,6 +3676,7 @@ if test "$libusb" != "no" ; then fi libusb="no" fi diff --git a/emulators/qemu-devel/files/patch-disas-libvixl-a64-disasm-a64.cc b/emulators/qemu-devel/files/patch-disas-libvixl-a64-disasm-a64.cc new file mode 100644 index 000000000000..3cfe79312f65 --- /dev/null +++ b/emulators/qemu-devel/files/patch-disas-libvixl-a64-disasm-a64.cc @@ -0,0 +1,12 @@ +--- a/disas/libvixl/a64/disasm-a64.cc ++++ b/disas/libvixl/a64/disasm-a64.cc +@@ -1337,7 +1337,8 @@ void Disassembler::AppendPCRelativeOffse + int64_t offset) { + USE(instr); + char sign = (offset < 0) ? '-' : '+'; +- AppendToOutput("#%c0x%" PRIx64, sign, std::abs(offset)); ++ // AppendToOutput("#%c0x%" PRIx64, sign, std::abs(offset)); ++ AppendToOutput("#%c0x%" PRIx64, sign, offset < 0 ? -offset : offset); + } + + diff --git a/emulators/qemu-devel/files/patch-hw-usb-host-libusb.c b/emulators/qemu-devel/files/patch-hw-usb-host-libusb.c deleted file mode 100644 index 2d46b9215dfb..000000000000 --- a/emulators/qemu-devel/files/patch-hw-usb-host-libusb.c +++ /dev/null @@ -1,15 +0,0 @@ ---- a/hw/usb/host-libusb.c -+++ b/hw/usb/host-libusb.c -@@ -1324,8 +1324,12 @@ static Property usb_host_dev_properties[ - DEFINE_PROP_UINT32("isobufs", USBHostDevice, iso_urb_count, 4), - DEFINE_PROP_UINT32("isobsize", USBHostDevice, iso_urb_frames, 32), - DEFINE_PROP_INT32("bootindex", USBHostDevice, bootindex, -1), -+#ifdef LIBUSB_LOG_LEVEL_WARNING - DEFINE_PROP_UINT32("loglevel", USBHostDevice, loglevel, - LIBUSB_LOG_LEVEL_WARNING), -+#else -+ DEFINE_PROP_UINT32("loglevel", USBHostDevice, loglevel, 0), -+#endif - DEFINE_PROP_BIT("pipeline", USBHostDevice, options, - USB_HOST_OPT_PIPELINE, true), - DEFINE_PROP_END_OF_LIST(), diff --git a/emulators/qemu-devel/files/patch-net-tap-bsd.c b/emulators/qemu-devel/files/patch-net-tap-bsd.c new file mode 100644 index 000000000000..83239d4d560a --- /dev/null +++ b/emulators/qemu-devel/files/patch-net-tap-bsd.c @@ -0,0 +1,10 @@ +--- a/net/tap-bsd.c ++++ b/net/tap-bsd.c +@@ -29,6 +29,7 @@ + + #if defined(__NetBSD__) || defined(__FreeBSD__) + #include <sys/ioctl.h> ++#include <sys/socket.h> + #include <net/if.h> + #include <net/if_tap.h> + #endif diff --git a/emulators/qemu-devel/files/patch-qemu-include-net-net.h b/emulators/qemu-devel/files/patch-qemu-include-net-net.h index 719e8baf1210..401f91246ee1 100644 --- a/emulators/qemu-devel/files/patch-qemu-include-net-net.h +++ b/emulators/qemu-devel/files/patch-qemu-include-net-net.h @@ -10,15 +10,3 @@ Index: qemu/include/net/net.h #define DEFAULT_BRIDGE_HELPER CONFIG_QEMU_HELPERDIR "/qemu-bridge-helper" #define DEFAULT_BRIDGE_INTERFACE "br0" -Index: qemu/net/tap_int.h -@@ -29,8 +29,8 @@ - #include "qemu-common.h" - #include "qemu-option.h" - --#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup" --#define DEFAULT_NETWORK_DOWN_SCRIPT "/etc/qemu-ifdown" -+#define DEFAULT_NETWORK_SCRIPT PREFIX "/etc/qemu-ifup" -+#define DEFAULT_NETWORK_DOWN_SCRIPT PREFIX "/etc/qemu-ifdown" - - int net_init_tap(QemuOpts *opts, Monitor *mon, const char *name, VLANState *vlan); - diff --git a/emulators/qemu-devel/files/patch-ui-gtk.c b/emulators/qemu-devel/files/patch-ui-gtk.c deleted file mode 100644 index b71eb187119c..000000000000 --- a/emulators/qemu-devel/files/patch-ui-gtk.c +++ /dev/null @@ -1,14 +0,0 @@ ---- a/ui/gtk.c -+++ b/ui/gtk.c -@@ -714,7 +718,11 @@ static gboolean gd_key_event(GtkWidget * - } else if (gdk_keycode < 97) { - qemu_keycode = gdk_keycode - 8; - } else if (gdk_keycode < 158) { -+#if 0 - qemu_keycode = translate_evdev_keycode(gdk_keycode - 97); -+#else -+ qemu_keycode = translate_xfree86_keycode(gdk_keycode - 97); -+#endif - } else if (gdk_keycode == 208) { /* Hiragana_Katakana */ - qemu_keycode = 0x70; - } else if (gdk_keycode == 211) { /* backslash */ diff --git a/emulators/qemu-devel/files/pcap-patch b/emulators/qemu-devel/files/pcap-patch index 497827e6037c..d22c8aa2b003 100644 --- a/emulators/qemu-devel/files/pcap-patch +++ b/emulators/qemu-devel/files/pcap-patch @@ -1,16 +1,16 @@ --- configure.orig +++ configure -@@ -324,6 +324,9 @@ tpm="no" - libssh2="" +@@ -335,6 +335,9 @@ libssh2="" vhdx="" - quorum="no" + quorum="" + numa="" +pcap="no" +pcap_create="no" +bpf="no" # parse CC options first for opt do -@@ -865,6 +868,10 @@ for opt do +@@ -888,6 +891,10 @@ for opt do ;; --enable-vnc-ws) vnc_ws="yes" ;; @@ -21,7 +21,7 @@ --disable-slirp) slirp="no" ;; --disable-uuid) uuid="no" -@@ -2130,6 +2137,51 @@ EOF +@@ -2216,6 +2223,51 @@ EOF fi ########################################## @@ -73,7 +73,7 @@ # VNC TLS/WS detection if test "$vnc" = "yes" -a \( "$vnc_tls" != "no" -o "$vnc_ws" != "no" \) ; then cat > $TMPC <<EOF -@@ -4133,6 +4185,7 @@ echo "Audio drivers $audio_drv_list" +@@ -4286,6 +4338,7 @@ echo "Audio drivers $audio_drv_list" echo "Block whitelist (rw) $block_drv_rw_whitelist" echo "Block whitelist (ro) $block_drv_ro_whitelist" echo "VirtFS support $virtfs" @@ -81,7 +81,7 @@ echo "VNC support $vnc" if test "$vnc" = "yes" ; then echo "VNC TLS support $vnc_tls" -@@ -4297,6 +4350,15 @@ fi +@@ -4447,6 +4500,15 @@ fi if test "$profiler" = "yes" ; then echo "CONFIG_PROFILER=y" >> $config_host_mak fi @@ -98,10 +98,11 @@ echo "CONFIG_SLIRP=y" >> $config_host_mak echo "CONFIG_SMBD_COMMAND=\"$smbd\"" >> $config_host_mak Index: net/clients.h -@@ -47,6 +47,11 @@ int net_init_tap(const NetClientOptions - int net_init_bridge(const NetClientOptions *opts, const char *name, - NetClientState *peer); +@@ -49,6 +49,12 @@ int net_init_bridge(const NetClientOptio + int net_init_l2tpv3(const NetClientOptions *opts, const char *name, + NetClientState *peer); ++ +#ifdef CONFIG_PCAP +int net_init_pcap(const NetClientOptions *opts, const char *name, + NetClientState *peer); @@ -357,7 +358,7 @@ Index: net/net.c --- qapi-schema.json.orig +++ qapi-schema.json -@@ -2622,6 +2622,10 @@ +@@ -2165,6 +2165,10 @@ '*br': 'str', '*helper': 'str' } } @@ -368,21 +369,21 @@ Index: net/net.c ## # @NetdevHubPortOptions # -@@ -2648,6 +2652,7 @@ - 'nic': 'NetLegacyNicOptions', +@@ -2232,6 +2236,7 @@ 'user': 'NetdevUserOptions', 'tap': 'NetdevTapOptions', + 'l2tpv3': 'NetdevL2TPv3Options', + 'pcap': 'NetdevPcapOptions', 'socket': 'NetdevSocketOptions', 'vde': 'NetdevVdeOptions', 'dump': 'NetdevDumpOptions', --- net/hub.c.orig +++ net/hub.c -@@ -322,6 +322,7 @@ void net_hub_check_clients(void) - case NET_CLIENT_OPTIONS_KIND_TAP: - case NET_CLIENT_OPTIONS_KIND_SOCKET: - case NET_CLIENT_OPTIONS_KIND_VDE: +@@ -325,6 +325,7 @@ void net_hub_check_clients(void) + case NET_CLIENT_OPTIONS_KIND_VHOST_USER: + case NET_CLIENT_OPTIONS_KIND_PCAP: has_host_dev = 1; break; default: + break; + } diff --git a/emulators/qemu-devel/pkg-plist b/emulators/qemu-devel/pkg-plist index dc3d821dcc71..bf5abfd7c319 100644 --- a/emulators/qemu-devel/pkg-plist +++ b/emulators/qemu-devel/pkg-plist @@ -25,6 +25,7 @@ %%NONX86%%bin/qemu-system-sh4eb %%NONX86%%bin/qemu-system-sparc %%NONX86%%bin/qemu-system-sparc64 +%%NONX86%%bin/qemu-system-tricore %%NONX86%%bin/qemu-system-unicore32 %%BSD_USER%%bin/qemu-arm%%STATIC%% %%BSD_USER%%bin/qemu-i386%%STATIC%% @@ -85,6 +86,8 @@ %%SOFTMMU%%%%DATADIR%%/kvmvapic.bin %%SOFTMMU%%%%DATADIR%%/qemu-icon.bmp %%SOFTMMU%%%%DATADIR%%/qemu_logo_no_text.svg +%%SOFTMMU%%%%DATADIR%%/trace-events +%%SOFTMMU%%%%DATADIR%%/u-boot.e500 %%SOFTMMU%%%%DATADIR%%/keymaps/ar %%SOFTMMU%%%%DATADIR%%/keymaps/bepo %%SOFTMMU%%%%DATADIR%%/keymaps/common @@ -127,3 +130,4 @@ %%GTK2%%share/locale/it/LC_MESSAGES/qemu.mo %%GTK2%%share/locale/hu/LC_MESSAGES/qemu.mo %%GTK2%%share/locale/tr/LC_MESSAGES/qemu.mo +%%GTK2%%share/locale/zh_CN/LC_MESSAGES/qemu.mo diff --git a/emulators/qemu-sbruno/Makefile b/emulators/qemu-sbruno/Makefile index c06238973e56..cf4fe8ef92b7 100644 --- a/emulators/qemu-sbruno/Makefile +++ b/emulators/qemu-sbruno/Makefile @@ -2,7 +2,7 @@ # $FreeBSD$ PORTNAME= qemu -PORTVERSION= 2.2.50.g20141230 +PORTVERSION= 2.2.50.g20150106 CATEGORIES= emulators MASTER_SITES= GH GHC \ LOCAL/nox \ @@ -20,8 +20,8 @@ COMMENT?= QEMU CPU Emulator - github bsd-user branch USE_GITHUB= yes GH_ACCOUNT= seanbruno GH_PROJECT= ${PORTNAME}-bsd-user -GH_COMMIT= 11db3cc -GH_TAGNAME= 11db3cc +GH_COMMIT= d1fbcfc +GH_TAGNAME= ${GH_COMMIT} HAS_CONFIGURE= yes USES= gmake pkgconfig bison perl5 python:2,build USE_PERL5= build diff --git a/emulators/qemu-sbruno/distinfo b/emulators/qemu-sbruno/distinfo index 152620658e93..dc50ef52c958 100644 --- a/emulators/qemu-sbruno/distinfo +++ b/emulators/qemu-sbruno/distinfo @@ -1,4 +1,4 @@ -SHA256 (qemu/2.2.50.g20141230/qemu-2.2.50.g20141230.tar.gz) = 17d9b7850032a2537f883b827b9e8a5c6e0208f8141b741624624d79ae9c0377 -SIZE (qemu/2.2.50.g20141230/qemu-2.2.50.g20141230.tar.gz) = 10698531 -SHA256 (qemu/2.2.50.g20141230/dtc-v1.4.0.tar.gz) = 39d0713efd82a27adc065ecb9ef36401c53d5ee87ae1764e2bb243fcd97488e3 -SIZE (qemu/2.2.50.g20141230/dtc-v1.4.0.tar.gz) = 131893 +SHA256 (qemu/2.2.50.g20150106/qemu-2.2.50.g20150106.tar.gz) = 7278a5b06e5a55efd5965eac9a5f9371c79fc2da556765d6fc6ed4b20226baf4 +SIZE (qemu/2.2.50.g20150106/qemu-2.2.50.g20150106.tar.gz) = 10698540 +SHA256 (qemu/2.2.50.g20150106/dtc-v1.4.0.tar.gz) = 39d0713efd82a27adc065ecb9ef36401c53d5ee87ae1764e2bb243fcd97488e3 +SIZE (qemu/2.2.50.g20150106/dtc-v1.4.0.tar.gz) = 131893 diff --git a/emulators/qemu-user-static/Makefile b/emulators/qemu-user-static/Makefile index 72327639123a..86cf66af53c5 100644 --- a/emulators/qemu-user-static/Makefile +++ b/emulators/qemu-user-static/Makefile @@ -2,7 +2,7 @@ # $FreeBSD$ MAINTAINER= nox@FreeBSD.org -COMMENT= QEMU CPU Emulator development version - static bsd-user targets +COMMENT= QEMU CPU Emulator github bsd-user branch - static user targets PKGNAMESUFFIX= -user-static QEMU_USER_STATIC= yes @@ -11,9 +11,7 @@ DESCR= ${.CURDIR}/pkg-descr OPTIONS_SLAVE= STATIC_LINK BSD_USER X86_TARGETS OPTIONS_EXCLUDE=SAMBA X11 GTK2 OPENGL GNUTLS SASL JPEG PNG CURL \ CDROM_DMA PCAP USBREDIR GNS3 DOCS -# XXX soon, when it builds again on 8 and 9: -# MASTERDIR= ${.CURDIR}/../qemu-sbruno -MASTERDIR= ${.CURDIR}/../qemu-devel +MASTERDIR= ${.CURDIR}/../qemu-sbruno post-install: @${RM} -r ${STAGEDIR}${PREFIX}/bin/qemu-ga diff --git a/emulators/qemu/Makefile b/emulators/qemu/Makefile index 64ea7c3a0ecd..dfd0883df06f 100644 --- a/emulators/qemu/Makefile +++ b/emulators/qemu/Makefile @@ -3,7 +3,7 @@ PORTNAME= qemu PORTVERSION= 0.11.1 -PORTREVISION= 17 +PORTREVISION= 18 CATEGORIES= emulators MASTER_SITES= ${MASTER_SITE_SAVANNAH} \ http://bellard.org/qemu/ @@ -20,7 +20,7 @@ USE_PERL5= build PATCH_STRIP= -p1 MAKE_ENV+= BSD_MAKE="${MAKE}" ONLY_FOR_ARCHS= amd64 i386 -CONFLICTS= qemu-devel-[0-9]* +CONFLICTS= qemu-devel-[0-9]* qemu-sbruno-[0-9]* OPTIONS_DEFINE= KQEMU RTL8139_TIMER SAMBA SDL GNUTLS CURL PCAP GNS3 \ CDROM_DMA ADD_AUDIO ALL_TARGETS DOCS |