about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-04-02 18:45:04 +0200
committerptitSeb <sebastien.chev@gmail.com>2023-04-02 18:45:04 +0200
commitb3a2031484465e26f71c9bee00ce5e2e9d6fc65a (patch)
tree4134f14fb911f03a5abbb7850fbcd7a89b6388b6 /src
parentabf6e4856c62db53eba7b5a06e9a83d234cad8c8 (diff)
downloadbox64-b3a2031484465e26f71c9bee00ce5e2e9d6fc65a.tar.gz
box64-b3a2031484465e26f71c9bee00ce5e2e9d6fc65a.zip
[DYNAREC] Never protect bridge memory (ported from box86)
Diffstat (limited to 'src')
-rw-r--r--src/custommem.c40
-rw-r--r--src/include/custommem.h7
-rwxr-xr-xsrc/tools/bridge.c19
3 files changed, 29 insertions, 37 deletions
diff --git a/src/custommem.c b/src/custommem.c
index 239af030..2872aa7d 100644
--- a/src/custommem.c
+++ b/src/custommem.c
@@ -798,11 +798,11 @@ void protectDB(uintptr_t addr, uintptr_t size)
         prot&=~PROT_CUSTOM;
         if(!prot)
             prot = PROT_READ | PROT_WRITE | PROT_EXEC;      // comes from malloc & co, so should not be able to execute
-        if((prot&PROT_WRITE)) {
+        if((prot&PROT_WRITE) && !(prot&PROT_NOPROT)) {
             if(!dyn) mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~PROT_WRITE);
-            memprot[i>>16].prot[i&0xffff] = prot|mapped|PROT_DYNAREC;   // need to use atomic exchange?
-        } else 
-            memprot[i>>16].prot[i&0xffff] = prot|mapped|PROT_DYNAREC_R;
+                memprot[i>>16].prot[i&0xffff] = prot|mapped|PROT_DYNAREC;   // need to use atomic exchange?
+            } else 
+                memprot[i>>16].prot[i&0xffff] = prot|mapped|PROT_DYNAREC_R;
     }
     mutex_unlock(&mutex_prot);
 }
@@ -824,14 +824,16 @@ void unprotectDB(uintptr_t addr, size_t size, int mark)
             i=(((i>>16)+1)<<16)-1;  // next block
         } else {
             uint32_t prot = memprot[i>>16].prot[i&0xffff];
-            if(prot&PROT_DYNAREC) {
-                prot&=~PROT_DYN;
-                if(mark)
-                    cleanDBFromAddressRange((i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, 0);
-                mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~PROT_MMAP);
-                memprot[i>>16].prot[i&0xffff] = prot;  // need to use atomic exchange?
-            } else if(prot&PROT_DYNAREC_R)
-                memprot[i>>16].prot[i&0xffff] = prot&~PROT_CUSTOM;
+            if(!(prot&PROT_NOPROT)) {
+                if(prot&PROT_DYNAREC) {
+                    prot&=~PROT_DYN;
+                    if(mark)
+                        cleanDBFromAddressRange((i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, 0);
+                    mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~PROT_MMAP);
+                    memprot[i>>16].prot[i&0xffff] = prot;  // need to use atomic exchange?
+                } else if(prot&PROT_DYNAREC_R)
+                    memprot[i>>16].prot[i&0xffff] = prot&~PROT_CUSTOM;
+            }
         }
     }
     mutex_unlock(&mutex_prot);
@@ -850,7 +852,7 @@ int isprotectedDB(uintptr_t addr, size_t size)
     }
     for (uintptr_t i=idx; i<=end; ++i) {
         uint32_t prot = memprot[i>>16].prot[i&0xffff];
-        if(!(prot&PROT_DYN)) {
+        if(!(prot&PROT_DYN) && !(prot&PROT_NOPROT)) {
             dynarec_log(LOG_DEBUG, "0\n");
             return 0;
         }
@@ -977,11 +979,13 @@ void updateProtection(uintptr_t addr, size_t size, uint32_t prot)
         uint32_t old_prot = memprot[i>>16].prot[i&0xffff];
         uint32_t dyn=(old_prot&PROT_DYN);
         uint32_t mapped=(old_prot&PROT_MMAP);
-        if(dyn && (prot&PROT_WRITE)) {   // need to remove the write protection from this block
-            dyn = PROT_DYNAREC;
-            mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~PROT_WRITE);
-        } else if(dyn && !(prot&PROT_WRITE)) {
-            dyn = PROT_DYNAREC_R;
+        if(!(prot&PROT_NOPROT)) {
+            if(dyn && (prot&PROT_WRITE)) {   // need to remove the write protection from this block
+                dyn = PROT_DYNAREC;
+                mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~PROT_WRITE);
+            } else if(dyn && !(prot&PROT_WRITE)) {
+                dyn = PROT_DYNAREC_R;
+            }
         }
         memprot[i>>16].prot[i&0xffff] = prot|dyn|mapped;
     }
