/*
 *  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, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/mman.h>

#include "qemu.h"

//#define DEBUG_MMAP

/* NOTE: all the constants are the HOST ones */
int target_mprotect(unsigned long start, unsigned long len, int prot)
{
    unsigned long end, host_start, host_end, addr;
    int prot1, ret;

#ifdef DEBUG_MMAP
    printf("mprotect: start=0x%lx len=0x%lx prot=%c%c%c\n", start, len,
           prot & PROT_READ ? 'r' : '-',
           prot & PROT_WRITE ? 'w' : '-',
           prot & PROT_EXEC ? 'x' : '-');
#endif

    if ((start & ~TARGET_PAGE_MASK) != 0)
        return -EINVAL;
    len = TARGET_PAGE_ALIGN(len);
    end = start + len;
    if (end < start)
        return -EINVAL;
    if (prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))
        return -EINVAL;
    if (len == 0)
        return 0;
    
    host_start = start & qemu_host_page_mask;
    host_end = HOST_PAGE_ALIGN(end);
    if (start > host_start) {
        /* handle host page containing start */
        prot1 = prot;
        for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) {
            prot1 |= page_get_flags(addr);
        }
        if (host_end == host_start + qemu_host_page_size) {
            for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
                prot1 |= page_get_flags(addr);
            }
            end = host_end;
        }
        ret = mprotect((void *)host_start, qemu_host_page_size, prot1 & PAGE_BITS);
        if (ret != 0)
            return ret;
        host_start += qemu_host_page_size;
    }
    if (end < host_end) {
        prot1 = prot;
        for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
            prot1 |= page_get_flags(addr);
        }
        ret = mprotect((void *)(host_end - qemu_host_page_size), qemu_host_page_size, 
                       prot1 & PAGE_BITS);
        if (ret != 0)
            return ret;
        host_end -= qemu_host_page_size;
    }
    
    /* handle the pages in the middle */
    if (host_start < host_end) {
        ret = mprotect((void *)host_start, host_end - host_start, prot);
        if (ret != 0)
            return ret;
    }
    page_set_flags(start, start + len, prot | PAGE_VALID);
    return 0;
}

/* map an incomplete host page */
int mmap_frag(unsigned long host_start, 
               unsigned long start, unsigned long end, 
               int prot, int flags, int fd, unsigned long offset)
{
    unsigned long host_end, ret, addr;
    int prot1, prot_new;

    host_end = host_start + qemu_host_page_size;

    /* get the protection of the target pages outside the mapping */
    prot1 = 0;
    for(addr = host_start; addr < host_end; addr++) {
        if (addr < start || addr >= end)
            prot1 |= page_get_flags(addr);
    }
    
    if (prot1 == 0) {
        /* no page was there, so we allocate one */
        ret = (long)mmap((void *)host_start, qemu_host_page_size, prot, 
                         flags | MAP_ANONYMOUS, -1, 0);
        if (ret == -1)
            return ret;
    }
    prot1 &= PAGE_BITS;

    prot_new = prot | prot1;
    if (!(flags & MAP_ANONYMOUS)) {
        /* msync() won't work here, so we return an error if write is
           possible while it is a shared mapping */
        if ((flags & MAP_TYPE) == MAP_SHARED &&
            (prot & PROT_WRITE))
            return -EINVAL;

        /* adjust protection to be able to read */
        if (!(prot1 & PROT_WRITE))
            mprotect((void *)host_start, qemu_host_page_size, prot1 | PROT_WRITE);
        
        /* read the corresponding file data */
        pread(fd, (void *)start, end - start, offset);
        
        /* put final protection */
        if (prot_new != (prot1 | PROT_WRITE))
            mprotect((void *)host_start, qemu_host_page_size, prot_new);
    } else {
        /* just update the protection */
        if (prot_new != prot1) {
            mprotect((void *)host_start, qemu_host_page_size, prot_new);
        }
    }
    return 0;
}

