about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <seebastien.chev@gmail.com>2023-10-27 09:57:34 +0200
committerptitSeb <seebastien.chev@gmail.com>2023-10-27 09:57:34 +0200
commitf8d65a831e6f92314513ab2603e74627bbc1711f (patch)
tree9ab42aeb8f8da14cd9aca9ad4cf60d7aefe90abf /src
parenta1ac21af75b0fae21981830e660cc31527f9f0f0 (diff)
downloadbox64-f8d65a831e6f92314513ab2603e74627bbc1711f.tar.gz
box64-f8d65a831e6f92314513ab2603e74627bbc1711f.zip
Another fix to wrapped mmap (should fix #1031, hopefully not creating more regression)
Diffstat (limited to 'src')
-rw-r--r--src/custommem.c18
-rw-r--r--src/include/custommem.h1
-rw-r--r--src/wrapped/wrappedlibc.c4
3 files changed, 21 insertions, 2 deletions
diff --git a/src/custommem.c b/src/custommem.c
index a5f4cf61..1a5da272 100644
--- a/src/custommem.c
+++ b/src/custommem.c
@@ -1571,6 +1571,24 @@ void* find47bitBlockNearHint(void* hint, size_t size)
     return NULL;
 }
 
+int isBlockFree(void* hint, size_t size)
+{
+    mapmem_t* m = mapmem;
+    uintptr_t h = (uintptr_t)hint;
+    if(h>0x800000000000LL)
+        return 0;   // no tracking there
+    while(m && m->end<0x800000000000LL) {
+        uintptr_t addr = (m->end+1+0xffff)&~0xffff;
+        uintptr_t end = (m->next)?(m->next->begin-1):0xffffffffffffffffLL;
+        if(addr<=h && end>=h && end-h+1>=size)
+            return 1;
+        if(addr>h)
+            return 0;
+        m = m->next;
+    }
+    return 0;
+}
+
 int unlockCustommemMutex()
 {
     int ret = 0;
diff --git a/src/include/custommem.h b/src/include/custommem.h
index ac715b52..31b3f30e 100644
--- a/src/include/custommem.h
+++ b/src/include/custommem.h
@@ -96,6 +96,7 @@ void* find32bitBlock(size_t size);
 void* find31bitBlockNearHint(void* hint, size_t size);
 void* find47bitBlock(size_t size);
 void* find47bitBlockNearHint(void* hint, size_t size);
+int isBlockFree(void* hint, size_t size);
 
 // unlock mutex that are locked by current thread (for signal handling). Return a mask of unlock mutex
 int unlockCustommemMutex(void);
diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c
index b63e55b7..47c6da19 100644
--- a/src/wrapped/wrappedlibc.c
+++ b/src/wrapped/wrappedlibc.c
@@ -2566,7 +2566,7 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot
         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 ? flags|MAP_FIXED : flags;
+        uint32_t new_flags = (addr && isBlockFree(addr, length) )? (flags|MAP_FIXED) : flags;
         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) &&
@@ -2575,7 +2575,7 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot
         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 ? flags|MAP_FIXED : flags;
+        uint32_t new_flags = (addr && isBlockFree(addr, length)) ? (flags|MAP_FIXED) : flags;
         ret = mmap64(addr, length, prot, new_flags, fd, offset);
         printf_log(LOG_DEBUG, " tried again with %p, got %p\n", addr, ret);
     }