about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2021-05-18 11:13:18 +0200
committerptitSeb <sebastien.chev@gmail.com>2021-05-18 11:13:18 +0200
commite35b25015bc457428cc27b5bfeec5c16a4dd9b22 (patch)
tree811ebe98fcd88b2edb21c94c65d8dd4309cbd103 /src
parent422844f84260b34d1f5da8aa99ff0d2d5247bcee (diff)
downloadbox64-e35b25015bc457428cc27b5bfeec5c16a4dd9b22.tar.gz
box64-e35b25015bc457428cc27b5bfeec5c16a4dd9b22.zip
Added signal mask handling in setjmp/longjmp functions
Diffstat (limited to 'src')
-rwxr-xr-xsrc/dynarec/dynarec.c8
-rwxr-xr-xsrc/libtools/signals.c6
-rwxr-xr-xsrc/wrapped/wrappedlibc.c32
-rwxr-xr-xsrc/wrapped/wrappedlibc_private.h4
4 files changed, 34 insertions, 16 deletions
diff --git a/src/dynarec/dynarec.c b/src/dynarec/dynarec.c
index a142f91d..94745bdd 100755
--- a/src/dynarec/dynarec.c
+++ b/src/dynarec/dynarec.c
@@ -81,7 +81,7 @@ void DynaCall(x64emu_t* emu, uintptr_t addr)
             ejb->emu = emu;
             ejb->jmpbuf_ok = 1;
             jmpbuf_reset = 1;
-            if(setjmp((struct __jmp_buf_tag*)ejb->jmpbuf)) {
+            if(sigsetjmp((struct __jmp_buf_tag*)ejb->jmpbuf, 1)) {
                 printf_log(LOG_DEBUG, "Setjmp DynaCall, fs=0x%x\n", ejb->emu->segs[_FS]);
                 addr = R_RIP;   // not sure if it should still be inside DynaCall!
             }
@@ -130,7 +130,7 @@ void DynaCall(x64emu_t* emu, uintptr_t addr)
                     ejb->emu = emu;
                     ejb->jmpbuf_ok = 1;
                     jmpbuf_reset = 1;
-                    if(setjmp((struct __jmp_buf_tag*)ejb->jmpbuf)) {
+                    if(sigsetjmp((struct __jmp_buf_tag*)ejb->jmpbuf, 1)) {
                         printf_log(LOG_DEBUG, "Setjmp inner DynaCall, fs=0x%x\n", ejb->emu->segs[_FS]);
                         addr = R_RIP;
                     }
@@ -171,7 +171,7 @@ int DynaRun(x64emu_t* emu)
 #ifdef DYNAREC
             jmpbuf_reset = 1;
 #endif
-            if(setjmp((struct __jmp_buf_tag*)ejb->jmpbuf))
+            if(sigsetjmp((struct __jmp_buf_tag*)ejb->jmpbuf, 1))
                 printf_log(LOG_DEBUG, "Setjmp DynaRun, fs=0x%x\n", ejb->emu->segs[_FS]);
         }
     }
@@ -208,7 +208,7 @@ int DynaRun(x64emu_t* emu)
                     ejb->emu = emu;
                     ejb->jmpbuf_ok = 1;
                     jmpbuf_reset = 1;
-                    if(setjmp((struct __jmp_buf_tag*)ejb->jmpbuf))
+                    if(sigsetjmp((struct __jmp_buf_tag*)ejb->jmpbuf, 1))
                         printf_log(LOG_DEBUG, "Setjmp inner DynaRun, fs=0x%x\n", ejb->emu->segs[_FS]);
                 }
             }
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index fd5f643e..a540f282 100755
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -643,13 +643,13 @@ void my_sigactionhandler_oldcode(int32_t sig, siginfo_t* info, void * ucntx, int
             seg = (sigcontext->uc_mcontext.gregs[X64_CSGSFS] >> 32)&0xffff;
             GO(FS);
             #undef GO
-            printf_log(LOG_DEBUG, "Context has been changed in Sigactionhanlder, doing longjmp to resume emu\n");
+            printf_log(LOG_DEBUG, "Context has been changed in Sigactionhanlder, doing siglongjmp to resume emu\n");
             if(old_code)
                 *old_code = -1;    // re-init the value to allow another segfault at the same place
             if(used_stack)  // release stack
                 new_ss->ss_flags = 0;
             relockMutex(Locks);
-            longjmp(ejb->jmpbuf, 1);
+            siglongjmp(ejb->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)":"");
     }
@@ -753,7 +753,7 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
                 ejb->emu->eflags.x64 = p->uc_mcontext.regs[26];
                 dynarec_log(LOG_DEBUG, "Auto-SMC detected, getting out of current Dynablock!\n");
                 relockMutex(Locks);
