diff options
Diffstat (limited to 'linux-user')
-rw-r--r-- | linux-user/mmap.c | 46 |
1 files changed, 46 insertions, 0 deletions
diff --git a/linux-user/mmap.c b/linux-user/mmap.c index b4ca1074b3..be1ddb9f25 100644 --- a/linux-user/mmap.c +++ b/linux-user/mmap.c @@ -73,6 +73,52 @@ void mmap_unlock(void) } #endif +void *qemu_vmalloc(size_t size) +{ + void *p; + unsigned long addr; + mmap_lock(); + /* Use map and mark the pages as used. */ + p = mmap(NULL, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + addr = (unsigned long)p; + if (addr == (target_ulong) addr) { + /* Allocated region overlaps guest address space. + This may recurse. */ + page_set_flags(addr & TARGET_PAGE_MASK, TARGET_PAGE_ALIGN(addr + size), + PAGE_RESERVED); + } + + mmap_unlock(); + return p; +} + +void *qemu_malloc(size_t size) +{ + char * p; + size += 16; + p = qemu_vmalloc(size); + *(size_t *)p = size; + return p + 16; +} + +/* We use map, which is always zero initialized. */ +void * qemu_mallocz(size_t size) +{ + return qemu_malloc(size); +} + +void qemu_free(void *ptr) +{ + /* FIXME: We should unmark the reserved pages here. However this gets + complicated when one target page spans multiple host pages, so we + don't bother. */ + size_t *p; + p = (size_t *)((char *)ptr - 16); + munmap(p, *p); +} + /* NOTE: all the constants are the HOST ones, but addresses are target. */ int target_mprotect(abi_ulong start, abi_ulong len, int prot) { |