mirror of
https://github.com/ptitSeb/box86.git
synced 2024-11-23 06:39:55 +00:00
[DYNAREC] Re-introduce a simple HotPage handling, to speedup heavily obfuscated program loading (backported from box64)
This commit is contained in:
parent
dd5bba2aac
commit
148722dac4
@ -881,6 +881,26 @@ int isprotectedDB(uintptr_t addr, size_t size)
|
||||
return 1;
|
||||
}
|
||||
|
||||
uintptr_t hotpage = 0;
|
||||
int hotpage_cnt = 0;
|
||||
#define HOTPAGE_MARK 64
|
||||
void SetHotPage(uintptr_t addr)
|
||||
{
|
||||
hotpage = addr&~(box86_pagesize-1);
|
||||
hotpage_cnt = HOTPAGE_MARK;
|
||||
}
|
||||
int isInHotPage(uintptr_t addr)
|
||||
{
|
||||
if(!hotpage_cnt)
|
||||
return 0;
|
||||
--hotpage_cnt;
|
||||
return (addr>=hotpage) && (addr<hotpage+box86_pagesize);
|
||||
}
|
||||
int checkInHotPage(uintptr_t addr)
|
||||
{
|
||||
return hotpage_cnt && (addr>=hotpage) && (addr<hotpage+box86_pagesize);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void updateProtection(uintptr_t addr, uintptr_t size, uint32_t prot)
|
||||
|
@ -262,6 +262,8 @@ static dynablock_t* internalDBGetBlock(x86emu_t* emu, uintptr_t addr, uintptr_t
|
||||
|
||||
dynablock_t* DBGetBlock(x86emu_t* emu, uintptr_t addr, int create)
|
||||
{
|
||||
if(isInHotPage(addr))
|
||||
return NULL;
|
||||
dynablock_t *db = internalDBGetBlock(emu, addr, addr, create, 1);
|
||||
if(db && db->done && db->block && getNeedTest(addr)) {
|
||||
if(db->always_test)
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "dynablock.h"
|
||||
#include "dynablock_private.h"
|
||||
#include "bridge.h"
|
||||
#include "custommem.h"
|
||||
void x86test_check(x86emu_t* ref, uintptr_t ip);
|
||||
#endif
|
||||
|
||||
@ -59,9 +60,13 @@ void* LinkNext(x86emu_t* emu, uintptr_t addr, void* x2)
|
||||
// no block, let link table as is...
|
||||
#ifdef HAVE_TRACE
|
||||
if(LOG_INFO<=box86_dynarec_log) {
|
||||
dynablock_t* db = FindDynablockFromNativeAddress(x2);
|
||||
elfheader_t* h = FindElfAddress(my_context, (uintptr_t)x2);
|
||||
dynarec_log(LOG_INFO, "Warning, jumping to a no-block address %p from %p (db=%p, x64addr=%p(elf=%s))\n", (void*)addr, x2, db, db?(void*)getX86Address(db, (uintptr_t)x2-4):NULL, h?ElfName(h):"(none)");
|
||||
if(checkInHotPage(addr)) {
|
||||
dynarec_log(LOG_INFO, "Not trying to run a block from a Hotpage at %p\n", (void*)addr);
|
||||
} else {
|
||||
dynablock_t* db = FindDynablockFromNativeAddress(x2-4);
|
||||
elfheader_t* h = FindElfAddress(my_context, (uintptr_t)x2-4);
|
||||
dynarec_log(LOG_INFO, "Warning, jumping to a no-block address %p from %p (db=%p, x86addr=%p(elf=%s))\n", (void*)addr, x2-4, db, db?(void*)getX86Address(db, (uintptr_t)x2-4):NULL, h?ElfName(h):"(none)");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//tableupdate(arm_epilog, addr, table);
|
||||
|
@ -76,6 +76,10 @@ void fini_custommem_helper(box86context_t* ctx);
|
||||
// ---- StrongMemoryModel
|
||||
void addLockAddress(uintptr_t addr); // add an address to the list of "LOCK"able
|
||||
int isLockAddress(uintptr_t addr); // return 1 is the address is used as a LOCK, 0 else
|
||||
|
||||
void SetHotPage(uintptr_t addr);
|
||||
int isInHotPage(uintptr_t addr);
|
||||
int checkInHotPage(uintptr_t addr);
|
||||
#endif
|
||||
|
||||
#endif //__CUSTOM_MEM__H_
|
@ -850,11 +850,22 @@ void my_box86signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
|
||||
int db_searched = 0;
|
||||
if ((sig==SIGSEGV) && (addr) && (info->si_code == SEGV_ACCERR) && (prot&PROT_CUSTOM)) {
|
||||
lock_signal();
|
||||
// access error, unprotect the block (and mark them dirty)
|
||||
unprotectDB((uintptr_t)addr, 1, 1); // unprotect 1 byte... But then, the whole page will be unprotected
|
||||
// check if SMC inside block
|
||||
db = FindDynablockFromNativeAddress(pc);
|
||||
db_searched = 1;
|
||||
static uintptr_t repeated_page = 0;
|
||||
dynarec_log(LOG_DEBUG, "SIGSEGV with Access error on %p for %p , db=%p(%p), prot=0x%hhx (old page=%p)\n", pc, addr, db, db?((void*)db->x86_addr):NULL, prot, (void*)repeated_page);
|
||||
static int repeated_count = 0;
|
||||
if(repeated_page == ((uintptr_t)addr&~(box86_pagesize-1))) {
|
||||
++repeated_count; // Access eoor multiple time on same page, disable dynarec on this page a few time...
|
||||
dynarec_log(LOG_DEBUG, "Detecting a Hotpage at %p (%d)\n", (void*)repeated_page, repeated_count);
|
||||
SetHotPage(repeated_page);
|
||||
} else {
|
||||
repeated_page = (uintptr_t)addr&~(box86_pagesize-1);
|
||||
repeated_count = 0;
|
||||
}
|
||||
// access error, unprotect the block (and mark them dirty)
|
||||
unprotectDB((uintptr_t)addr, 1, 1); // unprotect 1 byte... But then, the whole page will be unprotected
|
||||
int db_need_test = (db && !box86_dynarec_fastpage)?getNeedTest((uintptr_t)db->x86_addr):0;
|
||||
dynarec_log(LOG_INFO/*LOG_DEBUG*/, "SIGSEGV with Access error on %p for %p , db=%p(%p)\n", pc, addr, db, db?((void*)db->x86_addr):NULL);
|
||||
if(db && ((addr>=db->x86_addr && addr<(db->x86_addr+db->x86_size)) || db_need_test)) {
|
||||
|
Loading…
Reference in New Issue
Block a user