/*
 *  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 "qemu.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);
}

/* 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);
    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;
    }
    page_flags |= PAGE_RESET;
    if (passthrough_start > passthrough_last) {
        page_set_flags(start, last, page_flags);
    } else {
        if (start < passthrough_start) {
            page_set_flags(start, passthrough_start - 1, page_flags);
        }
        page_set_flags(passthrough_start, passthrough_last,
                       page_flags | PAGE_PASSTHROUGH);
        if (passthrough_last < last) {
            page_set_flags(passthrough_last + 1, last, page_flags);
        }
    }
    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 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) {
        CPUState *cpu = thread_cpu;
        if (!tcg_cflags_has(cpu, CF_PARALLEL)) {
            tcg_cflags_set(cpu, CF_PARALLEL);
            tb_flush(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 = start + len - 1;
    real_start = start & -host_page_size;
    real_last = ROUND_UP(last, 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);
        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 (!guest_range_valid_untagged(old_addr, old_size) ||
        ((flags & MREMAP_FIXED) &&
         !guest_range_valid_untagged(new_addr, new_size)) ||
        ((flags & MREMAP_MAYMOVE) == 0 &&
         !guest_range_valid_untagged(old_addr, new_size))) {
        errno = ENOMEM;
        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) {
                    mmap_reserve_or_unmap(old_addr + old_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);
        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_RESET);
        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_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(__arm__) || 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_RESET | PAGE_READ |
                       (shmflg & SHM_RDONLY ? 0 : PAGE_WRITE) |
                       (shmflg & SHM_EXEC ? PAGE_EXEC : 0));

        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.
     */
    if (!tcg_cflags_has(cpu, CF_PARALLEL)) {
        tcg_cflags_set(cpu, CF_PARALLEL);
        tb_flush(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);
            shm_region_rm_complete(shmaddr, last);
            mmap_reserve_or_unmap(shmaddr, size);
        }
    }
    return rv;
}
