get mmap.c to compile

This commit is contained in:
tehzz 2020-05-08 14:04:38 -04:00
parent 19069e7148
commit 930dcd2996
2 changed files with 85 additions and 69 deletions

View File

@ -1,6 +1,7 @@
obj-y = main.o syscall.o strace.o mmap.o signal.o \
elfload.o linuxload.o uaccess.o uname.o \
safe-syscall.o
safe-syscall.o \
shim_fallocate.o shim_gettid.o shim_timers.o
obj-$(TARGET_HAS_BFLT) += flatload.o
obj-$(TARGET_I386) += vm86.o

View File

@ -24,6 +24,11 @@
//#define DEBUG_MMAP
/** macOS does not define this mask for the sharing type and options
* this both matches the flag in linux, and works with macOS
*/
#define MAP_TYPE 0x000f
static pthread_mutex_t mmap_mutex = PTHREAD_MUTEX_INITIALIZER;
static __thread int mmap_lock_count;
@ -671,79 +676,89 @@ int target_munmap(abi_ulong start, abi_ulong len)
return ret;
}
/** macOS/darwin does not have mremap. It is possible that (parts?) of
* of this syscall could be emualted, but it is not necessary for Irix
* https://ipads.se.sjtu.edu.cn:1312/opensource/powerlyra/commit/e226dc04639692b57fcaf666cf4006498c48f516
*/
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;
mmap_lock();
if (flags & MREMAP_FIXED) {
host_addr = mremap(g2h(old_addr), old_size, new_size,
flags, g2h(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(old_addr, old_size);
}
} else if (flags & MREMAP_MAYMOVE) {
abi_ulong mmap_start;
mmap_start = mmap_find_vma(0, new_size);
if (mmap_start == -1) {
errno = ENOMEM;
host_addr = MAP_FAILED;
} else {
host_addr = mremap(g2h(old_addr), old_size, new_size,
flags | MREMAP_FIXED, g2h(mmap_start));
if (reserved_va) {
mmap_reserve(old_addr, old_size);
}
}
} else {
int prot = 0;
if (reserved_va && old_size < new_size) {
abi_ulong addr;
for (addr = old_addr + old_size;
addr < old_addr + new_size;
addr++) {
prot |= page_get_flags(addr);
}
}
if (prot == 0) {
host_addr = mremap(g2h(old_addr), old_size, new_size, flags);
if (host_addr != MAP_FAILED && reserved_va && old_size > new_size) {
mmap_reserve(old_addr + old_size, new_size - old_size);
}
} else {
errno = ENOMEM;
host_addr = MAP_FAILED;
}
/* Check if address fits target address space */
if ((unsigned long)host_addr + new_size > (abi_ulong)-1) {
/* Revert mremap() changes */
host_addr = mremap(g2h(old_addr), new_size, old_size, flags);
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, 0);
page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID);
}
tb_invalidate_phys_range(new_addr, new_addr + new_size);
mmap_unlock();
return new_addr;
return -1;
}
// 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;
//
// mmap_lock();
//
// if (flags & MREMAP_FIXED) {
// host_addr = mremap(g2h(old_addr), old_size, new_size,
// flags, g2h(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(old_addr, old_size);
// }
// } else if (flags & MREMAP_MAYMOVE) {
// abi_ulong mmap_start;
//
// mmap_start = mmap_find_vma(0, new_size);
//
// if (mmap_start == -1) {
// errno = ENOMEM;
// host_addr = MAP_FAILED;
// } else {
// host_addr = mremap(g2h(old_addr), old_size, new_size,
// flags | MREMAP_FIXED, g2h(mmap_start));
// if (reserved_va) {
// mmap_reserve(old_addr, old_size);
// }
// }
// } else {
// int prot = 0;
// if (reserved_va && old_size < new_size) {
// abi_ulong addr;
// for (addr = old_addr + old_size;
// addr < old_addr + new_size;
// addr++) {
// prot |= page_get_flags(addr);
// }
// }
// if (prot == 0) {
// host_addr = mremap(g2h(old_addr), old_size, new_size, flags);
// if (host_addr != MAP_FAILED && reserved_va && old_size > new_size) {
// mmap_reserve(old_addr + old_size, new_size - old_size);
// }
// } else {
// errno = ENOMEM;
// host_addr = MAP_FAILED;
// }
// /* Check if address fits target address space */
// if ((unsigned long)host_addr + new_size > (abi_ulong)-1) {
// /* Revert mremap() changes */
// host_addr = mremap(g2h(old_addr), new_size, old_size, flags);
// 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, 0);
// page_set_flags(new_addr, new_addr + new_size, prot | PAGE_VALID);
// }
// tb_invalidate_phys_range(new_addr, new_addr + new_size);
// mmap_unlock();
// return new_addr;
// }
int target_msync(abi_ulong start, abi_ulong len, int flags)
{