about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-06-04 10:56:16 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-06-04 10:56:16 +0200
commit1c1e39ef644cda816e26f04ea63eb71919bb5942 (patch)
tree4942dfb4cd80756e5a648df2967312f13c6af140 /src
parentf5655d85a3f6c7948e78d3594839f00986da464d (diff)
downloadbox64-1c1e39ef644cda816e26f04ea63eb71919bb5942.tar.gz
box64-1c1e39ef644cda816e26f04ea63eb71919bb5942.zip
[DYNAREC] Improved SMC handling
Diffstat (limited to 'src')
-rwxr-xr-xsrc/libtools/signals.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index a540f282..adc28413 100755
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -722,14 +722,12 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
     int db_searched = 0;
     if ((sig==SIGSEGV) && (addr) && (info->si_code == SEGV_ACCERR) && (prot&PROT_DYNAREC)) {
         // access error, unprotect the block (and mark them dirty)
-        if(prot&PROT_DYNAREC)   // on heavy multi-thread program, the protection can already be gone...
-            unprotectDB((uintptr_t)addr, 1);    // unprotect 1 byte... But then, the whole page will be unprotected
+        unprotectDB((uintptr_t)addr, 1);    // unprotect 1 byte... But then, the whole page will be unprotected
         // check if SMC inside block
-        if(!db_searched) {
-            db = FindDynablockFromNativeAddress(pc);
-            db_searched = 1;
-        }
-        if(db && (addr>=db->x64_addr && addr<(db->x64_addr+db->x64_size))) {
+        db = FindDynablockFromNativeAddress(pc);
+        db_searched = 1;
+        dynarec_log(LOG_DEBUG, "SIGSEGV with Access error on %p for %p , db=%p(%p)\n", pc, addr, db, db?((void*)db->x64_addr):NULL);
+        if(db && ((addr>=db->x64_addr && addr<(db->x64_addr+db->x64_size)) || db->need_test)) {
             // dynablock got auto-dirty! need to get out of it!!!
             emu_jmpbuf_t* ejb = GetJmpBuf();
             if(ejb->jmpbuf_ok) {
@@ -751,7 +749,11 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
                 ejb->emu->regs[_R15].q[0] = p->uc_mcontext.regs[25];
                 ejb->emu->ip.q[0] = getX64Address(db, (uintptr_t)pc);
                 ejb->emu->eflags.x64 = p->uc_mcontext.regs[26];
-                dynarec_log(LOG_DEBUG, "Auto-SMC detected, getting out of current Dynablock!\n");
+                if(addr>=db->x64_addr && addr<(db->x64_addr+db->x64_size)) {
+                    dynarec_log(LOG_INFO, "Auto-SMC detected, getting out of current Dynablock!\n");
+                } else {
+                    dynarec_log(LOG_INFO, "Dynablock unprotected, getting out!\n");
+                }
                 relockMutex(Locks);
                 siglongjmp(ejb->jmpbuf, 2);
             }