Patchwork [10/23] bsd-user: add shims for memory management related syscalls

login
register
mail settings
Submitter Stacey Son
Date June 24, 2013, 2:03 a.m.
Message ID <1372039435-41921-11-git-send-email-sson@FreeBSD.org>
Download mbox | patch
Permalink /patch/253915/
State New
Headers show

Comments

Stacey Son - June 24, 2013, 2:03 a.m.
This change adds support for bsd memory management system calls including
mmap(2), munmap(2), mprotect(2), msync(2), etc.  Also, it adds shared memory
management system calls. In addition, cleans up syscall.c a bit and fixes
checkpatch.pl warnings and errors.

Signed-off-by: Stacey Son <sson@FreeBSD.org>
---
 bsd-user/Makefile.objs  |    2 +-
 bsd-user/bsd-errno.h    |   41 +++++
 bsd-user/bsd-mem.c      |  122 +++++++++++++++
 bsd-user/bsd-mem.h      |  387 +++++++++++++++++++++++++++++++++++++++++++++++
 bsd-user/bsd-mman.h     |  121 ---------------
 bsd-user/mmap.c         |   84 +++--------
 bsd-user/qemu-bsd.h     |   34 ++++
 bsd-user/qemu.h         |    1 +
 bsd-user/syscall.c      |  185 +++++++++++++----------
 bsd-user/syscall_defs.h |   71 +++++++++
 10 files changed, 782 insertions(+), 266 deletions(-)
 create mode 100644 bsd-user/bsd-errno.h
 create mode 100644 bsd-user/bsd-mem.c
 create mode 100644 bsd-user/bsd-mem.h
 delete mode 100644 bsd-user/bsd-mman.h
 create mode 100644 bsd-user/qemu-bsd.h
Peter Maydell - June 24, 2013, 5:26 p.m.
On 24 June 2013 03:03, Stacey Son <sson@freebsd.org> wrote:
> This change adds support for bsd memory management system calls including
> mmap(2), munmap(2), mprotect(2), msync(2), etc.  Also, it adds shared memory
> management system calls. In addition, cleans up syscall.c a bit and fixes
> checkpatch.pl warnings and errors.

"Also" in a commit message again -- would be better split.

thanks
-- PMM

Patch

diff --git a/bsd-user/Makefile.objs b/bsd-user/Makefile.objs
index 5e77f57..d0cea36 100644
--- a/bsd-user/Makefile.objs
+++ b/bsd-user/Makefile.objs
@@ -1,2 +1,2 @@ 
 obj-y = main.o bsdload.o elfload.o mmap.o signal.o strace.o syscall.o \
-	        uaccess.o
+	        uaccess.o bsd-mem.o
diff --git a/bsd-user/bsd-errno.h b/bsd-user/bsd-errno.h
new file mode 100644
index 0000000..721bfc0
--- /dev/null
+++ b/bsd-user/bsd-errno.h
@@ -0,0 +1,41 @@ 
+/*
+ *  errno translation
+ *
+ *  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
+ *  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_ERRNO_H_
+#define __BSD_ERRNO_H_
+
+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;
+    }
+}
+
+static inline int is_error(abi_long ret)
+{
+
+    return (abi_ulong)ret >= (abi_ulong)(-4096);
+}
+
+#endif /* !__BSD_ERRNO_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..ec44a30
--- /dev/null
+++ b/bsd-user/bsd-mem.h
@@ -0,0 +1,387 @@ 
+/*
+ *  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(abi_long arg1, abi_long arg2, abi_long arg3,
+        abi_long arg4, abi_long arg5, abi_long arg6)
+{
+
+    return get_errno(target_mmap(arg1, arg2, arg3,
+                target_to_host_bitmask(arg4, mmap_flags_tbl), arg5, arg6));
+}
+
+/* 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-mman.h b/bsd-user/bsd-mman.h
deleted file mode 100644
index 2193ce7..0000000
--- a/bsd-user/bsd-mman.h
+++ /dev/null
@@ -1,121 +0,0 @@ 
-/*--
- * 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.
- *
- *      @(#)mman.h      8.2 (Berkeley) 1/9/95
- * $FreeBSD: src/sys/sys/mman.h,v 1.42 2008/03/28 04:29:27 ps Exp $
- */
-
-#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
-
-/*      $NetBSD: mman.h,v 1.42 2008/11/18 22:13:49 ad Exp $     */
-
-/*-
- * 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.
- * 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.
- *
- *      @(#)mman.h      8.2 (Berkeley) 1/9/95
- */
-#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
-
-/*      $OpenBSD: mman.h,v 1.18 2003/07/21 22:52:19 tedu Exp $  */
-/*      $NetBSD: mman.h,v 1.11 1995/03/26 20:24:23 jtc Exp $    */
-
-/*-
- * 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.
- * 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.
- *
- *      @(#)mman.h      8.1 (Berkeley) 6/2/93
- */
-
-#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
diff --git a/bsd-user/mmap.c b/bsd-user/mmap.c
index 29e0427..2fbc97c 100644
--- a/bsd-user/mmap.c
+++ b/bsd-user/mmap.c
@@ -26,13 +26,12 @@ 
 
 #include "qemu.h"
 #include "qemu-common.h"