/* NOTE: all the constants are the HOST ones */
long target_mmap(unsigned long start, unsigned long len, int prot, 
                 int flags, int fd, unsigned long offset)
{
    unsigned long ret, end, host_start, host_end, retaddr, host_offset, host_len;
#if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__) || \
    defined(__ia64)
    static unsigned long last_start = 0x40000000;
#endif

#ifdef DEBUG_MMAP
    {
        printf("mmap: start=0x%lx len=0x%lx prot=%c%c%c flags=",
               start, len, 
               prot & PROT_READ ? 'r' : '-',
               prot & PROT_WRITE ? 'w' : '-',
               prot & PROT_EXEC ? 'x' : '-');
        if (flags & MAP_FIXED)
            printf("MAP_FIXED ");
        if (flags & MAP_ANONYMOUS)
            printf("MAP_ANON ");
        switch(flags & MAP_TYPE) {
        case MAP_PRIVATE:
            printf("MAP_PRIVATE ");
            break;
        case MAP_SHARED:
            printf("MAP_SHARED ");
            break;
        default:
            printf("[MAP_TYPE=0x%x] ", flags & MAP_TYPE);
            break;
        }
        printf("fd=%d offset=%lx\n", fd, offset);
    }
#endif

    if (offset & ~TARGET_PAGE_MASK) {
        errno = EINVAL;
        return -1;
    }

    len = TARGET_PAGE_ALIGN(len);
    if (len == 0)
        return start;
    host_start = start & qemu_host_page_mask;

    if (!(flags & MAP_FIXED)) {
#if defined(__alpha__) || defined(__sparc__) || defined(__x86_64__) || \
    defined(__ia64)
        /* tell the kenel to search at the same place as i386 */
        if (host_start == 0) {
            host_start = last_start;
            last_start += HOST_PAGE_ALIGN(len);
        }
#endif
        if (qemu_host_page_size != qemu_real_host_page_size) {
            /* NOTE: this code is only for debugging with '-p' option */
            /* reserve a memory area */
            host_len = HOST_PAGE_ALIGN(len) + qemu_host_page_size - TARGET_PAGE_SIZE;
            host_start = (long)mmap((void *)host_start, host_len, PROT_NONE, 
                                    MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
            if (host_start == -1)
                return host_start;
            host_end = host_start + host_len;
            start = HOST_PAGE_ALIGN(host_start);
            end = start + HOST_PAGE_ALIGN(len);
            if (start > host_start)
                munmap((void *)host_start, start - host_start);
            if (end < host_end)
                munmap((void *)end, host_end - end);
            /* use it as a fixed mapping */
            flags |= MAP_FIXED;
        } else {
            /* if not fixed, no need to do anything */
            host_offset = offset & qemu_host_page_mask;
            host_len = len + offset - host_offset;
            start = (long)mmap((void *)host_start, host_len, 
                               prot, flags, fd, host_offset);
            if (start == -1)
                return start;
            /* update start so that it points to the file position at 'offset' */
            if (!(flags & MAP_ANONYMOUS)) 
                start += offset - host_offset;
            goto the_end1;
        }
    }
    
    if (start & ~TARGET_PAGE_MASK) {
        errno = EINVAL;
        return -1;
    }
    end = start + len;
    host_end = HOST_PAGE_ALIGN(end);

    /* worst case: we cannot map the file because the offset is not
       aligned, so we read it */
    if (!(flags & MAP_ANONYMOUS) &&
        (offset & ~qemu_host_page_mask) != (start & ~qemu_host_page_mask)) {
        /* msync() won't work here, so we return an error if write is
           possible while it is a shared mapping */
        if ((flags & MAP_TYPE) == MAP_SHARED &&
            (prot & PROT_WRITE)) {
            errno = EINVAL;
            return -1;
        }
        retaddr = target_mmap(start, len, prot | PROT_WRITE, 
                              MAP_FIXED | MAP_PRIVATE | MAP_ANONYMOUS, 
                              -1, 0);
        if (retaddr == -1)
            return retaddr;
        pread(fd, (void *)start, len, offset);
        if (!(prot & PROT_WRITE)) {
            ret = target_mprotect(start, len, prot);
            if (ret != 0)
                return ret;
        }
        goto the_end;
    }

    /* handle the start of the mapping */
    if (start > host_start) {
        if (host_end == host_start + qemu_host_page_size) {
            /* one single host page */
            ret = mmap_frag(host_start, start, end,
                            prot, flags, fd, offset);
            if (ret == -1)
                return ret;
            goto the_end1;
        }
        ret = mmap_frag(host_start, start, host_start + qemu_host_page_size,
                        prot, flags, fd, offset);
        if (ret == -1)
            return ret;
        host_start += qemu_host_page_size;
    }
    /* handle the end of the mapping */
    if (end < host_end) {
        ret = mmap_frag(host_end - qemu_host_page_size, 
                        host_end - qemu_host_page_size, host_end,
                        prot, flags, fd, 
                        offset + host_end - qemu_host_page_size - start);
        if (ret == -1)
            return ret;
        host_end -= qemu_host_page_size;
    }
    
    /* map the middle (easier) */
    if (host_start < host_end) {
        unsigned long offset1;
	if (flags & MAP_ANONYMOUS)
	  offset1 = 0;
	else
	  offset1 = offset + host_start - start;
        ret = (long)mmap((void *)host_start, host_end - host_start, 
                         prot, flags, fd, offset1);
        if (ret == -1)
            return ret;
    }
 the_end1:
    page_set_flags(start, start + len, prot | PAGE_VALID);
 the_end:
#ifdef DEBUG_MMAP
    printf("ret=0x%lx\n", (long)start);
    page_dump(stdout);
    printf("\n");
#endif
    return start;
}

int target_munmap(unsigned long start, unsigned long len)
{
    unsigned long end, host_start, host_end, addr;
    int prot, ret;

#ifdef DEBUG_MMAP
    printf("munmap: start=0x%lx len=0x%lx\n", start, len);
#endif
    if (start & ~TARGET_PAGE_MASK)
        return -EINVAL;
    len = TARGET_PAGE_ALIGN(len);
    if (len == 0)
        return -EINVAL;
    end = start + len;
    host_start = start & qemu_host_page_mask;
    host_end = HOST_PAGE_ALIGN(end);

    if (start > host_start) {
        /* handle host page containing start */
        prot = 0;
        for(addr = host_start; addr < start; addr += TARGET_PAGE_SIZE) {
            prot |= page_get_flags(addr);
        }
        if (host_end == host_start + qemu_host_page_size) {
            for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
                prot |= page_get_flags(addr);
            }
            end = host_end;
        }
        if (prot != 0)
            host_start += qemu_host_page_size;
    }
    if (end < host_end) {
        prot = 0;
        for(addr = end; addr < host_end; addr += TARGET_PAGE_SIZE) {
            prot |= page_get_flags(addr);
        }
        if (prot != 0)
            host_end -= qemu_host_page_size;
    }
    
    /* unmap what we can */
    if (host_start < host_end) {
        ret = munmap((void *)host_start, host_end - host_start);
        if (ret != 0)
            return ret;
    }

    page_set_flags(start, start + len, 0);
    return 0;
}

/* XXX: currently, we only handle MAP_ANONYMOUS and not MAP_FIXED
   blocks which have been allocated starting on a host page */
long target_mremap(unsigned long old_addr, unsigned long old_size, 
                   unsigned long new_size, unsigned long flags,
                   unsigned long new_addr)
{
    int prot;

    /* XXX: use 5 args syscall */
    new_addr = (long)mremap((void *)old_addr, old_size, new_size, flags);
    if (new_addr == -1)
        return new_addr;
    prot = page_get_flags(old_addr);
    page_set_flags(old_addr, old_addr + old_size, 0);
    page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID);
    return new_addr;
}

int target_msync(unsigned long start, unsigned long len, int flags)
{
    unsigned long end;

    if (start & ~TARGET_PAGE_MASK)
        return -EINVAL;
    len = TARGET_PAGE_ALIGN(len);
    end = start + len;
    if (end < start)
        return -EINVAL;
    if (end == start)
        return 0;
    
    start &= qemu_host_page_mask;
    return msync((void *)start, end - start, flags);
}

