diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2021-06-21 10:49:42 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2021-06-21 10:49:42 +0200 |
| commit | bcd504eb055af1a13d69dbb3cbe0c7f00654d468 (patch) | |
| tree | 5596bc8aa2537cc55d9370722173e877e62afc40 /src | |
| parent | 7057b7f92962c6971fbd617cb9e78c7251a1c403 (diff) | |
| download | box64-bcd504eb055af1a13d69dbb3cbe0c7f00654d468.tar.gz box64-bcd504eb055af1a13d69dbb3cbe0c7f00654d468.zip | |
Various change to try improve stability on JIT'd program (like mono for Terraria, with moderate success)
Diffstat (limited to 'src')
| -rw-r--r-- | src/custommem.c | 41 | ||||
| -rwxr-xr-x | src/dynarec/dynablock.c | 7 | ||||
| -rwxr-xr-x | src/dynarec/dynarec_arm64.c | 4 |
3 files changed, 19 insertions, 33 deletions
diff --git a/src/custommem.c b/src/custommem.c index 151dad63..e1413157 100644 --- a/src/custommem.c +++ b/src/custommem.c @@ -561,20 +561,22 @@ void cleanDBFromAddressRange(uintptr_t addr, size_t size, int destroy) dynablocklist_t* dblist = dynmap123[idx3][idx2][idx1]; if(dblist) { if(destroy) { - if(FreeRangeDynablock(dblist, addr, size)) { // dblist is empty, check if we can delete more... + if(FreeRangeDynablock(dblist, addr, size) && 0) { // dblist is empty, check if we can delete more... + // disabling this for now. It seems to cause random crash in Terraria if(!arm64_lock_storeifref(&dynmap123[idx3][idx2][idx1], NULL, dblist)) { - free(dblist); dynablocklist_t** p = dynmap123[idx3][idx2]; if(dynmapempty((void**)p)) { if(!arm64_lock_storeifref(&dynmap123[idx3][idx2], NULL, p)) { - free(p); dynablocklist_t*** p2 = dynmap123[idx3]; if(dynmapempty((void**)p2)) { - if(!arm64_lock_storeifref(&dynmap123[idx3], NULL, p2)) + if(!arm64_lock_storeifref(&dynmap123[idx3], NULL, p2)) { free(p2); + } } + free(p); } } + FreeDynablockList(&dblist); } } } else @@ -690,15 +692,13 @@ uintptr_t getJumpTableAddress64(uintptr_t addr) return (uintptr_t)&box64_jmptbl3[idx3][idx2][idx1][idx0]; } -// Remove the Write flag from an adress range, so DB can be executed -// no log, as it can be executed inside a signal handler -void protectDB(uintptr_t addr, size_t size) +// Remove the Write flag from an adress range, so DB can be executed safely +void protectDBnolock(uintptr_t addr, uintptr_t size) { dynarec_log(LOG_DEBUG, "protectDB %p -> %p\n", (void*)addr, (void*)(addr+size-1)); uintptr_t idx = (addr>>MEMPROT_SHIFT); uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT); int ret; - pthread_mutex_lock(&mutex_prot); for (uintptr_t i=idx; i<=end; ++i) { const uint32_t key = (i>>MEMPROT_SHIFT2)&0xffffffff; khint_t k = kh_put(memprot, memprot, key, &ret); @@ -714,30 +714,13 @@ void protectDB(uintptr_t addr, size_t size) if(!(prot&PROT_DYNAREC)) mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~(PROT_WRITE|PROT_CUSTOM)); } - pthread_mutex_unlock(&mutex_prot); } -void protectDBnolock(uintptr_t addr, uintptr_t size) +void protectDB(uintptr_t addr, size_t size) { - dynarec_log(LOG_DEBUG, "protectDB %p -> %p\n", (void*)addr, (void*)(addr+size-1)); - uintptr_t idx = (addr>>MEMPROT_SHIFT); - uintptr_t end = ((addr+size-1LL)>>MEMPROT_SHIFT); - int ret; - for (uintptr_t i=idx; i<=end; ++i) { - const uint32_t key = (i>>MEMPROT_SHIFT2)&0xffffffff; - khint_t k = kh_put(memprot, memprot, key, &ret); - if(ret) { - uint8_t *m = (uint8_t*)calloc(1, MEMPROT_SIZE); - kh_value(memprot, k) = m; - } - const uintptr_t ii = i&(MEMPROT_SIZE-1); - uint8_t prot = kh_value(memprot, k)[ii]; - if(!prot) - prot = PROT_READ | PROT_WRITE; // comes from malloc & co, so should not be able to execute - kh_value(memprot, k)[ii] = prot|PROT_DYNAREC; - if(!(prot&PROT_DYNAREC)) - mprotect((void*)(i<<MEMPROT_SHIFT), 1<<MEMPROT_SHIFT, prot&~(PROT_WRITE|PROT_CUSTOM)); - } + pthread_mutex_lock(&mutex_prot); + protectDBnolock(addr, size); + pthread_mutex_unlock(&mutex_prot); } void lockDB() diff --git a/src/dynarec/dynablock.c b/src/dynarec/dynablock.c index a592b28f..5df4979d 100755 --- a/src/dynarec/dynablock.c +++ b/src/dynarec/dynablock.c @@ -337,7 +337,7 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t void* old = (void*)arm64_lock_storeifref(&dynablocks->direct[addr-dynablocks->text], 0, block); if(old!=block && old) {// put it back in place, strange things are happening here! dynarec_log(LOG_INFO, "Warning, a wild block appeared at %p: %p\n", (void*)addr, old); - // doing nothing else, the block as not be writen + // doing nothing else, the block has not be writen } free(block); block = NULL; @@ -362,8 +362,11 @@ static dynablock_t* internalDBGetBlock(x64emu_t* emu, uintptr_t addr, uintptr_t protectDBnolock((uintptr_t)block->x64_addr, block->x64_size); // fill-in jumptable addJumpTableIfDefault64(block->x64_addr, block->block); - for(int i=0; i<block->sons_size; ++i) + for(int i=0; i<block->sons_size; ++i) { addJumpTableIfDefault64(block->sons[i]->x64_addr, block->sons[i]->block); + block->sons[i]->done = 1; + } + block->done = 1; unlockDB(); } diff --git a/src/dynarec/dynarec_arm64.c b/src/dynarec/dynarec_arm64.c index 63652c6b..c4f4dd6a 100755 --- a/src/dynarec/dynarec_arm64.c +++ b/src/dynarec/dynarec_arm64.c @@ -474,7 +474,7 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) { if(!son->x64_size) {printf_log(LOG_NONE, "Warning, son with null x64 size! (@%p / ARM=%p)", son->x64_addr, son->block);} son->father = block; son->size = sz + son->block - block->block; // update size count, for debugging - son->done = 1; + //son->done = 1; if(!son->parent) son->parent = block->parent; sons[sons_size] = son; @@ -489,6 +489,6 @@ void* FillBlock64(dynablock_t* block, uintptr_t addr) { } free(helper.sons_x64); free(helper.sons_arm); - block->done = 1; + //block->done = 1; return (void*)block; } |