/*
 *  mmap support for qemu
 *
 *  Copyright (c) 2003 Fabrice Bellard
 *
 *  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 "qemu/osdep.h"
#include <sys/shm.h>
#include "trace.h"
#include "exec/log.h"
#include "exec/page-protection.h"
#include "exec/mmap-lock.h"
#include "qemu.h"
#include "user/page-protection.h"
#include "user-internals.h"
#include "user-mmap.h"
#include "target_mman.h"
#include "qemu/interval-tree.h"

#ifdef TARGET_ARM
#include "target/arm/cpu-features.h"
#endif

static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER;
static __thread int mmap_lock_count;

void mmap_lock(void)
{
    if (mmap_lock_count++ == 0) {
        pthread_mutex_lock(&mmap_mutex);
    }
}

void mmap_unlock(void)
{
    assert(mmap_lock_count > 0);
    if (--mmap_lock_count == 0) {
        pthread_mutex_unlock(&mmap_mutex);
    }
}

bool have_mmap_lock(void)
{
    return mmap_lock_count > 0 ? true : false;
}

/* Grab lock to make sure things are in a consistent state after fork().  */
void mmap_fork_start(void)
{
    if (mmap_lock_count)
        abort();
    pthread_mutex_lock(&mmap_mutex);
}

void mmap_fork_end(int child)
{
    if (child) {
        pthread_mutex_init(&mmap_mutex, NULL);
    } else {
        pthread_mutex_unlock(&mmap_mutex);
    }
}

/* Protected by mmap_lock. */
static IntervalTreeRoot shm_regions;

static void shm_region_add(abi_ptr start, abi_ptr last)
{
    IntervalTreeNode *i = g_new0(IntervalTreeNode, 1);

    i->start = start;
    i->last = last;
    interval_tree_insert(i, &shm_regions);
}

static abi_ptr shm_region_find(abi_ptr start)
{
    IntervalTreeNode *i;

    for (i = interval_tree_iter_first(&shm_regions, start, start); i;
         i = interval_tree_iter_next(i, start, start)) {
        if (i->start == start) {
            return i->last;
        }
    }
    return 0;
}

static void shm_region_rm_complete(abi_ptr start, abi_ptr last)
{
    IntervalTreeNode *i, *n;

    for (i = interval_tree_iter_first(&shm_regions, start, last); i; i = n) {
        n = interval_tree_iter_next(i, start, last);
        if (i->start >= start && i->last <= last) {
            interval_tree_remove(i, &shm_regions);
            g_free(i);
        }
    }
}

/*
 * Validate target prot bitmask.
 * Return the prot bitmask for the host in *HOST_PROT.
 * Return 0 if the target prot bitmask is invalid, otherwise
 * the internal qemu page_flags (which will include PAGE_VALID).
 */
static int validate_prot_to_pageflags(int prot)
{
    int valid = PROT_READ | PROT_WRITE | PROT_EXEC | TARGET_PROT_SEM;
    int page_flags = (prot & PAGE_RWX) | PAGE_VALID;

#ifdef TARGET_AARCH64
    {
        ARMCPU *cpu = ARM_CPU(thread_cpu);

        /*
         * The PROT_BTI bit is only accepted if the cpu supports the feature.
         * Since this is the unusual case, don't bother checking unless
         * the bit has been requested.  If set and valid, record the bit
         * within QEMU's page_flags.
         */
        if ((prot & TARGET_PROT_BTI) && cpu_isar_feature(aa64_bti, cpu)) {
            valid |= TARGET_PROT_BTI;
            page_flags |= PAGE_BTI;
        }
        /* Similarly for the PROT_MTE bit. */
        if ((prot & TARGET_PROT_MTE) && cpu_isar_feature(aa64_mte, cpu)) {
            valid |= TARGET_PROT_MTE;
            page_flags |= PAGE_MTE;
        }
    }
#elif defined(TARGET_HPPA)
    valid |= PROT_GROWSDOWN | PROT_GROWSUP;
#endif

    return prot & ~valid ? 0 : page_flags;
}

/*
 * For the host, we need not pass anything except read/write/exec.
 * While PROT_SEM is allowed by all hosts, it is also ignored, so
 * don't bother transforming guest bit to host bit.  Any other
 * target-specific prot bits will not be understood by the host
 * and will need to be encoded into page_flags for qemu emulation.
 *
 * Pages that are executable by the guest will never be executed
 * by the host, but the host will need to be able to read them.
 */
static int target_to_host_prot(int prot)
{
    return (prot & (PROT_READ | PROT_WRITE)) |
           (prot & PROT_EXEC ? PROT_READ : 0);
}

/* Target bits to be cleared by mprotect if not present in target_prot. */
#ifdef TARGET_AARCH64
#define TARGET_PAGE_NOTSTICKY  PAGE_BTI
#else
#define TARGET_PAGE_NOTSTICKY  0
#endif