-                longjmp(ejb->jmpbuf, 2);
+                siglongjmp(ejb->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);
         }
diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c
index ced6a6cc..caf22c3c 100755
--- a/src/wrapped/wrappedlibc.c
+++ b/src/wrapped/wrappedlibc.c
@@ -534,9 +534,9 @@ EXPORT void my__longjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p,
 EXPORT void my_siglongjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p, int32_t __val) __attribute__((alias("my_longjmp")));
 EXPORT void my___longjmp_chk(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p, int32_t __val) __attribute__((alias("my_longjmp")));
 
-EXPORT int32_t my_setjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p);
-EXPORT int32_t my__setjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p) __attribute__((alias("my_setjmp")));
-EXPORT int32_t my___sigsetjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p) __attribute__((alias("my_setjmp")));
+//EXPORT int32_t my_setjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p);
+//EXPORT int32_t my__setjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p) __attribute__((alias("my_setjmp")));
+//EXPORT int32_t my___sigsetjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p) __attribute__((alias("my_setjmp")));
 
 EXPORT int my_printf(x64emu_t *emu, void* fmt, void* b) {
     myStackAlign(emu, (const char*)fmt, b, emu->scratch, R_EAX, 1);
@@ -1851,16 +1851,19 @@ void EXPORT my_longjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p,
     R_R14 = jpbuff->save_r14;
     R_R15 = jpbuff->save_r15;
     R_RSP = jpbuff->save_rsp;
-    // jmp to saved location, plus restore val to eax
-    R_EAX = __val;
+    // jmp to saved location, plus restore val to rax
+    R_RAX = __val;
     R_RIP = jpbuff->save_rip;
+    if(((__jmp_buf_tag_t*)p)->__mask_was_saved) {
+        sigprocmask(SIG_SETMASK, &((__jmp_buf_tag_t*)p)->__saved_mask, NULL);
+    }
     if(emu->quitonlongjmp) {
         emu->longjmp = 1;
         emu->quit = 1;
     }
 }
 
-EXPORT int32_t my_setjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p)
+EXPORT int32_t my___sigsetjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p, int savesigs)
 {
     jump_buff_x64_t *jpbuff = &((__jmp_buf_tag_t*)p)->__jmpbuf;
     // save the buffer
@@ -1872,10 +1875,25 @@ EXPORT int32_t my_setjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p
     jpbuff->save_r15 = R_R15;
     jpbuff->save_rsp = R_RSP+sizeof(uintptr_t); // include "return address"
     jpbuff->save_rip = *(uintptr_t*)(R_RSP);
-    // and that's it.. Nothing more for now
+    if(savesigs) {
+        if(sigprocmask(SIG_SETMASK, NULL, &((__jmp_buf_tag_t*)p)->__saved_mask))
+            ((__jmp_buf_tag_t*)p)->__mask_was_saved = 0;
+        else
+            ((__jmp_buf_tag_t*)p)->__mask_was_saved = 1;
+    } else
+        ((__jmp_buf_tag_t*)p)->__mask_was_saved = 0;
     return 0;
 }
 
+EXPORT int32_t my__setjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p)
+{
+    return  my___sigsetjmp(emu, p, 0);
+}
+EXPORT int32_t my_setjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p)
+{
+    return  my___sigsetjmp(emu, p, 1);
+}
+
 EXPORT void my___explicit_bzero_chk(x64emu_t* emu, void* dst, uint32_t len, uint32_t dstlen)
 {
     (void)emu; (void)dstlen;
diff --git a/src/wrapped/wrappedlibc_private.h b/src/wrapped/wrappedlibc_private.h
index fb26171c..2c8fc470 100755
--- a/src/wrapped/wrappedlibc_private.h
+++ b/src/wrapped/wrappedlibc_private.h
@@ -1689,7 +1689,7 @@ GO(siggetmask, iFv)
 //GO(sigisemptyset, 
 //GO(__sigismember, 
 GO(sigismember, iFpi)
-//GOW(siglongjmp, 
+GOM(siglongjmp, iFEpi)
 GOM(signal, pFEip)  //Weak
 //GO(signalfd, 
 GO(__signbit, iFd)
@@ -1704,7 +1704,7 @@ GOW(sigprocmask, iFipp)
 //GO(sigrelse, 
 //GOW(sigreturn, 
 GOM(sigset, pFEip)
-GOM(__sigsetjmp, iFEp)
+GOM(__sigsetjmp, iFEpi)
 //GOW(sigsetmask, 
 //GO(sigstack, 
 GO(__sigsuspend, iFp)