diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2024-01-29 09:57:02 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2024-01-29 09:57:02 +0100 |
| commit | 8ee250e9acd463b74e57c677630f8cb3c3c3e78b (patch) | |
| tree | be3920e2f8b20b15361fdc7e0afd0ecbba68d7d0 /src | |
| parent | e485fe1d1855bef0e3e6e25b4ac48a7f8a7c7776 (diff) | |
| download | box64-8ee250e9acd463b74e57c677630f8cb3c3c3e78b.tar.gz box64-8ee250e9acd463b74e57c677630f8cb3c3c3e78b.zip | |
[DYNAREC] Small improvment in dynablock/protectDB handling
Diffstat (limited to 'src')
| -rw-r--r-- | src/custommem.c | 39 | ||||
| -rw-r--r-- | src/dynarec/dynablock.c | 18 | ||||
| -rw-r--r-- | src/include/custommem.h | 1 |
3 files changed, 47 insertions, 11 deletions
diff --git a/src/custommem.c b/src/custommem.c index 03d02e24..9882f886 100644 --- a/src/custommem.c +++ b/src/custommem.c @@ -992,6 +992,43 @@ 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)); + + uintptr_t cur = addr&~(box64_pagesize-1); + uintptr_t end = ALIGN(addr+size); + + mutex_lock(&mutex_prot); + while(cur!=end) { + uint32_t prot = 0, oprot; + uintptr_t bend = 0; + rb_get_end(memprot, cur, &prot, &bend); + if(bend>end) + bend = end; + oprot = prot; + uint32_t dyn = prot&PROT_DYN; + if(!prot) + prot = PROT_READ | PROT_WRITE | PROT_EXEC; + if(!(dyn&PROT_NOPROT)) { + prot&=~PROT_CUSTOM; + if(prot&PROT_WRITE) { + if(!dyn) + mprotect((void*)cur, bend-cur, prot&~PROT_WRITE); + prot |= PROT_DYNAREC; + } else + prot |= PROT_DYNAREC_R; + } + if (prot != oprot) // If the node doesn't exist, then prot != 0 + rb_set(memprot, cur, bend, prot); + cur = bend; + } + if(jump) + setJumpTableIfRef64((void*)addr, jump, ref); + mutex_unlock(&mutex_prot); +} + +// Remove the Write flag from an adress range, so DB can be executed safely void protectDB(uintptr_t addr, uintptr_t size) { dynarec_log(LOG_DEBUG, "protectDB %p -> %p\n", (void*)addr, (void*)(addr+size-1)); @@ -1067,8 +1104,8 @@ void unprotectDB(uintptr_t addr, size_t size, int mark) int isprotectedDB(uintptr_t addr, size_t size) { dynarec_log(LOG_DEBUG, "isprotectedDB %p -> %p => ", (void*)addr, (void*)(addr+size-1)); - uintptr_t end = ALIGN(addr+size); addr &=~(box64_pagesize-1); + uintptr_t end = ALIGN(addr+size); mutex_lock(&mutex_prot); while (addr < end) { uint32_t prot; diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c index fda14912..11499203 100644 --- a/src/dynarec/dynablock.c +++ b/src/dynarec/dynablock.c @@ -291,11 +291,10 @@ dynablock_t* DBGetBlock(x64emu_t* emu, uintptr_t addr, int create, int is32bits) 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); - protectDB((uintptr_t)db->x64_addr, db->x64_size); - // fill back jumptable - if(isprotectedDB((uintptr_t)db->x64_addr, db->x64_size) && !db->always_test) { - setJumpTableIfRef64(db->x64_addr, db->block, db->jmpnext); - } + if(db->always_test) + protectDB((uintptr_t)db->x64_addr, db->x64_size); + else + protectDBJumpTable((uintptr_t)db->x64_addr, db->x64_size, db->block, db->jmpnext); } if(!need_lock) mutex_unlock(&my_context->mutex_dyndump); @@ -329,11 +328,10 @@ dynablock_t* DBAlternateBlock(x64emu_t* emu, uintptr_t addr, uintptr_t filladdr, } else FreeInvalidDynablock(old, need_lock); } else { - protectDB((uintptr_t)db->x64_addr, db->x64_size); - // fill back jumptable - if(isprotectedDB((uintptr_t)db->x64_addr, db->x64_size) && !db->always_test) { - setJumpTableIfRef64(db->x64_addr, db->block, db->jmpnext); - } + if(db->always_test) + protectDB((uintptr_t)db->x64_addr, db->x64_size); + else + protectDBJumpTable((uintptr_t)db->x64_addr, db->x64_size, db->block, db->jmpnext); } if(!need_lock) mutex_unlock(&my_context->mutex_dyndump); diff --git a/src/include/custommem.h b/src/include/custommem.h index d6867a4f..aa0e7f4d 100644 --- a/src/include/custommem.h +++ b/src/include/custommem.h @@ -88,6 +88,7 @@ int getMmapped(uintptr_t addr); void loadProtectionFromMap(void); #ifdef DYNAREC void protectDB(uintptr_t addr, size_t size); +void protectDBJumpTable(uintptr_t addr, size_t size, void* jump, void* ref); void unprotectDB(uintptr_t addr, size_t size, int mark); // if mark==0, the blocks are not marked as potentially dirty int isprotectedDB(uintptr_t addr, size_t size); #endif |