about summary refs log tree commit diff stats
path: root/src/libtools
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2023-07-08 17:21:49 +0200
committerptitSeb <sebastien.chev@gmail.com>2023-07-08 17:21:49 +0200
commitab2d68ef45c729134d92e9dad0d78c1fa035a489 (patch)
treebd8d00b0d7367eb2523f0abde9ff7b00ba547740 /src/libtools
parentb7a2d59a61809739f86c2840294adb000a40f38f (diff)
downloadbox64-ab2d68ef45c729134d92e9dad0d78c1fa035a489.tar.gz
box64-ab2d68ef45c729134d92e9dad0d78c1fa035a489.zip
Simplyfied internal jmpbuf handling
Diffstat (limited to 'src/libtools')
-rwxr-xr-xsrc/libtools/signals.c76
-rwxr-xr-xsrc/libtools/threads.c29
2 files changed, 47 insertions, 58 deletions
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index de014cfe..b3a18d8d 100755
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -527,6 +527,28 @@ void copyUCTXreg2Emu(x64emu_t* emu, ucontext_t* p, uintptr_t ip) {
 #endif
 }
 
+x64emu_t* getEmuSignal(x64emu_t* emu, ucontext_t* p, dynablock_t* db)
+{
+#if defined(DYNAREC)
+#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
+#endif //DYNAREC
+    return emu;
+}
+
 void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void * ucntx, int* old_code, void* cur_db)
 {
     int Locks = unlockMutex();
@@ -784,9 +806,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);
@@ -796,7 +817,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);
@@ -806,14 +827,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);
@@ -830,7 +851,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)":"");
     }
@@ -907,6 +928,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;
@@ -972,31 +994,31 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
         unprotectDB((uintptr_t)addr, 1, 1);    // unprotect 1 byte... But then, the whole page will be unprotected
         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
                 //TODO: Need proper SIMD/x87 register traking!
                 /*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(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
@@ -1010,8 +1032,8 @@ void my_box64signalhandler(int32_t sig, siginfo_t* info, void * ucntx)
                 unlock_signal();
                 if(Locks & is_dyndump_locked)
                     CancelBlock64(1);
-                ejb->emu->test.clean = 0;
-                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);
         }
@@ -1113,7 +1135,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;
@@ -1121,9 +1142,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];
diff --git a/src/libtools/threads.c b/src/libtools/threads.c
index c2c6dfb1..d70851f6 100755
--- a/src/libtools/threads.c
+++ b/src/libtools/threads.c
@@ -1066,28 +1066,6 @@ EXPORT int my_pthread_barrier_init(x64emu_t* emu, pthread_barrier_t* bar, my_bar
 
 #endif
 
-static void emujmpbuf_destroy(void* p)
-{
-	emu_jmpbuf_t *ej = (emu_jmpbuf_t*)p;
-	if(ej) {
-		box_free(ej->jmpbuf);
-		box_free(ej);
-	}
-}
-
-static pthread_key_t jmpbuf_key;
-
-emu_jmpbuf_t* GetJmpBuf()
-{
-	emu_jmpbuf_t *ejb = (emu_jmpbuf_t*)pthread_getspecific(jmpbuf_key);
-	if(!ejb) {
-		ejb = (emu_jmpbuf_t*)box_calloc(1, sizeof(emu_jmpbuf_t));
-		ejb->jmpbuf = box_calloc(1, sizeof(struct __jmp_buf_tag));
-		pthread_setspecific(jmpbuf_key, ejb);
-	}
-	return ejb;
-}
-
 void init_pthread_helper()
 {
 	real_pthread_cleanup_push_defer = (vFppp_t)dlsym(NULL, "_pthread_cleanup_push_defer");
@@ -1108,8 +1086,6 @@ void init_pthread_helper()
 	}
 
 	InitCancelThread();
-	pthread_key_create(&jmpbuf_key, emujmpbuf_destroy);
-	pthread_setspecific(jmpbuf_key, NULL);
 	pthread_key_create(&thread_key, emuthread_destroy);
 	pthread_setspecific(thread_key, NULL);
 }
@@ -1118,11 +1094,6 @@ void fini_pthread_helper(box64context_t* context)
 {
 	FreeCancelThread(context);
 	CleanStackSize(context);
-	emu_jmpbuf_t *ejb = (emu_jmpbuf_t*)pthread_getspecific(jmpbuf_key);
-	if(ejb) {
-		pthread_setspecific(jmpbuf_key, NULL);
-		emujmpbuf_destroy(ejb);
-	}
 	emuthread_t *et = (emuthread_t*)pthread_getspecific(thread_key);
 	if(et) {
 		pthread_setspecific(thread_key, NULL);