diff --git a/src/include/custommem.h b/src/include/custommem.h
index e03db81c..5f9164f3 100644
--- a/src/include/custommem.h
+++ b/src/include/custommem.h
@@ -51,9 +51,10 @@ uintptr_t getJumpAddress64(uintptr_t addr);
 
 #define PROT_DYNAREC    0x80
 #define PROT_DYNAREC_R  0x40
-#define PROT_MMAP       0x20
-#define PROT_DYN        (PROT_DYNAREC | PROT_DYNAREC_R)
-#define PROT_CUSTOM     (PROT_DYNAREC | PROT_DYNAREC_R | PROT_MMAP)
+#define PROT_NOPROT     0x20
+#define PROT_MMAP       0x10
+#define PROT_DYN        (PROT_DYNAREC | PROT_DYNAREC_R | PROT_NOPROT)
+#define PROT_CUSTOM     (PROT_DYNAREC | PROT_DYNAREC_R | PROT_MMAP | PROT_NOPROT)
 
 void updateProtection(uintptr_t addr, size_t size, uint32_t prot);
 void setProtection(uintptr_t addr, size_t size, uint32_t prot);
diff --git a/src/tools/bridge.c b/src/tools/bridge.c
index 3bc7ca22..16aaaf74 100755
--- a/src/tools/bridge.c
+++ b/src/tools/bridge.c
@@ -60,6 +60,9 @@ brick_t* NewBrick(void* old)
     if(ptr == MAP_FAILED) {
         printf_log(LOG_NONE, "Warning, cannot allocate 0x%lx aligned bytes for bridge, will probably crash later\n", NBRICK*sizeof(onebridge_t));
     }
+    #ifdef DYNAREC
+    setProtection((uintptr_t)ptr, NBRICK * sizeof(onebridge_t), PROT_READ | PROT_WRITE | PROT_EXEC | PROT_NOPROT);
+    #endif
     dynarec_log(LOG_INFO, "New Bridge brick at %p (size 0x%zx)\n", ptr, NBRICK*sizeof(onebridge_t));
     ret->b = ptr;
     return ret;
@@ -82,10 +85,6 @@ void FreeBridge(bridge_t** bridge)
     x64emu_t* emu = thread_get_emu();
     while(b) {
         brick_t *n = b->next;
-        #ifdef DYNAREC
-        if(getProtection((uintptr_t)b->b)&(PROT_DYNAREC|PROT_DYNAREC_R))
-            unprotectDB((uintptr_t)b->b, NBRICK*sizeof(onebridge_t), 0);
-        #endif
         my_munmap(emu, b->b, NBRICK*sizeof(onebridge_t));
         box_free(b);
         b = n;
@@ -119,24 +118,12 @@ uintptr_t AddBridge(bridge_t* bridge, wrapper_t w, void* fnc, int N, const char*
     kh_value(bridge->bridgemap, k) = (uintptr_t)&b->b[sz].CC;
     mutex_unlock(&my_context->mutex_bridge);
 
-    #ifdef DYNAREC
-    int prot = 0;
-    if(box64_dynarec) {
-        prot=(getProtection((uintptr_t)b->b)&(PROT_DYNAREC|PROT_DYNAREC_R))?1:0;
-        if(prot)
-            unprotectDB((uintptr_t)b->b, NBRICK*sizeof(onebridge_t), 0);    // don't mark blocks, it's only new one
-    }
-    #endif
     b->b[sz].CC = 0xCC;
     b->b[sz].S = 'S'; b->b[sz].C='C';
     b->b[sz].w = w;
     b->b[sz].f = (uintptr_t)fnc;
     b->b[sz].C3 = N?0xC2:0xC3;
     b->b[sz].N = N;
-    #ifdef DYNAREC
-    if(box64_dynarec)
-        protectDB((uintptr_t)b->b, NBRICK*sizeof(onebridge_t));
-    #endif
     #ifdef HAVE_TRACE
     if(name)
         addBridgeName(fnc, name);