diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/arm64/dynarec_arm64_00.c | 18 | ||||
| -rw-r--r-- | src/dynarec/dynarec_native_functions.c | 2 | ||||
| -rw-r--r-- | src/dynarec/rv64/dynarec_rv64_00_3.c | 14 | ||||
| -rw-r--r-- | src/emu/x64int3.c | 7 | ||||
| -rw-r--r-- | src/emu/x64run.c | 13 | ||||
| -rw-r--r-- | src/libtools/signals.c | 9 |
6 files changed, 48 insertions, 15 deletions
diff --git a/src/dynarec/arm64/dynarec_arm64_00.c b/src/dynarec/arm64/dynarec_arm64_00.c index 5a638072..0ad91284 100644 --- a/src/dynarec/arm64/dynarec_arm64_00.c +++ b/src/dynarec/arm64/dynarec_arm64_00.c @@ -2385,7 +2385,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin //LDRx_U12(x3, x1, offsetof(box64context_t, signals[SIGTRAP])); CMPSx_U12(x3, 0); B_NEXT(cEQ); - GETIP(ip); + GETIP(addr); // update RIP STORE_XEMU_CALL(xRIP); CALL(native_int3, -1); LOAD_XEMU_CALL(xRIP); @@ -2401,7 +2401,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin INST_NAME("INT 29/2c/2d"); // lets do nothing MESSAGE(LOG_INFO, "INT 29/2c/2d Windows interruption\n"); - GETIP(ip); + GETIP(ip); // priviledged instruction, IP not updated STORE_XEMU_CALL(xRIP); MOV32w(x1, u8); CALL(native_int, -1); @@ -2422,10 +2422,20 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin MARK; LOAD_XEMU_REM(); jump_to_epilog(dyn, 0, xRIP, ninst); + } else if(u8==0x03) { + INST_NAME("INT 3"); + SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state + GETIP(addr); + STORE_XEMU_CALL(xRIP); + CALL(native_int3, -1); + LOAD_XEMU_CALL(xRIP); + jump_to_epilog(dyn, 0, xRIP, ninst); + *need_epilog = 0; + *ok = 0; } else { INST_NAME("INT n"); SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state - GETIP(ip); + GETIP(ip); // priviledged instruction, IP not updated STORE_XEMU_CALL(xRIP); CALL(native_int, -1); LOAD_XEMU_CALL(xRIP); @@ -2440,7 +2450,7 @@ uintptr_t dynarec64_00(dynarec_arm_t* dyn, uintptr_t addr, uintptr_t ip, int nin } else { INST_NAME("INTO"); READFLAGS(X_OF); - GETIP(ip); + GETIP(addr); TBZ_NEXT(wFlags, F_OF); STORE_XEMU_CALL(xRIP); CALL(native_int, -1); diff --git a/src/dynarec/dynarec_native_functions.c b/src/dynarec/dynarec_native_functions.c index 6a118dfa..376541d1 100644 --- a/src/dynarec/dynarec_native_functions.c +++ b/src/dynarec/dynarec_native_functions.c @@ -188,7 +188,7 @@ void native_singlestep(x64emu_t* emu) void native_int3(x64emu_t* emu) { - emit_signal(emu, SIGTRAP, (void*)R_RIP, 128); + emit_signal(emu, SIGTRAP, NULL, 3); } void native_div0(x64emu_t* emu) diff --git a/src/dynarec/rv64/dynarec_rv64_00_3.c b/src/dynarec/rv64/dynarec_rv64_00_3.c index 790d00bb..43ef69d7 100644 --- a/src/dynarec/rv64/dynarec_rv64_00_3.c +++ b/src/dynarec/rv64/dynarec_rv64_00_3.c @@ -442,7 +442,7 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int INST_NAME("INT 29/2c/2d"); // lets do nothing MESSAGE(LOG_INFO, "INT 29/2c/2d Windows interruption\n"); - GETIP(ip); + GETIP(ip); // priviledged instruction, IP not updated STORE_XEMU_CALL(x3); MOV32w(x1, u8); CALL(native_int, -1); @@ -462,10 +462,20 @@ uintptr_t dynarec64_00_3(dynarec_rv64_t* dyn, uintptr_t addr, uintptr_t ip, int MARK; LOAD_XEMU_REM(x3); jump_to_epilog(dyn, 0, xRIP, ninst); + } else if (u8==0x03) { + INST_NAME("INT 3"); + SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state + GETIP(addr); + STORE_XEMU_CALL(x3); + CALL(native_int3, -1); + LOAD_XEMU_CALL(); + jump_to_epilog(dyn, 0, xRIP, ninst); + *need_epilog = 0; + *ok = 0; } else { INST_NAME("INT n"); SETFLAGS(X_ALL, SF_SET_NODF); // Hack to set flags in "don't care" state - GETIP(ip); + GETIP(ip); // priviledged instruction, IP not updated STORE_XEMU_CALL(x3); CALL(native_priv, -1); LOAD_XEMU_CALL(); diff --git a/src/emu/x64int3.c b/src/emu/x64int3.c index 3dd818ed..14493647 100644 --- a/src/emu/x64int3.c +++ b/src/emu/x64int3.c @@ -364,9 +364,10 @@ void x64Int3(x64emu_t* emu, uintptr_t* addr) } return; } - if(!box64_ignoreint3 && my_context->signals[SIGTRAP]) - emit_signal(emu, SIGTRAP, (void*)R_RIP, 128); - else { + if(!box64_ignoreint3 && my_context->signals[SIGTRAP]) { + R_RIP = *addr; // update RIP + emit_signal(emu, SIGTRAP, NULL, 3); + } else { printf_log(LOG_DEBUG, "%04d|Warning, ignoring unsupported Int 3 call @%p\n", GetTID(), (void*)R_RIP); R_RIP = *addr; } diff --git a/src/emu/x64run.c b/src/emu/x64run.c index fecb1311..614bf91c 100644 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -1488,6 +1488,7 @@ x64emurun: STEP2; break; case 0xCC: /* INT 3 */ + R_RIP = addr; // update RIP #ifndef TEST_INTERPRETER x64Int3(emu, &addr); if(emu->quit) goto fini; // R_RIP is up to date when returning from x64Int3 @@ -1511,6 +1512,7 @@ x64emurun: printf_log(LOG_DEBUG, "INT 29 called => __fastfail(0x%x)\n", R_ECX); emit_interruption(emu, 0x29, (void*)R_RIP); } else if (tmp8u==0x80) { + R_RIP = addr; // 32bits syscall #ifndef TEST_INTERPRETER x86Syscall(emu); @@ -1518,9 +1520,17 @@ x64emurun: #else test->notest = 1; #endif + } else if (tmp8u==0x03) { + R_RIP = addr; + #ifndef TEST_INTERPRETER + emit_signal(emu, SIGTRAP, NULL, 3); + STEP2; + #else + test->notest = 1; + #endif } else { #ifndef TEST_INTERPRETER - emit_signal(emu, SIGSEGV, (void*)R_RIP, 0); + emit_interruption(emu, tmp8u, (void*)R_RIP); STEP2; #else test->notest = 1; @@ -1533,6 +1543,7 @@ x64emurun: goto fini; } emu->old_ip = R_RIP; + R_RIP = addr; #ifndef TEST_INTERPRETER CHECK_FLAGS(emu); if(ACCESS_FLAG(F_OF)) diff --git a/src/libtools/signals.c b/src/libtools/signals.c index 7d052c29..e58081c1 100644 --- a/src/libtools/signals.c +++ b/src/libtools/signals.c @@ -1164,11 +1164,9 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void info2->si_signo = SIGTRAP; sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 3; sigcontext->uc_mcontext.gregs[X64_ERR] = 0; - sigcontext->uc_mcontext.gregs[X64_RIP]+=2; // segfault after the INT } else if(int_n==0x04) { sigcontext->uc_mcontext.gregs[X64_TRAPNO] = 4; sigcontext->uc_mcontext.gregs[X64_ERR] = 0; - sigcontext->uc_mcontext.gregs[X64_RIP]+=2; // segfault after the INT } else if (int_n==0x29 || int_n==0x2c || int_n==0x2d) { sigcontext->uc_mcontext.gregs[X64_ERR] = 0x02|(int_n<<3); } else { @@ -1186,10 +1184,13 @@ 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) + else if(sig==SIGTRAP) { + info2->si_code = 128; sigcontext->uc_mcontext.gregs[X64_TRAPNO] = info->si_code; + sigcontext->uc_mcontext.gregs[X64_ERR] = 0; + } //TODO: SIGABRT generate what? - printf_log(LOG_DEBUG, "Signal %d: TRAPNO=%d, ERR=%d, RIP=%p\n", sig, sigcontext->uc_mcontext.gregs[X64_TRAPNO], sigcontext->uc_mcontext.gregs[X64_ERR],sigcontext->uc_mcontext.gregs[X64_RIP]); + printf_log(LOG_DEBUG, "Signal %d: si_addr=%p, TRAPNO=%d, ERR=%d, RIP=%p\n", sig, (void*)info2->si_addr, sigcontext->uc_mcontext.gregs[X64_TRAPNO], sigcontext->uc_mcontext.gregs[X64_ERR],sigcontext->uc_mcontext.gregs[X64_RIP]); // call the signal handler x64_ucontext_t sigcontext_copy = *sigcontext; // save old value from emu |