about summary refs log tree commit diff stats
path: root/src/libtools/signals.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libtools/signals.c')
-rw-r--r--src/libtools/signals.c199
1 files changed, 133 insertions, 66 deletions
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index 39dc190e..468a83f5 100644
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -1,3 +1,4 @@
+#define _GNU_SOURCE
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdint.h>
@@ -269,7 +270,7 @@ static void sigstack_key_alloc() {
 
 //1<<8 is mutex_dyndump
 #define is_dyndump_locked (1<<8)
-uint64_t RunFunctionHandler(int* exit, x64_ucontext_t* sigcontext, uintptr_t fnc, int nargs, ...)
+uint64_t RunFunctionHandler(int* exit, int dynarec, x64_ucontext_t* sigcontext, uintptr_t fnc, int nargs, ...)
 {
     if(fnc==0 || fnc==1) {
         va_list va;
@@ -295,8 +296,6 @@ uint64_t RunFunctionHandler(int* exit, x64_ucontext_t* sigcontext, uintptr_t fnc
     if(box64_dynarec_test)
         emu->test.test = 0;
     #endif
-
-    printf_log(LOG_DEBUG, "%04d|signal function handler %p called, RSP=%p\n", GetTID(), (void*)fnc, (void*)R_RSP);
     
     /*SetFS(emu, default_fs);*/
     for (int i=0; i<6; ++i)
@@ -320,14 +319,26 @@ uint64_t RunFunctionHandler(int* exit, x64_ucontext_t* sigcontext, uintptr_t fnc
     }
     va_end (va);
 
+    printf_log(LOG_DEBUG, "%04d|signal #%d function handler %p called, RSP=%p\n", GetTID(), R_EDI, (void*)fnc, (void*)R_RSP);
+
     int oldquitonlongjmp = emu->quitonlongjmp;
     emu->quitonlongjmp = 2;
+    int old_cs = R_CS;
+    R_CS = 0x33;
     
-    EmuCall(emu, fnc);  // avoid DynaCall for now
-    //DynaCall(emu, fnc);
-    if(nargs>6)
+    emu->eflags.x64 &= ~(1<<F_TF); // this one needs to cleared
+
+    if(dynarec)
+        DynaCall(emu, fnc);
+    else
+        EmuCall(emu, fnc);
+
+    if(nargs>6 && !emu->longjmp)
         R_RSP+=((nargs-6)*sizeof(void*));
 
+    if(!emu->longjmp && R_CS==0x33)
+        R_CS = old_cs;
+
     emu->quitonlongjmp = oldquitonlongjmp;
 
     #ifdef DYNAREC
@@ -449,6 +460,25 @@ uintptr_t getX64Address(dynablock_t* db, uintptr_t arm_addr)
     } while(db->instsize[i].x64 || db->instsize[i].nat);
     return x64addr;
 }
+x64emu_t* getEmuSignal(x64emu_t* emu, ucontext_t* p, dynablock_t* db)
+{
+#if defined(ARM64)
+        if(db && p->uc_mcontext.regs[0]>0x10000) {
+            emu = (x64emu_t*)p->uc_mcontext.regs[0];
+        }
+#elif defined(LA464)
+        if(db && p->uc_mcontext.__gregs[4]>0x10000) {
+            emu = (x64emu_t*)p->uc_mcontext.__gregs[4];
+        }
+#elif defined(RV64)
+        if(db && p->uc_mcontext.__gregs[10]>0x10000) {
+            emu = (x64emu_t*)p->uc_mcontext.__gregs[10];
+        }
+#else
+#error Unsupported Architecture
+#endif //arch
+    return emu;
+}
 #endif
 
 void copyUCTXreg2Emu(x64emu_t* emu, ucontext_t* p, uintptr_t ip) {
@@ -713,16 +743,21 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
             else
                 sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 14; // PAGE_FAULT
         } else {
-            sigcontext->uc_mcontext.gregs[X64_TRAPNO] = (info->si_code == SEGV_ACCERR)?13:14;
+            sigcontext->uc_mcontext.gregs[X64_TRAPNO] = (info->si_code == SEGV_ACCERR)?14:13;
             //X64_ERR seems to be INT:8 CODE:8. So for write access segfault it's 0x0002 For a read it's 0x0004 (and 8 for exec). For an int 2d it could be 0x2D01 for example
             sigcontext->uc_mcontext.gregs[X64_ERR] = 0x0004;    // read error? there is no execute control in box64 anyway
         }
         if(info->si_code == SEGV_ACCERR && old_code)
             *old_code = -1;
-    } else if(sig==SIGFPE)
-        sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 19;
-    else if(sig==SIGILL)
+    } else if(sig==SIGFPE) {
+        if (info->si_code == FPE_INTOVF)
+            sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 4;
+        else
+            sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 19;
+    } else if(sig==SIGILL)
         sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 6;