/* NOTE: all the constants are the HOST ones, but addresses are target. */
int target_mprotect(abi_ulong start, abi_ulong len, int target_prot)
{
    int host_page_size = qemu_real_host_page_size();
    abi_ulong starts[3];
    abi_ulong lens[3];
    int prots[3];
    abi_ulong host_start, host_last, last;
    int prot1, ret, page_flags, nranges;

    trace_target_mprotect(start, len, target_prot);

    if ((start & ~TARGET_PAGE_MASK) != 0) {
        return -TARGET_EINVAL;
    }
    page_flags = validate_prot_to_pageflags(target_prot);
    if (!page_flags) {
        return -TARGET_EINVAL;
    }
    if (len == 0) {
        return 0;
    }
    len = TARGET_PAGE_ALIGN(len);
    if (!guest_range_valid_untagged(start, len)) {
        return -TARGET_ENOMEM;
    }

    last = start + len - 1;
    host_start = start & -host_page_size;
    host_last = ROUND_UP(last, host_page_size) - 1;
    nranges = 0;

    mmap_lock();

    if (host_last - host_start < host_page_size) {
        /* Single host page contains all guest pages: sum the prot. */
        prot1 = target_prot;
        for (abi_ulong a = host_start; a < start; a += TARGET_PAGE_SIZE) {
            prot1 |= page_get_flags(a);
        }
        for (abi_ulong a = last; a < host_last; a += TARGET_PAGE_SIZE) {
            prot1 |= page_get_flags(a + 1);
        }
        starts[nranges] = host_start;
        lens[nranges] = host_page_size;
        prots[nranges] = prot1;
        nranges++;
    } else {
        if (host_start < start) {
            /* Host page contains more than one guest page: sum the prot. */
            prot1 = target_prot;
            for (abi_ulong a = host_start; a < start; a += TARGET_PAGE_SIZE) {
                prot1 |= page_get_flags(a);
            }
            /* If the resulting sum differs, create a new range. */
            if (prot1 != target_prot) {
                starts[nranges] = host_start;
                lens[nranges] = host_page_size;
                prots[nranges] = prot1;
                nranges++;
                host_start += host_page_size;
            }
        }

        if (last < host_last) {
            /* Host page contains more than one guest page: sum the prot. */
            prot1 = target_prot;
            for (abi_ulong a = last; a < host_last; a += TARGET_PAGE_SIZE) {
                prot1 |= page_get_flags(a + 1);
            }
            /* If the resulting sum differs, create a new range. */
            if (prot1 != target_prot) {
                host_last -= host_page_size;
                starts[nranges] = host_last + 1;
                lens[nranges] = host_page_size;
                prots[nranges] = prot1;
                nranges++;
            }
        }

        /* Create a range for the middle, if any remains. */
        if (host_start < host_last) {
            starts[nranges] = host_start;
            lens[nranges] = host_last - host_start + 1;
            prots[nranges] = target_prot;
            nranges++;
        }
    }

    for (int i = 0; i < nranges; ++i) {
        ret = mprotect(g2h_untagged(starts[i]), lens[i],
                       target_to_host_prot(prots[i]));
        if (ret != 0) {
            goto error;
        }
    }

    page_set_flags(start, last, page_flags, PAGE_RWX | TARGET_PAGE_NOTSTICKY);
    ret = 0;

 error:
    mmap_unlock();
    return ret;
}

/*
 * Perform munmap on behalf of the target, with host parameters.
 * If reserved_va, we must replace the memory reservation.
 */
static int do_munmap(void *addr, size_t len)
{
    if (reserved_va) {
        void *ptr = mmap(addr, len, PROT_NONE,
                         MAP_FIXED | MAP_ANONYMOUS
                         | MAP_PRIVATE | MAP_NORESERVE, -1, 0);
        return ptr == addr ? 0 : -1;
    }
    return munmap(addr, len);
}

/*
 * Perform a pread on behalf of target_mmap.  We can reach EOF, we can be
 * interrupted by signals, and in general there's no good error return path.
 * If @zero, zero the rest of the block at EOF.
 * Return true on success.
 */
static bool mmap_pread(int fd, void *p, size_t len, off_t offset, bool zero)
{
    while (1) {
        ssize_t r = pread(fd, p, len, offset);

        if (likely(r == len)) {
            /* Complete */
            return true;
        }
        if (r == 0) {
            /* EOF */
            if (zero) {
                memset(p, 0, len);
            }
            return true;
        }
        if (r > 0) {
            /* Short read */
            p += r;
            len -= r;
            offset += r;
        } else if (errno != EINTR) {
            /* Error */
            return false;
        }
    }
}

/*
 * Map an incomplete host page.
 *
 * Here be dragons.  This case will not work if there is an existing
 * overlapping host page, which is file mapped, and for which the mapping
 * is beyond the end of the file.  In that case, we will see SIGBUS when
 * trying to write a portion of this page.
 *
 * FIXME: Work around this with a temporary signal handler and longjmp.
 */
static bool mmap_frag(abi_ulong real_start, abi_ulong start, abi_ulong last,
                      int prot, int flags, int fd, off_t offset)
{
    int host_page_size = qemu_real_host_page_size();
    abi_ulong real_last;
    void *host_start;
    int prot_old, prot_new;
    int host_prot_old, host_prot_new;

    if (!(flags & MAP_ANONYMOUS)
        && (flags & MAP_TYPE) == MAP_SHARED
        && (prot & PROT_WRITE)) {
        /*
         * msync() won't work with the partial page, so we return an
         * error if write is possible while it is a shared mapping.
         */
        errno = EINVAL;
        return false;
    }

    real_last = real_start + host_page_size - 1;
    host_start = g2h_untagged(real_start);

    /* Get the protection of the target pages outside the mapping. */
    prot_old = 0;
    for (abi_ulong a = real_start; a < start; a += TARGET_PAGE_SIZE) {
        prot_old |= page_get_flags(a);
    }
    for (abi_ulong a = real_last; a > last; a -= TARGET_PAGE_SIZE) {
        prot_old |= page_get_flags(a);
    }

    if (prot_old == 0) {
        /*
         * Since !(prot_old & PAGE_VALID), there were no guest pages
         * outside of the fragment we need to map.  Allocate a new host
         * page to cover, discarding whatever else may have been present.
         */
        void *p = mmap(host_start, host_page_size,
                       target_to_host_prot(prot),
                       flags | MAP_ANONYMOUS, -1, 0);
        if (p != host_start) {
            if (p != MAP_FAILED) {
                do_munmap(p, host_page_size);
                errno = EEXIST;
            }
            return false;
        }
        prot_old = prot;
    }
    prot_new = prot | prot_old;

    host_prot_old = target_to_host_prot(prot_old);
    host_prot_new = target_to_host_prot(prot_new);

    /* Adjust protection to be able to write. */
    if (!(host_prot_old & PROT_WRITE)) {
        host_prot_old |= PROT_WRITE;
        mprotect(host_start, host_page_size, host_prot_old);
    }

    /* Read or zero the new guest pages. */
    if (flags & MAP_ANONYMOUS) {
        memset(g2h_untagged(start), 0, last - start + 1);
    } else if (!mmap_pread(fd, g2h_untagged(start), last - start + 1,
                           offset, true)) {
        return false;
    }

    /* Put final protection */
    if (host_prot_new != host_prot_old) {
        mprotect(host_start, host_page_size, host_prot_new);
    }
    return true;
}

