about summary refs log tree commit diff stats
path: root/src
diff options
context:
space:
mode:
authorptitSeb <sebastien.chev@gmail.com>2025-08-27 16:17:17 +0200
committerptitSeb <sebastien.chev@gmail.com>2025-08-27 16:17:17 +0200
commit3fe020572dfc0636ab82bae962c3514134e9e128 (patch)
treeee2fe2191bab2db8f04404debe951d0040e55430 /src
parent234f6f2b14231679832a9c64469df2a5c8cefa73 (diff)
downloadbox64-3fe020572dfc0636ab82bae962c3514134e9e128.tar.gz
box64-3fe020572dfc0636ab82bae962c3514134e9e128.zip
Improved handling of TF flag
Diffstat (limited to 'src')
-rw-r--r--src/dynarec/dynarec.c9
-rw-r--r--src/emu/x64emu.c2
-rw-r--r--src/emu/x64run.c12
-rw-r--r--src/include/box64cpu.h2
-rw-r--r--src/libtools/signal32.c2
-rw-r--r--src/libtools/signals.c4
-rw-r--r--src/os/emit_signals_linux.c9
7 files changed, 30 insertions, 10 deletions
diff --git a/src/dynarec/dynarec.c b/src/dynarec/dynarec.c
index fc24a121..2f3d7914 100644
--- a/src/dynarec/dynarec.c
+++ b/src/dynarec/dynarec.c
@@ -147,6 +147,7 @@ void DynaRun(x64emu_t* emu)
     // prepare setjump for signal handling
     JUMPBUFF jmpbuf[1] = {0};
     int skip = 0;
+    int need_tf = 0;
     JUMPBUFF *old_jmpbuf = emu->jmpbuf;
     #ifdef RV64
     uintptr_t old_savesp = emu->xSPSave;
@@ -184,7 +185,7 @@ void DynaRun(x64emu_t* emu)
 #ifdef DYNAREC
         if(!BOX64ENV(dynarec))
 #endif
-            Run(emu, 0);
+            Run(emu, 0, 0);
 #ifdef DYNAREC
         else {
             int newis32bits = (emu->segs[_CS]==0x23);
@@ -216,7 +217,8 @@ void DynaRun(x64emu_t* emu)
                 }
                 if (BOX64ENV(dynarec_test))
                     emu->test.clean = 0;