+    else if(sig==SIGTRAP)
+        sigcontext->uc_mcontext.gregs[X64_TRAPNO] = info->si_code;
     //TODO: SIGABRT generate what?
     // call the signal handler
     x64_ucontext_t sigcontext_copy = *sigcontext;
@@ -744,10 +779,15 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
 
     int exits = 0;
     int ret;
-    if (simple)
-        ret = RunFunctionHandler(&exits, sigcontext, my_context->signals[sig], 1, sig);
-    else
-        ret = RunFunctionHandler(&exits, sigcontext, my_context->signals[sig], 3, sig, info2, sigcontext);
+    int dynarec = 0;
+    #ifdef DYNAREC
+    if(sig!=SIGSEGV && !(Locks&is_dyndump_locked))
+        dynarec = 1;
+    #endif
+    /*if (simple)
+        ret = RunFunctionHandler(&exits, dynarec, sigcontext, my_context->signals[sig], 1, sig);
+    else*/
+        ret = RunFunctionHandler(&exits, dynarec, sigcontext, my_context->signals[sig], 3, sig, info2, sigcontext);
     // restore old value from emu
     if(used_stack)  // release stack
         new_ss->ss_flags = 0;
@@ -763,9 +803,8 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
     #undef GO
 
     if(memcmp(sigcontext, &sigcontext_copy, sizeof(x64_ucontext_t))) {
-        emu_jmpbuf_t* ejb = GetJmpBuf();
-        if(ejb->jmpbuf_ok) {
-            #define GO(R)   ejb->emu->regs[_##R].q[0]=sigcontext->uc_mcontext.gregs[X64_R##R]
+        if(emu->jmpbuf) {
+            #define GO(R)   emu->regs[_##R].q[0]=sigcontext->uc_mcontext.gregs[X64_R##R]
             GO(AX);
             GO(CX);
             GO(DX);
@@ -775,7 +814,7 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
             GO(SP);
             GO(BX);
             #undef GO
-            #define GO(R)   ejb->emu->regs[_##R].q[0]=sigcontext->uc_mcontext.gregs[X64_##R]
+            #define GO(R)   emu->regs[_##R].q[0]=sigcontext->uc_mcontext.gregs[X64_##R]
             GO(R8);
             GO(R9);
             GO(R10);
@@ -785,14 +824,14 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
             GO(R14);
             GO(R15);
             #undef GO
-            ejb->emu->ip.q[0]=sigcontext->uc_mcontext.gregs[X64_RIP];
+            emu->ip.q[0]=sigcontext->uc_mcontext.gregs[X64_RIP];
             sigcontext->uc_mcontext.gregs[X64_RIP] = R_RIP;
             // flags
-            ejb->emu->eflags.x64=sigcontext->uc_mcontext.gregs[X64_EFL];
+            emu->eflags.x64=sigcontext->uc_mcontext.gregs[X64_EFL];
             // get segments
             uint16_t seg;
             seg = (sigcontext->uc_mcontext.gregs[X64_CSGSFS] >> 0)&0xffff;
-            #define GO(S) if(ejb->emu->segs[_##S]!=seg)  {ejb->emu->segs[_##S]=seg; ejb->emu->segs_serial[_##S] = 0;}
+            #define GO(S) if(emu->segs[_##S]!=seg)  {emu->segs[_##S]=seg; emu->segs_serial[_##S] = 0;}
             GO(CS);
             seg = (sigcontext->uc_mcontext.gregs[X64_CSGSFS] >> 16)&0xffff;
             GO(GS);
@@ -809,7 +848,7 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
             if(Locks & is_dyndump_locked)
                 CancelBlock64(1);
             #endif
-            siglongjmp(ejb->jmpbuf, 1);
+            siglongjmp(emu->jmpbuf, 1);
         }
         printf_log(LOG_INFO, "Warning, context has been changed in Sigactionhanlder%s\n", (sigcontext->uc_mcontext.gregs[X64_RIP]!=sigcontext_copy.uc_mcontext.gregs[X64_RIP])?" (EIP changed)":"");
     }
@@ -854,13 +893,23 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void
         exit(ret);
     }
     if(restorer)
