diff --git a/src/dynarec/dynarec.c b/src/dynarec/dynarec.c index 106b447a4..84ff79ad1 100644 --- a/src/dynarec/dynarec.c +++ b/src/dynarec/dynarec.c @@ -109,9 +109,6 @@ void DynaCall(x64emu_t* emu, uintptr_t addr) multiuint_t old_op1 = emu->op1; multiuint_t old_op2 = emu->op2; multiuint_t old_res = emu->res; - // uc_link - void* old_uc_link = emu->uc_link; - emu->uc_link = NULL; #ifdef BOX32 if(box64_is32bits) @@ -124,7 +121,6 @@ void DynaCall(x64emu_t* emu, uintptr_t addr) DynaRun(emu); emu->quit = 0; // reset Quit flags... emu->df = d_none; - emu->uc_link = old_uc_link; if(emu->flags.quitonlongjmp && emu->flags.longjmp) { if(emu->flags.quitonlongjmp==1) emu->flags.longjmp = 0; // don't change anything because of the longjmp @@ -229,15 +225,6 @@ void DynaRun(x64emu_t* emu) emu->fork = 0; emu = x64emu_fork(emu, forktype); } - if(emu->quit && emu->uc_link) { - emu->quit = 0; - #ifdef BOX32 - if(box64_is32bits) - my32_setcontext(emu, emu->uc_link); - else - #endif - my_setcontext(emu, emu->uc_link); - } } #endif if(emu->flags.need_jmpbuf) diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c index 7619483bc..e63f46ddc 100644 --- a/src/emu/x64emu.c +++ b/src/emu/x64emu.c @@ -608,9 +608,6 @@ void EmuCall(x64emu_t* emu, uintptr_t addr) multiuint_t old_op1 = emu->op1; multiuint_t old_op2 = emu->op2; multiuint_t old_res = emu->res; - // uc_link - void* old_uc_link = emu->uc_link; - emu->uc_link = NULL; //Push64(emu, GetRBP(emu)); // set frame pointer //SetRBP(emu, GetRSP(emu)); // save RSP //R_RSP -= 200; @@ -626,7 +623,6 @@ void EmuCall(x64emu_t* emu, uintptr_t addr) Run(emu, 0); emu->quit = 0; // reset Quit flags... emu->df = d_none; - emu->uc_link = old_uc_link; if(emu->flags.quitonlongjmp && emu->flags.longjmp) { if(emu->flags.quitonlongjmp==1) emu->flags.longjmp = 0; // don't change anything because of the longjmp diff --git a/src/emu/x64emu_private.h b/src/emu/x64emu_private.h index caa92848b..ff2d6af54 100644 --- a/src/emu/x64emu_private.h +++ b/src/emu/x64emu_private.h @@ -128,8 +128,6 @@ typedef struct x64emu_s { uintptr_t old_savedsp; #endif - void* uc_link; // to handle setcontext (can be x64_ucontext_t or a i386_ucontext_t) - int type; // EMUTYPE_xxx define #ifdef BOX32 int libc_err; // copy of errno from libc diff --git a/src/emu/x64run.c b/src/emu/x64run.c index a0939a921..e90e86691 100644 --- a/src/emu/x64run.c +++ b/src/emu/x64run.c @@ -2253,7 +2253,7 @@ int Run(x64emu_t *emu, int step) fini: #ifndef TEST_INTERPRETER // check the TRACE flag before going to out, in case it's a step by step scenario - if(!emu->quit && !emu->fork && !emu->uc_link && ACCESS_FLAG(F_TF)) { + if(!emu->quit && !emu->fork && ACCESS_FLAG(F_TF)) { R_RIP = addr; emit_signal(emu, SIGTRAP, (void*)addr, 1); if(emu->quit) goto fini; @@ -2261,7 +2261,7 @@ int Run(x64emu_t *emu, int step) #endif if(emu->segs[_CS]!=0x33 && emu->segs[_CS]!=0x23) printf_log(LOG_NONE, "Warning, CS is not default value: 0x%x\n", emu->segs[_CS]); #ifndef TEST_INTERPRETER - printf_log(LOG_DEBUG, "End of X86 run (%p), RIP=%p, Stack=%p, unimp=%d, emu->fork=%d, emu->uc_link=%p, emu->quit=%d\n", emu, (void*)R_RIP, (void*)R_RSP, unimp, emu->fork, emu->uc_link, emu->quit); + printf_log(LOG_DEBUG, "End of X86 run (%p), RIP=%p, Stack=%p, unimp=%d, emu->fork=%d, emu->quit=%d\n", emu, (void*)R_RIP, (void*)R_RSP, unimp, emu->fork, emu->quit); if(unimp) { //emu->quit = 1; UnimpOpcode(emu, is32bits); @@ -2278,18 +2278,6 @@ if(emu->segs[_CS]!=0x33 && emu->segs[_CS]!=0x23) printf_log(LOG_NONE, "Warning, return 0; goto x64emurun; } - // setcontext handling - else if(emu->quit && emu->uc_link) { - emu->quit = 0; - #ifdef BOX32 - if(box64_is32bits) - my32_setcontext(emu, emu->uc_link); - else - #endif - my_setcontext(emu, emu->uc_link); - addr = R_RIP; - goto x64emurun; - } #else if(unimp) { printf_log(LOG_INFO, "Warning, inimplemented opcode in Test Interpreter\n"); diff --git a/src/libtools/signal32.c b/src/libtools/signal32.c index 1bb133384..2a7e3a521 100644 --- a/src/libtools/signal32.c +++ b/src/libtools/signal32.c @@ -31,6 +31,7 @@ #include "threads.h" #include "emu/x87emu_private.h" #include "custommem.h" +#include "bridge.h" #ifdef DYNAREC #include "dynablock.h" #include "../dynarec/dynablock_private.h" @@ -949,8 +950,6 @@ EXPORT int my32_getcontext(x64emu_t* emu, void* ucp) fpu_savenv(emu, from_ptrv(u->uc_mcontext.fpregs), 1); // it seems getcontext only save fpu env, not fpu regs // get signal mask sigprocmask(SIG_SETMASK, NULL, (sigset_t*)&u->uc_sigmask); - // ensure uc_link is properly initialized - u->uc_link = to_ptrv(emu->uc_link); return 0; } @@ -963,15 +962,15 @@ EXPORT int my32_setcontext(x64emu_t* emu, void* ucp) emu->init_stack = from_ptrv(u->uc_stack.ss_sp); emu->size_stack = from_ulong(u->uc_stack.ss_size); // set general register - R_EAX = u->uc_mcontext.gregs[I386_EAX]; - R_ECX = u->uc_mcontext.gregs[I386_ECX]; - R_EDX = u->uc_mcontext.gregs[I386_EDX]; - R_EDI = u->uc_mcontext.gregs[I386_EDI]; - R_ESI = u->uc_mcontext.gregs[I386_ESI]; - R_EBP = u->uc_mcontext.gregs[I386_EBP]; - R_EIP = u->uc_mcontext.gregs[I386_EIP]; - R_ESP = u->uc_mcontext.gregs[I386_ESP]; - R_EBX = u->uc_mcontext.gregs[I386_EBX]; + R_RAX = u->uc_mcontext.gregs[I386_EAX]; + R_RCX = u->uc_mcontext.gregs[I386_ECX]; + R_RDX = u->uc_mcontext.gregs[I386_EDX]; + R_RDI = u->uc_mcontext.gregs[I386_EDI]; + R_RSI = u->uc_mcontext.gregs[I386_ESI]; + R_RBP = u->uc_mcontext.gregs[I386_EBP]; + R_RIP = u->uc_mcontext.gregs[I386_EIP]; + R_RSP = u->uc_mcontext.gregs[I386_ESP]; + R_RBX = u->uc_mcontext.gregs[I386_EBX]; // get segments R_GS = u->uc_mcontext.gregs[I386_GS]; R_FS = u->uc_mcontext.gregs[I386_FS]; @@ -983,12 +982,22 @@ EXPORT int my32_setcontext(x64emu_t* emu, void* ucp) fpu_loadenv(emu, from_ptrv(u->uc_mcontext.fpregs), 1); // set signal mask sigprocmask(SIG_SETMASK, (sigset_t*)&u->uc_sigmask, NULL); - // set uc_link - emu->uc_link = from_ptrv(u->uc_link); + errno = 0; return R_EAX; } +void vFEv_32(x64emu_t *emu, uintptr_t fnc); +EXPORT void my32_start_context(x64emu_t* emu) +{ + // this is call indirectly by swapcontext from a makecontext, and will link context or just exit + i386_ucontext_t *u = (i386_ucontext_t*)from_ptriv(R_EBX); + if(u) + my32_setcontext(emu, u); + else + emu->quit = 1; +} + EXPORT void my32_makecontext(x64emu_t* emu, void* ucp, void* fnc, int32_t argc, int32_t* argv) { // printf_log(LOG_NONE, "Warning: call to unimplemented makecontext\n"); @@ -997,8 +1006,12 @@ EXPORT void my32_makecontext(x64emu_t* emu, void* ucp, void* fnc, int32_t argc, u->uc_mcontext.gregs[I386_ESP] = to_ptr(u->uc_stack.ss_sp + u->uc_stack.ss_size - 4); // setup the function u->uc_mcontext.gregs[I386_EIP] = to_ptrv(fnc); - // setup args uint32_t* esp = (uint32_t*)from_ptr(u->uc_mcontext.gregs[I386_ESP]); + // setup return to private start_context uc_link + *esp = u->uc_link; + u->uc_mcontext.gregs[I386_EBX] = (uintptr_t)esp; + --esp; + // setup args for (int i=0; iexit_bridge); + *esp = AddCheckBridge(my_context->system, vFEv_32, my32_start_context, 0, "my_start_context");//my_context->exit_bridge;//to_ptr(my_context->exit_bridge); u->uc_mcontext.gregs[I386_ESP] = (uintptr_t)esp; } diff --git a/src/libtools/signals.c b/src/libtools/signals.c index 04702fe62..d71208427 100644 --- a/src/libtools/signals.c +++ b/src/libtools/signals.c @@ -31,6 +31,7 @@ #include "threads.h" #include "emu/x87emu_private.h" #include "custommem.h" +#include "bridge.h" #ifdef DYNAREC #include "dynablock.h" #include "../dynarec/dynablock_private.h" @@ -2291,8 +2292,6 @@ EXPORT int my_getcontext(x64emu_t* emu, void* ucp) // get signal mask sigprocmask(SIG_SETMASK, NULL, (sigset_t*)&u->uc_sigmask); - // ensure uc_link is properly initialized - u->uc_link = (x64_ucontext_t*)emu->uc_link; return 0; } @@ -2331,12 +2330,20 @@ EXPORT int my_setcontext(x64emu_t* emu, void* ucp) emu->mxcsr.x32 = *(uint32_t*)(ucp + 432); // set signal mask sigprocmask(SIG_SETMASK, (sigset_t*)&u->uc_sigmask, NULL); - // set uc_link - emu->uc_link = u->uc_link; errno = 0; return R_EAX; } +void vFEv(x64emu_t *emu, uintptr_t fnc); +EXPORT void my_start_context(x64emu_t* emu) +{ + // this is call indirectly by swapcontext from a makecontext, and will link context or just exit + x64_ucontext_t *u = *(x64_ucontext_t**)R_RBX; + if(u) + my_setcontext(emu, u); + else + emu->quit = 1; +} EXPORT void my_makecontext(x64emu_t* emu, void* ucp, void* fnc, int32_t argc, int64_t* argv) { @@ -2346,15 +2353,19 @@ EXPORT void my_makecontext(x64emu_t* emu, void* ucp, void* fnc, int32_t argc, in uintptr_t* rsp = (uintptr_t*)(u->uc_stack.ss_sp + u->uc_stack.ss_size - sizeof(uintptr_t)); // setup the function u->uc_mcontext.gregs[X64_RIP] = (intptr_t)fnc; + // setup return to private start_context uc_link + *rsp = (uintptr_t)u->uc_link; + u->uc_mcontext.gregs[X64_RBX] = (uintptr_t)rsp; + --rsp; // setup args int n = 3; int j = 0; int regs_abi[] = {_DI, _SI, _DX, _CX, _R8, _R9}; for (int i=0; iregs[regs_abi[n++]].q[0]; + v = emu->regs[regs_abi[n++]].dword[0]; else v = argv[j++]; // push value @@ -2372,7 +2383,7 @@ EXPORT void my_makecontext(x64emu_t* emu, void* ucp, void* fnc, int32_t argc, in } // push the return value --rsp; - *rsp = my_context->exit_bridge; + *rsp = AddCheckBridge(my_context->system, vFEv, my_start_context, 0, "my_start_context");//my_context->exit_bridge; u->uc_mcontext.gregs[X64_RSP] = (uintptr_t)rsp; }