diff options
| author | ptitSeb <seebastien.chev@gmail.com> | 2023-08-13 12:24:12 +0200 |
|---|---|---|
| committer | ptitSeb <seebastien.chev@gmail.com> | 2023-08-13 12:24:12 +0200 |
| commit | e2077c46ce334453c567382cb254d1010f733fb1 (patch) | |
| tree | 84d23a64d703baa121230b17d9f4ae9d99a4f4a1 /src | |
| parent | e8972efca192e988cdd72fc765ef001defe9a5a4 (diff) | |
| download | box64-e2077c46ce334453c567382cb254d1010f733fb1.tar.gz box64-e2077c46ce334453c567382cb254d1010f733fb1.zip | |
Improved jmpbuff handling a bit
Diffstat (limited to 'src')
| -rw-r--r-- | src/dynarec/dynarec.c | 16 | ||||
| -rw-r--r-- | src/emu/x64emu.c | 6 | ||||
| -rw-r--r-- | src/emu/x64emu_private.h | 15 | ||||
| -rw-r--r-- | src/libtools/signals.c | 14 | ||||
| -rw-r--r-- | src/tools/callback.c | 6 | ||||
| -rw-r--r-- | src/wrapped/wrappedlibc.c | 18 |
6 files changed, 42 insertions, 33 deletions
diff --git a/src/dynarec/dynarec.c b/src/dynarec/dynarec.c index 9c2fb4c0..bb6b3ba9 100644 --- a/src/dynarec/dynarec.c +++ b/src/dynarec/dynarec.c @@ -87,9 +87,9 @@ void DynaCall(x64emu_t* emu, uintptr_t addr) DynaRun(emu); emu->quit = 0; // reset Quit flags... emu->df = d_none; - if(emu->quitonlongjmp && emu->longjmp) { - if(emu->quitonlongjmp==1) - emu->longjmp = 0; // don't change anything because of the longjmp + if(emu->flags.quitonlongjmp && emu->flags.longjmp) { + if(emu->flags.quitonlongjmp==1) + emu->flags.longjmp = 0; // don't change anything because of the longjmp } else { R_RBX = old_rbx; R_RDI = old_rdi; @@ -106,10 +106,12 @@ void DynaRun(x64emu_t* emu) struct __jmp_buf_tag jmpbuf[1] = {0}; int skip = 0; struct __jmp_buf_tag *old_jmpbuf = emu->jmpbuf; + emu->flags.jmpbuf_ready = 0; while(!(emu->quit)) { - if(!emu->jmpbuf || (emu->need_jmpbuf && emu->jmpbuf!=jmpbuf)) { + if(!emu->jmpbuf || (emu->flags.need_jmpbuf && emu->jmpbuf!=jmpbuf)) { emu->jmpbuf = jmpbuf; + emu->flags.jmpbuf_ready = 1; if((skip=sigsetjmp(emu->jmpbuf, 1))) { printf_log(LOG_DEBUG, "Setjmp DynaRun, fs=0x%x\n", emu->segs[_FS]); #ifdef DYNAREC @@ -121,8 +123,8 @@ void DynaRun(x64emu_t* emu) #endif } } - if(emu->need_jmpbuf) - emu->need_jmpbuf = 0; + if(emu->flags.need_jmpbuf) + emu->flags.need_jmpbuf = 0; #ifdef DYNAREC if(!box64_dynarec) @@ -153,7 +155,7 @@ void DynaRun(x64emu_t* emu) } } #endif - if(emu->need_jmpbuf) + if(emu->flags.need_jmpbuf) emu->quit = 0; } // clear the setjmp diff --git a/src/emu/x64emu.c b/src/emu/x64emu.c index 9de4cb18..95077d4a 100644 --- a/src/emu/x64emu.c +++ b/src/emu/x64emu.c @@ -567,9 +567,9 @@ void EmuCall(x64emu_t* emu, uintptr_t addr) Run(emu, 0); emu->quit = 0; // reset Quit flags... emu->df = d_none; - if(emu->quitonlongjmp && emu->longjmp) { - if(emu->quitonlongjmp==1) - emu->longjmp = 0; // don't change anything because of the longjmp + if(emu->flags.quitonlongjmp && emu->flags.longjmp) { + if(emu->flags.quitonlongjmp==1) + emu->flags.longjmp = 0; // don't change anything because of the longjmp } else { R_RBX = old_rbx; R_RDI = old_rdi; diff --git a/src/emu/x64emu_private.h b/src/emu/x64emu_private.h index e3a474ca..8076049d 100644 --- a/src/emu/x64emu_private.h +++ b/src/emu/x64emu_private.h @@ -36,6 +36,14 @@ typedef struct x64test_s { uint8_t mem[16]; } x64test_t; +typedef struct emu_flags_s { + uint32_t need_jmpbuf:1; // need a new jmpbuff for signal handling + uint32_t quitonlongjmp:2; // quit if longjmp is called + uint32_t quitonexit:2; // quit if exit/_exit is called + uint32_t longjmp:1; // if quit because of longjmp + uint32_t jmpbuf_ready:1; // the jmpbuf in the emu is ok and don't need refresh +} emu_flags_t; + typedef struct x64emu_s { // cpu reg64_t regs[16]; @@ -83,12 +91,9 @@ typedef struct x64emu_s { int quit; int error; int fork; // quit because need to fork - int need_jmpbuf; // need a new jmpbuff for signal handling - forkpty_t* forkpty_info; int exit; - int quitonlongjmp; // quit if longjmp is called - int quitonexit; // quit if exit/_exit is called - int longjmp; // if quit because of longjmp + forkpty_t* forkpty_info; + emu_flags_t flags; x64test_t test; // used for dynarec testing #ifdef HAVE_TRACE sse_regs_t old_xmm[16]; diff --git a/src/libtools/signals.c b/src/libtools/signals.c index 5e249432..e47a3dac 100644 --- a/src/libtools/signals.c +++ b/src/libtools/signals.c @@ -321,8 +321,8 @@ uint64_t RunFunctionHandler(int* exit, int dynarec, x64_ucontext_t* sigcontext, printf_log(LOG_DEBUG, "%04d|signal #%d function handler %p called, RSP=%p\n", GetTID(), R_EDI, (void*)fnc, (void*)R_RSP); - int oldquitonlongjmp = emu->quitonlongjmp; - emu->quitonlongjmp = 2; + int oldquitonlongjmp = emu->flags.quitonlongjmp; + emu->flags.quitonlongjmp = 2; int old_cs = R_CS; R_CS = 0x33; @@ -333,13 +333,13 @@ uint64_t RunFunctionHandler(int* exit, int dynarec, x64_ucontext_t* sigcontext, else EmuCall(emu, fnc); - if(nargs>6 && !emu->longjmp) + if(nargs>6 && !emu->flags.longjmp) R_RSP+=((nargs-6)*sizeof(void*)); - if(!emu->longjmp && R_CS==0x33) + if(!emu->flags.longjmp && R_CS==0x33) R_CS = old_cs; - emu->quitonlongjmp = oldquitonlongjmp; + emu->flags.quitonlongjmp = oldquitonlongjmp; #ifdef DYNAREC if(box64_dynarec_test) @@ -347,9 +347,9 @@ uint64_t RunFunctionHandler(int* exit, int dynarec, x64_ucontext_t* sigcontext, emu->test.clean = 0; #endif - if(emu->longjmp) { + if(emu->flags.longjmp) { // longjmp inside signal handler, lets grab all relevent value and do the actual longjmp in the signal handler - emu->longjmp = 0; + emu->flags.longjmp = 0; if(sigcontext) { sigcontext->uc_mcontext.gregs[X64_R8] = R_R8; sigcontext->uc_mcontext.gregs[X64_R9] = R_R9; diff --git a/src/tools/callback.c b/src/tools/callback.c index f3a6bbbf..162c801f 100644 --- a/src/tools/callback.c +++ b/src/tools/callback.c @@ -233,10 +233,10 @@ uint64_t RunFunctionWithEmu(x64emu_t *emu, int QuitOnLongJump, uintptr_t fnc, in uintptr_t oldip = R_RIP; int old_quit = emu->quit; - int oldlong = emu->quitonlongjmp; + int oldlong = emu->flags.quitonlongjmp; emu->quit = 0; - emu->quitonlongjmp = QuitOnLongJump; + emu->flags.quitonlongjmp = QuitOnLongJump; DynaCall(emu, fnc); @@ -246,7 +246,7 @@ uint64_t RunFunctionWithEmu(x64emu_t *emu, int QuitOnLongJump, uintptr_t fnc, in } emu->quit = old_quit; - emu->quitonlongjmp = oldlong; + emu->flags.quitonlongjmp = oldlong; return R_RAX; diff --git a/src/wrapped/wrappedlibc.c b/src/wrapped/wrappedlibc.c index 45758e32..06726923 100644 --- a/src/wrapped/wrappedlibc.c +++ b/src/wrapped/wrappedlibc.c @@ -2494,8 +2494,8 @@ void EXPORT my_longjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p, if(((__jmp_buf_tag_t*)p)->__mask_was_saved) { sigprocmask(SIG_SETMASK, &((__jmp_buf_tag_t*)p)->__saved_mask, NULL); } - if(emu->quitonlongjmp) { - emu->longjmp = 1; + if(emu->flags.quitonlongjmp) { + emu->flags.longjmp = 1; emu->quit = 1; } } @@ -2520,8 +2520,10 @@ EXPORT int32_t my___sigsetjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/vo } else ((__jmp_buf_tag_t*)p)->__mask_was_saved = 0; // quit emulation loop and create a new jumpbuf if needed - emu->need_jmpbuf = 1; - emu->quit = 1; + if(!emu->flags.jmpbuf_ready) { + emu->flags.need_jmpbuf = 1; + emu->quit = 1; + } return 0; } EXPORT int32_t my_sigsetjmp(x64emu_t* emu, /*struct __jmp_buf_tag __env[1]*/void *p, int savesigs) @@ -3192,10 +3194,10 @@ static int clone_fn(void* p) updateGlibcTidCache(); // update cache tid if needed x64emu_t *emu = arg->emu; R_RSP = arg->stack; - emu->quitonexit = 1; + emu->flags.quitonexit = 1; thread_set_emu(emu); int ret = RunFunctionWithEmu(emu, 0, arg->fnc, 1, arg->args); - int exited = (emu->quitonexit==2); + int exited = (emu->flags.quitonexit==2); thread_set_emu(NULL); FreeX64Emu(&emu); if(arg->stack_clone_used) @@ -3274,10 +3276,10 @@ EXPORT int my_register_printf_type(x64emu_t* emu, void* f) extern int box64_quit; EXPORT void my_exit(x64emu_t* emu, int code) { - if(emu->quitonexit) { + if(emu->flags.quitonexit) { emu->quit = 1; R_EAX = code; - emu->quitonexit = 2; + emu->flags.quitonexit = 2; return; } emu->quit = 1; |