-        RunFunctionHandler(&exits, NULL, restorer, 0);
+        RunFunctionHandler(&exits, 0, NULL, restorer, 0);
     relockMutex(Locks);
 }
 
 extern void* current_helper;
-#ifdef DYNAREC
+#define USE_SIGNAL_MUTEX
+#ifdef USE_SIGNAL_MUTEX
+#ifdef USE_CUSTOM_MUTEX
 static uint32_t mutex_dynarec_prot = 0;
+#else
+static pthread_mutex_t mutex_dynarec_prot = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
+#endif
+#define lock_signal()     mutex_lock(&mutex_dynarec_prot)
+#define unlock_signal()   mutex_unlock(&mutex_dynarec_prot)
+#else   // USE_SIGNAL_MUTEX
+#define lock_signal()     
+#define unlock_signal()   
 #endif
 
 extern int box64_quit;
@@ -876,6 +925,7 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
     ucontext_t *p = (ucontext_t *)ucntx;
     void* addr = (void*)info->si_addr;  // address that triggered the issue
     void* rsp = NULL;
+    x64emu_t* emu = thread_get_emu();
 #ifdef __aarch64__
     void * pc = (void*)p->uc_mcontext.pc;
     struct fpsimd_context *fpsimd = NULL;
@@ -915,14 +965,14 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
     #endif
 #ifdef DYNAREC
     if((Locks & is_dyndump_locked) && (sig==SIGSEGV) && current_helper) {
-        relockMutex(Locks);
         CancelBlock64(0);
         cancelFillBlock();  // Segfault inside a Fillblock, cancel it's creation...
+        relockMutex(Locks);
     }
     dynablock_t* db = NULL;
     int db_searched = 0;
     if ((sig==SIGSEGV) && (addr) && (info->si_code == SEGV_ACCERR) && (prot&PROT_DYNAREC)) {
-        mutex_lock(&mutex_dynarec_prot);
+        lock_signal();
         // check if SMC inside block
         db = FindDynablockFromNativeAddress(pc);
         db_searched = 1;
@@ -939,31 +989,33 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
         }
         // 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
