about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-04-02 13:38:23 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-04-02 13:38:23 +0200
commit128724d147a0079952275e1bbce48a7e2a0522ab (patch)
tree829a04caf0a69161fceaaaf67347f45d5b44fb00 /src
parentc6c6bfcf2c6aae86d34c29cee3e73031305a72da (diff)
downloadbox64-128724d147a0079952275e1bbce48a7e2a0522ab.tar.gz
box64-128724d147a0079952275e1bbce48a7e2a0522ab.zip
Implemented a workaround for mmap64 with MAP_32BIT flag
Diffstat (limited to 'src')
-rw-r--r--src/custommem.c35
-rw-r--r--src/include/custommem.h3
-rwxr-xr-xsrc/wrapped/wrappedlibc.c7
3 files changed, 45 insertions, 0 deletions
diff --git a/src/custommem.c b/src/custommem.c
index 956e67fd..d1921b83 100644
--- a/src/custommem.c
+++ b/src/custommem.c
@@ -803,6 +803,41 @@ uint32_t getProtection(uintptr_t addr)
     return ret;
 }
 
+#ifndef NOALIGN
+#define LOWEST (void*)0x20000
+int availableBlock(uint8_t* p, size_t n)
+{
+    for (int i=0; i<n; ++i, ++p)
+        if(*p)
+            return 0;
+    return 1;
+}
+void* find32bitBlock(size_t size)
+{
+    // slow iterative search... Would need something better one day
+    const uint32_t key = 0; // upper value is 0 by request
+    pthread_mutex_lock(&mutex_prot);
+    khint_t k = kh_get(memprot, memprot, key);
+    if(k==kh_end(memprot)) {
+        pthread_mutex_unlock(&mutex_prot);
+        return LOWEST;
+    }
+    uint8_t *prot = kh_val(memprot, k);
+    pthread_mutex_unlock(&mutex_prot);
+    void* p = (void*)LOWEST;
+    int pages = (size+MEMPROT_SIZE-1)>>MEMPROT_SHIFT;
+    do {
+        const uintptr_t idx = ((((uintptr_t)p)&0xffffffff)>>MEMPROT_SHIFT);
+        if(availableBlock(prot+idx, pages))
+            return p;
+        p += 0x10000;
+    } while(p!=(void*)0xffff0000);
+    return NULL;
+}
+#undef LOWEST
+#endif
+
+
 void init_custommem_helper(box64context_t* ctx)
 {
     if(inited) // already initialized
diff --git a/src/include/custommem.h b/src/include/custommem.h
index c1de067f..551063d1 100644
--- a/src/include/custommem.h
+++ b/src/include/custommem.h
@@ -45,6 +45,9 @@ void unprotectDB(uintptr_t addr, uintptr_t size);
 void lockDB();
 void unlockDB();
 #endif
+#ifndef NOALIGN
+void* find32bitBlock(size_t size);
+#endif
 
 
 void init_custommem_helper(box64context_t* ctx);
diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c
index 756a8ee8..fa021802 100755
--- a/src/wrapped/wrappedlibc.c
+++ b/src/wrapped/wrappedlibc.c
@@ -1887,6 +1887,13 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot
     if(prot&PROT_WRITE) 
         prot|=PROT_READ;    // PROT_READ is implicit with PROT_WRITE on i386
     if(box64_log<LOG_DEBUG) {dynarec_log(LOG_DEBUG, "mmap64(%p, %lu, 0x%x, 0x%x, %d, %ld) =>", addr, length, prot, flags, fd, offset);}
+    #ifndef NOALIGN
+    if(!addr && (flags&0x40)) {
+        // 0x40 is MAP_32BIT, wich only exist on x86_64!
+        //flags &= ~0x40;   // let the flags in?
+        addr = find32bitBlock(length);
+    }
+    #endif
     void* ret = mmap64(addr, length, prot, flags, fd, offset);
     if(box64_log<LOG_DEBUG) {dynarec_log(LOG_DEBUG, "%p\n", ret);}
     #ifdef DYNAREC