diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-11-17 16:21:38 +0100 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-11-17 16:21:38 +0100 |
| commit | 54be0c0dec8ad3c81caa0366f84c056717792cb2 (patch) | |
| tree | ec3f895739734aba1a0b73eb622634cf39c1e8c4 | |
| parent | 20df2789b542b5c280d71b4ae0fa797a24f6d130 (diff) | |
| download | box64-54be0c0dec8ad3c81caa0366f84c056717792cb2.tar.gz box64-54be0c0dec8ad3c81caa0366f84c056717792cb2.zip | |
Saved defered flag status when processing signal / foreign function
| -rw-r--r-- | src/dynarec/dynarec.c | 23 | ||||
| -rw-r--r-- | src/emu/x64run.c | 2 | ||||
| -rw-r--r-- | src/libtools/signals.c | 2 | ||||
| -rw-r--r-- | src/tools/callback.c | 16 |
4 files changed, 40 insertions, 3 deletions
diff --git a/src/dynarec/dynarec.c b/src/dynarec/dynarec.c index b832b1e5..16c1c464 100644 --- a/src/dynarec/dynarec.c +++ b/src/dynarec/dynarec.c @@ -81,6 +81,15 @@ void DynaCall(x64emu_t* emu, uintptr_t addr) uint64_t old_rsi = R_RSI; uint64_t old_rbp = R_RBP; uint64_t old_rip = R_RIP; + // save defered flags + deferred_flags_t old_df = emu->df; + multiuint_t old_op1 = emu->op1; + multiuint_t old_op2 = emu->op2; + multiuint_t old_res = emu->res; + multiuint_t old_op1_sav= emu->op1_sav; + multiuint_t old_res_sav= emu->res_sav; + deferred_flags_t old_df_sav= emu->df_sav; + PushExit(emu); R_RIP = addr; emu->df = d_none; @@ -91,6 +100,15 @@ void DynaCall(x64emu_t* emu, uintptr_t addr) if(emu->flags.quitonlongjmp==1) emu->flags.longjmp = 0; // don't change anything because of the longjmp } else { + // restore defered flags + emu->df = old_df; + emu->op1 = old_op1; + emu->op2 = old_op2; + emu->res = old_res; + emu->op1_sav = old_op1_sav; + emu->res_sav = old_res_sav; + emu->df_sav = old_df_sav; + // and the old registers R_RBX = old_rbx; R_RDI = old_rdi; R_RSI = old_rsi; @@ -100,6 +118,7 @@ void DynaCall(x64emu_t* emu, uintptr_t addr) } } +int my_setcontext(x64emu_t* emu, void* ucp); void DynaRun(x64emu_t* emu) { // prepare setjump for signal handling @@ -158,6 +177,10 @@ void DynaRun(x64emu_t* emu) emu->fork = 0; emu = x64emu_fork(emu, forktype); } + if(emu->quit && emu->uc_link) { + emu->quit = 0; + my_setcontext(emu, emu->uc_link); + } } #endif if(emu->flags.need_jmpbuf) diff --git a/src/emu/x64run.c b/src/emu/x64run.c index 2296611e..0edfcc08 100644 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -2068,7 +2068,7 @@ if(emu->segs[_CS]!=0x33 && emu->segs[_CS]!=0x23) printf_log(LOG_NONE, "Warning, goto x64emurun; } // setcontext handling - else if(emu->uc_link) { + else if(emu->quit && emu->uc_link) { emu->quit = 0; my_setcontext(emu, emu->uc_link); addr = R_RIP; diff --git a/src/libtools/signals.c b/src/libtools/signals.c index 19c49dab..2145a3e4 100644 --- a/src/libtools/signals.c +++ b/src/libtools/signals.c @@ -966,7 +966,7 @@ void my_sigactionhandler_oldcode(int32_t sig, int simple, siginfo_t* info, void else if(sig==SIGSEGV) { if((uintptr_t)info->si_addr == sigcontext->uc_mcontext.gregs[X64_RIP]) { sigcontext->uc_mcontext.gregs[X64_ERR] = (info->si_errno==0x1234)?0:((info->si_errno==0xdead)?(0x2|(info->si_code<<3)):0x0010); // execution flag issue (probably), unless it's a #GP(0) - sigcontext->uc_mcontext.gregs[X64_TRAPNO] = (info->si_code == SEGV_ACCERR || (info->si_errno==0x1234) || (info->si_errno==0xdead) || (uintptr_t)info->si_addr==0)?13:14; + sigcontext->uc_mcontext.gregs[X64_TRAPNO] = ((info->si_code==SEGV_ACCERR) || (info->si_errno==0x1234) || (info->si_errno==0xdead) || ((uintptr_t)info->si_addr==0))?13:14; } else if(info->si_code==SEGV_ACCERR && !(prot&PROT_WRITE)) { sigcontext->uc_mcontext.gregs[X64_ERR] = 0x0002; // write flag issue if(labs((intptr_t)info->si_addr-(intptr_t)sigcontext->uc_mcontext.gregs[X64_RSP])<16) diff --git a/src/tools/callback.c b/src/tools/callback.c index 162c801f..341a554d 100644 --- a/src/tools/callback.c +++ b/src/tools/callback.c @@ -164,6 +164,13 @@ uint64_t RunSafeFunction(uintptr_t fnc, int nargs, ...) Push64(emu, R_R10); Push64(emu, R_R11); Push64(emu, R_RAX); + deferred_flags_t old_df = emu->df; + multiuint_t old_op1 = emu->op1; + multiuint_t old_op2 = emu->op2; + multiuint_t old_res = emu->res; + multiuint_t old_op1_sav= emu->op1_sav; + multiuint_t old_res_sav= emu->res_sav; + deferred_flags_t old_df_sav= emu->df_sav; R_RSP -= stackn*sizeof(void*); // need to push in reverse order @@ -200,7 +207,14 @@ uint64_t RunSafeFunction(uintptr_t fnc, int nargs, ...) R_RSP = old_rbp; // mov rsp, rbp R_RBP = Pop64(emu); // pop rbp - + + emu->df = old_df; + emu->op1 = old_op1; + emu->op2 = old_op2; + emu->res = old_res; + emu->op1_sav = old_op1_sav; + emu->res_sav = old_res_sav; + emu->df_sav = old_df_sav; return ret; } |