diff --git a/darwin-user/Makefile.objs b/darwin-user/Makefile.objs index 8c93058100..54fe9214d8 100644 --- a/darwin-user/Makefile.objs +++ b/darwin-user/Makefile.objs @@ -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 diff --git a/darwin-user/mmap.c b/darwin-user/mmap.c index 0fbfd6dff2..ce379201a0 100644 --- a/darwin-user/mmap.c +++ b/darwin-user/mmap.c @@ -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) {