-        if(db && ((addr>=db->x64_addr && addr<(db->x64_addr+db->x64_size)) || getNeedTest((uintptr_t)db->x64_addr))) {
+        int db_need_test = (db && !box64_dynarec_fastpage)?getNeedTest((uintptr_t)db->x64_addr):0;
+        if(db && ((addr>=db->x64_addr && addr<(db->x64_addr+db->x64_size)) || db_need_test)) {
+            emu = getEmuSignal(emu, p, db);
             // dynablock got auto-dirty! need to get out of it!!!
-            emu_jmpbuf_t* ejb = GetJmpBuf();
-            if(ejb->jmpbuf_ok) {
-                copyUCTXreg2Emu(ejb->emu, p, getX64Address(db, (uintptr_t)pc));
+            if(emu->jmpbuf) {
+                copyUCTXreg2Emu(emu, p, getX64Address(db, (uintptr_t)pc));
 #ifdef ARM64
-                if(fpsimd) {
-                    ejb->emu->xmm[0].u128 = fpsimd->vregs[0];
-                    ejb->emu->xmm[1].u128 = fpsimd->vregs[1];
-                    ejb->emu->xmm[2].u128 = fpsimd->vregs[2];
-                    ejb->emu->xmm[3].u128 = fpsimd->vregs[3];
-                }
+                //TODO: Need proper SIMD/x87 register traking!
+                /*if(fpsimd) {
+                    emu->xmm[0].u128 = fpsimd->vregs[0];
+                    emu->xmm[1].u128 = fpsimd->vregs[1];
+                    emu->xmm[2].u128 = fpsimd->vregs[2];
+                    emu->xmm[3].u128 = fpsimd->vregs[3];
+                }*/
 #elif defined(LA464)
                 /*if(fpsimd) {
-                    ejb->emu->xmm[0].u128 = fpsimd->vregs[0];
-                    ejb->emu->xmm[1].u128 = fpsimd->vregs[1];
-                    ejb->emu->xmm[2].u128 = fpsimd->vregs[2];
-                    ejb->emu->xmm[3].u128 = fpsimd->vregs[3];
+                    emu->xmm[0].u128 = fpsimd->vregs[0];
+                    emu->xmm[1].u128 = fpsimd->vregs[1];
+                    emu->xmm[2].u128 = fpsimd->vregs[2];
+                    emu->xmm[3].u128 = fpsimd->vregs[3];
                 }*/
 #elif defined(RV64)
                 /*if(fpsimd) {
-                    ejb->emu->xmm[0].u128 = fpsimd->vregs[0];
-                    ejb->emu->xmm[1].u128 = fpsimd->vregs[1];
-                    ejb->emu->xmm[2].u128 = fpsimd->vregs[2];
-                    ejb->emu->xmm[3].u128 = fpsimd->vregs[3];
+                    emu->xmm[0].u128 = fpsimd->vregs[0];
+                    emu->xmm[1].u128 = fpsimd->vregs[1];
+                    emu->xmm[2].u128 = fpsimd->vregs[2];
+                    emu->xmm[3].u128 = fpsimd->vregs[3];
                 }*/
 #else
 #error  Unsupported architecture
@@ -974,25 +1026,24 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
                     dynarec_log(LOG_INFO, "Dynablock unprotected, getting out!\n");
                 }
                 //relockMutex(Locks);
-                mutex_unlock(&mutex_dynarec_prot);
-                #ifdef DYNAREC
+                unlock_signal();
                 if(Locks & is_dyndump_locked)
                     CancelBlock64(1);
-                #endif
-                siglongjmp(ejb->jmpbuf, 2);
+                emu->test.clean = 0;
+                siglongjmp(emu->jmpbuf, 2);
             }
             dynarec_log(LOG_INFO, "Warning, Auto-SMC (%p for db %p/%p) detected, but jmpbuffer not ready!\n", (void*)addr, db, (void*)db->x64_addr);
         }
         // done
-        if((prot&PROT_WRITE) || (prot&PROT_DYNAREC)) {
-            mutex_unlock(&mutex_dynarec_prot);
+        if((prot&PROT_WRITE)/*|| (prot&PROT_DYNAREC)*/) {
+            unlock_signal();
             // if there is no write permission, don't return and continue to program signal handling
             relockMutex(Locks);
             return;
         }
-        mutex_unlock(&mutex_dynarec_prot);
+        unlock_signal();
     } else if ((sig==SIGSEGV) && (addr) && (info->si_code == SEGV_ACCERR) && ((prot&(PROT_READ|PROT_WRITE))==(PROT_READ|PROT_WRITE))) {
-        mutex_lock(&mutex_dynarec_prot);
+        lock_signal();
         db = FindDynablockFromNativeAddress(pc);
         db_searched = 1;
         if(db && db->x64_addr>= addr && (db->x64_addr+db->x64_size)<addr) {
@@ -1011,7 +1062,7 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
                 glitch_addr = addr;
                 glitch_prot = prot;
                 relockMutex(Locks);
-                mutex_unlock(&mutex_dynarec_prot);
+                unlock_signal();
                 return; // try again
             }
 dynarec_log(/*LOG_DEBUG*/LOG_INFO, "Repeated SIGSEGV with Access error on %p for %p, db=%p, prot=0x%x\n", pc, addr, db, prot);
@@ -1033,14 +1084,14 @@ dynarec_log(/*LOG_DEBUG*/LOG_INFO, "Repeated SIGSEGV with Access error on %p for
                 refreshProtection((uintptr_t)addr);
                 relockMutex(Locks);
                 sched_yield();  // give time to the other process
-                mutex_unlock(&mutex_dynarec_prot);
+                unlock_signal();
                 return; // try again
             }
             glitch2_pc = NULL;
             glitch2_addr = NULL;
             glitch2_prot = 0;
         }
-        mutex_unlock(&mutex_dynarec_prot);
+        unlock_signal();
     } else if ((sig==SIGSEGV) && (addr) && (info->si_code == SEGV_ACCERR) && (prot&PROT_DYNAREC_R)) {
         // unprotect and continue to signal handler, because Write is not there on purpose
         unprotectDB((uintptr_t)addr, 1, 1);    // unprotect 1 byte... But then, the whole page will be unprotected
@@ -1081,7 +1132,6 @@ exit(-1);
         uintptr_t x64pc = (uintptr_t)-1;
         const char* x64name = NULL;
         const char* elfname = NULL;
-        x64emu_t* emu = thread_get_emu();
         // Adjust RIP for special case of NULL function run
         if(sig==SIGSEGV && R_RIP==0x1 && (uintptr_t)info->si_addr==0x0)
             R_RIP = 0x0;
@@ -1089,9 +1139,6 @@ exit(-1);
         rsp = (void*)R_RSP;
 #if defined(DYNAREC)
 #if defined(ARM64)
-        if(db && p->uc_mcontext.regs[0]>0x10000) {
-            emu = (x64emu_t*)p->uc_mcontext.regs[0];
-        }
         if(db) {
             x64pc = getX64Address(db, (uintptr_t)pc);
             rsp = (void*)p->uc_mcontext.regs[10+_SP];
@@ -1218,6 +1265,7 @@ exit(-1);
         }
         if(log_minimum<=box64_log) {
             static const char* reg_name[] = {"RAX", "RCX", "RDX", "RBX", "RSP", "RBP", "RSI", "RDI", " R8", " R9","R10","R11", "R12","R13","R14","R15"};
+            static const char* seg_name[] = {"ES", "CS", "SS", "DS", "GS", "FS"};
             int shown_regs = 0;
 #ifdef DYNAREC
             uint32_t hash = 0;
@@ -1239,8 +1287,11 @@ exit(-1);
                     if(!(i%4)) printf_log(log_minimum, "\n");
                     printf_log(log_minimum, "%s:0x%016llx ", reg_name[i], p->uc_mcontext.regs[10+i]);
                 }
+                printf_log(log_minimum, "\n");
+                for (int i=0; i<6; ++i)
+                    printf_log(log_minimum, "%s:0x%04x ", seg_name[i], emu->segs[i]);
             }
