about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2024-02-01 16:41:16 +0100
committerptitSeb <sebastien.chev@gmail.com>2024-02-01 16:42:16 +0100
commit1344b1837909da6d91153cf686557a4a10bcb468 (patch)
tree4094e4397b3b0c3d7170687ed2f9dd69bba5f5c5 /src
parent1deec05f3dfaa93b034d0bb7cf00b0f9d73d4016 (diff)
downloadbox64-1344b1837909da6d91153cf686557a4a10bcb468.tar.gz
box64-1344b1837909da6d91153cf686557a4a10bcb468.zip
[DYNAREC] Handling of memfd_create backed mmap on dynarec (help #1234 but doesn't solve it completly)
Diffstat (limited to 'src')
-rw-r--r--src/custommem.c10
-rw-r--r--src/dynarec/dynablock.c4
-rw-r--r--src/dynarec/dynarec_native.c7
-rw-r--r--src/include/custommem.h6
-rw-r--r--src/wrapped/wrappedlibc.c11
5 files changed, 27 insertions, 11 deletions
diff --git a/src/custommem.c b/src/custommem.c
index 9882f886..ac3643b0 100644
--- a/src/custommem.c
+++ b/src/custommem.c
@@ -994,7 +994,7 @@ uintptr_t getJumpAddress64(uintptr_t addr)
 // Remove the Write flag from an adress range, so DB can be executed safely
 void protectDBJumpTable(uintptr_t addr, size_t size, void* jump, void* ref)
 {
-    dynarec_log(LOG_DEBUG, "protectDB %p -> %p\n", (void*)addr, (void*)(addr+size-1));
+    dynarec_log(LOG_DEBUG, "protectDBJumpTable %p -> %p\n", (void*)addr, (void*)(addr+size-1));
 
     uintptr_t cur = addr&~(box64_pagesize-1);
     uintptr_t end = ALIGN(addr+size);
@@ -1010,7 +1010,7 @@ void protectDBJumpTable(uintptr_t addr, size_t size, void* jump, void* ref)
         uint32_t dyn = prot&PROT_DYN;
         if(!prot)
             prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-        if(!(dyn&PROT_NOPROT)) {
+        if(!(dyn&PROT_NEVERPROT)) {
             prot&=~PROT_CUSTOM;
             if(prot&PROT_WRITE) {
                 if(!dyn) 
@@ -1047,7 +1047,7 @@ void protectDB(uintptr_t addr, uintptr_t size)
         uint32_t dyn = prot&PROT_DYN;
         if(!prot)
             prot = PROT_READ | PROT_WRITE | PROT_EXEC;
-        if(!(dyn&PROT_NOPROT)) {
+        if(!(dyn&PROT_NEVERPROT)) {
             prot&=~PROT_CUSTOM;
             if(prot&PROT_WRITE) {
                 if(!dyn) 
@@ -1085,7 +1085,7 @@ void unprotectDB(uintptr_t addr, size_t size, int mark)
         oprot = prot;
         if(bend>end)
             bend = end;
-        if(!(prot&PROT_NOPROT)) {
+        if(!(prot&PROT_NEVERPROT)) {
             if(prot&PROT_DYNAREC) {
                 prot&=~PROT_DYN;
                 if(mark)
@@ -1137,7 +1137,7 @@ void updateProtection(uintptr_t addr, size_t size, uint32_t prot)
         uint32_t oprot;
         rb_get_end(memprot, cur, &oprot, &bend);
         uint32_t dyn=(oprot&PROT_DYN);
-        if(!(dyn&PROT_NOPROT)) {
+        if(!(dyn&PROT_NEVERPROT)) {
             if(dyn && (prot&PROT_WRITE)) {   // need to remove the write protection from this block
                 dyn = PROT_DYNAREC;
                 mprotect((void*)cur, bend-cur, prot&~PROT_WRITE);
diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c
index 11499203..c3fa4726 100644
--- a/src/dynarec/dynablock.c
+++ b/src/dynarec/dynablock.c
@@ -278,7 +278,7 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits)
         int need_lock = mutex_trylock(&my_context->mutex_dyndump);
         if(hash!=db->hash) {
             db->done = 0;   // invalidating the block
-            dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, hash, db->hash, (void*)addr);
+            dynarec_log(LOG_DEBUG, "Invalidating block %p from %p:%p (hash:%X/%X, always_test:%d) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, hash, db->hash, db->always_test,(void*)addr);
             // Free db, it's now invalid!
             dynablock_t* old = InvalidDynablock(db, need_lock);
             // start again... (will create a new block)
@@ -290,7 +290,7 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits)
             } else
                 FreeInvalidDynablock(old, need_lock);
         } else {
-            dynarec_log(LOG_DEBUG, "Validating block %p from %p:%p (hash:%X) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, db->hash, (void*)addr);
+            dynarec_log(LOG_DEBUG, "Validating block %p from %p:%p (hash:%X, always_test:%d) for %p\n", db, db->x64_addr, db->x64_addr+db->x64_size-1, db->hash, db->always_test, (void*)addr);
             if(db->always_test)
                 protectDB((uintptr_t)db->x64_addr, db->x64_size);
             else
diff --git a/src/dynarec/dynarec_native.c b/src/dynarec/dynarec_native.c
index 6dfc9c89..46360231 100644
--- a/src/dynarec/dynarec_native.c
+++ b/src/dynarec/dynarec_native.c
@@ -655,6 +655,13 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr, int alternate, int is32bit
         block->dirty = 1;
         //protectDB(addr, end-addr);
     }
+    if(getProtection(addr)&PROT_NEVERCLEAN) {
+        block->dirty = 1;
+        block->always_test = 1;
+    }
+    if(block->always_test) {
+        dynarec_log(LOG_DEBUG, "Note: block marked as always dirty %p:%ld\n", block->x64_addr, block->x64_size);
+    }
     current_helper = NULL;
     //block->done = 1;
     return (void*)block;
diff --git a/src/include/custommem.h b/src/include/custommem.h
index aa0e7f4d..71ed1b0c 100644
--- a/src/include/custommem.h
+++ b/src/include/custommem.h
@@ -70,11 +70,13 @@ uintptr_t getJumpAddress64(uintptr_t addr);
 #endif //SAVE_MEM
 #endif
 
+#define PROT_NEVERCLEAN 0x100
 #define PROT_DYNAREC    0x80
 #define PROT_DYNAREC_R  0x40
 #define PROT_NOPROT     0x20
-#define PROT_DYN        (PROT_DYNAREC | PROT_DYNAREC_R | PROT_NOPROT)
-#define PROT_CUSTOM     (PROT_DYNAREC | PROT_DYNAREC_R | PROT_NOPROT)
+#define PROT_DYN        (PROT_DYNAREC | PROT_DYNAREC_R | PROT_NOPROT | PROT_NEVERCLEAN)
+#define PROT_CUSTOM     (PROT_DYNAREC | PROT_DYNAREC_R | PROT_NOPROT | PROT_NEVERCLEAN)
+#define PROT_NEVERPROT  (PROT_NOPROT | PROT_NEVERCLEAN)
 #define PROT_WAIT       0xFF
 
 void updateProtection(uintptr_t addr, size_t size, uint32_t prot);
diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c
index c67db340..03d1c75a 100644
--- a/src/wrapped/wrappedlibc.c
+++ b/src/wrapped/wrappedlibc.c
@@ -2624,7 +2624,7 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot
     void* ret = internal_mmap(addr, length, prot, new_flags, fd, offset);
     #ifndef NOALIGN
     if((ret!=MAP_FAILED) && (flags&MAP_32BIT) &&
-      (((uintptr_t)ret>0xffffffffLL) || (box64_wine && ((uintptr_t)ret&0xffff) && (ret!=addr)))) {
+      (((uintptr_t)ret>0xffffffffLL) || ((box64_wine || 1) && ((uintptr_t)ret&0xffff) && (ret!=addr)))) {
         int olderr = errno;
         if(emu && (box64_log>=LOG_DEBUG || box64_dynarec_log>=LOG_DEBUG)) printf_log(LOG_NONE, "Warning, mmap on 32bits didn't worked, ask %p, got %p ", addr, ret);
         munmap(ret, length);
@@ -2636,7 +2636,7 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot
         if(emu && (box64_log>=LOG_DEBUG || box64_dynarec_log>=LOG_DEBUG)) printf_log(LOG_NONE, " tried again with %p, got %p\n", addr, ret);
         if(old_addr && ret!=old_addr && ret!=MAP_FAILED)
             errno = olderr;
-    } else if((ret!=MAP_FAILED) && !(flags&MAP_FIXED) && (box64_wine) && (old_addr) && (addr!=ret) &&
+    } else if((ret!=MAP_FAILED) && !(flags&MAP_FIXED) && ((box64_wine || 1)) && (old_addr) && (addr!=ret) &&
              (((uintptr_t)ret>0x7fffffffffffLL) || ((uintptr_t)ret&~0xffff))) {
         int olderr = errno;
         if(emu && (box64_log>=LOG_DEBUG || box64_dynarec_log>=LOG_DEBUG)) printf_log(LOG_NONE, "Warning, mmap on 47bits didn't worked, ask %p, got %p ", addr, ret);
@@ -2675,6 +2675,13 @@ EXPORT void* my_mmap64(x64emu_t* emu, void *addr, unsigned long length, int prot
     }
     #endif
     if(ret!=MAP_FAILED) {
+        if((flags&MAP_SHARED) && (fd>0)) {
+            uint32_t flags = fcntl(fd, F_GETFL);
+            if((flags&O_ACCMODE)==O_RDWR) {
+                if((box64_log>=LOG_DEBUG || box64_dynarec_log>=LOG_DEBUG)) {printf_log(LOG_NONE, "Note: Marking the region as NEVERCLEAN because fd have O_RDWR attribute\n");}
+                prot |= PROT_NEVERCLEAN;
+            }
+        }
         if(emu)
             setProtection_mmap((uintptr_t)ret, length, prot);
         else