From c71035530a982ac940aa5c71233edf2e21445c92 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Sat, 28 Oct 2023 10:16:55 +0200 Subject: More small improvment to wrapped mmap64 --- src/wrapped/wrappedlibc.c | 39 ++++++++++++++++++++++++++------------- 1 file changed, 26 insertions(+), 13 deletions(-) diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index d78b6ecb..d44d3ad2 100644 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -2545,49 +2545,62 @@ EXPORT int my_readlinkat(x64emu_t* emu, int fd, void* path, void* buf, size_t bu } return readlinkat(fd, path, buf, bufsize); } - +#ifndef MAP_FIXED_NOREPLACE +#define MAP_FIXED_NOREPLACE 0x200000 +#endif +#ifndef MAP_32BIT +#define MAP_32BIT 0x40 +#endif EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot, int flags, int fd, int64_t offset) { (void)emu; if(prot&PROT_WRITE) prot|=PROT_READ; // PROT_READ is implicit with PROT_WRITE on i386 if(box64_log ", addr, length, prot, flags, fd, offset);} + int new_flags = flags; #ifndef NOALIGN void* old_addr = addr; - if(flags&0x40) { - // 0x40 is MAP_32BIT, wich only exist on x86_64! - //flags &= ~0x40; // let the flags in? + new_flags&=~MAP_32BIT; // remove MAP_32BIT + if(flags&MAP_32BIT) { + // MAP_32BIT only exist on x86_64! addr = find31bitBlockNearHint(addr, length); } else if (box64_wine || 1) { // other mmap should be restricted to 47bits if(!addr) addr = find47bitBlock(length); } #endif - void* ret = mmap64(addr, length, prot, flags, fd, offset); + void* ret = mmap64(addr, length, prot, new_flags, fd, offset); #ifndef NOALIGN - if((ret!=(void*)-1) && (flags&0x40) && + if((ret!=MAP_FAILED) && (flags&MAP_32BIT) && (((uintptr_t)ret>0xffffffffLL) || (box64_wine && ((uintptr_t)ret&0xffff)))) { printf_log(LOG_DEBUG, "Warning, mmap on 32bits didn't worked, ask %p, got %p ", addr, ret); munmap(ret, length); loadProtectionFromMap(); // reload map, because something went wrong previously addr = find31bitBlockNearHint(old_addr, length); // is this the best way? - uint32_t new_flags = (addr && isBlockFree(addr, length) )? (flags|MAP_FIXED) : flags; + new_flags = (addr && isBlockFree(addr, length) )? (new_flags|MAP_FIXED) : new_flags; + if(new_flags&(MAP_FIXED|MAP_FIXED_NOREPLACE)==(MAP_FIXED|MAP_FIXED_NOREPLACE)) new_flags&=~MAP_FIXED_NOREPLACE; ret = mmap64(addr, length, prot, new_flags, fd, offset); printf_log(LOG_DEBUG, " tried again with %p, got %p\n", addr, ret); - } else if((ret!=(void*)-1) && !(flags&MAP_FIXED) && (box64_wine) && (old_addr) && (addr!=ret) && + } else if((ret!=MAP_FAILED) && !(flags&MAP_FIXED) && (box64_wine) && (old_addr) && (addr!=ret) && (((uintptr_t)ret>0x7fffffffffffLL) || ((uintptr_t)ret&~0xffff))) { printf_log(LOG_DEBUG, "Warning, mmap on 47bits didn't worked, ask %p, got %p ", addr, ret); munmap(ret, length); loadProtectionFromMap(); // reload map, because something went wrong previously addr = find47bitBlockNearHint(old_addr, length); // is this the best way? - uint32_t new_flags = (addr && isBlockFree(addr, length)) ? (flags|MAP_FIXED) : flags; + new_flags = (addr && isBlockFree(addr, length)) ? (new_flags|MAP_FIXED) : new_flags; + if(new_flags&(MAP_FIXED|MAP_FIXED_NOREPLACE)==(MAP_FIXED|MAP_FIXED_NOREPLACE)) new_flags&=~MAP_FIXED_NOREPLACE; ret = mmap64(addr, length, prot, new_flags, fd, offset); printf_log(LOG_DEBUG, " tried again with %p, got %p\n", addr, ret); } #endif + if((ret!=MAP_FAILED) && (flags&MAP_FIXED_NOREPLACE) && (ret!=addr)) { + munmap(ret, length); + errno = EEXIST; + return MAP_FAILED; + } if(box64_log