abi_ulong task_unmapped_base;
abi_ulong elf_et_dyn_base;
abi_ulong mmap_next_start;

/*
 * Subroutine of mmap_find_vma, used when we have pre-allocated
 * a chunk of guest address space.
 */
static abi_ulong mmap_find_vma_reserved(abi_ulong start, abi_ulong size,
                                        abi_ulong align)
{
    target_ulong ret;

    ret = page_find_range_empty(start, reserved_va, size, align);
    if (ret == -1 && start > mmap_min_addr) {
        /* Restart at the beginning of the address space. */
        ret = page_find_range_empty(mmap_min_addr, start - 1, size, align);
    }

    return ret;
}

/*
 * Find and reserve a free memory area of size 'size'. The search
 * starts at 'start'.
 * It must be called with mmap_lock() held.
 * Return -1 if error.
 */
abi_ulong mmap_find_vma(abi_ulong start, abi_ulong size, abi_ulong align)
{
    int host_page_size = qemu_real_host_page_size();
    void *ptr, *prev;
    abi_ulong addr;
    int wrapped, repeat;

    align = MAX(align, host_page_size);

    /* If 'start' == 0, then a default start address is used. */
    if (start == 0) {
        start = mmap_next_start;
    } else {
        start &= -host_page_size;
    }
    start = ROUND_UP(start, align);
    size = ROUND_UP(size, host_page_size);

    if (reserved_va) {
        return mmap_find_vma_reserved(start, size, align);
    }

    addr = start;
    wrapped = repeat = 0;
    prev = 0;

    for (;; prev = ptr) {
        /*
         * Reserve needed memory area to avoid a race.
         * It should be discarded using:
         *  - mmap() with MAP_FIXED flag
         *  - mremap() with MREMAP_FIXED flag
         *  - shmat() with SHM_REMAP flag
         */
        ptr = mmap(g2h_untagged(addr), size, PROT_NONE,
                   MAP_ANONYMOUS | MAP_PRIVATE | MAP_NORESERVE, -1, 0);

        /* ENOMEM, if host address space has no memory */
        if (ptr == MAP_FAILED) {
            return (abi_ulong)-1;
        }

        /*
         * Count the number of sequential returns of the same address.
         * This is used to modify the search algorithm below.
         */
        repeat = (ptr == prev ? repeat + 1 : 0);

        if (h2g_valid(ptr + size - 1)) {
            addr = h2g(ptr);

            if ((addr & (align - 1)) == 0) {
                /* Success.  */
                if (start == mmap_next_start && addr >= task_unmapped_base) {
                    mmap_next_start = addr + size;
                }
                return addr;
            }

            /* The address is not properly aligned for the target.  */
            switch (repeat) {
            case 0:
                /*
                 * Assume the result that the kernel gave us is the
                 * first with enough free space, so start again at the
                 * next higher target page.
                 */
                addr = ROUND_UP(addr, align);
                break;
            case 1:
                /*
                 * Sometimes the kernel decides to perform the allocation
                 * at the top end of memory instead.
                 */
                addr &= -align;
                break;
            case 2:
                /* Start over at low memory.  */
                addr = 0;
                break;
            default:
                /* Fail.  This unaligned block must the last.  */
                addr = -1;
                break;
            }
        } else {
            /*
             * Since the result the kernel gave didn't fit, start
             * again at low memory.  If any repetition, fail.
             */
            addr = (repeat ? -1 : 0);
        }

        /* Unmap and try again.  */
        munmap(ptr, size);

        /* ENOMEM if we checked the whole of the target address space.  */
        if (addr == (abi_ulong)-1) {
            return (abi_ulong)-1;
        } else if (addr == 0) {
            if (wrapped) {
                return (abi_ulong)-1;
            }
            wrapped = 1;
            /*
             * Don't actually use 0 when wrapping, instead indicate
             * that we'd truly like an allocation in low memory.
             */
            addr = (mmap_min_addr > TARGET_PAGE_SIZE
                     ? TARGET_PAGE_ALIGN(mmap_min_addr)
                     : TARGET_PAGE_SIZE);
        } else if (wrapped && addr >= start) {
            return (abi_ulong)-1;
        }
    }
}

/*
 * Record a successful mmap within the user-exec interval tree.
 */
static abi_long mmap_end(abi_ulong start, abi_ulong last,
                         abi_ulong passthrough_start,
                         abi_ulong passthrough_last,
                         int flags, int page_flags)
{
    if (flags & MAP_ANONYMOUS) {
        page_flags |= PAGE_ANON;
    }
    if (passthrough_start > passthrough_last) {
        page_set_flags(start, last, page_flags, PAGE_VALID);
    } else {
        if (start < passthrough_start) {
            page_set_flags(start, passthrough_start - 1,
                           page_flags, PAGE_VALID);
        }
        page_set_flags(passthrough_start, passthrough_last,
                       page_flags | PAGE_PASSTHROUGH, PAGE_VALID);
        if (passthrough_last < last) {
            page_set_flags(passthrough_last + 1, last, page_flags, PAGE_VALID);
        }
    }
    shm_region_rm_complete(start, last);
    trace_target_mmap_complete(start);
    if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
        FILE *f = qemu_log_trylock();
        if (f) {
            fprintf(f, "page layout changed following mmap\n");
            page_dump(f);
            qemu_log_unlock(f);
        }
    }
    return start;
}