-                Run(emu, 1);
+                Run(emu, 1, need_tf);
+                need_tf = 0;
             } else {
                 dynarec_log(LOG_DEBUG, "%04d|Running DynaRec Block @%p (%p) of %d x64 insts (hash=0x%x) emu=%p\n", GetTID(), (void*)R_RIP, block->block, block->isize, block->hash, emu);
                 if(!BOX64ENV(dynarec_df)) {
@@ -224,6 +226,9 @@ void DynaRun(x64emu_t* emu)
                 }
                 // block is here, let's run it!
                 native_prolog(emu, block->block);
+                if(ACCESS_FLAG(F_TF) && !emu->quit)
+                    need_tf = 1; 
+                    skip = 1;
             }
             if(emu->fork) {
                 int forktype = emu->fork;
diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c
index 9d6f4a8b..0c68de08 100644
--- a/src/emu/x64emu.c
+++ b/src/emu/x64emu.c
@@ -562,7 +562,7 @@ void EmuCall(x64emu_t* emu, uintptr_t addr)
         PushExit(emu);
     R_RIP = addr;
     emu->df = d_none;
-    Run(emu, 0);
+    Run(emu, 0, 0);
     emu->quit = 0;  // reset Quit flags...
     emu->df = d_none;
     if(emu->flags.quitonlongjmp && emu->flags.longjmp) {
diff --git a/src/emu/x64run.c b/src/emu/x64run.c
index 9c536731..fc9e8270 100644
--- a/src/emu/x64run.c
+++ b/src/emu/x64run.c
@@ -32,7 +32,7 @@
 int RunTest(x64test_t *test)
 #else
 int running32bits = 0;
-int Run(x64emu_t *emu, int step)
+int Run(x64emu_t *emu, int step, int need_tf)
 #endif
 {
     uint8_t opcode;
@@ -68,6 +68,15 @@ int Run(x64emu_t *emu, int step)
     test->memsize = 0;
 #else
     CheckExec(emu, R_RIP);
+#ifndef TEST_INTERPRETER
+        // check the TRACE flag before going to next
+        if(ACCESS_FLAG(F_TF) && need_tf) {
+            need_tf = 0;
+            CLEAR_FLAG(F_TF);
+            EmitSignal(emu, X64_SIGTRAP, (void*)addr, 1);
+            if(emu->quit) goto fini;
+        }
+#endif
 x64emurun:
     while(1) 
 #endif
@@ -2252,6 +2261,7 @@ x64emurun:
             } else {
                 tf_next = 0;
                 R_RIP = addr;
+                CLEAR_FLAG(F_TF);
                 EmitSignal(emu, X64_SIGTRAP, (void*)addr, 1);
                 if(emu->quit) goto fini;
             }
diff --git a/src/include/box64cpu.h b/src/include/box64cpu.h
index 72df2c69..b565e06f 100644
--- a/src/include/box64cpu.h
+++ b/src/include/box64cpu.h
@@ -3,7 +3,7 @@
 
 typedef struct x64emu_s x64emu_t;
 
-int Run(x64emu_t *emu, int step);
+int Run(x64emu_t *emu, int step, int need_tf);
 void EmuCall(x64emu_t* emu, uintptr_t addr);
 void StopEmu(x64emu_t* emu, const char* reason, int is32bits);
 void DynaRun(x64emu_t *emu);
diff --git a/src/libtools/signal32.c b/src/libtools/signal32.c
index cd5f054d..4e6c8e1e 100644
--- a/src/libtools/signal32.c
+++ b/src/libtools/signal32.c
@@ -400,8 +400,6 @@ uint32_t RunFunctionHandler32(int* exit, int dynarec, i386_ucontext_t* sigcontex
     int old_cs = R_CS;
     R_CS = 0x23;
 
-    emu->eflags.x64 &= ~(1<<F_TF); // this one needs to cleared
-
     if(dynarec)
         DynaCall(emu, fnc);
     else
diff --git a/src/libtools/signals.c b/src/libtools/signals.c
index bbfa8958..7fa41e7b 100644
--- a/src/libtools/signals.c
+++ b/src/libtools/signals.c
@@ -160,8 +160,6 @@ uint64_t RunFunctionHandler(x64emu_t* emu, int* exit, int dynarec, x64_ucontext_
     int old_cs = R_CS;
     R_CS = 0x33;
 
-    emu->eflags.x64 &= ~(1<<F_TF); // this one needs to cleared
-
     if(dynarec)
         DynaCall(emu, fnc);
     else
@@ -1102,7 +1100,7 @@ void my_sigactionhandler_oldcode_64(x64emu_t* emu, int32_t sig, int simple, sigi
     int ret;
     int dynarec = 0;
     #ifdef DYNAREC
-    if(sig!=X64_SIGSEGV && !(Locks&is_dyndump_locked) && !(Locks&is_memprot_locked))
+    if(!(sig==X64_SIGSEGV || (Locks&is_dyndump_locked) || (Locks&is_memprot_locked)))
         dynarec = 1;
     #endif
     ret = RunFunctionHandler(emu, &exits, dynarec, sigcontext, my_context->signals[info2->si_signo], 3, info2->si_signo, info2, sigcontext);
diff --git a/src/os/emit_signals_linux.c b/src/os/emit_signals_linux.c
index 4e7f6c77..efc2af51 100644
--- a/src/os/emit_signals_linux.c
+++ b/src/os/emit_signals_linux.c
@@ -22,6 +22,7 @@
 #include "x64emu.h"
 #include "signals.h"
 #include "libtools/signal_private.h"
+#include "box64cpu_util.h"
 
 void my_sigactionhandler_oldcode(x64emu_t* emu, int32_t sig, int simple, siginfo_t* info, void * ucntx, int* old_code, void* cur_db, uintptr_t x64pc);
 void EmitSignal(x64emu_t* emu, int sig, void* addr, int code)
@@ -49,6 +50,14 @@ void EmitSignal(x64emu_t* emu, int sig, void* addr, int code)
         if (elf)
             elfname = ElfName(elf);
         printf_log(LOG_NONE, "Emit Signal %d at IP=%p(%s / %s) / addr=%p, code=0x%x\n", sig, (void*)R_RIP, x64name ? x64name : "???", elfname ? elfname : "?", addr, code);
+        if(sig==5)
+            printf_log(LOG_INFO, "\t Opcode (%02X %02X %02X %02X) %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
+                Peek(emu, -4), Peek(emu, -3), Peek(emu, -2), Peek(emu, -1),
+                Peek(emu, 0), Peek(emu, 1), Peek(emu, 2), Peek(emu, 3),
+                Peek(emu, 4), Peek(emu, 5), Peek(emu, 6), Peek(emu, 7),
+                Peek(emu, 8), Peek(emu, 9), Peek(emu,10), Peek(emu,11),
+                Peek(emu,12), Peek(emu,13), Peek(emu,14));
+
         print_rolling_log(LOG_INFO);
 
         if ((BOX64ENV(showbt) || sig == X64_SIGABRT) && BOX64ENV(log) >= LOG_INFO) {