-            if(rsp!=addr)
+            if(rsp!=addr && getProtection((uintptr_t)rsp-4*8) && getProtection((uintptr_t)rsp+4*8))
                 for (int i=-4; i<4; ++i) {
                     printf_log(log_minimum, "%sRSP%c0x%02x:0x%016lx", (i%4)?" ":"\n", i<0?'-':'+', abs(i)*8, *(uintptr_t*)(rsp+i*8));
                 }
@@ -1251,8 +1302,11 @@ exit(-1);
                     if(!(i%4)) printf_log(log_minimum, "\n");
                     printf_log(log_minimum, "%s:0x%016llx ", reg_name[i], p->uc_mcontext.__gregs[16+i]);
                 }
+                printf_log(log_minimum, "\n");
+                for (int i=0; i<6; ++i)
+                    printf_log(log_minimum, "%s:0x%04x ", seg_name[i], emu->segs[i]);
             }
-            if(rsp!=addr)
+            if(rsp!=addr && getProtection((uintptr_t)rsp-4*8) && getProtection((uintptr_t)rsp+4*8))
                 for (int i=-4; i<4; ++i) {
                     printf_log(log_minimum, "%sRSP%c0x%02x:0x%016lx", (i%4)?" ":"\n", i<0?'-':'+', abs(i)*8, *(uintptr_t*)(rsp+i*8));
                 }
@@ -1262,11 +1316,15 @@ exit(-1);
 #else
             printf_log(log_minimum, "%04d|%s @%p (%s) (x64pc=%p/%s:\"%s\", rsp=%p), for accessing %p (code=%d)", GetTID(), signame, pc, name, (void*)x64pc, elfname?elfname:"???", x64name?x64name:"???", rsp, addr, info->si_code);
 #endif
-            if(!shown_regs)
+            if(!shown_regs) {
                 for (int i=0; i<16; ++i) {
                     if(!(i%4)) printf_log(log_minimum, "\n");
                     printf_log(log_minimum, "%s:0x%016llx ", reg_name[i], emu->regs[i].q[0]);
                 }
+                printf_log(log_minimum, "\n");
+                for (int i=0; i<6; ++i)
+                    printf_log(log_minimum, "%s:0x%04x ", seg_name[i], emu->segs[i]);
+            }
             if(sig==SIGILL)
                 printf_log(log_minimum, " opcode=%02X %02X %02X %02X %02X %02X %02X %02X (%02X %02X %02X %02X %02X)\n", ((uint8_t*)pc)[0], ((uint8_t*)pc)[1], ((uint8_t*)pc)[2], ((uint8_t*)pc)[3], ((uint8_t*)pc)[4], ((uint8_t*)pc)[5], ((uint8_t*)pc)[6], ((uint8_t*)pc)[7], ((uint8_t*)x64pc)[0], ((uint8_t*)x64pc)[1], ((uint8_t*)x64pc)[2], ((uint8_t*)x64pc)[3], ((uint8_t*)x64pc)[4]);
             else if(sig==SIGBUS)