/*
 * Special case host page size == target page size,
 * where there are no edge conditions.
 */
static abi_long mmap_h_eq_g(abi_ulong start, abi_ulong len,
                            int host_prot, int flags, int page_flags,
                            int fd, off_t offset)
{
    void *p, *want_p = NULL;
    abi_ulong last;

    if (start || (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) {
        want_p = g2h_untagged(start);
    }

    p = mmap(want_p, len, host_prot, flags, fd, offset);
    if (p == MAP_FAILED) {
        return -1;
    }
    /* If the host kernel does not support MAP_FIXED_NOREPLACE, emulate. */
    if ((flags & MAP_FIXED_NOREPLACE) && p != want_p) {
        do_munmap(p, len);
        errno = EEXIST;
        return -1;
    }

    start = h2g(p);
    last = start + len - 1;
    return mmap_end(start, last, start, last, flags, page_flags);
}

/*
 * Special case host page size < target page size.
 *
 * The two special cases are increased guest alignment, and mapping
 * past the end of a file.
 *
 * When mapping files into a memory area larger than the file,
 * accesses to pages beyond the file size will cause a SIGBUS.
 *
 * For example, if mmaping a file of 100 bytes on a host with 4K
 * pages emulating a target with 8K pages, the target expects to
 * be able to access the first 8K. But the host will trap us on
 * any access beyond 4K.
 *
 * When emulating a target with a larger page-size than the hosts,
 * we may need to truncate file maps at EOF and add extra anonymous
 * pages up to the targets page boundary.
 *
 * This workaround only works for files that do not change.
 * If the file is later extended (e.g. ftruncate), the SIGBUS
 * vanishes and the proper behaviour is that changes within the
 * anon page should be reflected in the file.
 *
 * However, this case is rather common with executable images,
 * so the workaround is important for even trivial tests, whereas
 * the mmap of a file being extended is less common.
 */
static abi_long mmap_h_lt_g(abi_ulong start, abi_ulong len, int host_prot,
                            int mmap_flags, int page_flags, int fd,
                            off_t offset, int host_page_size)
{
    void *p, *want_p = NULL;
    off_t fileend_adj = 0;
    int flags = mmap_flags;
    abi_ulong last, pass_last;

    if (start || (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) {
        want_p = g2h_untagged(start);
    }

    if (!(flags & MAP_ANONYMOUS)) {
        struct stat sb;

        if (fstat(fd, &sb) == -1) {
            return -1;
        }
        if (offset >= sb.st_size) {
            /*
             * The entire map is beyond the end of the file.
             * Transform it to an anonymous mapping.
             */
            flags |= MAP_ANONYMOUS;
            fd = -1;
            offset = 0;
        } else if (offset + len > sb.st_size) {
            /*
             * A portion of the map is beyond the end of the file.
             * Truncate the file portion of the allocation.
             */
            fileend_adj = offset + len - sb.st_size;
        }
    }

    if (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE)) {
        if (fileend_adj) {
            p = mmap(want_p, len, host_prot, flags | MAP_ANONYMOUS, -1, 0);
        } else {
            p = mmap(want_p, len, host_prot, flags, fd, offset);
        }
        if (p != want_p) {
            if (p != MAP_FAILED) {
                /* Host does not support MAP_FIXED_NOREPLACE: emulate. */
                do_munmap(p, len);
                errno = EEXIST;
            }
            return -1;
        }

        if (fileend_adj) {
            void *t = mmap(p, len - fileend_adj, host_prot,
                           (flags & ~MAP_FIXED_NOREPLACE) | MAP_FIXED,
                           fd, offset);

            if (t == MAP_FAILED) {
                int save_errno = errno;

                /*
                 * We failed a map over the top of the successful anonymous
                 * mapping above. The only failure mode is running out of VMAs,
                 * and there's nothing that we can do to detect that earlier.
                 * If we have replaced an existing mapping with MAP_FIXED,
                 * then we cannot properly recover.  It's a coin toss whether
                 * it would be better to exit or continue here.
                 */
                if (!(flags & MAP_FIXED_NOREPLACE) &&
                    !page_check_range_empty(start, start + len - 1)) {
                    qemu_log("QEMU target_mmap late failure: %s",
                             strerror(save_errno));
                }

                do_munmap(want_p, len);
                errno = save_errno;
                return -1;
            }
        }
    } else {
        size_t host_len, part_len;

        /*
         * Take care to align the host memory.  Perform a larger anonymous
         * allocation and extract the aligned portion.  Remap the file on
         * top of that.
         */
        host_len = len + TARGET_PAGE_SIZE - host_page_size;
        p = mmap(want_p, host_len, host_prot, flags | MAP_ANONYMOUS, -1, 0);
        if (p == MAP_FAILED) {
            return -1;
        }

        part_len = (uintptr_t)p & (TARGET_PAGE_SIZE - 1);
        if (part_len) {
            part_len = TARGET_PAGE_SIZE - part_len;
            do_munmap(p, part_len);
            p += part_len;
            host_len -= part_len;
        }
        if (len < host_len) {
            do_munmap(p + len, host_len - len);
        }

        if (!(flags & MAP_ANONYMOUS)) {
            void *t = mmap(p, len - fileend_adj, host_prot,
                           flags | MAP_FIXED, fd, offset);

            if (t == MAP_FAILED) {
                int save_errno = errno;
                do_munmap(p, len);
                errno = save_errno;
                return -1;
            }
        }

        start = h2g(p);
    }

    last = start + len - 1;
    if (fileend_adj) {
        pass_last = ROUND_UP(last - fileend_adj, host_page_size) - 1;
    } else {
        pass_last = last;
    }
    return mmap_end(start, last, start, pass_last, mmap_flags, page_flags);
}

/*
 * Special case host page size > target page size.
 *
 * The two special cases are address and file offsets that are valid
 * for the guest that cannot be directly represented by the host.
 */
static abi_long mmap_h_gt_g(abi_ulong start, abi_ulong len,
                            int target_prot, int host_prot,
                            int flags, int page_flags, int fd,
                            off_t offset, int host_page_size)
{
    void *p, *want_p = NULL;
    off_t host_offset = offset & -host_page_size;
    abi_ulong last, real_start, real_last;
    bool misaligned_offset = false;
    size_t host_len;

    if (start || (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) {
        want_p = g2h_untagged(start);
    }

    if (!(flags & (MAP_FIXED | MAP_FIXED_NOREPLACE))) {
        /*
         * Adjust the offset to something representable on the host.
         */
        host_len = len + offset - host_offset;
        p = mmap(want_p, host_len, host_prot, flags, fd, host_offset);
        if (p == MAP_FAILED) {
            return -1;
        }

        /* Update start to the file position at offset. */
        p += offset - host_offset;

        start = h2g(p);
        last = start + len - 1;
        return mmap_end(start, last, start, last, flags, page_flags);
    }

    if (!(flags & MAP_ANONYMOUS)) {
        misaligned_offset = (start ^ offset) & (host_page_size - 1);

        /*
         * The fallback for misalignment is a private mapping + read.
         * This carries none of semantics required of MAP_SHARED.
         */
        if (misaligned_offset && (flags & MAP_TYPE) != MAP_PRIVATE) {
            errno = EINVAL;
            return -1;
        }
    }

    last = start + len - 1;
    real_start = start & -host_page_size;
    real_last = ROUND_UP(last, host_page_size) - 1;

    /*
     * Handle the start and end of the mapping.
     */
    if (real_start < start) {
        abi_ulong real_page_last = real_start + host_page_size - 1;
        if (last <= real_page_last) {
            /* Entire allocation a subset of one host page. */
            if (!mmap_frag(real_start, start, last, target_prot,
                           flags, fd, offset)) {
                return -1;
            }
            return mmap_end(start, last, -1, 0, flags, page_flags);
        }

        if (!mmap_frag(real_start, start, real_page_last, target_prot,
                       flags, fd, offset)) {
            return -1;
        }
        real_start = real_page_last + 1;
    }

    if (last < real_last) {
        abi_ulong real_page_start = real_last - host_page_size + 1;
        if (!mmap_frag(real_page_start, real_page_start, last,
                       target_prot, flags, fd,
                       offset + real_page_start - start)) {
            return -1;
        }
        real_last = real_page_start - 1;
    }

    if (real_start > real_last) {
        return mmap_end(start, last, -1, 0, flags, page_flags);
    }

    /*
     * Handle the middle of the mapping.
     */

    host_len = real_last - real_start + 1;
    want_p += real_start - start;

    if (flags & MAP_ANONYMOUS) {
        p = mmap(want_p, host_len, host_prot, flags, -1, 0);
    } else if (!misaligned_offset) {
        p = mmap(want_p, host_len, host_prot, flags, fd,
                 offset + real_start - start);
    } else {
        p = mmap(want_p, host_len, host_prot | PROT_WRITE,
                 flags | MAP_ANONYMOUS, -1, 0);
    }
    if (p != want_p) {
        if (p != MAP_FAILED) {
            do_munmap(p, host_len);
            errno = EEXIST;
        }
        return -1;
    }

    if (misaligned_offset) {
        if (!mmap_pread(fd, p, host_len, offset + real_start - start, false)) {
            do_munmap(p, host_len);
            return -1;
        }
        if (!(host_prot & PROT_WRITE)) {
            mprotect(p, host_len, host_prot);
        }
    }

    return mmap_end(start, last, -1, 0, flags, page_flags);
}

static abi_long target_mmap__locked(abi_ulong start, abi_ulong len,
                                    int target_prot, int flags, int page_flags,
                                    int fd, off_t offset)
{
    int host_page_size = qemu_real_host_page_size();
    int host_prot;

    /*
     * For reserved_va, we are in full control of the allocation.
     * Find a suitable hole and convert to MAP_FIXED.
     */
    if (reserved_va) {
        if (flags & MAP_FIXED_NOREPLACE) {
            /* Validate that the chosen range is empty. */
            if (!page_check_range_empty(start, start + len - 1)) {
                errno = EEXIST;
                return -1;
            }
            flags = (flags & ~MAP_FIXED_NOREPLACE) | MAP_FIXED;
        } else if (!(flags & MAP_FIXED)) {
            abi_ulong real_start = start & -host_page_size;
            off_t host_offset = offset & -host_page_size;
            size_t real_len = len + offset - host_offset;
            abi_ulong align = MAX(host_page_size, TARGET_PAGE_SIZE);

            start = mmap_find_vma(real_start, real_len, align);
            if (start == (abi_ulong)-1) {
                errno = ENOMEM;
                return -1;
            }
            start += offset - host_offset;
            flags |= MAP_FIXED;
        }
    }

    host_prot = target_to_host_prot(target_prot);

    if (host_page_size == TARGET_PAGE_SIZE) {
        return mmap_h_eq_g(start, len, host_prot, flags,
                           page_flags, fd, offset);
    } else if (host_page_size < TARGET_PAGE_SIZE) {
        return mmap_h_lt_g(start, len, host_prot, flags,
                           page_flags, fd, offset, host_page_size);
    } else {
        return mmap_h_gt_g(start, len, target_prot, host_prot, flags,
                           page_flags, fd, offset, host_page_size);
    }
}

/* NOTE: all the constants are the HOST ones */
abi_long target_mmap(abi_ulong start, abi_ulong len, int target_prot,
                     int flags, int fd, off_t offset)
{
    abi_long ret;
    int page_flags;

    trace_target_mmap(start, len, target_prot, flags, fd, offset);

    if (!len) {
        errno = EINVAL;
        return -1;
    }

    page_flags = validate_prot_to_pageflags(target_prot);
    if (!page_flags) {
        errno = EINVAL;
        return -1;
    }

    /* Also check for overflows... */
    len = TARGET_PAGE_ALIGN(len);
    if (!len || len != (size_t)len) {
        errno = ENOMEM;
        return -1;
    }

    if (offset & ~TARGET_PAGE_MASK) {
        errno = EINVAL;
        return -1;
    }
    if (flags & (MAP_FIXED | MAP_FIXED_NOREPLACE)) {
        if (start & ~TARGET_PAGE_MASK) {
            errno = EINVAL;
            return -1;
        }
        if (!guest_range_valid_untagged(start, len)) {
            errno = ENOMEM;
            return -1;
        }
    }

    mmap_lock();

    ret = target_mmap__locked(start, len, target_prot, flags,
                              page_flags, fd, offset);

    mmap_unlock();

    /*
     * If we're mapping shared memory, ensure we generate code for parallel
     * execution and flush old translations.  This will work up to the level
     * supported by the host -- anything that requires EXCP_ATOMIC will not
     * be atomic with respect to an external process.
     */
    if (ret != -1 && (flags & MAP_TYPE) != MAP_PRIVATE) {
        begin_parallel_context(thread_cpu);
    }

    return ret;
}

static int mmap_reserve_or_unmap(abi_ulong start, abi_ulong len)
{
    int host_page_size = qemu_real_host_page_size();
    abi_ulong real_start;
    abi_ulong real_last;
    abi_ulong real_len;
    abi_ulong last;
    abi_ulong a;
    void *host_start;
    int prot;

    last = ROUND_UP(start + len, TARGET_PAGE_SIZE) - 1;
    real_start = start & -host_page_size;
    real_last = ROUND_UP(last + 1, host_page_size) - 1;

    /*
     * If guest pages remain on the first or last host pages,
     * adjust the deallocation to retain those guest pages.
     * The single page special case is required for the last page,
     * lest real_start overflow to zero.
     */
    if (real_last - real_start < host_page_size) {
        prot = 0;
        for (a = real_start; a < start; a += TARGET_PAGE_SIZE) {
            prot |= page_get_flags(a);
        }
        for (a = last; a < real_last; a += TARGET_PAGE_SIZE) {
            prot |= page_get_flags(a + 1);
        }
        if (prot != 0) {
            return 0;
        }
    } else {
        for (prot = 0, a = real_start; a < start; a += TARGET_PAGE_SIZE) {
            prot |= page_get_flags(a);
        }
        if (prot != 0) {
            real_start += host_page_size;
        }

        for (prot = 0, a = last; a < real_last; a += TARGET_PAGE_SIZE) {
            prot |= page_get_flags(a + 1);
        }
        if (prot != 0) {
            real_last -= host_page_size;
        }

        if (real_last < real_start) {
            return 0;
        }
    }

    real_len = real_last - real_start + 1;
    host_start = g2h_untagged(real_start);

    return do_munmap(host_start, real_len);
}

int target_munmap(abi_ulong start, abi_ulong len)
{
    int ret;

    trace_target_munmap(start, len);

    if (start & ~TARGET_PAGE_MASK) {
        errno = EINVAL;
        return -1;
    }
    len = TARGET_PAGE_ALIGN(len);
    if (len == 0 || !guest_range_valid_untagged(start, len)) {
        errno = EINVAL;
        return -1;
    }

    mmap_lock();
    ret = mmap_reserve_or_unmap(start, len);
    if (likely(ret == 0)) {
        page_set_flags(start, start + len - 1, 0, PAGE_VALID);
        shm_region_rm_complete(start, start + len - 1);
    }
    mmap_unlock();

    return ret;
}

abi_long target_mremap(abi_ulong old_addr, abi_ulong old_size,
                       abi_ulong new_size, unsigned long flags,
                       abi_ulong new_addr)
{
    int prot;
    void *host_addr;

    if (((flags & MREMAP_FIXED) &&
         !guest_range_valid_untagged(new_addr, new_size)) ||
        ((flags & MREMAP_MAYMOVE) == 0 &&
         !guest_range_valid_untagged(old_addr, new_size))) {
        errno = EINVAL;
        return -1;
    }
    if (!guest_range_valid_untagged(old_addr, old_size)) {
        errno = EFAULT;
        return -1;
    }

    mmap_lock();

    if (flags & MREMAP_FIXED) {
        host_addr = mremap(g2h_untagged(old_addr), old_size, new_size,
                           flags, g2h_untagged(new_addr));

        if (reserved_va && host_addr != MAP_FAILED) {
            /*
             * If new and old addresses overlap then the above mremap will
             * already have failed with EINVAL.
             */
            mmap_reserve_or_unmap(old_addr, old_size);
        }
    } else if (flags & MREMAP_MAYMOVE) {
        abi_ulong mmap_start;

        mmap_start = mmap_find_vma(0, new_size, TARGET_PAGE_SIZE);

        if (mmap_start == -1) {
            errno = ENOMEM;
            host_addr = MAP_FAILED;
        } else {
            host_addr = mremap(g2h_untagged(old_addr), old_size, new_size,
                               flags | MREMAP_FIXED,
                               g2h_untagged(mmap_start));
            if (reserved_va) {
                mmap_reserve_or_unmap(old_addr, old_size);
            }
        }
    } else {
        int page_flags = 0;
        if (reserved_va && old_size < new_size) {
            abi_ulong addr;
            for (addr = old_addr + old_size;
                 addr < old_addr + new_size;
                 addr++) {
                page_flags |= page_get_flags(addr);
            }
        }
        if (page_flags == 0) {
            host_addr = mremap(g2h_untagged(old_addr),
                               old_size, new_size, flags);

            if (host_addr != MAP_FAILED) {
                /* Check if address fits target address space */
                if (!guest_range_valid_untagged(h2g(host_addr), new_size)) {
                    /* Revert mremap() changes */
                    host_addr = mremap(g2h_untagged(old_addr),
                                       new_size, old_size, flags);
                    errno = ENOMEM;
                    host_addr = MAP_FAILED;
                } else if (reserved_va && old_size > new_size) {
                    /* Re-reserve pages we just shrunk out of the mapping */
                    mmap_reserve_or_unmap(old_addr + new_size,
                                          old_size - new_size);
                }
            }
        } else {
            errno = ENOMEM;
            host_addr = MAP_FAILED;
        }
    }

    if (host_addr == MAP_FAILED) {
        new_addr = -1;
    } else {
        new_addr = h2g(host_addr);
        prot = page_get_flags(old_addr);
        page_set_flags(old_addr, old_addr + old_size - 1, 0, PAGE_VALID);
        shm_region_rm_complete(old_addr, old_addr + old_size - 1);
        page_set_flags(new_addr, new_addr + new_size - 1,
                       prot | PAGE_VALID, PAGE_VALID);
        shm_region_rm_complete(new_addr, new_addr + new_size - 1);
    }
    mmap_unlock();
    return new_addr;
}

abi_long target_madvise(abi_ulong start, abi_ulong len_in, int advice)
{
    abi_ulong len;
    int ret = 0;

    if (start & ~TARGET_PAGE_MASK) {
        return -TARGET_EINVAL;
    }
    if (len_in == 0) {
        return 0;
    }
    len = TARGET_PAGE_ALIGN(len_in);
    if (len == 0 || !guest_range_valid_untagged(start, len)) {
        return -TARGET_EINVAL;
    }

    /* Translate for some architectures which have different MADV_xxx values */
    switch (advice) {
    case TARGET_MADV_DONTNEED:      /* alpha */
        advice = MADV_DONTNEED;
        break;
    case TARGET_MADV_WIPEONFORK:    /* parisc */
        advice = MADV_WIPEONFORK;
        break;
    case TARGET_MADV_KEEPONFORK:    /* parisc */
        advice = MADV_KEEPONFORK;
        break;
    /* we do not care about the other MADV_xxx values yet */
    }

    /*
     * Most advice values are hints, so ignoring and returning success is ok.
     *
     * However, some advice values such as MADV_DONTNEED, MADV_WIPEONFORK and
     * MADV_KEEPONFORK are not hints and need to be emulated.
     *
     * A straight passthrough for those may not be safe because qemu sometimes
     * turns private file-backed mappings into anonymous mappings.
     * If all guest pages have PAGE_PASSTHROUGH set, mappings have the
     * same semantics for the host as for the guest.
     *
     * We pass through MADV_WIPEONFORK and MADV_KEEPONFORK if possible and
     * return failure if not.
     *
     * MADV_DONTNEED is passed through as well, if possible.
     * If passthrough isn't possible, we nevertheless (wrongly!) return
     * success, which is broken but some userspace programs fail to work
     * otherwise. Completely implementing such emulation is quite complicated
     * though.
     */
    mmap_lock();
    switch (advice) {
    case MADV_DONTDUMP:
        page_set_flags(start, start + len - 1, PAGE_DONTDUMP, 0);
        break;
    case MADV_DODUMP:
        page_set_flags(start, start + len - 1, 0, PAGE_DONTDUMP);
        break;
    case MADV_WIPEONFORK:
    case MADV_KEEPONFORK:
        ret = -EINVAL;
        /* fall through */
    case MADV_DONTNEED:
        if (page_check_range(start, len, PAGE_PASSTHROUGH)) {
            ret = get_errno(madvise(g2h_untagged(start), len, advice));
            if ((advice == MADV_DONTNEED) && (ret == 0)) {
                page_reset_target_data(start, start + len - 1);
            }
        }
    }
    mmap_unlock();

    return ret;
}

#ifndef TARGET_FORCE_SHMLBA
/*
 * For most architectures, SHMLBA is the same as the page size;
 * some architectures have larger values, in which case they should
 * define TARGET_FORCE_SHMLBA and provide a target_shmlba() function.
 * This corresponds to the kernel arch code defining __ARCH_FORCE_SHMLBA
 * and defining its own value for SHMLBA.
 *
 * The kernel also permits SHMLBA to be set by the architecture to a
 * value larger than the page size without setting __ARCH_FORCE_SHMLBA;
 * this means that addresses are rounded to the large size if
 * SHM_RND is set but addresses not aligned to that size are not rejected
 * as long as they are at least page-aligned. Since the only architecture
 * which uses this is ia64 this code doesn't provide for that oddity.
 */
static inline abi_ulong target_shmlba(CPUArchState *cpu_env)
{
    return TARGET_PAGE_SIZE;
}
#endif

#if defined(__mips__) || defined(__sparc__)
#define HOST_FORCE_SHMLBA 1
#else
#define HOST_FORCE_SHMLBA 0
#endif

abi_ulong target_shmat(CPUArchState *cpu_env, int shmid,
                       abi_ulong shmaddr, int shmflg)
{
    CPUState *cpu = env_cpu(cpu_env);
    struct shmid_ds shm_info;
    int ret;
    int h_pagesize;
    int t_shmlba, h_shmlba, m_shmlba;
    size_t t_len, h_len, m_len;

    /* shmat pointers are always untagged */

    /*
     * Because we can't use host shmat() unless the address is sufficiently
     * aligned for the host, we'll need to check both.
     * TODO: Could be fixed with softmmu.
     */
    t_shmlba = target_shmlba(cpu_env);
    h_pagesize = qemu_real_host_page_size();
    h_shmlba = (HOST_FORCE_SHMLBA ? SHMLBA : h_pagesize);
    m_shmlba = MAX(t_shmlba, h_shmlba);

    if (shmaddr) {
        if (shmaddr & (m_shmlba - 1)) {
            if (shmflg & SHM_RND) {
                /*
                 * The guest is allowing the kernel to round the address.
                 * Assume that the guest is ok with us rounding to the
                 * host required alignment too.  Anyway if we don't, we'll
                 * get an error from the kernel.
                 */
                shmaddr &= ~(m_shmlba - 1);
                if (shmaddr == 0 && (shmflg & SHM_REMAP)) {
                    return -TARGET_EINVAL;
                }
            } else {
                int require = TARGET_PAGE_SIZE;
#ifdef TARGET_FORCE_SHMLBA
                require = t_shmlba;
#endif
                /*
                 * Include host required alignment, as otherwise we cannot
                 * use host shmat at all.
                 */
                require = MAX(require, h_shmlba);
                if (shmaddr & (require - 1)) {
                    return -TARGET_EINVAL;
                }
            }
        }
    } else {
        if (shmflg & SHM_REMAP) {
            return -TARGET_EINVAL;
        }
    }
    /* All rounding now manually concluded. */
    shmflg &= ~SHM_RND;

    /* 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 length, bail out */
        return ret;
    }
    t_len = TARGET_PAGE_ALIGN(shm_info.shm_segsz);
    h_len = ROUND_UP(shm_info.shm_segsz, h_pagesize);
    m_len = MAX(t_len, h_len);

    if (!guest_range_valid_untagged(shmaddr, m_len)) {
        return -TARGET_EINVAL;
    }

    WITH_MMAP_LOCK_GUARD() {
        bool mapped = false;
        void *want, *test;
        abi_ulong last;

        if (!shmaddr) {
            shmaddr = mmap_find_vma(0, m_len, m_shmlba);
            if (shmaddr == -1) {
                return -TARGET_ENOMEM;
            }
            mapped = !reserved_va;
        } else if (shmflg & SHM_REMAP) {
            /*
             * If host page size > target page size, the host shmat may map
             * more memory than the guest expects.  Reject a mapping that
             * would replace memory in the unexpected gap.
             * TODO: Could be fixed with softmmu.
             */
            if (t_len < h_len &&
                !page_check_range_empty(shmaddr + t_len,
                                        shmaddr + h_len - 1)) {
                return -TARGET_EINVAL;
            }
        } else {
            if (!page_check_range_empty(shmaddr, shmaddr + m_len - 1)) {
                return -TARGET_EINVAL;
            }
        }

        /* All placement is now complete. */
        want = (void *)g2h_untagged(shmaddr);

        /*
         * Map anonymous pages across the entire range, then remap with
         * the shared memory.  This is required for a number of corner
         * cases for which host and guest page sizes differ.
         */
        if (h_len != t_len) {
            int mmap_p = PROT_READ | (shmflg & SHM_RDONLY ? 0 : PROT_WRITE);
            int mmap_f = MAP_PRIVATE | MAP_ANONYMOUS
                       | (reserved_va || mapped || (shmflg & SHM_REMAP)
                          ? MAP_FIXED : MAP_FIXED_NOREPLACE);

            test = mmap(want, m_len, mmap_p, mmap_f, -1, 0);
            if (unlikely(test != want)) {
                /* shmat returns EINVAL not EEXIST like mmap. */
                ret = (test == MAP_FAILED && errno != EEXIST
                       ? get_errno(-1) : -TARGET_EINVAL);
                if (mapped) {
                    do_munmap(want, m_len);
                }
                return ret;
            }
            mapped = true;
        }

        if (reserved_va || mapped) {
            shmflg |= SHM_REMAP;
        }
        test = shmat(shmid, want, shmflg);
        if (test == MAP_FAILED) {
            ret = get_errno(-1);
            if (mapped) {
                do_munmap(want, m_len);
            }
            return ret;
        }
        assert(test == want);

        last = shmaddr + m_len - 1;
        page_set_flags(shmaddr, last,
                       PAGE_VALID | PAGE_READ |
                       (shmflg & SHM_RDONLY ? 0 : PAGE_WRITE) |
                       (shmflg & SHM_EXEC ? PAGE_EXEC : 0),
                       PAGE_VALID);

        shm_region_rm_complete(shmaddr, last);
        shm_region_add(shmaddr, last);
    }

    /*
     * We're mapping shared memory, so ensure we generate code for parallel
     * execution and flush old translations.  This will work up to the level
     * supported by the host -- anything that requires EXCP_ATOMIC will not
     * be atomic with respect to an external process.
     */
    begin_parallel_context(cpu);

    if (qemu_loglevel_mask(CPU_LOG_PAGE)) {
        FILE *f = qemu_log_trylock();
        if (f) {
            fprintf(f, "page layout changed following shmat\n");
            page_dump(f);
            qemu_log_unlock(f);
        }
    }
    return shmaddr;
}

abi_long target_shmdt(abi_ulong shmaddr)
{
    abi_long rv;

    /* shmdt pointers are always untagged */

    WITH_MMAP_LOCK_GUARD() {
        abi_ulong last = shm_region_find(shmaddr);
        if (last == 0) {
            return -TARGET_EINVAL;
        }

        rv = get_errno(shmdt(g2h_untagged(shmaddr)));
        if (rv == 0) {
            abi_ulong size = last - shmaddr + 1;

            page_set_flags(shmaddr, last, 0, PAGE_VALID);
            shm_region_rm_complete(shmaddr, last);
            mmap_reserve_or_unmap(shmaddr, size);
        }
    }
    return rv;
}
