diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2025-09-29 12:47:36 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2025-09-29 12:47:36 +0200 |
| commit | 86dde8c1f7f798df0fcf8c0603b75de838b41241 (patch) | |
| tree | ee378302e52499c6fe75e08b433b382723707ef6 /src | |
| parent | e48881715a7b4a9444ba7ff24973547ad965b2db (diff) | |
| download | box64-86dde8c1f7f798df0fcf8c0603b75de838b41241.tar.gz box64-86dde8c1f7f798df0fcf8c0603b75de838b41241.zip | |
Improved TF handling
Diffstat (limited to 'src')
| -rw-r--r-- | src/emu/x64run.c | 58 | ||||
| -rw-r--r-- | src/libtools/signal32.c | 1 | ||||
| -rw-r--r-- | src/libtools/signals.c | 1 |
3 files changed, 25 insertions, 35 deletions
diff --git a/src/emu/x64run.c b/src/emu/x64run.c index fc5188e2..909437e0 100644 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -53,7 +53,8 @@ int Run(x64emu_t *emu, int step, int need_tf) rex_t rex = {0}; int unimp = 0; int is32bits = (emu->segs[_CS]==0x23); - int tf_next = 0; + int no_tf = 0; + int tf = ACCESS_FLAG(F_TF); if(emu->quit) return 0; @@ -68,15 +69,6 @@ int Run(x64emu_t *emu, int step, int need_tf) 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 @@ -91,6 +83,19 @@ x64emurun: #endif emu->old_ip = addr; + #ifndef TEST_INTERPRETER + // check the TRACE flag before going to next + if(tf) { + if(no_tf) + no_tf = 0; + else { + R_RIP = addr; + EmitSignal(emu, X64_SIGTRAP, (void*)addr, 1); + if(emu->quit) goto fini; + } + } +#endif + opcode = F8; rex.rex = 0; @@ -123,7 +128,7 @@ x64emurun: if(rex.seg) rex.offset = GetSegmentBaseEmu(emu, rex.seg); - + if(rex.is66) { /* 16bits prefix */ #ifdef TEST_INTERPRETER @@ -138,6 +143,7 @@ x64emurun: R_RIP = addr; goto fini; } + tf = ACCESS_FLAG(F_TF); #endif } else switch(opcode) { @@ -279,8 +285,7 @@ x64emurun: } emu->segs[_SS] = Pop32(emu); // no check, no use.... emu->segs_serial[_SS] = 0; - if(ACCESS_FLAG(F_TF)) - tf_next = 1; + tf = 0; break; case 0x1E: /* PUSH DS */ @@ -772,8 +777,8 @@ x64emurun: GETED(0); emu->segs[((nextop&0x38)>>3)] = ED->word[0]; emu->segs_serial[((nextop&0x38)>>3)] = 0; - if(((nextop&0x38)>>3)==_SS && ACCESS_FLAG(F_TF)) - tf_next = 1; + if(((nextop&0x38)>>3)==_SS && tf) // disable trace when SS is accessed + no_tf = 1; break; case 0x8F: /* POP Ed */ nextop = F8; @@ -842,12 +847,9 @@ x64emurun: Push64(emu, emu->eflags.x64); break; case 0x9D: /* POPF */ - if(ACCESS_FLAG(F_TF) && !tf_next) - --tf_next; emu->eflags.x64 = (((rex.is32bits?Pop32(emu):Pop64(emu)) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x202; // mask off res2 and res3 and on res1 RESET_FLAGS(emu); - if(ACCESS_FLAG(F_TF)) - ++tf_next; + tf = ACCESS_FLAG(F_TF); break; case 0x9E: /* SAHF */ CHECK_FLAGS(emu); @@ -1516,8 +1518,7 @@ x64emurun: EmitInterruption(emu, 0x29, (void*)R_RIP); } else if (tmp8u==0x80) { R_RIP = addr; - if(ACCESS_FLAG(F_TF)) - tf_next = 1; + if(tf) no_tf = 1; // 32bits syscall #ifndef TEST_INTERPRETER EmuX86Syscall(emu); @@ -1567,6 +1568,7 @@ x64emurun: #endif RESET_FLAGS(emu); emu->eflags.x64 = ((((!rex.w)?Pop32(emu):Pop64(emu)) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1 + tf = ACCESS_FLAG(F_TF); if(!is32bits || (is32bits && (new_cs!=0x23))) { uintptr_t new_sp = (!rex.w)?Pop32(emu):Pop64(emu); uint32_t new_ss = ((!rex.w)?Pop32(emu):Pop64(emu))&0xffff; @@ -2273,20 +2275,6 @@ x64emurun: unimp = 1; goto fini; } -#ifndef TEST_INTERPRETER - // check the TRACE flag before going to next - if(ACCESS_FLAG(F_TF) || (tf_next<0)) { - if(tf_next>0) { - tf_next = 0; - } else { - tf_next = 0; - R_RIP = addr; - CLEAR_FLAG(F_TF); - EmitSignal(emu, X64_SIGTRAP, (void*)addr, 1); - if(emu->quit) goto fini; - } - } -#endif R_RIP = addr; } diff --git a/src/libtools/signal32.c b/src/libtools/signal32.c index 9324e89f..47975f43 100644 --- a/src/libtools/signal32.c +++ b/src/libtools/signal32.c @@ -546,6 +546,7 @@ void my_sigactionhandler_oldcode_32(x64emu_t* emu, int32_t sig, int simple, sigi sigcontext->uc_mcontext.gregs[I386_EIP] = R_EIP;//emu->old_ip; // old_ip should be more accurate as the "current" IP, but it's not always up-to-date // flags sigcontext->uc_mcontext.gregs[I386_EFL] = emu->eflags.x64; + CLEAR_FLAG(F_TF); // now clear TF flags inside the signal handler // get segments sigcontext->uc_mcontext.gregs[I386_CS] = R_CS; sigcontext->uc_mcontext.gregs[I386_DS] = R_DS; diff --git a/src/libtools/signals.c b/src/libtools/signals.c index 7f99c182..f9e87bc5 100644 --- a/src/libtools/signals.c +++ b/src/libtools/signals.c @@ -930,6 +930,7 @@ void my_sigactionhandler_oldcode_64(x64emu_t* emu, int32_t sig, int simple, sigi sigcontext->uc_mcontext.gregs[X64_RIP] = R_RIP; // flags sigcontext->uc_mcontext.gregs[X64_EFL] = emu->eflags.x64; + CLEAR_FLAG(F_TF); // now clear TF flags inside the signal handler // get segments sigcontext->uc_mcontext.gregs[X64_CSGSFS] = ((uint64_t)(R_CS)) | (((uint64_t)(R_GS))<<16) | (((uint64_t)(R_FS))<<32); if(R_CS==0x23) { |