-#include "bsd-mman.h"
 
 //#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)
 {
@@ -72,67 +71,7 @@  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;
-}
+#endif /* ! CONFIG_USE_NPTL */
 
 /* NOTE: all the constants are the HOST ones, but addresses are target. */
 int target_mprotect(abi_ulong start, abi_ulong len, int prot)
@@ -275,7 +214,7 @@  unsigned long last_brk;
 */
 /* 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;
@@ -344,6 +283,11 @@  abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
         case MAP_SHARED:
             printf("MAP_SHARED ");
             break;
+#ifdef MAP_STACK
+        case MAP_STACK:
+            printf("MAP_STACK ");
+            break;
+#endif
         default:
             printf("[MAP_FLAGMASK=0x%x] ", flags & TARGET_BSD_MAP_FLAGMASK);
             break;
@@ -352,6 +296,16 @@  abi_long target_mmap(abi_ulong start, abi_ulong len, int prot,
     }
 #endif
 
+#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;
diff --git a/bsd-user/qemu-bsd.h b/bsd-user/qemu-bsd.h
new file mode 100644
index 0000000..0add0b3
--- /dev/null
+++ b/bsd-user/qemu-bsd.h
@@ -0,0 +1,34 @@ 
+/*
+ *  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_
+
+/* 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);
+
+
+#endif /* !_QEMU_BSD_H_ */
diff --git a/bsd-user/qemu.h b/bsd-user/qemu.h
index 1e2abd5..02a05bb 100644
--- a/bsd-user/qemu.h
+++ b/bsd-user/qemu.h
@@ -217,6 +217,7 @@  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)
diff --git a/bsd-user/syscall.c b/bsd-user/syscall.c
index 02740d5..b64c0b0 100644
--- a/bsd-user/syscall.c
+++ b/bsd-user/syscall.c
@@ -27,7 +27,6 @@ 
 #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>
@@ -36,65 +35,12 @@ 
 #include "qemu.h"
 #include "qemu-common.h"
 
-//#define DEBUG
-
-static abi_ulong target_brk;
-static abi_ulong target_original_brk;
-
-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;
-}
-
 #define target_to_host_bitmask(x, tbl) (x)
 
-static inline int is_error(abi_long ret)
-{
-    return (abi_ulong)ret >= (abi_ulong)(-4096);
-}
-
-void target_set_brk(abi_ulong new_brk)
-{
-    target_original_brk = target_brk = HOST_PAGE_ALIGN(new_brk);
-}
-
-/* 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;
-
-    if (!new_brk)
-        return 0;
-    if (new_brk < target_original_brk)
-        return -TARGET_EINVAL;
-
-    brk_page = HOST_PAGE_ALIGN(target_brk);
-
-    /* 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;
-    }
-
-    /* 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));
+#include "bsd-errno.h"
+#include "bsd-mem.h"
 
-    if (!is_error(mapped_addr))
-        target_brk = new_brk;
-    else
-        return mapped_addr;
-
-    return 0;
-}
+/* #define DEBUG */
 
 #if defined(TARGET_I386)
 static abi_long do_freebsd_sysarch(CPUX86State *env, int op, abi_ulong parms)
@@ -278,15 +224,17 @@  static abi_long do_freebsd_sysctl(abi_ulong namep, int32_t namelen, abi_ulong ol
  * 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)
+        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)
+    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);
@@ -304,13 +252,14 @@  static abi_long lock_iovec(int type, struct iovec *vec, abi_ulong target_addr,
 }
 
 static abi_long unlock_iovec(struct iovec *vec, abi_ulong target_addr,
-                             int count, int copy)
+        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);
+    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++) {
@@ -383,15 +332,95 @@  abi_long do_freebsd_syscall(void *cpu_env, int num, abi_long arg1,
                              arg3));
         unlock_user(p, arg1, 0);
         break;
-    case TARGET_FREEBSD_NR_mmap:
-        ret = get_errno(target_mmap(arg1, arg2, arg3,
-                                    target_to_host_bitmask(arg4, mmap_flags_tbl),
-                                    arg5,
-                                    arg6));
+
+        /*
+         * Memory management system calls.
+         */
+    case TARGET_FREEBSD_NR_mmap: /* mmap(2) */
+        ret = do_bsd_mmap(arg1, arg2, arg3, arg4, arg5, arg6);
+        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_mprotect:
-        ret = get_errno(target_mprotect(arg1, arg2, arg3));
+
+    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;
+
+
     case TARGET_FREEBSD_NR_break:
         ret = do_obreak(arg1);
         break;
@@ -466,15 +495,14 @@  abi_long do_netbsd_syscall(void *cpu_env, int num, abi_long arg1,
                              arg3));
         unlock_user(p, arg1, 0);
         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(arg1, arg2, arg3, arg4, arg5, arg6);
         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);
@@ -538,15 +566,14 @@  abi_long do_openbsd_syscall(void *cpu_env, int num, abi_long arg1,
                              arg3));
         unlock_user(p, arg1, 0);
         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(arg1, arg2, arg3, arg4, arg5, arg6);
         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);
diff --git a/bsd-user/syscall_defs.h b/bsd-user/syscall_defs.h
index a2b0ebe..dea94ef 100644
--- a/bsd-user/syscall_defs.h
+++ b/bsd-user/syscall_defs.h
@@ -12,4 +12,75 @@  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 */
+};
+
+/*
+ * 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/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
+
 #endif /* ! _SYSCALL_DEFS_H_ */