diff options
| -rwxr-xr-x | src/dynarec/arm64/dynarec_arm64_00.c | 7 | ||||
| -rw-r--r-- | src/dynarec/dynarec_native_functions.c | 6 | ||||
| -rw-r--r-- | src/dynarec/dynarec_native_functions.h | 1 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_2.c | 8 | ||||
| -rwxr-xr-x | src/emu/x64run.c | 9 | ||||
| -rwxr-xr-x | src/libtools/signals.c | 4 |
6 files changed, 35 insertions, 0 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index d52f4eae..7926ebe7 100755 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -1159,6 +1159,13 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin ANDw_REG(xFlags, xFlags, x1); ORRw_mask(xFlags, xFlags, 0b011111, 0); //mask=0x00000002 SET_DFNONE(x1); + if(box64_wine) { // should this be done all the time? + TBZ_NEXT(xFlags, F_TF); + MOV64x(x1, addr); + STORE_XEMU_CALL(x1); + CALL(native_singlestep, -1); + BFCw(xFlags, F_TF, 1); + } break; case 0x9E: INST_NAME("SAHF"); diff --git a/src/dynarec/dynarec_native_functions.c b/src/dynarec/dynarec_native_functions.c index 42c7fba8..cec37771 100644 --- a/src/dynarec/dynarec_native_functions.c +++ b/src/dynarec/dynarec_native_functions.c @@ -160,6 +160,12 @@ void native_ud(x64emu_t* emu) void native_priv(x64emu_t* emu) { + emu->test.test = 0; + emit_signal(emu, SIGTRAP, (void*)R_RIP, 1); +} + +void native_singlestep(x64emu_t* emu) +{ emit_signal(emu, SIGSEGV, (void*)R_RIP, 0); } diff --git a/src/dynarec/dynarec_native_functions.h b/src/dynarec/dynarec_native_functions.h index 2733cd5a..e9862598 100644 --- a/src/dynarec/dynarec_native_functions.h +++ b/src/dynarec/dynarec_native_functions.h @@ -45,6 +45,7 @@ void native_clflush(x64emu_t* emu, void* p); void native_ud(x64emu_t* emu); void native_priv(x64emu_t* emu); +void native_singlestep(x64emu_t* emu); // Caches transformation (for loops) // Specific, need to be written par backend int CacheNeedsTransform(dynarec_native_t* dyn, int i1); diff --git a/src/dynarec/rv64/dynarec_rv64_00_2.c b/src/dynarec/rv64/dynarec_rv64_00_2.c index 22c83db3..5bfeec16 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_2.c +++ b/src/dynarec/rv64/dynarec_rv64_00_2.c @@ -500,6 +500,14 @@ uintptr_t dynarec64_00_2(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int AND(xFlags, xFlags, x1); ORI(xFlags, xFlags, 0x2); SET_DFNONE(); + if(box64_wine) { // should this be done all the time? + ANDI(x1, xFlags, ~(1<<F_TF)); + CBZ_NEXT(x1); + MOV64x(xRIP, addr); + STORE_XEMU_CALL(); + CALL(native_singlestep, -1); + ANDI(xFlags, xFlags, ~(1<<F_TF)); + } break; case 0xA1: INST_NAME("MOV EAX,Od"); diff --git a/src/emu/x64run.c b/src/emu/x64run.c index 20b70945..876459b0 100755 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -640,6 +640,15 @@ x64emurun: case 0x9D: /* POPF */ emu->eflags.x64 = ((Pop(emu) & 0x3F7FD7)/* & (0xffff-40)*/ ) | 0x2; // mask off res2 and res3 and on res1 RESET_FLAGS(emu); + #ifndef TEST_INTERPRETER + if(ACCESS_FLAG(F_TF)) { + R_RIP = addr; + emit_signal(emu, SIGTRAP, (void*)addr, 1); + if(emu->quit) goto fini; + CLEAR_FLAG(F_TF); + STEP; + } + #endif break; case 0x9E: /* SAHF */ CHECK_FLAGS(emu); diff --git a/src/libtools/signals.c b/src/libtools/signals.c index f3da73a9..3ddb52f4 100755 --- a/src/libtools/signals.c +++ b/src/libtools/signals.c @@ -324,6 +324,8 @@ uint64_t RunFunctionHandler(int* exit, int dynarec, x64_ucontext_t* sigcontext, int oldquitonlongjmp = emu->quitonlongjmp; emu->quitonlongjmp = 2; + emu->eflags.x64 &= ~(1<<F_TF); // this one needs to cleared + if(dynarec) DynaCall(emu, fnc); else @@ -727,6 +729,8 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void 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; |