@@ -1360,6 +1418,7 @@ EXPORT sighandler_t my_sysv_signal(x64emu_t* emu, int signum, sighandler_t handl
 
 int EXPORT my_sigaction(x64emu_t* emu, int signum, const x64_sigaction_t *act, x64_sigaction_t *oldact)
 {
+    printf_log(LOG_DEBUG, "Sigaction(signum=%d, act=%p(f=%p, flags=0x%x), old=%p)\n", signum, act, act?act->_u._sa_handler:NULL, act?act->sa_flags:0, oldact);
     if(signum<0 || signum>=MAX_SIGNAL) {
         errno = EINVAL;
         return -1;
@@ -1372,6 +1431,7 @@ int EXPORT my_sigaction(x64emu_t* emu, int signum, const x64_sigaction_t *act, x
         return 0;
     struct sigaction newact = {0};
     struct sigaction old = {0};
+    uintptr_t old_handler = my_context->signals[signum];
     if(act) {
         newact.sa_mask = act->sa_mask;
         newact.sa_flags = act->sa_flags&~0x04000000;  // No sa_restorer...
@@ -1404,6 +1464,8 @@ int EXPORT my_sigaction(x64emu_t* emu, int signum, const x64_sigaction_t *act, x
             oldact->_u._sa_sigaction = old.sa_sigaction; //TODO should wrap...
         else
             oldact->_u._sa_handler = old.sa_handler;  //TODO should wrap...
+        if((uintptr_t)oldact->_u._sa_sigaction == (uintptr_t)my_sigactionhandler && old_handler)
+            oldact->_u._sa_sigaction = (void*)old_handler;
         oldact->sa_restorer = NULL; // no handling for now...
     }
     return ret;
@@ -1471,7 +1533,7 @@ int EXPORT my_syscall_rt_sigaction(x64emu_t* emu, int signum, const x64_sigactio
         struct sigaction newact = {0};
         struct sigaction old = {0};
         if(act) {
-            printf_log(LOG_DEBUG, " New action flags=0x%x mask=0x%lx\n", act->sa_flags, *(uint64_t*)&act->sa_mask);
+            printf_log(LOG_DEBUG, " New action for signal #%d flags=0x%x mask=0x%lx\n", signum, act->sa_flags, *(uint64_t*)&act->sa_mask);
             newact.sa_mask = act->sa_mask;
             newact.sa_flags = act->sa_flags&~0x04000000;  // No sa_restorer...
             if(act->sa_flags&0x04) {
@@ -1648,7 +1710,7 @@ EXPORT int my_makecontext(x64emu_t* emu, void* ucp, void* fnc, int32_t argc, int
     }
     // push the return value
     --rsp;
-    *rsp = (uintptr_t)GetExit();
+    *rsp = my_context->exit_bridge;
     u->uc_mcontext.gregs[X64_RSP] = (uintptr_t)rsp;
     
     return 0;
@@ -1663,10 +1725,15 @@ EXPORT int my_swapcontext(x64emu_t* emu, void* ucp1, void* ucp2)
     my_setcontext(emu, ucp2);
     return 0;
 }
-#ifdef DYNAREC
+#ifdef USE_SIGNAL_MUTEX
 static void atfork_child_dynarec_prot(void)
 {
+    #ifdef USE_CUSTOM_MUTEX
     native_lock_store(&mutex_dynarec_prot, 0);
+    #else
+    pthread_mutex_t tmp = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP; 
+    memcpy(&mutex_dynarec_prot, &tmp, sizeof(mutex_dynarec_prot));
+    #endif
 }
 #endif
 void init_signal_helper(box64context_t* context)
@@ -1690,7 +1757,7 @@ void init_signal_helper(box64context_t* context)
     sigaction(SIGABRT, &action, NULL);
 
     pthread_once(&sigstack_key_once, sigstack_key_alloc);
-#ifdef DYNAREC
+#ifdef USE_SIGNAL_MUTEX
     atfork_child_dynarec_prot();
     pthread_atfork(NULL, NULL, atfork_child_dynarec_prot);
 #endif