diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/custommem.c | 40 | ||||
| -rw-r--r-- | src/include/custommem.h | 7 | ||||
| -rwxr-xr-x | src/tools/bridge.c | 19 |
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); |