diff options
| author | ptitSeb <sebastien.chev@gmail.com> | 2023-07-30 22:12:30 +0200 |
|---|---|---|
| committer | ptitSeb <sebastien.chev@gmail.com> | 2023-07-30 22:12:30 +0200 |
| commit | fb0e8ee9c6237993c393f3737e528199be41c23c (patch) | |
| tree | 77f2805581337ebd007d72399270d5cd0e2956b7 /src/dynarec | |
| parent | 6a8cc8ace371c0a683fb3f57048be6b642a56187 (diff) | |
| download | box64-fb0e8ee9c6237993c393f3737e528199be41c23c.tar.gz box64-fb0e8ee9c6237993c393f3737e528199be41c23c.zip | |
Change again a bit how jmpbuffer and resuming of signal is handled
Diffstat (limited to 'src/dynarec')
| -rw-r--r-- | src/dynarec/dynarec.c | 139 |
1 files changed, 43 insertions, 96 deletions
diff --git a/src/dynarec/dynarec.c b/src/dynarec/dynarec.c index ab7a21ae..0d2c63f1 100644 --- a/src/dynarec/dynarec.c +++ b/src/dynarec/dynarec.c @@ -73,114 +73,63 @@ void* LinkNext(x64emu_t* emu, uintptr_t addr, void* x2, uintptr_t* x3) } #endif -#ifdef __GNUC__ -// Disable "clobbered" warnings -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wclobbered" -#endif void DynaCall(x64emu_t* emu, uintptr_t addr) { - // prepare setjump for signal handling - struct __jmp_buf_tag jmpbuf[1] = {0}; - int skip = 0; - struct __jmp_buf_tag *old_jmpbuf = emu->jmpbuf; - emu->jmpbuf = jmpbuf; - - if((skip = sigsetjmp(emu->jmpbuf, 1))) { - printf_log(LOG_DEBUG, "Setjmp DynaCall, fs=0x%x\n", emu->segs[_FS]); - addr = R_RIP; // not sure if it should still be inside DynaCall! - #ifdef DYNAREC - if(box64_dynarec_test) { - if(emu->test.clean) - x64test_check(emu, R_RIP); - emu->test.clean = 0; - } - #endif - } -#ifdef DYNAREC - if(!box64_dynarec) -#endif - EmuCall(emu, addr); -#ifdef DYNAREC - else { - uint64_t old_rsp = R_RSP; - uint64_t old_rbx = R_RBX; - uint64_t old_rdi = R_RDI; - uint64_t old_rsi = R_RSI; - uint64_t old_rbp = R_RBP; - uint64_t old_rip = R_RIP; - PushExit(emu); - R_RIP = addr; - emu->df = d_none; - while(!emu->quit) { - int is32bits = (emu->segs[_CS]==0x23); - dynablock_t* block = (skip)?NULL:DBGetBlock(emu, R_RIP, 1, is32bits); - if(!block || !block->block || !block->done) { - skip = 0; - // no block, of block doesn't have DynaRec content (yet, temp is not null) - // Use interpreter (should use single instruction step...) - dynarec_log(LOG_DEBUG, "%04d|Calling Interpreter @%p, emu=%p\n", GetTID(), (void*)R_RIP, emu); - if(box64_dynarec_test) - emu->test.clean = 0; - Run(emu, 1); - } else { - dynarec_log(LOG_DEBUG, "%04d|Calling DynaRec Block @%p (%p) of %d x64 instructions (hash=0x%x) emu=%p\n", GetTID(), (void*)R_RIP, block->block, block->isize ,block->hash, emu); - CHECK_FLAGS(emu); - // block is here, let's run it! - native_prolog(emu, block->block); - } - if(emu->fork) { - int forktype = emu->fork; - emu->quit = 0; - emu->fork = 0; - emu = x64emu_fork(emu, forktype); - } - } - 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 - } else { - R_RBX = old_rbx; - R_RDI = old_rdi; - R_RSI = old_rsi; - R_RBP = old_rbp; - R_RSP = old_rsp; - R_RIP = old_rip; // and set back instruction pointer - } + uint64_t old_rsp = R_RSP; + uint64_t old_rbx = R_RBX; + uint64_t old_rdi = R_RDI; + uint64_t old_rsi = R_RSI; + uint64_t old_rbp = R_RBP; + uint64_t old_rip = R_RIP; + PushExit(emu); + R_RIP = addr; + emu->df = d_none; + 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 + } else { + R_RBX = old_rbx; + R_RDI = old_rdi; + R_RSI = old_rsi; + R_RBP = old_rbp; + R_RSP = old_rsp; + R_RIP = old_rip; // and set back instruction pointer } -#endif - // clear the setjmp - emu->jmpbuf = old_jmpbuf; } -int DynaRun(x64emu_t* emu) +void DynaRun(x64emu_t* emu) { // prepare setjump for signal handling struct __jmp_buf_tag jmpbuf[1] = {0}; int skip = 0; struct __jmp_buf_tag *old_jmpbuf = emu->jmpbuf; - emu->jmpbuf = jmpbuf; - if((skip=sigsetjmp(emu->jmpbuf, 1))) { - printf_log(LOG_DEBUG, "Setjmp DynaRun, fs=0x%x\n", emu->segs[_FS]); - #ifdef DYNAREC - if(box64_dynarec_test) { - if(emu->test.clean) - x64test_check(emu, R_RIP); - emu->test.clean = 0; + while(!(emu->quit)) { + if(!emu->jmpbuf || (emu->need_jmpbuf && emu->jmpbuf!=jmpbuf)) { + emu->jmpbuf = jmpbuf; + if((skip=sigsetjmp(emu->jmpbuf, 1))) { + printf_log(LOG_DEBUG, "Setjmp DynaRun, fs=0x%x\n", emu->segs[_FS]); + #ifdef DYNAREC + if(box64_dynarec_test) { + if(emu->test.clean) + x64test_check(emu, R_RIP); + emu->test.clean = 0; + } + #endif + } } - #endif - } + if(emu->need_jmpbuf) + emu->need_jmpbuf = 0; #ifdef DYNAREC - if(!box64_dynarec) + if(!box64_dynarec) #endif - return Run(emu, 0); + Run(emu, 0); #ifdef DYNAREC - else { - while(!emu->quit) { + else { int is32bits = (emu->segs[_CS]==0x23); dynablock_t* block = (skip)?NULL:DBGetBlock(emu, R_RIP, 1, is32bits); if(!block || !block->block || !block->done) { @@ -202,13 +151,11 @@ int DynaRun(x64emu_t* emu) emu->fork = 0; emu = x64emu_fork(emu, forktype); } + if(emu->need_jmpbuf) + emu->quit = 0; } } // clear the setjmp emu->jmpbuf = old_jmpbuf; - return 0; #endif } -#ifdef __GNUC__ -#pragma GCC diagnostic pop -#endif |